深度学习不同显卡跑出来的模型精度不一样
参考链接
一个由GPU型号不同导致模型掉点问题的排查过程TF32 vs FP32
https://blog.csdn.net/wohenibdxt/article/details/124542075
怪不得说深度学习是神学,本来在精度%1就很重要的情况下,发现3090和4090跑出来的结果是不一样的。。。。。。。。。。
参考:最靠谱的pytorch训练可复现性设置方案 https://zhuanlan.zhihu.com/p/629526120
一些发现-相同显卡跑出来是有办法一致的
服务器1:30904
服务器2:40903
服务器3:4090*4
只要随机种子一致,发现只是显卡影响精度,不是系统环境和设备,例如:
服务器1的3090每一张显卡每次跑出来的精度一致;
服务器2的4090每一张显卡每次跑出来的精度一致;
并且!:
服务器2和服务器3的4090每一张显卡每次跑出来的精度一致。
所以可以得出结论,其他条件一样的情况下,相同显卡跑出来的精度一致
2026-1-29记录 碰到最难搞的一次,服务器显卡一致,跑出来的精度居然不一致
这次是
CCE 4:40903 64核
CCE 5:40902 48核
CCE 6:4090*4 48核
申请的事情发生了,刚开始一直都是5=6,但4不一样,然后发现是dataloader有一个地方搞的鬼,就是这个num_workers没有固定,会造成精度不一致
data_loader = DataLoader(
dataset=ds_train,
sampler=sampler,
shuffle=(sampler is None),
batch_size=args.batch_size,
num_workers=args.num_workers,
pin_memory=True,
drop_last=True,
worker_init_fn=seed_worker,
generator=g,
)
解决完这个发现还是精度对不齐,偶然发现了model改为deit_small_distilled_patch16_224后是一致的,也就是上述解决了deit_small_distilled_patch16_224的精度一致问题,但是resnet50还是对不齐。
最后发现是这里搞的鬼:
if args.model == 'resnet50':
bdim = 2048
else:
freeze(body, 0)
bdim = 384
last_norm = nn.LayerNorm(bdim, elementwise_affine=False).cuda() if args.use_lastnorm else nn.Identity()
last_layer = nn.Sequential(last_norm, nn.Linear(bdim, args.emb), last)
last_layer.apply(_init_weights)
if args.model.startswith("vit") or args.model.startswith("deit"):
body.reset_classifier(0, args.pool)
else:
rm_head(body)
最后需要在这里把把线程锁死成单线程,不然线程数不同(64 核 vs 48 核)会导致结果微差
if args.model == 'resnet50':
bdim = 2048
else:
freeze(body, 0)
bdim = 384
#####################固定线程数#################################
import os # 用于设置 OpenMP / MKL / OpenBLAS 等线程环境变量
import random # Python 随机数
import numpy as np # NumPy 随机数
# ---- (1) 锁死 CPU 相关库线程数:尽量在调用任何线性代数/初始化函数之前设置 ----
os.environ["OMP_NUM_THREADS"] = "1" # OpenMP 线程数(很多底层库会用)
os.environ["MKL_NUM_THREADS"] = "1" # Intel MKL 线程数(如果用到 MKL)
os.environ["OPENBLAS_NUM_THREADS"] = "1" # OpenBLAS 线程数(如果用到 OpenBLAS)
os.environ["NUMEXPR_NUM_THREADS"] = "1" # numexpr 线程数(以防间接用到)
torch.set_num_threads(1) # PyTorch CPU 算子线程数
torch.set_num_interop_threads(1) # PyTorch 并行调度线程数(interop)
# ---- (2) 在 head 初始化前重新置随机种子:确保这里用到的随机数序列固定 ----
random.seed(args.seed) # 重置 Python random 的 RNG 状态
np.random.seed(args.seed) # 重置 NumPy 的 RNG 状态
torch.manual_seed(args.seed) # 重置 PyTorch CPU RNG 状态
#####################固定线程数#################################
last_norm = nn.LayerNorm(bdim, elementwise_affine=False).cuda() if args.use_lastnorm else nn.Identity()
last_layer = nn.Sequential(last_norm, nn.Linear(bdim, args.emb), last)
last_layer.apply(_init_weights)
本文来自博客园,作者:JaxonYe,转载请注明原文链接:https://www.cnblogs.com/yechangxin/articles/18596058
侵权必究
浙公网安备 33010602011771号