vLLM 使用:部署微调模型
目录
- [第一章:为什么需要 vLLM](#第一章:为什么需要 vLLM)
- [第二章:核心概念------LoRA 适配器与原模型](#第二章:核心概念——LoRA 适配器与原模型)
- [第三章:vLLM 的核心优势](#第三章:vLLM 的核心优势)
- [第四章:用 vLLM 加载 LoRA 模型](#第四章:用 vLLM 加载 LoRA 模型)
- [第五章:启动 API 服务](#第五章:启动 API 服务)
- [第六章:在 LangChain 中调用 vLLM 服务](#第六章:在 LangChain 中调用 vLLM 服务)
- [第七章:多 LoRA 切换(Multi-Agent 进阶)](#第七章:多 LoRA 切换(Multi-Agent 进阶))
- 第八章:一站式部署流程图
第一章:为什么需要 vLLM
LLaMA-Factory 的推理够用吗?
你用 LLaMA-Factory 微调完,可以用 llamafactory-cli chat 聊天测试。但这个方式只适合本地调试,不适合正式使用:
| LLaMA-Factory 推理 | vLLM 部署 | |
|---|---|---|
| 场景 | 训练后随手测一测 | 正式对外提供服务 |
| 性能 | 单次推理,无优化 | PagedAttention,高并发 |
| API | 命令行交互 | OpenAI 兼容 API |
| 吞吐 | 低(一次处理一个请求) | 高(连续批处理) |
| 多 LoRA | 不支持动态切换 | 支持一模型加载多个 LoRA |
一句话:LLaMA-Factory 是"试一下效果",vLLM 是"上线给用户用"。
vLLM 是什么
vLLM 是一个高性能大模型推理引擎,由加州大学伯克利分校开发。它解决的核心问题就是:
同样一块 GPU,vLLM 能服务的用户数量是普通推理方式的 5-10 倍。
第二章:核心概念------LoRA 适配器与原模型
微调后的产物是什么?
很多人第一次微调完,看到输出目录会疑惑:
output/my_model/
├── adapter_config.json ← 补丁配置
├── adapter_model.safetensors ← 补丁权重(~5-30MB)
└── training_log.json ← 训练日志
只有几 MB?这能算一个模型吗?
不算。你得到的只是一个 "补丁"(LoRA 适配器),它必须贴在原模型上才能用。
直观理解
┌──────────────────────────┐
│ Qwen2.5-7B 基座模型 │ ← 完整的 15GB 大模型
│ (记住了通用的知识) │
└──────────┬───────────────┘
│
+ ← 把补丁贴上去
│
┌──────────▼───────────────┐
│ LoRA 适配器(~5-30MB) │ ← 你微调训练出来的
│ (记了你的领域知识) │
└──────────────────────────┘
│
▼
┌──────────────────────────┐
│ 微调版模型 可回答你的问题 │
└──────────────────────────┘
关键理解:
- 基座模型 = 操作系统(Windows/Linux)
- LoRA 适配器 = 你装的一个软件
- 每次运行都要"操作系统 + 软件"一起加载
vLLM 做了什么事
LLaMA-Factory 训练出补丁(adapter_model.safetensors)
↓
vLLM 加载:基座模型 + LoRA 补丁 = 可用的微调模型
↓
对外提供 OpenAI 兼容 API → 任何程序都能调用
第三章:vLLM 的核心优势
3.1 PagedAttention------核心创新
传统推理的问题:
一个请求来了,模型需要记住"之前说了什么"
这个"记忆"(KV Cache)放在 GPU 显存里
但显存就像一个房间------东西放进去要占位置
传统方式:给每个请求划一个固定大小的房间
→ 即使请求很短,房间也空着浪费
→ 请求一多,房间不够用
PagedAttention 的解决方式:
像操作系统的虚拟内存一样管理
不划固定房间
需要多少就用多少
不够了可以分页到"墙外"(非连续显存)
每个请求用完了,空间立刻释放给下一个
效果 :显存利用率提升到 接近 100%,同一个 GPU 能服务更多用户。
3.2 连续批处理
传统方式:
请求 A → 处理完 → 请求 B → 处理完 → 请求 C → ...
vLLM 方式:
请求 A 来了 → 开始处理
请求 B 来了 → 不等待 A 结束,和 A 一起处理
请求 C 来了 → 三个一起处理
先处理完的请求先返回结果,不互相等待
效果 :总吞吐量提升 5-10 倍。
3.3 OpenAI 兼容 API
客户端(任何语言) → HTTP 请求 → vLLM → 模型
你写的代码:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1", # vLLM 服务地址
api_key="empty" # 本地不需要鉴权
)
response = client.chat.completions.create(
model="Qwen2.5-7B",
messages=[{"role": "user", "content": "你好"}]
)
也就是说 :如果你之前写的代码是调 OpenAI 的 API,现在只要把 base_url 改成 vLLM 的地址,一行代码都不用改。
第四章:用 vLLM 加载 LoRA 模型
安装 vLLM
pip install vllm
建议在有 GPU 的环境安装(Colab / 云服务器 / 本地 Nvidia 显卡)。
代码方式加载
from vllm import LLM, SamplingParams
# 加载基座模型 + 开启 LoRA 支持
llm = LLM(
model="Qwen/Qwen2.5-7B", # 基座模型(HuggingFace 名称或本地路径)
enable_lora=True, # 关键参数:开启 LoRA
max_loras=1, # 同时加载几个 LoRA
max_lora_rank=16, # 必须和训练时的 rank 一致
tensor_parallel_size=1, # 使用几张 GPU
gpu_memory_utilization=0.9, # GPU 显存使用比例
)
# 准备输入
prompts = [
"什么是 LangChain 的 Chain?",
"请给我写一首关于春天的诗",
]
sampling_params = SamplingParams(
temperature=0.7,
top_p=0.9,
max_tokens=512,
)
# 推理时指定 LoRA 适配器路径
outputs = llm.generate(
prompts,
sampling_params,
lora_request="output/my_model" # ← 指向你的 adapter 文件夹
)
for output in outputs:
print(output.outputs[0].text)
关键参数说明
| 参数 | 作用 | 注意 |
|---|---|---|
enable_lora=True |
告诉 vLLM 要加载 LoRA | 不加这个不会加载补丁 |
max_lora_rank |
LoRA 的秩大小 | 必须和 LLaMA-Factory 训练时设置的一致 |
lora_request |
指定用哪个 LoRA 适配器 | 指向 adapter_config.json 所在目录 |
第五章:启动 API 服务
一行命令启动
python -m vllm.entrypoints.openai.api_server \
--model Qwen/Qwen2.5-7B \
--enable-lora \
--lora-modules my-lora=output/my_model \
--port 8000
启动后你会在终端看到:
INFO: Started server process [12345]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000
测试服务是否启动成功
# 方法一:用 curl
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "my-lora",
"messages": [{"role": "user", "content": "什么是 Chain?"}]
}'
# 方法二:用 Python
curl http://localhost:8000/v1/models
# 返回可用模型列表
在多 LoRA 场景下启动
# 加载多个 LoRA 适配器,客户端指定用哪个
python -m vllm.entrypoints.openai.api_server \
--model Qwen/Qwen2.5-7B \
--enable-lora \
--lora-modules \
langchain-lora=output/langchain_model \
poetry-lora=output/poetry_model \
sql-lora=output/sql_model \
--port 8000
第六章:在 LangChain 中调用 vLLM 服务
这是你学习路线中的关键衔接点------微调完模型,部署成 API,然后在 LangChain 中调用它。
方式一:通过 ChatOpenAI(推荐)
vLLM 提供 OpenAI 兼容 API,所以 LangChain 的 ChatOpenAI 可以直接用:
from langchain_openai import ChatOpenAI
# 指向你的 vLLM 服务
llm = ChatOpenAI(
base_url="http://localhost:8000/v1",
api_key="not-needed",
model="my-lora", # 对应 --lora-modules 里的名字
temperature=0.7,
)
# 像调用正常模型一样使用
response = llm.invoke("什么是 LangChain 的 Chain?")
print(response.content)
方式二:组装成 Chain
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
# 微调后的模型 + Prompt 模板
llm = ChatOpenAI(
base_url="http://localhost:8000/v1",
api_key="not-needed",
model="my-lora",
)
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个 LangChain 专家,用中文回答"),
("human", "{question}"),
])
chain = prompt | llm
result = chain.invoke({"question": "Agent 和 Chain 有什么区别?"})
和普通 API 调用的唯一区别
之前学 LangChain 时:
llm = ChatOpenAI(model="qwen-plus", ...) # 调阿里云的 API
现在:
llm = ChatOpenAI(base_url="http://localhost:8000/v1", model="my-lora", ...)
# 调自己微调部署的服务
其他的都一样------Chain、Agent、RAG、Memory 全部照用。
第七章:多 LoRA 切换(Multi-Agent 进阶)
一个模型,多个专家
你可以给同一个基座模型训练多个 LoRA 适配器:
基座模型:Qwen2.5-7B
├── LoRA A:LangChain 专家(基于你的笔记微调)
├── LoRA B:SQL 专家(基于 SQL 问答微调)
├── LoRA C:客服专家(基于客服对话微调)
└── LoRA D:翻译专家(基于翻译数据微调)
Multi-Agent 架构
from langchain_openai import ChatOpenAI
# 每个 Agent 使用不同的 LoRA
langchain_agent = ChatOpenAI(
base_url="http://localhost:8000/v1",
model="langchain-lora",
)
sql_agent = ChatOpenAI(
base_url="http://localhost:8000/v1",
model="sql-lora",
)
# 一个 Supervisor 决定把任务交给哪个专家
if "SQL" in user_query:
return sql_agent.invoke(user_query)
elif "LangChain" in user_query:
return langchain_agent.invoke(user_query)
切换代价极低------LoRA 适配器只有几 MB,模型参数共享,切换几乎零开销。
第八章:一站式部署流程图
┌──────────────────────────────────────────────────────────────┐
│ 完整流程:从数据到服务 │
├──────────────────────────────────────────────────────────────┤
│ │
│ 你的笔记/数据 │
│ ↓ │
│ ┌─────────────────┐ │
│ │ LLaMA-Factory │ ← 第三章 准备数据 │
│ │ QLoRA 微调 │ ← 第七章 跑训练 │
│ └────────┬────────┘ │
│ ↓ │
│ ┌─────────────────┐ │
│ │ LoRA 适配器 │ ← adapter_model.safetensors (~5-30MB) │
│ │ 输出目录 │ │
│ └────────┬────────┘ │
│ ↓ │
│ ┌─────────────────┐ │
│ │ vLLM 部署服务 │ ← 本章内容 │
│ │ localhost:8000 │ │
│ └────────┬────────┘ │
│ ↓ │
│ ┌─────────────────┐ │
│ │ OpenAI 兼容 API │ ← 任何程序都能调用 │
│ └────────┬────────┘ │
│ ↓ │
│ ┌─────────────────┐ │
│ │ LangChain 应用 │ ← 你正在学的方向 │
│ │ Chain / Agent │ │
│ │ RAG / Memory │ │
│ └─────────────────┘ │
│ │
│ 一句话:数据 → 训练 → 部署 → 应用 │
│ 你的笔记 LLaMA vLLM LangChain │
│ Factory API │
└──────────────────────────────────────────────────────────────┘
附录:常用命令速查
# 安装 vLLM
pip install vllm
# 启动 API 服务(单 LoRA)
python -m vllm.entrypoints.openai.api_server \
--model Qwen/Qwen2.5-7B \
--enable-lora \
--lora-modules my-lora=output/my_model \
--port 8000
# 启动 API 服务(多 LoRA)
python -m vllm.entrypoints.openai.api_server \
--model Qwen/Qwen2.5-7B \
--enable-lora \
--lora-modules \
langchain=output/langchain_model \
sql=output/sql_model \
--port 8000
# 测试 API
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "my-lora", "messages": [{"role": "user", "content": "你好"}]}'
# 查看可用模型列表
curl http://localhost:8000/v1/models
总结一句
微调不是为了训练,是为了用。
LLaMA-Factory 给你一个补丁,vLLM 把你的补丁变成服务。