先把当时的情况摆出来。训练完把 adapter 合并回底模,推理效果比直接加载 adapter 差很多,回答变得生硬,同一批测试用例得分掉了十几个点。

把日志和配置对完,能解释这个现象的基本就这几处。合并时用了 fp16 计算,权重相加产生精度损失。也可能是adapter 与底模不是同一份权重训练出来的。

还有一种情况,合并前没有切换到评估模式,dropout 仍在生效。另外,缩放系数被重复应用,等效权重被放大。

先在 fp32 下合并再转回半精度

base = AutoModelForCausalLM.from_pretrained(path, torch_dtype=torch.float32); merged = PeftModel.from_pretrained(base, adapter).merge_and_unload()

接着合并后保存并重新加载验证

merged.save_pretrained('./merged'); tokenizer.save_pretrained('./merged')

然后对比合并前后同一批用例的输出

python eval.py --model ./merged --cases 50

剩下的就是确认底模版本与训练时一致

python -c "print(open('./adapter/adapter_config.json').read()[:200])"

别只看报错消失,验证要多做一步。合并后的模型在同一批用例上的得分与加载 adapter 时相差不超过一个点,输出风格保持一致。

提醒一点。adapter 里记录了训练时的底模路径,拿错底模合并不会报错,只会得到一个看似正常但能力下降的模型,合并前务必核对。报错文案容易误导,真正的原因往往在相邻那一层的日志里。

作者 9823189