导语:我们已经成功地微调并评估了我们的“AI 皮肤科医生”模型。现在,我们面临着“最后一公里”的挑战:如何将这个模型部署成一个高性能、高吞吐、可供成千上万用户同时访问的在线服务?使用标准的 Hugging Face
pipeline进行推理,在生产环境下会很快遇到性能瓶颈。此时,我们需要一个专为 LLM 推理而生的“涡轮增压引擎”——vLLM。vLLM 是一个由伯克利大学开源的、用于 LLM 推理和服务的库,它通过 PagedAttention 等一系列创新技术,可以极大地提升推理速度和吞吐量。本章,我们将手把手带你使用 vLLM,为我们微调好的 LoRA 模型启动一个与 OpenAI API 兼容的、生产级的推理服务,并将其无缝对接到我们已有的 Agent 系统中。
目录
- 推理的“慢”痛点:为什么标准的 Hugging Face Pipeline 不够快?
- 显存的浪费:KV Cache 的管理难题
- 吞吐量的瓶颈:一次只能处理一个请求序列
- vLLM 的“黑科技”:PagedAttention 简介
- 像操作系统的“虚拟内存”一样管理 KV Cache
- 实现近乎零的显存浪费和极高的吞吐量
- 第一步:安装 vLLM
- 硬件要求与 CUDA 版本
pip install vllm
- 第二步:启动 OpenAI 兼容的推理服务
- vLLM 的核心优势:内置一个与 OpenAI API 完全兼容的 API Server。
- 启动命令详解:
python -m vllm.entrypoints.openai.api_server--model: 指定基础模型的路径 (e.g.,Qwen/Qwen1.5-7B-Chat)--enable-lora: 开启 LoRA 支持--lora-modules: 指定我们训练好的LoRA 适配器的路径和名称--max-lora-rank: 设置支持的最大 LoRA 秩
- 第三步:测试你的 vLLM 服务
- 方法一:使用
curl- 像调用 OpenAI API 一样,向
http://localhost:8000/v1/chat/completions发送请求。
- 像调用 OpenAI API 一样,向
- 方法二:使用
openaiPython 客户端- 设置
api_key和base_url。 - 在
model参数中,指定要使用的 LoRA 适配器名称。 - vLLM 会在后台动态地将适配器加载到基础模型上。
- 设置
- 方法一:使用
- 第四步:无缝集成到现有的 Agentic AI 系统
- 改造“旅小智”:
- 修改
docker-compose.yml,新增一个llm-server服务,专门用于运行 vLLM。 - 修改
backend服务的环境变量,将其 OpenAIbase_url指向 vLLM 服务 (http://llm-server:8000/v1)。 - 在 Agent 代码中,当需要调用“AI 皮肤科医生”时,将 LLM 模型的名称指定为我们定义的 LoRA 适配器名称。
- 修改
- 改造“旅小智”:
- 总结:为你的 Agent 装上“性能怪兽”引擎
1. 推理的“慢”痛点:为什么标准的 Hugging Face Pipeline 不够快?
当你使用标准的 transformers 库加载一个模型并进行推理时,尤其是在处理多个并发请求(批处理,Batching)时,会遇到两大性能瓶颈:
- 显存的浪费 (KV Cache Management)
- 在生成文本的过程中,模型需要为每个 Token 计算并存储其 Key 和 Value,这就是所谓的 KV Cache。这个 Cache 会随着生成序列的增长而变得非常大。
- 传统的实现方式是为每个请求预先分配一块连续的、能够容纳其最大可能长度的显存空间来存储 KV Cache。这意味着,即使一个请求只生成了 10 个 Token,它也可能占用了 2048 个 Token 的显存空间,造成了巨大的浪费。
- 吞吐量的瓶颈 (Throughput Bottleneck)
- 在批处理多个请求时,只要其中一个请求完成了生成,整个批次也需要等待。而如果不同请求的长度差异很大,长序列会拖慢整个批次的速度。
2. vLLM 的“黑科技”:PagedAttention 简介
vLLM 的核心创新是 PagedAttention 算法,它从根本上解决了 KV Cache 的管理难题。
- 核心思想:PagedAttention 借鉴了计算机操作系统中管理虚拟内存和分页 (Paging) 的思想。它不再为每个序列预分配连续的显存,而是将 KV Cache 存储在非连续的、固定大小的“块”(Block)中。
- 效果:
- 近乎零的浪费:显存按需分配,一个序列需要多少 Block 就给多少,空间利用率极高。
- 高吞吐量:不同的请求序列可以共享物理显存块,极大地提升了并发处理能力(吞吐量)。根据官方数据,vLLM 可以将吞-吐量提升 10-20 倍。
3. 第一步:安装 vLLM
硬件与环境要求
- vLLM 强依赖于 NVIDIA 显卡和 CUDA 环境。请确保你的驱动和 CUDA Toolkit 版本与 vLLM 官网要求的版本兼容。
- 通常需要 Python 3.8+。
安装
# 确保你的 pip 和 torch 是最新版本
pip install --upgrade pip torch
# 安装 vllm
pip install vllm
4. 第二步:启动 OpenAI 兼容的推理服务
vLLM 最令人称道的功能之一,就是它内置了一个与 OpenAI API 完全兼容的 HTTP 服务器。这意味着,你只需要一行命令,就可以将你的本地模型,伪装成一个“私有化部署的 OpenAI 服务”。
启动命令详解
假设我们已经微调好了 medical-expert-v1 这个 LoRA 适配器,现在我们要启动一个服务来托管它。
python -m vllm.entrypoints.openai.api_server \
--model "Qwen/Qwen1.5-7B-Chat" \
--enable-lora \
--lora-modules medical-expert=./saves/Qwen1.5-7B-Chat/lora/medical-expert-v1 \
--max-lora-rank 8
让我们来分解这个命令:
python -m vllm.entrypoints.openai.api_server: 这是启动 vLLM 的 OpenAI 风格 API 服务器的入口。--model "Qwen/Qwen1.5-7B-Chat": 指定要加载的基础模型。vLLM 会自动从 Hugging Face Hub 下载。--enable-lora: 必须添加此标志,以开启对 LoRA 的支持。--lora-modules <lora_name>=<path_to_adapter>: 这是最关键的参数。我们在这里注册我们训练好的 LoRA 适配器。medical-expert: 这是我们为这个适配器起的调用名称 (LoRA Name)。在后续的 API 请求中,我们将使用这个名字来指定使用此适配器。./saves/.../medical-expert-v1: 这是包含adapter_model.safetensors等文件的适配器路径。
--max-lora-rank 8: 告诉 vLLM 我们使用的 LoRA 适配器的最大秩。这个值应该等于或大于你训练时设置的lora_rank。
执行该命令后,vLLM 会加载基础模型,并准备好随时加载 LoRA 适配器。你将看到日志显示服务器正在 http://localhost:8000 上监听。
5. 第三步:测试你的 vLLM 服务
方法一:使用 curl
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "medical-expert",
"messages": [
{"role": "user", "content": "我脸上长痘痘怎么办?"}
],
"max_tokens": 256
}'
关键点:
- URL 是
http://localhost:8000/v1/chat/completions,与 OpenAI API 的结构完全一致。 "model": "medical-expert": 我们在这里传入的不是基础模型的名称,而是我们在启动服务时,为 LoRA 适配器定义的调用名称。vLLM 会根据这个名称,在后台动态地将medical-expert-v1适配器应用到Qwen1.5-7B-Chat基础模型上进行本次推理。
方法二:使用 openai Python 客户端
# test_vllm_service.py
import openai
# 1. 创建一个指向 vLLM 服务的客户端
client = openai.OpenAI(
api_key="vllm-is-great", # api_key 是必需的,但内容不重要
base_url="http://localhost:8000/v1" # 指向我们的 vLLM 服务地址
)
# 2. 调用模型,model 参数指定 LoRA 适配器名称
response = client.chat.completions.create(
model="medical-expert",
messages=[
{"role": "user", "content": "我脸上长痘痘怎么办?"}
],
temperature=0.7,
max_tokens=256
)
print(response.choices[0].message.content)
# 3. 对比:调用不带 LoRA 的基础模型
# 在 model 参数中传入基础模型的路径
# 这需要你在启动 vLLM 服务时,--model 参数传入的模型名称与这里一致
response_base = client.chat.completions.create(
model="Qwen/Qwen1.5-7B-Chat",
messages=[
{"role": "user", "content": "我脸上长痘痘怎么办?"}
]
)
print("\n--- Base Model Response ---")
print(response_base.choices[0].message.content)
运行这个脚本,你就能清晰地看到加载了 LoRA 适配器的模型和原始基础模型在回答风格上的巨大差异,验证了 vLLM 的动态适配器加载功能。
6. 第四步:无缝集成到现有的 Agentic AI 系统
vLLM 最大的好处在于,它对上层应用是“透明”的。任何能够调用 OpenAI API 的代码,都可以在几乎不修改的情况下,切换到使用 vLLM 部署的模型。
改造“旅小智”
假设我们希望在“旅小智”应用中,加入我们的“AI 皮肤科医生”作为一个新的专家 Agent。
1. 修改 docker-compose.yml
我们需要新增一个 llm-server 服务来专门运行 vLLM。
# docker-compose.yml (新增部分)
version: '3.8'
services:
# 新增 vLLM 服务
llm-server:
image: vllm/vllm-openai:latest # 使用官方的 vLLM 镜像
command: >
--model Qwen/Qwen1.5-7B-Chat
--enable-lora
--lora-modules medical-expert=/app/lora_adapters/medical-expert-v1
--max-lora-rank 8
volumes:
# 将我们训练好的适配器文件挂载到容器中
- ./saves/Qwen1.5-7B-Chat/lora/medical-expert-v1:/app/lora_adapters/medical-expert-v1
# 如果使用 NVIDIA 显卡,需要添加 deploy 配置
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
networks:
- trip_genius_net
backend:
# ... backend 原有配置 ...
environment:
# 将 OpenAI Base URL 指向新的 vLLM 服务
- OPENAI_API_BASE=http://llm-server:8000/v1
depends_on:
- llm-server # 后端服务依赖 LLM 服务
networks:
- trip_genius_net
frontend:
# ...
networks:
trip_genius_net:
driver: bridge
2. 在 Agent 代码中调用
在 agents/experts.py 中,当我们创建“医疗专家”时,只需要指定 model 名称即可。
# agents/experts.py
def create_medical_expert_runnable():
# 这个 client 会读取环境变量,自动指向 vLLM 服务
llm = ChatOpenAI(
model="medical-expert", # 指定使用我们微调的 LoRA 模型
temperature=0.7
)
prompt = ChatPromptTemplate.from_messages(...)
return prompt | llm
就这样,我们的“旅小智”主管 Agent 在需要进行医疗咨询时,就可以调用这个新的专家,而这个专家背后使用的,正是由 vLLM 高性能驱动的、我们亲手微调的专业模型。整个过程对上层 Agent 逻辑完全透明。
7. 总结:为你的 Agent 装上“性能怪兽”引擎
通过本章的学习,我们补上了“模型定制化”流程的最后一块、也是最关键的一块拼图——高性能部署。
- 我们理解了 vLLM 通过 PagedAttention 等技术实现推理加速的核心原理。
- 我们学会了使用一行命令,将我们微调好的 LoRA 模型部署成一个与 OpenAI API 兼容的服务。
- 我们掌握了如何在上层应用(无论是简单的 Python 脚本还是复杂的 Agentic 系统)中,无缝地调用由 vLLM 托管的模型。
vLLM 就像一个“性能怪兽”,它为你扫清了在生产环境中大规模应用定制化 LLM 的性能障碍。掌握了 LlamaFactory (微调) + vLLM (部署) 这套组合拳,你就拥有了端到端、低成本、高性能地打造和交付垂直领域专业 AI Agent 的全栈能力。