vLLM 实战:从本地 CPU Docker 部署到 Google Cloud Serverless

本文将手把手带你走完 vLLM 的部署流程。我们将学习如何使用 Docker 在本地 CPU 环境(包括 ARM 架构的 Mac)中运行大模型,并进一步将其部署到 Google Cloud Run,实现一个可扩展的 Serverless 推理服务。

阅读时长: 6 分钟
共 2769字
作者: eimoon.com

想在自己电脑上跑个大模型,但又被复杂的环境配置和昂贵的 GPU 劝退?vLLM 可能是个不错的答案。它是一个为大模型推理设计的高性能库,最吸引人的一点是它兼容 OpenAI 的 API 格式,这意味着你可以几乎无缝地用自托管的模型替换掉原来调用 OpenAI 的代码。

这篇文章,我们就来动手走一遍,看看怎么用 Docker 在我们自己的电脑上(就算是纯 CPU)把 vLLM 跑起来,然后再把它部署到 Google Cloud 上,变成一个随时可用的云服务。

在本地用 Docker 和 CPU 跑 vLLM

vLLM 的官方文档主要是围绕 CUDA 环境,也就是 NVIDIA GPU 来优化的。但对我们大多数人来说,手头可能并没有高端 GPU。好在 vLLM 官方也提供了 CPU 版本的 Docker 镜像,让我们可以在没有 CUDA 环境的情况下也能玩起来。

使用 Docker 的好处是显而易见的:它把所有乱七八糟的依赖项都打包好了,我们不用再头疼环境配置问题,可以专注于模型本身。

第一步:构建 Docker 镜像

首先,我们需要从 vLLM 的官方仓库里构建一个 Docker 镜像。他们很贴心地为不同 CPU 架构准备了不同的 Dockerfile。

  • Dockerfile.cpu:用于常规的 x86 架构 CPU。
  • Dockerfile.arm:用于 ARM 架构的 CPU,比如新款的苹果 Mac。

我用的是 M2 芯片的 Mac,所以选择 .arm 文件。先把项目克隆下来,然后在项目根目录里执行下面的命令:

docker build -f Dockerfile.arm -t vllm-cpu --shm-size=4g .

简单解释一下这个命令:

  • docker build:构建镜像的命令。
  • -f Dockerfile.arm:指定使用的 Dockerfile 文件。
  • -t vllm-cpu:给镜像打个标签,方便后面引用,名字可以随便取。
  • --shm-size=4g:分配 4GB 的共享内存,这对提升性能有帮助。

第二步:准备 Hugging Face Token

vLLM 需要从 Hugging Face Hub 上拉取模型,所以我们需要准备一个 Token。

  1. 注册账号:如果还没有,去 Hugging Face 官网 注册一个。
  2. 申请模型访问权限:有些模型(比如 Meta 的 Llama 系列)需要先在模型页面上申请访问权限。本文我们用 meta-llama/Llama-3.2-1B-Instruct 这个小模型做演示,记得先去它的主页同意相关条款。
  3. 创建 Token:在你的 Hugging Face 个人设置里找到 Access Tokens 页面,创建一个新的 Token,并把它复制下来。

第三步:启动 Docker 容器

万事俱备,现在可以用一行命令启动我们的模型服务了:

docker run -it --rm -p 8000:8000 \
--env "HUGGING_FACE_HUB_TOKEN=<你的HF_TOKEN>" \
vllm-cpu --model meta-llama/Llama-3.2-1B-Instruct \
--dtype float16

我们来拆解一下这个命令:

  • docker run:运行一个容器。
  • -it:以交互模式运行,并分配一个终端。
  • --rm:容器停止后自动删除,适合临时测试。
  • -p 8000:8000:把容器的 8000 端口映射到我们电脑的 8000 端口。
  • --env "HUGGING_FACE_HUB_TOKEN=...":通过环境变量把我们刚才创建的 Hugging Face Token 传进去。记得替换成你自己的 Token。
  • vllm-cpu:指定使用我们刚才构建的镜像。
  • --model meta-llama/Llama-3.2-1B-Instruct:指定要加载的模型。
  • --dtype float16:在 CPU 上运行时,模型通常要求使用 float16 数据类型。

第一次运行会比较慢,因为它需要从网上下载模型文件。当你在终端看到类似下面的输出时,就说明服务启动成功了:

INFO:     Started server process [1]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

和本地模型交互

vLLM 的 API 服务完美兼容 OpenAI 的格式,这意味着我们可以直接用 openai 这个 Python 库来和它交互,几乎不用改代码。

from openai import OpenAI

# vLLM 默认不需要 API key,设为 "EMPTY" 即可
openai_api_key = "EMPTY"
# 指向我们本地启动的服务
openai_api_base = "http://localhost:8000/v1"

client = OpenAI(
    api_key=openai_api_key,
    base_url=openai_api_base,
)

models = client.models.list()
model = models.data[0].id

completion = client.chat.completions.create(
    model=model,
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Hello"},
    ]
)

print(completion.choices[0].message.content)

如果你想给自己的服务加个简单的认证,可以在启动容器时加上 --api-key 参数,比如 --api-key supersecretkey,然后在 Python 代码里把 openai_api_key 设成对应的值就行了。

部署到 Google Cloud

本地跑通了,下一步就是把它部属到云上,让任何人都能访问。这里我们选择 Google Cloud Run,这是一个 Serverless 服务,可以直接运行我们的 Docker 容器,按需计费,非常方便。

第一步:创建 Google Cloud 项目和仓库

  1. 创建项目:登录 Google Cloud Console,创建一个新项目,比如叫 vllm-demo
  2. 启用 Artifact Registry:Artifact Registry 是 Google Cloud 用来存放 Docker 镜像的地方。在控制台搜索 “Artifact Registry” 并为你的项目启用它。
  3. 创建仓库:在 Artifact Registry 中创建一个新的仓库,格式选择 “Docker”,区域可以选 us-central1,给仓库起个名字,比如 vllm-cpu

第二步:构建并推送 Docker 镜像

这一步我们直接在 Google Cloud Shell 里操作,可以省去本地配置 gcloud CLI 的麻烦。

  1. 打开 Cloud Shell:在控制台右上角找到并点击 “Activate Cloud Shell” 图标。
  2. 克隆 vLLM 仓库
    git clone https://github.com/vllm-project/vllm.git
    cd vllm
    
  3. 构建镜像:这次构建镜像时,需要打上符合 Google Artifact Registry 格式的标签。
    # 格式: <区域>-docker.pkg.dev/<项目ID>/<仓库名>/<镜像名>:<标签>
    docker build \
    -t us-central1-docker.pkg.dev/vllm-demo/vllm-cpu/vllm-openai:latest \
    -f Dockerfile.cpu .
    
  4. 推送镜像:把构建好的镜像推送到我们的仓库。
    docker push us-central1-docker.pkg.dev/vllm-demo/vllm-cpu/vllm-openai:latest
    

第三步:在 Cloud Run 上创建服务

镜像已经上传到云端,现在可以用它来创建一个 Cloud Run 服务了。

  1. 在控制台搜索并进入 “Cloud Run”,点击 “Create Service”。

  2. 选择镜像:选择我们刚刚推送的那个镜像。

  3. 配置服务

    • 端口:将容器端口(Container port)设置为 8000
    • 资源分配:在 “Container, Variables & Secrets” 标签页下,给容器分配足够的资源。对于一个小模型,建议至少分配 4 个 vCPU16 GiB 内存
    • 环境变量:在 “Variables & Secrets” 中,添加一个名为 HUGGING_FACE_HUB_TOKEN 的环境变量,值就是你的 Hugging Face Token。
    • 容器参数:在 “Args” 部分,添加启动参数,比如 --model=meta-llama/Llama-3.2-1B-Instruct
    • 实例数:为了避免冷启动(第一次请求时下载模型会很慢),可以在 “Autoscaling” 设置里将 “Minimum number of instances” 设为 1。这会增加成本,但能保证服务随时可用。
  4. 点击 “Create”,等待服务部署完成。部署成功后,Cloud Run 会提供一个公开的 URL,这就是我们跑起来的的模型的 API 地址。

和云端模型交互

交互方式和本地完全一样,只需要把 Python 代码中的 openai_api_base 换成 Cloud Run 提供的 URL 就行了。

# 换成你的 Cloud Run 服务 URL
openai_api_base = "https://your-service-url.run.app/v1"

重要:成本提醒

请注意! 在云上保留资源是会持续产生费用的。特别是 Artifact Registry 的存储费和 Cloud Run 设置了最小实例数后的运行费用。实验结束后,一定记得删除 Cloud Run 服务、删除 Artifact Registry 中的镜像,或者直接关闭项目,避免产生不必要的账单。

其他选择

  • Google Cloud GPU:Cloud Run 目前也开始提供 GPU 支持(可能需要申请)。如果能用上 GPU,性能会好得多,而且可以直接使用官方优化好的 vllm/vllm-openai:latest 镜像,省去自己构建的步骤。
  • RunPod:如果你觉得上面这些步骤还是太繁琐,可以看看 RunPod 这样的平台。它们提供一键式的 Serverless 部署方案,非常方便,当然,方便的代价通常是价格会高一些。

总结

vLLM 确实降低了自托管大模型的门槛。从本地 CPU 环境的 Docker 实验,到云端的 Serverless 部署,整个流程走下来其实相当顺畅。这为很多中小型项目和个人开发者探索大模型的应用打开了新的可能性。

接下来,你或许可以试试换个自己感兴趣的模型,或者把它集成到你的下一个应用里去。

关于

关注我获取更多资讯

公众号
📢 公众号
个人号
💬 个人号
使用 Hugo 构建
主题 StackJimmy 设计