最近想做的工作和分布式的深度学习或者大模型训练有关。我想要实现某种方法对节点间的通信信息进行拦截。参照师兄的一些论文,了解了一些分布式的深度学习训练框架,我决定NCCL进行插桩。经过一些调研,我学习到了dlsym等函数的插桩方法,于是就去配置NCCL的环境,尝试写了一些测试程序对一些集合通信函数进行插桩,写一些简单的动态链接库文件。但是想要把这个运用到pytorch上的时候,发现一直不成功。这时候我才想起来pytorch在编译的时候是直接把NCCL库编译链接进去的,也就是嵌入了二进制代码而不是用的系统内配置的二进制环境,虽然可以考虑使用USE_SYSTEM_NCCL=1的方式指定自己的库,但是由于这个问题的产生我也意识到了,如果想在大规模集群配置这样比较个性化的环境,难度可想而知,不仅是开发难度很逆天,真正如果需要转化为一些能落地的成果(虽然不太可能哈哈哈)更上难度了。
这时候我就想,要不就去直接改pytorch内部的NCCL的源码,只是做插桩的话,似乎还可以,重新编译pytorch也只需要一遍并且用develop模式也方便开发,做好之后在管理节点创一个
Anaconda核。于是我尝试在本地主机上去修改和重新编译pytorch,然后就被这个编译给恶心到了,爆各种乱七八糟的错误,并且还慢的出奇,各种依赖错误,所以我就想,能不能不去重新编译pytorch,只是导入一个我开发包就能拦截信息。
所以为了绕开这个问题,我就想把插桩的逻辑更上一层,也就是在pytorch的distri的层面去做,不修改源码,使用猴子补丁!我大概了解了一些pytorch distribution的一些实现,发现其内部有封装好的一些集合通信,想必这些集合通信原语的实现也是依赖于nccl库,所以直接在不重新编译pytorch 的情况下进行插桩似乎也是可行的,因为这些函数的实现似乎没有像java项目里边那样非常清晰的权限定义,使得在外部也能非常轻松地进行修改函数指针的操作。