pytorch训练gan时需同时设置random、numpy、torch.manual_seed及torch.cuda.manual_seed_all四个种子,且须按序执行;还需禁用cudnn benchmark并启用deterministic,多线程下须通过worker_init_fn为各worker重设种子。

PyTorch训练GAN时随机种子不生效的典型表现
GAN训练中模型输出不稳定、相同代码两次运行loss曲线差异大、生成图像质量忽高忽低——这些往往不是模型结构问题,而是随机性未真正固定。尤其在多GPU或多线程环境下,torch.manual_seed() 单独调用几乎无效,因为CUDA运算、cuDNN后端、Python内置随机模块、NumPy等各自维护独立状态。
必须同时设置的4个种子位置
只设一个地方等于没设。以下四点缺一不可,且顺序不能颠倒(尤其cudnn.deterministic需在torch.cuda.is_available()之后立即设置):
import random; random.seed(42)import numpy as np; np.random.seed(42)-
torch.manual_seed(42)(CPU和默认GPU种子) -
torch.cuda.manual_seed_all(42)(多卡必须用all,单卡也建议统一写法)
注意:torch.cuda.manual_seed() 只影响当前默认device,多线程或DataParallel下易失效;torch.cuda.manual_seed_all() 才能覆盖所有可见GPU。
cudnn.deterministic = True 与 benchmark = False 的取舍
这是GAN训练中最容易被忽略的关键配置。cuDNN默认启用benchmark=True,会自动缓存并选择最快卷积算法,但不同输入尺寸/shape可能触发不同算法路径,导致结果不可复现。
- 必须加:
torch.backends.cudnn.deterministic = True(强制使用确定性算法) - 必须关:
torch.backends.cudnn.benchmark = False(禁用自动优化搜索)
副作用是训练速度下降5%–15%,但GAN对生成结果一致性要求远高于这点性能损失。若用Ampere架构GPU(如A100、RTX3090),还需额外加torch.backends.cudnn.allow_tf32 = False,否则FP32卷积仍可能引入非确定性。
多线程/多进程下额外要防的坑
Dataloader开启num_workers > 0时,每个worker是独立Python进程,其内部随机状态不会继承主进程种子。常见错误是只在main里设种子,却忘了worker_init_fn:
def worker_init_fn(worker_id):
np.random.seed(42 + worker_id)
random.seed(42 + worker_id)
torch.manual_seed(42 + worker_id)
dataloader = DataLoader(dataset, num_workers=4, worker_init_fn=worker_init_fn)
另外,如果用了torch.multiprocessing.spawn(如DDP启动),每个子进程都必须重新执行全部4项种子设置——不能只靠父进程传参。DDP模式下还建议显式设置torch.cuda.set_device(rank)后再调用cuda.manual_seed_all(),避免device索引错位。
真正麻烦的从来不是“设不设”,而是“在哪设、对谁设、设几遍”。GAN这类对随机敏感的模型,漏掉任意一层(比如worker、cuDNN、TF32),复现性就直接崩掉。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











