死锁是指多个进程或线程在分布式训练中相互等待对方释放资源,导致所有进程或线程都无法继续执行的状态。
系统响应缓慢,进程或线程挂起,系统资源利用率低,系统吞吐量下降,系统响应时间延长。
死锁的发生需要满足四个必要条件:互斥条件、请求并持有条件、不可剥夺条件、循环等待条件。
确保所有参与分布式训练的机器之间的网络连接正常,可通过ping命令测试机器之间的连通性。
使用工具如nvidia-smi观察GPU的使用率和内存占用,检查是否存在资源分配不均或资源耗尽的情况。
确保防火墙设置允许进程间通信,避免因防火墙限制导致进程之间的通信异常。
确保分布式环境的初始化放在程序的最开始阶段,所有进程在开始实际计算前已经建立了正确的通信渠道和同步机制。
确保所有进程在关键代码段前后添加适当的同步点,避免因进程间不同步导致死锁。
确保资源分配的顺序一致,避免因资源分配顺序不同导致循环等待。
增加详细的日志记录,特别是在进程初始化和模型加载阶段,便于问题定位。
使用如TORCH_DISTRIBUTED_DEBUG=DETAIL等调试工具获取更详细的调试信息,协助诊断分布式训练中的问题。
对每个被锁住的线程,记录其请求锁的时间戳以及获取锁的时间戳,定期检查是否存在请求时间戳比获取时间戳还要早的情况。
用于监控GPU的使用率和内存占用,协助判断是否存在资源瓶颈。
用于测试机器之间的网络连通性,确保网络连接正常。
用于检查和配置防火墙设置,确保进程间通信不受限制。
如TORCH_DISTRIBUTED_DEBUG=DETAIL,用于获取分布式训练中的详细调试信息。
如DeadLock,用于检测和监控死锁情况,协助快速定位问题。
用于分析日志文件,快速定位问题发生的位置和缘由。
用于构建和分析分布式资源分配图,检测是否存在循环依赖。
如Redisson、ZooKeeper等,提供分布式锁功能,减少死锁的发生。
用于定期检测节点是否存活,在节点宕机时,对其持有的锁进行回收操作,防止死锁。