1. 大模型推理优化到底在优化什么
先把话说直白一点:训练是把模型教聪明,推理是让模型在真实业务里跑得快、跑得稳、跑得便宜。很多团队模型训得不错,一上线就崩——首 token 延迟三秒起步,并发一上来显存直接爆,单次调用成本高到业务方想砍预算。推理优化要解决的就是这三件事:延迟、吞吐、成本。
我见过太多人把推理优化理解成“换个更快的卡”或者“把模型量化一下”。不能说错,但只做了 20% 的工作。真正的推理优化是一条链路,从模型结构、权重精度、KV Cache 管理、批处理策略、调度框架、硬件选型到服务编排,每一层都有可榨的空间。训练营里我会把这条链路拆成可操作的模块,而不是丢一堆论文让你自己悟。
适合谁来学?如果你满足下面任意一条,这个方向就值得投入:做过模型微调但没碰过线上部署;用 Ollama 或 vLLM 跑过 demo 但一上并发就翻车;负责企业私有化部署,被“四张卡怎么撑住 200 并发”这类问题卡住;或者你是应用开发,想搞明白为什么同样调 API,别人比你便宜一半。
提示:推理优化不是“调参玄学”,它有一套可量化的指标体系。学之前先把 TTFT、TPOT、吞吐、显存占用这四个词刻进脑子里,后面所有手段都是围绕它们做权衡。
2. 推理优化的核心指标体系与常见误区
2.1 四个必须盯死的指标
TTFT(Time To First Token,首 token 延迟):从请求发出到第一个 token 返回的时间。对话类应用最敏感的就是它,用户等超过 1.5 秒就开始觉得卡。它主要受 prefill 阶段影响,和输入长度强相关。
TPOT(Time Per Output Token,单 token 输出时间):decode 阶段每生成一个 token 的平均耗时。它决定了“打字机效果”的流畅度,通常要求控制在 50ms 以内,体验才自然。
吞吐(Throughput):单位时间处理的 token 数或请求数,一般看 tokens/s。它直接决定你的单卡能扛多少业务,是成本的核心。
显存占用:权重 + KV Cache + 激活值。很多人只算权重,结果一上长上下文就 OOM,问题几乎都出在 KV Cache 上。
这四个指标不是孤立的,而是互相拉扯。你把 batch 调大,吞吐上去了,但 TTFT 和 TPOT 都会变差;你把精度压到 INT4,显存省了,但某些任务质量会掉。优化的本质就是在你的业务约束下找平衡点。
2.2 新手最容易踩的三个认知坑
第一个坑:以为量化越狠越好。INT8 通常几乎无损,INT4 在通用对话上也能接受,但涉及数值推理、代码生成、长链逻辑时,INT4 的掉点会很明显。我的建议是分场景:面向 C 端的闲聊可以激进,面向 B 端的合同解析、报表生成要保守,最好做 A/B 对比再定。
第二个坑:忽略输入长度分布。很多团队压测时用固定 512 长度,上线后用户粘贴一篇 8000 字的文档,prefill 直接把延迟拉爆。正确做法是统计真实请求的长度分布,按 P95 甚至 P99 来设计容量。
第三个坑:把并发等同于 batch。并发是同时到达的请求数,batch 是框架实际打包一起算的请求数。两者不是一回事。连续批处理(continuous batching)之所以重要,就是它让 batch 能动态变化,而不是等一批凑齐再算。
| 指标 | 关注阶段 | 典型目标 | 主要影响手段 |
|---|---|---|---|
| TTFT | prefill | < 1.5s | 输入截断、prefix cache、并行 |
| TPOT | decode | < 50ms | 量化、KV Cache 优化、批大小 |
| 吞吐 | 整体 | 越高越好 | 连续批处理、张量并行 |
| 显存 | 整体 | 留 20% 余量 | 量化、PagedAttention、卸载 |
3. 从零搭建推理环境的实操路线
3.1 硬件与框架选型:别一上来就堆卡
选型第一步不是买卡,是搞清楚你的业务形态。如果是离线批量任务(比如每天夜里跑一批文档摘要),那吞吐优先,可以用大 batch、低频率,甚至用消费级卡凑;如果是在线对话,延迟优先,就得考虑单卡性能和高带宽显存。
框架层面,目前主流就几条路:vLLM适合高并发在线服务,PagedAttention 和连续批处理是它的看家本领;TensorRT-LLM在 NVIDIA 卡上极致性能,但编译和适配成本高;Ollama适合本地快速验证和个人开发,部署简单但生产级调度能力弱;SGLang在结构化输出和多轮对话场景有优势。训练营里我会带大家把这几个都跑一遍,亲手感受差异,而不是听别人说哪个好。
注意:不要迷信“某个框架一定最快”。同一模型、同一硬件,不同框架在不同输入长度下的表现可能差一倍。选型必须用你自己的真实流量压测。
3.2 环境搭建的关键步骤
以 Linux + NVIDIA 环境为例,我通常按这个顺序来,避免依赖地狱:
- 确认驱动和 CUDA 版本匹配。用
nvidia-smi看驱动支持的最高 CUDA 版本,再决定装哪个版本的 PyTorch。 - 用 conda 或 venv 建独立环境,别在系统 Python 里折腾。
- 先装 PyTorch,再装推理框架,顺序反了容易出 ABI 冲突。
- 拉一个小模型(比如 Qwen 的 0.5B 或 1.8B)做冒烟测试,确认能跑通再上大模型。
- 记录每一步的版本号,写成
requirements.txt,方便复现。
# 冒烟测试示例:确认环境和显存都正常 python -c " import torch print('CUDA available:', torch.cuda.is_available()) print('Device:', torch.cuda.get_device_name(0)) print('Total mem GB:', torch.cuda.get_device_properties(0).total_memory/1024**3) "这一步看着简单,但我见过太多人跳过它,结果在大模型上排查半天,最后发现是环境问题。先用小模型验证链路,再上大模型,这是省时间的关键。
3.3 模型下载与本地化存储
企业私有化部署绕不开模型文件的获取和存放。几个实操要点:模型文件动辄几十 GB,磁盘要预留足够空间,最好单独挂一块数据盘;下载用支持断点续传的工具,别用浏览器;下载完校验文件完整性,避免半包导致加载报错。
存放路径建议统一规范,比如/data/models/{模型名}/{版本},方便多版本共存和回滚。如果是多机部署,考虑用共享存储或内网分发,避免每台机器重复下载。
4. 推理加速的核心手段逐个拆解
4.1 量化:省显存的第一把刀
量化的本质是把权重和激活从 FP16 压到 INT8、INT4 甚至更低。FP16 每个参数占 2 字节,INT8 占 1 字节,INT4 占 0.5 字节。一个 7B 模型,FP16 权重约 14GB,INT8 约 7GB,INT4 约 3.5GB。省下来的显存可以直接换成更大的 batch 或更长的上下文。
但量化不是免费的午餐。权重量化(如 GPTQ、AWQ)相对成熟,激活量化(如 SmoothQuant)难度更高。我的经验是:先做权重量化,观察质量掉点,再决定要不要动激活。校准数据集要用你自己的业务数据,别用通用语料,否则量化后的分布和真实输入对不上,掉点会更严重。
实操上,AWQ 在多数场景下比 GPTQ 更稳,尤其是小模型。INT4 的 AWQ 模型在 7B 级别通常能保留 95% 以上的效果,但一定要用业务测试集验证,别只看困惑度。
4.2 KV Cache 优化:长上下文的命门
KV Cache 是 decode 阶段缓存的历史键值对,避免重复计算。它的显存占用和层数 × 头数 × 头维度 × 序列长度 × batch × 精度成正比。序列一长,KV Cache 能轻松超过权重本身。
PagedAttention 的思路是把 KV Cache 分页管理,像操作系统管理内存一样,减少碎片、支持共享。vLLM 就是靠它把显存利用率拉上去的。另一个方向是prefix caching,如果多个请求共享相同前缀(比如同一个系统提示词),可以复用这部分 KV,省下大量重复计算。
提示:如果你的业务有固定系统提示词,务必开启 prefix caching。实测在客服、问答类场景,TTFT 能降 30% 以上。
4.3 批处理与调度:吞吐的放大器
连续批处理(continuous batching)是近两年推理框架的标配。传统静态 batch 要等一批请求凑齐、一起算完才能接下一批,GPU 空转严重。连续批处理让每个请求独立进出,GPU 始终有活干,吞吐能提升数倍。
调度策略上还有几个细节:优先级调度保证重要请求先算;抢占式调度在显存紧张时把长请求临时换出;chunked prefill把长输入的 prefill 切块,避免它长时间霸占 GPU 导致其他请求的 TPOT 抖动。这些在 vLLM 和 SGLang 里都有对应配置,训练营会带大家逐个开关对比效果。
4.4 并行策略:多卡怎么用才不浪费
单卡放不下或扛不住时,就上多卡。张量并行(TP)把单层切开分到多卡,适合层内计算量大、卡间带宽高的场景;流水线并行(PP)按层切分,适合层数多的模型,但会有气泡;数据并行(DP)每卡一份完整模型,适合吞吐扩展。
企业里常见的“四卡部署”问题,答案取决于模型大小和带宽。7B 模型单卡 24G 显存基本够用,四卡更多是为了并发而不是放不下。70B 模型才真正需要 TP。选 TP 还是 DP,要看你的瓶颈是显存还是吞吐。
| 并行方式 | 适用场景 | 优点 | 代价 |
|---|---|---|---|
| 张量并行 TP | 单卡放不下 | 显存分摊 | 卡间通信频繁 |
| 流水线并行 PP | 层数多 | 通信较少 | 有流水气泡 |
| 数据并行 DP | 吞吐扩展 | 实现简单 | 每卡一份权重 |
5. 企业私有化部署的完整落地流程
5.1 需求梳理与容量估算
落地第一步永远是算账。假设你的业务是客服问答,日均 5 万次请求,峰值 QPS 20,平均输入 800 token、输出 200 token。你需要估算:单请求的 KV Cache 占用、单卡能扛的并发、需要几张卡。
粗略公式:单请求 KV Cache ≈ 2 × 层数 × 头数 × 头维度 × 序列长度 × 精度字节。以 7B 模型(32 层、32 头、头维度 128)为例,序列 1000、FP16,单请求约 2×32×32×128×1000×2 ≈ 0.5GB。如果单卡 24G,权重占 14G,剩 10G 给 KV,理论上能扛 20 个并发,但实际要留余量,按 12 到 15 算比较稳。
这个估算不精确,但能帮你快速判断需要几张卡,避免拍脑袋采购。
5.2 服务编排与灰度上线
生产环境不能直接python server.py就跑。要有进程守护、健康检查、日志采集、指标监控。常见做法是用容器编排,把推理服务、网关、监控拆开。网关负责鉴权、限流、路由;推理服务专注算;监控盯 TTFT、TPOT、显存、错误率。
上线一定要灰度。先放 5% 流量,观察指标,再逐步放大。我踩过的坑是:压测环境用合成数据一切正常,上线后真实请求长度分布完全不同,直接 OOM。所以灰度阶段要采集真实请求的长度分布,回头修正容量模型。
5.3 成本核算与持续调优
推理成本 = 卡时成本 / 吞吐。优化吞吐就是降成本。除了前面说的手段,还有几个容易被忽略的点:请求合并(把多个短请求拼成一个 batch)、结果缓存(相同问题直接返回)、模型分级(简单问题走小模型,复杂问题走大模型)。
模型分级这招在企业里特别实用。用一个小模型做意图识别和简单问答,只有搞不定的才转给大模型,整体成本能降一半以上。训练营里我会带大家搭一个这样的两级路由。
6. 常见问题排查与避坑实录
6.1 高频问题速查表
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| 启动即 OOM | 权重 + KV 超显存 | 降精度、减 batch、开卸载 |
| TTFT 忽高忽低 | 长请求抢占 | 开 chunked prefill、限输入长度 |
| TPOT 抖动 | batch 波动大 | 调调度策略、固定 batch 上限 |
| 吞吐上不去 | GPU 利用率低 | 查是否静态 batch、开连续批处理 |
| 输出质量下降 | 量化过度 | 换 INT8、换校准集 |
| 多卡加速比低 | 通信瓶颈 | 换并行策略、查卡间带宽 |
6.2 几个只有踩过才知道的坑
坑一:显存看着够,一跑就爆。原因是 PyTorch 有缓存分配器,nvidia-smi显示的占用包含缓存,实际可用比看起来少。用torch.cuda.memory_summary()看真实分配,别被表面数字骗了。
坑二:量化模型加载慢。INT4 模型加载时要反量化,首次加载可能比 FP16 还慢。解决办法是预热,服务启动后先跑几个请求把权重加载进显存,再对外提供服务。
坑三:长上下文和并发不可兼得。上下文越长,KV Cache 越大,能并发的请求越少。如果你的业务既有长文档又有高并发,考虑把长文档任务单独拆一个服务,别和在线对话混在一起。
坑四:忽略 tokenizer 开销。大输入下,tokenize 本身可能占几十毫秒。用快速 tokenizer,或者把 tokenize 放到 CPU 侧并行做。
提示:排查性能问题,先定位瓶颈在 prefill 还是 decode,再看是计算瓶颈还是显存瓶颈。用 profiling 工具(如 PyTorch Profiler、Nsight)看时间花在哪,别靠猜。
7. 训练营的学习路径与实战安排
7.1 分阶段的学习路线
我把整个学习路径分成四段,每段都有明确的产出物,不是听完就忘的讲座。
第一阶段打基础:搞懂 Transformer 推理的计算流程、prefill 和 decode 的区别、四个核心指标的定义和测量方法。产出是一份自己写的性能测试脚本。
第二阶段上手框架:分别用 Ollama、vLLM、SGLang 部署同一个模型,压测对比。产出是一份框架选型报告,包含你业务场景下的推荐。
第三阶段深度优化:量化、KV Cache 优化、连续批处理、并行策略逐个实操。产出是一套调优后的配置,以及优化前后的指标对比。
第四阶段企业落地:容量估算、服务编排、灰度上线、成本核算。产出是一份可执行的部署方案。
7.2 实战项目的设计思路
训练营的实战项目不会用玩具数据。我们会用真实的业务场景:一个带长文档解析的客服系统,一个高并发的代码补全服务,一个多轮对话的助手。每个项目都有明确的性能目标,比如“四卡撑住 200 并发、TTFT 低于 1 秒”。
做项目时我会强调一个习惯:每次改动只动一个变量,记录前后指标。很多人一次改五个参数,效果好了不知道是哪个起作用,效果差了也不知道该回退哪个。科学的调优是控制变量。
7.3 学完之后你能带走什么
不是一堆笔记,而是几样能直接用的东西:一套可复现的压测脚本,一份针对你业务场景的选型与调优报告,一个跑通的企业级部署方案,以及一套排查性能问题的方法论。这些才是推理优化工程师真正的核心竞争力。
我个人在实际操作中的体会是,推理优化最值钱的不是会调某个参数,而是建立指标意识——任何改动都要用数据说话,任何结论都要能复现。这个习惯一旦养成,你面对任何新框架、新硬件都不会慌,因为你知道该测什么、该看什么。最后再分享一个小技巧:把你每次调优的配置和指标记成一个表格,时间久了,这就是你自己的经验库,比任何教程都值钱。