Mac OS Metal(M4 Max)下PyTorch Lightning设置num_workers>0时无法终止
针对训练完成后程序挂起、必须Ctrl+C终止的问题,结合你的环境和代码,提供几个可行的解决思路:
关闭
persistent_workers参数
你的DataLoader设置了persistent_workers=True,这个参数会让worker进程在各epoch间保持活跃以提升速度,但在MPS(Apple Silicon GPU)环境下,可能存在进程回收的兼容性bug,导致训练结束后worker进程无法正常退出,进而卡住主程序。
修改方式:把DataLoader里的persistent_workers=True删掉或者改成False,再重新运行训练。调整
num_workers到合理范围
虽然官方教程用了14,但M4 Max是14核CPU,过多的worker会导致系统资源竞争,反而可能引发进程终止异常。建议把num_workers设为CPU核心数的一半(比如7)或者略低于核心数(比如10),平衡速度和稳定性。手动清理worker进程
在训练结束后,手动触发DataLoader的worker关闭逻辑,强制回收进程。在trainer.fit()之后添加以下代码:# 手动关闭训练和验证加载器的worker进程 if hasattr(train_loader, '_iterator'): train_loader._iterator._shutdown_workers() if hasattr(val_loader, '_iterator'): val_loader._iterator._shutdown_workers()检查版本兼容性
你使用的PyTorch 2.7.1和PyTorch Lightning 2.5.1可能存在版本适配问题,部分新版本组合在MPS环境下的多进程处理有bug。可以尝试降级PyTorch到2.6.x版本,或者升级PyTorch Lightning到最新稳定版(比如2.6.x),再测试是否解决问题。添加worker初始化函数
MacOS的多进程环境下,worker进程的随机种子可能引发冲突,导致进程无法正常终止。给DataLoader添加worker_init_fn,确保每个worker有独立的随机状态:def worker_init_fn(worker_id): import torch torch.manual_seed(torch.initial_seed() + worker_id) train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, num_workers=10, worker_init_fn=worker_init_fn) val_loader = DataLoader(val_dataset, batch_size=64, shuffle=False, num_workers=10, worker_init_fn=worker_init_fn)
内容的提问来源于stack exchange,提问作者Rangumi

