训练复现实验:随机种子固定只是第一步
一、复现不是跑出差不多
机器学习实验经常说“结果可复现”,但很多时候只是固定了随机种子。真正复现需要代码、数据、环境、参数、硬件、依赖版本和评测脚本都可追踪。否则今天的结果,过两周可能没人能解释。
随机种子固定只是第一步,不是复现实验的全部。
二、先保存实验元数据
flowchart TD A[实验运行] --> B[代码版本] A --> C[数据版本] A --> D[参数配置] A --> E[环境依赖] A --> F[指标结果]每次实验都应该记录这些信息。缺任何一项,复现都会变成猜。
experiment_metadata: git_commit: required dataset_version: required config_hash: required docker_image: required seed: required配置也要 hash。否则参数文件被改了,实验记录却看不出来。
三、随机性来源很多
import random import numpy as np import torch random.seed(42) np.random.seed(42) torch.manual_seed(42) torch.cuda.manual_seed_all(42)除了 Python、NumPy、PyTorch,还要考虑 DataLoader worker、CUDA 算子、分布式训练顺序。某些操作天然非确定,强行 deterministic 可能降低性能。
复现实验要说明使用了哪些确定性设置,以及是否允许小范围波动。
四、数据版本要锁住
数据集如果每天更新,固定代码也复现不了。训练集、验证集、测试集都要有版本。预处理脚本也要版本化,因为同一份原始数据经过不同清洗规则会变成不同训练数据。
dataset_manifest: raw_data_hash: sha256:xxx preprocess_commit: abc123 split_seed: 42 train_size: 100000最好保存 split 文件,而不是只保存 split seed。因为数据顺序变化后,同一个 seed 也可能切出不同集合。
最后,复现要定期演练。随机挑一个历史实验,从记录里重新跑一遍,确认能得到接近结果。只有演练过,才能知道记录是否足够。
复现还要定义容忍范围。深度学习实验可能因为硬件、并行顺序和非确定算子产生轻微波动。报告里应写明主要指标允许的误差范围,而不是要求逐位相同。
reproduction_tolerance: accuracy_delta: 0.003 loss_delta: 0.01 speed_delta_percent: 5环境镜像也要保存。只保存 requirements 不够,因为系统库、CUDA、驱动和编译选项都会影响结果。Docker 镜像 digest 或 Conda lock 文件比自由文本说明可靠。
还要记录失败复现。复现失败并不是无效信息,它能暴露记录缺口、依赖漂移或代码不可重复。失败记录应该进入实验系统,而不是被悄悄删掉。
最后,复现任务最好由非原作者执行。原作者脑子里有隐含上下文,外部复现更能检验记录是否完整。
模型产物也要有固定存储位置。checkpoint、tokenizer、配置快照、评测输出和训练日志如果散落在不同机器上,复现时很容易只找到一部分。产物路径应写进实验记录,并且带上不可变版本号。
artifact_bundle: checkpoint: required tokenizer: required config_snapshot: required eval_outputs: required immutable_uri: true复现状态可以分级标记。例如exact表示指标在容忍范围内且日志一致,close表示主指标接近但速度或次要指标有差异,failed表示无法得到可比较结果。状态明确后,团队才知道哪些实验可以引用,哪些只能作为线索。
五、总结
训练复现实验要记录代码、数据、配置、环境、随机性来源和评测脚本,并定期演练历史实验。
随机种子固定只是第一步。复现能力来自完整证据链。