20. 定容量:8.71M 参数 / 6 GB 显存 / 4470 刻每秒(已定为默认)

★★★ 28.0k 字 · 源文件 PROJECT.md 第 3724 行起 · ruler arch external

用户的明确要求(2026-09-27):

「定一个这样的参数量吧,训练和运行时吃 6G 显存,占用尽量吃满」

#20.1 ★★ 为什么必须看整卡读数,不能看 torch.max_memory_allocated()

experiments/diag_capacity_6g.py 的实测对照(同一配置,两种量法):

配置PyTorch 自报 allocated自报 reservednvidia-smi 整卡峰值差
u4096 bb256 B256 T243884 MiB5204 MiB5690 MiB1.5×

差额来自 CUDA 上下文 + cuDNN 工作区 + 分配器缓存碎片。

★★ 这正是 §19 那次"爆显存"事故的根因:我按自报的 1415 MiB 估每个进程, 于是开了 4 个并行;实际每个吃 4.1~4.5 GB,8.6 GB 塞进 8.0 GB 的卡。 Windows WDDM 把溢出部分放进系统内存(共享显存涨到 15.9 GB), 每次张量访问都过 PCIe —— 整机卡顿、速度塌方。

立即可用的规矩:定并行数/定 batch 一律用 nvidia-smi 的整卡读数。

#20.2 容量扫描结果

配置参数量整卡峰值刻/秒判定
u256 bb16 B64 T161,377,3962093 MiB3408偏小
u1024 bb64 B64 T162,107,0442235 MiB3401偏小
u2048 bb128 B128 T163,653,3482984 MiB3928偏小
u4096 bb256 B256 T168,712,0364914 MiB4147可用
u4096 bb256 B256 T248,712,0365690 MiB(95%)4470★ 推荐
u4096 bb512 B384 T1614,020,7086152 MiB4082超预算
u8192 bb512 B512 T1626,693,7327864 MiB1678超预算(吞吐崩了)
u8192 bb512 B384 T2426,693,7327794 MiB977超预算(吞吐崩了)

#20.3 ★★ 定案:units=4096, backbone=256, batch=256

text
参数量      8,712,036      (比之前的 1.31M 大 6.6 倍)
整卡显存    5690 / 6000 MiB  = 95%
吞吐        4470 刻/秒      (之前的 B64 是 2860 -> 快 56%)

★ 又一次验证 §15 那条"加参数几乎免费":

参数量秒/步
u256 bb16 B2561.38M—
u4096 bb256 B2568.71M(×6.3)只慢 9%

★ u8192 那一档吞吐塌方(1678 / 977 刻/秒)—— 说明算力墙在 26M 参数附近, 再往上加就要付真代价。8.7M 是这台机器在当前任务形状下的甜点。

#20.4 配套改动

  1. tools/gpu_guard.py:开跑前查整卡空闲显存,不够就等而不是硬闯。 参数化 --need-mb(exp31 ≈ 4200、exp41 ≈ 4600)。实测过两种情形都判对。

  2. tools/run_serial.ps1:一次只跑一个大任务,每次开跑前过闸门。 取代之前那些并行启动器(并行的代价已经用一次事故交过学费了)。

  3. --enc-lr-scale / 冻结:接地线的诊断显示 lr=3e-3 会一直在动预训练编码器, 而 |g| 长期 10~38(裁剪阈值 1.0,一直被裁)。大模型必须给小 lr。

#20.5 ★★ 接地线的新发现:任务是可学的,之前全是配置错

experiments/diag_ground_learn.py(纯模仿 150 步,起点格距恒为 3.00):

配置平均格距到位率sup_c`g`
基线 lr3e-3 cw251.0012.5%0.22210.4
冻结编码器3.000%0.2205.2
编码器 lr×0.024.000%0.2214.6
lr 3e-43.000%0.2203.6
lr 1e-41.00100%0.42638.3
CONT_W 51.000%0.2212.3
CONT_W 1000.5050%0.22223.9
冻结 + lr3e-43.000%0.22810.7

★★ 有组合能让它动起来(CONT_W=100 时格距 0.50、到位率 50%) —— 所以不是架构问题,是配置问题。

而且规律很清楚: · lr 太小(3e-4 / 1e-4)反而更容易停在 3.00(学不动) · CONT_W 是关键:5 时不动、25 时勉强、100 时才明确动 -> 印证了 §14.6 那个判断(79 个"永远负"的离散位会淹没 2 维摇杆), 而且我估的 25 还是太小。 · 冻结编码器 / 把 encoder lr 调小 并不能救(都是 3.00~4.00) -> 说明不是"编码器被改坏",而是摇杆那一路的梯度不够

★ 注意 sup_c 在 lr1e-4/100% 那组反而更高(0.426):因为它真的在输出 变化的摇杆值(而不是恒定 0),MSE 自然更大。不要用 sup_c 的绝对值判断好坏。

为什么会这样(假说,待验证):

  1. 优势估计的尺度问题:塑形奖励是编辑距离(量级 0~6), 而 adv 做了批内标准化 —— 标准化会把"模仿得很好、所有动作都对"的样本 也变成有正有负的噪声,于是 RL 项在惩罚正确的动作。 · 判据:看 rl 那一项在 β→0 之后的正负(实测多为负:rl=-0.414 / -0.020 / +0.137 乱跳)

  2. v 一直降不下来(0.9~2.5),说明价值函数没学会 —— 优势就是噪声。
  3. 探索噪声不该加在"已经在做对的事"上:β=1 时策略已 99.3% 正确, 此时 RL 的唯一作用是把它推离那个解。

★ 这三条都可以用现有日志验证,见 §19.5 的实验计划。

#19.5 下一步:先解释"RL 为什么会破坏模仿"

实验做法判据
E1 关掉 RL(只留监督)--beta-floor 1.0 跑满 1000 步若到 95%+ -> 模仿本身没问题,问题全在 RL
E2 只降 lr 的 RL 部分策略头 lr 调小、编码器照旧若掉幅变小 -> 是步子太大
E3 加 KL 锚(信任域)加 KL(π ‖ π_模仿) 惩罚项正解,但要写代码
E4 优势不改尺度去掉 adv 的批内标准化若 rl 不再乱跳 -> 就是尺度问题

优先级:E1(免费,只要一个参数)-> E4(改一行)-> E3(要写代码)。

★ E1 值得马上做:它是"RL 到底有没有正贡献"的直接判据, 而现在我们对这个问题的答案可能是没有。


§21 第 0 步:hunger 从"假驱力"变成"真驱力"(四项判据全过)

用户的要求(明确排序): 先需求/欲望(如好奇心、生存欲)-> 后期情感需求 -> 对它自己有认知

一、先修已经有的那个:hunger 原来是假的 energy += RATE 每刻涨;energy -= GAIN if dist==0 只有"整串打对"才掉。 而"整串打对"要求先开门、先打字、每字 65% 正确率 -> 几乎永远发生不了 -> clamp(0,1) 把它顶在 1.0 -> 一个恒定在 1.0 的信号不是驱力,是偏置。

★★ 一个不改变行为的"驱力"不是驱力,是标签。 它最危险的地方:看起来很深,而且永远不会以失败的形式暴露 —— 你没法从日志上看出"它其实没被驱动"。

二、修的过程中连踩三个设计错(每个都留档)

  1. 判据在"策略没学会"时没有分辨力: 第一版在同一个训练过程里换 DRIVE_REWARD 比行为,两个跑次正确率都是 9.4%(都还没学会)-> "行为一模一样"是必然的。 与 §12.19「C′ 满分线 0%」同类:分不开不是因为机制没用,而是任务没做对。 修法:先训会,再对照。

  2. 开关必须作用在"会改变参数"的那条路径上: 第二版在一个已冻结的策略上改 DRIVE_REWARD 再比行为 —— 而它只在训练时影响奖励,冻结后改它对行为不可能有影响。 那次读数(22.7% vs 22.7%)同样是必然的。 修法:同配置各训一次再比。

  3. ★★★ Δd 被"换字"主导,方向是反的: corr(energy, Δd) = +0.285 —— 越"进步"越饿。 原因:回合结束换一个新目标,dist 从 0 跳回 2~6,那是个巨大且无意义的 Δd。 -> 那个驱力机制在跟踪"换题",不是在跟踪"做得好不好"。 修法:饱足信号改用真正的成就(dist == 0,环境免费给): energy += RATE(1 - solved) - GAINsolved*energy

三、最终读数(diag_hunger.py --warm-steps 400) 判据 结果 ① 能量不是常数(std>0.02) 0.2131 [OK] ② 跟着成就走(corr(energy,距离)>0)+0.814 [OK] 越近越饱 ③ 没长期饱和(<50%) 0.0% [OK](DRIVE_MAX 从 1.0 放宽到 3.0) ④ 行为对照(各训一次) 正确率差 3.9pp / 认字差 7.8pp [OK] energy 均值 0.145 范围 [0.000, 0.600]

四、⚠️ 但判据 ④ 的方向是负的(重要的意外) DRIVE_REWARD=0.5 -> 正确率 4.7% 认字 29.7% d 2.55 DRIVE_REWARD=0.0 -> 正确率 8.6% 认字 37.5% d 2.39 -> 驱力确实改变了训练,但开驱力的更差。

原因(假说,很确定):r_used = r_ext * (1 + DRIVE_REWARD*energy) 是乘性放大。 能量 97.7% 时间很低 -> 调制大多数时候几乎不起作用(乘 1.07); 偶尔能量高时把奖励放大约 1.3 倍 -> 只是增加了策略梯度的方差, 没有提供任何方向性信息。

> ★★ 一个有信息量的驱力应该改变"做什么",而不是"奖励多大"。 > 现在这版只改了后者 —— 所以它降级成了"噪声源"。

★ 这条修正了 §13.2 里「内驱力能修 emit 门 -> ✅」那个结论: 那次改善很可能来自 emit 调制(它改变采样分布 = 改变行为), 而惩罚变差的是 reward 调制(它只改奖励尺度)。两者必须分开评价。

五、得到的新判据(以后每个驱力都按这个测)

  1. 不是常数:std > 0.02
  2. 跟着成就走:corr(驱力, 成就) 的符号必须对
  3. 不贴天花板:饱和占比 < 50%
  4. ★★ 改变行为:同配置各训一次,行为读数必须不同(且方向要更好)
  5. ★ 前置:策略必须先学会,否则判据 4 没有分辨力

六、下一步 好奇心(第 1 层)—— 注意它天然满足"改变做什么"(它改变去哪里看), 所以预期能避开第五点那个"只改奖励尺度"的坑。 附带的噪声区自检必须做(noisy-TV 陷阱)。


§22 第 1 步:好奇心(机制已建、防线未验证、判据已就位)

一、机制(已建) · 内在奖励 = 预测误差 / 集成分歧(r += CURIOSITY * curiosity), 加法而不是乘法 —— §21 已证明乘法只改奖励尺度、只增加梯度方差。 · 两道门 + 集成分歧: 门 1 画面必须真的在变(用原始像素的最大逐像素变化) 门 2 单头路线:误差 > 近期滑动均值 × 1.5 集成路线(推荐):奖励 K 个头之间的分歧(Pathak 2017)

二、★★★ 关键洞察:分歧衡量"认不认得",误差衡量"准不准" 噪声永远测不准,但很快认得出来它是噪声 —— 只有分歧能表达这一点。 这是集成路线在原理上优于单头路线的唯一理由。

三、★★ 连踩三个"探针设计错"(比实现错更贵)

  1. 判据对不同实现给出同一个数 -> 先怀疑判据。 第一版探针用未训练的策略,单头与集成都给 81.25%。 随机初始化的头当然互相分歧 —— 那个数测的是"未训练策略",不是"防线"。

  2. 门 1 的度量选错了:原来用 .mean()(全屏平均)。 噪声区 24×24=576 像素只占 96×96 的 6.25%, 它在全屏平均里被稀释到 ~0.007,远低于阈值 0.02 —— 门 1 从来没真正工作过,而它算出的"变化"几乎完全由字符区决定 (成了"字有没有变"的代理,不是"屏幕有没有动")。 改成 .amax()(最大逐像素变化)后才符合设计意图。

  3. assert 形状守卫 > 猜:好奇心涉及 5 个张量的广播, 报错只说 size of tensor a (96) must match b (32),不说是哪个。 实测形状:x=(B,1,1,96,96) —— 取帧要两级索引 [:, 0, 0]。

四、⚠️ 诚实结论:防线未验证 分段趋势(--steps 120,噪声区在场): 集成头数 = 1:93.8% -> 93.8% -> 93.8% -> 93.7% -> 92.9% -> 83.7% [不降] 集成头数 = 3:93.8% -> 93.8% -> 93.8% -> 93.8% -> 93.8% -> 93.8% [不降] 没有一个降下来,所以:我没有一个经过验证的 noisy-TV 防线。

已知的两个原因(都还没排除): a) 算力:120~400 步、batch 32~64 下,预测头远未训练好, 分歧还没收敛到"噪声处为 0"。 b) 门 1 的语义:随机噪声块确实是"屏幕在变", 门 1 按设计就该放行它 —— 它只负责挡"静止屏", 不负责区分"可学的新奇"和"不可学的噪声"。那个责任全在门 2 / 集成上。

五、目前唯一站得住的判据(已全过) · 好奇心信号真的在发(非零占比 2.4%) · 开关好奇心,行为确实不同(正确率/认字/d/emit 都有差) · ★ 判据 5(认字)没有掉 —— 没有"用意外换成绩"

六、下一步(下一步该做的)

  1. 把预测头训好(--steps 2000+)再看分歧在噪声处是否趋于 0。 若仍然不趋于 0,那就不是算力问题,是噪声块真的不可学(不可学即应被奖励?不)。

  2. 若集成路线也失败,退回"可学性"判据: 用"预测误差随参数更新而下降的速度"当新奇度,而不是终值。

  3. ★ 但这三步都应在有注视控制的环境里做 —— 本环境没有注视, noisy-TV 的经典形式不可表达,探针只能用"噪声块"这种替代物, 而替代物与真现象不等价(这正是本次判据反复失效的根源)。


§23 ★★★ RND 换目标:noisy-TV 被根治 + 三个判据设计错

用户的判断:"我认为情感需求的陪伴之类的是为生存的一种机制,好奇心可能也是为了 更好地学习,饥饿也是,他们都是为了生存服务的……但这些机制应该是从生存需求 衍生出来的还是本身就存在的?"

一、查到的现成机制(RND / Burda 2018, arXiv:1810.12894) ① ★★★ 预测目标必须是输入的确定函数 —— 这是根治 noisy-TV 的正解 原文诊断:agents that maximize such prediction errors tend to get attracted to transitions where the answer to the prediction problem is a stochastic function of the inputs … the 'noisy-TV' problem 原文解法:define an exploration bonus using a prediction problem where the answer is a deterministic function of its inputs. Namely we predict the output of a fixed randomly initialized neural network on the current observation. ② 内在奖励必须归一化(除以内在回报的滑动标准差) ③ 两条奖励流两个价值头 —— 因为"外在工作奖励是平稳的,内在奖励是非平稳的" ④ 事实:内在奖励会衰减/消失(学过的就不新奇) ⑤ 陷阱:非回合制的外部奖励会被"故意自杀重开刷开头奖励"利用

经验依据(RND Table 1,Montezuma)—— 只换预测目标: RND 8,152 vs 前向动力学误差 400 (差 20 倍)

二、★ 我们原来的实现错在哪(这是本节最重要的一条) 旧:predictor(当前帧) -> 编码器(下一帧) ❌ 目标是随机的 新:predictor(当前帧) -> 固定随机网络(当前帧) ✅ 目标是确定函数 => 我加的两道门 + 集成,全部是在给一个错误的问题打补丁。 RND 路线根本不需要 noisy-TV 的门。

三、★★★ 决定性验证(diag_rnd_noise.py --steps 180) 无噪声 :内在奖励幅度 0.3505 -> 0.2689 -> 0.2736 -> 0.2846 -> 0.2757 -> 0.2766 (78.9%) 噪声区在场:内在奖励幅度 0.7983 -> 0.4110 -> 0.1538 -> 0.0764 -> 0.0607 -> 0.0506 (6.3%)

判据 结果 ① 噪声区幅度大幅衰减(末段<首段25%) 6.3% [OK] ② 末段幅度 < 0.10(相对任务奖励可忽略) 0.0506 [OK] ③ 字符区信号还在 0.2766 [OK] ④ ★★ 噪声区衰减比字符区更快 6.3% vs 78.9% [OK]

★★ 判据 ④ 最有说服力:噪声被认得比字形更快 —— 因为噪声块是输入的 确定函数(每个像素只是它自己),而字形之间的差别要多花样本。 这正是 RND 的机制,而它在数据里显形了。

对照(旧实现的现场,--steps 120): 集成头数=1:非零占比 93.8% -> 93.8% -> 92.9% -> 83.7% [不降] 集成头数=3:非零占比 93.8% -> 93.8% -> 93.8% -> 93.8% [不降]

四、★★ 又一次"判据设计错"(第四次了,值得单列) "非零占比"这个判据对 RND 这条路线恒为 100% —— 因为 RND 的奖励是 pe / running_rms,一个归一化后的均方误差,永远不可能恰好为 0。 我第一版用它,于是"100% -> 100%"被读成失败,而同一批数据的幅度 显示噪声区降了 16 倍。

> ★★ 要测的量必须能区分对与错。一个恒为 100% 的量测不出任何东西。 > 这与 §21「策略没学会时判据没有分辨力」、§22「判据对不同实现给同一个数」 > 是同一类错误的第四次出现。这是本项目最反复的失效模式。

五、关于"衍生 vs 原生"(用户的问题) · 心理学没有定论: Hull 驱力减退(1943):全部为降低生物驱力 Berlyne(1950s):老鼠在无任何强化的迷宫里仍主动探索 -> 驱力减退说不成立 Butler(1954):猴子为"看一眼"而工作 -> 探索本身即奖励 Harlow 恒河猴:小猴选没奶的绒布妈妈 -> 依恋不是喂食派生的 · Panksepp:7 个初级情绪系统(含 SEEKING=好奇、CARE、PANIC/GRIEF=分离焦虑) · Deci & Ryan:自主/胜任/联结是基本心理需求,与生理需求并列 · ★ 最站得住的中间立场:硬件给定,参数可塑(半原生) —— 机制原生,但目标对象与强度是学出来的 · 架构结论:不能只有一条"生存"标量(与 Harlow 矛盾); 取"分层":每条内在线各自原生 + 各自的价值头;生存当终止/可行性约束, 不当唯一分数。这正是 RND 第 ③ 条的推广。

六、本次代码改动 · pred_target:冻结的随机网络(题目),pred:学生 · 预测改到同一时刻(pred(h_t) -> pred_target(z_t)) · 逐样本误差 pred_pe (B,T) -> 内在奖励;pred_rms 是 buffer(跟着权重存) · 删掉两道门、集成分支、cur_prev_z/cur_prev_scr · 4 条 RND 自检(冻结/目标确定性/predictor 有梯度/pred_rms 是 buffer) · --curiosity 现在必须配 --pred-coef > 0(否则报错退出,不静默失效)


#记录:RND 之后的第二次改动(双价值头)以及一个回归的定位过程

#这份文件是诊断笔记,不是提交信息。

现状(未提交): exp31_read_rl.py +114 行:加 v_int 第二价值头、pred_pe 逐样本、 内在奖励归一化、forward_with_pred 加 PRED_COEF 守卫 exp41_ground_rl.py +29 行:改走 forward_with_pred(但不用 val_int)

回归: exp31 自检 21 项全过 exp41 自检的回归判据 FAIL:纯模仿 120 步后平均格距 3.00/4.00, 而 9c60573 时是 1.00 同时 diag_min_repro.py 的 |g| 从 10~40 掉到 0.2

已排除: · 不是 _g.reset 那一行(有无都一样) · 不是 diag_min_repro 的 LIFO 栈污染(那是我读错,但两个 case 都是 3.00) · 不是预测头的梯度泄漏(已加 PRED_COEF<=0 守卫在模型内部,exp41 走 forward_with_pred 时 pred/tgt 都是 None)

我的第一个改动(RND 换目标)是已验证的: 噪声区内奖励幅度 0.7983 -> 0.0506(6.3%),字符区 78.9% -> 判据 ④ 过 见 §23 与 results/logs/rnd_noise.json

所以问题一定在这次「双价值头」改动里。下一步是在同一状态上做干净的 A/B:把 v_int 从 ReadPolicy 里去掉,看 exp41 自检是否立刻回到 1.00。


§25 两个数据缺口 + 一次"以磁盘为准"的校正

一、★★★ 数据缺口一:acc_eval 声明了却从来没被写入 curve_*.json 里声明了 "acc_eval": None,但代码里没有任何地方给它赋值 -> 我们所有曲线里一个评估量都没有,只有逐 step 的训练损失。

为什么这个缺口很贵:它让我无法回答"能力跳变是真的还是度量造的"。 而那个问题(Schaeffer et al., arXiv 2304.15004)正好是我们反复踩的坑。

已修:评估点把五个量并排写进曲线 —— · acc_eval 离散(0/1,"整串全对") ← 嫌疑对象 · dist_eval 连续(编辑距离) · first_eval 连续(首字正确率) · key1_eval 连续(认字率) · emit_eval 连续(门开率) 验证:tools/show_curve_metrics.py results/logs/curve_metriccheck.json -> 5 个键都在,格式通过。

> ★ 规矩:声明了却从不写入的字段 = 数据缺口,比崩溃更难发现 —— > 因为它不报错,只是让某个问题永远无法回答。

二、★★★ 数据缺口二:我自己的记忆缺口(这个更值钱)

本轮开始时我以为项目停在"好奇心防线未验证"。 实际 git log 显示已有两个提交是我记忆里没有的: 9c60573 §23 RND 换目标:noisy-TV 被根治 54ec37e 双价值头 + 修判据(格距方差太大导致连续误判两轮)

> ★★ 上下文压缩会制造"记忆缺口",而缺口的表现是"我以为的进度"与 > 磁盘状态不一致。 > 规矩:每轮开头先 git log + 读 tools/diag_note.md, > 以磁盘为准,不要以叙述为准。这次正是这样校正回来的。

三、★★ 校正后的真实状态(磁盘为准)

项状态
RND 换目标✅ 已验证:噪声区奖励幅度 0.7983 -> 0.0506(6.3%)
双价值头 v_int✅ 已实现并跑通 600 步
exp31 自检✅ 21 项全过
exp41 自检✅ 全过(判据已改用 sup_c 是否下降)
涌现判据⏳ 曲线记录已补齐,形状对比待跑

四、★★★ 双价值头对"RL 摧毁模仿"的效果(这是目前最硬的一条对比)

同一个接地线任务、同一个 β 日程(β 降到 0):

跑次β=0 后到位率平均格距
big_c1(单价值头)25.0%3.00
v2head(双价值头)50.0%2.00

★ 双价值头把 β→0 之后的性能从 25% 提到 50%(翻倍)。 方向与预测一致(RND 那篇说"两个头各面对一个平稳/非平稳的流"), 但没有完全解决 —— 仍低于纯模仿期的 100%。

> 所以"RL 摧毁模仿"现在是三个可分辨的层次: > ① 纯模仿(β=1):100% > ② 双价值头 + RL(β=0):50% > ③ 单价值头 + RL(β=0):25% > 每加一个正确的机制,恢复一层。下一步要找的是第二层缺口(50% -> 100%)。

五、"涌现"那条判据的进展

experiments/diag_emergence_metric.py 已建,判据是 跳变度 = max|Δ| / (max-min):平滑曲线 ≈ 1/步数,阶跃曲线 ≈ 1。

对现有曲线(只有连续量)测得:teach_acc 的跳变度 0.28~0.72。 ★ 注意这不是结论 —— 它说明连续量本身也不平滑(这削弱了 "跳变全是度量造的"这一简单版本),但要真正检验 Schaeffer, 必须让离散量也进曲线(已补上,待跑)。

六、教训:判据的方差会让人连续误判 54ec37e 记录:平均格距在同一配置下能从 1.00 变到 5.00(只有 16 个回合), 于是连续两轮把"没学会"误判成"会动"、又反过来。 修法:改用 sup_c(监督项的连续分量)是否下降 —— 它来自 4096 个样本, 方差小得多。 > ★ 与 §22 那三条"判据设计错"是同一类:判据本身的噪声 = 假结论。


§26 检验"涌现是度量造的吗":一个判据失效,一个结论(阴性)

一、读到的东西(Schaeffer et al. 的精确主张) "Are Emergent Abilities of Large Language Models a Mirage?" arXiv 2304.15004,NeurIPS 2023 最佳论文: > "when analyzing fixed model outputs, emergent abilities appear due to the > researcher's choice of metric … nonlinear or discontinuous metrics produce > apparent emergent abilities, whereas linear or continuous metrics produce > smooth, continuous predictable changes"

★ 关键在 "fixed model outputs" —— 他主张的是:模型能力已经饱和 (曲线本应平了)时,离散度量凭空造出跳变。 不是在"学习还在快速爬升"的阶段。

二、★★★ 判据失效:跳变度在点数少时恒等于 1 第一版判据 jump = max|Δ| / (max-min)。实测 4 个量 (1 个离散 acc_eval + 3 个连续 dist_eval/first_eval/key1_eval) 全是 1.000。

原因:5 个点必然包含 max 和 min,所以 max|Δ| = max-min,比值恒为 1。 这个判据在 n=5 时没有任何分辨力。

> ★★★ 这是我在 §22 写下那条规矩的第三次违例: > "判据若对不同实现给出同一个数,先怀疑判据,别怀疑实现。" > 第一次:未训练策略的探针(单头/集成都 81.25%) > 第二次:没学会的任务(两组行为都是 9.4%) > 第三次:点数不够(四个量都是 1.000) > ★ 规律:判据失效的样子总是"所有东西看起来一样"。

已修:改成按点数归一的 jumpiness * (n-1) (1 = 完全平滑,n-1 = 一步到位),且 n < 8 一律标 nan。

三、★★ 结论(阴性,且不支持 Schaeffer 的简单版本)

在同一组评估点上(8 点,curve_shape.json):

度量类型归一跳变度
acc_eval离散6.87
dist_eval连续7.00
first_eval连续5.69
key1_eval连续6.56
离散/连续1.09×

离散量并没有比连续量更跳。 所以在这份数据上, "能力跳变是度量造出来的"不成立。

四、★ 但这一轮不能用来检验 Schaeffer(混淆必须说清) curve_shape.json 只跑了 50 步 —— 模型处在早期快速学习期, 所有曲线都在陡升,于是任何度量看起来都"跳"。

要真正检验,需要:跑到曲线真的平下来,然后看离散量在 "连续量已经平坦"的区域是否仍然跳。 -> 这是下一轮该做的那件事(不需要新机制,只需要跑长 + 用已补的曲线记录)。

五、这一轮的正面产出(都是可复用的)

  1. acc_eval 声明了却从未被写入 -> 已修,五个评估量并排入曲线 (离散 acc_eval + 连续 dist_eval/first_eval/key1_eval/emit_eval)

  2. experiments/diag_emergence_metric.py —— 判据已修成按点数归一
  3. tools/show_curve_metrics.py —— 看一条曲线的离散/连续量
  4. ★★ "每轮开头先 git log + 读 tools/diag_note.md" —— 本轮正是靠这条才发现两个我记忆里没有的提交(§23 RND、双价值头), 上下文压缩会造成记忆缺口,必须以磁盘为准。

六、意识文献的要点(子代理报告,全文在 darlin-consciousness-literature-report.md) (用户 brief 的三处纠正) · arXiv 1810.11143 不是展开论证,它是 "Smell Pittsburgh"; 展开论证没有 arXiv 版,规范引用是 doi 10.1016/j.concog.2019.04.002 · "The Free Energy Principle: A Critique"(Colombo & Wright)未能证实存在 · "Juliani et al. Deep Learning and the GWT" 是另一篇(arXiv 2204.05133)

(改变"下一步做什么"的四条)

  1. Butlin 表不是测试,是可信度更新:其 v3 免责声明说满足指标 "would not mean that such an AI system would definitely be conscious"; 且 Koch, arXiv 2603.27597 指出这些赋值 无法校准、生物到硅的迁移无独立支持。 -> 唯一诚实的输出是相对建筑排名,永远不是概率。

  2. ★★ 可辩护的可测构念是 meta-d'(Type-2 元认知敏感度),不是"意识"。 ECE/Brier 把"知道多少"和"知道得准不准"混在一起。 ★ 必须用 0–20 置信度刻度:0–100 时 >78% 的回答挤在三个整数上。

  3. ★★ 唯一有已发表先例的因果协议:"no-rewire 自我模型损伤"双分离 (Phua, arXiv 2512.19155)—— "abolishes metacognitive calibration while preserving first-order task performance"(合成版盲视)。 同一篇的阴性结果:工作台瓶颈下 PCI-A 反而下降 —— IIT 系代理指标不能naive搬到工程智能体上。

  4. 不要建在 Φ/IIT 或 FEP-as-metaphysics 上(三重独立否证 + 2025 Nature 对手合作实验同时重创 IIT 与 GNWT)。 但 active inference 有具体的可证伪内容(如标准版在 horizon=1 是 Bellman 最优、再长就失败)。

("自我模型"的最低门槛:5 个条件,每个都有已记录的失效模式) · 写在决策路径上,不是旁边 —— Xie, arXiv 2604.11914:辅助置信模块 "collapse to near-constant outputs (confidence std < 0.006)"、 "the agent's decisions are unaffected by module outputs" · 显式且可解码(探针能从内部激活读出"关于自己"的属性,且不是世界模型已给的) · 生成式/预测式(要报误差 + 零假设 + 时程) · 选择性必要(双分离) —— 这是承重的那条 · 设计上就不完整(自身状态的残差误差有非零地板)


§25 ★★ 双价值头的决定性验证结果(崩溃止住了,但没保住最好状态)

一、对照(判据在跑之前写死:β→0 之后不许崩)

步 β v2head(双价值头) big_c1(单头,对照) 到位率 高亮前 教师一致 到位率 高亮前 教师一致 120 1.00 45.3% 45.3% +0.252 — — — 180 0.82 0.0% 0.0% +0.314 100% 100% +0.264 240 0.64 0.0% 0.0% +0.391 100% 100% +0.285 300 0.46 0.0% 0.0% +0.470 75% 75% +0.341 360 0.29 18.8% 18.8% +0.556 100% 100% +0.331 420 0.11 25.0% 25.0% +0.547 100% 100% +0.328 480 0.00 54.7% 54.7% +0.324 100% 100% +0.314 540 0.00 50.0% 50.0% +0.430 25% 25% -0.449 600 0.00 50.0% 50.0% +0.108 25% 25% -0.441

二、结论(诚实版) ✅ 双价值头止住了崩溃:β→0 之后不再从 100% 崩到 25%。 ✅ ★ 教师一致度再没翻符号:big_c1 在步 540 变成 -0.449(符号都反了), v2head 全程为正、末尾 +0.108。 ❌ 但它没保住最好状态:v2head 的峰值只有 45.3%(步 120), 末尾 50%;而纯模仿(β≡1)能到 100%。 -> 所以"非平稳流"是部分原因,不是全部。 -> 判据 5 的分母仍是 100%(纯模仿),所有 β 退火跑次都还在它之下。

三、下一个嫌疑:量级(两条,都已做成开关) (a) pi 在步 600 到 -4.954,而 sup 只有 0.33~0.86 —— RL 项比监督项大一个数量级,而监督项才是让策略"会做"的东西。 这正是 §21 在 exp31 里发现的同一个病(那边监督 ~0.02、RL 1~45)。 -> 加 --rl-scale (b) ★★ exp41 原来一直在做 advantage 批内标准化: adv_n = (adv - mean) / (std + 1e-6) β→0 时 not_taught 变多、adv 的批内方差变小, 除以一个小 std 会把噪声放大。 exp31 里已经发现并默认关掉了这个(§21),但 exp41 漏了 —— 两个文件同一处逻辑分叉,正是 §18 那条"两处必须一致"的又一次代价。 -> 加 --adv-norm(默认关)

四、正在跑(run_N_rlscale.ps1) rs01(rl-scale 0.1)、rs002(0.02)、rs01frozen(rl-scale 0.1 + β 下限 0.1) 判据:至少要有一个超过 50%,同时 β→0 之后仍不许崩。

五、★★★ 本次最贵的一课:判据本身的方差 改完双价值头后 exp41 自检回归 FAIL(格距 3.00 -> 4.00), 我连续给出两个错误归因(先怪共享 rng,再怪双价值头)。 真凶是判据(平均格距)方差极大: diag_min_repro.py 同一份代码、同一策略, 训练循环前有 _g.reset(...) -> 格距 1.00 训练循环前没有那一行 -> 格距 5.00 起点本身也在 3.00~5.00 摆动。

> ★★★ 用一个方差巨大的代理量去判"结构性改动有没有把东西弄坏", > 必然得到随机结论。 我为此连看两轮 1.00/3.00/3.88/4.00/4.25/4.88, > 一直以为"代码在退化",而它只是同一个健康状态的噪声。

修法:换直接读数 sup_c(监督项的摇杆分量): 健康(自检):1.101 -> 0.222 健康(§21 外部):~4.5 -> 0.22 坏掉(79 离散位淹没摇杆):起点就只有 ~0.22,且不降 判据 = "降到 0.5 以下 且 相对起点降 ≥1.5 倍"。 ★ 附带:阈值不能用"起点绝对值"卡死(起点随初始状态在 1.1~4.5 变), 要卡的是降幅。

六、未解决的环境问题(记下来,别忘) _g.reset(...) 会改变训练结果(1.00 vs 5.00)。说明 GroundGroup.reset 用 self.rng 抽字体这件事,让"重置一次" 成了一个有副作用的操作。应当让字体抽样完全由显式种子决定, 不受"这个对象被用过几次"影响。(evaluate 已走显式 seed,训练循环里还没有。)

七、提交纪律(一次小事故) 我用 git add -A 时把 _emergence_research/ 里 9 个 .raw/.txt 研究中间产物误提交了(2914 行数据)。 已 git rm --cached 撤出,并给 .gitignore 加 *.raw。 > ★ 教训:提交要用显式路径(git add experiments/ tools/ PROJECT.md), > 不要 git add -A —— 工作目录里随时可能有别人的产物。


§27 三主题调研定稿:能落地的规则 + 一条可立即检验的假说

三个子代理全部交回(各写了完整报告文件): · 涌现 _emergence_research/EMERGENCE_SURVEY.md · 意识 darlin-consciousness-literature-report.md · LNN 见下文第六节(本会话内已落地)

一、★★★ 涌现:定稿结论(比我 §26 写的更精确)

  1. Schaeffer et al. 的主张成立,但比双方说的都窄。 已确立:① 构造性演示(固定模型输出只换度量,跳变消失; GPT-3 算术、LaMDA/BIG-bench,外加两个从没人声称涌现的视觉域); ② 总体基率(39 个 BIG-bench 首选度量里至多 5 个显示涌现;

    92% 的主张落在两个阈值型度量上);③ 分辨率不足;④ ~10⁶ 个三元组的 p-hacking 面。

    未确立:不是"涌现从不真实"(他们自己明说);不是"锐变不可能"。 ★ 注意 NeurIPS 官方奖项页写的是 "Outstanding Paper",不是"最佳论文"。

  1. ★★ Wei et al. 原文自己就承认了度量解释 (附录 A.1:"We find that all six BIG-Bench tasks fall under Outcome 2" —— 即交叉熵平滑改进而 EM/BLEU/accuracy 停在随机水平)。 但其 §5.1 的 steelman:*"using evaluation metrics that do not give partial credit are at best an incomplete explanation*"。所以不是一边倒。

  1. ★★★ 最重要的反证:Zhao et al. [2502.17356] 他们构造了一个可证 Lipschitz 连续的度量(逐 token 最大损失的 token 均值 —— 有限个 Lipschitz 函数取 max 仍 Lipschitz), 结果:*"the distribution of this metric across random seeds is still clustered… emergent capabilities exhibit bimodal distributions even when using a continuous performance metric."* MMLU 的 NLL 双峰,Hartigan Dip Test p<0.001。 -> 有些离散的东西是真的,但它在「跨随机种子的分布」层面,不在均值上。

  1. ★★★ grokking 的机制否掉了"突然"(Nanda et al. [2301.05217]): 三阶段 = 记忆 -> 电路形成 -> 清理。原文: *"the sudden transition to perfect test accuracy in grokking occurs during cleanup, after the generalizing mechanism is learned."* 而且他们的进度度量(restricted/excluded loss)在 grokking 之前连续改进。 -> 跳变发生在"清理"阶段,而机制早就形成了。

  1. 哲学定性(Krakauer/Krakauer/Mitchell [2506.11135] 最有用): ML 的"涌现"至多是 Chalmers 的弱涌现(相对于某个外推族的意外), 而在 Schaeffer 分析的场合里不满足 Bedau 的不可压缩性判据 —— 因为宏观曲线正是微观平滑量的一个可压缩的确定性变换。 他们的操作性规则:*"the term emergence… should be reserved for the combination of successful task performance and the associated new coarse-grained representations formed within the responsible structure"*。 标题即结论:"Emergent Capability Is Not Emergent Intelligence."

二、★★★ 对我们的可执行测量规则(按性价比排序,[L] = 先做)

A. 让度量造不出跳变

  1. [L] 阈值型度量永远不能当主要证据(exact-match / accuracy / pass@1 / "每步都对" / MC-grade 都是阶跃函数)。可以报,但必须与底层量并排。

  2. [L] 主度量用似然型:目标续写的平均逐 token NLL + ★ 逐 token 最大损失的 token 均值(可证 Lipschitz 连续, 正是 Zhao 等用来证明"双峰不是阈值造成的"那个度量)。 这一个选择就化解掉整场 Schaeffer 之争。

  3. 能力要报两次:固定 k 的 pass@k(能力)与 pass@1(可靠性)。混起来就是假涌现。 小 p 时用 PassUntil(采样到 r 个通过,报 PU = r/K,负二项 MLE,近无限分辨率)。

  4. 多步任务设计上就给部分分(逐步正确率 + 对了多少步),让复合误差可见。

B. 别再画单次运行的均值

  1. [L] 每个配置 n ≥ 10 个种子,并把逐种子原始点画出来,不只画均值。 ★ "是不是跳变"这个问题本身就是关于分布的。

  2. [L] 每个配置做一次模态检验(Hartigan Dip Test,或 KDE + 自助法数峰数)。 "连续度量下仍双峰"是唯一便宜的、能活过 mirage 批判的证据。

  3. 报区间不报点估计(比例用 Wilson/Clopper–Pearson;分组题用聚类稳健标准误; 配对到题目层面,绝不用两个聚合数相减)。

  4. 跑之前做功效分析。N=200 题 -> 0.5% 分辨率;N=20 题 -> 5%, 这时任何"涌现"都在误差棒里。

C. 诚实呈现曲线

  1. [L] 每条曲线都画线性轴与对数轴两种,并说明结论依赖哪一种。 对数轴掩盖跳变,线性轴掩盖平滑的尾部进展 —— 两边各有一次合法命中。

  2. 拟合函数形式并报平滑度统计量(最大局部斜率/值域),别只说"很尖"。
  3. 扫第二个控制变量(轮数、数据量、内存、打断率)。跳变位置随检查点漂移 => 是预算/双下降产物。

D. 买机制证据,不买曲线形状

  1. [L] 在声称不连续之前,先找连续进度度量。 模板:Barak et al. 的权重移动量/Fourier 间隙;Nanda et al. 的 restricted/excluded loss —— 白盒标量单调上升,而黑盒度量平坦。 对我们的做法:在每个检查点上线性探针那个你认为承载行为的表征。 探针平滑 + 行为后跳 => 那是读出/竞争事件,就这么说。

  2. 优先因果检验而不是曲线形状(Omnigrok 能诱发也能消除 grokking; Varma 等预测并验证了 ungrokking)。

  3. 跟踪步级"隐藏进展"(首次失败前解对的比例;逐步最大损失)。 端到端平台期 + 步级损失在降 = 复合误差,不是新能力。

E. 设计护栏

  1. [L] 冻结并消融 harness。 对一个可打断智能体, 打断策略、重试预算、温度都是 harness。CurveShift [2608.00355]: 难题上的增益 "cannot be assigned to the model or its scaffold"。 -> 把 scaffold 当一个因子去变,报它的主效应。

  2. 难度要外生锚定(人工评分、留出生成器、固定题库的 IRT/Rasch), 否则"难题上的进步"有一部分只是天花板效应的改述。

  3. 预注册主度量、对照与停止规则。若扫 k 个度量 x m 个任务,报出 k·m 并做多重比较校正。
  4. 利用输出等价性:原始输出只存一次,离线用任意度量重打分 —— 零成本且结论不可辩驳。
  5. 在一个"不可能有这个能力"的模型上做 sanity check(随机初始化;不可能的任务)。

F. 语言纪律(免费,而且它改变你去找什么)

  1. 说"度量 M 在规模 S 处发生了锐变",不要说"能力 X 涌现了"。 "涌现"一词留给至少满足一条的主张: · 连续度量下逐种子双峰 + 通过模态检验; · 识别出一个屏蔽掉微观权重的粗粒化内部变量; · 相对预注册外推的预测性意外。 用"相变"就先说清序参量与控制参数。

★ 一句话分诊: *这个变化在「对逐 token 误差 Lipschitz 连续」的度量下还看得见吗? 它在逐种子上看得见,还是只在均值上?有没有一个内部连续进度度量预告了它?* 三个都否 -> 是度量。任一是 -> 有真东西要解释,而且你知道是哪一种。

三、★ 一条可以立刻用我们自己的数据检验的假说

我们有那个"100% 突然掉到 25%"的现场(big_c1 单头 vs v2head 双头)。 按上面 A2 + B5 + B6,正确的问法是:

把同一配置跑 n ≥ 10 个不同种子,看 β→0 之后的到位率是 (a) 每个种子一个固定值、种子之间分成两簇(-> Zhao 式双峰,真现象) (b) 每个种子内部就抖动(-> 只是噪声/评估方差) (c) 所有种子都平滑下滑(-> 就是连续的,之前的"崩"是阈值度量的错觉)

★ 这与 §26 那次检验不同:§26 只跑了 50 步(还在陡升期), 这次要跑到 β=0 之后曲线平下来,并且跨种子。 这是"涌现"主题唯一还欠我们的实验,而且它同时回答"RL 摧毁模仿是不是真的离散"。

四、意识:定稿要点(子代理完整报告已存) · 没有任何单一有效的机器意识检验,文献自己就这么说 (Butlin 的免责声明、Koch 的校准/迁移批判、Schwitzgebel 的不可知论证)。 · 唯一真实的清单是 Butlin/Long et al. 的 14 条指标属性(5 个理论), 但它是可信度更新,不是测试;Koch [2603.27597] 指出赋值无法校准、 生物->硅的迁移无独立支持。-> 诚实输出是相对建筑排名,不是概率。 · ★★ 可辩护的可测构念是 meta-d'(Type-2 元认知敏感度),不是"意识"; ECE/Brier 把"知道多少"和"知道得准不准"混在一起。 ★ 必须用 0–20 置信度刻度(0–100 时 >78% 答案挤在三个整数上)。 · ★★ 唯一有已发表先例的因果协议:no-rewire 自我模型损伤双分离 (损伤掉元认知校准、保住一阶任务)。同篇阴性结果: PCI-A 在瓶颈下反而下降 -> IIT 系代理指标不能搬。 · 不要建在 Φ/IIT 或 FEP-as-metaphysics 上。 active inference 有具体可证伪内容(标准版在 horizon=1 是 Bellman 最优、再长就失败)。 · "自我监控必须坐在决策路径上,不是旁边" —— Xie [2604.11914]:辅助置信模块 "collapse to near-constant outputs (std < 0.006)"、 决策不受影响。

五、★ 对我们架构的具体含义(这是三份调研的交点) · "全局工作台"(GWT-2/3/4)与"元认知"(HOT-2)是我们缺的两格 —— 而它们与我此前说的"③自我模型 -> ④元认知之间缺主动"是同一个位置。 · 但按 Koch 的批判,不要为了"上清单"去做它;要做的是 可测的功能后果(meta-d' 双分离),并把结论写成机制声明而非意识声明。 · active inference 那条"horizon>1 就失败"是唯一可以立刻拿来做判据的理论预测。

六、LNN:定稿(已在本会话落地) · 留在 ncps CfC,不换。 没有更好的、还保留连续时间/可打断特性的替代。 所有候选在维护性上都更差(raminmh/CfC 自 2022 死;LRC 8★;haiku_CfC 2★; flaxoil 转私有;LTC-SE 不在 PyPI;LTCNN 2022 孤儿)。 · ★★ 生态定性:作为库生态已僵死,作为研究小生境还活着。 ncps 2351★ 但最后一次合并 PR = 2024-08-14(25 个月前); HF 上 ltc 标签 0 个模型、ncps 标签 2 个且都是 0 下载; "CfC network" 全文 0 命中;TorchRL/SB3/RLlib/mctx/Gymnasium 全 0。 ★ 对比:LTC 论文 HF 3 个赞 vs Mamba 152 个。 · ★★ 两条对我 brief 的纠正(已接受): ① 不存在 lucidrains 那条线 —— 枚举其全部 400 个公开仓库, liquid|ltc|cfc|circuit 零匹配;lucidrains/liquid-neural-networks 是 404。 ncps 纯粹是 mlech26l + raminmh。 ② "Liquid AI 还在推液态网络"是品牌错觉 —— LFM2 技术报告 (作者含 Hasani、Lechner)写的是 *"gated short convolutions with a small number of grouped query attention blocks"*,没有 LTC/CfC。 · ★★★ 本会话最重要的落地:ts 逐样本时间 ncps 的 timespans 在 batch>1 时是坏的(issue #83,修复 PR #85 仍未合并), 且 B==units 时静默算错。但 cell 级传 (B,1) 是好的、无需 fork。 我已实现并加了三条自检(core/models.py): 常量 ts 下 (B,1) 与标量差 0.00e+00(等价) 逐样本 ts 下样本间输出差 1.8093(真的生效) (B,) 形状被守卫挡住 ★ 并修正了 core/models.py 里那条过严的结论(原文"LTC 只能接受标量 ts")。 ★★★ (B,) 是"只在你想用它的时候才坏"的 bug: 常量 ts 下它和正确路径完全一样(差 0.0), 一旦真传逐样本不同的 ts(那正是用它唯一的理由),差 0.4243 静默算错。 > 规矩:形状错误若只在"常量"下被检验,就等于没检验。

七、★ 顺手修掉的一个"检查器自己有 bug" tools/check_quotes.py 第一版用 line.split("#", 1)[0] 剥注释再数引号, 但某行有 # 在字符串内部((issue #83)),于是把 #83)") 当注释砍掉, 报成"引号不成对" —— 而那一行完全合法。差点让我去改一段正确的代码。 > ★★ "检查器自己有 bug"是最难发现的一类 —— 它的输出看起来在指控被测对象。 > 规矩:检查器报错时,先验证检查器本身的判据。 已改用 Python tokenizer(分词通过 = 引号全对),全仓复扫 0 假警。


← 返回《PROJECT.md》目录