现场是这样的。为了省显存冻结了前二十层,结果训练 loss 几乎不降,输出和原模型相似度极高,看起来像完全没训练。

中间走过弯路,把「Embedding 与输出层同时被冻结,梯度传不回去」当成主因,改完现象没变。

真正麻烦的地方在于,几个原因的现象几乎一样。冻结范围过大,可训练参数太少;冻结后没有重新设置优化器参数组;学习率对剩余层来说仍然偏小。

动手时先统计可训练参数占比

python -c "import torch;print(sum(p.numel() for p in model.parameters() if p.requires_grad))"

只冻结前半部分并保留输出层可训练

for n,p in model.named_parameters(): p.requires_grad = not n.startswith('model.layers.0')

随后重新构建优化器,只传可训练参数

opt = torch.optim.AdamW(filter(lambda p: p.requires_grad, model.parameters()), lr=1e-5)

末了用单条样本验证能否过拟合

python train.py --overfit_one true --steps 50

别只看报错消失,验证要多做一步。可训练参数占比回到合理区间,loss 能明显下降,生成风格出现可观察的变化。

提醒一点。冻结参数后如果优化器里还带着全部参数,权重衰减仍然生效,某些实现会因此悄悄改变被冻结的权重。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。

作者 9823189