尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

长上下文推理成本高?线性注意力把复杂度从平方级降到线性

长上下文推理成本高?线性注意力把复杂度从平方级降到线性 全注意力贵贵在“每个新词都要把前面所有历史重新翻一遍”。这不是比喻是标准自注意力机制里真实发生的运算过程。序列长度是 n 时模型要计算一个 n×n 的关联矩阵计算量和内存占用都按 n² 增长。上下文从 1 万涨到 100 万成本不是涨 100 倍而是接近涨一万倍。Kimi Linear 这个系列要拆的就是怎么把这个“逐页重读”的过程改成“维护摘要”让长上下文的成本从平方级降到线性。这篇文章先讲清楚最大本的问题全注意力为什么贵贵在哪些环节以及 Linear 方案的切入点到底在哪。适合看这篇的人想知道长上下文模型的推理成本从哪里来、为什么超长上下文 API 的计费和延迟明显更高、以及线性注意力这类路线究竟在改什么的开发者、算法学习者和模型选型同学。不需要你完全会推矩阵求导但最好有基本的线性代数和语言模型概念。1. 先理解自注意力在干什么每个新词都要查一遍全部历史1.1 从一次“查询”说起自注意力机制里输入是一串 token每个 token 会生成三个向量Query、Key、Value。用最直白的话解释Query 是当前这个词“想问的问题”。Key 是历史上每个词身上的“标签”。Value 是历史上每个词真正携带的“内容”。当前这个词要做的事就是拿自己的 Query 去和历史上所有 Key 做相似度计算得到一组权重再用这些权重去加权求和所有 Value。结果就是这个词融合了上下文之后的新表示。这个过程的设计意图很明确让每一个位置都有机会看到全局信息而不是只看周围几个词。Transformer 能处理长距离依赖靠的就是这种全局视野。1.2 为什么必须看“所有”历史你可能想过既然上下文那么长能不能只看附近的内容问题在于如果只按距离截断模型的视野就被人为限制了。一个关键信息可能出现在文档开头真正被引用时已经到了结尾。比如一份 10 万字的合同第 1 页定义的某个术语在第 5000 页才被再次提到。模型必须把第 1 页的信息保留并关联到最后。全注意力不赌局部性它给每个位置同样的机会去看全量历史。代价就是每生成一个新 token都要把所有历史拿出来重新计算一遍相关度。这就是标题里“百万页记录”的由来——它不是一个营销比喻而是计算过程里真实发生的读取和运算。2. 平方复杂度贵在哪注意力矩阵和 KV Cache 双重膨胀2.1 注意力矩阵是 n×n假设输入序列长度是 n每个 token 的特征维度是 d。计算注意力分数时Query 矩阵和 Key 矩阵相乘结果是一个 n×n 的分数矩阵。这个矩阵里的每一个元素代表“第 i 个位置对第 j 个位置的关注强度”。矩阵本身没有额外含义问题是它的大小随 n 平方增长n1000矩阵有 100 万个元素n10000矩阵有 1 亿个元素n100000矩阵有 100 亿个元素。这还只是单层单头的量。真实模型有几十层、几十个头最后的总量要再乘一个很大的系数。所以“上下文越长越贵”不是产品定价问题是算法复杂度决定的。可以用一段示意代码感受增长趋势# 示意只看注意力矩阵的元素数量 for n in [1_000, 10_000, 100_000]: elements n * n print(fn{n:7,} - attention matrix {elements / 1e8:.1f} 亿 elements)输出是 0.01 亿、1 亿、100 亿。每增加一个数量级矩阵规模涨两个数量级。这就是平方增长的直观感受。2.2 KV Cache历史要被“带在身上”除了注意力矩阵还有一个容易被忽略的成本KV Cache。生成时模型每处理一个 token都会算出它的 Key 和 Value。为了让后面的 token 能继续看到它这些 Key 和 Value 不能丢必须缓存下来一直留到整个序列处理完。KV Cache 的大致占用量可以根据模型结构估算。举一个常见的 32 层、32 头、每个头 128 维的模型为例每个 token 每层要存 2 个向量Key 和 Value每个向量维度是 32×1284096每个 token 每层就是 2×40968192 个元素32 层加起来是 262144 个元素用 FP16 存储每个元素 2 字节约 0.5 MB 一个 token128K 上下文时KV Cache 约 64 GB。这只是一个示例模型结构不是特指某个具体模型。但它能说明问题长上下文的 KV Cache 会非常快地吃掉显存。这也是为什么“超长上下文”在工程上很难做不只是算力问题是内存根本放不下。2.3 一个直观的对比表上下文长度单层注意力矩阵相对成本对比 1K直觉类比1K100 万1x一本书10K1 亿100x十本书100K100 亿10000x一百本书1M1 万亿1000000x一百万页注意力矩阵是计算量层面的二次增长KV Cache 是内存层面的近似线性增长。两者叠加构成了长上下文推理最主要的成本。注意实际工程实现会有很多优化不会真的把完整 n×n 矩阵全部保留下来。但复杂度的本质没有变优化只是把常数变小大 O 级别仍然是 n²。3. Decode 阶段最痛每生成一个 token 都在重新读历史3.1 Prefill 和 Decode 是两种完全不同的开销大模型生成文本分两个阶段Prefill把用户输入的提示词一次性处理完得到每个位置的 Key 和 Value并产出第一个输出 token。这个阶段输入长、计算密集但并行度高。Decode每生成一个 token就把它追加到序列末尾计算这个新 token 的注意力再继续生成下一个。这个阶段是逐 token 进行的每一步都要和全部历史做一次关联。很多人只关注 Prefill 阶段“处理长输入”很慢实际生产里 Decode 阶段才是最难优化的部分。3.2 每一步都在“重读”关键在 Decode 阶段每一步新 token 的 Query 都要和缓存里所有 Key 计算相似度再对所有 Value 做加权求和。用序列长度 n 算一笔账。生成第 1 个 token 时要和前面已有的输入历史做过一次注意力生成第 2 个 token 时历史多了一位再做一次。整个过程读历史的总量接近 123...n约等于 n²/2。这就是“每个新词都要重翻百万页记录”的真正含义。它不是每一步都真的翻了一百万页而是“每一步都要从头到尾把历史重新过一遍”只是历史越长单步读的量越大整体累计就是平方级。3.3 真正的瓶颈常常是内存带宽GPU 上 Decode 阶段有个很反直觉的现象算术量其实不大但每一步都要把 KV Cache 从显存里搬出来参与计算。搬数据的速度取决于显存带宽而不是 GPU 的计算峰值。假设当前 KV Cache 有几十 GB每一步都要读一遍。哪怕带宽再好几十 GB 的读取也要消耗几十毫秒级别的时间。算下来生成速度就会明显变慢。所以你会看到长上下文生成时GPU 利用率往往不高但每个 token 出得特别慢。不是因为算力不够而是“读历史”的内存访问开销太大。这也是为什么长上下文模型在 API 上的成本天然更高。4. Linear Attention 的切入点把逐页重读改成维护摘要4.1 数学上为什么能换顺序标准注意力公式可以简写成Attention(Q,K,V) softmax(QK^T / sqrt(d)) V公式里最大的麻烦是 softmax。softmax 的分母要对所有 Key 求和这导致 QK^T 和 V 之间不能随便交换乘法顺序。只能先算出注意力矩阵再去和 V 相乘。Linear Attention 的切入点是把 softmax 换成一个可以拆成独立内积形式的核函数。比如把相似度写成 φ(Q) 和 φ(K) 的内积公式就变成Attention(Q,K,V) ≈ φ(Q) * (Σ φ(K)^T V)注意括号的位置发生了变化原来是 (QK^T)V现在变成了 Q(K^T V)。括号里的 Σ φ(K)^T V 可以独立于当前 token 计算每来一个新 token只需要做一次增量更新。4.2 存“摘要”而不是存“全文”这个括号里的累积量本质上是一个固定大小的状态矩阵维度是 d×d。不管前文有 1 万 token 还是 100 万 token这个状态矩阵的大小都不变。用最通俗的类比全注意力是每次提问都把整本书重新读一遍线性注意力是边读边记读书笔记提问时只看笔记。读书笔记一定会丢细节可能漏掉某个精确的数字、某个位置的表述。但它换来的是提问成本不再随书的厚度增长。这就是线性注意力最核心的取舍。4.3 复杂度从 n² 降到 n线性注意力的执行逻辑可以写成这样# 标准注意力每一步都重算所有历史 state 0 for new_token in 生成过程: scores Q_new · K_all^T weights softmax(scores) out weights · V_all # 线性注意力维护一个状态增量更新 state 0 for new_token in 生成过程: state φ(K_new)^T · V_new # 只更新状态 out φ(Q_new) · state # 查询时直接用状态每一步的计算量只和向量维度 d 相关和序列长度 n 无关。所以总体复杂度从 O(n²·d) 降到 O(n·d²)。当 n 很大时这个差距是决定性的。这里给的是最基础的原理版本。实际工程里还有各种变形分块计算、滑动窗口、归一化技巧、混合精度训练。但核心不变——用可累积的状态替代完整的历史注意力。5. Kimi Linear 的定位不是替换全部注意力而是混合取舍5.1 为什么不能把所有注意力都换成线性线性注意力省掉了平方复杂度但代价是表达能力下降。标准注意力可以在任意两个位置之间建立精确关联。而线性注意力把历史压缩成一个状态之后位置信息和细粒度关联都会变弱。遇到需要精确引用原文、长距离推理、代码跨行引用这类任务纯线性方案的精度通常不如标准注意力。所以实际落地的方案绝大多数不是“全线性”而是“混合”。常见做法是部分层继续用标准注意力少量层用线性注意力处理超长历史或者用线性注意力做全局粗关联用标准注意力精读最近窗口。5.2 长上下文是线性注意力最自然的战场Kimi 系列模型一直以长上下文见长。这个方向天然要直面 n² 复杂度问题。把线性注意力引入架构最合理的动机就是在超长上下文场景下不必让“每个新词重读全部历史”这件事完整吃掉平方级的资源。需要说明的是具体到 Kimi Linear 的实现细节——线性注意力层放在哪几层、窗口怎么切、状态怎么初始化、训练序列多长——这些应该以官方技术报告和开源代码为准。本文讲的是原理层判断线性注意力不是免死金牌而是一组有边界的工程决策。注意不要因为一个模型叫“Linear”就默认它所有层都是线性注意力。同一个命名下不同版本的具体实现可能差别很大。做技术选型时一定要看模型卡、论文和开源仓库而不是只看名字。5.3 质量问题怎么补偿混合架构里核心问题是如何保证质量不崩。通常会组合几类手段局部窗口注意力负责细粒度信息线性注意力负责全局信息用门控机制和额外归一化控制状态更新的幅度训练阶段注入长上下文数据让模型适应状态累积的行为对关键 token 或关键段落用标准注意力再精读一遍。这些补偿手段本身也有成本。所以最终“线性”带来的收益不是简单套一个复杂度公式就完事而是工程上的综合平衡。判断一个方案好不好要看它在实际任务上的准确率和延迟而不是看它宣传自己是几倍加速。6. 对开发者和选型人员的实际影响成本、延迟和验证指标6.1 上下文越长全注意力的边际成本越高如果你在调用长上下文模型的 API全注意力架构在输入特别长时费用和延迟都会显著上升。这不是厂商定价随意是计算和内存成本真实存在。一个 1 万 token 的请求和一个 100 万 token 的请求在全注意力模型上的成本差距不是 100 倍而是接近 10000 倍甚至更高。这也是为什么“长上下文”能力看起来很强真正大规模使用时却要仔细算预算。6.2 选型时我一般看这些指标指标判断方式输入长度上限支持多长这个长度是训练时见过的还是外推出来的延迟曲线上下文翻倍时首 token 延迟和生成延迟分别涨多少内存占用长输入下 KV Cache 是否可控制有没有做稀疏或压缩质量衰减长上下文检索、引用、总结的准确率变化成本曲线按 token 计费时长上下文请求的单价曲线如果只要一个“支持 200K 上下文”的宣传数字不验证自己任务在长上下文上的准确率很容易被表面参数误导。6.3 什么时候该真正关心 Linear 这类设计如果你是调用 API 做业务不需要自己实现线性注意力但要看懂技术方案背后的成本逻辑。当你的场景是超长文档分析、海量文件问答、持续对话时线性注意力类设计意味着更低的边际成本和更稳定的延迟。如果你做推理优化或模型训练这个原理就是基本功。拿到一个“长上下文方案”先看它 QK^T 那一步有没有被拆开就能判断它是真正的线性复杂度还是套了一个优化名字的近似方案。7. 三个常见误区和一套可复用的验证顺序7.1 “线性注意力零成本”是误解线性注意力把复杂度从 n² 降到 n但常数项不小。状态矩阵的更新涉及 d×d 的矩阵乘法而 d 通常很大几千到上万都很常见。在短上下文场景下线性注意力未必比标准注意力快有时反而更慢。所以“线性”不等于“免费”它的优势只在序列足够长时才体现出来。短文本任务老老实实用标准注意力反而更稳。7.2 “支持长上下文每句话都被认真读过”也要小心支持长上下文不等于模型对所有历史内容都一视同仁地精读。数学上标准注意力给每个位置同样的全局视野但训练出来的注意力分布通常很稀疏真正起作用的可能是几个关键片段其余大部分是背景噪声。线性注意力方案在压缩历史时还会进一步丢失细节。如果你的任务需要从 100 页文档里精确抽取某个数字、某个日期、某条引文建议额外做检索增强或分段处理不能完全依赖模型自己记住。7.3 工程验证顺序从简单到苛刻如果要在项目里验证某个“线性注意力模型”或“长上下文方案”是否适合你的任务我建议按这个顺序来先跑一个中等长度任务确认基本输出质量正常再用一个接近模型长度上限的任务观察质量是否明显衰减记录延迟和资源占用对比上下文翻倍时是线性增长还是平方增长构造一个“关键信息埋在开头、问题在结尾”的任务测试长程精确关联能力最后用你自己的业务数据样本按真实比例测一遍成本和成功率。这个顺序能过滤掉很多表面宣传。尤其是第 4 步很多模型在普通长文本上表现不错但一旦要求跨越很远的距离精确关联信息差距就立刻体现出来。回到开头那个问题全注意力为什么贵因为每个新词生成时都要把全部历史重新过一遍注意力计算和读取都随序列长度平方增长。Kimi Linear 这类方案的核心不是消灭注意力而是换一种“维护摘要”的方式来处理历史让每一步的开销尽量和序列长度解耦。真正落地时它通常也不会把标准注意力全部替换掉而是做混合在长上下文的成本、延迟和模型精度之间找平衡。建议你先在自己的任务上跑一轮“信息埋在开头、问题在结尾”的测试再决定要不要为线性注意力这个方向付出跟进成本。
返回列表