title: 模型部署与推理优化实战:微调完的模型怎么上线?
# 模型部署与推理优化实战:微调完的模型怎么上线?
上一篇文章我们聊了多轮对话微调,用 Chat Template 把一问一答的模型训练成了能记住上下文的对话助手。但微调完只是第一步——模型躺在训练机上的 .bin 文件是没有价值的,你得把它”跑起来”、暴露成 API、让别人能用。这一步,就叫部署。
很多人踩过这样的坑:训练时 batch size 开 4 跑得稳稳的,一上线推理,显存直接爆了。为什么?因为训练和部署对资源的诉求完全不同。训练可以等,推理不能等;训练可以慢慢算,推理要瞬间响应。
今天这篇不讲理论大道理,直接给实操方案。
一、上线前先搞清三个问题
1. 显存去哪儿了
一个 7B 参数的模型,FP16 精度下光参数就要 14GB 显存。但这只是”裸奔”——推理时还要存 KV Cache(Key-Value 缓存),这个才是吃显存的大头。
举个例子:用 7B 模型跑 2048 token 的对话,KV Cache 要吃掉大约 2GB 额外显存。跑 4096 token 的上下文,就是 4GB。长对话场景下(比如客服、文档助手),显存很快就爆了。
2. 并发上来就卡
单用户推理时还算流畅,一上 10 个并发,要不排队,要不 OOM。因为大多数推理框架默认”串行处理”——一个请求算完才接下一个。
3. 延迟 vs 吞吐量
这两者经常是矛盾的。为了降低单次延迟可以加大 batch,但 batch 加太大,单个用户等的时间反而长了。生产环境需要在延迟和吞吐量之间做 trade-off。
二、四个核心优化技术
2.1 量化:用精度换显存
量化是把模型参数的精度降低,让每个参数占更少的字节。
| 精度 | 每参数字节 | 7B 模型占用 | 推荐场景 |
|---|---|---|---|
| FP16 | 2 bytes | 14 GB | 高质量场景,显存充足 |
| INT8 | 1 byte | 7 GB | 平衡方案 |
| INT4 (AWQ/GPTQ) | 0.5 byte | 3.5 GB | 低显存场景,消费级显卡 |
最推荐的是 AWQ 量化(Activation-aware Weight Quantization)。和传统 GPTQ 不同,AWQ 不是无差别地把所有参数压缩,而是先分析哪些权重对模型输出影响更大,给它们保留更高的精度。实测 AWQ 比 GPTQ 在相同压缩比下推理速度提升约 1.3 倍,质量损失几乎不可感知。
量化后的模型可以直接用 transformers 加载:
from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained(
"model-owner/model-name",
device_map="auto",
quantization_config="awq"
)
2.2 PagedAttention:vLLM 的核心武器
这是 vLLM 能比传统推理框架快 10 倍的关键。
传统方法:KV Cache 在显存里连续分配,就像数组——你也不知道对话会变多长,只能按最大长度预留一整块显存。假设最大长度 4096 token,但实际平均只用了 2000,另一半显存就白占了。
PagedAttention 的做法很巧妙:把 KV Cache 切成固定大小的”页”(类似操作系统的虚拟内存),需要多少就分配多少页。用完还显存。这个机制让显存利用率从 ~40% 提升到 ~95%。
这也是为什么 vLLM 能跑更大的 batch size,能处理更长的上下文——它不是凭空多出来显存,而是把浪费掉的找回来了。
2.3 连续批处理
传统推理框架:来一个请求,算完,再处理下一个。显存利用率低。
连续批处理:不等待”所有请求都算完”再清空 batch,而是动态管理——哪个请求生成完了就把它移出 batch,新来的请求随时加入。中间有 idle 的时间窗口,立刻填上新请求。这种”流水线”方式让 GPU 一直在干活,吞吐量能翻几倍。
2.4 KV Cache 量化
vLLM 在 0.6.0 之后支持 KV Cache 用 FP8 存储。默认是 FP16,换成 FP8 后 KV Cache 的显存占用直接减半。对长上下文场景(8K+ token)效果非常明显,而质量损失在 1% 以内。
三、主流部署框架选型
目前社区用得最多的三个框架:
vLLM(推荐首选)
GitHub 53k+ stars,社区最活跃。核心优势:
- 全量支持 PagedAttention + 连续批处理
- OpenAI 兼容 API,一行代码都不用改就能接入
- 原生支持 AWQ/GPTQ/FP8 量化
vllm serve Qwen/Qwen2.5-7B-Instruct \
--port 8000 \
--dtype auto \
--max-model-len 4096 \
--quantization awq \
--gpu-memory-utilization 0.9
启动后直接访问 http://localhost:8000/v1/chat/completions,跟调 OpenAI API 一模一样:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="not-needed"
)
response = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct",
messages=[
{"role": "system", "content": "你是一个有用的助手"},
{"role": "user", "content": "用简单的话解释什么是 KV Cache"}
]
)
print(response.choices[0].message.content)
这也是为什么 vLLM 是目前最主流的选择——不需要改代码,拿来就用。
HuggingFace TGI
HuggingFace 官方的解决方案,跟 transformers 生态集成最好。如果你的模型已经用 transformers 训练,TGI 可以直接加载,不需要额外转换格式。缺点:量化支持不如 vLLM 丰富。
启动命令也很简单:
docker run --gpus all -p 8080:80 \
ghcr.io/huggingface/text-generation-inference:3.3.7 \
--model-id Qwen/Qwen2.5-7B-Instruct \
--num-shard 1
Ollama
适合个人开发环境。一键安装、模型管理方便、不需要写代码。但不适合生产高并发,不支持连续批处理。你微调好的 LoRA 权重可以用 Modelfile 导入,但大规模部署不推荐。
简单总结:
| 框架 | 适合场景 | 并发能力 | 量化支持 | 难度 |
|---|---|---|---|---|
| vLLM | 生产环境、高并发 | ⭐⭐⭐⭐⭐ | AWQ/GPTQ/FP8 | 中等 |
| TGI | HuggingFace 生态 | ⭐⭐⭐⭐ | GPTQ/FP8 | 中等 |
| Ollama | 个人开发、测试 | ⭐⭐ | GGUF 格式 | 极低 |
四、实战:三步上线微调模型
假设你之前用 QLoRA 微调了一个 Qwen2.5-7B 模型,现在要部署。
第一步:合并 LoRA 权重
python merge_lora.py \
--base-model Qwen/Qwen2.5-7B-Instruct \
--lora-weights ./qlora-output/checkpoint-500 \
--output ./merged-model
这一步把 LoRA 权重合并回基础模型,得到一个完整的 HuggingFace 格式模型。
第二步:AWQ 量化(可选,但强烈推荐)
# 先用 AutoAWQ 量化
python -m autoawq \
--model_path ./merged-model \
--quant_path ./merged-model-awq \
--quant_algo awq \
--bits 4
量化后 7B 模型从 14GB 降到 3.5GB,一张 8GB 的显卡就能跑。
第三步:用 vLLM 启动服务
vllm serve ./merged-model-awq \
--port 8000 \
--dtype auto \
--max-model-len 4096 \
--gpu-memory-utilization 0.9 \
--max-num-seqs 32
关键参数详解:
--gpu-memory-utilization 0.9:最多用 90% 的显存用于模型 + KV Cache,留 10% 做 buffer--max-num-seqs 32:最大并发请求数,根据你的显存和延迟要求调整--max-model-len 4096:最大输入长度,越长 KV Cache 占用越大
测试 API
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "./merged-model-awq",
"messages": [
{"role": "user", "content": "什么是 PagedAttention?"}
]
}'
如果返回了正常的 JSON 回复,恭喜,模型上线成功。
五、性能调优的几个经验
最后分享几个实战中踩出来的坑:
gpu-memory-utilization 别设 1.0 — 留点余量给 torch 临时分配,否则偶发 OOM
长对话场景用 KV Cache 量化 — --kv-cache-dtype fp8,显存减半,质量几乎不变
多 GPU 部署留意通信 — 跨卡推理的通信瓶颈会吃掉加速收益,4 卡以下优先考虑单卡 + 量化
监控首 Token 延迟 — 这是用户感知最明显的指标。vLLM 的 --enable-metrics 可以导出 Prometheus 指标
不要盲目上大 batch — batch size 翻倍,延迟也可能翻倍。先设 8,逐步上调,找到性能拐点
总结
部署优化这件事,本质上就是在”模型质量”、”响应速度”和”硬件成本”之间找平衡。而 vLLM 的 PagedAttention + 连续批处理 + FP8 KV Cache 这三个技术组合,是目前开源生态里性价比最高的方案,没有之一。
下期预告:RAG 进阶——从简单向量检索到 Agentic RAG 的架构演进。微调 + 部署都搞定后,我们来聊聊怎么让模型能主动查资料、调工具、做决策。
参考资料
vLLM 官方文档:https://docs.vllm.ai/en/latest/
vLLM GitHub:https://github.com/vllm-project/vllm
HuggingFace TGI:https://github.com/huggingface/text-generation-inference
AWQ 论文:Lin et al., “AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration”, arXiv:2306.00978
PagedAttention 论文:Kwon et al., “Efficient Memory Management for Large Language Model Serving with PagedAttention”, SOSP 2023
Ollama:https://ollama.ai
AutoAWQ 量化工具:https://github.com/casper-hansen/AutoAWQ
FP8 KV Cache 技术说明:https://docs.vllm.ai/en/latest/features/kv_cache.html
转载请注明:Falost的小窝 » 模型部署与推理优化实战:微调完的模型怎么上线?


