以前代码debug一直用原始的pdb,方便好用。最近接触的代码框架使用了ddp加速训练,导致pdb不好用了。
具体来说,在ddp训练时,用单卡训练,跟非ddp模式是一致的,python -m pdb xxx.py的模式也能正常用pdb。但是常态训练需要用多卡分布式训练,执行命令时用非侵入式 python -m pdb xxx.py 的模式无效,好像只能使用侵入式的pdb调试方法,具体为在想要中断的程序行前预先添加
import pdb;
pdb.set_trace()
在实际使用中,这种方式确实能在多卡训练时使程序中断,但是在中断窗口不能正常键入字母。有时候是键盘按半天屏幕什么也不显示,有时候是根本没输入成功,直接将其他地方复制的长语句(比如某文件路径)粘过来也会变成乱七八糟的字母组合,根本无法正常用n,c,b等等正常用的pdb命令。由此,找到了remote pdb这个工具。
首先pip安装超时,去他们官网下载whl自己安,然后是几个简单使用后发现的特点。
1、官网提供了两种用例:
实际我在分布式训练使用时,发现第二种不太行。ddp训练GPU和节点数≥2,在设置断点的地方会同时占用两个端口,导致第二种写法中预先定义的一个端口被占用,无法分配给第二个节点(或者更多),报错。所以在ddp中,用第一种写法。
2、分布式训练时,如果用pdb调试,好像会根据预设的节点数量(也即GPU数量)出现同样多的调试终端窗口,在程序运行中,需要所有的节点的调试终端的都c或者n到指定位置,整个程序才会继续执行下去。
3、如果在程序的不同位置预先设置了remote-pdb断点,在程序进行到第一个断点时,主程序终端会给出与训练节点数量一致的连接地址和端口,
连进去之后就是显示程序停留在预设的断点位置。在所有终端操作完继续执行后,程序开始顺序执行一直到下个预设断点,这其中主程序原本的输出还是会打印在主终端窗口中,一直到运行到下一个断点,主终端会再次出现
当你去连接到这两个地址时,上面第一次的连接会自动关闭,好像被程序注销了一样。完成替代。
4、在主程序的正常执行过程中,代表断点的remote终端关闭并不会影响主程序的运行,但是当主程序执行到当前断点,你在其他终端连接到当前断点的remote 窗口,又手动关闭后,主程序会自动终止退出。