pycharm下,使用anaconda prompt命令行也是,深度学习训练突然结束,没有报错,没有进行到预期的迭代上限,但是相同的代码在linux上不会发生这种现象。结束信息:
进程已结束,退出代码为 -1073741571 (0xC00000FD)
在,控制面板\所有控制面板项\Windows 工具\事件查看器\Windows日志\应用程序,中的信息为:
错误应用程序名称: python.exe,版本: 3.12.3150.1013,时间戳: 0x663932f8
错误模块名称: ntdll.dll,版本: 10.0.22621.3733,时间戳: 0x67ca8829
异常代码: 0xc00000fd
错误偏移量: 0x000000000003c2f6
错误进程 ID: 0x0x71E4
错误应用程序启动时间: 0x0x1DAD054FFB3F4C7
错误应用程序路径: D:\env\anaconda3\envs\torch2.3\python.exe
错误模块路径: C:\WINDOWS\SYSTEM32\ntdll.dll
报告 ID: e34e812f-7fba-4b91-8b06-d9f4d0436c12
错误程序包全名:
错误程序包相对应用程序 ID:
环境:
PyCharm 2024.1 (Professional Edition)
版本 Windows 11 专业版
版本号 23H2
操作系统版本 22631.3810
# Name Version Build Channel
pytorch 2.3.1 py3.12_cuda12.1_cudnn8_0 pytorch
经过代码的重重排查,终于找到了问题代码块,但是还是不知道具体原因
源代码:
def train(epoch, dataloader, model, criterion, optimizer, scaler: GradScaler, logger):
losses = AverageMeter('Loss', ':.4f')
top1 = AverageMeter('Acc@1', ':6.2f')
top5 = AverageMeter('Acc@5', ':6.2f')
model.train()
end = time.time()
loss_list = torch.zeros(len(dataloader.dataset))
for i, (images, labels, index) in enumerate(dataloader):
images = images.cuda(non_blocking=True)
labels = labels.cuda(non_blocking=True)
optimizer.zero_grad()
# Forward + Backward + Optimize
with torch.autocast(device_type="cuda"):
_, _, logits = model(images)
loss = criterion(logits, labels)
for j in range(images.size(0)):
loss_list[index[j]] = loss[j]
loss = loss.mean()
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
acc1, acc5 = accuracy(logits.cpu(), labels.cpu(), topk=(1, 5))
batch_size = images.size(0)
top1.update(acc1[0], batch_size)
top5.update(acc5[0], batch_size)
losses.update(loss.item(), batch_size)
if (i + 1) % 50 == 0:
logger.info(f"Epoch[{epoch}][{i}/{len(dataloader)}] "
f"lr: {optimizer.param_groups[-1]['lr']: .5f}\t"
f"Loss {losses.val:.3f} ({losses.avg:.3f})\t"
f"Acc@1 {top1.val:.3f} ({top1.avg:.3f})\t"
f"Acc@5 {top5.val:.3f} ({top5.avg:.3f})\t")
logger.info(f'Train1 Summary '
f'Time cost {time.time() - end:.3f}s\t'
f'Loss {losses.avg:.3f}\t'
f'Acc@1 {top1.avg:.3f}\t'
f'Acc@5 {top5.avg:.3f}\t')
print(f'{epoch} end train')
return loss_list
loss_list = torch.zeros
改成loss_list = np.zeros
后解决了,如果收集的loss不需要梯度可以进一步改进:
for j in range(batch_size):
loss_list[index[j]] = loss[j].item()
给你两个参考链接:
https://www.cnblogs.com/joorey/p/11769426.html
https://stackoverflow.com/questions/7763959/what-is-unknown-software-exception-0xc00000fd-error-and-how-to-avoid-it
至于咋解决,我也不特别清楚。查阅是程序栈溢出导致的问题,也就是你深度学习在 Win 上跑的栈溢出了,你看看能不能设置你深度学习跑模型使用的栈大小,如果能设置的话,把改大应该就没问题了。
https://www.cnblogs.com/bean-boom/p/12439027.html
这个是我找到的设置 python 运行的栈大小的方法,你在跑模型的代码之前加上试试。
感谢回复,尝试了第三个链接的设置,以及更大的参数 sys.setrecursionlimit(999999999)还是没有解决问题。
如果是我,我可能会在工具版本上看看如何解决,或者用云平台使用相同的环境训练试试。
服务器和win的内存不一样差距太大,另外Python的版本换成64位的试试。个人经验是某段代码一直循环,导致内存使用一直在增加,可以重点关注,另外使用后台运行!使用后台运行!使用后台运行!不要在工具或命令行中调用
谢谢回复,win的内存为48G,运行时没有达到上限。python的版本已是64bits:
3.12.3 | packaged by Anaconda, Inc. | (main, May 6 2024, 19:42:21) [MSC v.1916 64 bit (AMD64)]
由于在linux上可以正常使用,因此应该不是我写的代码逻辑问题。
另外,我不了解不使用命令行的后台运行,您可否告知。
来自AI的回答:
错误代码 0xC00000FD
表示栈溢出。栈溢出通常发生在程序使用过多的栈内存时,导致系统无法分配足够的内存来支持程序的执行。这可能是由于递归调用过深,或者在堆栈中使用了大量的局部变量等原因导致的。
在您的情况下,错误的发生可能是因为您的代码在Windows系统中使用了过多的栈内存。这可能与深度学习模型的计算量和资源需求有关。由于同样的代码在Linux上没有问题,这可能是因为Linux系统和Windows系统在处理栈溢出问题上有所不同。
以下是一些可能的解决方案:
threading.stack_size()
函数来设置线程的栈大小。sys.setrecursionlimit()
函数来增加可递归调用的深度限制。我倒是觉得代码有问题,在某种情况下无限递归了,至于在linux上没有问题,那是因为依赖得库文件在win和linux都是尽量适配同样得功能,但是某些功能适配得行为不一定是一致得。