现场是这样的。检查训练数据时发现大量标签是 -100,担心数据出错,但 loss 又能正常下降,不确定这样是否正确。
中间走过弯路,把「padding 位置被统一设成 -100」当成主因,改完现象没变。
排查方向其实有限,先把可能性排一排。-100 是交叉熵里忽略该位置的约定值;指令微调只对回答部分计算损失;整条样本都是 -100,实际没有可学的目标。
上来先统计被忽略位置的比例
python -c "import torch;print((labels==-100).float().mean().item())"
再往下确认回答片段确实没有被掩掉
print(tokenizer.decode(input_ids[labels[0]!=-100]))
随后检查是否存在整条全掩码的样本
python -c "print((labels!=-100).sum(dim=1).min())"
剩下的就是按模板重算一次标签做对照
python build_labels.py --template chatml --check
别只看报错消失,验证要多做一步。被忽略比例在合理范围,回答片段完整保留,没有全掩码样本,loss 只反映回答部分的拟合程度。
补一句。如果只对回答算损失,loss 的绝对值会比整句计算高,不能直接和别人的曲线比较,看趋势比看数值更有意义。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。