4、Docker 容器化环境搭建:Docker 与 Docker Compose 安装、拉取 PyTorch 官方镜像、编写 Dockerfile 定制环境、容器与宿主机文件/端口映射

说实话,搞大模型推理环境,最头疼的就是依赖冲突。

你装个 PyTorch,它要 CUDA 11.8;另一个项目非要 CUDA 12.1。来回折腾系统环境,我当年就吃过这个亏——有一次把显卡驱动搞崩了,重装系统花了一整天。后来我学乖了,所有项目都上 Docker。

Docker 说白了就是个轻量级虚拟机。但它比虚拟机快得多,因为它共享宿主机的内核。你想想看,一个容器启动只要几秒钟,资源开销几乎可以忽略不计。对于咱们搞大模型的人来说,Docker 能保证你的环境「一次构建,到处运行」。

4.1 Docker 与 Docker Compose 安装

先说说 Docker 怎么装。我个人习惯用官方脚本,省事。

# 一键安装 Docker(Ubuntu/Debian)
curl -fsSL https://get.docker.com | bash

# 验证安装
docker --version

# 把当前用户加入 docker 组,避免每次 sudo
sudo usermod -aG docker $USER
# 记得退出重新登录,或者执行 newgrp docker

嗯,这里要注意:如果你用的是 CentOS 或者 RHEL,官方脚本一样能用。但如果你在 Windows 上搞,我建议直接装 Docker Desktop,它自带 WSL2 后端,体验还不错。

Docker Compose 呢?它是用来编排多个容器的工具。比如你既要跑推理服务,又要跑数据库,用 Compose 可以一键启动所有服务。

# 安装 Docker Compose 插件(新版 Docker 自带)
docker compose version

# 如果没装,手动下载
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
我的小建议: 新版 Docker 已经把 Compose 集成进去了,直接用 docker compose(注意没有横杠)就行。别再用老版的 docker-compose 了,容易混淆。

4.2 拉取 PyTorch 官方镜像

Docker 装好了,下一步就是拉镜像。PyTorch 官方提供了很多预构建镜像,省得你自己从头装 CUDA、cuDNN 这些底层库。

# 拉取 PyTorch 官方镜像(带 CUDA 12.1)
docker pull pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime

# 拉取 PyTorch 官方镜像(带 CUDA 11.8)
docker pull pytorch/pytorch:2.1.0-cuda11.8-cudnn8-runtime

# 查看本地已有镜像
docker images

为什么我要列两个版本?因为不同显卡对 CUDA 版本有要求。比如 RTX 4090 必须用 CUDA 12.x,而 RTX 3090 用 CUDA 11.8 更稳定。我在项目中遇到过,有人用 4090 强行装 CUDA 11.8,结果训练速度反而变慢了——因为驱动要来回做兼容转换。

避坑指南: 我曾经因为镜像版本选错,浪费了半天时间。记住:-runtime 后缀的镜像只包含运行环境,适合部署;-devel 后缀的镜像包含开发工具链,适合编译自定义算子。如果你要跑推理,用 -runtime 就够了,镜像体积小一半。

4.3 编写 Dockerfile 定制环境

官方镜像虽然方便,但往往缺东西。比如你要装 transformers、accelerate 这些库,就得自己写 Dockerfile。

说白了,Dockerfile 就是一份「环境搭建说明书」。你告诉 Docker 要装什么、怎么装,它自动帮你构建镜像。

# 基础镜像:PyTorch 2.1.0 + CUDA 12.1
FROM pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime

# 设置工作目录
WORKDIR /app

# 安装系统依赖(比如 git、wget)
RUN apt-get update && apt-get install -y \
    git \
    wget \
    && rm -rf /var/lib/apt/lists/*

# 安装 Python 依赖
RUN pip install --no-cache-dir \
    transformers==4.36.0 \
    accelerate==0.25.0 \
    sentencepiece==0.1.99

# 复制项目代码到容器
COPY . /app

# 暴露端口(比如推理服务用 8000)
EXPOSE 8000

# 容器启动时执行的命令
CMD ["python", "inference.py"]

你可能会问:为什么用 --no-cache-dir?因为 pip 的缓存文件会增大镜像体积。我习惯在构建时加上这个参数,能让镜像小 200-300MB。

构建镜像:
# 在 Dockerfile 所在目录执行
docker build -t my-inference-env:latest .

# 查看构建好的镜像
docker images | grep my-inference-env

4.4 容器与宿主机文件/端口映射

镜像构建好了,怎么跑起来?这里有两个关键概念:文件映射端口映射

文件映射:容器里的文件默认是隔离的,容器删了数据就没了。所以你要把宿主机上的模型文件、代码目录挂载到容器里。

端口映射:容器内部的服务(比如推理 API)默认只能在容器内访问。你要把容器的端口映射到宿主机,才能从外部调用。

# 启动容器,带文件映射和端口映射
docker run -d \
  --name my-inference \
  --gpus all \
  -v /home/user/models:/app/models \
  -v /home/user/data:/app/data \
  -p 8000:8000 \
  my-inference-env:latest

解释一下参数:

  • -d:后台运行
  • --gpus all:让容器使用所有 GPU
  • -v /宿主机路径:/容器路径:文件映射,冒号左边是宿主机,右边是容器
  • -p 宿主机端口:容器端口:端口映射
我的习惯: 我会把模型文件放在 /data/models 目录下,代码放在 /data/code 目录下。这样即使容器删了重建,模型不用重新下载,代码也不用重新拷贝。你想想看,一个 7B 的模型文件十几 GB,每次重建容器都重新拷贝,那得多慢。

如果你用 Docker Compose,可以写成 YAML 文件,更方便管理:

version: '3.8'

services:
  inference:
    image: my-inference-env:latest
    container_name: my-inference
    runtime: nvidia
    volumes:
      - /home/user/models:/app/models
      - /home/user/data:/app/data
    ports:
      - "8000:8000"
    environment:
      - CUDA_VISIBLE_DEVICES=0,1
    restart: unless-stopped

启动方式:

docker compose up -d
注意: 如果你用的是旧版 Docker,runtime: nvidia 可能不生效。需要先安装 nvidia-container-toolkit
# 安装 NVIDIA 容器工具包
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker

4.5 本章知识体系

下面这张图总结了 Docker 容器化环境搭建的核心流程:

Docker 容器化环境搭建流程 安装 Docker curl 一键安装 安装 Docker Compose 编排多容器服务 安装 NVIDIA Toolkit GPU 容器支持 拉取 PyTorch 官方镜像 pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime 编写 Dockerfile 定制环境 安装 transformers、accelerate 等依赖 运行容器(文件映射 + 端口映射) -v /宿主机路径:/容器路径 -p 宿主机端口:容器端口 --gpus all docker run -d --name my-inference

整个流程其实就四步:装 Docker → 拉镜像 → 写 Dockerfile → 跑容器。每一步都有坑,但只要你按上面的步骤来,基本不会出问题。

我个人建议,刚开始接触 Docker 的同学,先别急着写复杂的 Dockerfile。先用官方镜像跑起来,看看效果,再慢慢加自己的依赖。这样出了问题也好排查——到底是镜像的问题,还是你加的东西有问题。

好了,这一章就到这里。记住:Docker 不是银弹,但它能解决 90% 的环境问题。剩下的 10%,嗯,那就要靠你慢慢积累了。