Skip to content

Python 环境管理

Python 环境管理是 AI 工程的高频痛点。不同项目需要不同版本的 PyTorch、CUDA、依赖库,不隔离则互相冲突。本页对比 venv、conda、pip-tools、uv 四大主流方案,并补充 poetry、pyenv、nix 以及容器内环境管理策略。

Docker 容器化的内容见 Docker 容器化,本页侧重于 Python 层面的依赖隔离与锁定。

方案优势劣势适用场景
venvPython 内置、轻量、无额外依赖不管理 Python 版本本身、不支持非 pip 包纯 Python 小项目、快速原型
conda科学计算生态完善、可管理 CUDA/cudnn 等非 Python 依赖安装慢、体积大、channel 冲突数据科学、多 CUDA 版本切换
pip-tools生成精确锁文件(hash 锁定)、可复现需手动维护 .in 和 .txt 两套文件生产部署、严格要求可复现
uv极速(Rust 编写)、兼容 pip 接口、内置版本管理生态较新(2024 才广泛采用)新项目首选、CI 加速
poetry依赖管理+打包一体化、锁文件支持速度不如 uv、对 monorepo 支持弱中型纯 Python 项目
pyenv编译安装多版本 Python编译耗时长、需系统依赖需要切换 Python 版本的开发机
Terminal window
# 创建虚拟环境(在项目目录下)
python -m venv .venv
# 激活
source .venv/bin/activate # Linux/macOS
# .venv\Scripts\activate # Windows
# 安装依赖
pip install torch torchvision fastapi
# 导出依赖
pip freeze > requirements.txt
# 退出
deactivate

💡 将 .venv/ 加入 .gitignore,不要提交虚拟环境目录。只提交 requirements.txt 或 pyproject.toml。

conda 最大的优势是可以安装非 Python 的二进制依赖(如 CUDA toolkit、cudnn、mkl),这对深度学习尤为重要:

Terminal window
# 创建环境,同时指定 Python 版本和 CUDA
conda create -n dl python=3.11 -y
conda activate dl
# 从 conda-forge 安装(比 pip 更稳定编译好的科学计算包)
conda install pytorch torchvision pytorch-cuda=12.1 -c pytorch -c nvidia -y
# 导出环境(含 channel 和 build 信息,可精确复现)
conda env export --no-builds > environment.yml
# 从文件创建
conda env create -f environment.yml
Terminal window
# channel 优先级:从上到下优先级降低
conda config --add channels conda-forge # 最优先(社区维护,包最全)
conda config --add channels nvidia # CUDA 相关
conda config --add channels pytorch # PyTorch 官方
# 使用 strict 优先级(避免 channel 冲突)
conda config --set channel_priority strict
# 推荐用 mamba(C++ 实现的 conda,依赖解析快 10 倍)
mamba create -n dl python=3.11 pytorch -c pytorch -y

mamba 是 conda 的 C++ 重写版本,依赖解析速度大幅提升。micromamba 是单文件版本,无需 conda 即可使用:

Terminal window
# 安装 micromamba(单二进制文件)
curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest | tar -xvj bin/micromamba
# 用法与 conda 类似
micromamba create -n dl python=3.11 pytorch -c pytorch -y
micromamba activate dl

requirements.txt 中 torch>=2.0 这类范围声明无法保证精确复现。pip-tools 将声明文件(.in)和锁文件(.txt)分离:

Terminal window
pip install pip-tools
# requirements.in(你手动维护的范围声明)
# fastapi>=0.110
# torch>=2.2
# 编译生成锁文件(解析所有子依赖、锁定版本+hash)
pip-compile requirements.in -o requirements.txt
# 同步安装(按锁文件精确安装,移除多余包)
pip-sync requirements.txt

生成的锁文件包含完整依赖树和 hash,适合生产部署:

#
# This file is autogenerated by pip-compile with Python 3.11
# To update, run:
#
# pip-compile requirements.in
#
anyio==4.4.0 \
--hash=sha256:5aadc6a1bbb7cdb0bede2b625aabc6a1bbb7cdb0...
fastapi==0.115.0 \
--hash=sha256:8e5b482a1cf3a9f5e3a2b625a0e3108...
# via -r requirements.in

uv 由 astral.sh(ruff 的作者)用 Rust 编写,号称比 pip 快 10-100 倍,2024 年迅速成为 Python 社区最热门的工具。它兼具 pip、pip-tools、venv、pyenv 的功能,一个工具替代多个:

Package Install Speed Comparison

Terminal window
# 安装
curl -LsSf https://astral.sh/uv/install.sh | sh
# 创建项目(自动管理 Python 版本和虚拟环境)
uv init my-ai-project
cd my-ai-project
# 添加依赖(极快,带全局缓存)
uv add torch torchvision fastapi uvicorn
uv add --dev pytest ruff mypy
# 自动创建 .venv 并安装,无需手动 activate
uv run python train.py # 在项目环境中运行
uv run pytest # 在项目环境中运行测试
# 锁定并生成 lockfile(uv.lock,跨平台可复现)
uv lock
# 精确同步(按 lockfile 安装)
uv sync
# 管理 Python 版本(内置,不需要 pyenv)
uv python install 3.12
uv python list # 查看可用版本
# pyproject.toml(uv 使用标准 PEP 621 格式)
[project]
name = "my-ai-project"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
"torch>=2.3",
"fastapi>=0.110",
"uvicorn[standard]>=0.30",
]
[dependency-groups]
dev = [
"pytest>=8.0",
"ruff>=0.6",
]

💡 2025 年起新项目强烈推荐 uv。对于已有的 conda/venv 项目,也可以渐进迁移:先用 uv pip install 替代 pip install 获得加速,再逐步迁移到 uv add / uv sync 工作流。

Terminal window
# 替代 pip install(加速,但保持 pip 语义)
uv pip install torch torchvision
uv pip install -r requirements.txt
uv pip freeze
# 管理多个 Python 版本
uv python install 3.10 3.11 3.12 3.13
# 为项目指定 Python 版本
uv python pin 3.12
# 运行一次性脚本/工具(自动创建临时环境)
uvx ruff check . # 等价于 pipx run ruff check .
uvx black --version
# 导出为 requirements.txt(兼容传统部署)
uv export --format requirements-txt > requirements.txt

Poetry 是 Python 社区成熟的依赖管理+打包工具,提供完整的依赖解析、虚拟环境管理、打包发布功能。

Terminal window
# 安装
curl -sSL https://install.python-poetry.org | python3 -
# 新建项目
poetry new my-project
# 或在已有项目初始化
poetry init
# 添加依赖
poetry add torch fastapi
poetry add --group dev pytest ruff
# 安装(按 poetry.lock 精确安装)
poetry install
# 在虚拟环境中运行
poetry run python train.py
poetry run pytest
# 打包发布
poetry build # 生成 .tar.gz 和 .whl
poetry publish # 发布到 PyPI
# pyproject.toml(Poetry 格式)
[tool.poetry]
name = "my-project"
version = "0.1.0"
description = "AI inference service"
[tool.poetry.dependencies]
python = "^3.11"
torch = "^2.3"
fastapi = "^0.110"
[tool.poetry.group.dev.dependencies]
pytest = "^8.0"
ruff = "^0.6"
维度Poetryuv
速度较慢(Python 实现)极快(Rust 实现)
打包发布内置需配合 build 或 hatchling
Lockfilepoetry.lockuv.lock
Python 版本管理不支持内置
生态成熟度成熟(2018+)较新(2024+)

💡 2025 年起新项目推荐 uv;已有 Poetry 项目无需急于迁移,两者都支持 pyproject.toml 标准。

pyenv 用于在同一台机器上安装和切换多个 Python 版本(CPython、PyPy 等),弥补 venv 不管理 Python 本身的不足。

Terminal window
# 安装 pyenv
curl https://pyenv.run | bash
# 配置 shell(~/.bashrc)
export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
# 安装编译依赖(Ubuntu)
sudo apt install -y build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev libffi-dev liblzma-dev
# 安装 Python 版本(编译,耗时几分钟)
pyenv install 3.12.4
pyenv install 3.11.9
# 切换版本
pyenv global 3.12.4 # 全局
pyenv local 3.11.9 # 当前目录(生成 .python-version 文件)
pyenv shell 3.10.14 # 当前 shell
# 查看已安装版本
pyenv versions

💡 如果已经在用 uv,uv python install 已经可以替代 pyenv 的核心功能,且不需要编译。

Nix 是声明式的包管理器和构建系统,强调可复现性——同一个配置在任何机器上产出完全一致的环境,精确到每一个系统库的版本。

Terminal window
# 进入一个包含特定 Python 和库的临时 shell
nix-shell -p python311 python311Packages.torch python311Packages.fastapi
# shell.nix(项目级临时环境)
# 让 c
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
python311
python311Packages.torch
python311Packages.fastapi
cudaPackages.cudatoolkit
];
}
flake.nix
{
description = "AI project environment";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
in {
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
python311
python311Packages.torch
python311Packages.fastapi
];
};
});
}
Terminal window
nix develop # 进入开发环境
nix flake lock # 锁定所有依赖版本(精确到 Git commit hash)
优势劣势
极致可复现(精确到系统库版本)学习曲线极陡
声明式配置,可版本控制非标准 Linux 需要额外配置
可回滚(代际管理)社区生态不如 conda/pip 丰富
不污染系统全局存储空间占用较大

💡 Nix 适合追求极致可复现性的团队。大多数 AI 项目用 uv + Docker 已经足够。Nix 在 CI/CD 缓存、嵌入式交叉编译等场景有独特优势。

在 Docker 容器内运行 Python 项目时,环境管理策略需要考虑镜像大小、构建速度和可复现性。

最简单的方案,适合小型推理服务:

FROM python:3.11-slim
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . /app
WORKDIR /app
CMD ["python", "server.py"]

适合容器内有多个 Python 应用或需要分离系统工具与应用依赖:

FROM python:3.11-slim
# 创建虚拟环境
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . /app
WORKDIR /app
CMD ["python", "server.py"]

利用 uv 的极速安装缩短 CI 构建时间:

FROM python:3.11-slim
# 安装 uv(复制单二进制文件)
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
WORKDIR /app
COPY pyproject.toml uv.lock ./
# --frozen 严格按 lockfile 安装,不更新
# --no-cache 不保留缓存(减小镜像体积)
RUN uv sync --frozen --no-cache --no-dev
COPY . .
CMD ["uv", "run", "python", "server.py"]

策略 4:多阶段构建 + BuildKit 缓存

Section titled “策略 4:多阶段构建 + BuildKit 缓存”
# syntax=docker/dockerfile:1
FROM python:3.11-slim AS builder
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
WORKDIR /app
COPY pyproject.toml uv.lock ./
# 利用 BuildKit 缓存挂载,跨构建复用 uv 全局缓存
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev
# ===== 运行阶段 =====
FROM python:3.11-slim AS runtime
# 从构建阶段拷贝虚拟环境
COPY --from=builder /app /app
WORKDIR /app
ENV PATH="/app/.venv/bin:$PATH"
COPY . .
CMD ["python", "server.py"]
  1. 永远不要把 .venv/ 提交到 Git。用 .gitignore 排除,只提交依赖声明文件。
  2. CI/CD 中锁定依赖:用 pip-tools 或 uv 生成带 hash 的锁文件,避免”昨天还能跑今天挂了”的依赖漂移。
  3. 生产环境用锁文件,开发环境用范围声明:requirements.in / pyproject.toml 是声明,requirements.txt / uv.lock 是锁定。
  4. 容器内优先用 uv 或多阶段构建:加速 CI 构建、减小镜像体积。
  5. conda channel 要固定优先级:用 channel_priority strict 避免 channel 冲突导致的版本混乱。
  • uv 全面普及:2024 年初发布 0.1 版本,到 2025 年已成为新项目事实标准。Rust 实现的依赖解析和安装速度远超 pip,内置 Python 版本管理、虚拟环境、lockfile,一个工具替代 pip + pip-tools + venv + pyenv。PyTorch、Hugging Face 等头部项目文档已推荐 uv。
  • uv 替代 pip 的趋势:CI/CD 中 uv pip install 比 pip install 快 10 倍以上,大幅缩短流水线时间。2025 年起,大量开源项目将贡献者指南从 pip install -e . 改为 uv sync。
  • Rust 编写的工具链崛起:uv(包管理)、ruff(lint+format,替代 flake8+black+isort)、mypy 的 Rust 后端替代品(ty)——Python 工具链正在经历 Rust 重写潮,速度提升 10-100 倍。
  • PEP 723 内联脚本依赖:Python 3.12+ + uv 支持在单个 .py 文件头部声明依赖(# /// script),用 uv run script.py 自动安装运行,适合一次性脚本和分享代码。
  • conda-forge 成为默认 channel:Anaconda 的 defaults channel 因商业授权争议,2024-2025 年社区加速向 conda-forge 迁移,配合 micromamba 获得更快体验。
术语英文解释
虚拟环境virtual environment (venv)隔离 Python 依赖的目录,避免全局污染
锁文件lockfile精确记录每个依赖版本(及 hash)的文件,保证可复现安装
Channel(conda)channelconda 的包仓库来源(如 conda-forge、nvidia、pytorch)
声明文件manifest / requirements.in手动维护的依赖范围声明,编译后生成锁文件
代际管理generation managementNix 的可回滚机制,每次修改环境生成一个新代际