NPU长上下文为何变慢?归一化怎样保持稳定?
长上下文推理会同时放大历史状态访问和数值处理压力。NPU运行注意力模型时,需要区分解码阶段不断增长的键值读取,与分块计算中归一化状态的正确维护,二者对应不同的优化边界。
自回归解码每生成一个新位置,都需要将当前查询与可见历史位置的键进行匹配,并用相应权重汇总值向量。若缓存的键和值无法全部留在足够近的存储中,历史长度增加就会使每步需要读取的数据增加。以标准全注意力为前提,缓存容量与层数、历史位置数、键值头数、头维度以及每元素字节数有关,键和值各占一份;实际还应计入对齐、分配粒度和运行时元数据,不能只按查询头数推算。
分组查询注意力让多个查询头共享较少的键值头,能够减少键值缓存的容量及理论读取需求,但它是模型结构选择,不能靠部署时随意删掉缓存头获得。已有模型采用何种头数,应读取模型配置并核对转换结果;后端也可能因广播或布局转换未能完全兑现共享带来的流量收益。对运行瓶颈,应结合缓存实际读取量和每步执行时间判断,不能看到上下文增长就断言所有设备都已受外存带宽限制。
预填充与逐步解码还应分开测试。预填充一次处理多个查询,具有不同的计算并行度与中间结果规模;单步解码的查询数量较少,历史缓存读取更容易占据成本。工程上可固定模型、批量和生成策略,逐步增加历史长度,记录每步耗时与访问字节数。若采用滑动窗口或其他受限注意力,历史读取不会永远按完整上下文增长,应按模型真正可见的范围重新估算,不能把全注意力公式套到所有架构。缓存容量估算还应包括同时活跃的会话数;每个会话长度受限,并不代表多会话合计仍能驻留。应把会话数与上下文长度作为独立变量核算。
另一项问题出现在不显式保存完整分数矩阵的分块注意力中。稳定的指数归一化通常先减去一行分数的最大值,再计算指数与求和。若每个分块单独减去自己的最大值,并直接把各块得到的归一化输出相加,结果一般不等于整行归一化,因为各块分母不同,块间概率质量已经被错误分配。分块降低了中间存储需求,却没有取消跨块维护统一归一化尺度的责任。
正确的在线方法应维护已经处理部分的最大值、指数和以及加权值累积。当新块引入更大最大值时,旧指数和与旧加权累积都要按新旧最大值之差的指数重新缩放,再加入新块贡献。最后用统一指数和对加权累积归一化。若保留的是已归一化输出,更新公式则还需带上旧分母,不能混用两种状态定义。这个重标定过程在实数运算意义下保持与标准注意力等价,但浮点舍入仍可能造成细小差异。
把该算法映射到NPU时,还要核对指数近似、累积精度和掩码边界。被完全屏蔽的一行若直接进行负无穷减负无穷,可能出现未定义数值,应按模型接口明确处理;正常因果掩码是否可能出现这种行,也取决于填充与有效长度。验证应覆盖极大分数差、分块边界和不同有效长度,并与高精度参考结果比较。不能只用普通随机输入验证,因为它们未必触发旧累积需要显著重标定的情况。
长上下文优化应先分清成本来源:历史缓存决定每步状态访问,在线归一化决定分块计算是否正确。前者需要按真实模型核算流量,后者需要以统一尺度维护跨块状态。





