假设你需要将你的程序,包括python代码,conda环境,大模型权重,lora,甚至操作系统都打包部署在离线环境,那么这一篇可以给到一个通用的解决策略——Docker容器化部署

Docker的安装

首先,必须保证开发机和部署机(离线)都安装docker与nvidia-docker。

docker的安装操作如下

apt-get -y install apt-transport-https ca-certificates curl software-properties-common apt-get update
apt-get install -y docker-ce docker version # 检查是否安装成功

如果你的代码需要调用GPU,那你必须安装如下nvidia-docker,下面是安装示例。离线机的安装需要另想办法

# 设置存储库并安装依赖项
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

# 安装 NVIDIA Container Toolkit
sudo apt-get update
sudo apt-get install -y nvidia-docker2

安装后重启docker

systemctl restart docker

打包conda环境

首先,你需要一个较为纯净,但确保能够运行你的程序的conda环境。

首先安装打包工具

conda install conda-pack

用以下命令把需要用到的your_env_name环境打包为一个tar包env_name.tar.gz

conda pack -n your_env_name -o env.tar.gz

编写dockerfile

假设你的文件目录如下,这里以docker_vllm虚拟环境,gemma-2-2b-it模型为例,你需要创建一个Dockerfile:

WorkSpace
├─ docker_vllm.tar.gz
├─ Dockerfile
└─ gemma-2-2b-it
 └─ 一系列的模型文件

如果你不幸用了venv环境

强烈不建议使用venv环境,但如果之前已经用了,可以试试以下办法进行环境迁移

# 使用 Ubuntu 作为基础镜像
FROM ubuntu:20.04

# 设置工作目录
WORKDIR /app

# 复制 Conda 环境包、模型文件夹
COPY docker_vllm.tar.gz /app/docker_vllm.tar.gz
COPY gemma-2-2b-it /app/gemma-2-2b-it

# 更换为阿里云的 Ubuntu 镜像源
RUN sed -i 's|http://archive.ubuntu.com/ubuntu/|http://mirrors.aliyun.com/ubuntu/|g' /etc/apt/sources.list

# 更新包列表并安装编译工具
RUN apt-get update && apt-get install -y build-essential

# 安装 Miniconda
RUN apt-get install -y wget && \
    wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-latest-Linux-x86_64.sh -O /miniconda.sh && \
    bash /miniconda.sh -b -p /miniconda && \
    rm /miniconda.sh

# 设置 Conda 环境
ENV PATH="/miniconda/bin:$PATH"

# 解压 Conda 环境包
RUN mkdir /app/env
RUN tar -xzf docker_vllm.tar.gz -C /app/env

# 激活 Conda 环境并设置路径
ENV PATH="/app/env/bin:$PATH"

# 设置默认的 CUDA 设备和端口
ENV CUDA_VISIBLE_DEVICES=6
ENV PORT=12340

# 暴露端口
EXPOSE ${PORT}

# 运行命令
CMD ["sh", "-c", "python -m vllm.entrypoints.openai.api_server \
     --model=./gemma-2-2b-it \
     --served-model-name=gemma \
     --port=${PORT} \
     --max-num-seqs=64 \
     --gpu-memory-utilization=0.97 \
     --trust-remote-code \
     --max-model-len=2048"]

重点在于在容器内的虚拟环境也开一个同版本python的venv,然后把site-packages移过去

构建镜像

在Dockerfile同级目录下,通过以下命令构建镜像 docker_vllm

docker build -t docker_vllm .

构建完成后,启动命令如下:

docker run \
  --gpus all \
  --rm \
  -e CUDA_VISIBLE_DEVICES=0 \
  -e PORT=12345 \
  -p 12345:12345 \
  docker_vllm

解释一下各个参数的含义

--gpus all让容器能够访问所有GPU,--rm能够在容器运行后自动释放空间

CUDA_VISIBLE_DEVICES指定选择的卡号,12345是选择开放的端口号

打包并迁移

将 Docker 镜像保存为一个压缩包文件,以便在离线机器上加载:

docker save -o docker_vllm_image.tar docker_vllm

your_image_name.tar 文件复制到离线机器上,然后加载并运行:

docker load -i docker_vllm_image.tar

然后就可以调用上面的启动命令,启用服务

把模型和镜像分开

如果不希望将巨大无比的模型文件 gemma-2-2b-it 直接包含在 Docker 镜像中,可以使用 Docker 的卷(volume)来挂载该文件夹。在运行 Docker 容器时指定 -v--mount 参数来挂载一个本地目录到容器内的特定路径。

在上述的dockerfile中将以下行删除

COPY gemma-2-2b-it /app/gemma-2-2b-it

启动命令改为

docker run \
  -v /path/to/local/gemma-2-2b-it:/app/gemma-2-2b-it \
  --gpus all \
  --rm \
  -e CUDA_VISIBLE_DEVICES=0 \
  -e PORT=12345 \
  -p 12345:12345 \
  docker_vllm

容器集群管理Docker-Compose

大量的容器管理可能会很麻烦,Docker-Compose 是一个用于定义和运行多容器 Docker 应用的工具。

docker-compose的安装指令如下

curl -SL https://github.com/docker/compose/releases/download/v2.19.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose docker-compose version # 检查是否安装成功

通过使用 YAML 文件,可以简单地配置应用所需的服务,包括容器的镜像、网络、卷和环境变量等。

# docker-compose.yaml
version: '3.8'

services:
  # 这里是上面提到的gemma模型服务
  gemma_service:
    image: docker_vllm
    container_name: gemma_container
    volumes:
      - ./gemma-2-2b-it:/app/gemma-2-2b-it
    ports:
      - "12345:12345"
    environment:
      - CUDA_VISIBLE_DEVICES=6
      - PORT=12345
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: "all"
              capabilities: [gpu]
  # 后面可以编写其他服务
  other_service_1:
      ...
  other_service_2:
      ...

通过一条命令,Docker-Compose 可以启动或停止这些服务,方便地管理复杂的应用环境。

启动服务:使用 docker-compose up 命令。这将根据 docker-compose.yml 文件中的配置启动所有定义的服务。如果你希望在后台运行这些服务,可以添加 -d 选项,即 docker-compose up -d

停止服务:使用 docker-compose down 命令。这将停止并移除所有与 docker-compose.yml 文件中定义的服务相关的容器、网络和默认卷。

Docker和他的朋友们的下载方式(离线安装)

  • 注意事项

  1. 在需要安装的电脑终端使用release -a之类的操作查清楚操作系统版本,以及arm64还是amd64,再选择对应版本安装

  2. 这里的docker compose是插件版,使用命令为docker compose(不是docker-compose

Docker+Docker compose

https://download.docker.com/linux/ubuntu/dists/

Nvidia container toolkit

https://github.com/NVIDIA/nvidia-container-toolkit/releases

  • 这里提供某一版本的所有.deb

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐