首页 / 资讯中心 / 文章详情

推理引擎不是四代升级线:调度、内存、复用与部署应分开看

推理引擎不是四代升级线:调度、内存、复用与部署应分开看 ★ FEATURED ARTICLE
把静态批处理、PagedAttention、前缀缓存、PD 分离画成四代产品很容易得出一个错误结论只要升级到最后一代前面的问题就一起消失了。实际选型时这几项技术经常同时存在解决的约束也不同。容量放得下不代表请求排得好省掉了重复 Prefill也不代表 Decode 会更快。10 月 20 日Google 发布 vLLM、SGLang 的原生 PyTorch TPU 后端说明调度器与硬件实现可以分层演进。对做性能工程的人更有用的问题是这次改动改变了哪一段工作代价转移到了哪里。Google 官方发布四条轴各有自己的账观察轴主要改变需要继续测什么批处理与调度哪些请求、多少 Token 一起执行排队时间、首字等待、输出间隔KV 内存组织逻辑 Token 怎样映射到物理块块浪费、共享写入、抢占次数前缀复用已计算的前缀能否再次使用命中长度、身份隔离、失效与重算Prefill/Decode 部署计算阶段放在哪些节点KV 传输、路由、负载不均与故障PagedAttention 的原论文讨论的是动态 KV 内存管理不要把它等同于完整的请求调度策略也不要把论文中的特定对比结果写成任何模型都能达到的常数。PagedAttention 论文2023例如多轮对话在下一轮发送完整历史时会产生重复的输入计算。前缀缓存直接针对这部分工作。但如果每次请求的系统提示都不同、输出又很长前缀复用能省下的工作就少得多。换成更大的显存池也不会让不存在的公共前缀自动出现。一个不用 GPU 的工作量检查下面只计算相邻请求的公共前缀长度不估计毫秒或吞吐。Token ID 是手写的教学输入不经过真实分词器。执行python3 example.py即可运行。from itertools import takewhile def common_prefix(a, b): return sum(1 for _ in takewhile(lambda pair: pair[0] pair[1], zip(a, b))) requests [[1, 2, 3, 4], [1, 2, 3, 8], [9, 2, 3, 4]] reusable [0] [common_prefix(a, b) for a, b in zip(requests, requests[1:])] original_work sum(map(len, requests)) remaining_work sum(len(row) - hit for row, hit in zip(requests, reusable)) assert reusable [0, 3, 0] assert original_work 12 and remaining_work 9 print({input_tokens: original_work, reusable_tokens: sum(reusable), remaining_prefill_tokens: remaining_work})这里的 12→9 只是这组三个序列的 Token 工作量变化。真实缓存可能同时查找更早的请求可能只在完整块边界命中也可能因模型、租户或容量限制不能复用。这个小程序没有证明“快了 25%”算子效率、队列以及数据搬运仍然会影响延迟。决策从瓶颈开始若日志显示大量 KV 抢占先检查容量预算、块组织和并发而不是直接拆成两套集群。若 GPU 有空档但请求排队检查 CPU 下发、调度轮次与批次形状。若一段公共提示反复计算再检查缓存键与路由。若长 Prefill 挤压流式输出才值得比较分块调度和 PD 分离的总成本。部署拆分还会增加网络传输、状态定位和失败回退。它可以解决干扰也会制造新的运维边界。一个完整方案应同时列出“省掉的工作”和“新增的工作”让同一条请求链路能够核对而不是把不同机器上的最好数字拼成演进史。本文没有运行真实模型、TPU 后端或多节点部署。离线例子仅验证公共前缀计算架构收益需要固定模型、硬件、输入输出分布、缓存热度和成功率再做同条件比较。选型的目标是处理手头的负载不是凑齐功能清单。
阅读完成 · 觉得有帮助?
咨询建站