不用 Conda,如何优雅地为不同项目切换 CUDA 版本

792 阅读5分钟

在深度学习、科学计算等领域,CUDA 是不可或缺的加速工具。然而,随着项目增多,不同项目往往依赖不同版本的 CUDA 工具链(如 nvcc)。如果你无法使用 Conda(如因授权、政策等原因),如何优雅地在同一台 Ubuntu 机器上为不同项目隔离 CUDA 版本,避免系统依赖冲突?本文将为你解答。


一、问题背景

1.1 多 CUDA 版本共存的需求

  • 典型场景
    • 项目 foo 需要 CUDA 11.8,项目 bar 需要 CUDA 12.2。
    • 系统上已预装 CUDA 11.8,但不希望全局替换,只希望 foo 项目用 CUDA 12.2。
  • 常见痛点
    • nvcc、libcuda.so 等工具和库默认全局唯一,切换版本容易影响其他项目或系统环境。
    • Conda 虽然能隔离 CUDA,但部分企业或高校无法使用。

1.2 目标

  • 实现项目级 CUDA 版本隔离,即只影响当前项目,不影响系统或其他项目。

二、主流解决方案综述

本文将介绍三种主流的无 Conda 方案:

  1. 虚拟环境 + 环境变量覆盖(推荐,轻量高效,适合 Python 项目)
  2. Docker 容器化(强隔离,适合需要高度可复现的环境)
  3. 符号链接切换(简易但有全局影响,需谨慎使用)

三、方案一:虚拟环境 + 环境变量覆盖(推荐)

3.1 原理

  • 通过修改项目虚拟环境的激活脚本,临时覆盖 PATHLD_LIBRARY_PATH,让项目优先使用指定版本的 CUDA 工具链和库。
  • 只影响当前虚拟环境,退出后恢复系统默认。

3.2 步骤详解

步骤 1:安装目标 CUDA 版本

假设你需要 CUDA 12.2(系统已有 CUDA 11.8):

# 下载官方 run 文件,安装到指定目录
sudo sh cuda_12.2.0_*.run --toolkit --silent --override
# 默认安装路径为 /usr/local/cuda-12.2

步骤 2:创建 Python 虚拟环境

python3 -m venv .venv

步骤 3:修改虚拟环境激活脚本

编辑 .venv/bin/activate,在末尾添加:

export PATH=/usr/local/cuda-12.2/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-12.2/lib64:$LD_LIBRARY_PATH

步骤 4:激活虚拟环境并验证

source .venv/bin/activate
nvcc --version  # 应显示 CUDA 12.2
python -c "import torch; print(torch.version.cuda)"  # 检查 PyTorch CUDA 版本
deactivate
nvcc --version  # 恢复为系统默认 CUDA 版本

3.3 优点与适用场景

  • 优点:无需 root 权限,操作简单,适合 Python 项目。
  • 适用场景:大部分 Python + CUDA 项目开发、测试、部署。

3.4 注意事项

  • 需确保 CUDA 驱动版本兼容所有 CUDA Toolkit 版本。
  • 若依赖 C++/CMake 编译,CMake 也会自动使用当前 PATH 下的 nvcc。

四、方案二:Docker 容器化(强隔离)

4.1 原理

  • 利用 Docker 容器,将 CUDA 工具链、依赖、项目代码全部打包,彻底隔离于宿主机。
  • NVIDIA 官方提供多版本 CUDA 镜像,支持 GPU 直通。

4.2 步骤详解

步骤 1:安装 Docker 与 NVIDIA Container Toolkit

sudo apt install docker.io
sudo apt install nvidia-container-toolkit
sudo systemctl restart docker

步骤 2:编写 Dockerfile

FROM nvidia/cuda:12.2.0-runtime-ubuntu22.04
WORKDIR /workspace
COPY . .
RUN apt-get update && apt-get install -y python3 python3-pip
RUN pip3 install -r requirements.txt

步骤 3:构建镜像

docker build -t foo-cuda122 .

步骤 4:运行容器

docker run --gpus all -it -v $(pwd):/workspace foo-cuda122

4.3 优点与适用场景

  • 优点:环境完全隔离,跨平台可移植,适合生产部署和团队协作。
  • 适用场景:深度学习训练、云端部署、多人协作开发。

4.4 注意事项

  • 需安装 NVIDIA 驱动和 nvidia-docker 支持。
  • 镜像体积较大,首次构建耗时较长。

五、方案三:符号链接切换(全局影响,需谨慎)

5.1 原理

  • 通过修改 /usr/local/cuda 的符号链接,快速切换系统默认 CUDA 版本。
  • 适合单用户、单项目开发机,不推荐多项目并行场景

5.2 步骤详解

步骤 1:安装多个 CUDA 版本

# 假设已安装 /usr/local/cuda-11.8 和 /usr/local/cuda-12.2

步骤 2:切换符号链接

sudo ln -sf /usr/local/cuda-12.2 /usr/local/cuda

步骤 3:验证

nvcc --version  # 应显示 CUDA 12.2

5.3 优点与适用场景

  • 优点:切换简单,适合快速测试。
  • 缺点:全局影响,易引发依赖冲突,不适合团队开发。

六、方案对比与选择建议

方案隔离性是否需 root复杂度适用场景
虚拟环境 + 环境变量Python 项目开发与测试
Docker生产部署、团队协作、复现需求
符号链接单用户、单项目临时切换

推荐:

  • 日常开发、测试优先用虚拟环境 + 环境变量
  • 生产部署、多人协作优先用Docker
  • 临时测试可用符号链接切换,但需注意全局影响

七、常见问题与补充说明

7.1 CUDA 驱动与 Toolkit 兼容性

  • 驱动版本需大于等于最高所需 CUDA 版本的要求。
  • 驱动无需多版本共存,只需升级到最高版本。

7.2 Python 包的 CUDA 版本兼容

  • 安装 PyTorch、TensorFlow 等包时,需选择对应 CUDA 版本的 wheel 包。
  • 可通过 pip install torch==+cu122 指定 CUDA 版本。

7.3 多人协作的最佳实践

  • 建议将环境变量配置脚本、Dockerfile 等纳入项目版本控制,便于团队成员一致复现。

八、结语

即使无法使用 Conda,你依然可以通过虚拟环境结合环境变量、Docker 容器等方式,实现项目级 CUDA 版本隔离。根据实际需求选择合适方案,不仅能解决依赖冲突,还能提升开发效率和环境可复现性。希望本文能帮助你优雅应对 CUDA 多版本管理难题!