VLLM Docker 可以高效的部署大型语言模型(LLM),本教程将指导如何在容器中进行快速、可扩展的 LLM 推理的设置、优化等。

1] VLLM 和 Docker 简介

VLLM 指代的是”Versatile LLM”,它是一个开源库,旨在实现 GPT 和 LLaMA 等大型语言模型 (LLM) 的高吞吐量、低延迟推理。VLLM 的特长在于其先进的内存管理和执行速度优化技术,使开发者能够更高效地运行 LLM,尤其是在生产环境中优势则更加明显。VLLM 非常适合需要实时交互的场景,例如聊天机器人、智能助手和 AI 驱动的内容生成。

VLLM 的亮点在于其 PagedAttention 功能,它能够显著减少推理过程中的内存占用。这意味着用户可以在更小的硬件上运行更大的模型,这对于预算有限的初创公司或研究人员来说是一个巨大的优势。VLLM 还支持 Hugging Face 模型,这非常便利,因为它是当今最大的预训练模型库之一。

更为有优势的特点是,VLLM 的设计充分考虑了生产环境的需求——这意味着它可以与 GPU 完美兼容,扩展流畅,并具有令人印象深刻的延迟性能。因此,无论是构建聊天机器人还是部署每分钟数千个查询的模型,VLLM 都可以胜任。

Docker 是一款可靠的容器化工具,可简化应用程序在一致环境中的打包、部署和管理。与 VLLM 搭配使用时,Docker 的功能将更加强大。为什么?因为 LLM 通常需要复杂的设置——特定的依赖项、CUDA 版本、Python 包。而 Docker 可以帮助用户将所有这些捆绑到一个可移植的单元中。

以下是一些 VLLM 选择使用 Docker 的原因:

  • 隔离性:每个容器独立运行,避免版本冲突
  • 可移植性:一次构建,随处运行——可在本地机器、云服务器或 Kubernetes 集群上运行
  • 可扩展性:Docker 让用户更轻松地水平扩展 VLLM 容器
  • 安全性:容器可以独立保护和更新,确保部署安全
  • 可重复性:用户可以完美地复制自己环境,用于开发、测试和生产

如果真的想在实际应用程序中部署 LLM,那么将 VLLM Docker 化不仅是一个好主意,而且它还是可扩展、可维护的 AI 架构的基础。

2] 配置需求

系统要求

在进入最有趣的部分——在容器中启动 VLLM 之前,我们必须确保自己的系统已经准备就绪。VLLM 对性能要求极高,它需要 GPU、大容量 VRAM 和基于 Linux 的操作系统才能正常运行。以下是所需配置的细节:

  • 操作系统:Linux(推荐使用 Ubuntu 20.04 及以上版本)。Windows 系统可以使用 WSL2,但原生 Linux 更稳定
  • CPU:任何现代多核处理器。对于无需 GPU 的推理或模型管理任务,这都足够了
  • GPU:CUDA 计算能力 7.0 或更高版本的 NVIDIA GPU(例如 RTX 30/40 系列、A100)
  • RAM:对于大型模型,建议至少使用 32GB 的系统 RAM
  • VRAM:根据模型不同,预计需要 16GB 到 80GB 以上的 GPU VRAM
  • 磁盘空间:20GB 以上的可用存储空间,最好是 SSD,用于存储 Docker 镜像和模型

这不仅仅是一份清单,更是一份基本成功指南。忽略硬件环节或许不会破坏构建,但会让整个过程变得痛苦而缓慢。

工具和依赖项

让 VLLM 在 Docker 中运行需要一些关键工具。以下需要的一些基本工具:

  • Docker 引擎:版本 20.10 及以上(使用 docker –version 命令检查)
  • NVIDIA 驱动程序:已安装在主机上。使用 nvidia-smi 命令确认其正常运行
  • NVIDIA 容器工具包:支持 Docker 容器内的 GPU 访问
  • Python 3.8 及以上版本:运行 VLLM 脚本和推理所需
  • Git:用于克隆 VLLM 代码库或相关资源
  • CUDA 工具包和 cuDNN:通常与基础 Docker 镜像捆绑在一起,但主机系统应与容器 CUDA 版本匹配,以确保性能

我们还需要准备一个可靠的文本编辑器(比如 VS Code),并熟悉终端的使用方法。这些在技术上并非必需,但它们在调试容器或调整脚本时作用非常大。

3] 安装配置

安装 Docker 和 NVIDIA 容器工具包

只要仔细按照步骤操作,Docker 的安装非常简单。以下是在 Ubuntu(或基于 Debian 的系统)上安装和运行 Docker 的方法:

卸载历史版本(如果有):

$ sudo apt remove docker docker-engine docker.io containerd runc

设置软件库:

$ sudo apt update
$ sudo apt install ca-certificates curl gnupg

添加官方 GPG key:

$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

添加 Docker 软件库至系统:

$ echo \ 
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ 
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

安装 Docker 引擎:

$ sudo apt update
$ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

验证安装:

$ sudo docker run hello-world

运行后,见到”Hello from Docker!”,就表示 Docker 已经成功安装了。

安装 NVIDIA Container Toolkit 以获得 GPU 支持

通过 NVIDIA Container Toolkit 就可以启用容器内的 GPU 访问。操作方法如下:

安装工具包:

$ sudo apt install nvidia-container-toolkit

配置 Docker 使用 NVIDIA 运行时:

$ sudo nvidia-ctk runtime configure --runtime=docker

重启 Docker:

$ sudo systemctl restart docker

测试一个 GPU 容器:

$ sudo docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu20.04 nvidia-smi

如果最后一个命令打印了使用的 GPU 规格,那么我们就可以构建和运行具有 GPU 加速的 VLLM 容器了。

构建 VLLM 容器镜像

VLLM 最酷的一点是它已经提供了社区维护的 Dockerfile,有时甚至是官方推荐的。这些 Dockerfile 本质上是构建 Docker 镜像的模版。如果是 Docker 新手,可以将 Dockerfile 视为指导 Docker 安装哪些内容以及如何设置环境的”菜谱”。

我们可以在 VLLM 的 GitHub 或相关论坛上找到官方或社区 Dockerfile。它们通常包含正确的 CUDA 基础镜像,预安装常用的 Python 软件包(例如 transforms、torch 和 vllm),并正确配置了 GPU 支持。

典型的 Dockerfile 内容如下:

FROM nvidia/cuda:12.2.0-cudnn8-runtime-ubuntu20.04
RUN apt-get update && apt-get install -y \
    python3-pip \
    git \
    && rm -rf /var/lib/apt/lists/*
RUN pip3 install --upgrade pip
RUN pip3 install torch transformers vllm
CMD ["python3"]

我们可以使用如下命令来构建镜像:

$ docker build -t vllm:latest .

这将会为我们提供了一个干净、可重复的 VLLM 环境,我们可以在任何具有 Docker 和兼容 GPU 的机器上启动它。

个性化 Dokcerfile 以满足特定需求

有时默认的 Dockerfile 并不能完全满足需求。也许想添加特定模型、使用不同版本的 Torch 或安装其他实用程序。这时,自定义 Dockerfile 就变得非常方便。

假设我们想添加对 FastAPI 的支持来服务我们的模型:

RUN pip3 install fastapi uvicorn

需要预加载模型吗?可以直接从 Hugging Face 克隆它:

RUN git clone https://huggingface.co/tiiuae/falcon-7b-instruct /models/falcon-7b-instruct

或者,如果正在试验量化模型并希望添加对 bitsandbytes 的支持,只需修改 Dockerfile 即可:

RUN pip3 install bitsandbytes

这些调整可以帮助我们创建一个精简、高效且特定于模型的镜像,该镜像可以快速启动并完全按照要求运行。

高效 Docker 构建的技巧

为了避免镜像臃肿和构建时间过长,以下是制作专业 Docker 镜像的一些实用技巧:

  • 使用 .dockerignore:与 .gitignore 类似,此文件可防止不必要的文件被复制到 Docker 构建上下文中
  • 利用 Docker 层缓存:合理安排 RUN 和 COPY 命令,充分利用缓存层
  • 最小化基础镜像:除非绝对需要完整的 Ubuntu 发行版,否则请坚持使用精简的基础镜像
  • 组合命令:使用链式软件包安装以减小镜像大小
  • 使用多阶段构建:如果需要编译代码,请将其一次性完成,然后将最终结果复制到最小化镜像中

以下是优化后的代码片段:

RUN apt-get update && apt-get install -y --no-install-recommends \
    python3-pip git && \
    rm -rf /var/lib/apt/lists/*

较少的膨胀意味着更快的构建、更小的镜像尺寸和更快的部署。

Docker 容器中启动 VLLM

构建好 Docker 镜像后,运行它就非常简单了。下面是启动支持 GPU 的容器的命令:

$ docker run --rm -it --gpus all vllm:latest

如果要持久化数据或者挂载模型目录,可以使用卷挂载:

$ docker run --rm -it --gpus all \
  -v $(pwd)/models:/models \
  vllm:latest

如果模型通过 API(例如 FastAPI + Uvicorn)公开,则需要映射端口:

$ docker run --rm -it --gpus all -p 8000:8000 vllm:api

挂载卷和管理端口

使用 Docker 卷可以更轻松地管理容器内的数据。我们可以将模型存储在主机上,然后将其挂载到容器中:

$ docker run -v /local/models:/app/models vllm:latest

需要从容器外部访问 Web 服务器或 API?端口转发就是个好办法:

$ docker run -p 5000:5000 vllm:latest

使用这些技巧来简化开发。无需每次都重建容器,只需挂载更新后的文件即可!

使用 Docker Compose 简化部署

Docker Compose 就像一个指挥,它允许我们在一个 docker-compose.yml 文件中定义多个服务(例如模型服务器 + API 前端),并通过单个命令启动它们。

以下是 VLLM 的简单 docker-compose.yml 文件内容:

version: '3.8'
services:
  vllm:
    image: vllm:latest
    ports:
      - "8000:8000"
    volumes:
      - ./models:/models
    deploy:
      resources:
        reservations:
          devices:
            - capabilities: [gpu]

如果要启动它,只需要使用如下命令:

$ docker-compose up

然后,我们就可以一次性完成运行 VLLM、获得 GPU 支持、卷安装和公开端口等所有工作。

使用 VLLM 加载和运行语言模型

加载预训练模型

VLLM 的一大优点在于它可以轻松加载和运行海量语言模型,尤其是托管在 Hugging Face 上的模型。无论使用的是 GPT-2、Falcon、LLaMA 还是 Mistral,加载模型通常只需指定模型名称即可。

进入 VLLM 容器或环境后,以下是加载模型的示例脚本:

from vllm import LLM, SamplingParams
model = LLM(model="tiiuae/falcon-7b-instruct")  # Hugging Face model name
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)
prompt = "What are the benefits of containerizing AI models?"
outputs = model.generate(prompt, sampling_params)
print(outputs[0].text)

这非常强大——得益于 VLLM 实现的内存高效注意力机制和推理技术,只需几秒钟,我们就可以在消费级 GPU 上运行一个拥有十亿参数的模型。

如果我们想避免在每次启动容器时都下载模型,还可以在 Docker 镜像构建期间预加载模型。只需将它们克隆或 wget 到 models/ 文件夹中,并将 VLLM 指向该本地路径即可。

微调支持和推理优化

VLLM 的功能远不止推理,它还支持一些高级任务,例如提供微调模型或优化输出以降低延迟。虽然 VLLM 目前还不支持模型训练(这最好留给 Hugging Face Transformers 或 DeepSpeed 等库来做),但它可以出色地处理微调模型的推理。

想要运行微调后的 LLaMA 模型?只需指定本地路径即可:

LLM(model="/models/finetuned-llama")

为了进一步提升性能,VLLM 支持批处理和流式输出。我们可以使用以下功能微调推理流程:

  • 波束搜索
  • 温度采样
  • Top-k / Top-p 采样
  • 停止标记和最大标记限制

VLLM 还充分利用了标记级缓存和智能批处理,允许多个请求高效共享内存和资源。这显著提高了吞吐量,尤其是在生产环境中。

管理内在的资源分配

LLM 推理的一个常见问题是内存溢出——无论是 RAM 还是 VRAM。Docker 可以为我们提供对内存和 CPU 限制的精细控制。以下是如何限制 Docker 容器中的内存使用量:

$ docker run --gpus all --memory=16g --cpus=4 vllm:latest

这可以防止内存不足错误,并提高在共享主机上运行时容器的稳定性。

我们还可以利用 VLLM 的动态批处理功能,该功能允许在一次前向传递中高效处理多个提示。这不仅关乎性能,也关乎在生产环境中实时负载下的生存。

总之,VLLM Docker 是一个强大的组合。我们可以获得闪电般的推理速度、精简的部署以及传统方法无法比拟的可扩展性。无论是在构建下一代强大的 AI 助手、在实验室进行实验,还是扩展生产 API,容器化 VLLM 都能带来简便性、速度和安全性。

在大型语言模型重塑行业的时代,拥有强大的容器化设置已不再是可有可无的,而是至关重要的。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注