把上下文“压进”权重:一次编码、多次作答
长上下文并不便宜。把文档塞进提示词,每次提问都要重新编码,键值缓存随长度膨胀。另一条路是微调:知识写进权重后推理不再需要原文,但每个新文档都要单独优化,比较慢。最近的论文《用参数流内化上下文》试图走第三条路:不优化、不保留原文,只用一次前向推理把上下文翻译成低秩适配器,此后仅凭问题作答。
三种供给知识的方式
提示词供给灵活、零训练,是检索增强的默认做法,代价是每次调用都重新付费。微调供给推理干净,但适应成本随文档数量增长,文档一变就要重来。参数生成则训练一个超网络,输入上下文、输出适配器:基座模型冻结,测试时没有任何梯度更新。这相当于把每个文档的优化,摊销成一个文本到权重的映射。
CLIK 如何生成适配器
核心方法叫 CLIK,分三步。第一步编码:冻结的基座模型自己读一遍上下文,取出全部层的隐藏状态,再用可学习的加权系数合成条件序列。第二步生成:把目标适配器看作按层和层内位置排布的权重令牌网格,用因子化注意力分别沿层间和层内方向传递信息,再通过交叉注意力读取上下文,最后还原为低秩矩阵。关键在于整套适配器是联合生成的,而不是逐层独立输出碎片,避免层间依赖在拼接中丢失。第三步注入:把适配器加进前馈网络,模型随后只看问题作答。
训练目标是上下文蒸馏。教师是同一个冻结模型,但能同时看到上下文和问题;学生只能看到问题,身上挂着生成的适配器。两者在答案位置的下一词分布之间计算带温度的散度,梯度只流向生成器。教师给出的不只是正确答案,还有它对各种可能答案的相对信心。
效果与诚实的数据
实验以 Qwen3-4B 为基座,适配器秩为十六,覆盖三十六层前馈投影,每段上下文对应约两千一百万个生成参数。按作者自报的结果,在带格式指令的协议下,CLIK 在六个文档问答基准上的平均分为三十分,高于同等规模改造后的 SHINE 和 Doc-to-LoRA,但仍明显落后于直接读原文的基座模型,多跳问答上的差距尤其大,说明内化会丢失一部分需要多步组合的事实。变体只生成下投影矩阵,每段上下文的状态从四十点五兆字节压缩到二点八兆字节,平均分只下降约四分。
三笔账
第一笔是训练账。生成器本身约十亿参数,作者报告的训练耗时达数万个 GPU 小时,远高于基线方法。所谓“一次前向生成”省的是每个新文档的优化成本,不是训练成本,只有服务海量文档时才划算。第二笔是推理账。生成适配器仍需先编码一次上下文并跑一遍生成器,只有同一文档被反复提问时摊销才成立;只问一次的场景,直接读原文大概率更便宜、更准确。第三笔是维护账。适配器是不透明的权重,无法像文本那样直接检查或局部修改;文档更新后必须重新生成,多版本之间的知识冲突如何调和,论文并未解决。
对工程实践的启示
把适配器看作“编译产物”会更直观:原文是源代码,适配器是编译结果,查询是运行。源代码改了要重新编译,编译产物可以缓存、复用、按版本管理,但调试时很难反推回源码。对多轮对话、同一份知识库被反复追问、延迟敏感的场景,这条路有真实价值;对需要逐字引用、频繁变更、单次查询的场景,原文加检索仍是更稳妥的选择。
这篇论文目前是预印本,所有数字均为作者自报,离生产落地还有距离。但它指出了一个值得认真对待的方向:上下文工程的终点未必是越来越长的窗口,也可能是越来越便宜的内化。
- 点赞
- 收藏
- 关注作者
评论(0)