背景
最近一年实在是忙得焦头烂额,好久没更新了,最近被各种大模型和基础模型逼上了悬崖,既然打不过那就加入,不然会后悔。虽然之前有一些多任务模型的基础,但面对基础模型的开发,对于完全不同的设计和开发范式,刚开始就碰壁了,主要是关于DDP, torch版本以及多任务模型设计之间的兼容问题。
BUG历程
Bug1: RuntimeError: Output 0 of SliceBackward0 is a view and is being modified inplace. This view is the output of a function that returns multiple views. Such functions do not allow the output views to be modified inplace. You should replace the inplace operation by an out-of-place one.
解说:此bug诞生于DDP模式下,YOLOX解耦头解码计算loss这个过程。其问题主要还是在于torch 1.10本身的bug,这个bug在torch1.11之后被修复,1.9以及更低的版本也同样没有此bug。虽然网上大家的做法都是对于Output,clone一个新的变量,但这个做法在DDP模式下的YOLOX效果很差,学会导致学习过程放缓,具体原因不详,暂时没空去深究,我的建议是不要用torch 1.10。
Bug2: 模型内部组件报错,也就是nn.Module下的模型未使用的自定义模块报错。
解说:此bug问题还是跟DDP有关,
model_train = torch.nn.parallel.DistributedDataParallel(model_train, device_ids=[local_rank],
find_unused_parameters=True)
当我们令find_unused_parameters为True时,如果我们的torch版本为1.10以下的,由于我们的模型是多任务基础模型,那么一个epoch我们只会使用其中一个或几个任务头,还剩下一些任务头虽然已经被定义,但当前epoch是不会参与反向传播的,那么就会报错。解决方案为:将没有参与反向传播的任务头的输出 * 0并将ground-truth设置为0,让未参与反向传播的任务头执行伪正向传播+反向传播,但这么做的弊端是会增加显存占用。我建议的解决方案是使用torch 1.11及以上的版本,因为torch forum上官方说他们在1.10的版本里已经解决了这个bug,允许DDP模式下未参与反向传播的参数的存在,但Bug1中提到了1.10的问题,那么我建议使用1.11及以上的版本。
Bug3: Multiple GPU model getting RuntimeError: Caught RuntimeError in replica 0 on device 0
解说:用DDP,别用DP,当然前提是你的机子是linux的。Windows+DP模式下不会有这个问题,Windows选手不用担心。
Bug4: RuntimeError: CUDA error: device-side assert triggered, Assertion input_val >= zero && input_val <= one
failed.
解说:这是个常见的索引溢出问题,但索引溢出只是表面原因。常见的解决方案是检查类别数量和模型任务头的大小是否一致,以及在目标检测任务中,bounding box的范围是否在图像大小内。要么就是sqrt的参数小于0。如果你使用了YOLOX中的SimOTA算法,那么也有可能是学习率太大的原因,目前这个问题在官方仓库中仍然没有被解决,主流的方法是调小学习率。当然,也有同学的问题是由于用了混合精度训练。但是,如果你检查过不是上述原因了,而且这个Bug伴随着Bug5一块来,那么就不是这么简单了,请看Bug5的解决方案。
Bug5: torch.distributed.elastic.multiprocessiong.erroes.ChildFailedError
解说:此bug也是DDP模式下的一个多线程同步的问题, 此类问题的解决方案:1.查看安装的包是否与要求的一致。2.更改batch的大小。3.查看其中是否有某一个gpu被占用。4. 也有可能是用了混合精度训练导致的,很迷。
torch.distributed.elastic.multiprocessing.api.SignalException: Process 40121 got signal: 1
在pytorch的多GPU并行时,会有概率会出现以上的问题,当关闭会话窗口的时候,相应的并行程序也就终止了。
一种解决方法使用tmux,
tmux的使用方法:
Tmux的启动:tmux
带有名字的启动:tmux new -s 名称
退出:exit
分离会话:tmux detach
重新会话:tmux a -t 名称
Kill会话:tmux kill-session -t 名称
切换:tmux switch -t 名称
重命名:tmux rename-session -t 名称 名称1
至于为什么,可以了解一下报错的原因以及tmux的原理。文章来源:https://www.toymoban.com/news/detail-455307.html
Bug6: 使用混合精度+YOLOX的SimOTA或YOLOv8的TaskAssigner做正样本匹配时loss为nan
解说:使用梯度截断来解决此问题。文章来源地址https://www.toymoban.com/news/detail-455307.html
scaler.scale(loss_value).backward()
scaler.unscale_(optimizer) # unscale gradients
torch.nn.utils.clip_grad_norm_(model_train.parameters(), max_norm=10.0)
scaler.step(optimizer)
scaler.update()
Bug7: 希望别再有了,
到了这里,关于记多任务基础模型的常见bug和debug历程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!