找回密码
 会员注册
查看: 37|回复: 0

DEBUG报错RuntimeErrorTryingtoresizestoragethatisnotresizable解决思路分享

[复制链接]

6

主题

0

回帖

19

积分

新手上路

积分
19
发表于 2024-9-3 13:23:24 | 显示全部楼层 |阅读模式
【DEBUG】报错RuntimeError:Tryingtoresizestoragethatisnotresizable解决思路分享问题来源解决方式DDP:DDP&DP问题来源问题跟这个博主的类似RuntimeError:Tryingtoresizestoragethatisnotresizable我认为原因是你dataloader当中存在数据shape大小不一致。比如假设你datasetgetitem写好了返回一个tensor。假设shape是(100,100),那么报错的原因就是存在一种情况你的getitem返回了一个shape不是(100,100)而是另一个不同形状的的tensor。这个时候pytorch没法拼接成[B,C,X,…]Batch大小的tensor用于后续训练。(假设你是batch是1,应该就会在训练的时候报错)解决方式(省流)最高效的办法是重新读入一遍dataloader,人为的iter一遍,检查形状不一致的情况;需要说明的是,这个问题不是你dataloaderreturn数据有问题,而是你数据的形状有问题,所以应该是要假定return出来的数据是不是你预想中的大小。(这是我踩完坑觉得最高效的方法,请一定首先检查是不是形状的问题,再考虑是不是num_worker跟gpu数量对不上的问题)下面是我自己具体分析这个问题的过程,权供网友们参考。在分析之前,包含了以下的知识点:ddp装饰显示error自定义collate_function打印错误使用pdb分析我首先想到的就是在主进程中debug,因为可能dataloader加载的方式很复杂,写的很臃肿(比如我),或者定位不到问题(写成了ddp),下面单独说下ddp情况要先加什么代码:DDP:#Pytorchddp由于多卡的问题,不能把errortracelace打印出来,这样就不知道具体的报错#第一步就是把你的整个训练代码写在main()函数下面#第二步是用record这个函数装饰一下main()fromtorch.distributed.elastic.multiprocessing.errorsimportrecord@recorddefmain(): #把你的代码放进来 pass1234567891011这样你运行torchdistributedlanch就会具体报错,报的还是RuntimeError:Tryingtoresizestoragethatisnotresizable.DDP&DPPytorchDataloader有一个很大的问题就是在vscode里面打不了断点,不方便debug。下面首先就是怎么定位到有问题的地方,既然是collatefunction报错,那么我们就自定义一个进去找问题fromtorch.utils.data._utils.collateimportdefault_collatedefcustom_collate_fn(batch):try:returndefault_collate(batch)exceptRuntimeErrorase:print(f"Collateerror:{e}")#Handletheerrororskipthebatchforiter,itemsinenumerate(batch): foriteminitems: print(item.shape)returnNone123456789101112这个时候,运行完程序,应该就会有一个报错,然后有具体的shape,应该就能明白问题了。假如还不够清晰,可以加一个assert或者ifelse来进一步确认,我肉眼一个一个比对看到了问题。下一步是找到具体是哪一个dataload进来有问题,确认我是全部的data设置有问题还是只是单个的,很直觉的想法就是找到对应的dataset在dataloader过程中究竟是哪一个idx报错。方法也很简单,用pdbset一个breakpoint然后手动debug一下就可以。fromtorch.utils.data._utils.collateimportdefault_collatedefcustom_collate_fn(batch):try:returndefault_collate(batch)exceptRuntimeErrorase: breakpoint()#手动设置一个breakpointprint(f"Collateerror:{e}")#Handletheerrororskipthebatchforiter,itemsinenumerate(batch): foriteminitems: print(item.shape)returnNone#Dataloader这里也要详细设置一下,把num_worker置0,让程序在主进程运行your_loader=DataLoader(...,num_workers=0,...)123456789101112131415161718假设文件名是main.pypythonmain.py1运行的时候,报错就会进入pdb,要简单了解的话可以参考这个b站视频码农高天-10分钟入门pdb,但其实思路还是比较简单的,总体上记住s代表step,where代表运行到哪里,u代表上溯,d代表下溯,想看什么变量直接打变量名就行。经过这样一番debug后,我也是确认了idx的具体值,然后进入dataloader单独验证发现了问题,并修复。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-27 13:33 , Processed in 0.420291 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表