老王 Good youtube to explain conda, uv difference https://www.youtube.com/watch?v=jd1aRE5pJWc&ab_channel=%E7%A8%8B%E5%BA%8F%E5%91%98%E8%80%81%E7%8E%8B
very good follow-up by 老王 https://www.youtube.com/watch?v=-MSLJKjH8U0&ab_channel=%E7%A8%8B%E5%BA%8F%E5%91%98%E8%80%81%E7%8E%8B
[@liaoPythonImport2020] 指出 import 常常遇到的問題
[@loongProjectStructure2021] Python project structure 寫的非常好,本文直接引用自己參考。
UV vs. Conda/Mamba
uv 和 conda/mamba 都包含 virtual environment 和 package dependency management, 但是代表兩個不同的派別。
uv: local virtual environment: .venv, install package 非常快。而且可以做現代 python project management, i.e. pyproject.toml.
conda/mamba: global virtual enviornment: conda 非常慢,但是 mamba 非常快!缺點是無法做 python project management. 解法: 用 mamba 取代 conda. 但似乎無法解決 python project management?
(2025/8/16) uv 從 local 變 global
第一個問題, why? 因爲不會占用太多資源。local package 無法 cross-platform, like PC with CUDA and Mac.
UV has a global cache system that can help with both issues. You can configure it to use a shared cache location:
1. Use UV’s global cache to avoid duplicate downloads
1 | |
2. Generate Platform-Specific Lock Files
使用同一個 pyproject.toml, 但是產生不同的 lock files. 然後用 uv sync –active 在各自的 global virtual enviornment.
uv lock and uv.lock
uv lock 產生 uv.lock file.
uv.lock 的角色
- 類似於
requirements.txt,但更完整,精確記錄實際安裝的版本與依賴樹。 - 還會包含 跨平台資訊(不同作業系統與 Python 版本的 resolution 結果)。
- 不要直接編輯
uv.lock,正確做法是修改pyproject.toml或需求檔,再透過uv lock來更新。
1 | |
uv sync 的幾種模式
接下來是最 confusing 的部分。先說結論:
對於 global environment, 使用 uv sync --active,
對於自己的 local environment, 使用 uv sync,
對於 clone 別人的 project, 使用 uv sync --frozen.
flowchart TD
A["要同步哪裡?"] --> B["Global (全域環境)"]
A --> C["Local env (專案 venv)"]
B --> D{"使用已啟動的環境嗎?"}
D -->|Yes| E["uv sync --active"]
C --> F{"是自己的專案嗎?"}
F -->|Yes| G["uv sync (預設模式)"]
F -->|No| H["uv sync --frozen"]
| 使用情境 | 指令 | 說明 |
|---|---|---|
Global environment(例如你想把全域 Python 環境的套件和 uv.lock 同步) |
uv sync --active |
會將目前「已啟動」的環境(例如全域 Python、或 venv/conda)與 uv.lock 中的套件同步 |
| Local environment(自己開發的專案) | uv sync |
預設會依據 uv.lock 建立或更新本地的 .venv/ |
| Clone 別人的專案,要確保環境完全一致 | uv sync --frozen |
嚴格依照 uv.lock,不會重新解析依賴。若 uv.lock 不符合當前環境,會直接失敗(避免偷偷 drift) |
另外還有 uv sync --locked 和 uv sync --frozen 類似但不同。見 Appendix A.
uv sync --locked vs --frozen 的關鍵差異
1 |
|
- 檢查 lockfile 是否最新:確保
uv.lock與pyproject.toml同步 - 如果過期會失敗:如果 lockfile 過期,命令會報錯退出
- 適用場景:CI/CD 環境,確保依賴完全一致
1 |
|
“To use the lockfile without checking if it is up-to-date, use the –frozen option”
- 不檢查 lockfile 狀態:直接使用現有的
uv.lock,不管是否過期 - 不會重新鎖定:完全按照現有 lockfile 安裝
- 適用場景:Docker 建構、生產部署
3. Add UV cache directories to .gitignore 這是 in case commit local cache.
注意要使用 .uvignore 和 .gitignore 以免 check-in 一堆 packages.
1 | |
(2025/8/8) Conda 轉 Mamba takeaway
from 5分钟彻底搞懂!Anaconda Miniconda conda-forge miniforge Mamba
- 以後千萬不要 install anaconda, 只要 install miniforge!
- 使用 miniforge 的 mamba 取代 anaconda 的 conda! 速度快十倍!
- 對於已經 install anaconda
-
conda install mamba -n base -c conda-forge
-
edit ~/.bashrc, 加上
eval "$(mamba shell hook --shell bash)" -
source ~/.bashrc, 以後把 conda command 改成 mamba command! ```bash
»> conda initialize »>
!! Contents within this block are managed by ‘conda init’ !!
__conda_setup=”$(‘/home/allen/anaconda3_25/bin/conda’ ‘shell.bash’ ‘hook’ 2> /dev/null)” if [ $? -eq 0 ]; then eval “$__conda_setup” else if [ -f “/home/allen/anaconda3_25/etc/profile.d/conda.sh” ]; then . “/home/allen/anaconda3_25/etc/profile.d/conda.sh” else export PATH=”/home/allen/anaconda3_25/bin:$PATH” fi fi unset __conda_setup
«< conda initialize «<
-
»> mamba initialize »>
Initialize mamba shell for bash
eval “$(mamba shell hook –shell bash)”
«< mamba initialize «<
1 | |
$ git clone https://github.com/karpathy/minbpe.git $ tree . ├── minbpe │ ├── init.py │ ├── base.py │ ├── basic.py │ ├── gpt4.py │ └── regex.py ├── minbpe.egg-info │ ├── PKG-INFO │ ├── SOURCES.txt │ ├── dependency_links.txt │ └── top_level.txt ├── pyproject.toml ├── requirements.txt ├── setup.py ├── tests │ ├── init.py │ ├── taylorswift.txt │ └── test_tokenizer.py └── train.py
$ pytest collected 21 items tests/test_tokenizer.py …….. [100%] ============= 21 passed in 22.04s ===
1 | |
- 建立新的 Python 專案(包含 pyproject.toml)
1 | |
此時 uv 會建立以下基本專案結構(含 pyproject.toml):
1 | |
- 建立虛擬環境
1 | |
- 這會在專案目錄下建立
.venv虛擬環境資料夾(名稱可自訂,預設是.venv)。 -
uv 也支援使用指定 Python 版本(如果沒裝,會自動下載):
1
uv venv --python 3.12.0
- 安裝或新增套件(並自動更新
pyproject.toml)
例如安裝 requests:
1 | |
- 這會在虛擬環境中安裝 requests,同時將依賴加入
pyproject.toml的 dependencies。
- 執行 Python 腳本
1 | |
- 會自動使用專案裡的虛擬環境執行。
- 鎖定依賴版本
1 | |
- 生成或更新
uv.lock文件,確保版本一致。
- 同步安裝所有依賴
若其他人拉取專案,或剛從版本庫複製專案,可用:
1 | |
- 根據
uv.lock與pyproject.toml安裝所有需依賴。
流程總結示意
1 | |
補充說明
- uv init 會自動幫你生成
pyproject.toml,並載入一份簡單的專案結構。 - 虛擬環境
.venv不會在uv init時自動建立,需要用uv venv指令生成。 uv add會同時安裝套件及更新pyproject.toml,保持依賴同步管理。uv run會自動找到並使用虛擬環境,免去手動 activate 的麻煩。uv lock和uv sync分別用於鎖版本和同步安裝,非常適用協作時保持環境一致性。
### uv add package 還是 uv pip install package?
uv add package- 是一個「高階的專案管理 API」。
- 它會將該套件自動加入你的專案的
pyproject.toml中的依賴清單,同時安裝套件。 - 適合你有使用
pyproject.toml來聲明專案依賴的情況。 - 這樣做有利於保持依賴的有序管理與版本鎖定,進而方便團隊同步。
uv add執行時會產生或更新uv.lock鎖定檔,確保環境跨機相容。- 簡言之,是 uv 推薦的「專案依賴管理」方式。
uv pip install package- 是一個「低階的 pip 兼容 API」,等同於傳統的
pip install。 - 僅僅在當前虛擬環境中安裝套件,不會改動
pyproject.toml。 - 適合臨時安裝或不使用
pyproject.toml管理依賴的場景。 - 這種用法類似傳統直接操作環境的方式,缺少專案層級的依賴追蹤。
- 是一個「低階的 pip 兼容 API」,等同於傳統的
簡單比喻:
| 功能 | uv add | uv pip install |
|---|---|---|
| 依賴管理 | 自動更新 pyproject.toml | 不更新配置文件 |
| 配合 pyproject.toml | 是(適合有專案依賴聲明) | 否(手動操作當前環境) |
| 適合用途 | 正規專案依賴管理與團隊協作 | 臨時、低階操作或快速安裝 |
| 產生鎖定檔 | 更新 uv.lock | 不產生鎖定檔 |
uv add會保證跨平台(Windows、Linux 等)相容性,選擇版本時更謹慎,能確保其他人也可以無差異環境重現。uv pip install則通常安裝最新版本(無跨平台版本限制),有時可能帶來不一致版本風險。uv add是「專案 API」,而uv pip install是「低階 pip 命令集」的替代方案。
結論建議:
- 如果你在用
pyproject.toml管理專案,請優先使用uv add package。這能讓專案依賴管理更規範且適合團隊合作。 - 如果只是臨時在某環境裝包,或不想改動依賴聲明,可以用
uv pip install package。
這樣能兼顧依賴管理的乾淨與裝包靈活度。
uv 設定
uv stores packages is important for cross-platform development. Here’s how uv works:
Where uv stores packages:
1. Virtual Environment (.venv directory)
1 | |
2. Global package cache (shared across projects)
- Linux/Mac:
~/.cache/uv/ - Windows:
%LOCALAPPDATA%\uv\cache\
Best practices for Google Drive sync:
✅ DO sync these files:
1 | |
❌ DON’T sync these:
1 | |
Recommended setup for cross-platform:
1. Create a .gitignore file in your project:
1 | |
2. Use pyproject.toml for dependency management:
1 | |
3. On each computer, recreate the environment:
1 | |
For your current situation:
Since you’re already using Google Drive sync, here’s what to do:
1 | |
This way, each computer maintains its own .venv directory locally, but your project configuration is synced via pyproject.toml. The environments are isolated and won’t conflict between different operating systems.
Cross-platform 挑戰
- Share 同一個 project with different PCs and Mac. 有些 PC 有 GPU with different CUDA 版本。 Mac 則需要 run CPU 版本。
如果你有兩台電腦共用同一個專案目錄,一台用 CPU 版本的 PyTorch,另一台用 CUDA 版本,要如何在 requirements.txt、pyproject.toml 或其他方式管理這種差異,核心問題是「依賴版本與來源有所不同怎麼條件安裝並共存」。
整理並參考最新的實務建議與工具支持,說明如下:
1. requirements.txt
-
傳統
requirements.txt只是單純列出套件名和版本,不支援根據硬體或環境條件切換版本。 -
你可以寫兩份
requirements-cpu.txt與requirements-gpu.txt,兩台電腦各自用對應檔案安裝套件:text
# requirements-cpu.txt torch==2.0.1+cpu torchvision==0.15.2+cputext
# requirements-gpu.txt torch==2.0.1+cu118 torchvision==0.15.2+cu118 -
安裝時指定檔案,例如:
pip install -r requirements-cpu.txt。但只能靠手動選擇檔案,不會自動根據硬體條件切換。
2. pyproject.toml + Poetry 或 uv
現在多數現代 Python 專案用 pyproject.toml 配合管理工具(Poetry、uv、PDM)管理依賴,更靈活支持根據系統條件安裝版本。
a. Poetry 支援「依賴群組」與「條件裝載」示例
text
[tool.poetry.dependencies] python = "^3.8" [tool.poetry.group.cpu] optional = true [tool.poetry.group.cpu.dependencies] torch = { version = "^2.0.1", source = "pypi", markers = "sys_platform != 'linux' and sys_platform != 'win32'" } torchvision = { version = "^0.15.2", source = "pypi", markers = "sys_platform != 'linux' and sys_platform != 'win32'" } [tool.poetry.group.gpu] optional = true [tool.poetry.group.gpu.dependencies] torch = { version = "^2.0.1+cu118", source = "torch_cuda", markers = "sys_platform == 'linux' or sys_platform == 'win32'" } torchvision = { version = "^0.15.2+cu118", source = "torch_cuda", markers = "sys_platform == 'linux' or sys_platform == 'win32'" } [[tool.poetry.source]] name = "torch_cuda" url = "https://download.pytorch.org/whl/cu118" priority = "explicit"
-
你可用命令選擇性安裝:
bash
poetry install --with cpu poetry install --with gpu -
但實務上系統判斷和混合安裝稍複雜,需要人工選擇。
b. uv 配置範例(根據系統條件切換索引源與版本)
pyproject.toml 範例(摘自 uv 文檔):
text
[project] name = "my_project" version = "0.1.0" requires-python = ">=3.12.0" dependencies = [ "torch>=2.7.0", "torchvision>=0.22.0", "pytorch-triton-rocm>=3.3.0 ; sys_platform == 'linux'", ] [tool.uv.sources] torch = [ { index = "pytorch-rocm", marker = "sys_platform == 'linux'" }, ] [[tool.uv.index]] name = "pytorch-rocm" url = "https://download.pytorch.org/whl/rocm6.3" explicit = true
-
可針對各平臺分別設定不同索引和版本條件安裝。
-
uv 能根據作業系統自動選擇對應版本,較適合跨平台 GPU/CPU 自動處理。
3. 用環境變數或安裝腳本動態決定依賴
-
實務中,有些團隊會撰寫安裝腳本判斷是否有 GPU,然後用不同指令安裝相應版本,避免在套件定義檔內複雜判斷。
-
例如 bash 下:
bash
if nvidia-smi >/dev/null 2>&1; then pip install torch==2.0.1+cu118 torchvision==0.15.2+cu118 -f https://download.pytorch.org/whl/cu118/torch_stable.html else pip install torch==2.0.1+cpu torchvision==0.15.2+cpu fi
總結建議
| 方法 | 優點 | 缺點 | 適用情境 |
|---|---|---|---|
| 兩份 requirements.txt | 簡單直接,技術門檻低 | 安裝時需手動選檔,不自動判斷GPU | 小型專案或無專案管理工具時使用 |
| pyproject.toml + Poetry | 可設定依賴群組,條件化安裝,方便版本鎖定 | 設定稍複雜,安裝需明確指定群組 | 現代複雜專案,自動化和版本控管需求 |
| pyproject.toml + uv | 支援根據平臺條件切換索引與版本,自動化較好 | 仍在成長中,設定較新,需習慣工具 | 跨平台、高度自動化需求 |
| 安裝腳本判定與安裝 | 靈活,具體判斷GPU存在與否 | 需要額外腳本管理,不納入依賴管理工具 | 需要最大彈性或混合環境使用情境 |
補充說明
-
CPU 與 GPU 版本 PyTorch 通常是不同的 wheel 套件,需要從不同索引源(如 PyTorch 官方 CPU 或 CUDA wheel 源)安裝。這使得在同一依賴定義檔內自動判斷更不容易實作。
-
pyproject.toml目前屬於靜態依賴定義,對於跨硬體需求仍依賴工具的擴展(Poetry群組、uv索引條件)或外部判斷腳本配合。
Method 1: pip install -e .
如果沒有 pyproject.toml 或是 setupy.py, 必須先產生一個。 此處以 setup.py 爲例。
1 | |
接下來就執行下式,產生 minbpe 0.1 version.
1 | |
使用方法
1 | |
Appendix A uv sync --locked vs --frozen 的關鍵差異
--locked
“The project is re-locked before syncing unless the –locked or –frozen flag is provided”
- 檢查 lockfile 是否最新:確保
uv.lock與pyproject.toml同步 - 如果過期會失敗:如果 lockfile 過期,命令會報錯退出
- 適用場景:CI/CD 環境,確保依賴完全一致
1 |
|
--frozen
“To use the lockfile without checking if it is up-to-date, use the –frozen option”
- 不檢查 lockfile 狀態:直接使用現有的
uv.lock,不管是否過期 - 不會重新鎖定:完全按照現有 lockfile 安裝
- 適用場景:Docker 建構、生產部署
1 |
|
實際使用建議
開發階段
1 | |
CI/CD 測試
1 | |
生產部署 / Docker
1 | |
克隆別人的專案
1 | |
重要注意事項
“This doesn’t work due to: error: the argument ‘–frozen’ cannot be used with ‘–locked’”
--locked 和 --frozen 不能同時使用,它們是互斥的選項。
總結:--locked 是「嚴格模式」(必須最新),--frozen 是「信任模式」(直接使用現有)。
Appendix B - Activate-prj.sh
The activate-prj.sh script is a smart environment activation tool for Python projects using PyTorch that automatically detects the platform and hardware capabilities, sets up the appropriate virtual environment, and installs the correct PyTorch backend suited for the environment. Here is a detailed flow and purpose summary:
Purpose
- Automates detection of platform capabilities (Windows WSL2, Linux, macOS) and CUDA GPU availability.
- Sets up Python virtual environments tailored to the detected hardware (CUDA GPU or CPU).
- Ensures correct PyTorch backend (CPU or CUDA) is installed by setting the PyTorch package index in advance.
- Provides consistency and predictability for environment names and backend separation.
Flow Breakdown
- Project Detection:
- Extracts the current project name (e.g., “my-rag-chatbot”).
- Defines CUDA-specific environment name by appending
-cuda.
- Platform & CUDA Detection:
- If
nvidia-smitool exists and OS is Linux GNU, it detects a WSL2/Linux environment with NVIDIA GPU and enables CUDA environment. - Otherwise, if on macOS, it defaults to a CPU environment.
- For other platforms (e.g., cloud servers), uses a CPU environment.
- If
- Environment Path & PyTorch Index Selection:
| Platform | Env Path | PyTorch Index | Use Case |
|---|---|---|---|
| WSL2 + NVIDIA | ~/.venvs/project-cuda | https://download.pytorch.org/whl/cu121 | GPU acceleration |
| macOS | ~/.venvs/project | cpu | Apple Silicon/Intel CPUs |
| Other Linux | ~/.venvs/project | cpu | Cloud or server CPU usage |
- Virtual Environment Management:
- If environment does not exist, create it via
python3 -m venv. - Activate the environment using standard
source .../bin/activate.
- If environment does not exist, create it via
- Dependency Installation:
- Sets
UV_EXTRA_INDEX_URLenvironment variable to PyTorch index URL for installing the right backend. - Uses
uv sync --activeto install dependencies based onpyproject.toml.
- Sets
Key Benefits
- Automatic Platform Detection: No manual settings; works transparently across WSL2, macOS, Linux.
- Chicken-and-Egg Problem Solved: Detects environment before PyTorch install, ensuring correct version and backend.
- Environment Consistency: Predictable naming separating CUDA and CPU environments so projects remain clean and consistent.
Usage Pattern For New Projects
- Copy
activate-prj.shinto project root and make executable. - Declare PyTorch-dependent packages in
pyproject.toml. - Run the script (
./activate-prj.sh) to set up and activate environment with dependencies ready.
Adaptations
- Remove PyTorch index export for non-PyTorch projects.
- Adjust CUDA version suffix in environment and PyTorch index URLs if using different CUDA.
- Customize environment paths if needed.
Example Output When Run
1 | |