如何优化大模型服务的并发、吞吐和响应速度?
如何优化大模型服务的并发、吞吐和响应速度?

这道题考的是大模型推理服务的性能优化。核心就一件事:怎么让模型在有限的硬件资源下,服务更多的用户,同时保证响应速度。
搞大模型服务的同学经常会遇到这种情况:模型跑起来了,但并发一高就卡顿,吞吐上不去,响应时间忽快忽慢。这道题就是来帮你理清思路的。
三个指标搞不清楚?先理解 TTFT、TPOT、Goodput
很多人优化了半天不知道在优化什么,就是因为连指标都没搞清楚。
TTFT(Time To First Token),就是用户发请求到收到第一个 token 花了多久。这段时间主要是模型在"思考"——排队、加载、预填充。TTFT 高说明你的队列或调度有问题,可能请求堆积了,或者 GPU 还没准备好。
TPOT(Time Per Output Token),生成每个 token 平均要多久。这个指标反映的是生成阶段的稳定性。TPOT 高说明模型生成太慢,可能是显存不够、批处理没做好、或者模型本身推理速度有限。
Goodput 是最容易忽略但最关键的指标。它不是简单的成功数量,而是满足 SLO 要求的有效吞吐量。比如你设置了 p99 延迟不超过 2 秒,那 Goodput 就是 2 秒内完成的有效请求数。
简单类比一下,就像点外卖:
- TTFT = 骑手接单时间(等待越长越烦躁)
- TPOT = 骑手配送时间(配送越快体验越好)
- Goodput = 你最终吃到的满意外卖数量(只算准时送达的)
记住一个公式:Goodput = SLO达标率 × 实际吞吐。你追求的应该是高 Goodput,而不是单纯的高吞吐。

vLLM 的吞吐上限不是算力,是显存与调度的"并发安全区"
很多同学以为模型跑不快是因为 GPU 算力不够,于是疯狂加卡。但实际情况往往是:显存先打满,GPU 算力还闲置着。
vLLM 为什么能大幅提升吞吐?核心在于 PagedAttention 和 连续批处理。
简单说,PagedAttention 就是把 KV Cache 像内存分页一样管理。以往每个序列的 KV Cache 需要连续内存,大模型上下文又很长,动辄几万 token,显存根本装不了几个并发请求。
vLLM 把 KV Cache 切成固定大小的"页",按需分配。就像图书馆的书架,每个格子放一本书,不浪费空间,需要多少放多少。这样显存利用率大幅提升,能同时处理更多请求。
连续批处理(Continuous Batching)解决的是另一个问题:变长序列的调度效率。传统静态批处理要等所有请求都完成才能处理下一批,浪费大量 GPU 空闲时间。连续批处理是请求完成一个就补进来一个,GPU 始终有活干。
打个比方,就像餐厅厨房:
- 显存 = 冰箱空间(决定了能同时备多少菜)
- 连续批处理 = 流水线作业(一批菜做完马上接下一批,而不是等所有菜做完再开新单)
所以 vLLM 的吞吐上限,本质上是显存容量和调度效率共同决定的并发安全区,不是 GPU 算力。你可以理解为:显存决定能同时放多少请求,调度决定 GPU 有多少时间在干活。

优化技术三板斧——量化、缓存、推测解码
实际工作中,最常用的优化手段就三个:
量化(Quantization)
模型权重从 FP16/BF16 压缩到 INT8 甚至 INT4,显存占用直接降一半甚至更多。W4A16 是目前比较主流的方案——权重 4-bit,激活值保持 16-bit,在精度和性能之间取得平衡。
AWQ 和 GPTQ 是两种常用量化方法。AWQ 更适合新模型,效果好但量化速度慢;GPTQ 量化快,适合大批量处理老模型。
就像快递打包:原来用大纸箱装,现在用压缩袋,能装的件數翻倍。
KV Cache
大模型生成是自回归的,每个 token 都依赖于之前所有 token 的 Key 和 Value。如果每次请求都重新计算,浪费巨大。KV Cache 把计算好的 Key-Value 存下来,下次相同前缀的请求直接复用。
更进一步,可以做 Prefix Cache——把常见系统提示、用户模板缓存住,减少重复计算。
这就像设立中转仓:货物到了大仓不直接送到用户,而是存到离家近的中转点,下次同一片区的订单直接从这里出库。
推测解码(Speculative Decoding)
用一个小型"草稿模型"快速生成多个候选 token,再用大模型验证。验证通过的 token 直接保留,不通过的丢弃重来。
加速效果明显:平均能快 2-3 倍。代价是要多跑一个模型,显存占用增加。
这就像考试抄答案:小弟先快速写一遍,你再快速核对一遍,比你自己写快多了。

高风险配置与资源配额——别让高峰把你打回原形
系统跑稳定了不代表真能扛住高峰。几个容易翻车的坑:
显存设太满 + 高并发 = OOM 崩溃
很多同学为了"充分利用"资源,把显存占用设到 90% 以上。日常低负载没问题,但高峰一来并发请求一多,KV Cache 分配超出预期,直接 OOM。这是最常见的线上事故。
建议预留 20-30% 的显存 headroom,给突发流量留缓冲空间。
混合长短请求不隔离 = 尾延迟爆炸
一个请求要生成 2000 token,另一个只要 20 token。短请求被迫等待长请求完成,p99 延迟飙升。一定要做请求分桶:短请求和长请求走不同队列,用不同策略处理。
超长上下文走单独服务池
128K 上下文和 4K 上下文的资源占用差几十倍,混在一起互相影响。超长上下文请求单独部署,用不同的资源配置。
就像节假日高速收费站:不做限流就彻底堵死,做了分流才能基本畅通。

部署架构与 SLO 契约——给团队一个明确承诺
最后说说怎么部署。技术栈其实很成熟:FastAPI 做 HTTP 接口,Docker 容器化,Kubernetes 做编排。
但比选什么框架更重要的是明确服务契约:
- 模型规格:用的什么模型、量化方案、上下文长度上限
- 请求规格:最大 token 数、并发限制、超时策略
- SLO 目标:TTFT、TPOT、Goodput 分别要达到多少
这个契约不仅是技术承诺,也是团队协作的基础。前端知道该怎么设计用户体验,产品知道怎么设定功能边界,运维知道什么时候该扩容。
就像租车服务:你要告诉客户能租什么车、限速多少、超时怎么计费,而不是让客户自己猜。

面试怎么答
基础版
优化大模型服务性能,我从三个指标入手:TTFT、TPOT 和 Goodput。TTFT 反映排队调度效率,TPOT 反映生成阶段稳定性,Goodput 才是最终目标——满足 SLO 的有效吞吐。
核心技术手段有三个:量化(AWQ/GPTQ)降低显存占用、KV Cache 减少重复计算、推测解码加速生成。vLLM 通过 PagedAttention 管理显存,连续批处理提升 GPU 利用率,本质是把"显存与调度共同限定的并发安全区"最大化。
实践中要避免显存占满、混合请求不隔离、超长上下文混用等问题。部署时要明确模型规格、请求规格和 SLO 目标,给团队一个清晰的服务契约。
加分版
我认为优化的本质是 Goodput = SLO达标率 × 实际吞吐。脱离 SLO 谈吞吐没有意义——疯狂压榨性能但尾延迟失控,用户体验依然很差。
吞吐上限不是算力决定的,而是显存容量和调度效率共同限定的并发安全区。vLLM 的 PagedAttention 把 KV Cache 分页管理,连续批处理让 GPU 始终有活干,这两个机制缺一不可。
高风险配置要特别关注:显存 headroom 要留足、长短请求必须队列隔离、超长上下文单独部署。
最终要给团队一个推理资源契约,明确模型规格、请求规格和 SLO 目标,从平台视角思考 SLO 交付承诺。
一句话总结
优化大模型服务就是围绕 Goodput 这个北极星指标,通过量化、缓存、推测解码等技术扩大"并发安全区",同时做好资源隔离和 SLO 契约管理。
