· liyu · ai · 8 min read

我训练出了一个「人工智障」:中文 LLaMA2 (204M) SFT 微调翻车实录与深度复盘

在上一篇完成 Kaggle GPU 上的 LoRA SFT 微调后,满心欢喜地启动推理测试,结果却令人哭笑不得:基座模型还能头头是道地接龙,微调后却退化成了无限复读机与胡言乱语的"人工智障"。本文结合欠拟合、重复惩罚缺失与 LoRA 容量等硬核成因进行深度诊断,给出针对性重构方案。

在上一篇完成 Kaggle GPU 上的 LoRA SFT 微调后,满心欢喜地启动推理测试,结果却令人哭笑不得:基座模型还能头头是道地接龙,微调后却退化成了无限复读机与胡言乱语的"人工智障"。本文结合欠拟合、重复惩罚缺失与 LoRA 容量等硬核成因进行深度诊断,给出针对性重构方案。

一、前言:理想很丰满,现实很「智障」

在上一篇文章《从预训练到指令微调:中文 LLaMA2 (204M) 原生 LoRA SFT 实战与 Kaggle GPU 避坑指南》中,我们完整打通了从预训练基座到 Kaggle Tesla T4 云端 LoRA 微调的全套流水线。

当时手写了原生 LoRA 模块、配置了 Loss Masking,并在 Kaggle 双卡上顺利启动了训练。本以为仅用 0.24% 的参数量就能调出一个能够正常对话的小助手,然而当我们敲下回车运行 chat.py 进行交互测试时,模型却直接退化成了一个让人哭笑不得的「人工智障」。


二、基座模型的续写能力

在进入微调之前,我们的中文 LLaMA2 基座模型(204.2M 参数,vocab=65000, dim=768, layers=12)经过了数亿 Token 的中文无监督预训练。

虽然尚未进行指令对齐、无法直接理解问答指令,但在**因果语言建模(Next-Token Prediction)**的文本接龙上,展现出了扎实的字词关联与常识理解能力:

预训练基座模型文本续写能力实测

可以看到,基座模型面对「人工智能是」或「秋天是一个丰收的季节」等提示时,能够精准联想出大数据、区块链或采摘、水果等相关概念,句式通顺、逻辑在线,是一个合格的「文本接龙机器」。


三、微调后的模型问答表现(变成「人工智障」)

按照预期,经过指令微调后,挂载 LoRA 的模型应该学会识别人类意图并给出清晰回答。然而实测问答却直接翻车:

LoRA 微调后模型问答实测翻车截图

实测中出现了极为典型的退化现象:

  1. 魔性复读:在概念问答中疯狂复读「自然语言」达 30 余次,并凭空捏造「李国色」、「华炎」等神秘人名;
  2. 死循环复读:在诗歌生成中连续复读 37 遍「丰收的喜悦」直至触发最大 Token 截断;
  3. 跨语言崩溃:英文翻译彻底退化为不可读的字符乱码拼接。

四、根本原因诊断:为什么微调把模型「训傻了」?

为什么原本表现尚可的预训练基座模型,在微调后反而退化成了极端复读的「人工智障」?结合训练过程与机制原理,深度归因诊断如下:

                        204M 模型微调失败根因诊断
┌─────────────────────────────────────────────────────────────────────────────┐
│ 1. 训练严重欠拟合 (11% 进度) ──> 仅学到局部词汇关联,未学会句子结构与 EOS 停机 │
│ 2. 推理解码缺惩罚 (No Penalty) ──> 缺少 Repetition Penalty 导致自注意力死循环  │
│ 3. 模型容量与任务不匹配     ──> 204M 基座 + 0.24% 浅层 LoRA 难以承载复杂任务 │
└─────────────────────────────────────────────────────────────────────────────┘

1. 训练严重欠拟合(仅完成了规划的 ~11%)

  • 训练步数严重不足:Belle 0.5M 数据集在双卡下跑满 2 轮总计约 31,250 步,而本次训练在 3,550 步 即被中断,实际进度仅完成约 11%,Loss 从基座的 4.30 下降到 3.53 ~ 3.63(困惑度 PPL 约 35);
  • 停机信号缺失:此时模型刚刚学会关键词关联,尚未学会组织连贯长句,更未学会何时输出 </s>(EOS 结束符)来终止生成,因此只能顺着自注意力不断无限循环生成相关字词,直到触发 max_tokens 强行截断。

2. 推理解码时缺少「重复惩罚(Repetition Penalty)」

204M 级别的小模型在无重复惩罚时,极易因注意力权重自激发而陷入复读死循环(例如生成了“自然语言”后,下一步预测又给“自然语言”赋予极高概率)。

3. 204M 小模型本身的容量与任务难度

  • 基座容量有限:当前模型参数量为 204M,基座预训练 Loss 约为 4.3;
  • LoRA 拟合容量受限:微调时 rank=8 且仅微调了注意力模块(wq, wk, wv, wo),可训练参数仅占 0.24%(49 万参数);
  • 任务难度过高:“几何计算”与“中英文精准翻译”对小基座模型属于高难度复杂任务,在浅层微调与欠拟合下极易出现幻觉与乱码。

五、针对性改进方案

为了彻底解决翻车问题,我们制定了三项具体的改进方案:

方案 1:优化推理脚本(给 chat.py 增加重复惩罚,立刻缓解复读)

在文本生成中加入 repetition_penalty = 1.2,抑制复读词生成:

def apply_repetition_penalty(logits, generated_tokens, penalty=1.2):
    """对已生成的 token logits 进行动态惩罚抑制"""
    for token_id in set(generated_tokens):
        if logits[token_id] > 0:
            logits[token_id] /= penalty
        else:
            logits[token_id] *= penalty
    return logits

方案 2:扩大 LoRA 拟合容量(提升 Rank 并覆盖 FFN 全层)

将 LoRA 秩提升至 16,并把 FFN 前馈网络层(w1, w2, w3)也纳入微调,大幅提升小模型的表达能力:

python scripts/finetune.py \
    --model-path models/checkpoints/best/model.safetensors \
    --data-path data/belle_sft_0.5m.json \
    --lora-rank 16 \
    --lora-alpha 32 \
    --target-modules wq wk wv wo w1 w2 w3 \
    --learning-rate 1e-4 \
    --batch-size 32

方案 3:充分训练让 Loss 降到 2.5 ~ 2.8 左右

让训练跑满完整 Epoch(双卡 T4 x 2 训练 1 轮大约耗时 1.5~2 小时),当 Loss 收敛至 2.8 以下时,模型会真正掌握完整的句子结构与生成 </s> 自动终止的能力。


六、总结

从「能够接龙的基座」到「听懂人话的助手」,大模型微调绝非一蹴而就。下降的 Loss 并不等于成功的对齐。 在 11% 进度就退出的微调,容易陷入关键词自激死循环。

下一阶段我们将带上 FFN 全层 LoRA 注入、跑满 3 万步训练、以及配备重复惩罚的解码器,进一步提升模型的对话生成表现!

Share:
Back to Blog

Related Posts

View All Posts »
从预训练到指令微调:中文 LLaMA2 (204M) 原生 LoRA SFT 实战与 Kaggle GPU 避坑指南

从预训练到指令微调:中文 LLaMA2 (204M) 原生 LoRA SFT 实战与 Kaggle GPU 避坑指南

完整记录中文 LLaMA2(204M 参数)从预训练向 SFT 指令微调演进的全流程。深入剖析 Loss Masking 数据管道、原生手写 LoRA/QLoRA 模块实现,并深度复盘 Kaggle 云端 GPU 迁移中的只读文件系统、Git LFS 假死、GPU 架构兼容与跨设备张量对齐四大经典工程踩坑。文末联动 AstrBot Agent 微信机器人实现 GPU 训练定时看护。