一个LLM推理请求看起来是一件事:提示词进去,token出来。但在底层,它是两件被塞进同一件风衣里的事。
预填充(prefill)读取整段提示词,并行计算注意力,是计算密集型,喜欢大批量,GPU能以接近峰值的浮点算力把它啃完。解码(decode)一次只生成一个token,自回归,每一步都依赖上一步,是内存带宽密集型,几乎用不满GPU的算力——而恰恰是它,决定了用户盯着转圈图标要等多久。
大多数服务栈把这两个阶段放在同一批GPU上、同一个批次里、用同一套调度逻辑跑。这正是团队在连续批处理、量化调优、KV缓存容量上反复缠斗的半数延迟病症的根源。你优化的不是一个负载,而是在为两个资源特征完全相反的工作负载找一个统一配置,而这个折中方案比任何一方的最优解都差。
预填充和解码,根本不是同一种问题
预填充做的事很直白:拿几千个token,跑一次大的前向传播,一次性算完整个序列的注意力。它高度可并行、矩阵乘法密集,跑预填充的GPU接近理论算力上限。提示词越长,工作量越大,但扩展是高效的——这也是为什么短提示词的首次token时间很便宜,长提示词会涨,但不会涨到灾难级别。
解码正好相反。每一步只产出一个新token,也就是一行新的激活值,意味着GPU要搬运海量的KV缓存进出,去换一次相对微小的数学计算。解码是带宽受限,不是算力受限。一块H100在解码时算力利用率停在个位数并不奇怪,因为瓶颈是从高带宽内存里流式读取缓存的键和值有多快,而不是矩阵乘法有多快。
这不是同一个问题的两种口味,而是两个不同的问题,恰好共用一个模型和一套权重。把“一个请求”当作调度原子单元的服务基础设施,优化错了颗粒度。
连续批处理掩盖了错配,但没有解决它
连续批处理——多数现代服务引擎背后的技术——解决了一个真实问题:静态批处理会让GPU空等一批里最慢的序列跑完。允许新请求在批次运行中途中加入、已完成的请求被逐出,就能在一池并发的解码步骤里保持GPU占用率。这是实打实的、重要的收益。
但连续批处理本质上是解码侧的优化,却挂着一个通用标签。新请求到达时,它的预填充总得在某个地方发生,而在多数实现里,它就发生在同一批GPU周期里,和已经在途的请求的解码步骤抢资源。一段长提示词的预填充,可以卡住另外十几个正在生成中的用户的解码——这就是“预填充干扰”,表现为仪表盘上找不到明显原因的延迟尖峰。硬件没有变慢,是一个大提示词独占了算力,其他人的token流跟着卡顿。
把预填充切成小块、与解码步骤交错执行(有时叫分块预填充)能缓解,但它仍然是在结构性错配之上打的一个调度补丁。你是在把一份资源按时间切片,分给两个最优批大小不同、最优精度不同、对延迟敏感度也不同的负载。
量化修不好架构问题
量化被当作推理成本的万能杠杆来卖:压小权重、压小KV缓存、每块GPU塞进更多并发序列、账单变低。这些都对。但量化主要打的是解码侧的瓶颈——要搬的内存少了,解码步骤更快,缓存占用更小。它对预填充的作用相对有限,因为预填充本来就不是内存受限,它是计算受限,而计算量不会因为权重精度变小就缩水。
于是团队激进地量化,看到解码吞吐提升,然后纳闷为什么长提示词的首次token时间几乎没动,为什么混合长短请求做批处理仍然产生不可预测的尾延迟。答案是:量化优化的是本来就好修的那一半,预填充与解码之间的结构性调度冲突原封不动。它是在一个未解问题之上叠加的真实收益,不是对解决问题的替代。
拆开部署,才是真正的杠杆
结构上站得住的修法,是别再假装预填充和解码应该同时待在同一套硬件上。分离式服务把集群拆成预填充池和解码池。请求的预填充跑在计算优化的节点上,为大 batch 并行吞吐调优,没有解码流量抢周期。产出的KV缓存随后通过高速互联传输——而不是重算——送到解码池,那边按内存带宽和高并发调优,服务大量在途序列。
这听起来像是为额外的管道付额外的复杂度,确实是。你需要一条缓存传输路径,需要给两个池而不是一个池做容量规划,还需要在两者之间智能路由请求。但回报是每个池都能独立调优、独立扩缩,甚至独立选硬件。预填充池可以跑更少、更大、计算密度高的GPU;解码池可以跑更多、更便宜、对内存带宽友好的硬件,按并发量而不是原始算力来定规模。你不用再为解码时用不上的算力、预填充时不需要的带宽买单。
经济账的变化很具体:成本模型从“每请求GPU小时”变成“预填充GPU秒 + 解码GPU秒 + 缓存传输成本”,三项各自可独立优化。这比调一个全局批大小、指望它对所有请求形态都是合理折中,要好使得多。
对自建服务栈的团队意味着什么
如果你跑的是自己的推理基础设施,而不是调托管API,可落地的结论是:别再把“延迟”当成一个要追的数字。首次token时间和token间延迟由不同资源支配,把它们捆在相同硬件上,等于保证你永远在两者之间做取舍。分开测量,分开做容量规划。
如果你的流量里提示词长度差异很大——长文档上下文挨着短聊天轮次——分离式部署不是锦上添花,而是阻止长提示词拖垮其他人解码延迟的唯一办法。
量化、投机解码、更聪明的批处理启发式,这些都还值得做,它们是每个池内部真实的、可叠加的收益。但它们是战术。战略问题是:你的服务架构是否承认单个LLM请求暗地里是两个负载,还是仍在假装它们是一个、指望调度器把差异抹平。调度器抹不平,至少不可能无限期抹平。错配是架构性的,架构问题需要架构层面的修法。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.