2. 环境准备

说实话,搭建推理服务这件事,百分之六十的坑都出在环境上。我见过太多人代码写得漂亮,结果在环境配置上卡了两三天。这一章咱们就把地基打牢——Python虚拟环境、CUDA/cuDNN、Docker,这三样东西搞明白了,后面就顺了。

本章核心目标:让你能在自己的机器上,干净、可复现地搭建一套推理服务开发环境。不污染系统,不依赖别人,随时可以重来。

2.1 Python虚拟环境:为什么你需要它?

你想想看,一个项目要PyTorch 1.13,另一个要PyTorch 2.0,还有的要TensorFlow。如果全装到系统Python里,不出三个月,你的pip list就会变成一团乱麻。

虚拟环境就是干这个的——每个项目有自己独立的Python解释器和包空间,互不干扰。

2.1.1 方案一:conda(推荐新手)

我个人习惯用conda管理深度学习环境。原因很简单:它不光管Python包,还能管CUDA、cuDNN这些底层库。省心。

安装Miniconda(轻量版,够用):

# 下载安装脚本
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh

# 运行安装
bash Miniconda3-latest-Linux-x86_64.sh

# 按提示走,默认路径就行
# 安装完后重新打开终端,或者 source ~/.bashrc

验证安装:

conda --version
# 输出类似:conda 23.11.0

创建虚拟环境:

# 创建一个叫 inference_env 的环境,Python 3.10
conda create -n inference_env python=3.10

# 激活环境
conda activate inference_env

# 这时候你的终端前面会多一个 (inference_env) 前缀

小技巧:我习惯把环境名和项目名保持一致。比如项目叫llm-server,环境就叫llm-server-env。这样半年后回来,一看名字就知道是干什么的。

常用conda命令速查:

操作 命令
创建环境 conda create -n 环境名 python=版本号
激活环境 conda activate 环境名
退出环境 conda deactivate
查看所有环境 conda env list
删除环境 conda remove -n 环境名 --all
导出环境配置 conda env export > environment.yml
从配置恢复环境 conda env create -f environment.yml

2.1.2 方案二:venv(轻量级选择)

如果你不想装conda,或者只是做个小项目,Python自带的venv就够了。它更轻,但不管CUDA这些底层东西。

# 创建虚拟环境
python3 -m venv myenv

# 激活
source myenv/bin/activate

# 退出
deactivate

注意:venv创建的虚拟环境就在项目目录下。我建议把它加到.gitignore里,别提交到代码仓库。曾经有个同事把整个venv目录推上去了,几百兆,review的时候大家都沉默了。

2.2 CUDA与cuDNN安装:让GPU跑起来

推理服务要跑在GPU上,CUDA是绕不过去的。说白了,CUDA是NVIDIA给GPU写的编程接口,cuDNN是专门优化深度学习计算的加速库。

2.2.1 先看你的显卡支持什么

# 查看显卡型号和驱动信息
nvidia-smi

# 重点关注:
# - Driver Version: 驱动版本
# - CUDA Version: 驱动支持的最高CUDA版本

举个例子,如果你看到CUDA Version: 12.2,那你可以装CUDA 12.x系列的任何版本,但不能装CUDA 11.x。

我的经验:别追最新版。CUDA 11.8和12.1是目前最稳的两个版本,PyTorch、TensorFlow对它们的支持也最好。我曾经手欠装了CUDA 12.3,结果某个库死活装不上,折腾了半天才降回去。

2.2.2 安装CUDA Toolkit

我推荐用runfile方式安装,灵活,可以指定路径。

# 从NVIDIA官网下载对应版本的runfile
# 以CUDA 11.8为例
wget https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda_11.8.0_520.61.05_linux.run

# 运行安装
sudo sh cuda_11.8.0_520.61.05_linux.run

# 安装时注意:
# - 不要安装驱动(Driver),只选CUDA Toolkit
# - 安装路径用默认的 /usr/local/cuda-11.8

配置环境变量:

# 加到 ~/.bashrc 或 ~/.zshrc
export PATH=/usr/local/cuda-11.8/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-11.8/lib64:$LD_LIBRARY_PATH

# 生效
source ~/.bashrc

# 验证
nvcc --version

2.2.3 安装cuDNN

cuDNN需要注册NVIDIA开发者账号才能下载。别嫌麻烦,注册一下就行。

# 下载 cuDNN for CUDA 11.x 的 tar 包
# 解压
tar -xzvf cudnn-linux-x86_64-8.9.7.29_cuda11-archive.tar.xz

# 复制到CUDA目录
sudo cp cudnn-*-archive/include/cudnn*.h /usr/local/cuda-11.8/include/
sudo cp -P cudnn-*-archive/lib/libcudnn* /usr/local/cuda-11.8/lib64/

# 设置权限
sudo chmod a+r /usr/local/cuda-11.8/include/cudnn*.h
sudo chmod a+r /usr/local/cuda-11.8/lib64/libcudnn*

# 验证
cat /usr/local/cuda-11.8/include/cudnn_version.h | grep CUDNN_MAJOR -A 2

避坑指南:CUDA和cuDNN的版本必须匹配。比如CUDA 11.8配cuDNN 8.9.x,CUDA 12.1配cuDNN 9.x。我曾经图省事,随便下了个cuDNN版本,结果训练时一直报错,查了半天才发现是版本不匹配。

2.3 Docker基础操作:环境打包带走

Docker解决的是"在我机器上能跑"的问题。你把环境、代码、依赖全部打包成一个镜像,别人拉下来就能跑,不用再配一遍环境。

2.3.1 安装Docker

# Ubuntu/Debian
sudo apt update
sudo apt install docker.io

# 启动Docker服务
sudo systemctl start docker
sudo systemctl enable docker

# 把当前用户加入docker组(避免每次sudo)
sudo usermod -aG docker $USER

# 重新登录终端生效

验证:

docker --version
docker run hello-world

2.3.2 核心概念速览

我画了张图,帮你快速理解Docker的核心逻辑:

Docker核心概念关系图 Dockerfile 构建脚本(配方) Image(镜像) 只读模板 Container(容器) 运行中的实例 Registry(仓库) 存储/分发镜像 push / pull 💡 工作流程: 写 Dockerfile → docker build 生成 Image → docker run 启动 Container 需要分享时:docker push 到 Registry → 别人 docker pull 下来直接运行

2.3.3 常用Docker命令

操作 命令 说明
查看镜像 docker images 列出本地所有镜像
查看运行中的容器 docker ps 加 -a 看所有容器(含已停止的)
拉取镜像 docker pull 镜像名:标签 比如 docker pull pytorch/pytorch:2.1.0-cuda11.8-cudnn8-runtime
运行容器 docker run -it 镜像名 /bin/bash -it 交互模式,退出后容器停止
后台运行 docker run -d --name 容器名 镜像名 -d 后台运行,--name 指定名字
进入运行中的容器 docker exec -it 容器名 /bin/bash 不中断容器运行
停止容器 docker stop 容器名
删除容器 docker rm 容器名 加 -f 强制删除运行中的
删除镜像 docker rmi 镜像名

2.3.4 一个简单的Dockerfile示例

咱们写一个推理服务的基础镜像:

# 基础镜像:PyTorch官方提供的CUDA 11.8环境
FROM pytorch/pytorch:2.1.0-cuda11.8-cudnn8-runtime

# 设置工作目录
WORKDIR /app

# 安装系统依赖
RUN apt-get update && apt-get install -y \
    git \
    curl \
    && rm -rf /var/lib/apt/lists/*

# 复制项目文件
COPY requirements.txt .
COPY src/ ./src/

# 安装Python依赖
RUN pip install --no-cache-dir -r requirements.txt

# 暴露端口
EXPOSE 8000

# 启动命令
CMD ["python", "src/server.py"]

构建和运行:

# 构建镜像
docker build -t my-inference-service:v1 .

# 运行容器,映射端口,挂载数据卷
docker run -d \
  --name inference-server \
  -p 8000:8000 \
  -v /path/to/models:/app/models \
  --gpus all \
  my-inference-service:v1

我的习惯:每次改代码后,重新build镜像太慢。我一般用 -v 挂载代码目录,这样改代码不用重新build,容器里直接生效。等代码稳定了,再打一个正式镜像。

2.4 本章小结

环境准备这块,说白了就三件事:

  • Python虚拟环境——用conda或venv把项目隔离开,别互相污染
  • CUDA/cuDNN——版本匹配是关键,别追新,求稳
  • Docker——把环境打包,走到哪跑到哪

这些东西配好了,后面写代码、部署推理服务的时候,你就不会在环境问题上浪费时间了。我见过太多人,模型写得挺好,结果部署时发现CUDA版本不对,又从头配环境,一搞就是半天。