18. 第 5 轮实测:预测头真的在学 + loss「规律起伏」的答案

★★★ 2.4k 字 · 源文件 PROJECT.md 第 3389 行起 · ruler arch optim read

#18.1 自监督预测:1.0 → 0.476(第一个"自主学习"的硬证据)

exp31_p_small(带 --pred-coef 1.0,其余与 g_small 相同):

步预测误差 pred_rel正确率无回显
11.0000(= 随机预测的理论值)0.0%0.0%
1000.24990.0%0.0%
2000.23531.0%2.1%
3000.30125.2%2.1%
4000.427510.4%14.6%
5000.403017.7%22.9%
6000.465638.5%22.9%
7000.475937.5%33.3%

★★ 预测误差从 1.0 降到 0.476 —— 也就是解释了下一帧编码 52% 的方差, 而且这完全不需要任何标注:下一帧自己就是标签。

这是本项目第一条"它在自己学世界"的量化证据,与判据 5(认字)是两条独立的线。

★ 为什么中间会回升(0.235 → 0.476):课程在扩池(33 → 84 → 134 → 142 字), 世界变复杂了,预测自然变难。这与"变差"不是一回事 —— 看趋势要看 "同期正确率在不在涨":它从 1.0% 涨到 37.5%。

#18.2 ★★ loss「规律起伏」的答案:主要是课程扩池,不是 bug

用户在看板上看到 loss 呈规整锯齿,问"这正常吗"。

先说清一件事:控制台每 250 步才打一行,那个稀疏度根本分不清 "结构性周期"与"单步方差" —— 所以我先加了 --loss-json(逐步落盘) 与 tools/loss_curve.py(自相关 + 把"扩池台阶"与"单步方差"分开)。

从已有点位能直接看出的部分(diag_loss_oscillation.py):

text
步    1  池= 33  loss=+13.939   正确率= 0.0%
步  100  池= 84  loss= +4.324   正确率= 0.0%   ★ 扩池,loss 掉 9.6
步  200  池= 84  loss= +1.232   正确率= 1.0%
步  300  池=134  loss= +1.504   正确率= 5.2%   ★ 扩池,loss **升** 0.27
步  400  池=142  loss= +1.614   正确率=10.4%   ★ 扩池,loss **升** 0.11
步  500  池=142  loss= +1.973   正确率=17.7%

模式很清楚:loss 与"进度"反着走,与"池大小"正着走。

正确读法:loss 不是"进度计",它是"当前难度下的拟合误差"。 课程扩池 -> 难度跳一级 -> loss 跳高;随后策略跟上 -> loss 回落。 于是它天然呈锯齿。这不是 bug,是该指标的性质。

★★ 判断"有没有进步"要看验证读数(正确率/判据 5/预测误差),不要看训练 loss。 本项目已经有三次因为错读指标差点走错方向(§12.17、§12.19、§16.4),这是第四次。

还有一条待量:loss 的单步方差有多大(--loss-json 的曲线里能算自相关)。 若自相关在某固定 lag 上强 -> 结构性;若接近 0 -> 单步方差大, 那时该只看滑动平均(tools/loss_curve.py 已经实现了这条判断)。

#18.3 ★★ 并行:GPU 从 8~17% 涨到 99%

之前并行 3 个之后
GPU 利用率8~17%99%
显存1.9 GiB7.2 GiB(上限 8.0)
每个 exp31(B=128) 进程—约 1.3 GiB

★ 安全上限是 3 个并行:开到 4 个时显存 7759/8151 MiB,逼近 OOM。 ★ 也就是说:§15 里"喂不饱"的结论是对的,而解药不只是加大 batch —— 并行跑多个实验也能把显卡填满。 两者要一起用,但要按显存算并行数。

★★ 这条对项目节奏的意义很大:实验吞吐从"一次一个"变成"一次三个", 而每个实验本身也快了 2 倍(batch 16→128)。综合约 6 倍。

#18.4 到目前为止的三条独立读数(必须并排看)

读数含义最新值
判据 5(β=0 正确率 / 纯模仿)撤掉老师后还行不行待重测(batch 128 口径)
预测误差 pred_rel它在不在学世界的结构0.476(起点 1.0)
无回显正确率它有没有拿屏幕当前缀内存33.3%(回显开时 37.5%)
空白屏对照它是不是真在用像素0.0% ✅

← 返回《PROJECT.md》目录