深度学习实验中,同一份代码换台机器就得出不同结果,是开发者常见的工程问题。即使使用相同的GPU算力平台,随机初始化、数据顺序、软件版本和CUDA算子差异,也可能让指标发生偏移。本文以PyTorch为例,建立一套从环境记录到结果复核的可复现流程。
一、问题背景
可复现不等于每次结果绝对一致,而是让实验条件可追溯、差异可解释。科研训练常见问题包括:只保存模型权重,没有记录数据版本;升级依赖后旧代码无法运行;重新启动大模型训练时忘记原始超参数;从训练转向推理部署后,预处理逻辑发生变化。
选择GPU服务器租用可以快速获得算力,但云端实例也会被重建或迁移。项目不能依赖"当前机器刚好能跑",而要把环境、代码、数据和配置一起固化。
二、环境准备
准备Linux、Python、CUDA、PyTorch、Git以及独立项目目录。先记录基础信息:
bash
nvidia-smi > environment.txt
python --version >> environment.txt
pip freeze > requirements-lock.txt
git rev-parse HEAD > commit.txt
润云智算提供Python 3.12 + CUDA 12.8开发镜像,包含Ubuntu 24.04、JupyterLab和SSH,并支持安装PyTorch、JAX等框架。可通过官网查看当前GPU云服务器和镜像资源。
三、实操步骤
步骤1:统一随机种子
python
import os, random, numpy as np, torch
seed = 2026
os.environ["PYTHONHASHSEED"] = str(seed)
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
若DataLoader启用了多进程,还要为Worker设置种子,避免数据增强在不同运行中漂移。
步骤2:控制CUDA确定性
python
torch.backends.cudnn.benchmark = False
torch.backends.cudnn.deterministic = True
torch.use_deterministic_algorithms(True)
确定性算法可能降低速度,个别算子也可能不支持。建议在基准复现实验中开启,在追求吞吐的正式训练中根据误差容忍度决定。
步骤3:把参数移出代码
使用YAML保存模型、数据和训练参数:
yaml
seed: 2026
batch_size: 16
learning_rate: 0.0001
epochs: 20
dataset_version: v3
每次运行都把配置复制到独立输出目录,不要只修改脚本中的常量。模型微调尤其要记录基座模型、数据版本、LoRA参数和精度设置。
步骤4:保存完整检查点
python
torch.save({
"model": model.state_dict(),
"optimizer": optimizer.state_dict(),
"epoch": epoch,
"config": config,
"seed": seed
}, "runs/exp01/latest.pt")
若需要断点恢复,还应保存学习率调度器和全局步数。文件名可加入实验编号,不要用多个含义不明的final.pt。
步骤5:执行最小复核
训练结束后,在全新虚拟环境中安装锁定依赖,拉取对应Git提交,加载相同验证集并再次计算指标。若结果不同,依次比较配置、数据哈希、预处理、GPU型号和框架版本。迁移到其他AI算力平台时,也应先运行相同的小规模样本,而不是直接开始完整任务。
四、常见问题
1. 设置种子后结果仍不同
检查多进程数据加载、非确定性算子、数据文件顺序和第三方库随机源。多GPU通信也可能带来微小数值差异。
2. 锁定依赖后无法安装
完整pip freeze可能包含与系统绑定的包。可同时维护一份核心依赖清单,并保留原环境快照用于排查。
3. 更换GPU会影响结果吗
不同架构、计算精度和底层库可能造成浮点差异,应关注指标容差,而不是要求每一位小数完全相同。
4. 只保存Notebook够不够
不够。Notebook还依赖外部数据、包版本和执行顺序,关键实验应整理成脚本并保存配置。
五、总结
实验可复现需要同时管理随机性、依赖、代码、数据、参数和检查点。规范归档能减少重复调试,也方便从深度学习验证过渡到生产服务。润云智算提供按需GPU资源和开发镜像,可支持科研实验、大模型训练与推理部署;无论使用哪种环境,都应让每次实验具备清晰的版本证据。
FAQ
Q1:所有任务都要开启确定性算法吗?
不一定。基准验证建议开启,性能训练可根据速度和误差要求选择。
Q2:数据版本怎么记录?
可记录目录清单、文件哈希或数据集版本号,并将生成方式写入说明文件。
Q3:Checkpoint需要保存哪些内容?
至少包括模型、优化器、Epoch和配置;续训时再保存调度器与全局步数。
Q4:如何比较不同GPU实例?
固定代码、依赖、数据和随机种子,再比较耗时、显存和指标差异。