一、起因经过
组上叫对比一下用相同的数据训练测试一下yolov10与yolov8各模型的实际情况,一边学习论文,一边安装环境准备跑一下v10的训练。
虽然提前知道v10是基于v8的某个版本改的,但是运行v10版本时弹出的v8版本号(如图8.1.34)还是有点难绷(有玩v7的时候弹v5版本号内味儿了),甚至运行时还会提示叫你升级v8版本🤣
单卡不报错能直接跑起来,用多卡训练时,DDP报错:
如果你的报错跟我差不多都是DDP命令行显示运行的文件为_temp_开头的临时文件以及报找不到module的错,那你可以往下看了。
二、原因及解决办法
1.原因是我今日下载下来的v10的代码中使用的还是v8.1.34版本的代码,其开启DDP时的创建ddp命令的类为:可以看到,它在代码中的file时直接生成一个临时的py文件用于分布式训练,位置根据不同的系统放在不同的用户配置文件夹下,linux的会放在如下位置,以及文件内容大概为:
问题在于你在这索引包,那指定是索引不到,所以会DDP运行失败进而报找不到包的错,改的方法无非就是 ① 让其能索引到包或者 ② 运行DDP命令时不使用临时生成的py文件。
2.解决办法
①思路就是改一下generate_ddp_file中预先指定生成py文件的内容,import sys添加指定路径之类的,但是我没用这个方法,这个方法遇到项目路径更改的时候还得去改,不够优雅(我也学会这个词了逮着就用)。
②既然不想指定DDP命令运行时的py文件为临时生成的文件,那就指定固定的py文件(官方的训练指导也叫创建py文件训练,你习惯用命令行那我帮不了你兄弟,可能之前生成临时文件就是为命令行训练服务的,有问题请自强),文件大差不差如下:
然后就是修改ultralytics/utils/dist.py下的generate_ddp_command类,直接参考之前我用的v8版本里的类(它就会直接DDP运行上面创建的py文件),改动如下:
先在dist.py下添加:
import re
from pathlib import Path
我确认了官方指定的python3.9下这样import没问题,别的版本请自行去确认。
然后把generate_ddp_command改成如下(复制粘贴就完事了):
def generate_ddp_command(world_size, trainer):
"""Generates and returns command for distributed training."""
import __main__ # noqa local import to avoid https://github.com/Lightning-AI/lightning/issues/15218
if not trainer.resume:
shutil.rmtree(trainer.save_dir) # remove the save_dir
file = str(Path(sys.argv[0]).resolve())
safe_pattern = re.compile(r'^[a-zA-Z0-9_. /\\-]{1,128}$') # allowed characters and maximum of 100 characters
if not (safe_pattern.match(file) and Path(file).exists() and file.endswith('.py')): # using CLI
file = generate_ddp_file(trainer)
dist_cmd = "torch.distributed.run" if TORCH_1_9 else "torch.distributed.launch"
port = find_free_network_port()
cmd = [sys.executable, "-m", dist_cmd, "--nproc_per_node", f"{world_size}", "--master_port", f"{port}", file]
return cmd, file
问题解决,DDP显示运行启动训练的py文件,训练正常进行:
如果你的问题解决了,麻烦点个免费的小赞鼓励一下分享精神,谢谢~