最近,我们做了一件看起来“不太可能”的事:
把一个 LoRA 微调后的 Qwen-7B 意图识别模型,压缩到 1.8GB 以内 ,在生产环境里跑到 P99 延迟 82ms ,并且还能做到 5 秒级热更新 。
这篇文章,尝试用尽量“接地气”的方式,讲清楚三件事:
为什么大模型必须做压缩?都有哪些“瘦身”方式?
量化到底在干什么?怎么做、怎么评估?
如何把一个量化后的 Qwen-7B 模型,用 vLLM + FastAPI 跑成可以随时上线的服务?
如果你正被“显存不够用、延迟太高、部署不稳定”折磨,希望这篇实战记录能给你一点参考。

一、从“跑不动”开始:为什么要压缩模型?
大模型训练阶段大家都很兴奋:loss 一路往下掉,验证集指标也好看,LoRA 微调完丢到本地一跑,感觉一切都很顺利。
真正的噩梦,往往出现在上线那天。
常见现场画面:
在本地 24G 显卡上推理没问题,一上生产环境直接 OOM
服务跑起来了,但 P99 延迟 300ms+ ,用户侧明显感觉“卡顿”
为了省显存不断减 batch size,结果吞吐量严重不够,只能继续加机器
问题的根源其实很简单: 模型太大了。
就好比你拿着一个 4K 的原始视频,想在 4G 流量下秒开秒看,不对它做压缩基本没戏。
模型压缩 = 给模型“转码”
对工程同学来说,可以把模型压缩类比为:
给一个 20GB 的 4K 原始视频,转码成 2GB 的 MP4,让它既能在手机上流畅播放,又不至于糊成马赛克。
对于大模型服务来说,压缩带来的直接收益包括:
显存占用 :从十几 GB 压到几 GB,甚至 1.xGB
推理速度 :延迟明显下降,吞吐量显著提升
成本 :同样的机器上能挂更多模型,或者更高的 QPS
所以,“模型压缩”不是锦上添花,而是很多团队能不能 上线、稳定跑、跑得起 的前提条件。
二、模型“瘦身”有哪些方式?
模型“瘦身”并不只有一个手段,常见的有三类:量化、剪枝、知识蒸馏。
1. 量化(Quantization)——LoRA 场景的首选
特点:
显存降低 :通常可以降到原来的 1/6 ~ 1/8
推理加速 :2~3 倍比较常见
工程改造成本低 :不需要重新训练,只对权重做数值压缩
对于已经用 LoRA 微调好的 Qwen-7B 模型,量化基本是第一选择。
2. 剪枝(Pruning)——理论很美,实践容易翻车
剪枝的逻辑是:把模型里“影响不大的参数”砍掉,让网络结构变得更小、更稀疏。
问题在于:
很容易破坏原有的“隐含逻辑”,导致 bad case 暴增
对于复杂任务,表现不稳定,难以在业务中快速落地
工程优化复杂,算子支持、稀疏加速都需要大量投入
在生产环境里,如果没有专门的算法团队持续跟进,剪枝一般不建议作为首选手段。
3. 知识蒸馏(Distillation)——能做,但周期长
把大模型的“知识”蒸馏到一个更小的模型中,例如从 7B 蒸馏到 1.3B/3B:
需要重新训练一个学生模型
数据要准备、训练要调参、评估要做一堆
周期长,成本高
在 LoRA 场景下,往往是: 业务节奏快、需求更新频繁 。这时候,蒸馏虽然从长远看很香,但短期内不一定划算。
结合实际经验:
对于“已经用 LoRA 微调好的 Qwen-7B 意图识别模型”,我们更推荐的路线是:
先合并 LoRA 权重
对合并后的模型做量化(INT8 / Int4 GPTQ)
配合 vLLM 做高并发部署
三、量化到底在干什么?
很多人对“量化”的第一反应是:
“是不是把模型搞笨了?”
可以先从一个直观的类比入手。
1. 从浮点到整数:数字精度的“有损压缩”
普通的模型权重是 32 位浮点数(FP32) 。
量化做的事情,其实就是把这些 FP32,换成更小的数据类型,比如: 8 位整数(INT8) 、4 位整数(Int4)。
一个简单的例子:
原始值:0.78(FP32)
量化后:200(INT8)
背后其实是:0.78 = 200 × scale(通过一个缩放比例来映射)
内存占用上,从 32 bit → 8 bit,相当于立刻省了 75% 。
就像图片压缩:
原图:几 MB 的 PNG
压缩后:几百 KB 的 JPEG
你能看到一些细节损失,但大部分场景完全可用
2. 精度损失真的严重吗?
答案跟任务有关。
对于 意图识别、分类、多轮对话 等任务:
适度量化(INT8 / Int4)带来的性能下降通常非常有限,用肉眼很难察觉
对于 精细数值预测、部分生成质量敏感任务 :
需要更细致地评估,甚至可能需要混合精度、某些层保留 FP16
可以把量化理解成:
用一点点精度损失,换显存和速度的大幅下降。
大多数业务场景,这笔账是非常划算的。
四、如何对 Qwen-7B 做 INT8 量化?

以我们实际落地的链路为例,大致分成三步。
第一步:先合并 LoRA 权重
很多人一上来就对 LoRA 权重做量化,这是不对的。
正确的顺序是:
先把 Qwen-7B 基座模型 和 LoRA 权重 合并成一个完整模型
得到一个更新后的全量权重
对这个“合并后的模型”做量化
原因很简单:线上推理时,你只想维护一个模型文件,减少依赖和加载过程的复杂性。
第二步:用工具做 INT8 / Int4 量化
市面上量化工具很多,我们这里提一句 swift 只是一个实际使用的例子,你可以选择熟悉的框架和工具链(如 transformers + bitsandbytes、AutoGPTQ 等)。
核心步骤:
加载合并后的 Qwen-7B 模型
指定量化方式(如 INT8、Int4 GPTQ 等)
保存量化后的权重文件
量化完成后,你会看到模型文件大小从十几 GB 压到了几 GB,甚至 1.xGB,这一步的收益是非常直观的。
第三步:离线评估 + 线上 A/B
量化一定要评估,否则就是盲目上生产。
建议两个层面的评估:
离线评估:
用历史标注数据 / 测试样本
比对“未量化模型”与“量化模型”的准确率 / F1 / 引导问题正确率等
重点看业务关心的指标,而不是只看通用基准
线上 A/B 测试(如果条件允许):
真正衡量量化带来的影响,还是要看线上用户的数据
关注投诉率、意图识别错误案例等
对于意图识别这种任务,只要不是极限压缩,一般来说 INT8 / Int4 的量化效果是足够支撑业务的。
五、Ollama 能用来做推理吗?
很多同学问: Ollama 能不能用来做推理?
简单一句话:
功能很丰富,体验好
非常适合作为 本地开发环境、模型探索、Demo 演示 的工具
但如果你要面对的是:
高并发请求
稳定的生产 SLA
成熟的监控、调度、批处理能力
就需要一个更“面向生产”的框架,比如下面要说的 vLLM。
六、为什么生产环境首选 vLLM?
vLLM 这两年几乎成了“大模型服务化部署”的事实标准,尤其是在高并发、低延迟的线上场景。
它的几个关键特性,基本上正对生产环境的痛点。
vLLM 的核心优势
吞吐量极高 :
依靠 PagedAttention,实现高效的 KV Cache 管理,让显存利用率非常高,QPS 水平上得去。
首 Token 延迟很低(TTFT) :
通过 chunked prefill,前几个 token 能很快给用户反馈。
KV Cache 效率高 :
同样是因为 PagedAttention,对显存做了更细粒度的分配和复用。
长上下文支持优秀(128K+) :
对需要长上下文的场景(多轮对话、长文档理解)非常友好。
多轮对话性能优化 :
Prefix Caching 能复用历史 KV,减少重复计算。
生产级功能完备 :
批处理、优先级调度、监控等都比较成熟,方便接到现有服务体系里。
一句话概括:
如果你想把量化后的 Qwen-7B 模型真正跑到线上, vLLM 是非常值得优先考虑的选项。
七、P99 延迟 100ms、5 秒热更新是怎么做到的?
我们当时的目标是:
模型体积压到 1.8GB 以内
在线推理做到 P99 延迟 ≈ 82ms
支持 约 5 秒内模型热更新
1. 如何把延迟压到 P99 ≈ 82ms?
整体思路可以拆成几块:
(1) 模型轻量化
使用 GPTQ-Int4 量化
把 Qwen-7B 模型从 14GB 压到 4GB 左右(不同版本略有差异)
显存占用大幅降低,推理加速明显
(2) 优化 Prefill 阶段
在 vLLM 中开启:
enable_chunked_prefill让“首 token”尽快生成,直接提升用户的主观体验
(3) 优化 KV Cache
开启:
enable_prefix_caching对多轮对话、相似请求复用历史 KV,减少重复计算
(4) 批处理参数调优
调整
max_num_batched_tokens等参数在“单请求延迟”和“整体吞吐”之间找到平衡点
这几个策略叠加起来,就可以把 P99 延迟压到一个比较理想的范围内。
2. 5 秒内模型热更新怎么实现?
vLLM 当前 原生并不直接支持热更新 模型(即在同一进程内无感知切换权重)。
所以需要借助外部的服务发现和负载均衡来实现。
我们采用的是典型的:
双实例蓝绿部署 + Nginx 路由
大致流程:
现网运行的是 A 实例(挂载旧模型)
启动一个新的 B 实例(挂载新模型),完成模型加载和预热
通过 Nginx / 网关,根据路由规则把流量从 A 切到 B
观察一段时间,确认稳定后下线 A
因为 B 实例是在后台完成启动和预热的,所以从流量切换的角度看,整体“模型升级”过程可以控制在几秒内完成,对用户几乎无感。
八、端到端部署:用 FastAPI + vLLM 搭出一个可上线服务
最后,用一段简化的代码,把整个链路串起来,看一下完整的部署形态。
下面是一个基于 FastAPI 的简单服务示例,用 vLLM 加载 GPTQ-Int4 量化后的 Qwen-7B 模型,并提供一个 /predict 接口做意图识别。
```python
from fastapi import FastAPI, HTTPException
from vllm import LLM, SamplingParams
import asyncio
app = FastAPI
全局 LLM 实例
llm = LLM(
model="Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4",
quantization="GPTQ",
enable_prefix_caching=True,
enable_chunked_prefill=True,
max_num_batched_tokens=2048,
gpu_memory_utilization=0.85,
dtype="half",
)
采样参数
sampling_params = SamplingParams(
temperature=0.7,
top_p=0.9,
max_tokens=512,
)
@app.post("/predict")
async def predict(request: dict):
try:
text = request["text"]
# 异步推理
result = await llm.generate.async_request(text, sampling_params)
return {"intent": result.outputs[0].text}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/health")
def health_check:
return {"status": "healthy", "model": "qwen-7b-int4-gptq"}
```
Docker 化部署与压测
构建镜像:
```bash
docker build -t intent-vllm .
```
运行服务:
```bash
docker run -p 8000:8000 --gpus all intent-vllm
```
之后,你可以用 wrk、hey、locust 等工具,对 /predict 接口进行压测:
测 P50 / P90 / P99 延迟
测 QPS
观察显存、GPU 利用率、CPU 占用等
把这些数据跟未量化、未优化版本对比,通常能看到非常明显的差距。
九、总结:
回顾一下这次实践中的几个关键点:
压缩是刚需 :
大模型要上生产,不做压缩很难靠堆机器解决问题。
LoRA 场景,量化优先 :
合并 LoRA → INT8 / Int4 量化 → vLLM 部署,是当前性价比最高的一条路。
量化 ≠ 把模型变笨 :
对于意图识别这类任务,只要评估得当,基本不会影响业务体验。
vLLM 是部署利器 :
高吞吐、低延迟,再加上完善的生产特性,非常适合直接接生产流量。
热更新靠“蓝绿 + 网关” :
利用双实例和 Nginx 路由,可以把模型升级控制在几秒内完成。
如果你现在正准备把一个 LoRA 微调的 Qwen-7B 模型推向线上,可以参考这套流程,先从最简单的一步开始:
先把模型压下来,再谈体验和成本。
上篇:
5分钟一键生成软著申请材料,coze工作流全教程,含提示词
下篇:
没有了
1 vLLM + FastAPI:一个高并发、低延迟的Qwen-7B量化服务搭建实录... 2 AI幽默风搞笑漫画 !10 分钟免费教会你如何制作AI漫画 3 小丑驴打工人搞笑视频制作!AI动漫搞笑视频 4 提示词太水了?AI 制作的太假?怎么看起来更高级。 5 谁敢信!用豆包生成8篇小说全部过签了 6 AI制作3D健康食谱漫画 7 Ai 新玩法,手把手教你用DeepSeek做十二星座视频教程 8 AI生成《乌鸦喝水》的成语故事,提问方法+实操 9 即梦智能多帧长达45s视频!连续创作 10 打戏万能提示词!古风电视剧片段 11 即梦4.0制作一家三口旅游视频!人物一致性高度统一 12 豆包新功能4.0来了!全免费,案例实测