欢迎光临
我们一直在努力

大模型知识--学了新的忘了旧的

在这里插入图片描述

目录

  • 遗忘是怎么发生的
  • 机理:新解覆盖旧解
  • 遗忘的代价实测口径
  • 数据重放:旧数据当锚
  • EWC:重要参数上锁
  • LoRA:结构上防遗忘
  • 模型合并:任务向量加减
  • 回归监控与选型建议
  • 总结
  • 摘要

    学了新的忘了旧的,指的是持续预训练或领域微调之后,旧任务与通用能力大幅下降的现象。本文从现象证据讲到参数覆盖机理,再依次给出数据重放、EWC、LoRA、模型合并四类缓解工具。 遗忘的度量是旧任务性能下降幅度,学新与保旧构成一条双曲线,鱼与熊掌要靠显式付出才能兼得。 工程结论是领域适配优先 LoRA 加重放,不做全参微调,并保留通用回归测试集持续监控。

    1. 遗忘是怎么发生的

    灾难性遗忘(catastrophic forgetting)指模型在新任务或新语料上训练后,旧任务性能大幅下降的现象。这个词在 1989 年前后由连接主义研究者提出,比大模型早了三十多年。它不是大模型特有的 bug,而是梯度下降这种学习方式的固有属性。

    先给一个可感的类比。一位全科医生去进修法律,三年只读法条,回来后看病水平明显退化。原因不是脑子坏了,而是这三年的练习里没有任何一道题需要用到医学知识。模型的处境完全一样:训练数据里没有旧知识,更新就只朝新知识的方向走。

    #mermaid-svg-LZmTEXse4oQI2PK3{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-LZmTEXse4oQI2PK3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LZmTEXse4oQI2PK3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LZmTEXse4oQI2PK3 .error-icon{fill:#552222;}#mermaid-svg-LZmTEXse4oQI2PK3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LZmTEXse4oQI2PK3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LZmTEXse4oQI2PK3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LZmTEXse4oQI2PK3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LZmTEXse4oQI2PK3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LZmTEXse4oQI2PK3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LZmTEXse4oQI2PK3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LZmTEXse4oQI2PK3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LZmTEXse4oQI2PK3 .marker.cross{stroke:#333333;}#mermaid-svg-LZmTEXse4oQI2PK3 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LZmTEXse4oQI2PK3 p{margin:0;}#mermaid-svg-LZmTEXse4oQI2PK3 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-LZmTEXse4oQI2PK3 .cluster-label text{fill:#333;}#mermaid-svg-LZmTEXse4oQI2PK3 .cluster-label span{color:#333;}#mermaid-svg-LZmTEXse4oQI2PK3 .cluster-label span p{background-color:transparent;}#mermaid-svg-LZmTEXse4oQI2PK3 .label text,#mermaid-svg-LZmTEXse4oQI2PK3 span{fill:#333;color:#333;}#mermaid-svg-LZmTEXse4oQI2PK3 .node rect,#mermaid-svg-LZmTEXse4oQI2PK3 .node circle,#mermaid-svg-LZmTEXse4oQI2PK3 .node ellipse,#mermaid-svg-LZmTEXse4oQI2PK3 .node polygon,#mermaid-svg-LZmTEXse4oQI2PK3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-LZmTEXse4oQI2PK3 .rough-node .label text,#mermaid-svg-LZmTEXse4oQI2PK3 .node .label text,#mermaid-svg-LZmTEXse4oQI2PK3 .image-shape .label,#mermaid-svg-LZmTEXse4oQI2PK3 .icon-shape .label{text-anchor:middle;}#mermaid-svg-LZmTEXse4oQI2PK3 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-LZmTEXse4oQI2PK3 .rough-node .label,#mermaid-svg-LZmTEXse4oQI2PK3 .node .label,#mermaid-svg-LZmTEXse4oQI2PK3 .image-shape .label,#mermaid-svg-LZmTEXse4oQI2PK3 .icon-shape .label{text-align:center;}#mermaid-svg-LZmTEXse4oQI2PK3 .node.clickable{cursor:pointer;}#mermaid-svg-LZmTEXse4oQI2PK3 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-LZmTEXse4oQI2PK3 .arrowheadPath{fill:#333333;}#mermaid-svg-LZmTEXse4oQI2PK3 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-LZmTEXse4oQI2PK3 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-LZmTEXse4oQI2PK3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LZmTEXse4oQI2PK3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-LZmTEXse4oQI2PK3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LZmTEXse4oQI2PK3 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-LZmTEXse4oQI2PK3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-LZmTEXse4oQI2PK3 .cluster text{fill:#333;}#mermaid-svg-LZmTEXse4oQI2PK3 .cluster span{color:#333;}#mermaid-svg-LZmTEXse4oQI2PK3 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-LZmTEXse4oQI2PK3 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-LZmTEXse4oQI2PK3 rect.text{fill:none;stroke-width:0;}#mermaid-svg-LZmTEXse4oQI2PK3 .icon-shape,#mermaid-svg-LZmTEXse4oQI2PK3 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LZmTEXse4oQI2PK3 .icon-shape p,#mermaid-svg-LZmTEXse4oQI2PK3 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-LZmTEXse4oQI2PK3 .icon-shape .label rect,#mermaid-svg-LZmTEXse4oQI2PK3 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LZmTEXse4oQI2PK3 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-LZmTEXse4oQI2PK3 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-LZmTEXse4oQI2PK3 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-LZmTEXse4oQI2PK3 .default>*{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-LZmTEXse4oQI2PK3 .default span{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-LZmTEXse4oQI2PK3 .default tspan{fill:#000000!important;}

    基座模型

    通用能力达标

    新领域语料继续训练

    参数朝新领域最优解移动

    领域基准上升

    通用基准下降

    灾难性遗忘

    图 1-1 灾难性遗忘的因果链。同一次参数移动同时产生一升一降两个结果,上升与下降共享同一批梯度更新。

    1.1 现象证据:通用基准掉分

    持续预训练(CPT,continued pre-training)是在基座上继续用领域语料预训练。社区与论文反复报告同一现象:领域基准上升的同时,通用基准如 MMLU 掉分。掉分幅度没有统一数字,文献里常见从几个点到两位数点的区间,取决于语料规模、训练步数与配比。

    方向上可以确定三件事。第一,领域语料越多、训练越深,通用能力越容易被侵蚀。第二,指令微调做过头同样会损基座能力,语言流畅度与推理稳定性一起退化。第三,侵蚀往往先出现在通用知识的边缘部分,比如冷门事实与多步推理,常用的格式化能力最后才退化。

    训练方式领域基准通用基准典型原因
    全参 CPT,纯领域语料 明显上升 明显下降 无旧数据约束
    全参 CPT,混通用语料 上升 基本持平 重放起作用
    LoRA 微调,冻结基座 上升 掉分很小 结构上隔离更新
    指令微调过深 对话格式上升 基座能力受损 过拟合到对话模板

    表 1-1 四种适配方式的方向性对比。具体数字随模型与数据浮动,表中给出的是文献与社区报告的普遍方向。

    方向性表述的边界也要讲清楚。掉分不是线性的,前几百步可能几乎无感,超过某个训练量后加速下滑。这说明存在一个可用的适配区间,工程上的目标不是零遗忘,而是把遗忘压在自己可接受的阈值内。

    还有一个判断技巧。适配后的模型如果只在通用基准上掉分,而领域基准也没涨,说明训练本身没生效,不是遗忘问题。真正的遗忘画像是一边明确上涨一边明确下滑,两条曲线同时移动。排查时先把这两条曲线画在一张图上,避免把训练失败误诊为遗忘。

    观测样本也有讲究。通用基准要选与领域距离远的子集。比如做法律微调,就别拿法律相关的那部分 MMLU 题目当通用参照,那部分反而会上涨。选远域子集才能干净地测出通用能力的侵蚀幅度。

    基准选择上还有一个实际问题。MMLU 这类静态基准本身有题库泄漏风险,领域语料若来自爬取网页,可能含基准题目。掉分读数要先用未泄漏的私有题集复核,再下结论。泄漏方向是虚高,复核方向是找真实值,两者结合才可信。

    时间维度也别忽略。同一基座在不同月份复测,分数本身就有波动。把适配前的分数当唯一定基线,会把正常波动算成遗忘。更稳的做法是适配前连测两三次取均值,让基线自带置信区间。

    评测口径还要固定解码参数。温度与采样种子不固定时,同一模型的复测分数本身就有波动,幅度可达一两个点,足以掩盖或放大真实的遗忘读数。适配前后两次评测必须用同一套解码配置,报告里也要注明。

    再看一类特殊证据。有些团队报告适配后代码能力掉分,这看似与领域无关。原因在于代码与通用推理共享底层能力,领域语料挤掉的不只是事实,还有结构化表达。这说明通用基准要覆盖代码类,不能只考知识题。

    把这些证据整理成一条经验规律。同样训练步数下,领域语料与原语料的分布距离越大,通用掉分越早越重。法条与网页距离远,掉分猛。客服对话与网页距离近,掉分缓。预估遗忘幅度时先估分布距离,比直接估训练量更准。

    还有规模效应。小模型掉分往往比大模型更重,因为参数冗余少,共享冲突更尖锐。做迁移结论时别把小模型的掉分幅度直接外推到大模型,量级可能差不少。

    1.2 一升一降:为什么必然同时出现

    一升一降的根源在于参数是共享的。模型的每一层权重同时服务于通用能力与领域能力,不存在一块只属于法律、一块只属于医学的独立分区。新语料的梯度落在这些共享参数上,更新在优化领域损失的同时,不可避免地移动了通用能力的解。

    #mermaid-svg-ffdlZZUWDYlPnCmk{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ffdlZZUWDYlPnCmk .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ffdlZZUWDYlPnCmk .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ffdlZZUWDYlPnCmk .error-icon{fill:#552222;}#mermaid-svg-ffdlZZUWDYlPnCmk .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ffdlZZUWDYlPnCmk .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ffdlZZUWDYlPnCmk .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ffdlZZUWDYlPnCmk .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ffdlZZUWDYlPnCmk .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ffdlZZUWDYlPnCmk .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ffdlZZUWDYlPnCmk .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ffdlZZUWDYlPnCmk .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ffdlZZUWDYlPnCmk .marker.cross{stroke:#333333;}#mermaid-svg-ffdlZZUWDYlPnCmk svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ffdlZZUWDYlPnCmk p{margin:0;}#mermaid-svg-ffdlZZUWDYlPnCmk .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-ffdlZZUWDYlPnCmk .cluster-label text{fill:#333;}#mermaid-svg-ffdlZZUWDYlPnCmk .cluster-label span{color:#333;}#mermaid-svg-ffdlZZUWDYlPnCmk .cluster-label span p{background-color:transparent;}#mermaid-svg-ffdlZZUWDYlPnCmk .label text,#mermaid-svg-ffdlZZUWDYlPnCmk span{fill:#333;color:#333;}#mermaid-svg-ffdlZZUWDYlPnCmk .node rect,#mermaid-svg-ffdlZZUWDYlPnCmk .node circle,#mermaid-svg-ffdlZZUWDYlPnCmk .node ellipse,#mermaid-svg-ffdlZZUWDYlPnCmk .node polygon,#mermaid-svg-ffdlZZUWDYlPnCmk .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ffdlZZUWDYlPnCmk .rough-node .label text,#mermaid-svg-ffdlZZUWDYlPnCmk .node .label text,#mermaid-svg-ffdlZZUWDYlPnCmk .image-shape .label,#mermaid-svg-ffdlZZUWDYlPnCmk .icon-shape .label{text-anchor:middle;}#mermaid-svg-ffdlZZUWDYlPnCmk .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ffdlZZUWDYlPnCmk .rough-node .label,#mermaid-svg-ffdlZZUWDYlPnCmk .node .label,#mermaid-svg-ffdlZZUWDYlPnCmk .image-shape .label,#mermaid-svg-ffdlZZUWDYlPnCmk .icon-shape .label{text-align:center;}#mermaid-svg-ffdlZZUWDYlPnCmk .node.clickable{cursor:pointer;}#mermaid-svg-ffdlZZUWDYlPnCmk .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ffdlZZUWDYlPnCmk .arrowheadPath{fill:#333333;}#mermaid-svg-ffdlZZUWDYlPnCmk .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ffdlZZUWDYlPnCmk .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ffdlZZUWDYlPnCmk .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ffdlZZUWDYlPnCmk .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ffdlZZUWDYlPnCmk .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ffdlZZUWDYlPnCmk .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ffdlZZUWDYlPnCmk .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ffdlZZUWDYlPnCmk .cluster text{fill:#333;}#mermaid-svg-ffdlZZUWDYlPnCmk .cluster span{color:#333;}#mermaid-svg-ffdlZZUWDYlPnCmk div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ffdlZZUWDYlPnCmk .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ffdlZZUWDYlPnCmk rect.text{fill:none;stroke-width:0;}#mermaid-svg-ffdlZZUWDYlPnCmk .icon-shape,#mermaid-svg-ffdlZZUWDYlPnCmk .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ffdlZZUWDYlPnCmk .icon-shape p,#mermaid-svg-ffdlZZUWDYlPnCmk .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ffdlZZUWDYlPnCmk .icon-shape .label rect,#mermaid-svg-ffdlZZUWDYlPnCmk .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ffdlZZUWDYlPnCmk .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ffdlZZUWDYlPnCmk .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ffdlZZUWDYlPnCmk :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-ffdlZZUWDYlPnCmk .default>*{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-ffdlZZUWDYlPnCmk .default span{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-ffdlZZUWDYlPnCmk .default tspan{fill:#000000!important;}

    共享参数池

    通用能力的解

    领域A的解

    领域B的解

    新语料梯度

    领域B解被强化

    通用解被挤出

    图 1-2 共享参数池的挤出效应。梯度只能作用于唯一的一份参数,强化一处必然挤压他处。

    用一份玩具实验把这条曲线跑出来。两个线性任务先后训练,观察任务 A 的性能在训练任务 B 时如何崩塌。

    # 来源:自实现 / forgetting_demo.py
    import numpy as np

    def make_task(dim=40, seed=0):
    # 每个任务一组线性权重,代表一种知识
    rng = np.random.default_rng(seed)
    w = rng.normal(size=dim)
    X = rng.normal(size=(200, dim))
    y = X @ w
    return w, X, y

    def sgd_train(w, X, y, steps=300, lr=0.05):
    # 极简梯度下降,模拟顺序训练
    for _ in range(steps):
    grad = 2 * X.T @ (X @ w – y) / len(X)
    w = w – lr * grad
    return w

    def score(w, w_true, X):
    # 用预测误差的倒数衡量保留度,越大越好
    err = np.mean((X @ w – X @ w_true) ** 2)
    return 1.0 / (1.0 + err)

    w_a, X_a, y_a = make_task(seed=1)
    w_b, X_b, y_b = make_task(seed=2)

    w = np.zeros(40)
    w = sgd_train(w, X_a, y_a) # 阶段一:只学任务A
    s_a_before = score(w, w_a, X_a)
    w = sgd_train(w, X_b, y_b) # 阶段二:只学任务B
    s_a_after = score(w, w_a, X_a)
    s_b = score(w, w_b, X_b)
    print(f"阶段一后 任务A分数 {s_a_before:.3f}")
    print(f"阶段二后 任务A分数 {s_a_after:.3f}") # 典型输出接近 0.00x
    print(f"阶段二后 任务B分数 {s_b:.3f}")

    典型输出是任务 A 分数从 0.9 以上掉到 0.01 量级,任务 B 接近满分。这段代码证明两件事:顺序训练不需要任何错误操作,遗忘自然发生;遗忘幅度不是小幅退化,而是接近清零的崩塌。

    1.3 知识型微调的具体损失

    对知识型微调而言,被侵蚀的不只是某个旧基准分数。具体有三层损失。第一层是通用知识,模型对领域外事实的召回变差,常见表现是冷门知识开始编造。第二层是推理能力,多步推理链更容易断,这一点本系列第 7 篇讨论过。第三层是指令遵循,输出格式不稳定,长指令的中段要求被忽略。

    第三层最容易被误判。团队看到领域问答分数上涨,就认为微调成功。但格式漂移与指令遗漏要到上线后才暴露,因为领域评测集通常不考察这两项。这也是后文强调回归监控的原因:评测集必须覆盖被训练目标之外的维度。

    被侵蚀的能力典型表现暴露时机
    通用知识 领域外事实开始编造 上线后随机出现
    多步推理 推理链中段断裂 复杂任务返工
    指令遵循 长指令中段要求被忽略 上线后格式投诉
    输出稳定性 同题多次答案不一致 抽检时发现

    表 1-2 知识型微调的四类隐性损失。后两类在领域评测集上不可见,是误判的主要来源。

    三层损失的出现顺序也有规律。格式能力最先退化,因为它依赖的是输出分布的精细校准。推理其次,它需要多条知识同时可用。通用知识最后退化,因为高频事实在领域语料里往往仍有间接出现。据此可以设计分阶段监控,早期盯格式,后期盯推理。

    还有一个反直觉现象值得一提。领域微调后,模型对领域内问题的自信度上升,但对领域外问题的自信度没有同步下降。于是出现"答错但很自信"的输出,比单纯不知道更危险。这属于校准受损,回归集里应加入置信度抽查。

    把这些损失落到验收清单上。领域评测集之外,至少加四组题:远域事实问答、多步推理、长指令遵循、同题多次采样一致性。每组几十题,适配前后各跑一次。这份清单的成本远低于上线返工,也是第 8 章监控体系的最小可用版本。

    顺带说一句术语命名。领域微调后通用能力下降,常被团队口头称为"过拟合",但严格说过拟合指训练集上好测试集上差。这里的现象是能力此消彼长,更接近持续学习里的后向干扰。名称混用会让排查方向跑偏。

    损失之间还有传染性。推理能力下降会连带知识答题变差,因为很多知识题实际需要一到两步推理才能落到答案上。表现为知识题掉分,根因却在推理。排查时要分维度看,也要看维度间是否共因,否则补错方向。

    给一个自查问句清单。适配后的模型,远域事实还能答对吗,两步推理还能走通吗,长指令中段要求还记得吗,同题三次答案一致吗。四个问题各答一次,就能在十分钟内判断有没有明显遗忘,成本远低于完整回归。

    损失的严重度还与训练阶段有关。预训练阶段的继续训练伤知识底座,指令微调阶段的过深训练伤行为校准。两者叠加时最危险,知识底座与行为层同时松动。分阶段适配并在阶段间插入回归,能把损失定位到具体阶段。

    给个量级感受。轻度领域适配常见掉一两个点,重度适配可到五个点以上。超过十个点通常意味着训练配置有实质问题,比如学习率过高或语料过窄,这时先修配置再谈缓解。

    2. 机理:新解覆盖旧解

    机理层面,遗忘是参数空间的覆盖问题。旧任务在参数空间里有一个解,新任务有另一个解。顺序训练时,参数先停在旧解附近,再被拉到新解。旧解丢失,不是因为被删除,而是因为参数离开了那个位置。

    2.1 SGD 没有旧约束

    随机梯度下降(SGD)的更新规则只由当前 batch 的梯度决定。如果当前 batch 全来自新领域,那么这一步更新里没有任何一项阻止参数偏离旧任务的解。换句话说,旧任务的性能不在损失函数里,优化器自然不会为它负责。

    #mermaid-svg-Frj2aGBq2SzhUiDs{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Frj2aGBq2SzhUiDs .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Frj2aGBq2SzhUiDs .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Frj2aGBq2SzhUiDs .error-icon{fill:#552222;}#mermaid-svg-Frj2aGBq2SzhUiDs .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Frj2aGBq2SzhUiDs .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Frj2aGBq2SzhUiDs .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Frj2aGBq2SzhUiDs .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Frj2aGBq2SzhUiDs .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Frj2aGBq2SzhUiDs .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Frj2aGBq2SzhUiDs .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Frj2aGBq2SzhUiDs .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Frj2aGBq2SzhUiDs .marker.cross{stroke:#333333;}#mermaid-svg-Frj2aGBq2SzhUiDs svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Frj2aGBq2SzhUiDs p{margin:0;}#mermaid-svg-Frj2aGBq2SzhUiDs .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Frj2aGBq2SzhUiDs .cluster-label text{fill:#333;}#mermaid-svg-Frj2aGBq2SzhUiDs .cluster-label span{color:#333;}#mermaid-svg-Frj2aGBq2SzhUiDs .cluster-label span p{background-color:transparent;}#mermaid-svg-Frj2aGBq2SzhUiDs .label text,#mermaid-svg-Frj2aGBq2SzhUiDs span{fill:#333;color:#333;}#mermaid-svg-Frj2aGBq2SzhUiDs .node rect,#mermaid-svg-Frj2aGBq2SzhUiDs .node circle,#mermaid-svg-Frj2aGBq2SzhUiDs .node ellipse,#mermaid-svg-Frj2aGBq2SzhUiDs .node polygon,#mermaid-svg-Frj2aGBq2SzhUiDs .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Frj2aGBq2SzhUiDs .rough-node .label text,#mermaid-svg-Frj2aGBq2SzhUiDs .node .label text,#mermaid-svg-Frj2aGBq2SzhUiDs .image-shape .label,#mermaid-svg-Frj2aGBq2SzhUiDs .icon-shape .label{text-anchor:middle;}#mermaid-svg-Frj2aGBq2SzhUiDs .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Frj2aGBq2SzhUiDs .rough-node .label,#mermaid-svg-Frj2aGBq2SzhUiDs .node .label,#mermaid-svg-Frj2aGBq2SzhUiDs .image-shape .label,#mermaid-svg-Frj2aGBq2SzhUiDs .icon-shape .label{text-align:center;}#mermaid-svg-Frj2aGBq2SzhUiDs .node.clickable{cursor:pointer;}#mermaid-svg-Frj2aGBq2SzhUiDs .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Frj2aGBq2SzhUiDs .arrowheadPath{fill:#333333;}#mermaid-svg-Frj2aGBq2SzhUiDs .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Frj2aGBq2SzhUiDs .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Frj2aGBq2SzhUiDs .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Frj2aGBq2SzhUiDs .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Frj2aGBq2SzhUiDs .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Frj2aGBq2SzhUiDs .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Frj2aGBq2SzhUiDs .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Frj2aGBq2SzhUiDs .cluster text{fill:#333;}#mermaid-svg-Frj2aGBq2SzhUiDs .cluster span{color:#333;}#mermaid-svg-Frj2aGBq2SzhUiDs div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Frj2aGBq2SzhUiDs .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Frj2aGBq2SzhUiDs rect.text{fill:none;stroke-width:0;}#mermaid-svg-Frj2aGBq2SzhUiDs .icon-shape,#mermaid-svg-Frj2aGBq2SzhUiDs .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Frj2aGBq2SzhUiDs .icon-shape p,#mermaid-svg-Frj2aGBq2SzhUiDs .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Frj2aGBq2SzhUiDs .icon-shape .label rect,#mermaid-svg-Frj2aGBq2SzhUiDs .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Frj2aGBq2SzhUiDs .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Frj2aGBq2SzhUiDs .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Frj2aGBq2SzhUiDs :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-Frj2aGBq2SzhUiDs .default>*{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-Frj2aGBq2SzhUiDs .default span{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-Frj2aGBq2SzhUiDs .default tspan{fill:#000000!important;}

    当前batch只有新数据

    损失只含新任务项

    梯度只朝新最优解方向

    旧任务项不在损失里

    无任何力拉住参数

    旧解被覆盖

    图 2-1 SGD 缺少旧约束的链条。遗忘不需要额外机制,只需要旧任务缺席损失函数。

    这条机理直接给出缓解方向。既然问题是旧任务缺席,补法就有三类。把旧数据放回来,即数据重放。给重要参数加惩罚,即正则化。干脆不动原参数,即低秩适配。后文的四个工具全部落在这三类里。

    缓解类别作用位置代表方法代价
    数据侧 损失函数 重放 replay 需要留旧数据,占用训练预算
    正则侧 损失函数加惩罚项 EWC 需算 Fisher,超参敏感
    结构侧 参数更新路径 LoRA、适配器 容量受限,深度适配不足
    合并侧 训练后处理 任务向量加减 任务间可能互相干扰

    表 2-1 四类缓解方法的作用位置与代价。没有免费午餐,每一类都在别处付费。

    这条机理还能推出一个容易被忽略的结论。旧任务缺席不仅指数据缺席,也指评测缺席。很多团队在适配时完全没有旧任务的评测集,于是遗忘在训练过程中不可见,直到上线才被发现。约束缺失与观测缺失是同一个问题的两面。

    另一个推论关于优化器。Adam 这类自适应优化器会为每个参数维护动量与二阶矩,切换到新领域数据后,这些状态量的惯性会加速参数偏离旧解。所以长任务切换数据分布时,重置优化器状态有时能减缓遗忘,代价是学习曲线短暂变陡。

    还能解释为什么早停有效。遗忘随训练步数加深而加重,因为参数离旧解越来越远。在领域基准刚收敛时就停,位移量小,旧能力损失也小。工程上可以把领域分数的收敛点当停训候选点,再用回归分数确认是否可接受。

    2.2 参数重叠度决定遗忘幅度

    遗忘幅度不是随机的,它取决于两个任务的解在参数空间里的距离。如果新旧任务相似,解本来就接近,遗忘就轻。如果两个任务方向相反,参数被迫大位移,遗忘就重。

    # 来源:自实现 / overlap_effect.py
    import numpy as np

    def run_pair(angle_deg, dim=8, steps=400, lr=0.08):
    # 构造两个任务真值,夹角控制任务相似度
    w1 = np.zeros(dim); w1[0] = 1.0
    rad = np.deg2rad(angle_deg)
    w2 = np.zeros(dim); w2[0] = np.cos(rad); w2[1] = np.sin(rad)
    rng = np.random.default_rng(0)
    X = rng.normal(size=(120, dim))
    w = np.zeros(dim)
    for _ in range(steps): # 先学任务1
    w = w – lr * 2 * X.T @ (X @ w – X @ w1) / len(X)
    s1 = 1.0 / (1.0 + np.mean((X @ w – X @ w1) ** 2))
    for _ in range(steps): # 再学任务2
    w = w – lr * 2 * X.T @ (X @ w – X @ w2) / len(X)
    s1_after = 1.0 / (1.0 + np.mean((X @ w – X @ w1) ** 2))
    return s1, s1_after

    for ang in (0, 15, 45, 90, 180):
    before, after = run_pair(ang)
    print(f"夹角{ang:3d}度 保旧前{before:.3f} 保旧后{after:.3f}")

    典型结果是:夹角 0 度时几乎没有遗忘,15 度轻微,45 度明显,90 度与 180 度接近崩塌。这段代码把"任务相似度决定遗忘幅度"量化出来,也解释了为什么领域语料与原语料分布差异越大,通用能力掉得越狠。

    2.3 覆盖不是删除

    有一个常见误解需要澄清。遗忘不等于知识被删除。实验上,用少量旧数据重放几个 epoch,旧任务性能常能部分恢复。这说明旧解的"痕迹"还在,只是参数离它远了,一个小的回拉力就能部分找回。

    这也解释了为什么重放有效率高的一面。恢复旧能力不需要重放全部旧数据,少量样本足以提供方向信号。但恢复不等于完全复原,尤其对推理这类脆弱能力,重放后仍可能留缺口。

    #mermaid-svg-GCr77neAk4B7NNVI{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-GCr77neAk4B7NNVI .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-GCr77neAk4B7NNVI .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-GCr77neAk4B7NNVI .error-icon{fill:#552222;}#mermaid-svg-GCr77neAk4B7NNVI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-GCr77neAk4B7NNVI .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-GCr77neAk4B7NNVI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-GCr77neAk4B7NNVI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-GCr77neAk4B7NNVI .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-GCr77neAk4B7NNVI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-GCr77neAk4B7NNVI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-GCr77neAk4B7NNVI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-GCr77neAk4B7NNVI .marker.cross{stroke:#333333;}#mermaid-svg-GCr77neAk4B7NNVI svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-GCr77neAk4B7NNVI p{margin:0;}#mermaid-svg-GCr77neAk4B7NNVI .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-GCr77neAk4B7NNVI .cluster-label text{fill:#333;}#mermaid-svg-GCr77neAk4B7NNVI .cluster-label span{color:#333;}#mermaid-svg-GCr77neAk4B7NNVI .cluster-label span p{background-color:transparent;}#mermaid-svg-GCr77neAk4B7NNVI .label text,#mermaid-svg-GCr77neAk4B7NNVI span{fill:#333;color:#333;}#mermaid-svg-GCr77neAk4B7NNVI .node rect,#mermaid-svg-GCr77neAk4B7NNVI .node circle,#mermaid-svg-GCr77neAk4B7NNVI .node ellipse,#mermaid-svg-GCr77neAk4B7NNVI .node polygon,#mermaid-svg-GCr77neAk4B7NNVI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-GCr77neAk4B7NNVI .rough-node .label text,#mermaid-svg-GCr77neAk4B7NNVI .node .label text,#mermaid-svg-GCr77neAk4B7NNVI .image-shape .label,#mermaid-svg-GCr77neAk4B7NNVI .icon-shape .label{text-anchor:middle;}#mermaid-svg-GCr77neAk4B7NNVI .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-GCr77neAk4B7NNVI .rough-node .label,#mermaid-svg-GCr77neAk4B7NNVI .node .label,#mermaid-svg-GCr77neAk4B7NNVI .image-shape .label,#mermaid-svg-GCr77neAk4B7NNVI .icon-shape .label{text-align:center;}#mermaid-svg-GCr77neAk4B7NNVI .node.clickable{cursor:pointer;}#mermaid-svg-GCr77neAk4B7NNVI .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-GCr77neAk4B7NNVI .arrowheadPath{fill:#333333;}#mermaid-svg-GCr77neAk4B7NNVI .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-GCr77neAk4B7NNVI .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-GCr77neAk4B7NNVI .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GCr77neAk4B7NNVI .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-GCr77neAk4B7NNVI .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GCr77neAk4B7NNVI .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-GCr77neAk4B7NNVI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-GCr77neAk4B7NNVI .cluster text{fill:#333;}#mermaid-svg-GCr77neAk4B7NNVI .cluster span{color:#333;}#mermaid-svg-GCr77neAk4B7NNVI div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-GCr77neAk4B7NNVI .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-GCr77neAk4B7NNVI rect.text{fill:none;stroke-width:0;}#mermaid-svg-GCr77neAk4B7NNVI .icon-shape,#mermaid-svg-GCr77neAk4B7NNVI .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GCr77neAk4B7NNVI .icon-shape p,#mermaid-svg-GCr77neAk4B7NNVI .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-GCr77neAk4B7NNVI .icon-shape .label rect,#mermaid-svg-GCr77neAk4B7NNVI .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GCr77neAk4B7NNVI .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-GCr77neAk4B7NNVI .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-GCr77neAk4B7NNVI :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-GCr77neAk4B7NNVI .default>*{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-GCr77neAk4B7NNVI .default span{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-GCr77neAk4B7NNVI .default tspan{fill:#000000!important;}

    有效

    推得太远

    旧解S1

    训练新数据后到S2

    少量旧数据重放

    部分回到S1附近

    回拉力不足

    旧性能部分恢复

    残留不可逆缺口

    图 2-2 覆盖与恢复的不对称。参数离旧解的距离决定少量重放是否够用,距离过远时恢复不完整。

    参数位移程度少量重放效果恢复完整度
    轻微偏离 基本恢复 高
    中等偏离 部分恢复 中
    推到远处 恢复有限 低

    表 2-2 位移程度与可恢复性。位移越远,重放救回的比例越低,这是重放要持续混入的依据。

    边界提示:如果训练步数极大、学习率较高,参数可能被推到离旧解非常远的区域,此时少量重放也救不回来。所以重放应当在新训练过程中持续混入,而不是等崩了再抢救。

    还有一点工程含义。既然旧解的痕迹仍在,那么适配早期发现回归掉分时,立即停训并回滚到上一个 checkpoint,代价远小于继续训练后再补救。所以 checkpoint 间隔不宜拉得太长,常见做法是按训练步数固定间隔保存,并保留至少三份历史版本。

    3. 遗忘的代价实测口径

    度量是工程的前提。遗忘度量的标准定义是旧任务性能下降幅度:遗忘量等于旧任务初始性能减去新训练后的性能。下降越多,遗忘越重。

    3.1 双曲线:学新与保旧的取舍

    把新任务性能当横轴、旧任务性能当纵轴,扫一遍训练强度或重放比例,得到一条双曲线。曲线上的点不能同时到达右上角,学新与保旧此消彼长。缓解方法的作用是把整条曲线往右上方推,但推不穿取舍本身。

    #mermaid-svg-az4A5K5VZEF7Y1Xn{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-az4A5K5VZEF7Y1Xn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-az4A5K5VZEF7Y1Xn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-az4A5K5VZEF7Y1Xn .error-icon{fill:#552222;}#mermaid-svg-az4A5K5VZEF7Y1Xn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-az4A5K5VZEF7Y1Xn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-az4A5K5VZEF7Y1Xn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-az4A5K5VZEF7Y1Xn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-az4A5K5VZEF7Y1Xn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-az4A5K5VZEF7Y1Xn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-az4A5K5VZEF7Y1Xn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-az4A5K5VZEF7Y1Xn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-az4A5K5VZEF7Y1Xn .marker.cross{stroke:#333333;}#mermaid-svg-az4A5K5VZEF7Y1Xn svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-az4A5K5VZEF7Y1Xn p{margin:0;}#mermaid-svg-az4A5K5VZEF7Y1Xn .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-az4A5K5VZEF7Y1Xn .cluster-label text{fill:#333;}#mermaid-svg-az4A5K5VZEF7Y1Xn .cluster-label span{color:#333;}#mermaid-svg-az4A5K5VZEF7Y1Xn .cluster-label span p{background-color:transparent;}#mermaid-svg-az4A5K5VZEF7Y1Xn .label text,#mermaid-svg-az4A5K5VZEF7Y1Xn span{fill:#333;color:#333;}#mermaid-svg-az4A5K5VZEF7Y1Xn .node rect,#mermaid-svg-az4A5K5VZEF7Y1Xn .node circle,#mermaid-svg-az4A5K5VZEF7Y1Xn .node ellipse,#mermaid-svg-az4A5K5VZEF7Y1Xn .node polygon,#mermaid-svg-az4A5K5VZEF7Y1Xn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-az4A5K5VZEF7Y1Xn .rough-node .label text,#mermaid-svg-az4A5K5VZEF7Y1Xn .node .label text,#mermaid-svg-az4A5K5VZEF7Y1Xn .image-shape .label,#mermaid-svg-az4A5K5VZEF7Y1Xn .icon-shape .label{text-anchor:middle;}#mermaid-svg-az4A5K5VZEF7Y1Xn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-az4A5K5VZEF7Y1Xn .rough-node .label,#mermaid-svg-az4A5K5VZEF7Y1Xn .node .label,#mermaid-svg-az4A5K5VZEF7Y1Xn .image-shape .label,#mermaid-svg-az4A5K5VZEF7Y1Xn .icon-shape .label{text-align:center;}#mermaid-svg-az4A5K5VZEF7Y1Xn .node.clickable{cursor:pointer;}#mermaid-svg-az4A5K5VZEF7Y1Xn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-az4A5K5VZEF7Y1Xn .arrowheadPath{fill:#333333;}#mermaid-svg-az4A5K5VZEF7Y1Xn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-az4A5K5VZEF7Y1Xn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-az4A5K5VZEF7Y1Xn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-az4A5K5VZEF7Y1Xn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-az4A5K5VZEF7Y1Xn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-az4A5K5VZEF7Y1Xn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-az4A5K5VZEF7Y1Xn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-az4A5K5VZEF7Y1Xn .cluster text{fill:#333;}#mermaid-svg-az4A5K5VZEF7Y1Xn .cluster span{color:#333;}#mermaid-svg-az4A5K5VZEF7Y1Xn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-az4A5K5VZEF7Y1Xn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-az4A5K5VZEF7Y1Xn rect.text{fill:none;stroke-width:0;}#mermaid-svg-az4A5K5VZEF7Y1Xn .icon-shape,#mermaid-svg-az4A5K5VZEF7Y1Xn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-az4A5K5VZEF7Y1Xn .icon-shape p,#mermaid-svg-az4A5K5VZEF7Y1Xn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-az4A5K5VZEF7Y1Xn .icon-shape .label rect,#mermaid-svg-az4A5K5VZEF7Y1Xn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-az4A5K5VZEF7Y1Xn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-az4A5K5VZEF7Y1Xn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-az4A5K5VZEF7Y1Xn :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-az4A5K5VZEF7Y1Xn .default>*{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-az4A5K5VZEF7Y1Xn .default span{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-az4A5K5VZEF7Y1Xn .default tspan{fill:#000000!important;}

    训练强度或配比扫描

    每个点测两个分数

    新任务性能为横轴

    旧任务性能为纵轴

    连成学新保旧双曲线

    曲线右上移即缓解生效

    图 3-1 双曲线的生成方式。缓解方法的评价标准不是单点分数,而是整条曲线是否外移。

    口径定义用途
    前向迁移 新任务初始性能 学新是否容易
    后向遗忘 旧任务性能下降幅度 本文核心口径
    平均性能 新旧任务均值 粗略综合指标
    面积指标 双曲线下面积 比较方法整体水平

    表 3-1 持续学习常用四种度量。后向遗忘是最直接的口径,面积指标适合跨方法比较。

    双曲线还有一层含义。曲线上的每个点对应一种配置,选择哪一点是业务决策而不是技术决策。客服场景可能宁可少学一点领域也要守住指令遵循,研发助手场景可能反过来。把曲线画出来交给业务方选点,比单点调参更有效率。

    画曲线的成本要控制。全量扫一遍配比代价高,常见做法是三点起步:低配比、中配比、高配比各跑一次,先确定曲线的大致走向,再在拐点附近加密采样。这样通常五到七个点就能定位到业务可接受的区间。

    还要注意曲线会随数据变化。领域语料更新一批后,原来的最优点可能偏移。所以双曲线不是一次性产物,应随语料版本重跑关键点,把配比当持续维护的超参而不是定死的常数。

    3.2 回归监控的代码骨架

    遗忘度量落到工程上就是回归监控。做法是固定一套通用基准,每次适配后必跑,与基线分数对比,超阈值就报警。

    # 来源:自实现 / forgetting_monitor.py
    import numpy as np

    def evaluate(w, suite):
    # suite 是基准字典,值为真值方向
    out = {}
    for name, w_true in suite.items():
    err = np.mean((w – w_true) ** 2)
    out[name] = 1.0 / (1.0 + err)
    return out

    def forgetting_report(baseline, current, threshold=0.10):
    # 遗忘量等于基线减当前,正值即退化
    rows = []
    for name in baseline:
    drop = baseline[name] – current[name]
    flag = "报警" if drop > threshold else "正常"
    rows.append((name, baseline[name], current[name], drop, flag))
    return rows

    if __name__ == "__main__":
    rng = np.random.default_rng(3)
    suite = {"通用知识": rng.normal(size=16),
    "通用推理": rng.normal(size=16),
    "指令遵循": rng.normal(size=16)}
    baseline = evaluate(np.zeros(16), suite) # 假装是适配前
    w_after = rng.normal(size=16) * 0.6 # 假装是适配后
    current = evaluate(w_after, suite)
    for name, b, c, d, f in forgetting_report(baseline, current):
    print(f"{name} 基线{b:.2f} 当前{c:.2f} 遗忘{d:+.2f} {f}")

    这段代码的核心是 forgetting_report 函数:遗忘量按维度分别计算并各自设阈值,而不是看总分。总分会被领域分数的上涨掩盖,分维度才暴露指令遵循这类隐性退化。

    3.3 常见误测与陷阱

    第一类误测是只跑领域基准。领域分数上涨与通用退化同时发生,只看前者会得出微调成功的错误结论。第二类是基准泄漏,通用回归集里混入了与领域语料同源的样本,分数虚高。第三类是提示词漂移,适配后模型对旧提示词的敏感度变化,测的不是知识而是格式。

    陷阱表现后果
    只跑领域基准 领域分涨通用分跌 误判微调成功
    基准泄漏 回归集混入同源样本 遗忘被低估
    提示词漂移 分数变化来自格式 测错对象
    单次采样 未控制解码随机性 波动当趋势

    表 3-2 四类常见误测。第三类最隐蔽,因为分数确实变了,只是变的原因不是知识。

    对策是三件事。回归集与领域语料严格隔离来源。回归集固定提示词模板,版本化管理。每次跑回归同时记录分布,做横向对比而不只做纵向对比。

    解码参数也要固定。温度设为零或固定值,采样种子固定,否则同一次评测的波动可能达到一两个点,把真实退化淹没在噪声里。对于开放式生成题,建议用固定参考答案加关键词命中判定,避免人工评分的主观漂移。

    最后一类坑是样本量不足。回归集每个维度只有十来道题时,单题对错就能造成 5 个点以上的波动。经验做法是每个维度至少几十道题,覆盖不同难度与不同问法,让单题影响压到 2 个点以内。

    还有一类陷阱与题目难度分布有关。回归集如果偏简单,适配后分数几乎不动,会得出零遗忘的假象。原因是大模型对简单题的冗余度高,参数位移不大时答案不变。回归集要保留一定比例的中高难度题,才对参数变化敏感。

    监控频率也要匹配训练节奏。只在训练结束后跑一次回归,无法区分是哪个阶段开始退化。建议在训练中按 checkpoint 间隔抽样跑轻量版回归,定位到退化开始的位置,再决定回滚还是调参。

    陷阱清单之外,还要防一种统计错误。只看单次差值就下结论,没有置信区间。回归集每维几十题时,两三个百分点的差异可能在噪声范围内。简单做法是同题集跑两次取均值,或把差异与历史波动幅度对比,超出波动才算真信号。

    最后是流程陷阱。回归集只在与领域团队无关的人手里时才可信。如果评测由微调执行者自己跑自己判,主观上倾向放行。把回归评测独立成角色或用脚本全自动判分,能消掉这层偏差。

    再列一个流程性陷阱。回归集建好后没有基线数据,第一次跑就是适配后的分数,无从对比。基线必须在适配前建立并归档,含分数、解码配置与题集版本。没有基线的回归等于没有刻度的尺子。

    陷阱的最后一项是过度依赖单一基准。任何一个基准都只覆盖能力的一角。两三个互补基准交叉验证,比一个基准反复跑更能反映真实遗忘。常见组合是一个知识型基准加一个推理型基准加一组指令题。

    4. 数据重放:旧数据当锚

    数据重放(replay)是最直接的补法:旧数据不放走,按比例混进新训练里。旧样本出现在 batch 中,损失函数就重新含旧任务项,梯度里就有了回拉力。

    4.1 重放比例与保留曲线

    重放比例是关键超参。比例太低锚不住,比例太高学不动新领域。经验区间通常在 5% 到 30% 之间起步,再按回归分数微调。

    #mermaid-svg-A1YS9uC3W5ddkoOr{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-A1YS9uC3W5ddkoOr .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-A1YS9uC3W5ddkoOr .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-A1YS9uC3W5ddkoOr .error-icon{fill:#552222;}#mermaid-svg-A1YS9uC3W5ddkoOr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-A1YS9uC3W5ddkoOr .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-A1YS9uC3W5ddkoOr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-A1YS9uC3W5ddkoOr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-A1YS9uC3W5ddkoOr .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-A1YS9uC3W5ddkoOr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-A1YS9uC3W5ddkoOr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-A1YS9uC3W5ddkoOr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-A1YS9uC3W5ddkoOr .marker.cross{stroke:#333333;}#mermaid-svg-A1YS9uC3W5ddkoOr svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-A1YS9uC3W5ddkoOr p{margin:0;}#mermaid-svg-A1YS9uC3W5ddkoOr .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-A1YS9uC3W5ddkoOr .cluster-label text{fill:#333;}#mermaid-svg-A1YS9uC3W5ddkoOr .cluster-label span{color:#333;}#mermaid-svg-A1YS9uC3W5ddkoOr .cluster-label span p{background-color:transparent;}#mermaid-svg-A1YS9uC3W5ddkoOr .label text,#mermaid-svg-A1YS9uC3W5ddkoOr span{fill:#333;color:#333;}#mermaid-svg-A1YS9uC3W5ddkoOr .node rect,#mermaid-svg-A1YS9uC3W5ddkoOr .node circle,#mermaid-svg-A1YS9uC3W5ddkoOr .node ellipse,#mermaid-svg-A1YS9uC3W5ddkoOr .node polygon,#mermaid-svg-A1YS9uC3W5ddkoOr .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-A1YS9uC3W5ddkoOr .rough-node .label text,#mermaid-svg-A1YS9uC3W5ddkoOr .node .label text,#mermaid-svg-A1YS9uC3W5ddkoOr .image-shape .label,#mermaid-svg-A1YS9uC3W5ddkoOr .icon-shape .label{text-anchor:middle;}#mermaid-svg-A1YS9uC3W5ddkoOr .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-A1YS9uC3W5ddkoOr .rough-node .label,#mermaid-svg-A1YS9uC3W5ddkoOr .node .label,#mermaid-svg-A1YS9uC3W5ddkoOr .image-shape .label,#mermaid-svg-A1YS9uC3W5ddkoOr .icon-shape .label{text-align:center;}#mermaid-svg-A1YS9uC3W5ddkoOr .node.clickable{cursor:pointer;}#mermaid-svg-A1YS9uC3W5ddkoOr .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-A1YS9uC3W5ddkoOr .arrowheadPath{fill:#333333;}#mermaid-svg-A1YS9uC3W5ddkoOr .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-A1YS9uC3W5ddkoOr .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-A1YS9uC3W5ddkoOr .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-A1YS9uC3W5ddkoOr .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-A1YS9uC3W5ddkoOr .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-A1YS9uC3W5ddkoOr .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-A1YS9uC3W5ddkoOr .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-A1YS9uC3W5ddkoOr .cluster text{fill:#333;}#mermaid-svg-A1YS9uC3W5ddkoOr .cluster span{color:#333;}#mermaid-svg-A1YS9uC3W5ddkoOr div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-A1YS9uC3W5ddkoOr .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-A1YS9uC3W5ddkoOr rect.text{fill:none;stroke-width:0;}#mermaid-svg-A1YS9uC3W5ddkoOr .icon-shape,#mermaid-svg-A1YS9uC3W5ddkoOr .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-A1YS9uC3W5ddkoOr .icon-shape p,#mermaid-svg-A1YS9uC3W5ddkoOr .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-A1YS9uC3W5ddkoOr .icon-shape .label rect,#mermaid-svg-A1YS9uC3W5ddkoOr .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-A1YS9uC3W5ddkoOr .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-A1YS9uC3W5ddkoOr .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-A1YS9uC3W5ddkoOr :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-A1YS9uC3W5ddkoOr .default>*{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-A1YS9uC3W5ddkoOr .default span{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-A1YS9uC3W5ddkoOr .default tspan{fill:#000000!important;}

    领域新语料

    按比例混合

    通用重放语料

    一个batch内新旧共存

    梯度含两项

    新能力上升

    旧能力被锚住

    图 4-1 重放的混合训练流程。旧样本进入 batch 是全部机制所在,简单但有效。

    # 来源:自实现 / replay_curve.py
    import numpy as np

    def make_task(dim=30, seed=0, n=150):
    # 旧任务为基准方向,新任务在其上加扰动,模拟领域与通用语料高度重叠
    rng = np.random.default_rng(seed)
    w = rng.normal(size=dim)
    X = rng.normal(size=(n, dim))
    return w, X, X @ w

    def train_mixed(w, Xa, ya, Xb, yb, ratio, steps=600, lr=0.03):
    # ratio 是旧任务项在总损失里的权重,模拟重放数据占比
    for _ in range(steps):
    ga = 2 * Xa.T @ (Xa @ w – ya) / len(Xa) # 旧任务全批梯度
    if len(Xb): # 空集时新任务项记零
    gb = 2 * Xb.T @ (Xb @ w – yb) / len(Xb)
    else:
    gb = 0.0
    w = w – lr * (ratio * ga + (1 – ratio) * gb)
    return w

    def score(w, wt, X):
    return 1.0 / (1.0 + np.mean((X @ w – X @ wt) ** 2))

    wa, Xa, ya = make_task(seed=10)
    wb, Xb, yb = make_task(seed=11)
    # 新领域目标与通用目标重叠约七成,贴近真实领域适配场景
    wb = 0.7 * wa + 0.3 * wb / np.linalg.norm(wb) * np.linalg.norm(wa)
    yb = Xb @ wb

    w0 = train_mixed(np.zeros(30), Xa, ya, Xb[:0], yb[:0], 1.0) # 先只学旧任务

    print("重放比例 保旧分数 学新分数")
    for r in (0.0, 0.05, 0.1, 0.2, 0.5):
    w = train_mixed(w0.copy(), Xa, ya, Xb, yb, r)
    print(f"{r:8.2f} {score(w, wa, Xa):7.3f} {score(w, wb, Xb):7.3f}")

    实测输出呈双曲线形态:重放 0 时保旧只有 0.21,学新满分。重放升到 0.2 时保旧回到 0.32,学新降到 0.85。重放 0.5 时保旧 0.56,学新 0.53,两边接近持平。这份表就是第 3 章双曲线的实测来源,也验证了任务重叠度决定可用区间。

    4.2 重放数据从哪来

    工程上有三个来源。第一是保留原预训练语料的抽样,成本最低但要拿到授权与存储。第二是合成回放,用基座模型自己生成通用样本,不依赖原始语料。第三是通用指令数据集的公开子集,用于对齐阶段的回锚。

    来源成本保旧效果风险
    原语料抽样 存储与授权 最好 版权与合规
    自生成回放 推理算力 中等 自我强化偏差
    公开通用子集 低 中等 分布覆盖不全

    表 4-1 三类重放来源对比。实际项目常组合使用,原语料加公开子集是常见搭配。

    适配场景首选来源备选
    自研基座团队 原语料抽样 加公开子集补推理
    开源基座二次开发 公开通用子集 自生成回放补充
    无法存原始数据 自生成回放 EWC 顶替数据侧

    表 4-2 三种团队形态的重放来源选择。数据可得性决定起点,效果再靠配比调优。

    三类来源各有适配场景。原语料抽样适合自研基座的团队,数据在自己手里。自生成回放适合拿不到原语料的场景,比如基于开源基座做二次开发,代价是要控制生成多样性,否则重放的是模型的偏差。公开通用子集最省事,但覆盖面有限,推理类题目占比往往不足。

    配比之外还要管采样策略。均匀抽样会让高频样本反复出现,低频但关键的能力被稀释。改进做法是按能力维度分层抽样,比如通用知识、推理、指令各占固定份额,确保每一维都有足够回拉力。

    还有一个实用细节:重放样本要打乱后与新数据混合,不能先训一批旧的再训一批新的。分批顺序训练等于制造第二次顺序遗忘,混合均匀才能让两项约束在每个 batch 里同时生效。

    数量级给个参考。重放集不需要与原预训练语料同量级,通常领域语料的 10% 到 30% 规模即可,关键是覆盖维度而不是样本总量。一个只有几千条但覆盖四类能力的重放集,往往好过几万条同类样本的堆量。

    维护上要版本化。重放集本身会随业务演进,比如指令遵循的典型形态变化。每次更新重放集都重跑一次基线,否则新旧两版的分数不可比,趋势判断会失真。

    自生成回放有个升级做法。不只生成通用问答,还生成针对回归集四维能力的定向样本。先用基座生成,再人工抽检质量,按维度归档。这样重放集与监控维度一一对应,哪个维度掉分就知道补哪个池子,闭环更清晰。

    混合来源时要防一个坑。公开子集与自生成样本的语言风格不同,模型可能学到风格差异而不是能力。解决办法是两类来源各占一定份额并打乱混排,避免模型把来源当特征。

    4.3 边界与失败模式

    重放的失败模式有三类。第一类是分布不匹配,重放样本太窄,锚住了表层格式却没锚住推理。第二类是预算挤占,重放占 30% 训练量,等价于新领域少训三成,学习速度被迫放慢。第三类是配比失效,随着训练推进,最优重放比例会变化,固定比例后期可能不足。

    #mermaid-svg-SqRLPYApFaD7DN4J{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-SqRLPYApFaD7DN4J .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-SqRLPYApFaD7DN4J .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-SqRLPYApFaD7DN4J .error-icon{fill:#552222;}#mermaid-svg-SqRLPYApFaD7DN4J .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-SqRLPYApFaD7DN4J .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-SqRLPYApFaD7DN4J .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-SqRLPYApFaD7DN4J .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-SqRLPYApFaD7DN4J .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-SqRLPYApFaD7DN4J .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-SqRLPYApFaD7DN4J .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-SqRLPYApFaD7DN4J .marker{fill:#333333;stroke:#333333;}#mermaid-svg-SqRLPYApFaD7DN4J .marker.cross{stroke:#333333;}#mermaid-svg-SqRLPYApFaD7DN4J svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-SqRLPYApFaD7DN4J p{margin:0;}#mermaid-svg-SqRLPYApFaD7DN4J .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-SqRLPYApFaD7DN4J .cluster-label text{fill:#333;}#mermaid-svg-SqRLPYApFaD7DN4J .cluster-label span{color:#333;}#mermaid-svg-SqRLPYApFaD7DN4J .cluster-label span p{background-color:transparent;}#mermaid-svg-SqRLPYApFaD7DN4J .label text,#mermaid-svg-SqRLPYApFaD7DN4J span{fill:#333;color:#333;}#mermaid-svg-SqRLPYApFaD7DN4J .node rect,#mermaid-svg-SqRLPYApFaD7DN4J .node circle,#mermaid-svg-SqRLPYApFaD7DN4J .node ellipse,#mermaid-svg-SqRLPYApFaD7DN4J .node polygon,#mermaid-svg-SqRLPYApFaD7DN4J .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-SqRLPYApFaD7DN4J .rough-node .label text,#mermaid-svg-SqRLPYApFaD7DN4J .node .label text,#mermaid-svg-SqRLPYApFaD7DN4J .image-shape .label,#mermaid-svg-SqRLPYApFaD7DN4J .icon-shape .label{text-anchor:middle;}#mermaid-svg-SqRLPYApFaD7DN4J .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-SqRLPYApFaD7DN4J .rough-node .label,#mermaid-svg-SqRLPYApFaD7DN4J .node .label,#mermaid-svg-SqRLPYApFaD7DN4J .image-shape .label,#mermaid-svg-SqRLPYApFaD7DN4J .icon-shape .label{text-align:center;}#mermaid-svg-SqRLPYApFaD7DN4J .node.clickable{cursor:pointer;}#mermaid-svg-SqRLPYApFaD7DN4J .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-SqRLPYApFaD7DN4J .arrowheadPath{fill:#333333;}#mermaid-svg-SqRLPYApFaD7DN4J .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-SqRLPYApFaD7DN4J .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-SqRLPYApFaD7DN4J .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-SqRLPYApFaD7DN4J .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-SqRLPYApFaD7DN4J .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-SqRLPYApFaD7DN4J .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-SqRLPYApFaD7DN4J .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-SqRLPYApFaD7DN4J .cluster text{fill:#333;}#mermaid-svg-SqRLPYApFaD7DN4J .cluster span{color:#333;}#mermaid-svg-SqRLPYApFaD7DN4J div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-SqRLPYApFaD7DN4J .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-SqRLPYApFaD7DN4J rect.text{fill:none;stroke-width:0;}#mermaid-svg-SqRLPYApFaD7DN4J .icon-shape,#mermaid-svg-SqRLPYApFaD7DN4J .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-SqRLPYApFaD7DN4J .icon-shape p,#mermaid-svg-SqRLPYApFaD7DN4J .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-SqRLPYApFaD7DN4J .icon-shape .label rect,#mermaid-svg-SqRLPYApFaD7DN4J .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-SqRLPYApFaD7DN4J .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-SqRLPYApFaD7DN4J .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-SqRLPYApFaD7DN4J :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-SqRLPYApFaD7DN4J .default>*{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-SqRLPYApFaD7DN4J .default span{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-SqRLPYApFaD7DN4J .default tspan{fill:#000000!important;}

    是

    否

    固定重放比例

    训练推进后回归掉分

    比例已不足

    维持比例继续

    上调重放比例

    重跑回归验证

    图 4-2 重放比例的动态调节回路。比例不是一次定死的超参,而是随回归信号迭代的控制量。

    失败模式信号修正动作
    分布不匹配 推理维度掉分最重 扩充重放集覆盖
    预算挤占 领域分数上不去 延长训练或降重放
    配比失效 后期回归再掉分 动态上调比例

    表 4-3 重放的三类失败与修正。信号都来自回归监控,这也是回归集必须先建的原因。

    对应做法:重放集要覆盖通用、推理、指令三类;把重放预算计入总预算再做排期;关键节点重跑回归并动态调比例。重放不解决全部问题,但它应当是所有方案的默认底座。

    最后一个常被忽略的边界:重放只能守住重放集覆盖到的分布。模型基线能力是个很宽的分布,重放集只是抽样。抽样外的能力仍可能退化,只是测不到。所以重放加回归监控必须成对出现,重放提供约束,监控提供暴露。

    两者配合的闭环是:监控发现某维度掉分,检查重放集是否覆盖该维度,不覆盖则补样本,覆盖则上调该维度份额。这个闭环让重放从静态配比变成可维护的资产。

    5. EWC:重要参数上锁

    弹性权重巩固(EWC,elastic weight consolidation)是正则化路线的代表。论文编号是 arXiv 1612.00796。它不留旧数据,改为对旧任务重要的参数加惩罚。本节先讲重要性怎么估计,再看惩罚怎么写进损失。

    5.1 Fisher 信息近似重要性

    EWC 用 Fisher 信息矩阵的对角线近似来度量参数对旧任务的重要性。直觉是:某参数轻微扰动会让旧任务损失大幅上升,它就是重要参数,应当锁住。损失函数加一项二次惩罚,权重就是 Fisher 值。

    #mermaid-svg-QU4k0xe9DOy8kYJA{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QU4k0xe9DOy8kYJA .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QU4k0xe9DOy8kYJA .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QU4k0xe9DOy8kYJA .error-icon{fill:#552222;}#mermaid-svg-QU4k0xe9DOy8kYJA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QU4k0xe9DOy8kYJA .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QU4k0xe9DOy8kYJA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QU4k0xe9DOy8kYJA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QU4k0xe9DOy8kYJA .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QU4k0xe9DOy8kYJA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QU4k0xe9DOy8kYJA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QU4k0xe9DOy8kYJA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QU4k0xe9DOy8kYJA .marker.cross{stroke:#333333;}#mermaid-svg-QU4k0xe9DOy8kYJA svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QU4k0xe9DOy8kYJA p{margin:0;}#mermaid-svg-QU4k0xe9DOy8kYJA .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-QU4k0xe9DOy8kYJA .cluster-label text{fill:#333;}#mermaid-svg-QU4k0xe9DOy8kYJA .cluster-label span{color:#333;}#mermaid-svg-QU4k0xe9DOy8kYJA .cluster-label span p{background-color:transparent;}#mermaid-svg-QU4k0xe9DOy8kYJA .label text,#mermaid-svg-QU4k0xe9DOy8kYJA span{fill:#333;color:#333;}#mermaid-svg-QU4k0xe9DOy8kYJA .node rect,#mermaid-svg-QU4k0xe9DOy8kYJA .node circle,#mermaid-svg-QU4k0xe9DOy8kYJA .node ellipse,#mermaid-svg-QU4k0xe9DOy8kYJA .node polygon,#mermaid-svg-QU4k0xe9DOy8kYJA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QU4k0xe9DOy8kYJA .rough-node .label text,#mermaid-svg-QU4k0xe9DOy8kYJA .node .label text,#mermaid-svg-QU4k0xe9DOy8kYJA .image-shape .label,#mermaid-svg-QU4k0xe9DOy8kYJA .icon-shape .label{text-anchor:middle;}#mermaid-svg-QU4k0xe9DOy8kYJA .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-QU4k0xe9DOy8kYJA .rough-node .label,#mermaid-svg-QU4k0xe9DOy8kYJA .node .label,#mermaid-svg-QU4k0xe9DOy8kYJA .image-shape .label,#mermaid-svg-QU4k0xe9DOy8kYJA .icon-shape .label{text-align:center;}#mermaid-svg-QU4k0xe9DOy8kYJA .node.clickable{cursor:pointer;}#mermaid-svg-QU4k0xe9DOy8kYJA .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-QU4k0xe9DOy8kYJA .arrowheadPath{fill:#333333;}#mermaid-svg-QU4k0xe9DOy8kYJA .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QU4k0xe9DOy8kYJA .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QU4k0xe9DOy8kYJA .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QU4k0xe9DOy8kYJA .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-QU4k0xe9DOy8kYJA .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QU4k0xe9DOy8kYJA .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-QU4k0xe9DOy8kYJA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QU4k0xe9DOy8kYJA .cluster text{fill:#333;}#mermaid-svg-QU4k0xe9DOy8kYJA .cluster span{color:#333;}#mermaid-svg-QU4k0xe9DOy8kYJA div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-QU4k0xe9DOy8kYJA .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QU4k0xe9DOy8kYJA rect.text{fill:none;stroke-width:0;}#mermaid-svg-QU4k0xe9DOy8kYJA .icon-shape,#mermaid-svg-QU4k0xe9DOy8kYJA .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QU4k0xe9DOy8kYJA .icon-shape p,#mermaid-svg-QU4k0xe9DOy8kYJA .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-QU4k0xe9DOy8kYJA .icon-shape .label rect,#mermaid-svg-QU4k0xe9DOy8kYJA .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QU4k0xe9DOy8kYJA .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QU4k0xe9DOy8kYJA .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QU4k0xe9DOy8kYJA :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-QU4k0xe9DOy8kYJA .default>*{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-QU4k0xe9DOy8kYJA .default span{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-QU4k0xe9DOy8kYJA .default tspan{fill:#000000!important;}

    旧任务训练完成

    采样估计Fisher对角阵

    Fisher大的参数标记为重要

    新任务训练

    损失加二次惩罚项

    重要参数移动被抑制

    旧解基本保住

    图 5-1 EWC 的两阶段流程。重要性估计在前,惩罚约束在后,全程不使用旧数据本身。

    # 来源:自实现 / ewc_demo.py,简化实现
    import numpy as np

    def fisher_diag(w_star, X, y, steps=200):
    # 经验Fisher:用随机标签重采样估计参数敏感度
    rng = np.random.default_rng(11)
    acc = np.zeros_like(w_star)
    for _ in range(steps):
    idx = np.random.randint(0, len(X), 32)
    y_p = y[idx] + rng.normal(scale=0.1, size=len(idx)) # 标签扰动
    g = 2 * X[idx].T @ (X[idx] @ w_star – y_p) / 32
    acc += g ** 2 # 平方累积近似重要性
    F = acc / steps
    return F / (F.max() + 1e-12) # 归一到0到1,惩罚系数才可比

    def train_ewc(w, X_new, y_new, fisher, w_star, lam, steps=400, lr=0.06, clip=1.0):
    for _ in range(steps):
    g = 2 * X_new.T @ (X_new @ w – y_new) / len(X_new)
    g += lam * fisher * (w – w_star) # 关键行:重要参数加惩罚
    n = np.linalg.norm(g)
    if n > clip: # 梯度裁剪,大lam下防发散
    g = g * clip / n
    w = w – lr * g
    return w

    def score(w, wt, X):
    return 1.0 / (1.0 + np.mean((X @ w – X @ wt) ** 2))

    if __name__ == "__main__":
    rng = np.random.default_rng(7)
    dim, n = 24, 120
    w_a = rng.normal(size=dim); X_a = rng.normal(size=(n, dim)); y_a = X_a @ w_a
    w_b = rng.normal(size=dim); X_b = rng.normal(size=(n, dim)); y_b = X_b @ w_b
    w = np.zeros(dim)
    for _ in range(300): # 先学任务A到收敛
    w = w – 0.06 * 2 * X_a.T @ (X_a @ w – y_a) / n
    w_star = w.copy()
    F = fisher_diag(w_star, X_a, y_a)
    print("惩罚系数 保旧分数 学新分数")
    for lam in (0.0, 1.0, 10.0, 100.0):
    w2 = train_ewc(w_star.copy(), X_b, y_b, F, w_star, lam)
    print(f"{lam:8.1f} {score(w2, w_a, X_a):7.3f} {score(w2, w_b, X_b):7.3f}")

    惩罚系数那一列是核心。lam 为 0 退化为纯顺序训练,保旧崩到 0.02。lam 升到 10 时保旧回到 0.34,学新降到 0.04。lam 到 100 时保旧 0.97,学新被压到 0.02。这段代码直接复现 EWC 论文的核心取舍:锁得越紧,新知识越难进去。

    5.2 与重放的互补关系

    EWC 与重放不是二选一。重放提供数据侧的回拉力,EWC 提供参数侧的锁定力。当旧数据拿不到或存储受限时,EWC 是唯一选项。当旧数据充足时,重放通常更稳,因为约束直接来自真实分布而不是对角 Fisher 的近似。

    维度数据重放EWC
    依赖旧数据 是 否
    额外计算 训练量增加 Fisher 估计一次
    超参敏感度 重放比例 惩罚系数
    对角近似误差 无此问题 高维下有偏差
    大模型可用性 高 受规模限制

    表 5-1 重放与 EWC 的多维对比。实际大模型项目里重放更常用,EWC 思想常以软形式融入。

    一个具体差异在于可解释性。重放出问题时,可以回溯到重放集的构成,缺哪类样本补哪类,归因路径清晰。EWC 出问题时,只能看到惩罚系数这一个旋钮,Fisher 值本身不直观,排查往往退化为重新扫参。这也是工程上重放更受欢迎的原因之一。

    两者也可以叠加。重放管数据分布,EWC 管参数位移,叠加时惩罚系数要下调,否则双重约束会把可动空间压得太小,新领域学不进去。叠加的价值在重放拿不全旧分布时,用参数锁补上没覆盖到的部分。

    边界提示:对角 Fisher 在大模型上只是粗近似,参数间的相关性被忽略。惩罚过强会导致新领域学不进去,形成另一种失败:模型看似没遗忘,其实是拒绝学新。上表"大模型可用性"一行说的就是这个,Fisher 估计本身也要在全量数据上前向若干遍,规模一大成本就不低。

    从 toy 实验还能读出一条规律。惩罚系数每升一个量级,保旧分数大幅上升而学新分数几乎贴地。这说明 EWC 的可用窗口偏窄,调参要细扫而不是粗扫。真实项目里建议按对数间隔扫惩罚系数,每档都记录双曲线点位。

    一个判断标准帮你在两者间选边。如果能拿到旧数据,优先重放,因为约束直接来自真实分布。如果拿不到,先用 LoRA 从结构上隔离,EWC 作为补充。直接对大模型算 Fisher 的场景相对少,多数团队在数据侧解决。

    EWC 思想还有个轻量变体:不显式算 Fisher,只对参数加权重衰减式的位移惩罚,权重对所有参数一致。这损失了重要性区分,但实现成本接近零,常作为默认配置先挂上,效果不够再升级到真 EWC。

    如果一定要在大模型上用 EWC 思想,实操上是简化版。只在适配相关的层上估计 Fisher,其余层直接冻结或低学习率。这样 Fisher 计算量大幅下降,效果损失有限。全模型 Fisher 估计在工程上很少真的做,成本与收益不匹配。

    从双曲线视角比较两者,重放的曲线通常整体更靠右上,因为约束来自真实分布。EWC 曲线更靠内,但对角近似让它在小任务上表现尚可。选型时如果两条曲线都能画出来,直接比面积指标即可。

    从实现难度看,重放只改数据管道,训练代码不动。EWC 要改损失函数并新增 Fisher 估计流程。工程改造成本上重放明显更低,这也是它成为默认选择的原因。先低成本方案跑通,再按需升级。

    还有一个组合细节。如果同时用重放与 EWC,Fisher 应基于重放后的旧任务分布估计,而不是原始分布。否则锁住的是旧分布的参数位置,与重放的数据约束可能打架,调参空间变得更复杂。

    6. LoRA:结构上防遗忘

    LoRA(low-rank adaptation)从结构上解决问题。做法是冻结基座全部参数,只在旁边挂低秩矩阵 B 与 A,前向变成冻结 W 加 B 乘 A 的增量。基座的旧解从结构上不可能被覆盖。

    6.1 参数量与效果对照

    LoRA 的数学形式是输出等于冻结 W 乘输入加 B 乘 A 乘输入,其中 B 与 A 是两个小矩阵。可训练参数量从全部参数降到两个小矩阵,通常只有原模型的一小部分,量级在百分之一以下。

    #mermaid-svg-yliCtMNlgwRT1C5e{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-yliCtMNlgwRT1C5e .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-yliCtMNlgwRT1C5e .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-yliCtMNlgwRT1C5e .error-icon{fill:#552222;}#mermaid-svg-yliCtMNlgwRT1C5e .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-yliCtMNlgwRT1C5e .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-yliCtMNlgwRT1C5e .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-yliCtMNlgwRT1C5e .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-yliCtMNlgwRT1C5e .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-yliCtMNlgwRT1C5e .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-yliCtMNlgwRT1C5e .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-yliCtMNlgwRT1C5e .marker{fill:#333333;stroke:#333333;}#mermaid-svg-yliCtMNlgwRT1C5e .marker.cross{stroke:#333333;}#mermaid-svg-yliCtMNlgwRT1C5e svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-yliCtMNlgwRT1C5e p{margin:0;}#mermaid-svg-yliCtMNlgwRT1C5e .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-yliCtMNlgwRT1C5e .cluster-label text{fill:#333;}#mermaid-svg-yliCtMNlgwRT1C5e .cluster-label span{color:#333;}#mermaid-svg-yliCtMNlgwRT1C5e .cluster-label span p{background-color:transparent;}#mermaid-svg-yliCtMNlgwRT1C5e .label text,#mermaid-svg-yliCtMNlgwRT1C5e span{fill:#333;color:#333;}#mermaid-svg-yliCtMNlgwRT1C5e .node rect,#mermaid-svg-yliCtMNlgwRT1C5e .node circle,#mermaid-svg-yliCtMNlgwRT1C5e .node ellipse,#mermaid-svg-yliCtMNlgwRT1C5e .node polygon,#mermaid-svg-yliCtMNlgwRT1C5e .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-yliCtMNlgwRT1C5e .rough-node .label text,#mermaid-svg-yliCtMNlgwRT1C5e .node .label text,#mermaid-svg-yliCtMNlgwRT1C5e .image-shape .label,#mermaid-svg-yliCtMNlgwRT1C5e .icon-shape .label{text-anchor:middle;}#mermaid-svg-yliCtMNlgwRT1C5e .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-yliCtMNlgwRT1C5e .rough-node .label,#mermaid-svg-yliCtMNlgwRT1C5e .node .label,#mermaid-svg-yliCtMNlgwRT1C5e .image-shape .label,#mermaid-svg-yliCtMNlgwRT1C5e .icon-shape .label{text-align:center;}#mermaid-svg-yliCtMNlgwRT1C5e .node.clickable{cursor:pointer;}#mermaid-svg-yliCtMNlgwRT1C5e .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-yliCtMNlgwRT1C5e .arrowheadPath{fill:#333333;}#mermaid-svg-yliCtMNlgwRT1C5e .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-yliCtMNlgwRT1C5e .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-yliCtMNlgwRT1C5e .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yliCtMNlgwRT1C5e .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-yliCtMNlgwRT1C5e .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yliCtMNlgwRT1C5e .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-yliCtMNlgwRT1C5e .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-yliCtMNlgwRT1C5e .cluster text{fill:#333;}#mermaid-svg-yliCtMNlgwRT1C5e .cluster span{color:#333;}#mermaid-svg-yliCtMNlgwRT1C5e div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-yliCtMNlgwRT1C5e .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-yliCtMNlgwRT1C5e rect.text{fill:none;stroke-width:0;}#mermaid-svg-yliCtMNlgwRT1C5e .icon-shape,#mermaid-svg-yliCtMNlgwRT1C5e .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yliCtMNlgwRT1C5e .icon-shape p,#mermaid-svg-yliCtMNlgwRT1C5e .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-yliCtMNlgwRT1C5e .icon-shape .label rect,#mermaid-svg-yliCtMNlgwRT1C5e .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yliCtMNlgwRT1C5e .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-yliCtMNlgwRT1C5e .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-yliCtMNlgwRT1C5e :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-yliCtMNlgwRT1C5e .default>*{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-yliCtMNlgwRT1C5e .default span{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-yliCtMNlgwRT1C5e .default tspan{fill:#000000!important;}

    输入x

    冻结的基座W

    可训练低秩B乘A

    两路相加

    输出y

    旧解原封不动

    图 6-1 LoRA 的双路结构。旁路增量与冻结主干并行,这是它防遗忘的全部秘密。

    # 来源:自实现 / lora_demo.py,mock 版本
    import numpy as np

    class LinearLoRA:
    def __init__(self, d_in, d_out, rank=4, seed=0):
    rng = np.random.default_rng(seed)
    self.W = rng.normal(scale=0.05, size=(d_in, d_out)) # 冻结基座
    self.B = np.zeros((rank, d_out)) # 初始为零保证起点一致
    self.A = rng.normal(scale=0.01, size=(d_in, rank))
    self.W_frozen = self.W.copy() # 备份旧解
    self.trainable = [self.A, self.B]

    def forward(self, x):
    return x @ self.W + x @ self.A @ self.B

    def param_count(self):
    full = self.W.size
    lora = self.A.size + self.B.size
    return full, lora, lora / full

    if __name__ == "__main__":
    layer = LinearLoRA(512, 512, rank=8)
    full, lora, ratio = layer.param_count()
    print(f"全参微调参数量 {full}")
    print(f"LoRA可训练参数量 {lora}")
    print(f"占比 {ratio:.4f}")
    print(f"基座是否原封未动 {np.array_equal(layer.W, layer.W_frozen)}")

    这段代码展示两件事。512 乘 512 的层全参要 26 万参数,秩 8 的 LoRA 只要约 8 千,占比约百分之三。训练结束后基座矩阵与备份逐元素相等,遗忘在结构层面被排除。

    6.2 为什么结构隔离仍有代价

    结构隔离不等于零代价。第一,容量上限变低,秩 8 到 32 的旁路难以承载大量新知识,深度领域适配可能欠拟合。第二,干扰转移,旁路与主干相加,旁路学到的偏置仍会在领域外样本上生效,表现为通用任务上轻微掉分。第三,多个任务的 LoRA 不能同时挂载推理,切换有工程成本。

    方案可训练参数量防遗忘强度新知识容量显存占用
    全参微调 全部 无 最大 最高
    LoRA 秩 8 约 0.1 到 1 个百分点 强 小 低
    LoRA 秩 32 约 1 到 5 个百分点 中 中 低
    重放加全参 全部 中 大 最高

    表 6-1 各方案的多维权衡。表中比例为常见区间,随模型规模与目标模块配置浮动。

    旁路挂载位置也影响防遗忘效果。只挂在注意力层的投影矩阵上,通用能力保护得好但知识容量小。同时挂到 FFN 层,容量上来,干扰风险也随之上升。本系列第 2 篇讲过 FFN 承担事实存储,动它就是动知识本体,所以要更谨慎。

    容量问题值得展开。LoRA 的旁路矩阵秩为 r 时,能表达的方向数上限就是 r。领域知识如果需要多个独立方向才能分开,秩低于这个数就学不进去。判断方法很直接:领域基准收敛但明显低于全参微调的参考分数,大概率是秩不够,先升秩再怀疑数据。

    干扰转移的量级通常不大,但方向值得知道。旁路对领域外样本输出一个固定偏置,等价于给所有输出加了一个领域先验。重放通用样本就是在教旁路"领域外时把增量压回零",这也是 6.3 组合拳的原理。

    挂载与切换的工程成本也要算。多任务各自一套 LoRA 权重,推理时按请求切换,需要网关层支持热加载与显存预算管理。任务数超过个位数时,合并或路由方案往往比多套旁路更省。

    与全参微调的对比要给个量化感受。同量级领域语料下,全参微调的领域分数通常高于 LoRA,差距随任务难度拉大。防遗忘的代价就是这份学习上限,选型时先确认业务能接受多大的领域分数让步,再决定是否上全参。

    还有推理侧的差异。挂载 LoRA 后每次前向多两次小矩阵乘法,延迟增加通常在小比例区间,但高并发场景要计入成本。多套旁路并存时显存也要预算,每套旁路虽小,数量多了不可忽略。

    还要区分两种掉分来源。基座没动,掉分只能来自旁路,这叫旁路偏置。基座动了,掉分来自主干,这才叫经典遗忘。LoRA 把第二种归零,第一种仍在。排查时先冻结旁路复测,能立刻分辨掉分来自哪一层。

    这个区分也指导修复。旁路偏置靠重放通用样本压回去,主干遗忘靠回滚或重放。修错层等于白费功夫,所以诊断这一步不能省。冻结旁路是一次推理实验,成本极低。

    旁路的初始化也影响防遗忘表现。标准做法是 B 初始化为零、A 随机小值,保证训练起点等于基座行为。如果两个矩阵都随机初始化,训练一开始就引入扰动,等于自带一层初始噪声,回归起点就不干净。

    另一个细节是学习率。旁路参数量小,常用学习率比全参微调高一个量级。但学习率过高时旁路快速偏移,领域外偏置随之放大。调参时旁路学习率与重放比例要一起看,两者共同决定旁路的行为边界。

    6.3 组合拳:LoRA 加重放

    LoRA 防住主干被覆盖,但旁路仍可能在通用分布上产生偏置。组合拳是在 LoRA 训练数据里同时混入通用重放样本,让旁路学到"领域内偏、领域外零"的行为。这是工程上最常见的稳定配置,也是本文选型建议的默认起点。

    #mermaid-svg-ri4Sy5TUMGc9k08b{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ri4Sy5TUMGc9k08b .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ri4Sy5TUMGc9k08b .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ri4Sy5TUMGc9k08b .error-icon{fill:#552222;}#mermaid-svg-ri4Sy5TUMGc9k08b .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ri4Sy5TUMGc9k08b .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ri4Sy5TUMGc9k08b .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ri4Sy5TUMGc9k08b .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ri4Sy5TUMGc9k08b .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ri4Sy5TUMGc9k08b .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ri4Sy5TUMGc9k08b .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ri4Sy5TUMGc9k08b .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ri4Sy5TUMGc9k08b .marker.cross{stroke:#333333;}#mermaid-svg-ri4Sy5TUMGc9k08b svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ri4Sy5TUMGc9k08b p{margin:0;}#mermaid-svg-ri4Sy5TUMGc9k08b .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-ri4Sy5TUMGc9k08b .cluster-label text{fill:#333;}#mermaid-svg-ri4Sy5TUMGc9k08b .cluster-label span{color:#333;}#mermaid-svg-ri4Sy5TUMGc9k08b .cluster-label span p{background-color:transparent;}#mermaid-svg-ri4Sy5TUMGc9k08b .label text,#mermaid-svg-ri4Sy5TUMGc9k08b span{fill:#333;color:#333;}#mermaid-svg-ri4Sy5TUMGc9k08b .node rect,#mermaid-svg-ri4Sy5TUMGc9k08b .node circle,#mermaid-svg-ri4Sy5TUMGc9k08b .node ellipse,#mermaid-svg-ri4Sy5TUMGc9k08b .node polygon,#mermaid-svg-ri4Sy5TUMGc9k08b .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ri4Sy5TUMGc9k08b .rough-node .label text,#mermaid-svg-ri4Sy5TUMGc9k08b .node .label text,#mermaid-svg-ri4Sy5TUMGc9k08b .image-shape .label,#mermaid-svg-ri4Sy5TUMGc9k08b .icon-shape .label{text-anchor:middle;}#mermaid-svg-ri4Sy5TUMGc9k08b .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ri4Sy5TUMGc9k08b .rough-node .label,#mermaid-svg-ri4Sy5TUMGc9k08b .node .label,#mermaid-svg-ri4Sy5TUMGc9k08b .image-shape .label,#mermaid-svg-ri4Sy5TUMGc9k08b .icon-shape .label{text-align:center;}#mermaid-svg-ri4Sy5TUMGc9k08b .node.clickable{cursor:pointer;}#mermaid-svg-ri4Sy5TUMGc9k08b .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ri4Sy5TUMGc9k08b .arrowheadPath{fill:#333333;}#mermaid-svg-ri4Sy5TUMGc9k08b .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ri4Sy5TUMGc9k08b .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ri4Sy5TUMGc9k08b .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ri4Sy5TUMGc9k08b .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ri4Sy5TUMGc9k08b .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ri4Sy5TUMGc9k08b .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ri4Sy5TUMGc9k08b .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ri4Sy5TUMGc9k08b .cluster text{fill:#333;}#mermaid-svg-ri4Sy5TUMGc9k08b .cluster span{color:#333;}#mermaid-svg-ri4Sy5TUMGc9k08b div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ri4Sy5TUMGc9k08b .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ri4Sy5TUMGc9k08b rect.text{fill:none;stroke-width:0;}#mermaid-svg-ri4Sy5TUMGc9k08b .icon-shape,#mermaid-svg-ri4Sy5TUMGc9k08b .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ri4Sy5TUMGc9k08b .icon-shape p,#mermaid-svg-ri4Sy5TUMGc9k08b .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ri4Sy5TUMGc9k08b .icon-shape .label rect,#mermaid-svg-ri4Sy5TUMGc9k08b .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ri4Sy5TUMGc9k08b .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ri4Sy5TUMGc9k08b .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ri4Sy5TUMGc9k08b :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-ri4Sy5TUMGc9k08b .default>*{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-ri4Sy5TUMGc9k08b .default span{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-ri4Sy5TUMGc9k08b .default tspan{fill:#000000!important;}

    领域语料

    混合训练

    通用重放样本

    只更新旁路BA

    领域样本产生偏置

    通用样本压回零

    领域内生效领域外归零

    图 6-2 LoRA 加重放的行为塑造。旁路学到的是条件化增量,而不是无条件偏置。

    配置防主干遗忘防旁路偏置实施成本
    纯 LoRA 结构保证 无 低
    纯重放加全参 数据约束 不适用 高
    LoRA 加重放 结构保证 数据约束 中

    表 6-2 三种配置的防护层次。组合拳是唯一同时覆盖两层遗忘路径的配置。

    需要注意秩的选择。秩过小新领域学不进去,过大接近全参的干扰风险。常见做法是从秩 8 或 16 起步,看领域基准是否收敛,再决定是否上调。回归分数与领域分数要同时看,单看任何一边都会误判。

    组合拳的调参顺序有讲究。先定秩再看配比,因为秩决定容量上限,配比不足可以用更多训练步数补,容量不足则补不动。常见路径是秩 16 起步,领域分数到平台期后判断是否升秩,重放比例始终跟随回归分数调整。

    一个实用验收标准:领域基准达到目标,同时四个回归维度降幅都在阈值内。两条同时满足才放行。只满足第一条的组合拳配置不成立,说明重放比例或旁路秩需要再调。

    7. 模型合并:任务向量加减

    模型合并(model merging)是训练后处理路线。做法是先算任务向量,等于微调后权重减去基座权重,再在向量层面做加减与组合,不触碰原始训练数据。相关方向的系统讨论见 arXiv 2212.04089,此处按方向性表述处理。

    7.1 任务向量的加减法

    任务向量提供了一个直观视角:微调学到的东西可以表示为基座上的一个位移。两个任务的向量相加得到一个同时具备两种能力的模型,两个向量相减可以移除某种能力。这种线性视角在多数场景是近似成立,不是精确成立。

    #mermaid-svg-eri8CfJoh99FztE7{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-eri8CfJoh99FztE7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-eri8CfJoh99FztE7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-eri8CfJoh99FztE7 .error-icon{fill:#552222;}#mermaid-svg-eri8CfJoh99FztE7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-eri8CfJoh99FztE7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-eri8CfJoh99FztE7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-eri8CfJoh99FztE7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-eri8CfJoh99FztE7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-eri8CfJoh99FztE7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-eri8CfJoh99FztE7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-eri8CfJoh99FztE7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-eri8CfJoh99FztE7 .marker.cross{stroke:#333333;}#mermaid-svg-eri8CfJoh99FztE7 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-eri8CfJoh99FztE7 p{margin:0;}#mermaid-svg-eri8CfJoh99FztE7 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-eri8CfJoh99FztE7 .cluster-label text{fill:#333;}#mermaid-svg-eri8CfJoh99FztE7 .cluster-label span{color:#333;}#mermaid-svg-eri8CfJoh99FztE7 .cluster-label span p{background-color:transparent;}#mermaid-svg-eri8CfJoh99FztE7 .label text,#mermaid-svg-eri8CfJoh99FztE7 span{fill:#333;color:#333;}#mermaid-svg-eri8CfJoh99FztE7 .node rect,#mermaid-svg-eri8CfJoh99FztE7 .node circle,#mermaid-svg-eri8CfJoh99FztE7 .node ellipse,#mermaid-svg-eri8CfJoh99FztE7 .node polygon,#mermaid-svg-eri8CfJoh99FztE7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-eri8CfJoh99FztE7 .rough-node .label text,#mermaid-svg-eri8CfJoh99FztE7 .node .label text,#mermaid-svg-eri8CfJoh99FztE7 .image-shape .label,#mermaid-svg-eri8CfJoh99FztE7 .icon-shape .label{text-anchor:middle;}#mermaid-svg-eri8CfJoh99FztE7 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-eri8CfJoh99FztE7 .rough-node .label,#mermaid-svg-eri8CfJoh99FztE7 .node .label,#mermaid-svg-eri8CfJoh99FztE7 .image-shape .label,#mermaid-svg-eri8CfJoh99FztE7 .icon-shape .label{text-align:center;}#mermaid-svg-eri8CfJoh99FztE7 .node.clickable{cursor:pointer;}#mermaid-svg-eri8CfJoh99FztE7 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-eri8CfJoh99FztE7 .arrowheadPath{fill:#333333;}#mermaid-svg-eri8CfJoh99FztE7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-eri8CfJoh99FztE7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-eri8CfJoh99FztE7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-eri8CfJoh99FztE7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-eri8CfJoh99FztE7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-eri8CfJoh99FztE7 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-eri8CfJoh99FztE7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-eri8CfJoh99FztE7 .cluster text{fill:#333;}#mermaid-svg-eri8CfJoh99FztE7 .cluster span{color:#333;}#mermaid-svg-eri8CfJoh99FztE7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-eri8CfJoh99FztE7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-eri8CfJoh99FztE7 rect.text{fill:none;stroke-width:0;}#mermaid-svg-eri8CfJoh99FztE7 .icon-shape,#mermaid-svg-eri8CfJoh99FztE7 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-eri8CfJoh99FztE7 .icon-shape p,#mermaid-svg-eri8CfJoh99FztE7 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-eri8CfJoh99FztE7 .icon-shape .label rect,#mermaid-svg-eri8CfJoh99FztE7 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-eri8CfJoh99FztE7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-eri8CfJoh99FztE7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-eri8CfJoh99FztE7 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-eri8CfJoh99FztE7 .default>*{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-eri8CfJoh99FztE7 .default span{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-eri8CfJoh99FztE7 .default tspan{fill:#000000!important;}

    基座权重T0

    领域微调后T1

    任务向量等于T1减T0

    向量按系数相加

    得到合并后权重

    单模型多能力

    向量相减则移除能力

    图 7-1 任务向量的构造与合并。关键洞察是微调增量可以脱离原数据被独立操作。

    操作表达式含义典型用途
    向量相加 两个位移叠加 合并多个领域能力
    向量相减 去掉某位移 移除不良行为
    系数缩放 位移乘小于1的系数 降低干扰
    逐层加权 不同层不同系数 精细合并

    表 7-1 任务向量的四种操作。方向性结论来自模型合并方向的公开研究,具体效果随模型浮动。

    这套操作的工程价值在于解耦。传统做法是一份权重上迭代,每加一个能力都要重跑全部回归。任务向量方式下,每个能力独立训练独立验证,组合时只验证组合点,验证工作量从随能力数线性增长降到只与组合数相关。

    还有一个被低估的用途是退化修复。某次微调引入了不良行为,比如过度拒答,可以用该次微调的任务向量按小于 1 的系数减回去,比重新训练便宜得多。前提是保留了基座权重与微调后权重,否则算不出向量。

    实现层面这套操作的门槛很低。只需要保存基座权重与每次微调后的权重,相减得到向量,合并就是基座加各向量按系数求和。不涉及训练,只需要权重算术与一次验证评测,几小时内可以试完多种组合。

    系数选择上有个经验方向。直接用系数 1 相加常会过冲,表现为主干能力下降。用 0.5 到 0.8 的系数往往更稳,牺牲一点领域能力换主干的稳定。多任务时各系数可以不同,重要任务给高系数。

    7.2 合并的边界与失败模式

    合并不是万能药。第一类失败是任务间干扰,两个向量在同一参数上方向相反,相加后互相抵消,两边都掉分。第二类是能力不对齐,合并后的模型在两个任务的混合指令上表现不稳。第三类是符号性局限,权重空间的线性叠加不等于能力的线性叠加,深层网络存在大量非线性行为。

    #mermaid-svg-H0qLPkxg8DDfpK9o{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-H0qLPkxg8DDfpK9o .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-H0qLPkxg8DDfpK9o .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-H0qLPkxg8DDfpK9o .error-icon{fill:#552222;}#mermaid-svg-H0qLPkxg8DDfpK9o .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-H0qLPkxg8DDfpK9o .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-H0qLPkxg8DDfpK9o .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-H0qLPkxg8DDfpK9o .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-H0qLPkxg8DDfpK9o .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-H0qLPkxg8DDfpK9o .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-H0qLPkxg8DDfpK9o .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-H0qLPkxg8DDfpK9o .marker{fill:#333333;stroke:#333333;}#mermaid-svg-H0qLPkxg8DDfpK9o .marker.cross{stroke:#333333;}#mermaid-svg-H0qLPkxg8DDfpK9o svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-H0qLPkxg8DDfpK9o p{margin:0;}#mermaid-svg-H0qLPkxg8DDfpK9o .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-H0qLPkxg8DDfpK9o .cluster-label text{fill:#333;}#mermaid-svg-H0qLPkxg8DDfpK9o .cluster-label span{color:#333;}#mermaid-svg-H0qLPkxg8DDfpK9o .cluster-label span p{background-color:transparent;}#mermaid-svg-H0qLPkxg8DDfpK9o .label text,#mermaid-svg-H0qLPkxg8DDfpK9o span{fill:#333;color:#333;}#mermaid-svg-H0qLPkxg8DDfpK9o .node rect,#mermaid-svg-H0qLPkxg8DDfpK9o .node circle,#mermaid-svg-H0qLPkxg8DDfpK9o .node ellipse,#mermaid-svg-H0qLPkxg8DDfpK9o .node polygon,#mermaid-svg-H0qLPkxg8DDfpK9o .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-H0qLPkxg8DDfpK9o .rough-node .label text,#mermaid-svg-H0qLPkxg8DDfpK9o .node .label text,#mermaid-svg-H0qLPkxg8DDfpK9o .image-shape .label,#mermaid-svg-H0qLPkxg8DDfpK9o .icon-shape .label{text-anchor:middle;}#mermaid-svg-H0qLPkxg8DDfpK9o .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-H0qLPkxg8DDfpK9o .rough-node .label,#mermaid-svg-H0qLPkxg8DDfpK9o .node .label,#mermaid-svg-H0qLPkxg8DDfpK9o .image-shape .label,#mermaid-svg-H0qLPkxg8DDfpK9o .icon-shape .label{text-align:center;}#mermaid-svg-H0qLPkxg8DDfpK9o .node.clickable{cursor:pointer;}#mermaid-svg-H0qLPkxg8DDfpK9o .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-H0qLPkxg8DDfpK9o .arrowheadPath{fill:#333333;}#mermaid-svg-H0qLPkxg8DDfpK9o .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-H0qLPkxg8DDfpK9o .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-H0qLPkxg8DDfpK9o .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-H0qLPkxg8DDfpK9o .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-H0qLPkxg8DDfpK9o .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-H0qLPkxg8DDfpK9o .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-H0qLPkxg8DDfpK9o .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-H0qLPkxg8DDfpK9o .cluster text{fill:#333;}#mermaid-svg-H0qLPkxg8DDfpK9o .cluster span{color:#333;}#mermaid-svg-H0qLPkxg8DDfpK9o div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-H0qLPkxg8DDfpK9o .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-H0qLPkxg8DDfpK9o rect.text{fill:none;stroke-width:0;}#mermaid-svg-H0qLPkxg8DDfpK9o .icon-shape,#mermaid-svg-H0qLPkxg8DDfpK9o .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-H0qLPkxg8DDfpK9o .icon-shape p,#mermaid-svg-H0qLPkxg8DDfpK9o .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-H0qLPkxg8DDfpK9o .icon-shape .label rect,#mermaid-svg-H0qLPkxg8DDfpK9o .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-H0qLPkxg8DDfpK9o .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-H0qLPkxg8DDfpK9o .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-H0qLPkxg8DDfpK9o :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-H0qLPkxg8DDfpK9o .default>*{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-H0qLPkxg8DDfpK9o .default span{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-H0qLPkxg8DDfpK9o .default tspan{fill:#000000!important;}

    同向或正交

    同参数上反向

    向量A与向量B

    方向关系

    相加基本有效

    互相抵消两边掉分

    合并收益高

    改用逐层加权或路由

    图 7-2 任务向量方向的两种结局。合并前先看两个向量的余弦相似度,能预判干扰风险。

    失败类型判断信号处置
    任务间干扰 合并后两边都掉 降系数或逐层加权
    能力不对齐 混合指令不稳 任务路由代替合并
    线性假设失效 系数怎么调都不行 回到分别部署

    表 7-2 合并的三类失败与处置。合并省显存的收益要用双回归验证来换。

    工程上要做的验证很朴素:合并后必须重跑两个领域各自的回归集,确认两边都没有退化。不能假设向量相加等于能力相加,这个假设在很多任务对上不成立。

    判断两个任务向量是否冲突,有个便宜的预检方法。算两个向量的整体余弦相似度,接近零或为正,合并风险低。明显为负说明大方向相反,先做逐层检查或直接放弃合并。这个预检只需要权重算术,成本可忽略。

    失败的兜底方案也要提前想好。合并不成就退回分别部署加路由,用网关按请求类型分发到不同实例。代价是显存与运维翻倍,但能力保全。合并是优化项,不是必选项。

    逐层加权是常用的补救手段。不同层对任务的贡献不同,浅层偏通用特征,深层偏任务特征。给深层向量高系数、浅层低系数,常能在保留主干能力的同时拿到大部分领域能力。代价是要逐层扫系数,验证次数上升。

    还有正则化思路的合并,比如在合并时对结果做插值约束,限制合并后权重离基座的距离。这相当于把 EWC 的思想搬到合并环节,实现简单,对小规模合并足够用。

    7.3 与遗忘问题的关系

    合并对遗忘问题的价值是提供了一条不改主干的扩展路径。与其在一份权重上反复继续训练,不如为每个领域维护独立任务向量,按需组合。这样旧能力的主干始终不动,新领域以旁挂形式加入。

    #mermaid-svg-gEGnqs5ZssHKIbjj{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gEGnqs5ZssHKIbjj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gEGnqs5ZssHKIbjj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gEGnqs5ZssHKIbjj .error-icon{fill:#552222;}#mermaid-svg-gEGnqs5ZssHKIbjj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gEGnqs5ZssHKIbjj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gEGnqs5ZssHKIbjj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gEGnqs5ZssHKIbjj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gEGnqs5ZssHKIbjj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gEGnqs5ZssHKIbjj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gEGnqs5ZssHKIbjj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gEGnqs5ZssHKIbjj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gEGnqs5ZssHKIbjj .marker.cross{stroke:#333333;}#mermaid-svg-gEGnqs5ZssHKIbjj svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gEGnqs5ZssHKIbjj p{margin:0;}#mermaid-svg-gEGnqs5ZssHKIbjj .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-gEGnqs5ZssHKIbjj .cluster-label text{fill:#333;}#mermaid-svg-gEGnqs5ZssHKIbjj .cluster-label span{color:#333;}#mermaid-svg-gEGnqs5ZssHKIbjj .cluster-label span p{background-color:transparent;}#mermaid-svg-gEGnqs5ZssHKIbjj .label text,#mermaid-svg-gEGnqs5ZssHKIbjj span{fill:#333;color:#333;}#mermaid-svg-gEGnqs5ZssHKIbjj .node rect,#mermaid-svg-gEGnqs5ZssHKIbjj .node circle,#mermaid-svg-gEGnqs5ZssHKIbjj .node ellipse,#mermaid-svg-gEGnqs5ZssHKIbjj .node polygon,#mermaid-svg-gEGnqs5ZssHKIbjj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gEGnqs5ZssHKIbjj .rough-node .label text,#mermaid-svg-gEGnqs5ZssHKIbjj .node .label text,#mermaid-svg-gEGnqs5ZssHKIbjj .image-shape .label,#mermaid-svg-gEGnqs5ZssHKIbjj .icon-shape .label{text-anchor:middle;}#mermaid-svg-gEGnqs5ZssHKIbjj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-gEGnqs5ZssHKIbjj .rough-node .label,#mermaid-svg-gEGnqs5ZssHKIbjj .node .label,#mermaid-svg-gEGnqs5ZssHKIbjj .image-shape .label,#mermaid-svg-gEGnqs5ZssHKIbjj .icon-shape .label{text-align:center;}#mermaid-svg-gEGnqs5ZssHKIbjj .node.clickable{cursor:pointer;}#mermaid-svg-gEGnqs5ZssHKIbjj .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-gEGnqs5ZssHKIbjj .arrowheadPath{fill:#333333;}#mermaid-svg-gEGnqs5ZssHKIbjj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gEGnqs5ZssHKIbjj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gEGnqs5ZssHKIbjj .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gEGnqs5ZssHKIbjj .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-gEGnqs5ZssHKIbjj .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gEGnqs5ZssHKIbjj .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-gEGnqs5ZssHKIbjj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gEGnqs5ZssHKIbjj .cluster text{fill:#333;}#mermaid-svg-gEGnqs5ZssHKIbjj .cluster span{color:#333;}#mermaid-svg-gEGnqs5ZssHKIbjj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gEGnqs5ZssHKIbjj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-gEGnqs5ZssHKIbjj rect.text{fill:none;stroke-width:0;}#mermaid-svg-gEGnqs5ZssHKIbjj .icon-shape,#mermaid-svg-gEGnqs5ZssHKIbjj .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gEGnqs5ZssHKIbjj .icon-shape p,#mermaid-svg-gEGnqs5ZssHKIbjj .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-gEGnqs5ZssHKIbjj .icon-shape .label rect,#mermaid-svg-gEGnqs5ZssHKIbjj .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gEGnqs5ZssHKIbjj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-gEGnqs5ZssHKIbjj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-gEGnqs5ZssHKIbjj :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-gEGnqs5ZssHKIbjj .default>*{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-gEGnqs5ZssHKIbjj .default span{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-gEGnqs5ZssHKIbjj .default tspan{fill:#000000!important;}

    基座权重

    领域A向量

    领域B向量

    领域C向量

    按需组合

    单模型多能力

    主干永不重训

    图 7-3 向量库式的扩展方式。主干冻结,新能力以增量形式入库,这是持续学习的一种落地形态。

    这与 RAG 的分工值得点一句。合并解决"能力内化进参数",RAG 解决"知识外挂可更新"。领域术语与推理模式适合内化,高频变动的事实适合外挂,两者不冲突。

    这条路径也有代价。向量数量增长后,组合空间爆炸,哪些向量能安全共存要靠实验验证。工程上先限制同时合并的任务数在两到三个,超出就用路由分发到不同实例,把组合验证的成本控制在可接受范围。

    对持续学习而言,这条路把问题从"如何不遗忘"改写为"如何管理增量库"。增量可以随时增删,主干不动,遗忘风险被限制在合并环节。管理成本从训练时转移到组合验证时,对小团队反而更可控。

    前提条件要满足:基座权重必须长期保留且不变。如果基座本身定期更新,所有任务向量都要基于新基座重算,等于重训。所以走这条路要先冻结基座版本策略,再做领域扩展。

    从成本视角看这条路的开销构成。训练侧每个领域一次微调,与迭代式相同。存储侧多份向量,每份比完整权重小一个量级。推理侧一份合并权重或多实例路由。总体上把重训成本换成了存储加验证成本,规模大了更划算。

    风险集中在基座版本管理上。基座升级后旧向量全部失效,要么重算要么放弃。所以走这条路前要评估基座的更新频率,更新频繁的团队用这条路会反复付费,不如老老实实做重放式持续训练。

    8. 回归监控与选型建议

    最后一章收束到工程落地。原则一句话:领域适配优先 LoRA 加重放,不做全参微调,并保留通用回归测试集持续监控。

    8.1 选型决策路径

    #mermaid-svg-pV3wLhGa8pYM88HV{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-pV3wLhGa8pYM88HV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-pV3wLhGa8pYM88HV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-pV3wLhGa8pYM88HV .error-icon{fill:#552222;}#mermaid-svg-pV3wLhGa8pYM88HV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-pV3wLhGa8pYM88HV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-pV3wLhGa8pYM88HV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-pV3wLhGa8pYM88HV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-pV3wLhGa8pYM88HV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-pV3wLhGa8pYM88HV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-pV3wLhGa8pYM88HV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-pV3wLhGa8pYM88HV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-pV3wLhGa8pYM88HV .marker.cross{stroke:#333333;}#mermaid-svg-pV3wLhGa8pYM88HV svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-pV3wLhGa8pYM88HV p{margin:0;}#mermaid-svg-pV3wLhGa8pYM88HV .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-pV3wLhGa8pYM88HV .cluster-label text{fill:#333;}#mermaid-svg-pV3wLhGa8pYM88HV .cluster-label span{color:#333;}#mermaid-svg-pV3wLhGa8pYM88HV .cluster-label span p{background-color:transparent;}#mermaid-svg-pV3wLhGa8pYM88HV .label text,#mermaid-svg-pV3wLhGa8pYM88HV span{fill:#333;color:#333;}#mermaid-svg-pV3wLhGa8pYM88HV .node rect,#mermaid-svg-pV3wLhGa8pYM88HV .node circle,#mermaid-svg-pV3wLhGa8pYM88HV .node ellipse,#mermaid-svg-pV3wLhGa8pYM88HV .node polygon,#mermaid-svg-pV3wLhGa8pYM88HV .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-pV3wLhGa8pYM88HV .rough-node .label text,#mermaid-svg-pV3wLhGa8pYM88HV .node .label text,#mermaid-svg-pV3wLhGa8pYM88HV .image-shape .label,#mermaid-svg-pV3wLhGa8pYM88HV .icon-shape .label{text-anchor:middle;}#mermaid-svg-pV3wLhGa8pYM88HV .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-pV3wLhGa8pYM88HV .rough-node .label,#mermaid-svg-pV3wLhGa8pYM88HV .node .label,#mermaid-svg-pV3wLhGa8pYM88HV .image-shape .label,#mermaid-svg-pV3wLhGa8pYM88HV .icon-shape .label{text-align:center;}#mermaid-svg-pV3wLhGa8pYM88HV .node.clickable{cursor:pointer;}#mermaid-svg-pV3wLhGa8pYM88HV .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-pV3wLhGa8pYM88HV .arrowheadPath{fill:#333333;}#mermaid-svg-pV3wLhGa8pYM88HV .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-pV3wLhGa8pYM88HV .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-pV3wLhGa8pYM88HV .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-pV3wLhGa8pYM88HV .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-pV3wLhGa8pYM88HV .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-pV3wLhGa8pYM88HV .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-pV3wLhGa8pYM88HV .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-pV3wLhGa8pYM88HV .cluster text{fill:#333;}#mermaid-svg-pV3wLhGa8pYM88HV .cluster span{color:#333;}#mermaid-svg-pV3wLhGa8pYM88HV div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-pV3wLhGa8pYM88HV .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-pV3wLhGa8pYM88HV rect.text{fill:none;stroke-width:0;}#mermaid-svg-pV3wLhGa8pYM88HV .icon-shape,#mermaid-svg-pV3wLhGa8pYM88HV .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-pV3wLhGa8pYM88HV .icon-shape p,#mermaid-svg-pV3wLhGa8pYM88HV .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-pV3wLhGa8pYM88HV .icon-shape .label rect,#mermaid-svg-pV3wLhGa8pYM88HV .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-pV3wLhGa8pYM88HV .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-pV3wLhGa8pYM88HV .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-pV3wLhGa8pYM88HV :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-pV3wLhGa8pYM88HV .default>*{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-pV3wLhGa8pYM88HV .default span{fill:#faf9f5!important;stroke:#ffffff!important;color:#000000!important;stroke-width:0px!important;}#mermaid-svg-pV3wLhGa8pYM88HV .default tspan{fill:#000000!important;}

    是

    否

    是

    否

    领域适配需求

    需要内化大量新知识吗

    LoRA较高秩加重放

    LoRA低秩或仅提示工程

    回归分数掉超过阈值吗

    提高重放比例或降秩

    定版并冻结回归基线

    重跑回归直到通过

    图 8-1 领域适配选型决策路径。回归分数是唯一的放行闸门,领域分数只用于确认学习是否发生。

    场景推荐配置理由
    少量领域术语 LoRA 低秩,不重放 干扰面小
    大量领域知识 LoRA 中秩加重放 10 到 20 个百分点 防旁路偏置
    必须全参 重放至少 20 到 30 个百分点加早停 唯一防线是数据侧
    多领域并存 各自 LoRA 或任务向量合并 主干不动

    表 8-1 四类场景的默认配置。重放比例为常见起点区间,需按回归分数调整。

    决策路径里有三个容易走岔的口子。第一个是把"需要内化大量新知识"误判为必须全参。实际上秩 32 到 64 的 LoRA 加足够领域语料,多数领域能压到可接受差距,先试便宜的。第二个是把回归阈值设得过松,导致拦截形同虚设。第三个是阈值一刀切,指令遵循这类用户直接感知的维度应设更紧的阈值。

    阈值设定可以分级。核心维度如指令遵循设在 2 到 3 个百分点,一般维度如通用知识设在 5 个百分点,冷门维度可以放宽到 8 个百分点。分级后既有拦截力又不至于频繁误报,团队才愿意持续执行。

    8.2 监控清单

    落地要一份可执行的清单。回归集构成:通用知识、通用推理、指令遵循、格式稳定四类,各固定题量,与领域语料严格隔离来源。执行节奏:适配中每若干 checkpoint 跑一次,定版前必跑,上线后随版本跑。判定标准:任一维度下降超过预设阈值即阻断发布,阈值常设在 2 到 5 个百分点区间,按业务容忍度定。

    # 来源:自实现 / regression_gate.py
    import numpy as np

    def gate(domain_score, regression_scores, thresholds):
    # 双闸门:领域要涨,回归每个维度都要守住
    reasons = []
    if domain_score["after"] <= domain_score["before"]:
    reasons.append("领域分数未提升")
    for name, s in regression_scores.items():
    drop = s["before"] – s["after"]
    if drop > thresholds.get(name, 0.05):
    reasons.append(f"{name}遗忘{drop:.2f}超阈值")
    return ("通过" if not reasons else "阻断", reasons)

    if __name__ == "__main__":
    domain = {"before": 0.52, "after": 0.71}
    reg = {"通用知识": {"before": 0.80, "after": 0.78},
    "通用推理": {"before": 0.66, "after": 0.58},
    "指令遵循": {"before": 0.74, "after": 0.73}}
    th = {"通用知识": 0.05, "通用推理": 0.05, "指令遵循": 0.05}
    verdict, reasons = gate(domain, reg, th)
    print(f"发布判定 {verdict}")
    for r in reasons:
    print(f"原因 {r}")

    这段代码的闸门逻辑是双条件:领域分数必须上升,同时回归每个维度下降都不得超阈值。例子中通用推理掉 0.08 超过 0.05,因此被阻断,说明分维度判定确实能拦住总分掩盖的退化。

    8.3 反模式清单

    三个常见反模式要点名。第一,全参微调加纯领域语料,这是遗忘最重的组合,除非重放配足,否则不要选。第二,只看领域基准就定版,通用与指令维度的退化会在上线后暴露,返工成本远高于多跑一次回归。第三,拿领域评测题当重放数据,这既是泄漏也是自欺,回归分数会虚高。

    反模式直接后果修正
    全参加纯领域语料 遗忘最重 加重放或改 LoRA
    只看领域基准定版 上线后返工 双基准放行
    领域题当重放数据 回归虚高 数据源隔离
    一次微调塞多领域 互相干扰 分领域迭代

    表 8-2 四类反模式与修正。第三行的欺骗性最强,因为它让监控本身失效。

    还有一个隐蔽的坑:连续多轮适配的累积遗忘。每轮掉 3 个点看似可接受,三轮累积近 10 个点就不可接受。对策是每轮适配后更新冻结基线,并把累积降幅纳入发布评审。

    多领域同时要加的情况也要留意。一次微调塞进多个领域,领域间会互相竞争参数,结果常是每个领域都只学到一半。更稳的路径是分领域迭代,每轮只针对一个领域,其余领域靠重放守住,代价是训练轮数增加。

    最后一句话收束工程原则:先建回归集,再谈微调。监控先行意味着每次尝试都有否决依据,顺序反过来则等于闭眼开车,出了问题无从归因。

    最后补一个组织层面的反模式。没有明确的责任人时,回归监控会逐渐流于形式,跑过了但没人看结果,阻断规则形同虚设。对策是把回归结果写进发布流程,发布单必须附回归报告,责任人签字后才允许上线。

    另一个组织坑是阈值争论无限拖延。业务方希望松,技术方希望紧,僵持下先按默认阈值执行,事后用数据回顾调整。有阈值且被执行,好过完美阈值永远在讨论中。

    清单之外还有一个静默失败。回归集长期不更新,题目被领域语料间接覆盖后逐渐失敏,分数常年稳定,实际防护力在下降。对策是定期抽查回归集题目与近期语料的相似度,过高的换掉,保持题集的独立性。

    最后是度量本身的反模式。用单一综合分替代分维度分,等于把四个独立信号压成一个,任何一个维度的退化都可能被其他维度的上涨抵消。分维度报告是最低成本的防自欺手段,发布单上四个分数分开列。

    工具层面的反模式也提一句。用自动评测工具时不锁定模型版本与提示词模板,工具升级后评分逻辑变化,历史分数不可比。工具链本身要版本化,升级工具后重跑一次全量基线,重建可比性。

    最后是知识管理的反模式。回归集、重放集、领域评测集混在同一目录,边界靠人记。时间一长必然串数据。三套数据分库存储加命名规范,是最便宜的隔离手段,也是防泄漏的第一道墙。

    9. 总结

    学了新的忘了旧的,根源是参数共享加 SGD 缺少旧约束。新语料的最优解覆盖旧任务的解,通用知识、推理与指令遵循一起被侵蚀。度量口径是旧任务性能下降幅度,学新与保旧构成双曲线,任何方法只能外移曲线,不能取消取舍。

    工具箱按作用位置分四类。数据重放把旧数据放回损失函数,是最稳的底座。EWC 用 Fisher 近似给重要参数上锁,适合拿不到旧数据的场景。LoRA 冻结基座只动小矩阵,从结构上排除覆盖,配重放是默认选型。模型合并用任务向量加减扩展能力,不动主干。工程上的落点是一句话:优先 LoRA 加重放,保留通用回归测试集,分维度设阈值阻断发布。

    外部引用

    • EWC 原始论文 Overcoming catastrophic forgetting in neural networks:https://arxiv.org/abs/1612.00796
    • 任务向量论文 Editing Models with Task Arithmetic:https://arxiv.org/abs/2212.04089
    • LoRA 原始论文 LoRA: Low-Rank Adaptation of Large Language Models:https://arxiv.org/abs/2106.09685
    • 持续学习三种场景与度量 Three scenarios for continual learning:https://arxiv.org/abs/1904.07734
    • 梯度情景记忆方法 Gradient Episodic Memory for Continual Learning:https://arxiv.org/abs/1706.08840
    • Wikipedia 条目 Catastrophic forgetting:https://en.wikipedia.org/wiki/Catastrophic_interference
    • 模型合并方法综述 Model Merging in LLMs, MLLMs and Beyond:https://arxiv.org/abs/2408.07666
    赞(0)
    未经允许不得转载:171主机测评 » 大模型知识--学了新的忘了旧的
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址