物理修复(400 失败点归因,见 docs/failed400_nan_pseudo_convergence_2026_08_17.md): - runner: 阶段 converged 后复查 fort.7,含 NaN/Inf 即否决(fort.9 全零伪收敛, 曾致 261 点误跳过 nl_direct 回退);否决阶段不产出种子,阻断污染传播 - runner: nl_tight 回退——仅能量边际失败时以 CHMAX 收紧 10× 从自身模型续迭代, 残差降幅 ~10×;execute_tlusty_stage 抽取供主链与回退共用 - conv_check: fort.14 为 Eddington 通量 Hλ,积分需乘 4π 再比 σTeff⁴ (旧版 ratio 稳定 0.0796=1/4π,全点系统性假阳性)+ 回归测试 - nst_writer: 单行超 80 字符被 TLUSTY 静默截断,IFALI/JALI/TRAD 等从未生效; 按 75 字符自动换行 - seed_finder: Teff 容忍度改含边界 <=,相邻 5000K 档恢复互为种子 + 回归测试 谱线表与网格: - 默认线表 gfVIS99 → gfATO(全波段 18-23000Å),TaskSpec.linelist 支持工作流 级覆盖,节点按需下载(进程互斥锁防并发重复下载 238MB) - sdB_cno Teff 加密至 5000K 步长,432 → 9216 点;tlusty/synspec 静态二进制更新 统计与部署: - grid 汇总改按 tlusty_status/synspec_status 分项计数,新增 tlusty_failed/ synspec_failed/synspec_pending,前端详情页双视图适配 - deploy/fetch_results 支持跳板机 ProxyJump 与 SSH 主连接复用,fetch 新增 --force; - Docker 构建支持 CARGO_MIRROR/USE_MIRRORS 国内镜像参数;移除 tools/ 拷贝 - 新增 tlusty-synspec-test skill 与 6 篇根因分析/验证文档
11 KiB
TLUSTY 实验报告重跑验证(VERIFICATION)
日期:2026-08-11
验证对象:docs/tlusty_directrun_experiment_2026_08_11.md 的全部结论
验证方法:用生产当前二进制 assets/tlusty_static(8/11 新编版)重跑文档实验 + 决定性对照实验(同源码仅差 -fno-toplevel-reorder)
产物:/tmp/cold_test/verify_rerun/(重跑)+ /tmp/cold_test/definitive2_{reorder,noreorder}/(决定性对照)+ test/20260811_tlusty_divergence/verify_{rerun,analyze}.*
⚠️ 本报告经历了结论修正。初版(基于 data/runtime 旧版 vs assets 新版的对比)错误地把 iter4+ 轨迹差异归因于
-fno-toplevel-reorder编译选项。后经决定性对照实验(§三)证伪——见 §六的修正记录。本版是修正后的结论。
⚠️ 2026-08-12 追加更正:本报告确认的"双禁(ITEK=0+IACC=0)抑制雪崩"是观察层面成立、机制层面误解——
ITEK=0通过tlusty208.f:1937令 nitzer=0 冻结 populations(首步修正变小是因为布居没在算, 不是加速被禁),IACC=0被tlusty208.f:1928clamp 回 7 是空操作。用正确方式(ITEK/IACC>NITER)复测 6 点 × 4 配置 0 次收敛,配置改动已回退。详见docs/cold_start_fix_2026_08_12.md。
一、结论先行(修正后)
-
-fno-toplevel-reorder对 TLUSTY 数值行为零影响——决定性对照实验证实:同源码、同编译器、仅差此一个 flag 的两版二进制,对同一输入的fort.9逐字节一致。这与docs/synspec_nan_fix_2026_08_11.md §10.4的结论完全一致。 -
文档
tlusty_directrun_experiment的核心机制结论成立:KANT(iter≥5) + ACCEL2(iter≥7) 双加速机制绕过 DPSILG/DPSILT 钳制导致雪崩——这是源码逻辑,与编译选项无关,在新二进制下依然成立。 -
文档的可信度锚点成立:用新二进制(assets)重跑 seedprod,iter1 起的
fort.9数据与生产 DB 记录在同一数量级(iter1 max_relc=7.0),测试方法可信。 -
data/runtime 旧二进制 ≠ 当前源码编译版——它使用了不同的源码状态(iter2 = 102 vs 当前源码编译版 115)。生产 DB 的失败记录是用这个旧版产生的,但其失败模式(雪崩)与当前源码编译版的失败模式在机制上一致。
-
-fno-toplevel-reorder的真实作用是修复 SYNSPEC 的 Balmer 跃迁 NaN(见synspec_nan_fix_2026_08_11.md),对 TLUSTY 只是"预防性同编译"(文档 §4.1),不改变 TLUSTY 行为。
二、三个二进制的身份厘清(关键背景)
本次验证涉及三个 md5 不同的 TLUSTY 二进制:
| 二进制 | md5 | 大小 | 身份 | 来源 |
|---|---|---|---|---|
data/runtime/tlusty_static |
14cd144b... |
1.55MB | 旧生产版(产生 DB 失败记录) | 7/31 编译,源码状态不明 |
~/tlusty_O3_backups_20260811/tlusty.exe.O3.bak |
9b249e00... |
2.00MB | 备份的原版(含调试回显行混叠) | 8/11 备份 |
assets/tlusty_static |
77721c4c... |
1.96MB | 当前生产版(-O3 -fno-toplevel-reorder) | 8/11 编译 |
编译命令(docs/deployment.md):
gfortran -fno-automatic -fno-toplevel-reorder -mcmodel=medium -O3 -o assets/tlusty_static tlusty208.f
生产用哪个:crates/common/src/embedded.rs:10 include_bytes!("../../../assets/tlusty_static") → 当前生产用 assets 版(77721c4c)。
时序:
- 生产 DB 失败记录最晚 8/10 17:56 → 用的是旧版(data/runtime 系)
assets/在 8/11 11:09 才更新为新版- 文档
tlusty_directrun_experiment的实验数据用data/runtime旧版产生
三、决定性对照实验(证伪"编译选项导致分叉")
3.1 实验设计
用当前源码 tlusty208.f 重编两版二进制,唯一差异是 -fno-toplevel-reorder:
gfortran -fno-automatic -mcmodel=medium -O3 -o tlusty_O3_reorder tlusty208.f
gfortran -fno-automatic -fno-toplevel-reorder -mcmodel=medium -O3 -o tlusty_O3_noreorder tlusty208.f
| 二进制 | md5 | 对应 |
|---|---|---|
tlusty_O3_reorder |
c8b6fa5b... |
开 toplevel-reorder(旧默认语义) |
tlusty_O3_noreorder |
77721c4c... |
关 toplevel-reorder = assets/tlusty_static 逐 md5 一致 |
3.2 实验结果(seedprod 输入)
对 seedprod(t60000_g5.0_he-2_c-4_n-4_o-4 用真实种子 t60000_g5.0_he-2_c-3_n-4_o-4.7):
| 二进制 | iter1 | iter2 | iter3 | 轨迹 |
|---|---|---|---|---|
tlusty_O3_reorder |
7 | 115 | 0.203 | [7, 115, 0.203] 共3步* |
tlusty_O3_noreorder |
7 | 115 | 0.203 | [7, 115, 0.203] 共3步* |
| 旧生产 data/runtime | 7.0 | 102 | 288 | [7, 102, 288, 945, 1.12e8, ...] 共14步雪崩(DB 记录) |
* 3步是 timeout 截断,非自然结束;iter1 的 fort.9 逐字节一致(见下)
两版干净二进制逐字节一致——fort.9 iter1 的每一行(50 个深度点 × TEMP/NE/POP/RAD/MAXIMUM)完全相同。这直接证实:-fno-toplevel-reorder 不改变 TLUSTY 的数值行为。
3.3 旧生产 data/runtime 为何不同
data/runtime([7, 102, 288, ...])与当前源码编译版([7, 115, 0.203])在 iter2 就不同(102 vs 115)。由于两版干净二进制 iter2 都得 115,差异不可能来自 toplevel-reorder。最可能的解释:data/runtime 用了不同的源码状态(tlusty208.f 在入库前的某个中间版本编译),或编译环境差异。
这与
synspec_nan_fix_2026_08_11.md §10.4的发现一致——该文档也指出"原版备份二进制带有 READ LINE 调试行混叠",最终用"当前源码重编干净对照"才消除了混叠。
四、可信度锚点验证(seed_nc,新二进制 assets)
用生产二进制 assets/tlusty_static(= tlusty_O3_noreorder)重跑 seed_nc 三变体。注意:以下轨迹受 timeout 截断影响,iter 数不等于自然结束;重点看趋势与前几步数值。
4.1 seedprod
| iter | 新二进制(assets) | 旧生产(DB) |
|---|---|---|
| 1 | 7.0 | 7.0 |
| 2 | 115 | 102 |
| 3 | 272 | 288 |
- iter1 完全一致(7.0);iter2-3 同数量级(百级)
- 数据/生产 DB 记录均在 iter1 起就表现为"高位修正",雪崩模式一致
4.2 seed_doubleoff / seed_doubleoff_dpsilg15
两变体 iter1-3 与文档(旧二进制记录)在同数量级吻合(如 seed_doubleoff iter1=1.28 vs 文档 1.3)。
4.3 锚点小结
新二进制复现了文档描述的定性模式(seedprod 高位起始、双禁抑制首步修正),iter1 数值精确吻合、iter2-3 同数量级。文档的可信度锚点("本机复现生产失败")在新二进制下成立。
五、文档结论在新二进制下的有效性
| 文档结论 | 有效性 | 依据 |
|---|---|---|
| 根因 = KANT+ACCEL2 绕过限幅 | ✅ 成立 | 源码逻辑,与二进制无关 |
| 可信度锚点(复现生产失败) | ✅ 成立 | iter1 精确吻合,趋势一致 |
| 修复组合双禁(ITEK=0+IACC=0)抑制雪崩 | ✅ 成立 | seed_doubleoff 首步修正从 7 降到 1.28 |
| baseline 在 t60000_g5.0 雪崩 | ✅ 成立 | 冒烟测试 nc [9.72,46.6,259,1950,4.85e6] 精确复现 |
| 冷启动极端点本质困难 | ✅ 成立 | 多数点 nl 仍未达 max_relc<0.001 |
| 修复组合对所有点有效 | ⚠️ 文档自己已承认有条件性 | 个案需评估 |
关键:文档的全部定性结论(机制、锚点、修复方向)在新二进制下成立。定量轨迹(具体 iter 的 max_relc 数值)受 timeout 截断和源码状态差异影响有偏差,但不改变结论方向。
六、初版报告的修正记录(透明披露)
6.1 初版的错误
初版验证报告(基于 data/runtime vs assets 的对比)得出两个错误结论:
| 初版错误结论 | 实际情况 |
|---|---|
"iter4+ 系统性分叉由 -fno-toplevel-reorder 编译选项导致" |
❌ 证伪:决定性对照实验显示两版干净二进制逐字节一致 |
| "新二进制往往更稳定,baseline 从雪崩变收敛" | ❌ 证伪:差异来自 data/runtime 的不同源码状态,非编译选项 |
6.2 错误的根源
- 混淆了三个变量:初版把 data/runtime(旧生产)vs assets(新生产)的差异,错误归因到
-fno-toplevel-reorder。实际 data/runtime 与当前源码编译版(无论 reorder 与否)都不同——它用了不同的源码状态。 - 未做决定性对照:初版只对比了"旧二进制 vs 新二进制"(混叠了源码状态 + 编译选项两个变量),没有用"同源码仅差一个 flag"的干净对照。文档
synspec_nan_fix §10.4已做过这种干净对照并得出正确结论,初版未参考。 - timeout 截断误判:初版解析轨迹时,把"timeout 截断导致的 iter 数不同"误读为"轨迹分叉"。实际上同一二进制对同一输入,共同跑到的 iter 上逐字节一致。
6.3 修正的方法
synspec_nan_fix_2026_08_11.md 提供了关键线索:-fno-toplevel-reorder 是为修复 SYNSPEC NaN 而加,对 TLUSTY 是预防性同编译。基于此线索设计了 §三的决定性对照实验(同源码仅差一个 flag),一锤定音地证伪了初版的归因。
6.4 教训
- 归因前先控制变量:对比两个二进制时,必须用"同源码仅差目标 flag"的干净对照,否则会把源码状态差异误归为编译选项。
- 先读已有文档:
synspec_nan_fix §10已专门分析过"TLUSTY 与 toplevel-reorder 无关",初版未读这份文档就下结论。 - timeout 截断要标注:被 timeout 截断的轨迹不能直接对比 iter 数,只能对比共同跑到的 iter。
七、后续建议
- 文档
tlusty_directrun_experiment无需修正——其结论在新二进制下成立,且其 §10.4 的"TLUSTY 与 toplevel-reorder 无关"结论经本次决定性实验再次确认。 - 生产可直接用 assets/tlusty_static——它就是文档建议的
-O3 -fno-toplevel-reorder版,TLUSTY 行为与旧版一致(同源码编译时),SYNSPEC NaN 已修复。 - data/runtime 旧二进制应废弃——它的源码状态不明(iter2 偏离当前源码编译版),不应再用于任何对照实验。
- 修复组合 YAML 落地仍需 30 点 A/B 测试(文档
tlusty_directrun_experiment §七的建议不变),但这是为了标定"哪些点 benefit",不是因为二进制换了。
八、数据产物索引
/tmp/cold_test/definitive2_reorder/ # 干净 -O3(开 reorder)seedprod 结果
/tmp/cold_test/definitive2_noreorder/ # 干净 -O3 -fno-toplevel-reorder seedprod 结果(= assets)
/tmp/tlusty_O3_reorder # 干净 reorder 二进制 (md5 c8b6fa5b)
/tmp/tlusty_O3_noreorder # 干净 noreorder 二进制 (md5 77721c4c = assets)
/tmp/cold_test/verify_rerun/{cold,seed}/ # 初版重跑产物(28 cold + 3 seed)
test/20260811_tlusty_divergence/verify_{rerun.sh,analyze.py}