tysgydk/Qwen3-4B-LoopIntervention

English summary. This repository is a research workbench for "loop intervention" on a frozen Qwen3-4B trunk: it ships 38 small intervention-network checkpoints plus the complete training, data-construction, evaluation and diagnostic scripts, together with the author's lab notebook and model registry. It contains no full model weights — every .pt file is a state dict of the intervention modules only (about 1 MB to 79 MB each) and must be combined with a separately downloaded Qwen/Qwen3-4B. Nothing here is loadable with from_pretrained, and none of these checkpoints is a production-ready model.

这是什么

  • 主干固定不变:Qwen/Qwen3-4B(官方 Instruct 后训练版,d=2560,36 层)全程冻结,只训练一个外挂的干预网络;目标是让"把同一段计算多走几圈"不坍缩,甚至变成真正的等效深度增益。
  • 仓库性质:这是实验胶水代码 + 中间检查点集合,不是成品模型。作者自己的定位见 model_registry.md(变体注册表 + 继承链)与 实验记录.md(427 行实验史,含作者批注)。
  • 三条架构线(model_registry.md 记录):旧主线(主干重复循环,已全部废弃)、残差循环(主干只 forward 一次,隐状态上叠低秩残差块)、变换循环(每圈用满秩 Proj 把隐状态翻译回 embedding 空间后重新 forward 主干)。

不含完整权重(重要澄清)

  • ckpt/ 下所有文件都是干预网络的 state_dict,两种格式:
    • 残差/旧架构:{'step', 'r', 'sd'}
    • 变换循环:{'step', 'r', 'loop_sd'}(内含 proj.*、loop_gate.*,可选 interv_loop.*、v_tokens.*)
  • 仓库内没有 config.json、tokenizer、model.safetensors 或主干 pytorch_model.bin;因此 AutoModelForCausalLM.from_pretrained("<本仓库>") 不能工作。
  • 使用方式只有一种:先自行获取 Qwen/Qwen3-4B,再把 .pt 里的干预参数加载到脚本定义的模块中(参见 scripts/train_residual.py 的 ResidualLoop)。

仓库内容

Qwen3-4B-LoopIntervention/
├── README.md            # 原卡片(含旧 front matter,声明 license: Apache License 2.0)
├── 实验记录.md          # 427 行实验史(含作者批注),日期标注 2026-08-18 ~ 2026-08-26
├── model_registry.md    # 变体注册表:继承链 + 每个变体的结构/成绩/状态,最后更新标注 2026-08-27
├── .gitattributes       # 声明 *.pt 等走 LFS(实际仓库内 0 个 LFS 对象,.pt 为普通文件)
├── ckpt/                # 38 个干预网络检查点(见下表)
└── scripts/             # 41 个训练/数据/评测/探针脚本(见下)

ckpt/:38 个检查点逐个说明

成绩口径(引自 model_registry.md / 实验记录.md,均为作者自测,除注明外为 MATH-500 第 201~260 题、60 题子集、cap1024、greedy):**纯主干 r1 = 16.7%**。

A. 旧主线(主干重复循环,train_interv.py 的结构:虚拟 token + 循环入口 FiLM + 共享/块化低秩加性修正)

文件(大小) 结构 记录中的状态/成绩
interv_step7500.pt (2.0 MB) 约 50 万参数,纯 GSM8K train 从头 7500 步 GSM8K r1 75.0%,文本"客场"崩;废弃
intervgen_step7500.pt (2.0 MB) 纯 fineweb + zh 语料从头 7500 步 wikitext CE 2.76,数学客场 43.3%;废弃
intervmix_step4000.pt (2.0 MB) 混合数据 mix_v1 4000 步("蓝莓",通用打底) 登记为 GSM8K r1 83.3% / r2 71.7%,MATH r2 18~40%;废弃(旧架构)
intervmargin005_step2000.pt (2.0 MB) 蓝莓 + margin 0.05 的反例 75.0%(掉 8.3 点,用于证明损失侧无油水);废弃
intervpollute_step2000.pt (2.0 MB) 蓝莓 + 污染纠错数据 pollute_v1s("草莓") 纠错 100% / 保持 100%;MATH r2 31.7%;废弃
intervmathcorr_step2000.pt (2.0 MB) 蓝莓 + 真实错误配对数据 MATH 11.7%(CE 教不会纠错);废弃
intervthink_step7500.pt (2.0 MB) 思考专家 v1:自蒸馏思维链从头 7500 步 21.7% 翻车(思维漫游);废弃
intervthinkv2_step3000.pt (2.0 MB) 思考专家 v2:v1 续训(思维链截断 + 短答案) 66.7%(收尾救回但仍输通才);废弃
intervcap1_step4000.pt (3.98 MB) 容量档一:蓝莓 + 每圈 128 虚拟 token + 秩 64,约 110 万参数 无增益(容量假设否定);废弃
intervblk6_step4000.pt (5.29 MB) 块化基线 6 块 × 2 圈 × 秩 16,约 132 万参数 MATH r1 23.3% / r2 25.0%(r2 首超 r1);废弃(基线)
intervcot1536_step6515.pt (5.29 MB) 块化 + cot_mix_v1 思维链语料 6515 步 MATH r1 31.7%(旧架构最佳单圈)/ r2 18.3%(第二圈失活);废弃
intervcot6ep_step26060.pt (5.29 MB) cot1536 续训 4 epoch(累计 5 epoch) r1 退化到 23.3%(过拟合反例);废弃
intervscore_step500.pt (5.29 MB) SCoRe R=2:train_score.py 的 REINFORCE,reward = 第二圈增量 r2 23.3%(微升);RL 路线废弃
intervr3_step6515.pt (7.93 MB) R=3 课程式:继承 cot1536 前 2 圈 + 新训第 3 圈,约 198 万参数 r3 25.0%(第三圈 gate 0.96 全开,但 r3 < 单圈 31.7%);废弃
intervscore_step100.pt (7.93 MB) SCoRe R=3:冻结前 2 圈只训第 3 圈,lr=1e-3 r3 崩到 0%;RL 第二次失败
intervgrpo_step5.pt (7.93 MB) GRPO R=3(reward = r3 是否优于 r2) 调试中断,80 步 reward 全 -1 未收敛;废弃

B. 新架构一:残差循环(主干只 forward 一次 + 低秩残差块堆叠,train_residual.py,W2 零初始化)

文件(大小) 结构 记录中的状态/成绩
intervres_step2000.pt (1.31 MB) 残差 R=2,秩 32,约 32.7 万参数 **MATH r2 50.0%**(对比纯主干/恒等第二圈 16.7%);注册表登记的最终点
intervres_step3000.pt (1.31 MB) 同一条线(tag=res)的另一个打点 注册表未单独登记(登记的是 step2000)
intervres3_step2000.pt (1.97 MB) 残差 R=3:继承 r2 前两圈 + 新训第 3 圈,约 49 万参数 MATH r3 45.0%;第三圈 CE 增量仅 -0.008~-0.017(第二圈 -0.68)⇒ 甜点 R=2
intervres3_best_step2000.pt (1.97 MB) 同上线的"最优快照"(脚本在早停时回滚保存 *_best_step*.pt) 与 intervres3_step2000 同点
intervres3c_step1500.pt / intervres3c_best_step500.pt (1.97 MB) R=3 重训版 实验记录.md:res3b 被 CE 早停阈值(1e-4 过敏感)误触发,修成 1e-3 + patience 8 后重训为 res3c,确认加第三圈无增益;注册表未单列
intervres3freeze_step2000.pt / intervres3freeze_best_step1000.pt (1.97 MB) 冻结实验:--freeze 1(冻结 t=1,只训 t=2) 坐实 r3 无增益的归因是"冻结主干在 t=1 残差后无可优化方向"(空间耗尽),而非抢梯度
intervresrank64_step1500.pt / intervresrank64_best_step1000.pt (2.62 MB) 同一架构把秩 32→64 重训 r2 46.67%(低于秩 32 的 50%),val_ce 1.17 高于 1.14 ⇒ 提容量无益
intervresblk6_step2000.pt / intervresblk6_best_step500.pt (0.99 MB) 分块残差:主干 forward 一次 + 中间层 6 块 × 秩 8 的 hook,约 24.6 万参数 r2 40.0%,val_ce 0.93 虚低但正确率低(CE 与正确率背离)⇒ 中间层干预无效

C. 新架构二:变换循环(每圈重新 forward 主干 + 满秩 Proj 圈间翻译 + 门控,train_residual.py --loop)

文件(大小) 结构 记录中的状态/成绩
intervloop2_step2000.pt (52.5 MB) 变换循环 R=2,满秩 Proj(2560×2560/圈 ×2)约 1310 万参数 MATH r2 46.67%(欠训版,曾被误判"未白嫖深度")
intervloop2x_step4000.pt (52.5 MB) 从 loop2 续训 4000 步(累计 6000 步 ≈ 2 epoch) **MATH r2 58.33%(35/60)+ 复验 55%(33/60),120 题综合 56.67%**,首次超过单层残差 50.0%
intervloop3_step6000.pt (78.7 MB) 变换循环 R=3 从头训 6000 步,约 1968 万参数 r3 50.0%,mean_len 589(R=2 为 480),第三圈 gate 掉到 0.34 ⇒ 甜点 R=2
intervloopblk2_step2000.pt (52.5 MB) 大小与 loop2 同档,属变换循环系列;文件名未出现在 实验记录.md / model_registry.md 中,无法从仓库内容确定其确切配置 未登记(推测为块化尝试,但无仓库内文字依据)
intervloopind2b_step2000.pt (54.5 MB) 变换循环 + 中间层分块 hook(附加 interv_loop 模块) r2 45.0%,无效(中间层干预 + 变换循环叠加无增益)
intervloopind2bx_step4000.pt (54.5 MB) loopind2b 续训 4000 步 r2 45.0% 持平,gate 失活到 0.104 ⇒ 非欠训、是失活
intervloopcur1_step2000.pt (53.5 MB) 大小与 loopcur2 同档,按命名属课程式变换循环一族;该文件名未出现在 实验记录.md / model_registry.md 中 未登记(记录里只有 cur2)
intervloopcur2_step2000.pt (53.5 MB) 课程式变换循环:先训 Proj 再解冻 3 层靠后 hook r2 48.33%(打平单层,mean_len 495);废弃
intervloopcur2x_step4000.pt (53.5 MB) loopcur2 续训 4000 步 r2 46.67%(降 1.66),gate 失活到 0.2 ⇒ 补训无效
intervvtok2_step2000.pt (52.7 MB) 变换循环 + 每圈 8 个输入端可学习虚拟 token(vtoken 约 4 万参数) r2 43.33%(26/60)/ mean_len 409 ⇒ 输入端软提示无效,且仍过早停止

scripts/:41 个脚本分组

训练(3 个)

  • train_interv.py(287 行):旧架构 R=2 训练。冻结主干 + 虚拟 token(默认每圈 64 个)+ 循环入口 FiLM(scale/shift)+ 逐层块化低秩加性修正(6 块 × 秩 16,W2 零初始化);损失 L = mean(各圈 CE) + lam * relu(CE_t - CE_{t-1} + margin);每 400 步做一次功能探针(各圈 CE、Δh 比率、top1 一致率、基座 CE 参照)。
  • train_residual.py(596 行,当前主线):四种模式合一——残差堆叠(默认)、--loop 真·变换循环、--n-blocks 分块残差、--vtok 虚拟 token;含 val_ce 早停、MATH 小样本早停(--eval-n,默认 8 题)、最优快照回滚。
  • train_score.py:REINFORCE 式 SCoRe 训练,冻结前 R-1 圈只更新最后一圈,outcome reward(末圈答对 +1 / 答错 -1)+ 滑动平均 baseline。

数据构造(8 个)

build_mix.py(50% GSM8K train / 30% fineweb-edu / 20% Ultra-FineWeb-zh → mix_v1.jsonl)、build_cot_data.py(NuminaMath + OpenThoughts + fineweb 按 4:4:2 包装成 Qwen3 chat+thinking 格式 → cot_mix_v1)、build_corr_data.py(用蓝莓 r2 的错误输出造纠错配对)、build_pollute.py(末步运算符翻转 / 答案转写扰动造污染纠错数据)、build_thinkv2.py(思维链截断到约 400 token + 30% GSM8K 短答案)、gen_distill.py(自蒸馏:主干开 thinking 生成 GSM8K 思维链,只留答对的)、gen_cached.py / gen_cached_v2.py(KV cache 版循环生成器,把 O(len²) 降到 O(len);v2 修了采样版索引 bug,加 temperature/top_p)。

评测(14 个)

eval_math500.py(位置参数 CKPT MODE_R N_PROBLEMS CAP TEMP TOP_P OFFSET,默认 60 题/cap512)、eval_math500_collect.py、eval_math500_base.py(纯主干基线,口径与前者一致)、eval_math500_samp.py(采样 + 自洽性多数投票,验证 greedy 是否低估循环)、eval_gsm8k.py、eval_aime.py(AIME 2024)、eval_cmmlu.py(选择题,关 thinking)、eval_loop.py / eval_residual.py(加载 loop / 残差 ckpt 跑 MATH 指定区间,默认 --offset 200 --n 20 或 --n 60)、eval_gen.py(GSM8K 前 60 题四臂:base / r1 / r2 / r2_zero)、eval_think.py(thinking on/off)、eval_cont.py(wikitext-2 CE + 续写定性)、eval_correct.py(纠错率 / 保持率)、eval_base_long.py(纯主干长链,用 caps 区分"真深度"与"长度换密度")、eval_dump.py、base_think.py、think_test.py。

探针 / 冒烟 / 运维(7 个)

probe_baseline.py(零干预循环坍缩基线:把 36 层当映射 M 反复施加)、probe_renorm.py(每轮重归一化范数,区分范数漂移与语义漂移)、probe_think.py、smoke_loop.py / smoke_loop_blk.py / smoke_blockwise.py(显存/梯度/不坍缩起点冒烟)、verify_freeze.py(验证冻结圈权重不变)、diag_r2.py / diag_r3.py(排查 r2 是"CE 训坏"还是"结构坍缩";采样 r3 排查 0 正样本)、accept.sh(验收三件套:GSM8K 公平评测 + wikitext CE + 引力面板)、cross_test.sh(数学/通用/通才三方主客场互测)、sweep_caps.sh(cap ∈ {64,128,256,1024} 的 token 效率曲线)、run_samp_after_base.sh(等某 PID 结束后自动跑采样评测)。

脚本用法(脚本内取证的真实命令)

所有脚本都把基座与数据写成绝对路径,例如 train_residual.py:12 → MODEL = '/root/autodl-tmp/models/Qwen/Qwen3-4B'、train_interv.py:15-18 → 数据在 /root/autodl-tmp/data/...、ckpt 输出到 CKPT_DIR = '/root/autodl-tmp/loop-exp/ckpt'、MATH = '/root/autodl-tmp/data/math500/test.jsonl'。直接跑之前必须改这些常量或建同名软链。

# 残差循环 R=2(默认值即线上配置:steps=2000, bs=2, lr=1e-3, rank=32, tag=res)
python scripts/train_residual.py --r 2 --rank 32 --tag res

# 变换循环(真深度):加 --loop;门控是每圈一个标量 loop_gate
python scripts/train_residual.py --loop --r 2 --rank 32 --tag loop2

# 变换循环续训(loop2x 即 --tag loop2x 从 loop2 的最终点继承,续训 4000 步)
python scripts/train_residual.py --loop --r 2 --rank 32 --tag loop2x \
    --init-ckpt <intervloop2_step2000.pt> --steps 4000

# 课程式变体:先只训 Proj/gate,再解冻靠后 hook(loopind/loopcur 系列用到)
python scripts/train_residual.py --loop --n-blocks 6 --rank 8 --freeze-interv --tag loopind2b
python scripts/train_residual.py --loop --n-blocks 6 --rank 8 --tag loopind2bx \
    --init-ckpt <intervloopind2b_step2000.pt> --steps 4000

# 分块残差 / 虚拟 token / R=3 继承 / 冻结实验
python scripts/train_residual.py --n-blocks 6 --rank 8 --tag resblk6
python scripts/train_residual.py --loop --vtok 8 --tag vtok2
python scripts/train_residual.py --r 3 --rank 32 --tag res3 --init-ckpt <intervres_step2000.pt>
python scripts/train_residual.py --r 3 --rank 32 --freeze 1 --tag res3freeze

# 旧架构 R=2 训练(虚拟 token 数/秩可用 --nvt/--rank 覆盖,默认 nvt=64, rank=16)
python scripts/train_interv.py --steps 7500 --bs 1 --lr 1e-3 --tag '' --data <gsm8k train parquet>

# 评测
python scripts/eval_residual.py <intervres_step2000.pt> --r 2 --n 60 --offset 200 --cap 1024 --rank 32
python scripts/eval_loop.py <intervloop2x_step4000.pt> --r 2 --n 20 --offset 200 --cap 1024
python scripts/eval_math500.py <ckpt.pt> 2 60 1024 - - 200   # 位置参数:ckpt r n cap temp top_p offset
python scripts/eval_math500_base.py base 1024 60              # 纯主干对照,提取器与上一致
python scripts/eval_aime.py --base                            # 或带 ckpt 跑 loop2x

关键超参(脚本内默认值):残差循环 --lr 1e-3 --weight-decay 0.01 --val-ratio 0.08 --ce-every 200 --eval-every 500 --eval-n 8 --patience 2,梯度裁剪 5.0;train_interv.py 用 --lr 1e-3、裁剪 5.0,损失里的 margin 默认 0.01、lam 1.0。

技术要点

  • 坍缩 vs 失活:作者先用 probe_baseline.py 证明"把 36 层反复施加"会结构性坍缩(第二圈恒等即 0%),再用残差堆叠(h_t = h_{t-1} + gate_t·W2_t·SiLU(W1_t·h_{t-1}),W2 零初始化保证恒等起点)解决它——这是本仓库第一个主线突破(r2 从 16.7% 到 50.0%)。
  • 欠训假说:变换循环的 Proj 是满秩 2560×2560(约 1310 万参数,是残差循环 32.7 万的约 40 倍),2000 步(约 0.67 epoch)只打平单层;续训到累计 6000 步后 r2 达 58.33%。
  • 干预加在哪是分水岭(作者结论):加在圈间(Proj + gate)有效;加在主干内部(中间层 hook)或输入端(虚拟 token)都失效——三个补训实验(loop2x 涨 11.66、loopcur2x 降 1.66、loopind2bx 持平)用于区分"欠训"与"失活"。
  • 长度换密度 + 真深度(作者四测试集复验结论):loop2x cap1024 前 30 题为 70%(mean_len 480),纯主干 cap8192 前 30 题为 60%(mean_len 4236);GSM8K 上 loop2x 72% 反输主干 98%,AIME2024 同分但顶帽率 10% vs 76.7%。作者定性为"无显著正确率优势,核心价值是压缩思考成本 + 消除顶帽短板"。
  • 失败的反例也被保留在仓库里:margin 反例、污染纠错、容量档、rank64、RL(SCoRe ×2 + GRPO)等,都与注册表里的"废弃/反例"标记对应。
  • 训练数据:mix_v1 记录为 14973 篇;cot_mix_v1 用于残差/变换循环,intervcot1536 记录为 6515 步 ≈ 260 万 token。

已知限制

  • 不是模型发行物:无 config/tokenizer/主干权重,不能 from_pretrained,也不能直接接 HF pipeline。
  • 许可为 Apache-2.0:仓库已随附 LICENSE 全文(原 README 的 front matter 亦声明 Apache License 2.0)。
  • 所有脚本硬编码绝对路径(/root/autodl-tmp/...、/root/loop-exp/...),且依赖不在仓库内的数据文件:math500/test.jsonl、gsm8k2/main/*.parquet、cot_mix_v1.jsonl、cmmlu_sample200.jsonl、aime2024.jsonl;数据构造脚本还依赖 NuminaMath / OpenThoughts / fineweb-edu / Ultra-FineWeb-zh 等外部语料,仓库未给出这些语料的版本或下载清单。
  • 成绩全部是作者自测,主要口径为 MATH-500 第 201~260 题(60 题)、cap1024、greedy,样本量小;model_registry.md 与 实验记录.md 对同一变体的早期数字口径不一致(例如 intervmix 的 GSM8K 数字),引用前需确认口径。
  • ckpt 与注册表不严格一一对应:intervres3c_*、intervres3freeze_*、intervloopcur1_step2000、intervloopblk2_step2000、intervres_step3000 未在注册表单列;intervgrpo_step5 是调试中断点。
  • .gitattributes 声明 *.pt 走 LFS,但仓库内当前 0 个 LFS 对象(.pt 是普通文件)——迁移到 HF 时需要自行决定 LFS 策略。
  • 参数量、gate 值、成绩均转引自作者记录,未在本仓库内重新复算。

未说明的信息:cot_mix_v1 等训练语料的样本量与 token 总量;各变体的训练时长/算力开销;除早期报告提到"AutoDL 魔改 4090 48G"以外的硬件环境;仓库的上传或最后更新时间;上传者的环境版本(torch/transformers 版本未记录)。

许可

  • 原 README 的 front matter 声明 license: Apache License 2.0,本卡片据此写 license: apache-2.0。
  • 仓库已随附 Apache-2.0 许可全文(根目录 LICENSE,11,343 字节,取自上游官方仓库原文,未作任何改动)。版权署名:Copyright 2026 我本是我沐。
  • 主干模型 Qwen/Qwen3-4B 的许可以其自身仓库为准(本仓库未再分发其权重)。

引用

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for tysgydke/Qwen3-4B-LoopIntervention

Finetuned
Qwen/Qwen3-4B
Finetuned
(1153)
this model