封面图

  • 日期:2026-09-23
  • 适合读者:研究生、科研新人和工程型研究者
  • 复现范围:整理 052–080 的证据索引,封装并重放 080 的报告实验;不重新训练模型。

摘要

一个月后,最容易丢失的往往不是代码,而是“这个数字究竟由哪次实验得到”。本轮从注意力、检索和训练方法走到解释性、校准与结果报告,最后需要留下能够再次运行、检查和质疑的研究资产。本文的目标很具体:把一份已有实验整理成自包含的小包,在两个空工作目录中重算报告,并主动修改代码、输入和环境记录,检查流程能否发现变化。成功标准是证据链清楚,而不是文件夹整齐。

目录

  1. 复现价值与本轮收获
  2. 核心思想与校验公式
  3. 官方代码阅读路线
  4. 最小实验与代码库结构
  5. 评测协议与实际结果
  6. 失败排查与证据边界
  7. 后续科研问题
  8. 总结与参考资料

一、复现价值与本轮收获

论文报告。 Pineau 等人在 JMLR 2021 总结了 NeurIPS 2019 的可复现性计划,包括代码提交、社区复现挑战和论文检查表。论文讨论的障碍不仅是代码缺失,还包括数据差异、训练说明不足、指标不明确、选择性报告和结论超出证据。[1] 因此,“仓库能启动”只是研究可检查性的一个条件。

本次实际验证。 扫描目录中的三位编号,052–080 共二十九篇,均保留通过记录。本次重新检查其元数据、中文字数、本地链接、图片文件与四十七个 Python 源文件的语法;历史运行和视觉验收记录予以保留,没有把全部模型重新跑一遍。完整导航见 研究代码库索引。

从这些文章可以提炼三类可复用资产。第一类是概念到实现的对应关系,例如注意力公式对应哪些张量变换;第二类是实验协议,例如检索候选、数据划分与拒答阈值如何确定;第三类是反证工具,例如消融、输入扰动和独立计数审计。代码库应保存三者之间的关系,而不只是收集训练脚本。

本轮的教学实验也有共同边界:小规模合成数据能帮助暴露接口和指标错误,却不能替代真实数据、官方模型及原论文预算下的复现。月度整理时,应优先把这些未验证项变成下一轮实验,而不是把文章状态“通过”解释成科学结论已经普遍成立。

二、核心思想与校验公式

本文把“实验包”定义为代码、配置、输入、环境记录和预期输出的集合。清单,即 manifest,是这些对象的目录与内容指纹;SHA-256 是把文件字节映射成固定长度摘要的算法,用来发现内容是否变化。

M={(pi,hi)}i=1K,hi=SHA256⁡(bytes⁡(pi)).M=\{(p_i,h_i)\}_{i=1}^{K},\qquad h_i=\operatorname{SHA256}(\operatorname{bytes}(p_i)).

这里 (p_i) 是包内相对路径,(h_i) 是保存的摘要,(K=5) 是本例载荷文件数。校验既比较摘要,也比较文件集合,因而缺失和意外新增文件都会被发现。哈希只说明字节是否与基线一致,不能证明标签正确,更不能证明作者诚实。

OA=F(C,D,θ,E,s),OB=F(C,D,θ,E,s).O_A=F(C,D,\theta,E,s),\qquad O_B=F(C,D,\theta,E,s).

(C) 是报告代码,(D) 是保存的实验摘要,(\theta) 是统计协议,(E) 是运行环境,(s) 是随机种子;(O_A,O_B) 是两个工作目录生成的结果。此处比较五个确定性输出的字节摘要,同时要求它们匹配事先从 080 保存的基线,而不是只检查两个新运行彼此相同。

输入分数的逻辑形状是 [3,5,4]:三个旧模型运行、五个扰动预算、四种攻击。它不是新训练的张量,也不是六十个独立种子。两个报告重放不增加模型实验的样本量,不能让原有误差线自动变窄。

三、官方代码阅读路线

先读 PyTorch 的 Reproducibility 文档:相同种子并不保证不同版本、平台或 CPU/GPU 之间结果完全一致。[2] 阅读时分别标记随机数来源、算子确定性和运行环境,避免把所有变化都归因于种子。

接着打开官方 torch/random.py。[3] 本次看到 manual_seed 委托给内部实现,后者为可用设备设置种子,并调用默认生成器;get_rng_state 返回的是 CPU 默认生成器状态。由此可以提出代码阅读问题:断点恢复保存了哪些生成器状态,数据加载顺序是否也恢复?记录一个整数种子并不能自动回答这些问题。

最后读 DVC 的阶段和锁文件说明。[4] cmd 描述执行命令,deps 描述输入依赖,outs 描述输出;dvc.lock 记录阶段状态与内容摘要。把脚本读取的外部文件漏在依赖列表之外,会让“输入没有变化”的判断失去依据。本文借用这种显式依赖思路,使用标准库实现一个更小的固定流程。

本次实际打开的是 PyTorch 文档显示的 2.14 页面和检索日 main 源码,二者不应被假定为同一提交;源码尚未固定 commit。DVC 也只进行了文档阅读。相关框架运行、版本兼容性与断点恢复实验均待人工核验。

四、最小实验与代码库结构

个人研究代码库重放流程

图中先校验输入,再分到两个工作目录,最后比较结果;分叉表示两份独立目录,代码按顺序执行。它不表示两台机器、容器隔离或并行加速。

从本篇目录执行,输出目录应为尚不存在的新路径:

python3 code/replay.py --out code/my_replay
PYTHONPYCACHEPREFIX=/tmp/081-pycache python3 -m py_compile code/replay.py code/capsule/report.py code/capsule/audit.py

仅需 Python 标准库,实际基线为 CPython 3.9.6。入口会核对解释器版本与实现;更换版本时应建立另一个经过审查的基线,而不是删除检查后仍声称相同环境。依赖和完整命令见 代码说明。

capsule/ 原样保存 080 的报告器、独立审计器,以及三个输入文件。capsule_manifest.json 保存这些文件的摘要、来源、随机种子和预期输出摘要。运行器使用当前解释器创建子进程,保留每条命令的标准输出、错误输出和结果;旧输出目录已存在时拒绝覆盖。

报告器内部的蒙特卡洛抽样固定种子为 80,运行器另将 Python 哈希种子设为 81。这里没有新增训练、数据抽样或模型下载。独立审计器不导入报告器函数,而是从整数失败计数和分数运算重新核对统计结果;它可以发现部分实现错误,但仍共享同一批上游资料。

个人库的公共层只负责运行身份、证据路径和验证结果,具体指标留在各实验中。比如检索召回率、拒答覆盖率和攻击成功率即使都是小数,也不能用一个含义模糊的 score 字段混合比较。附带的 研究卡模板 要求写清分母、方向、划分和结论范围。

五、评测协议与实际结果

本次检验的是保存摘要的可重放性。开始执行前,五个载荷摘要与五个确定性输出摘要均取自已有 080 文件。每份工作目录从载荷复制开始,没有预放结果;随后执行报告器和审计器,再与基线比较。

本次实际验证。 两个工作目录均成功处理六十条条件日志和二十个统计组;五个确定性输出分别是报告 JSON、穷举重采样列表、CSV 表、Markdown 表与审计 JSON。它们在两次重放之间、以及与 080 基线之间均字节一致。详细记录见 重放验收日志。

检查对象 判定规则 实际结果
输入与代码 文件集合及摘要一致 五个载荷通过
报告重算 两个新目录分别匹配旧基线 每次五个输出通过
计数与统计 独立审计重新计算 两次均通过
漂移样例 明确拒绝变化 七类均被发现

七类样例分别改变代码、配置、数据、文件缺失、额外文件、解释器版本记录和输出表。故障只注入临时副本,不修改原始实验。前三类通过追加字节模拟文件漂移,证明的是完整性检查会生效,不是所有语义错误都会被检测。

耗时日志整份保留,但不要求字节一致,因为真实运行时间会变化;其记录数、分数形状与 Python 版本仍被检查。这一排除规则在清单中事先写明,不能在看到差异后任意删除不喜欢的字段。

六、失败排查与证据边界

第一类失败是输入身份不明。文件名相同不代表内容相同,配置漏记默认值也会使两个“同名实验”实质不同。应先查载荷摘要和配置,再查结果,而不是直接调整容差让比较通过。若清单与文件同时被修改,本例不会认证其真实性;正式归档需要独立版本记录。

第二类失败是隐藏依赖。脚本从个人目录读取缓存、依赖当前工作路径,或复用旧结果,都可能产生虚假的重放成功。本例使用相对包路径并在新目录执行,但没有实施文件访问追踪或网络沙箱,因此不能声称证明了所有外部依赖都不存在。

第三类失败是同错一致。两次运行共享同一错误公式,仍会生成相同表格。因此需要原始计数、独立实现和人工语义检查。上游若存在标签错误或测试污染,本次摘要审计不能修复;它也没有重新核验逐样本预测和模型权重。

第四类失败是统计对象被替换。重放同一结果不是新的随机重复;跨设备差异也不等于方法效果差异。当前结论严格限于这台机器、这个解释器和这份载荷。跨操作系统、依赖升级、真实 GPU 训练、官方 benchmark 与区间覆盖率均未运行,待人工核验。

语法检查和 CPU smoke test 已通过。现有结果目录拒绝覆盖,便于保留失败证据;前置校验失败会直接打印错误,执行阶段失败则在新目录写入未完成状态。不要把失败记录清空后只留下最终成功运行。

七、后续科研问题

作者推断。 下一轮最有价值的问题,是这种记录方式能否帮助第三方定位复现差异。可以固定数据和代码,逐项改变解释器、数值库和硬件,预先定义预测误差容差,再比较变化发生在哪个阶段。当前的字节相等标准适合小型报告流程,不能未经论证就用于所有浮点训练结果。

还可以研究最小证据保存量:只有汇总指标、保存逐样本预测、再增加中间激活,分别能发现哪些故障?应先列出待检测的错误,再比较存储成本与检出能力。保存更多文件本身不保证更可靠,关键是能否反驳具体的错误解释。

对研究生而言,可以从索引中选一篇仍缺真实数据验证的实验,固定官方提交,补一组强基线与失败分析,形成新的研究卡。对初学者,先尝试改坏一个输入再观察错误信息,往往比同时安装许多实验管理工具更容易理解证据链。

八、总结

个人研究代码库应让每条结论都能回到来源、协议、输入和运行记录。本次留下二十九篇既有实验的导航,以及一个经过双目录重放和故障检查的小包。它证明了有限范围内的流程可检查性;后续科研的任务,是继续检验这些教学实验尚未覆盖的假设。

参考资料

检索日期:2026-09-23。以下一手页面与源码均已实际打开。在线文档与分支内容可能变化,未运行的版本兼容性待人工核验。

  1. Joelle Pineau, Philippe Vincent-Lamarre, Koustuv Sinha, Vincent Lariviere, Alina Beygelzimer, Florence d'Alche-Buc, Emily Fox, Hugo Larochelle. Improving Reproducibility in Machine Learning Research (A Report from the NeurIPS 2019 Reproducibility Program). JMLR 22(164):1–20, 2021:论文页面、正式 PDF。
  2. PyTorch Contributors. Reproducibility,页面显示 2.14;本次未安装或执行该框架版本。
  3. PyTorch Contributors. 官方 torch/random.py,检索日 main,未固定提交;用于阅读种子和生成器状态路径。
  4. DVC Contributors. dvc.yaml Files:Stages 与 dvc.lock,在线文档检索日版本;本次未执行 DVC。