vLLM因其出色的GPU吞吐量而闻名,但在某些场景下(如本地开发、功能测试或资源受限的环境),用户可能需要在纯CPU上运行vLLM服务。虽然性能远不如GPU,但通过正确的配置,我们依然可以利用vLLM的简洁API和高效加载机制在CPU上启动模型。
本文将详细指导如何通过Docker环境,强制vLLM在没有CUDA设备的情况下加载模型并提供推理服务。
前提条件
- 已安装Docker环境。
- 已准备一个Hugging Face格式的大语言模型(例如Llama-2 7B)。
核心原理:禁用CUDA可见性
vLLM的Docker镜像通常基于包含CUDA运行时和驱动的基镜像构建。要在CPU上运行,我们必须通过设置环境变量来告知容器内部的PyTorch和vLLM运行时,它们不应该使用任何GPU设备。
关键的环境变量是 CUDA_VISIBLE_DEVICES=””。
第一步:准备模型路径
为了让容器能够访问本地的模型文件,我们需要使用Docker的卷挂载(Volume Mount)。假设你的模型文件存储在本地路径 ~/models/llama-2-7b。
第二步:启动vLLM CPU服务
我们将使用vLLM官方提供的支持OpenAI API的Docker镜像。在启动命令中,我们需要特别注意 -e CUDA_VISIBLE_DEVICES=”” 参数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 # 替换为你本地的模型路径
LOCAL_MODEL_DIR=/path/to/your/llama-2-7b
# 容器内部的模型路径,建议使用 /app/models/your_model_name
CONTAINER_MODEL_PATH=/app/models/llama-2-7b
# 运行Docker容器
docker run -d \
--name vllm-cpu-server \
-v ${LOCAL_MODEL_DIR}:${CONTAINER_MODEL_PATH} \
-p 8000:8000 \
-e CUDA_VISIBLE_DEVICES="" \
vllm/vllm-openai:latest \
--model ${CONTAINER_MODEL_PATH} \
--host 0.0.0.0 \
--port 8000 \
--tensor-parallel-size 1 \
--dtype auto
# 注意:在CPU模式下,vLLM可能会自动或需要额外的配置来确保使用CPU后端,
# 设定 CUDA_VISIBLE_DEVICES="" 是最直接的强制CPU fallback方法。
命令解析:
- -e CUDA_VISIBLE_DEVICES=””: 这是核心。它将CUDA设备列表设置为空,强制PyTorch和vLLM使用CPU作为设备。
- -v …: 将本地模型挂载到容器内部的指定路径。
- vllm/vllm-openai:latest: 使用官方提供的最新vLLM镜像。
- –model …: 指定容器内部的模型路径。
验证服务启动
检查Docker日志确认服务是否已成功启动,并且确实在使用CPU模式。
1 docker logs vllm-cpu-server
在日志中,你通常会看到类似如下的初始化信息,表明模型加载成功:
1
2
3 INFO 05-23 08:30:15 worker.py:101] Running on device: cpu
INFO 05-23 08:30:15 model_runner.py:120] Loading model weights took 10.50s
... 确认 HTTP server 启动信息 ...
第三步:进行推理测试
vLLM的OpenAI兼容服务运行在 http://localhost:8000 上。我们可以使用标准的OpenAI Python库进行测试。
首先,确保安装了必要的库:
1 pip install openai
然后,执行以下Python脚本进行文本生成测试:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 import openai
import time
# 配置为vLLM服务的地址
client = openai.OpenAI(
api_key="sk-not-needed", # vLLM不需要真实的API Key
base_url="http://localhost:8000/v1"
)
model_id = "/app/models/llama-2-7b" # 必须与启动时指定的模型名称一致
print(f"Testing inference on model: {model_id}")
try:
start_time = time.time()
response = client.chat.completions.create(
model=model_id,
messages=[
{"role": "user", "content": "用一句话解释为什么大型语言模型需要大量的计算资源?"}
],
max_tokens=64,
temperature=0.7,
stream=False # 非流式请求
)
end_time = time.time()
print("\n--- Response ---")
print(response.choices[0].message.content.strip())
print(f"\nInference Time: {end_time - start_time:.2f} seconds")
except Exception as e:
print(f"An error occurred: {e}")
print("请检查Docker日志,确保模型已完全加载,且端口8000可用。")
总结
虽然vLLM在CPU上的推理速度相对较慢(尤其是对于大型模型),但通过设置 CUDA_VISIBLE_DEVICES=”” 环境变量,我们可以有效地利用vLLM的Docker镜像在标准CPU环境中进行模型加载和API服务部署。这种方法极大地简化了本地开发和集成测试的流程,避免了对GPU的硬性依赖。
汤不热吧