一、首Token时延与吞吐为何互相牵制
推理服务的用户体验由两个数字定义:首字出现的快慢,以及后续文字流出的速度。前者对应首Token时延,后者对应每秒输出Token数。运营者关心的则是第三个数字,即单卡每秒能服务多少Token,也就是吞吐。三者之间存在结构性矛盾。
矛盾的根源在批处理。GPU的算力只有在矩阵足够大时才能被充分利用,单请求推理的算力利用率往往不足两成。把多个请求合并成批,利用率可以提到七成以上,吞吐随之数倍提升。但合并需要等待,等待就意味着排队时延,首字体验因此变差。
时延的完整拆解包含三段。排队段是请求到达后等待被纳入批次的时间;预填充段是处理输入提示的时间,与输入长度近似线性相关;解码段则是逐个生成输出Token的时间,每个Token需要一次完整的前向计算。首Token时延等于排队段加预填充段,与输出长度无关。
三段的优化手段完全不同。排队段靠调度策略压缩,预填充段靠分块与并行改善,解码段靠显存带宽与批次大小决定。把三段分开度量,才能知道优化投入应该放在哪里。实践中常见的误区是笼统地看整体时延,结果在解码段反复调优,而真正的瓶颈在排队。
还需要区分场景。交互式对话对首字极为敏感,用户等待超过一秒就会感到迟滞;批量文档处理则完全不关心首字,只在意单位时间处理量。两类场景若混在同一个服务实例中,参数无论怎么调都会有一方不满意。
二、连续批处理与调度队列的设计
静态批处理要求同批请求同时开始、同时结束,短请求必须等待长请求跑完,GPU在末段大量空转。连续批处理打破了这一约束:每完成一步解码就检查队列,已结束的请求立即退出并释放显存,等待中的请求随即补位。实测中,同样的硬件下吞吐可提升两到三倍。
插入时机需要权衡。每步都检查会引入调度开销,且频繁变更批次结构会打断内核执行的连贯性。工程上通常每若干步检查一次,或在有请求结束时才触发重组。检查间隔设为四到八步,调度开销可控制在总耗时的百分之二以内。
优先级分层是压低首字时延的关键。把请求分为交互与批量两类,交互类始终优先纳入批次,批量类只在剩余容量中填充。这样交互请求的排队时间稳定在数十毫秒,批量请求的完成时间略有延后但总吞吐不受影响。
预填充分块进一步缓解长输入的干扰。一个包含数万Token的长提示,其预填充可能占用数百毫秒,期间所有解码步骤被阻塞,正在输出的请求会出现明显卡顿。把长提示切成固定大小的块,与解码步骤交错执行,卡顿感基本消除,代价是长输入的整体处理时间延长约一成。
三、显存复用:分页管理与前缀共享
显存是推理服务最稀缺的资源。模型权重占据固定份额,剩余部分要留给KV缓存,而KV缓存的大小与并发数、上下文长度成正比。管理方式直接决定了单卡能承载多少并发。
早期实现为每个请求预留最大长度的连续显存,浪费极其严重。实际输出长度往往远小于上限,预留部分从未被使用。分页管理借鉴了虚拟内存的思路:把KV缓存切成固定大小的块,按需分配,逻辑上连续而物理上分散。显存碎片率从三成以上降到百分之四以内,同等显存下并发数提升两倍有余。
前缀共享是第二个杠杆。多数在线场景中,大量请求共享相同的系统提示或少数几种模板,这部分KV缓存完全相同。把共享前缀的缓存块标记为只读并允许多请求引用,可节省可观显存。在系统提示较长的客服类应用中,节省比例可达四成。
共享需要引用计数与写时复制。当某个请求在共享前缀之后追加内容时,从分歧点开始分配新块,之前的块继续共享,引用计数归零才真正释放。这套机制的实现复杂度不低,但收益随共享度提升而放大,值得投入。
换出与回收是最后一道保障。显存不足时,把优先级低且长时间未活跃的请求的KV缓存换出到主机内存,需要时再换回。换入换出的带宽有限,因此只应作为过载时的缓冲手段,而非常态。触发阈值宜设在显存占用九成,并配合请求准入控制,从源头限制并发。
四、分级服务与容量规划方法
把上述技术组合起来,就可以对外提供分级服务。基础档保证吞吐但不承诺首字时延,适合批量处理;标准档承诺首字时延在八百毫秒以内;高级档承诺三百毫秒以内并预留专属容量。三档使用不同的调度参数与准入阈值,物理资源则可以共享。
容量规划需要一套可计算的模型。单卡吞吐大致等于批次大小乘以每步耗时的倒数再乘以批内输出速率均值,而批次大小受限于显存容量除以单请求KV缓存占用。把模型参数量、上下文长度分布与目标时延代入,即可估算单卡承载的并发数,进而反推所需卡数。
估算之后必须实测校正。真实流量的长度分布、突发程度与提示重复度都会显著影响结果,理论值与实测值相差三成并不少见。建议用真实流量回放做压测,逐步加压直到时延超出承诺,记录此时的并发数作为规格容量,并留出两成余量应对波动。
最后是持续观测。把首字时延、输出速率、显存占用率、批次填充率与准入拒绝率五项指标纳入常规监控,任何一项偏离基线都提示容量或参数需要调整。其中批次填充率最容易被忽视,它直接反映调度效率,长期偏低说明请求到达稀疏或分层策略过于保守。
结语:推理服务的调优本质上是在时延、吞吐与成本三者之间寻找当前业务最合适的落点。连续批处理解决了资源空转,分页管理与前缀共享解决了显存浪费,分级服务则把技术能力翻译成用户可选的承诺。这些手段并不互斥,但收益有先后:先做连续批处理与分页管理,再谈前缀共享与换出,最后才是精细的优先级调参。按这个顺序推进,多数团队在几周内就能看到成倍的容量改善,而不必急于更换硬件。