摘要
这篇文章想回答一个看似分散、其实高度统一的问题:为什么这两年围绕大模型推理的系统创新,越来越不像是在“优化一个神经网络”,反而像是在“设计一个内存系统”?
如果把2023年以前的大模型工程叙事概括成“拼FLOPS、拼Tensor Core、拼训练吞吐”,那么2024–2026年的推理叙事,已经明显转向了另一条主线:KV cache、TTFT/TPOT、continuous batching、prefix reuse、prefill/decode disaggregation、hierarchical cache、CXL memory pool。
这不是偶然。Transformer的自回归推理天然会把“历史”变成一块不断增长、必须反复访问的状态;而RLHF/RLVR、reasoning、agent workflow、长上下文和多轮交互,又把这块状态推到了系统设计的正中央。OpenRLHF甚至直接指出,在PPO风格的RLHF/RLVR里,inference阶段经常占到总运行时间的90%以上;同一时期,Mooncake、LMCache、Strata、KVFlow、Beluga、TraCT这类系统则在从不同层面把KV cache提升为“一等公民”。
站在今天回看,真正的变化不是“某个kernel更快了”,而是推理系统的重心,正在从计算图转向内存图。本文会沿着这条线,把Mac/Uma、NVIDIA/NVLink、FlashAttention、vLLM、RL rollout、Mooncake、LMCache、CXL,以及2025–2026的新论文串成一条完整主线。
目录
-
- 大模型推理的本质:Prefill vs Decoding
-
- KV Cache:Transformer推理的真正状态变量
-
- 为什么瓶颈会从compute转向memory
-
- RL / Agent:为什么后训练把问题推向decoding
-
- 为什么Mac / UMA会重新变重要
-
- 为什么FlashAttention救不了decoding
-
- 推理优化的四层结构:kernel、engine、model、hardware
-
- Continuous Batching:从“请求级”到“token级”调度
-
- 模型结构如何直接决定系统上限:MQA / GQA
-
- KV Cache其实是一种高度冗余的外部记忆
-
- 为什么很多线上系统仍然在“重复计算历史”
-
- 第一代KV-centric架构:DistServe、Mooncake、LMCache
-
- 为什么Mooncake / LMCache不是终点
-
- 新一代Memory-centric架构:Strata、CAKE、R-KV、KVFlow、FastSwitch、CacheBlend
-
- CXL:看起来像终极答案,为什么现实里还很难
-
- LLM serving正在变成一个“操作系统问题”
-
- KV cache之后是什么:Mamba、RWKV与“在线压缩记忆”
-
- 结语:三条真正的主线
1. 大模型推理的本质:Prefill vs Decoding
现代主流LLM,大多沿着GPT这条 causal decoder-only Transformer 路线发展:输入是“到目前为止的上下文”,输出是“下一个token的概率分布”。这与BERT这种 bidirectional encoder 路线的根本区别在于:GPT类模型天然支持逐token自回归生成,而BERT的预训练目标是masked language modeling,本质上依赖左右文共同参与表示计算。换句话说,KV cache只对causal decoder天然成立,对BERT这种双向编码器并不是一等机制。
一旦把推理过程按执行阶段拆开,你会发现LLM serving其实不是一个统一的工作负载,而是两个物理性质很不一样的阶段叠在一起。
第一阶段是 prefill。它读取整段输入prompt,对所有输入token做一次前向传播,并为每一层生成后续要复用的K/V状态。这个阶段的并行度高、矩阵乘比例大、GPU Tensor Core能用得很满,所以更接近我们熟悉的“训练前向”形态。Sarathi-Serve和DistServe都明确把prefill视为高延迟、但能显著吃满GPU计算资源的阶段。
第二阶段是 decoding。模型每次只生成一个token,然后把这个token追加到历史,再生成下一个token。这个阶段每一步的算子规模不大,GPU不容易被纯算力吃满;真正贵的是:你必须把历史KV cache读回来参加注意力计算。Sarathi-Serve直接指出,decode iteration虽然单次延迟低,但计算利用率也低,因此系统必须依赖batching才能把吞吐做起来。
这就是理解后面所有系统工作的第一把钥匙:
prefill更像compute-bound,decode更像memory-bound。
当然,这不是绝对的,而是workload-dependent。文档摘要、RAG、大段代码分析等长输入场景,prefill会非常重;实时聊天、长输出推理、RL rollout、agent多轮执行,则会让decode和KV cache问题变得更突出。DistServe在实际实验中就专门区分了chatbot、programming assistant、document summary这类不同workload,并强调TTFT与TPOT目标并不相同。
所以,后面凡是看到有人说“LLM推理是算力问题”或“LLM推理是内存问题”,你都应该先追问一句:你说的是prefill还是decode?你说的是哪类workload?
如果只从算法式子看,自注意力似乎只是
Attention(Q, K, V) = softmax(QK^T)V。
但在推理系统里,这个式子最重要的副产品不是输出,而是历史状态如何被保存。
在causal decoder中,每来一个新token,模型都会在每一层计算该token对应的 K 和 V,并把它们保存下来;之后生成新token时,当前token的 Q 只需要去和全部历史的K/V交互即可。于是,KV cache实际上存的是:每一层、每个历史token的Key和Value表示。它不存 Q,因为 Q 只属于“当前这一拍”;它也不存完整的attention矩阵,因为后者随当前 Q 的变化而变化,而且体量更大。这个机制依赖causal mask:历史不会被未来改写,所以过去token的K/V可以安全复用。
这件事在系统层面的意义非常大。
如果没有KV cache,那么第 t 步生成时,你需要重新对前 t-1 个token做前向计算,相当于重复计算整个历史;有了KV cache之后,你只需要对新token做一次增量前向,但仍然要把历史K/V读出来参加注意力。于是,问题从“反复重算历史”变成了“反复读取历史”。Shazeer在Multi-Query Attention论文里对这一点说得非常直接:incremental decoding慢,核心是反复加载巨大的K/V张量所带来的memory-bandwidth cost。
也因此,KV cache不是某个实现细节,而是Transformer自回归推理的真正状态变量。对于一个有 L 层、H_kv 个KV头、每头维度 d、上下文长度 T、batch为 B 的模型,KV cache的规模大致按
O(L * H_kv * d * T * B)
增长。你一旦把 T 拉长,把 B 拉高,或者让一次请求分裂成多条trajectory,这块状态就会迅速膨胀。CAKE、R-KV、FlexiCache这类2025年的论文,本质上都是在承认并处理这一事实:KV cache本身已经大到必须被压缩、分层、淘汰和预测。
这里还有一个经常被忽略的差别:模型参数 weights 是共享且静态的,而KV cache是按请求增长且互不共享。前者是“把知识装进模型里”;后者更像“把每次推理的思考过程存起来”。这会直接导致一个系统级分水岭:同样是显存/内存占用,weights的成本更偏容量,而KV的成本更偏容量 + 带宽 + 延迟。这也是为什么我后面会说,未来很多场景里,KV cache的压缩价值可能比参数压缩更大。
3. 为什么瓶颈会从compute转向memory
很多关于LLM推理的争论,实际上都输在“把workload混为一谈”上。
更精确的说法不是“推理越来越偏向decode”,而是:
只要工作负载在走向多轮、长历史、长输出、长CoT、可复用上下文,系统瓶颈就会从prefill的计算,逐渐转向decode阶段对KV cache的访问。
这和“prompt到底变长还是变短”不是一回事。
先看最容易理解的聊天场景。如果用户输入短、系统提示稳定,而输出较长,那么prefill只做一次,decode却要重复几十上百次;这时decode的累计成本很容易压过prefill。Sarathi-Serve、DistServe和OpenRLHF都是在这种“prefill与decode特性完全不同”的观察上做系统设计的。
但这并不意味着所有工作负载都如此。
在RAG、长文总结、代码仓分析等任务里,输入可能有几千到几十万token,输出却很短;这类workload的第一个大问题是TTFT,因为模型必须先把长输入完整prefill完。LinkedIn那篇关于prefix reuse调度的理论论文就明确把“long-prompt, short-output”视为一个prefill-dominant区间,并指出在这种场景下,prefix reuse对TTFT非常关键。
真正有意思的是 agent / reasoning / RL rollout。
这些场景里,逻辑上的“上下文”确实在变长:模型思考、调用工具、读回工具输出、再继续思考,历史不断追加。但如果系统能有效复用KV cache,那么增长的不是“每轮重新prefill的计算量”,而是“需要继续维护和读取的历史状态量”。也就是说,长history并不自动等于更重的prefill;它可能意味着更大的KV cache、更高的decode memory pressure。 OpenRLHF明确把long CoT视为训练效率的关键瓶颈,并把vLLM接入rollout engine来缓解长推理链带来的推理负担。R-KV更进一步,直接把reasoning model的“超长输出导致KV cache爆炸”作为问题出发点。
这也是为什么我会说:
“长prompt”和“长history”不是同一件事。
- 长prompt,如果每次都要重新喂进去,是prefill问题。
- 长history,如果以KV cache形式被保留下来,是decode / memory问题。
现代API和serving system的大量创新,恰恰都是围绕这个区别展开的:prompt caching、prefix reuse、PD disaggregation、hierarchical cache,本质上都在努力把“重复计算的长prompt”转换成“可复用的长history”。
4. RL / Agent:为什么后训练把问题推向decoding
如果只看SFT时代,训练的主角还是标准的forward/backward:数据集给定,模型吃进去,算损失、回传梯度。那是典型的“训练是核心、推理只是辅助”的时代。
但后训练,尤其是RLHF、RLVR、reasoning-oriented RL、agentic RL,不再是这样。
今天的一个典型PPO/GRPO风格循环更像:
- 给prompt;
- 模型rollout出一条或多条答案/轨迹;
- 奖励模型、验证器、工具执行器或环境给反馈;
- 再基于这些rollout更新参数。
在这个pipeline里,训练并不是直接对固定样本做优化,而是先生成样本,再训练。于是系统重心自然向rollout倾斜。OpenRLHF的论文给了一个非常重的判断:在PPO风格RLHF/RLVR中,inference phase often accounts for over 90% of total runtime,因为模型要在每个inference step里生成成千上万个token。
RLVR (Reinforcement Learning from Value Reflection) 作为新一代agentic RL方法,进一步放大了这个问题:它需要模型在rollout过程中不断反思、修正自己的轨迹,导致轨迹长度通常比普通RLHF更长,KV cache需要保留的状态也更大。最近的工程经验指出,在terminal environment这类复杂agent场景中,rollout轨迹长度很容易达到数千token,而且每个policy update需要采样多条轨迹,KV cache的内存压力会比传统推理场景高出一个数量级。
一旦接受这点,很多原本看似奇怪的系统设计就变得顺理成章了。
ECHO-2直接提出把centralized learning和distributed rollout inference分开,让rollout生成从数据中心GPU集群外溢出去;AgentRL提出fully-asynchronous generation-training pipeline,用来支撑多轮、多任务agent RL;OpenRLHF则把rollout engine和actor/training engine显式拆开,并强调异步数据流对长CoT时代尤其重要。
为什么rollout会特别“难”?因为它同时具备几个糟糕特征:
第一,它是 decode-heavy 的。
不是一次性吞掉一段输入,而是token-by-token往前走。
第二,它的长度高度不规则。
同一批prompt,有的几步就完成,有的会展开很长的chain-of-thought;在agent setting里,不同工具调用还会导致轨迹长度进一步分叉。AgentRL和OpenRLHF都把asynchronous pipeline当成必要设计,而不是锦上添花。
第三,它天然会放大KV cache。
如果一个prompt不只采样1条输出,而是采样 k 条trajectory;如果每条trajectory还会持续增长;如果中间还要保留verifier、tool use、multi-turn state,那么系统不只是多了 k 次计算,而是多了 k 份不断膨胀的历史状态。R-KV把reasoning output的冗长性视为核心问题,正是因为reasoning model的“输出长度”已经直接映射到KV cache成本。
我之前提出的一个猜想——“后训练需要Mac,可能是因为rollout时间比train时间更多”——方向是对的,但更准确的说法应该是:
不是简单因为rollout更久,而是因为rollout把问题从backward-dominated变成了decode/KV-dominated.
这也是为什么越来越多post-training框架会把vLLM、SGLang这类serving engine嵌进训练框架:OpenRLHF明确把vLLM当作长CoT RLHF/RLVR的关键基础设施;其论点不是“生成顺便用一下推理引擎”,而是“推理本身已经是训练效率的核心瓶颈”。
5. 为什么Mac / UMA会重新变重要
很多人谈Mac跑大模型,容易把它误解成“Apple GPU能和NVIDIA拼训练吞吐”。这基本不是重点。
Mac重新变重要,核心不是因为它在纯算力上赢了,而是因为它在内存系统组织方式上走了另一条路。
Apple在官方材料里反复强调unified memory architecture:M3家族的描述是“单一内存池,芯片里所有技术都能访问同一份数据而无需在多个内存池之间拷贝”;M2 Ultra则明确给出 800GB/s system memory bandwidth,并支持 192GB unified memory;到2025年的M3 Ultra,Apple进一步给到 最高512GB unified memory 和 超过800GB/s的内存带宽;而到了2026年3月,M5 Max官方规格已经达到 614GB/s unified memory bandwidth。Apple自己甚至把“直接在设备内存里运行超大LLM”当成Mac Studio的AI卖点之一。
这对LLM推理意味着什么?
不是“Mac的GPU比H100快”,而是:
- 模型权重、KV cache、CPU-side orchestration可以共享同一大内存池;
- 很多CPU/GPU协作场景不再需要显式拷贝;
- 只要容量够,单机可以把更大的working set放在一个统一地址空间里。
Apple对MLX的描述也很直接:MLX利用Apple silicon的unified memory architecture,CPU和GPU之间运行操作时不需要来回搬数据。
这正好击中decode-heavy / rollout-heavy工作负载的软肋。
因为decode的难点本来就不是做一个巨大的GEMM,而是如何低成本地读取和维护一大块历史状态。如果你的模型、KV cache、tool runtime和CPU/GPU orchestration共享一个大内存池,那么系统层的“摩擦损耗”会明显小很多。Apple的表述一直围绕高带宽、低延迟、单池共享,而不是独立显存 + PCIe copy。
但这并不等于“Mac全面优于NVIDIA”。
NVIDIA仍然在prefill、训练和高并发serving上拥有压倒性生态与算力优势。H100级别产品的HBM带宽已经达到 3TB/s 量级,而Grace Hopper GH200还通过 NVLink-C2C的900GB/s coherent interface 提供CPU+GPU coherent memory model。NVIDIA自己的官方说法就是:GH200通过NVLink-C2C提供硬件级memory coherency。
换句话说,NVIDIA并不是没看到Apple这条路,而是在沿着另一条更可扩展的路径逼近它:
从传统的“离散GPU + PCIe”,到“NVLink互联”,再到“Grace Hopper coherent memory model”,再到今天围绕CXL、shared memory pool、PD disaggregation的一系列论文。Apple的意义更像是:它让很多人第一次真正感受到,统一内存不是移动设备卖点,而是LLM推理的结构性优势。
所以,如果你问“为什么后训练也有人要Mac”,我会给出一个更谨慎的判断:
在cluster-scale post-training上,NVIDIA仍然是主角;但在本地实验、低并发rollout、长上下文推理、agent原型、长CoT调试这类memory-centric场景里,Mac的UMA确实切中了关键痛点。
这不是“Mac比NVIDIA更强”,而是“当workload从FLOPS转向working set时,内存架构开始决定体验”。
6. 为什么FlashAttention救不了decoding
FlashAttention是过去几年最重要的attention kernel创新之一,但它经常被误用为“attention已经优化完了”的证据。实际上,FlashAttention解决的是prefill的一个核心痛点,而不是decode的根问题。
FlashAttention的原论文把问题表述得非常明确:标准attention的关键瓶颈不是理论FLOPS,而是 HBM与片上SRAM之间的IO。它通过tiling方式避免materialize巨大的中间attention矩阵,从而显著减少HBM读写。这个优化对长序列prefill非常有效,因为prefill阶段会面对大规模的 N x N 注意力结构。
但decode完全不是这个形态。
在decoding的第 t 步,当前只有一个新token,因此 Q 的序列长度几乎是1,而 K/V 的长度是历史长度 t-1。这时attention更像一个 1 x N 的查询过程,而不是一个要显式构造 N x N 中间矩阵的过程。换句话说,decode的问题不是“中间attention matrix太大”,而是“历史K/V必须被完整读一遍”。Shazeer的MQA论文把incremental decoding的瓶颈直接归因于repeated loading of large keys and values tensors。
这就是为什么你会看到一个非常反直觉的结论:
- FlashAttention对prefill常常非常关键;
- 但对decode,它更多是在局部kernel效率上锦上添花,而不是改变瓶颈。
因为decode真正无法绕开的,是 O(N) 的KV read。你可以减少kernel overhead,可以更好地融合一些计算,但只要模型还是标准causal attention,历史状态就必须被访问。Sarathi-Serve之所以强调batching、chunked-prefill和stall-free schedule,而不是把希望完全押在attention kernel上,背后就是这个现实:decode的系统瓶颈不再是单个算子本身。
在2026年3月5日,FlashAttention-4进一步优化了异构计算和片上内存管理,在长序列prefill上继续获得显著提升,但核心观察仍然成立:对incremental decoding而言,瓶颈的本质仍然是对历史KV的反复读取,而非kernel内的计算调度。即使kernel效率再优化一个量级,只要你需要每一步都读完整历史,memory带宽仍然会是核心约束。
这也是理解后面所有系统设计的第二把钥匙:
当瓶颈是“必须读历史”时,优化方向就会从kernel下沉到memory layout、cache reuse、调度和体系结构。
7. 推理优化的四层结构:kernel、engine、model、hardware
为了不把各种技术混成一锅,我更喜欢把LLM推理优化分成四层:
第一层:kernel层
典型代表就是FlashAttention。
它关心的是:单个attention / decode kernel如何更少搬HBM、更多留在片上SRAM,如何更高效地执行。这层很重要,但它只回答“这一步怎么算更快”。
第二层:engine层
典型代表是Orca、vLLM、SGLang、Sarathi-Serve。
这层关心的是:请求如何被动态调度、KV cache如何被分页/复用、prefill与decode如何协同、如何提高GPU利用率与goodput。Orca把request-level scheduling改成iteration-level scheduling;vLLM用PagedAttention解决KV内存碎片;SGLang用RadixAttention做前缀复用;Sarathi-Serve通过chunked-prefill平衡吞吐与延迟。
第三层:model层
典型代表是MQA / GQA、以及更激进的Mamba / RWKV方向。
这层关心的是:如果decode慢是因为要读太多K/V,那能不能让K/V变少,甚至不用K/V? MQA直接共享K/V;GQA折中共享;Mamba/RWKV则试图把历史压成递归状态。
第四层:hardware层
典型代表是Apple UMA、Grace Hopper coherent memory、CXL memory pool。
这层关心的是:既然历史必须读,那能不能让“读”这件事更像访问本地内存,而不是频繁跨总线搬数据? Apple走unified memory;NVIDIA用GH200把coherent memory带进CPU+GPU;Beluga、TraCT、CXL-SpecKV则尝试把更大的共享内存池引入集群级推理。
如果只盯着第一层,你会觉得问题是“attention还不够快”。
如果看到第二层,你会意识到问题是“GPU经常在等、不够满”。
如果看到第三层,你会发现“模型本身就在决定系统带宽压力”。
如果再看到第四层,你就会明白:今天很多所谓AI infra的创新,本质已经不是神经网络论文,而是memory system论文。
8. Continuous Batching:从“请求级”到“token级”调度
LLM serving的一个基本矛盾是:decode每一步的计算量很小,不batch很容易吃不满GPU;但一旦batch,序列长度和完成时间又高度不一致,传统static batching会制造大量浪费。
Orca是这条线的源头之一。它提出 iteration-level scheduling:系统不是把一批请求整体跑完再换下一批,而是以“迭代”为单位调度,每次只让引擎执行单次迭代,然后马上允许新请求进入、已完成请求退出。Orca论文把这件事的收益说得很清楚:对于Transformer-based generative models,这种按iteration调度的方式显著优于传统request-granularity serving。
vLLm把这条思路进一步工程化。
其PagedAttention论文的出发点是:KV cache又大又动态增长,传统连续分配方式既浪费显存又难以高吞吐serving。PagedAttention把KV cache管成类似操作系统分页的形式,以支撑更灵活的请求装配和内存复用。
一旦KV cache能被分页管理,continuous batching 才真正成立。
它的核心不是“一次多攒几个请求”,而是:每个decode step都重新组batch。谁结束了就退出,谁新到就尽快插入;batch生命周期从“一个请求的完整生成期”缩短为“一个token step”。这和静态batching的本质区别,不在于batch更大,而在于batch的重组粒度更细。Orca的迭代级调度、vLLM的continuous batching、TensorRT-LLM的in-flight batching,本质都在做这件事。
为什么它能把GPU利用率显著拉高?
因为decode阶段单个请求的计算太小,必须把多个请求的“下一token”拼在一起算,才能提高张量并行度;而静态batching会被最长请求拖住,短请求完成后留下的“空座位”无法立刻补入。continuous batching把等待最长请求的串行模式,改造成了token-level的流水线模式。Sarathi-Serve进一步指出,decode batching对overall throughput特别有效,但prefill与decode混排又会制造stall,因此需要chunked-prefill来减轻这种互扰。
当然,continuous batching也不是“batch越大越好”。
Revisiting SLO and Goodput Metrics in LLM Serving、DistServe、以及一系列后续工作都提醒我们:在线serving的目标不是单纯最大吞吐,而是满足TTFT / TPOT / 尾延迟等SLO的 goodput。batch太大,虽然吞吐可能继续升一点,但TPOT、P99 latency可能恶化,最终goodput反而下降。
所以,continuous batching的真正目标不是“无限放大batch”,而是:
在给定的KV带宽、尾延迟和SLO约束下,让GPU在每个时间片都尽可能做有价值的token计算。
这已经非常像操作系统里的在线调度问题,而不再像经典深度学习里的“固定batch训练”。
9. 模型结构如何直接决定系统上限:MQA / GQA
如果你理解了decode的核心成本是“不断读历史K/V”,那MQA / GQA的意义就会变得非常清楚。
Shazeer在2019年提出MQA时,问题定义几乎就是现在整个行业的共同语言:incremental decoding之所以慢,是因为repeated loading of large keys and values tensors带来了memory-bandwidth cost。MQA的解法简单粗暴:让所有query heads共享同一组K/V heads。这样做并不会减少query head数量,但会显著减少K/V的尺寸,从而降低decode的带宽压力。
GQA则是这条路线的工程折中。
Google的GQA论文明确指出:MQA推理很快,但质量可能下降;于是他们提出grouped-query attention,在“每头独立K/V”和“全头共享K/V”之间取一个中间点。论文结论也很清楚:uptrained GQA的质量接近MHA,而速度接近MQA。
这件事的重要性,在系统层面远超“注意力机制换了个变体”。
因为当你减少 H_kv 的时候,减少的不只是KV cache占用,还减少了每一步decode必须读回来的数据量。换句话说:
- MHA把系统拖向memory wall;
- MQA/GQA在主动降低单请求的memory footprint;
- 这会直接推高可实现的optimal batch size,并改善TTOT/throughput曲线。
这正是“模型设计开始服务系统效率”的典型例子。它不是单纯为了学术上更优雅,而是在用结构设计换系统带宽。
从这个角度看,很多人把“模型架构”和“系统优化”分成两个世界,其实已经不太成立了。
GQA并不是一个脱离部署场景的纯模型创新;它是在非常明确地回应serving时代的物理瓶颈。后面你再看CAKE、R-KV、FlexiCache这类方法,会发现这条线更进一步:不只是让K/V变少,还要让K/V 更聪明地存在。
2024年底到2025年初,这条演化路线又走出了关键几步:
MLA:DeepSeek V3.1的低秩压缩KV
DeepSeek V3.1提出的 Multi-Head Latent Attention (MLA),把MQA/GQA的思路推向了新的高度。它不再是简单共享K/V头,而是对K/V做低秩投影压缩,把原始K/V投影到更低维度的latent space存储,需要时再恢复。这种方法在保持模型质量的同时,能把KV cache体积压缩 30–50%,显著降低了decode阶段的带宽压力。MLA的意义在于:它证明了模型架构可以主动通过表示压缩来服务系统级的内存效率,而不只是被动等待系统层面的优化。
Lightning Indexer:DeepSeek V3.2的增量KV优化
DeepSeek V3.2进一步推出 Lightning Indexer,针对MLA做了增量推理优化。它把KV cache的索引结构从全局压缩变成了增量更新,新incoming token的KV可以直接写入压缩缓存而不需要重新压缩整个序列,从而在保持压缩比的同时不增加延迟开销。这再次说明:模型结构和内存系统设计必须协同进化——压缩带来了容量好处,但增量更新的工程问题必须一起解决才能落地。
Attention Residuals:Kimi / MiniMax的分层KV保持
Kimi和MiniMax在近期的推理优化中都采用了类似 Attention Residuals 的思路:它们不再对所有层、所有token保留完整精度的KV,而是只在底层保留完整KV,高层只保留residuals或增量信息。这种分层压缩进一步降低了总体KV体积,同时因为底层attention更多关注局部位置,高层更多关注抽象语义,这种非均匀压缩对模型质量的影响非常有限。它代表了另一个方向:利用attention机制本身的层次特性来做非均匀KV压缩。
这些新进展继续验证着同一个方向:模型架构设计正在越来越主动地回应推理时的内存瓶颈,而不是把所有问题都丢给系统侧解决。模型定义了KV的冗余结构,系统才能在这个结构上做更精细的管理。
10. KV Cache其实是一种高度冗余的外部记忆
如果说2023年以前,很多系统还默认“KV cache就是该存的东西,想办法装下就好”,那么2025年以后,一个越来越强的共识是:
KV cache不是最优表示,只是最保守表示。
它保留了Transformer为了不丢信息而存下来的全部历史状态,但这些状态在时间、层次、head和token维度上都存在显著冗余。
R-KV的问题设定很有代表性:reasoning models往往会生成过长的chain-of-thought,这会导致“prohibitively large KV caches during inference”。作者进一步指出,传统KV压缩方法在reasoning model上容易失败,因为reasoning token里既有真正关键的推理状态,也有大量冗余token;R-KV通过redundancy-aware compression,在只保留 10% KV 的情况下接近满血效果,甚至在16% KV下能超过full KV baseline。
CAKE则从另一个角度说明“冗余”不是均匀分布的。
它把KV eviction建模成一个layer-aware、time-aware的资源分配问题:不同层的attention pattern不同,不同token的重要性还会随时间移动。结果非常激进:在LongBench和NeedleBench上,CAKE只保留 3.2% KV cache 仍能维持性能,并在长上下文下显著降低decode latency。
FlexiCache又提供了第三种视角:
attention heads在时间上的稳定性并不一样。有些heads会反复关注接近的top-K页,有些则频繁变化。于是系统就没必要对所有heads一视同仁:稳定的head可以只在GPU上保留top-K页面,其余下沉到host memory;不稳定的head则保留更多GPU-resident pages。
如果把这三类工作放在一起看,你会发现它们共同指向一个结论:
- 很多token的贡献是稀疏的;
- 很多层和很多heads的贡献并不对等;
- 很多历史状态可以被压缩、淘汰、延迟加载或部分重算。
这时,KV cache就越来越像一种“外部记忆系统”而不是“固定中间结果”。
Transformer过去的做法,本质上是把历史逐token存档;但一个更成熟的memory system会问:哪些应该保留在热层?哪些可以降层?哪些其实只是冗余副本?哪些应该预测性预取?哪些干脆可以忘掉?
所以我会说,未来很多推理系统里,KV compression的战略价值可能比参数量化还高。
参数压缩解决的是“模型能不能装下”;KV压缩解决的是“系统能不能真正跑起来、跑得快、跑得稳”。R-KV和CAKE的结果已经在很大程度上证明了这一点。
11. 为什么很多线上系统仍然在“重复计算历史”
到这里,一个自然问题是:既然KV cache这么重要,为什么很多线上系统没有把它彻底用好?
答案是:因为系统工程的最优解,不等于单请求计算的最优解。
在API层面,很多云服务长期采用的是近乎stateless的交互模型。
OpenAI的Chat Completions文档写得很明白:请求里要提供 messages,也就是“the conversation so far”;这意味着客户端要把历史对话内容一起发回来。后来Responses API加入了 previous_response_id、Conversations等状态机制,可以“store and retrieve conversation state across Response API calls”,并且Prompt Caching允许对完全相同的前缀做自动缓存。但从系统角度看,这仍然和“把某个用户会话的完整KV cache长期pin在某个GPU上”不是一回事。
为什么大家不直接做强stateful KV serving?
因为那会让会话和特定GPU / 节点强绑定,恶化负载均衡、容错和多租户隔离。只要请求可以落到任意副本,副本就必须能在不知道前情的情况下接住请求;于是最保守的设计就是让客户端或上层服务把必要上下文重新发来。Prompt Caching是一个很聪明的折中:OpenAI官方文档明确说cache hits只可能出现在 exact prefix matches 上,而且现在还能通过 prompt_cache_key 和最长24小时的extended prompt caching来提高命中率。它确实能减少prefill成本,但它仍然是“围绕前缀重用做的工程折中”,而不是通用的跨请求KV内存系统。
这就是很多“伪agent”系统的本质。
逻辑上,它们看起来是多轮agent:用户问一句、工具跑一轮、模型再思考一轮。
但物理上,很多时候它们其实是:每一轮都重新构造prompt,再做一次full prefill。
当上下文越来越长、链路越来越多、工具越来越复杂时,你看到的不是“状态被稳态保留”,而是“历史被反复重放”。这会让prefill成本非常高,也解释了为什么prompt caching / prefix reuse / PD disaggregation会变得如此重要。
所以,线上系统的真实矛盾不是“工程师不知道KV cache有用”,而是:
如何在可扩展、可容错、可调度的云架构里,尽量恢复KV cache的好处。
第一代KV-centric系统,就是在解这个矛盾。
12. 第一代KV-centric架构:DistServe、Mooncake、LMCache
如果说vLLM和SGLang主要解决的是“单引擎或单节点内,如何更好地跑”,那么2024年开始的一批系统开始把问题升级为:
跨请求、跨节点、跨阶段,KV cache应该怎么成为系统级资源?
这条线里,DistServe、Mooncake、LMCache是三个非常关键的坐标。
DistServe:先把prefill和decode拆开
DistServe的出发点是goodput:
现有serving系统把prefill与decode混在一起跑,会同时带来 prefill-decoding interference 和 resource coupling。前者让两个阶段互相拖累;后者让资源配置无法针对TTFT与TPOT分别优化。于是DistServe直接做 prefill/decode disaggregation:把prefill分到一批GPU,把decode分到另一批GPU,再按应用的TTFT/TPOT目标联合优化资源分配与并行策略。论文报告在不同模型和workloads上,DistServe能在延迟约束下显著提升可服务请求率。
DistServe的重要性不在于它是唯一答案,而在于它第一次非常系统地把一个常识变成了架构原则:
prefill和decode不是同一类资源需求。
Mooncake:把KV cache提升为调度核心
Mooncake更进一步。
它直接把自己定义为 KVCache-centric disaggregated architecture。在Mooncake里,prefill集群和decode集群是分离的,同时系统会利用GPU集群里原本被低估的CPU、DRAM、SSD、NIC资源来构建一个分布式KV cache;核心则是围绕KV cache设计的scheduler,用来在吞吐、SLO和过载情况下平衡调度。Mooncake论文报告在Kimi相关工作负载下,真实场景里可以多处理约 75% 请求。
Mooncake的思路非常值得注意:
它已经不再把KV cache当成“模型执行之后顺手留下来的临时副产品”,而是把它当成系统调度的对象。
这是一个很大的范式转变。
LMCache:把KV cache变成共享层
如果Mooncake更偏架构与调度,那么LMCache更像是把KV抽象成一个可插拔的cache layer。
LMCache论文把自己的定位说得非常清楚:它从vLLM和SGLang这类现代LLM engine里提取并存储KV cache,然后跨queries、cross engines共享这些KV cache,既支持prefix reuse,也支持PD disaggregation下的跨引擎KV transfer。论文报告,和vLLM结合时,吞吐在一些workload上可提升到 15x。
所以如果你非要给三者一个最简洁的分工,我会这样总结:
- DistServe:先把prefill和decode分开,解决两阶段互扰;
- Mooncake:让KV cache成为分布式调度核心;
- LMCache:把KV cache抽象成可存储、可迁移、可复用的系统层。
与此同时,SGLang的RadixAttention提供了另一种非常关键的能力:在复杂LM program中自动发现并复用共享前缀。SGLang论文强调,它的runtime可以利用RadixAttention实现KV cache reuse,并在多种任务上大幅提高吞吐。
有意思的是,到2026年初,Mooncake和LMCache官方文档已经明确展示了二者的集成:Mooncake可以作为LMCache的后端存储和传输引擎,官方甚至直接展示了LMCache + Mooncake + vLLM的PD-disaggregated demo。也就是说,现实里它们并不是“二选一”的关系,而是常常叠加使用。
13. 为什么Mooncake / LMCache不是终点
如果Mooncake / LMCache已经把KV提成一等公民,为什么2025年以后还会冒出一大堆“下一代”论文?
因为当你把KV做成系统级资源之后,新的瓶颈会立刻暴露出来。
第一,KV太大,搬不动
Mooncake/LMCache的默认设定仍然是:
KV值得存、值得搬、值得复用。
但一旦上下文变长、请求变多、agent变复杂,KV cache的体积会很快膨胀到GPU容量之外。此时问题就从“有没有cache”变成“cache如何从CPU/SSD/远程内存高效回到GPU”。
Strata的摘要对此几乎是点名式批评:长上下文下,分层缓存不可避免,但把大块cached contexts重新加载回GPU时会遇到严重瓶颈——paged layouts带来的fragmented I/O无法吃满带宽,现有scheduler又不考虑cache-loading delay,结果系统变成loading-bound而不是compute-bound。
第二,prefix reuse会和延迟目标冲突
自动prefix reuse并不自动等于更好的online latency。
LinkedIn那篇关于RadixAttention调度的NeurIPS 2025论文做了一件很重要的事:它把“有prefix reuse的在线调度”形式化之后证明,在TTFT约束下,这个问题是NP-hard的。更直观地说,简单地贪心追求longest-prefix-match,可能会让某些请求的TTFT爆掉。作者因此提出k-LPM,用来平衡prefix reuse与fairness/waiting time。
这说明什么?
说明Mooncake / LMCache把“缓存能不能用”解决了,但“缓存什么时候用、优先给谁用”还没有彻底解决。
第三,agent workload的复用模式和普通LRU不一样
KVFlow直接把矛头指向agentic workflows:
当前系统虽然会做prefix caching,但通常采用LRU淘汰策略,这会在agent即将下一次被调用前把其KV cache提前丢掉。KVFlow因而引入workflow-aware的Agent Step Graph、细粒度eviction,以及主动prefetch。它本质上是在说:agent场景下,缓存管理必须理解工作流结构,而不能只看最近访问。
第四,公平性和抢占有上下文切换成本
FastSwitch又暴露了另一个问题:
现有block-based KV cache分配虽然减少了内存浪费,但会导致上下文切换粒度不足、切换开销高。FastSwitch因此提出一种fairness-aware serving system,专门优化preemption/context switching的效率。换句话说,当KV成为状态后,抢占不再是免费动作。
第五,精确前缀命中本身就过于苛刻
在RAG这类场景里,两个请求往往不是“完全相同前缀”,而是“共享大量检索上下文但并不严格前缀一致”。CacheBlend就是在这个问题上往前走了一步:它不再要求严格prefix match,而是允许复用已缓存的KV,再对少量token的KV做selective recompute,从而在RAG上显著改善TTFT和吞吐。
所以,Mooncake / LMCache之所以“不是最新”,不是因为它们过时了,而是因为它们把问题推进到了下一阶段。
它们解决的是:让KV进入系统视野。
而下一代工作解决的是:当KV已经成为系统资源后,如何处理I/O、调度、agent reuse、分层缓存、公平性和局部重算。
14. 新一代Memory-centric架构:Strata、CAKE、R-KV、KVFlow、FastSwitch、CacheBlend
我更愿意把2025年之后的工作叫做 memory-centric,而不是简单的KV-centric。因为这时研究重心已经不只是“缓存有没有被复用”,而是:
如何把KV cache管理成一个真正的分层内存系统。
Strata:分层缓存 + GPU-assisted I/O + cache-aware scheduling
Strata可以看作Mooncake/LMCache之后最系统的一次升级。
它关注的不是“怎样做prefix reuse”,而是“当长上下文cache被分层存储后,如何高效把它重新搬回GPU”。论文提出GPU-assisted I/O、GPU/CPU layout decoupling和cache-aware scheduling,并报告在长上下文基准上相对vLLM + LMCache可实现 最高5x更低TTFT。
这类工作很关键,因为它把“KV cache存在哪”从一个yes/no问题变成了一个多级层次问题:HBM、CPU DRAM、SSD,乃至更远的内存池,都是缓存层的一部分。
CAKE:Layer-aware eviction
CAKE的贡献,是把“删谁”这件事变得全局且结构化。
它不再把eviction看成简单LRU,而是结合layer-specific preference与temporal dynamics去做cascading allocation。最值得记住的不是具体算法,而是它的结果背后的信号:很多层、很多token、很多时刻的KV实际上并不值钱。
R-KV:Reasoning-specific compression
R-KV之所以值得单独拎出来,是因为它直接对应了当下最火的workload:reasoning。
作者指出reasoning models经常会生成excessively long outputs,而existing compression approach又会在reasoning failure上翻车,于是他们专门针对reasoning冗余做压缩。结果同样非常有标志性:10% KV接近满血性能,16% KV甚至能超过baseline。
这说明reasoning场景不只是“更长”,还意味着冗余结构有别于普通聊天输出。
FlexiCache:按head稳定性做层次管理
FlexiCache进一步把memory policy做到了attention head层级:
稳定的heads,只保留top-K pages在GPU;不稳定heads,保留更多热页。这代表着另一个很重要的趋势:缓存管理正在越来越细粒度地靠近模型内部结构。
KVFlow:workflow-aware cache for agents
KVFlow则非常明确地站在agent workflow一侧。
它的核心思想很简单但很有力:agent workload不是随机序列,而是带有工作流依赖的Agent Step Graph;因此缓存策略应该“知道”哪个agent下一步更可能被再次激活。KVFlow再加上fully overlapped prefetch,本质上已经很像CPU cache里的“预测下一步会用什么”。
FastSwitch:context switching也是成本
FastSwitch说明,当你把大量请求都做成可抢占的、可中断的KV-stateful过程时,context switching本身会成为瓶颈。这和操作系统里的进程切换越来越像:不是说抢占不能做,而是抢占的粒度、上下文布局、恢复成本都必须被认真设计。
CacheBlend:从exact prefix reuse走向approximate reuse
CacheBlend值得注意,是因为它指出exact prefix reuse过于局限。
对于RAG之类场景,共享上下文不一定是“完全一样的开头”,但仍然值得复用一大块历史。CacheBlend用少量selective recompute把这种近似重用变成可能,这实际上把“缓存”和“计算”做成了连续体,而不是非此即彼。
把这些工作放在一起看,你会发现新一代架构的关键词已经不是简单的“cache reuse”,而是:
- hierarchical tiers
- cache-aware scheduling
- workflow-aware eviction
- partial recompute
- proactive prefetch
- fairness-aware switching
这已经完全是memory system的语言了。
15. CXL:看起来像终极答案,为什么现实里还很难
CXL之所以让人兴奋,是因为它表面上很像一条“兼得”的路线:
容量可以扩展、内存池可以共享、load/store语义更自然、看起来又比RDMA更像真正的内存。
Beluga的摘要就很有代表性:它提出通过CXL switch让GPU和CPU访问一个shared large-scale memory pool,并强调这种load/store access semantics能带来near-local memory latency、减少同步与编程复杂度。论文在vLLM上报告了相对RDMA baseline显著TTFT和吞吐改善。
但如果因此得出“CXL就是最终解”,那就太乐观了。
第一,CXL解决的是容量,不是HBM级带宽
HBM的价值不只是近,而是又近又宽。
CXL能做出更大的共享内存池,但它不会自动给你HBM级吞吐。Beluga的改进之所以成立,是相对RDMA等更曲折路径而言;并不意味着CXL可以无成本替代GPU本地显存。
第二,CXL不是自动coherent的天堂
TraCT的摘要非常有教育意义。
它明确指出,为了实现基于CXL shared memory的rack-scale KV cache,必须处理 synchronization, consistency, and data management on non-coherent CXL memory。换言之,现实里的CXL,至少在很多商用品质和部署形态下,并不是“天然全局一致的UMA”。你还是要自己补软件协议。
第三,数据移动不见得比重算便宜
只要KV足够大、访问足够碎、竞争足够高,跨层搬运本身就会成为主成本。TraCT专门把KV transfer视为PD disaggregation的fundamental bottleneck;CXL-SpecKV则不得不引入speculative prefetch + FPGA compression/decompression,才能把disaggregated KV-cache的代价压住。
第四,CXL方案经常不得不引入更多“系统补丁”
Beluga通过shared pool + native load/store降低编程复杂度;TraCT通过软件级同步机制处理non-coherence;CXL-SpecKV又通过speculative prefetch和压缩去弥补带宽/延迟问题。你会发现,CXL不是一个“买来即用”的硬件银弹,而是一个要求系统/软件/硬件协同设计的平台。
所以我会把CXL的真实定位概括成一句话:
CXL很重要,但它更像“新增一层内存层级”,而不是“让所有远程内存都变成本地HBM”。
一旦这样理解,很多现象就不矛盾了:
为什么CXL方案总在讨论prefetch、压缩、shared pool、non-coherence、software sync?
因为它们在本质上做的是——承认远程内存仍然更慢,然后尽量把这份慢掩盖掉。
16. LLM serving正在变成一个“操作系统问题”
如果把今天的主流LLM serving系统和5年前的DNN serving系统一对比,最大的变化不是模型更大,而是抽象层变了。
你会看到一整套越来越像操作系统的概念:
pages / blocks:PagedAttention像虚拟内存分页;
radix tree:RadixAttention像基于前缀的共享索引;
cache hit / miss:prompt caching、prefix reuse、KVFlow、CacheBlend都在围绕命中率做文章;
eviction policy:CAKE、KVFlow、FastSwitch都在研究谁该被驱逐;
prefetch:KVFlow、CXL-SpecKV、Beluga这类系统都在强调预测性加载;
scheduling under SLO:DistServe、Revisiting SLO and Goodput、LinkedIn那篇k-LPM理论工作,都把serving视为latency-constrained online scheduling。
甚至“好不好”的评价指标都越来越不像传统训练。
训练时代,大家比的是tokens/sec、TFLOPS utilization、samples/sec。
Serving时代,越来越关键的是:TTFT、TPOT、P99、SLO attainment、goodput。Revisiting SLO and Goodput Metrics in LLM Serving明确指出,传统goodput指标甚至会鼓励一些违背用户体验的行为,因此需要重新定义serving指标框架。
这意味着一个非常根本的变化:
以前我们常说“LLM infra的核心是分布式训练系统”。
现在更准确的说法也许是:LLM serving的核心正在变成一个面向KV state的在线内存操作系统。
这个“操作系统”要解决的事情包括:
- 如何把状态拆成页;
- 如何在多层存储中放置;
- 如何决定谁驻留GPU;
- 如何预测谁下一步会用;
- 如何平衡公平、吞吐和尾延迟;
- 如何在必要时压缩、重算、抢占和迁移;
- 如何让prefix sharing和多租户服务共存。
从这个角度看,Mooncake/LMCache只是“把文件系统建起来”的第一步;Strata、KVFlow、FastSwitch、Beluga、TraCT,则在往“完整内存管理器”方向走。
17. KV cache之后是什么:Mamba、RWKV与“在线压缩记忆”
如果把问题继续追到底,一个更激进的问题会冒出来:
既然大家已经承认KV cache很大、很贵、很冗余,那为什么不干脆不要KV cache?
这就是Mamba、RWKV这类方向的吸引力。
Mamba的核心主张很明确:Transformer在长序列上存在根本性的计算效率问题,因此它用selective state spaces去构建一种linear-time sequence model。论文强调Mamba是fully recurrent的,并报告在语言建模上获得很强性能,同时推理吞吐优于同规模Transformer。
RWKV的表述也很直接:它想结合Transformer可并行训练的优点与RNN高效推理的优点,实现线性扩展的推理过程。
如果用一句更系统的话来说,Transformer的KV cache是一种“把历史逐token存档”的外部记忆;而Mamba/RWKV这类模型更像在尝试一种“在线压缩记忆”:不是把每一段历史都原样保留,而是把历史不断压缩进一个递归状态里。
这条路线的诱惑非常大,因为它从根子上避免了“每步必须读完整历史K/V”的问题。
但现实也很清楚:截至2026年,Transformer仍然是工业部署的主流,围绕KV cache的系统创新还在高速推进。这说明产业界的短中期共识不是“马上替换Transformer”,而是“先把KV-based world优化到极致”。
所以,KV cache之后的未来,大概率不是一个瞬间翻篇的故事,而是两条线并行:
- 一条线继续把Transformer serving做成真正成熟的memory system;
- 另一条线探索如何用state-space / recurrent / hybrid架构,把“历史存储成本”在模型层面降下来。
这两条线并不冲突。相反,今天围绕KV cache做出的所有系统认知,都会成为理解下一代序列架构的基础。
18. 结语:三条真正的主线
如果要把整篇文章浓缩成三条主线,我会这样总结。
第一条:从Compute到Memory
Transformer训练时代,焦点是FLOPS;
Transformer推理时代,焦点越来越是 working set、带宽、延迟、状态复用。
FlashAttention重要,但它不是终局;真正的终局问题是:历史信息该如何被存储、访问、迁移和压缩。
第二条:从Stateless到Stateful
云上API为了可扩展、可容错和多租户,天然偏向stateless;
但agent、多轮对话、长CoT、RL rollout,又天然需要stateful。
于是过去两年最重要的serving创新,几乎都在试图调和这对矛盾:prompt caching、prefix reuse、RadixAttention、LMCache、Mooncake、DistServe、KVFlow、Beluga、TraCT。它们的共同目标都是:在不牺牲云架构弹性的前提下,尽量恢复状态复用的收益。
第三条:从Model到System,再到Memory OS
过去我们常把“模型创新”和“系统优化”分开看。
但今天,GQA这种结构设计直接影响带宽;R-KV这种压缩方法直接影响serving成本;KVFlow/FastSwitch/Strata这种系统工作又在深度利用模型内部的时间稳定性、前缀结构和层间差异。到这个阶段,模型、引擎、调度、内存层级其实已经被绑在一起。
所以,这篇文章真正想表达的不是“Mac好还是NVIDIA好”,也不是“Mooncake和LMCache过没过时”。
我更想强调的是:
大模型推理的下一阶段,越来越不是一个“神经网络算子优化”问题,而是一个“如何把历史变成可管理内存”的系统问题。
一旦你接受这一点,很多过去看似碎片化的现象就会统一起来:
- 为什么RL rollout让inference比training更贵;
- 为什么Mac的统一内存会重新有意义;
- 为什么FlashAttention不够;
- 为什么vLLM、SGLang、Mooncake、LMCache、Strata、Beluga、TraCT会同时出现;
- 为什么CXL让人兴奋又让人头疼;
- 为什么KV cache compression可能比参数压缩更重要;
- 为什么未来的LLM serving,看起来越来越像一个操作系统。
而这,也许才是过去两年AI infra最值得被认真理解的变化。
想要深入探讨更多人工智能与系统架构的前沿话题,欢迎持续关注云栈社区的技术动态与深度解析。