训练 loss 掉到 0.007,我以为成了——其实模型在背答案
训练 loss 掉到 0.007,我以为成了——其实模型在背答案
写在前面:这篇文章适合谁
如果你也在做这些事,这篇可能有用:
- 用家里显卡 + 远程穿透,自己微调小模型
- 数据只有几十、一两百条,想「先跑通再说」
- 盯着训练曲线,看到 loss 一路往下掉就很开心
- 真正想要的是:同类意思能换着说法写,而不是把训练稿背熟
这不是论文复现,是我这两天真实踩过的坑。
数字都来自家里那台 RTX 5070 Ti 上的两次训练记录。
一句话先说在前面:
训练 loss 越低,不等于模型越聪明。
有时候只是:它把你的答案本背完了。
创作不易,点个关注不迷路。
0. 我到底在训什么
项目叫「喵格」:先用规则算出猫是十六型里的哪一型,再让模型写一段第一人称脾气报告。
注意分工:
| 谁干 | 干什么 |
|---|---|
| 规则代码 | 决定「你是客厅霸王 / 沙发软糖 / ……」 |
| 模型 | 学会「这一型该怎么说话」 |
我想要的效果不是:
一问「客厅霸王」,永远吐出训练里那同一段字。
而是:
同一型、换个场景,说法常变,但脾气核还在——黏、皮、犟,别糊成通用温柔猫。
换句话说:要随机性、要类似描述,不要背诵。
工具链很朴素:
- 穿透:FRP(人在外面,卡在家里)
- 训练:LLaMA-Factory(
llamafactory-cli train) - 基座:Qwen3-8B
- 方法:QLoRA(4-bit + LoRA)
- 显卡:RTX 5070 Ti 16GB
(有人会把名字记成 vLLM-Factory——我们实际用的就是 LLaMA-Factory。)
1. 先用一个学生考试的比喻,建立直觉
把微调想成补习班:
- 训练数据 = 老师发的练习册(有标准答案)
- loss(损失) = 「你这道题离标准答案有多远」
- epoch = 「这本练习册你整本刷了几轮」
- 过拟合 = 练习册倒背如流,换一本新卷子就不会了
考试时你真正想要的是什么?
不是把练习册第 17 页第 3 题的句子一字不差默写出来,
而是:换道相似题,还能用自己的话写对思路。
模型也一样。
- loss 高:还不太会照着写
- loss 慢慢降:开始学会这种写法了
- loss 低到离谱(比如 0.007):很危险——它可能已经在背原句了
所以后面你会看到一个反直觉的结论:
第二次训练「成绩单」好看得多,
恰恰是我最该警惕过拟合的时候。
2. 两天,两次训练:一张对照表
都是远程开训:本机整理好 Alpaca 格式 JSON,传到家里 GPU,再跑 LLaMA-Factory。
| 昨天(冒烟) | 今天(扩数据) | |
|---|---|---|
| 日期 | 2026-08-11 约 17:39–17:41 | 2026-08-12 约 15:54–16:03 |
| 数据条数 | 32(十六型 × 各 2 条) | 160(场景更丰富) |
| 训练轮数 epoch | 6 | 5 |
| 总步数 | 24 | 100 |
| 纯训练耗时 | ≈ 2 分钟 | ≈ 8 分钟 |
| 全程平均 train_loss | 3.968 | 0.900 |
| 最后一步 step loss | 3.71 | 0.007 |
| 退出码 | 0(成功) | 0(成功) |
表面上:今天完胜。
平均 loss 从将近 4 掉到不到 1,末步更是掉到 0.007——曲线党会鼓掌。
但我想要的是「会说类似的话」,不是「把 160 条默写满分」。
所以要把这两次的曲线拆开看。
3. 第一次:32 条,先把水管接通
3.1 目的很土
不管效果好不好,先证明整条链路活着:
- 外面能 SSH 进家里机
- 数据进得了 LLaMA-Factory
- Qwen3-8B + QLoRA 能在 16G 上跑完
- 适配器文件能落盘
32 条,十六型每种两篇,刚好够「冒个烟」。
3.2 关键旋钮(大白话版)
| 旋钮 | 我设的值 | 人话 |
|---|---|---|
| 量化 4-bit | 开 | 显存不够就压缩着训 |
| LoRA rank/alpha | 16 / 32 | 只训一小撮「补丁参数」 |
| 学习率 | 1e-4 | 常见起步 |
| 批大小×累积 | 1×8 | 等效一次看 8 条 |
| 截断长度 | 2048 | 报告偏长,给够长度 |
| 模板 | qwen3_nothink |
少让它冒思考标签 |
| 验证集 | 0 | 当时图省事,埋了雷 |
3.3 Loss 怎么走的
节选真实 step Loss:
step 1 ≈ 4.82
step 7 ≈ 4.12
step 13 ≈ 3.72
step 19 ≈ 3.54
step 24 ≈ 3.71 ← 结束
平均 train_loss ≈ 3.97
怎么读:
- 从 4.8 降到 3.5 左右:说明它在学,但离「背熟」还远
- 末尾甚至略有回弹:小数据上很常见,别慌
- 平均还在 4 附近:更像「刚入门」,不像「倒背如流」
这一次的问题不是过拟合,而是:
数据太少,声口还立不稳——该扩数据了。
于是有了第二天。
4. 第二次:160 条,loss 漂亮得吓人
4.1 我以为会更好
想法很正常:
- 昨天 32 条跑通了
- 今天扩到 160 条,场景更多
- epoch 从 6 收到 5(还以为自己已经克制了)
- 其他旋钮几乎照抄
配置几乎只改了三处:数据集名、输出目录、epoch=5。
4.2 然后曲线变成这样
真实 step loss 节选:
step 1 ≈ 4.28 还不会
step 26 ≈ 1.21 开始像样
step 51 ≈ 0.13 已经很低了
step 76 ≈ 0.011 低得过分
step 100 ≈ 0.007 ← 结束,几乎贴地
平均 train_loss ≈ 0.90
如果只看数字,你会说:今天训得「好太多了」。
但我要的是随机、同义的改写。
当最后一步 loss 到 0.007 时,更像发生了这件事:
练习册上的句子,它已经能几乎一字不差地复述了。
这就叫过拟合风险拉满。
5. 过拟合到底是什么意思(别被术语吓到)
5.1 一句话
过拟合 = 把训练集背熟了,换题就不会了。
不是程序报错,也不是训练失败。
两次都是 EXIT 0,文件都正常保存。
它「成功」地完成了你给的目标函数——把训练答案的误差压到极低。
问题在于:你真正想要的目标,和 loss 这个数字,并不完全是一回事。
5.2 对照你的产品目标
| 你想要的 | 过拟合后常见表现 |
|---|---|
| 同一猫格,换场景,说法常变 | 多次生成高度像训练原文 |
| 脾气核稳定(黏/皮/犟……) | 新场景一来,糊成「万能温柔猫」或串型 |
| 读起来像活的 | 读起来像默写 |
所以:
- loss 从 4 → 1:通常值得高兴(在学)
- loss 从 0.1 → 0.007:要开始怀疑(在背)
5.3 为什么小数据特别容易踩
你可以粗算一下「它把练习册刷了几遍」:
- 160 条 × 5 个 epoch = 相当于整本刷了 5 遍
- 有效 batch 又不大
- 报告文风相对固定、句式容易撞车
对大模型来说,背 160 段短文并不难。
难的是:没见过的场景,还能用「同一型的口气」即兴说。
我当时还关了验证集(val_size: 0),等于:
考试时只看练习册得分,不看模拟卷。
练习册 100 分,你就以为高考稳了。
这是过程里第二个埋雷的地方。
6. 两张成绩单并排,过拟合就现形了
把关键数字放一起:
| 信号 | 32 条那次 | 160 条那次 | 怎么理解 |
|---|---|---|---|
| 末步 loss | 3.71 | 0.007 | 右边像背熟 |
| 平均 train_loss | 3.97 | 0.90 | 右边「卷面分」更好看 |
| 训练是否成功 | 是 | 是 | 成功 ≠ 泛化好 |
| 更接近我想要的「会改写」 | 可能还欠拟合 | 高风险过拟合 | 两边都不是终点 |
再用人话翻译一遍:
- 欠拟合:还没学会,说话飘、不像那一型
- 合适区:会说、会换说法,核还在
- 过拟合:太像标准答案打印机
我要的随机性,落在中间那一区。
而今天这条曲线,已经滑向右边了。
7. 那怎么办?按「我真正想要什么」来治
目标再次对齐:
不是背熟,是很多随机性、类似的描述。
可以分三层,从便宜到治本:
7.1 推理时先把「骰子」打开(立刻能试)
就算权重有点背,也别用「温度 = 0」那种死板解码。
| 参数 | 可以先试 | 作用 |
|---|---|---|
| temperature | 0.8~1.1 | 越高越活,太高易串型 |
| top_p | 0.9~0.95 | 从更广的词里抽样 |
| 同题连抽 3~5 次 | — | 看会不会换说法 |
记住:
温度负责「这一次措辞抖不抖」;
训练负责「它心里有没有留改写空间」。
背得太死,温度再高也只是在原文附近抖渣。
7.2 别迷信最终档,去试中间 checkpoint
这次 160 条按 epoch 存了:
checkpoint-20 / 40 / 60 / 80 / 100
末步 0.007 对应的是最晚那档。
往往 40 或 60 更接近「会说但还没背穿」。
这很像考试:
刷到第 3 轮时开始懂方法;
刷到第 5 轮时开始背页码。
先测中间卷,再决定要不要整场重考。
7.3 下次训练直接「少背几遍」
对我这种一百多条的规模,更稳妥的起点往往是:
- epoch:2~3(别一上来 5)
- 留一点验证集:
val_size: 0.1,盯 eval_loss - dropout:0.05 → 0.1
- 学习率:必要时 1e-4 → 5e-5
训练中的停手信号很简单:
训练 loss 还在降,验证 loss 开始升——就可以收工了。
7.4 数据才是随机性的粮仓
模型的「类似说法」从哪来?
主要从你喂进去的 同核多说法:
- 同一猫格
- 场景不同
- 句式不同
- 细节不同
- 脾气核一致
如果你 10 条都像同一段换皮,它再怎么采样也跳不出那套骨架。
想要随机,先让练习册本身就有很多「同义改写」。
8. 我后来才想通的三句口诀
口诀 1:成功跑完 ≠ 训对了目标
EXIT 0 只说明程序没崩。
它优化的是「贴训练答案」,不是「贴你心里的产品感觉」。
口诀 2:loss 是练习册分数,不是高考分数
没有验证集、没有对话抽测,你就只有练习册分。
练习册可以 99 分,换题照样不及格。
口诀 3:我要的是会说类似的话,不是标准答案打印机
产品目标一旦说清,很多「看起来很美」的曲线就会变得可疑。
0.007 很美,但可能美错了地方。
9. 如果你也想复盘自己的训练,看这几个文件就够
不必先上复杂平台。家里机上这几个文件,已经能讲清故事:
| 文件 | 能告诉你什么 |
|---|---|
train_results.json |
平均 train loss、跑了多久 |
trainer_state.json |
每一步 loss 怎么走的 |
training_loss.png |
一眼看曲线 |
checkpoint-* |
不同「刷题轮次」的快照 |
| 启动用的 YAML | 你到底设了几 epoch、有没有验证集 |
我这两次的产物大致在:
saves/miaoge-qwen3-8b-qlora/ # 32 条
saves/miaoge-qwen3-8b-qlora-160/ # 160 条
远程怎么连、家里卡怎么挂,是另一篇的事;
这篇只想钉死一件事:
曲线很好看的那天,更要问一句——
它是学会了,还是背会了?
10. 总结:下次我怎么改
按优先级,我会这样做:
- 先验收:同一题抽 5 次,看会不会换说法;再丢训练里没见过的场景
- 先换档:拿
checkpoint-40/60对比最终档 - 再重训:160 条 × 2~3 epoch,加上验证集
- 持续扩数据:同型多场景、多句式,而不是同一段反复刷
如果最后你只记住一句,记住这句就行:
我要的不是 loss 贴地,是换个场景还能用很多类似的话,把同一只猫说活。
更多推荐

所有评论(0)