0 行权重改动,77% 首字延迟下降:2026 年的推理提速为什么都发生在权重之外

0 阅读18分钟

同一个模型权重,同一批卡,同一个请求分布。只改一件事——哪一个实例接这个请求

长上下文负载下,P50 首字延迟(TTFT)掉了 71%~77%,KV cache 命中率从约 25% 涨到最高 82%,吞吐涨了 15%~16%。没有一个权重矩阵被改过,没有重新训练,没有换模型。

同一时间窗口里,还有几件事凑到了一起:OpenAI 用 2 名工程师把核心存储服务从 Python 重写成 Rust,CPU 效率涨 6 倍;佐治亚理工 + NVIDIA Research + 斯坦福的 BOOST 让 vLLM 同时读写 HBM 和主机内存,吞吐平均涨 31%;NVIDIA 把一个 3×3 卷积 + bias + ReLU 折进同一个 kernel,省掉两次中间张量写。

这些数字放在一起,指向一个不太好听但很实用的结论:过去几年我们习惯了从权重里挤性能——量化、剪枝、蒸馏、稀疏化。而 2026 年最猛的那批提速,几乎全部发生在权重之外。

原因不是玄学,是一条物理约束。先把这条约束讲清楚。

fig1-内存墙.png

一、旧范式的原罪:decode 是内存墙,不是算力墙

要理解为什么"不碰权重"能省这么多,得先知道 LLM 推理的哪一段卡在哪。

推理分两段,两段的瓶颈完全不同。

① PREFILL(处理输入)
   一次前向传播吃掉整段 prompt 的所有 token
   每个 token 都要和所有前序 token 做注意力 → 大矩阵 × 大矩阵
   算术强度高  →  COMPUTE-BOUND(算力受限)

② DECODE(逐 token 生成)
   每次前向只处理「上一个 token」,但要把全部权重读一遍
   算术强度低  →  MEMORY-BOUND(带宽受限)

算术强度(arithmetic intensity)就是 FLOPs 除以字节数。batch = 1 的 decode 阶段,每生成一个 token 要做大约 2N 次浮点运算(N 是参数量),同时要把 N 个参数从显存完整读一遍:

I_decode(batch=1) ≈ 2N FLOPs / (N × bytes_per_param)
                  = 2 / bytes_per_param

FP8(1 字节/参数)→  I2 FLOPs/Byte

拿它去比 roofline 的拐点:以 H100 为例,FP16 峰值算力与 HBM 带宽的比值在 3×10² FLOPs/Byte 量级(989 TFLOPS / 3.35 TB/s ≈ 295)。而 batch = 1 的 decode 只有个位数 FLOPs/Byte

差了将近两个数量级。

这个差距的直接后果是:GPU 的算力单元大部分时间在等数据。你花两万美金买的张量核心,在 decode 阶段有 90% 以上的时间处于饥饿状态。换句话说——decode 阶段省下来的每一分钱,都不是靠"算得更快"赚到的,而是靠"搬得更少、或者搬得更巧"赚到的。

这就是为什么下面这四条路全都不需要碰权重矩阵。它们是同一个物理约束的四种解法。

   目标:降低「每个 token 需要搬运的字节数」
                    │
   ┌────────────────┼────────────────┬──────────────────┐
   │                │                │                  │
 ① 复用已算的计算   ② 换更宽的搬运通道  ③ 让中间结果不落地   ④ 别让 CPU 饿死 GPU
   前缀路由          HBM + 主机内存并发   算子融合           服务层重写
   KV cache 命中     提取两层合并带宽    消除中间张量写      消除调度抖动
   25% → 82%         吞吐 +31%          AMAX 原地算        CPU 效率 6×

二、四条路的原理

路 1:复用已算过的计算 —— 前缀感知路由

大量 LLM 应用每次请求都送一段几乎一样的长前缀:系统指令、检索回来的文档、对话历史、源码文件。

任何现代服务引擎(vLLM、TensorRT-LLM)都能缓存这段前缀的 KV。但缓存只有在请求被送到同一个实例时才有用。而默认的负载均衡策略是随机的——它把共享同一前缀的请求打散到不同实例,于是每个实例都在从零重算同一段前缀。

AWS 在 2026 年 9 月给 SageMaker 推理加了一个 PREFIX_AWARE 路由策略,做的事简单到有点朴素:用请求的前缀做指纹,把前缀相同的请求尽量送到同一个实例。

配置文件层面只多了三个参数:RoutingStrategyPrefixLengthConcurrencyThreshold。不需要改模型容器,不需要改服务框架。

它的收益不是线性的,而是随"可复用前缀有多长、多常见"变化的——这一点后面单独讲,因为它同时也是这条路的天花板。

路 2:换更宽的搬运通道 —— 并发访问两层内存

BOOST 这篇论文(arXiv:2609.13592,佐治亚理工 + NVIDIA Research + 斯坦福)观察到的现象很具体:

GPU 内存有两个层级——一层是极快的 HBM,一层是通过 CPU-GPU 互联挂上来的主机内存。现有服务系统把它们当层级用:数据装得下就全放 HBM,装不下就先把数据 prefetch 到 HBM 再用。

两种做法都有一个共同的浪费:**主机内存的带宽从来没被好好利用过。**更糟的是 prefetch 这条路——它为了扩展容量,把数据写进 HBM,而这次写入消耗的正是本来该留给 demand load 的 HBM 带宽。所以论文里出现了一个反直觉的结果:prefetch 让 TPOT(每个输出 token 的时间)恶化了 6%

BOOST 的做法是:让 GPU 的每一波(wave)threadblock 同时、并按带宽比例访问两层

传统(层级式)           BOOST(并发式)
                         
Host ──copy──▶ HBM       Host ──┐
                │               ├──▶ GPU kernel
                ▼        HBM ────┘
           GPU kernel           (每波同时读两层,
             (只能吃一层)        按带宽比例分配)

为什么以前做不到?论文给了两个具体原因:已有的"按带宽比例放置"策略不了解 GPU wave,而且 GPU 页大小有 2MB——这么粗的粒度做不了细粒度的比例控制。

解法是让页分配本身感知 wave:静态权重用基于取模的页放置消除访问比例方差;动态分配的 KV 页池做成 wave-aware。

结果(vLLM + Grace Hopper 实测):

场景BOOST对比 prefetch
固定 batch,TPOT改善 4.3%恶化 6%
高吞吐服务,吞吐平均 +31%比 prefetch 高 15 个百分点

不需要改 kernel,不需要改模型。

路 3:让中间结果不落地 —— 算子融合

这一条是最纯粹的"减少内存流量"。

NVIDIA 的 cuDNN Graph API 教程里给了两个例子,都非常具体:

**例子一:Conv + Bias + ReLU 链式融合。**把 bias 加法和激活函数折进同一个 kernel,消除两次中间张量写。这两次写原本要把中间结果落到显存再读回来——纯粹的内存流量,零计算价值。

**例子二:矩阵乘的 epilogue 内联 AMAX。**一个 M=512, K=1024, N=512 的批矩阵乘,epilogue 里塞进缩放系数、bias、激活,再加一个 AMAX 归约

这个 AMAX 是 FP8 的关键原语:它产出下一层要用的量化 scale factor。放在同一个 kernel 里算,就意味着不需要为了取最大值再完整遍历一遍输出

论文和教程都强调同一个点:加速来自消除 epilogue 的内存流量,而不是来自更快的 GEMM 核心。

配套的两个工程手段解决的是"启动成本":

  • plan 序列化:把编译好的执行计划存成字节流,下次进程启动直接反序列化,省掉冷启动的 JIT 编译。
  • CUDA graph capture:把 kernel 派发录成一个图,回放时 CPU 的 launch 开销几乎消失。

路 4:别让 CPU 饿死 GPU —— 服务层重写

这一条最容易被误读成"Rust 比 Python 快",但实际情况不是。

OpenAI 在 2026 年 Q2 披露:2 名工程师,借助 Codex 和 GPT-5.5,用一个季度把核心在线存储服务 Habitat 从 Python 整体重写成 Rust。Habitat 是所有产品背后的那一层(ChatGPT、API、Codex 都经过它),每秒 7000 万+ 请求,管理 500PB 数据。重写后 Rust 版承担的生产请求已达 95%,CPU 效率约 6 倍,内存效率约 15 倍,Python 版本计划在几周内下线。

但真正值得看的是瓶颈清单

原 Python 服务的真实瓶颈修复手段
asyncio GIL 导致调度抖动数百毫秒换掉运行时
Statsig 配置刷新让 8 个进程同时卡住(每 60 秒解析一个大文件)加随机抖动 + 集中解析
连接池用 LIFO → "越慢的服务器收到越多请求"改成 FIFO
进程太多引发惊群Envoy HTTP/2 多路复用

**这四条里没有一条是模型推理问题。**瓶颈全在运行时调度、连接池策略、配置刷新这几处——GPU 侧的模型根本没被喂满。

这才是"服务层重写"的真实含义:它不是让计算变快,它是让计算不再空转。

附:还有一条不在"降本"里,但属于同一族 —— 把串行变并行

NVIDIA 在 9 月的 IFA 上发布了 PAIR(Personal AI Router)公测:一个透明代理,接管 Ollama / LM Studio 的端口,用 mDNS 发现局域网里的机器,把 agent 的每一个独立推理请求整份分给一台可用节点。

它有明确的边界——不池化显存、不分片模型、不拆分单个请求,每个节点都要有模型的完整副本。

数据是这样的(五个子代理的 Hermes 任务):

配置平均完成时间
单台 RTX Spark 笔记本18 分 00 秒
三机集群(Spark 笔记本 + DGX Spark + RTX 5090)8 分 48 秒(2.05×)
单张 RTX 50906 分 18 秒
双 RTX 50903 分 48 秒(1.66×)

注意第一行的算术:五个独立调用分到三台机器,理论最优是两波、也就是 2.5× 上限,实测 2.05× 达到上限的 82%。而双 5090 那一行是翻倍硬件换 1.66×——已经开始衰减。

三、理想丰满,现实骨感:五个死结

上面四个数字都很漂亮。但每一个都有明确的适用范围,越界之后收益会掉得很快。这一节是这篇文章里最该记住的部分。

死结 1:前缀路由的收益随前缀长度"陡降"

同一份 AWS 基准里,长上下文和短对话的结果差得很远:

负载类型P50 TTFTP90 TTFT吞吐KV cache 命中率
长上下文(8000 token 共享前缀,持续 1 小时)−71% ~ −77%−33% ~ −37%+15% ~ +16%约 25% → 82%
短对话(ShareGPT 风格,30 分钟)−13% ~ −16%−24% ~ −37%+1.7% ~ +2%约 30% → 80%

**吞吐那一列是判据。**长前缀负载下 +15~16%,短对话负载下只有 +1.7~2%——差了近一个数量级。

原因很直白:命中的前缀短,每次命中跳过的计算就少。前缀路由不是一个固定倍数的加速开关,它的价值等于"可复用前缀的比例 × 处理这些前缀的成本"。

另外三个前置条件,缺一个这条路就不成立:

  • 需要 ≥2 个实例。 单实例部署无处可路由。
  • 客户端要有序列化纪律。 共享的前缀必须是字节级稳定的——system prompt 里插一个时间戳、动态注入一个 request-id,前缀指纹就变了,命中率直接打散。
  • 要有过载保护。 某个前缀突然火爆,会让所有请求涌向同一实例形成热点。AWS 在这个基准里的应对是 ConcurrencyThreshold,实测 7 个实例的请求分布落在 13.3%~15.4%(理想均分是 14.3%),没有形成热点。

死结 2:BOOST 只在"真正有两层带宽"的硬件上成立

BOOST 的整个前提是 HBM 带宽与主机内存带宽可以相加。这要求两层是物理上分离的通道——Grace Hopper 就是这种形态(NVLink-C2C 提供 CPU-GPU 一致性互联,HBM 与 LPDDR5X 是两套独立介质)。

有工程师在 GB10(统一内存、128GB 单池)上实测复现时发现:numactl -H 只报出一个 NUMA 节点,CPU 和 GPU 共享同一个内存池,"两层带宽相加"这个前提根本不存在。他的结论是 BOOST 无法直接移植。

还有一层:per-token 的收益本身不大(4.3%),真正的大头是"同样硬件服务更多人"(吞吐 +31%)。如果你的场景是低并发、低延迟敏感,这个杠杆基本没用。

最后,它是研究代码而非产品——集成在 vLLM 里、只在 GH200 上测过。

死结 3:算子融合是"一次性的",且 plan 会失效

融合的边界是图里还有没有可省的中间写。你做过的融合,第二次就不能再省。

更麻烦的是 plan 序列化带来了新的依赖:

  • plan blob 与设备、cuDNN 版本绑定。 换卡、升级 cuDNN,这份 blob 直接失效,得重新编译。
  • 动态形状需要另配 kernel cache。 batch 或序列长度变了要重新 JIT,除非形状与缓存的 kernel tile 配置兼容。
  • CUDA graph 的 buffer 指针在捕获时被冻结。 指针一变,图就不能直接回放。

翻译一下:**这些优化的收益是确定的,但它们的运维债也是确定的。**每一次硬件或驱动升级,都要重跑一遍 autotune——收益是一次性的,成本不是。

死结 4:Rust 重写只在"瓶颈真的是运行时层"时才有效

这个案例特别容易被误读成"重写就能提效",但 OpenAI 自己披露的瓶颈清单说明:**Habitat 的瓶颈不是模型推理。**GIL 调度抖动、LIFO 连接池、配置解析风暴——这些都是服务层问题。

推理两个问题:

  • 如果你的瓶颈真是 GPU 侧,重写语言不会有 6 倍。 换个运行时不会让张量核心变快。
  • **迁移成本是真的,而且验证成本随生成速度上升。**AI 生成的代码越多越快,人工审查的重点就越从"写"转到安全性验证、边界条件、性能回归。同期的公开复盘里,Bun 从 Zig 移植到 Rust 用高度并行的方式"一次性"完成,而 GitHub 把 Copilot 运行时迁到 Rust 走的是增量路线——128 个 PR、约 14.5 周,因为这个产品在迁移期间还要继续发布。

重写规模没有变小,变小的只是打字时间。

fig2-四条路与边界.png

死结 5:PAIR 的收益天然递减

PAIR 不分片、不池化、不拆分单个请求,所以它的加速上限是纯算术:

加速上限 = 独立请求数 / 节点数    (向上取整的波数之比)

五个独立子调用 / 三个节点 = 两波 → 上限 2.5×,实测 2.05×。节点继续加,上限不动。而如果负载是一条长链(每一步依赖上一步),或者只有一个节点装了你要的模型,收益接近于零。

NVIDIA 自己也写明了:这些是"非官方、配置相关"的演示,不是通用基准,也不是线性扩展的承诺

四、判据:什么场景赚,什么场景亏

把上面五条压成一张对照表——这是可以直接贴进技术方案评审的那张:

手段谁在赚谁在亏关键前置条件
前缀路由长共享前缀、多实例、高并发(RAG、多轮对话、模板化机器人、代码补全)短前缀、前缀不共享、单实例部署≥2 实例;前缀字节级稳定;配过载阈值
并发两层内存(BOOST)高吞吐服务、容量不足需扩展、有独立 HBM+主机内存通道统一内存架构;低并发低延迟场景两层带宽物理可分;接受研究级代码
算子融合有可融合的算子链、含 FP8 量化 epilogue、启动成本占比高图已经很干净;频繁换卡/升级 cuDNNplan 需重新 autotune;动态形状要 kernel cache
服务层重写瓶颈在运行时/调度/连接池/配置层瓶颈在 GPU 侧迁移+验证成本真实存在;建议增量而非一次性
请求级多机路由(PAIR)大量独立短请求、有闲置机器、可容忍无 QoS长链依赖任务;单节点无副本;需要确定性延迟每节点需完整模型副本;上限受波数约束

五、选型决策树

你的推理服务慢,先量三件事:TTFT / TPOT / 吞吐
│
├─ 吞吐上不去,但 TTFT 和 TPOT 尚可
│   └─ 大概率是排队与调度 → ① 请求级路由(PAIR 型)
│                          ② 或查服务层:连接池策略、配置刷新、进程数
│
├─ TTFT 高(首字慢),TPOT 正常
│   ├─ 前缀高度重复?
│   │   ├─ 是 → ① 前缀路由 / 前缀缓存(最大收益:长前缀 + 高频复用)
│   │   └─ 否 → 检查 prefill 本身:批处理、分块 prefill、稀疏注意力
│   └─ 前缀短 → 收益有限,别指望它解决问题
│
├─ TPOT 高(每 token 都慢),且 batch 小
│   └─ 典型的 memory-bound 症状
│       ├─ 显存装得下 → ③ 算子融合 / 减少中间写 / 开 CUDA graph
│       └─ 显存不够要做 offload → ② 检查两层内存通道能否并发
│                                  (统一内存架构直接放弃这条路)
│
└─ 全部指标正常,但成本高
    └─ 先看是不是「算力空转」:GPU 利用率低 + 主线程等待高
        → ④ 服务层重写;确认瓶颈不在模型侧再动手

六、我的判断:从「买卡」到「清淤」

三点。

第一,2026 年的推理优化主题词已经变了:不是"更聪明的模型",而是"更少的浪费"。上面这些手段有一个共同性质——它们回收的都是本来就在发生的浪费:被重算的前缀、被浪费的主机内存带宽、被落地的中间张量、被调度抖动耗掉的时间。量化剪枝是拿精度换效率,这些是拿工程换效率,而且不付精度代价。这是它们在方法论上更强的地方。

**第二,这条路的天花板是"浪费的存量",不是"性能的增量"。**把浪费清干净之后就停了——这也是为什么前缀路由在短前缀场景只有 1.7%~2% 的吞吐收益:那里本来就没有多少可复用的东西。所有声称"系统层优化还有 10 倍空间"的说法都该被这个约束审查一遍。

**第三,真正的机会在"谁来做这套清淤"。**prefix 指纹稳定性、plan blob 的版本管理、路由策略与缓存寿命的联合调优——这些都不是能一行配置解决的事,都把工程复杂度从"模型侧"搬到了"服务侧"。SageMaker 把路由策略做成了三个配置项,HyperPod 把 KV cache 做成了两级(节点 CPU 内存做 L1、Redis 跨节点做 L2)——云厂商正在把"清淤"产品化。这可能是接下来一两年里,最不性感但最容易被低估的一块基础设施进展。

下一个值得盯的信号:看这些手段能不能叠加。前缀路由提升 cache 命中率,BOOST 改变 KV 页的驻留策略,算子融合改变内存流量结构——它们各自的正收益会不会互相抵消?目前每篇都是单点基准,没有一篇给出"全开"后的联合实测。如果联合收益明显低于各自之和,那么"系统层还有多少空间"这个问题的答案会比今天的乐观估计低不少。


参考

  • AWS, Reduce LLM latency with prefix-aware routing on Amazon SageMaker Inference, 2026-09-10(Llama 3.1 70B Instruct,7× ml.p5.48xlarge,vLLM + prefix caching;16 种配置,数据为 AWS 自报)
  • Saxena A, Ju J H, Taneja H, Tsai P-A, Jaleel A, Kozyrakis C, Qureshi M. BOOST: Concurrent Access to Host Memory and HBM to Accelerate LLM Inference. arXiv:2609.13592(佐治亚理工 + NVIDIA Research + 斯坦福);集成于 vLLM,Grace Hopper 评测
  • OpenAI Habitat 重写:OpenAI 2026 年 Q2 披露,The New Stack 等报道(2 名工程师 × Codex + GPT-5.5;CPU 6×、内存 15×;95% 生产请求)
  • NVIDIA cuDNN Frontend Graph API 教程(经 MarkTechPost 报道):Conv-Bias-ReLU 融合、epilogue AMAX、plan 序列化、动态形状、CUDA graph capture
  • NVIDIA PAIR(Personal AI Router)公测,2026-09 IFA Berlin;NVIDIA 自述为"非官方、配置相关"的演示,非通用基准
  • GB10 统一内存环境下 BOOST 不可直接移植的第三方实测复盘

数据说明:所有性能数字均为厂商或论文作者自报,本文未独立复现。SageMaker、PAIR 的数据为官方基准,其中 PAIR 的演示 NVIDIA 明确声明不构成性能保证;BOOST 的数字来自论文自身在单一硬件平台(Grace Hopper)的实测。第三方观点与未获独立验证的细节已在正文标注来源类型。本文为技术分析,具体收益请以自有负载实测为准。