5. PyTorch+NCCL源码编译

系列文章

  • 第1章 多机多卡运行nccl-tests 和channel获取
  • 第2章 多机多卡nccl-tests 对比分析
  • 第3章 使用tcpdump抓取rdma数据包
  • 第5章 PyTorch+NCCL源码编译

目录

  • 系列文章
  • 前言
  • 一、本地环境
  • 二、安装cudnn
  • 三、使用pytorch自带NCCL库进行编译安装
    • 1. 源码编译
    • 2. 查看版本和all_reduce测试
  • 四、 修改NCCL源代码并重新编译后测试,体现出源码更改


前言

从源码编译PyTorch和NCCL,可以实现对NCCL源码进行修改以适应特定需求,并应用于实际的分布式训练中,本文基于torch 2.2.1和nccl 2.19.3描述了一个大致过程,并验证了源码更改的有效性。


一、本地环境

  • Ubuntu 22.04.4 LTS (GNU/Linux 6.5.0-35-generic x86_64)
  • cuda 11.8+ cudnn 8
  • python 3.11
  • torch v2.2.1+ nccl v2.19.3
  • NVIDIA GeForce RTX 4090 *2

二、安装cudnn

下载cudnn包之后打开

cd cudnn-linux-x86_64-8.9.7.29_cuda11-archive
# 复制到指定目录
sudo cp ./include/cudnn*.h /usr/local/cuda/include
sudo cp ./lib/libcudnn* /usr/local/cuda/lib64

chmod a+r /usr/local/cuda/include/cudnn*.h
chmod a+r /usr/local/cuda/lib64/libcudnn*

确认已经安装cudnn,除了cudnn_version.h,务必检查同目录下也有cudnn_ops_infer.h文件

cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR -A 2

在这里插入图片描述
可以看到对应cudnn版本为8.9.7

三、使用pytorch自带NCCL库进行编译安装

1. 源码编译

使用 python setup.py 命令进行源码编译,develop 命令通常在开发过程中使用,以在"开发模式"中安装包,其中对源代码的更改会立即生效而无需重新安装。develop更改为install 就是直接安装。

# 新建conda虚拟环境,取名为nccl2
conda create -n nccl2 python=3.11
conda activate nccl2

#下载v2.2.1 源码
git clone --branch v2.2.1 --recursive https://github.com/pytorch/pytorch
cd pytorch      # v2.2.1 

# 安装依赖包
pip install -r requirements.txt

#以开发模式安装torch,不使用系统nccl,而是torch自带的,位于third party目录下 
MAX_JOBS=32 USE_CUDA=1 USE_NCCL=1 USE_SYSTEM_NCCL=0 python setup.py develop
  • 如下图所示即为开始编译:
    在这里插入图片描述
  • 中途报错如下:貌似是numpy相关的错误
  • pip show numpy | grep Version查看numpy 版本,为2.0.0
    在这里插入图片描述
  • 估计是numpy版本太新,导致一些变量名更改,=> 对numpy降级,实测1.26.3 可行, 之后make clean ,再重新编译在这里插入图片描述
  • 源码编译的过程可能比较久,编译成功后提示如下,说明已经成功安装torch
    在这里插入图片描述

2. 查看版本和all_reduce测试

编译完毕,测试能否用torch,cuda,nccl以及识别出GPU。这里新建了一个version.py

# version.py
import torch

print("torch version",torch.__version__)
print(torch.cuda.is_available(), torch.distributed.is_nccl_available())
print("nccl version:",torch.cuda.nccl.version())
print("cuda version:", torch.version.cuda)       
        
cudnn_version = torch.backends.cudnn.version()
print("cuDNN version:", cudnn_version)
print(torch.cuda.device_count(), torch.cuda.get_device_name(0))

结果如下,可以看到troch和nccl的版本,检测到双卡等。

在这里插入图片描述

执行以下代码,新建test.py, 使用 nccl 作为通信后端,在一个gpu上测试分布式训练中张量的 all_reduce 操作。

#test.py

import os
import torch
import torch.distributed as dist

os.environ['MASTER_ADDR'] = 'localhost'
os.environ['MASTER_PORT'] = '29500'
dist.init_process_group("nccl", rank=0, world_size=1)
x = torch.ones(6)

if torch.cuda.is_available():
    y = x.cuda()
    dist.all_reduce(y)
    print(f"cuda allreduce result: {y}")   

结果如下:

在这里插入图片描述

四、 修改NCCL源代码并重新编译后测试,体现出源码更改

修改 pytorch-2.2.1/third_party/nccl/nccl/src/collectives.cc 文件后,重新编译,

原代码如下,文件内包含了all_gather,all_reduce等各个集合通信操作,29行开始是All_Reduce的相关定义

/*************************************************************************
 * Copyright (c) 2015-2023, NVIDIA CORPORATION. All rights reserved.
 *
 * See LICENSE.txt for license information
 ************************************************************************/

#include "argcheck.h" // Need some checks here since we access comm
#include "collectives.h"
#include "enqueue.h"
#include "nccl.h"

NCCL_API(ncclResult_t, ncclAllGather, const void* sendbuff, void* recvbuff, size_t sendcount,
    ncclDataType_t datatype, ncclComm_t comm, cudaStream_t stream);
ncclResult_t ncclAllGather(const void* sendbuff, void* recvbuff, size_t sendcount,
    ncclDataType_t datatype, ncclComm_t comm, cudaStream_t stream) {
  // Just pass the size of one message and not the total bytes sent/received.
  constexpr nvtxPayloadSchemaEntry_t AllGatherSchema[] = {
    {0, NVTX_PAYLOAD_ENTRY_TYPE_SIZE, "Message size [bytes]"}
  };
  size_t msgsize = sendcount * ncclTypeSize(datatype);
  NVTX3_FUNC_WITH_PARAMS(AllGather, AllGatherSchema, msgsize)

  struct ncclInfo info = { ncclFuncAllGather, "AllGather",
    sendbuff, recvbuff, sendcount, datatype, ncclSum, 0, comm, stream, /* Args */
    ALLGATHER_CHUNKSTEPS, ALLGATHER_SLICESTEPS };
  return ncclEnqueueCheck(&info);
}

NCCL_API(ncclResult_t, ncclAllReduce, const void* sendbuff, void* recvbuff, size_t count,ncclDataType_t datatype, ncclRedOp_t op, ncclComm* comm, cudaStream_t stream);
ncclResult_t ncclAllReduce(const void* sendbuff, void* recvbuff, size_t count,ncclDataType_t datatype, ncclRedOp_t op, ncclComm* comm, cudaStream_t stream) 
{
  struct NvtxParamsAllReduce {
    size_t bytes;
    ncclRedOp_t op;
  };
  // Just pass the size of one message and not the total bytes sent/received.
  static constexpr nvtxPayloadSchemaEntry_t AllReduceSchema[] = {
    {0, NVTX_PAYLOAD_ENTRY_TYPE_SIZE, "Message size [bytes]"},
    {0, NVTX_PAYLOAD_ENTRY_NCCL_REDOP, "Reduction operation", nullptr, 0,
      offsetof(NvtxParamsAllReduce, op)}
  };
  NvtxParamsAllReduce payload{count * ncclTypeSize(datatype), op};
  NVTX3_FUNC_WITH_PARAMS(AllReduce, AllReduceSchema, payload)

  struct ncclInfo info = { ncclFuncAllReduce, "AllReduce",
    sendbuff, recvbuff, count, datatype, op, 0, comm, stream, /* Args */
    ALLREDUCE_CHUNKSTEPS, ALLREDUCE_SLICESTEPS };
  return ncclEnqueueCheck(&info);
}

修改ncclAllReduce函数, 将内部全部注释掉,加一句 return ncclSystemError;

NCCL_API(ncclResult_t, ncclAllReduce, const void* sendbuff, void* recvbuff, size_t count,ncclDataType_t datatype, ncclRedOp_t op, ncclComm* comm, cudaStream_t stream);

ncclResult_t ncclAllReduce(const void* sendbuff, void* recvbuff, size_t count,ncclDataType_t datatype, ncclRedOp_t op, ncclComm* comm, cudaStream_t stream) 
{
  // struct NvtxParamsAllReduce {
  //   size_t bytes;
  //   ncclRedOp_t op;
  // };
  // // Just pass the size of one message and not the total bytes sent/received.
  // static constexpr nvtxPayloadSchemaEntry_t AllReduceSchema[] = {
  //   {0, NVTX_PAYLOAD_ENTRY_TYPE_SIZE, "Message size [bytes]"},
  //   {0, NVTX_PAYLOAD_ENTRY_NCCL_REDOP, "Reduction operation", nullptr, 0,
  //     offsetof(NvtxParamsAllReduce, op)}
  // };
  // NvtxParamsAllReduce payload{count * ncclTypeSize(datatype), op};
  // NVTX3_FUNC_WITH_PARAMS(AllReduce, AllReduceSchema, payload)

  // struct ncclInfo info = { ncclFuncAllReduce, "AllReduce",
  //   sendbuff, recvbuff, count, datatype, op, 0, comm, stream, /* Args */
  //   ALLREDUCE_CHUNKSTEPS, ALLREDUCE_SLICESTEPS };
  // return ncclEnqueueCheck(&info);
  return ncclSystemError;
}

每次修改pytorch中nccl源码,要使之生效需要进行重新编译,先删除原有编译文件再重新编译

#删除原有nccl相关的
rm -r ./build/nccl*

#重新编译
MAX_JOBS=32 USE_CUDA=1 USE_NCCL=1 USE_SYSTEM_NCCL=0  python setup.py develop

#运行测试文件,看看有没有报错
python test.py

在这里插入图片描述

如图:报错ncclSystemError,体现出了源码的更改。
以后就可以按照这种方法修改nccl源码,使之与pytorch集成,将修改后的nccl应用于实际的分布式训练中了。

关于nccl源码及大致的总体流程,推荐一个大佬的文章,写的比较详细,令我受益匪浅。
https://blog.csdn.net/kidgin7439/category_11998768.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/749940.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Nature推荐的三种ChatGPT论文写作指令(含PDF下载)

1. 润色学术论文 ChatGPT学术润色指令: “I’m writing a paper on [topic]for a leading [discipline] academic journal. WhatItried to say in the following section is [specific point]. Please rephrase itfor clarity, coherence and conciseness, ensuri…

电脑系统重装怎么操作?分享四个win10重装系统方法

“我遇到了一些笔记本电脑的问题,别人告诉我解决这个问题需要重新安装Win10电脑系统。但我不记得我把光盘放在哪里了,我能否在不丢失文件的情况下重新安装操作系统?电脑系统重装怎么操作?”虽然电脑自带系统中有多种方法可供选择&…

嵌入式工程师从0开始,到底该学什么,怎么学

在开始前刚好我有一些资料,是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」, 点个关注在评论区回复“666”之后私信回复“666”,全部无偿共享给大家!!!嵌入式是个大筐&#xff0…

C++之STL(十二)

1、容器适配器 #include <iostream> #include <stack> #include <list> #include <queue> #include <functional> #include <iterator>using namespace std;int main() {// 栈&#xff08;先进后出filo&#xff09;stack<int, list<…

boss直聘招聘数据爬取及可视化分析2.0

boss直聘招聘数据爬取及可视化分析2.0 一、需求介绍二、完整代码2.1 爬虫代码2.2 数据可视化模块一、需求介绍 笔者在前两篇介绍boss直聘招聘数据爬取和可视化分析的博客的基础上,对代码和功能进行了完善。在数据爬取的模块,代码更加简洁易懂,且性能更加稳定;在数据可视化…

【AI大模型】Transformers大模型库(十四):Datasets Viewer

目录 一、引言 二、Datasets Viewer数据查看器 2.1 概述 2.2 示例 三、总结 一、引言 这里的Transformers指的是huggingface开发的大模型库&#xff0c;为huggingface上数以万计的预训练大模型提供预测、训练等服务。 &#x1f917; Transformers 提供了数以千计的预训练…

linux的安全技术和防火墙

一、安全技术 1.入侵检测系统&#xff1a;特点式不阻断网络访问&#xff0c;主要式提供报警和事后监督&#xff0c;不主动介入&#xff0c;默默的看着你&#xff08;相当于360安全卫士&#xff09; 2.入侵防御系统&#xff1a;透明模式工作&#xff0c;对数据包&#xff0c;网…

音频——性能测试中的基本概念

文章目录 频率响应平均电平增益ADC 路径增益DAC 路径增益底噪信噪比总谐波失真+噪声(THD+N)延迟频率响应 对于音频设备,频率响应可以理解为音频设备对不同频率信号的处理或重现。对于音频信号频率,一般关注20Hz~20kHz范围。理想情况下,输入幅度相同的不同频率信号,过音频…

springboot社区维修平台

设计技术&#xff1a; springboot、mysql、maven、前端vue 主要功能&#xff1a; 住户管理、社区公告管理、维修工管理、维修订单管理、接单信息管理、订单信息管理、在线沟通管理、举报信息管理、留言板管理、系统管理等功能模块。 管理员功能模块 管理员通过后台登录页面…

sessionStorage 能在多个标签页之间共享数据吗?

&#x1f9d1;‍&#x1f4bb; 写在开头 点赞 收藏 学会&#x1f923;&#x1f923;&#x1f923; 最近&#xff0c;我的一个朋友在面试中被一个关于 sessionStorage 的问题难住了。我们来聊聊这个话题。 sessionStorage 能在多个标签页之间共享数据吗&#xff1f; 在回答…

vscode刷LeetCode算法题环境配置

首先&#xff0c;下载nodejs 在vscode中安装LeetCode插件 安装好进行配置 选择leetcode-cn 填上刚才下载node.exe的路径 完成之后重启一下vscode 重启之后登陆LeetCode 完成之后就可以看到题目了 点击 code now 就可以开始刷题了

计算机网络之数据通信原理(下)

上一讲内容&#xff1a;数据传输方式、数据传输形式、传输差错处理、常用差错检测方法 数据通信过程中&#xff0c;一个很重要的问题就是如何控制数据的传输&#xff0c;就涉及到了传输控制规程&#xff08;协议&#xff09; 下面介绍两种&#xff1a; ①BSC&#xff1a;面向…

反向代购是怎么火起来的?今后的发展趋势如何?

反向代购和反向海淘的兴起可以归因于多个因素&#xff0c;这些因素共同推动了海外消费者对中国商品的需求和购买热潮。以下是对其火起来的原因的详细分析&#xff1a; 海外华人华侨的需求增加&#xff1a; 随着中国国际移民群体的扩大&#xff0c;海外华人华侨数量不断增多。这…

基于哈尔小波基的一维密度估计(Python)

先说点其他的东西。 关于强非线性、强间断、多物理场强耦合或高度复杂几何形态问题能够得以有效求解的核心难题之一&#xff0c;是如何构建在多尺度情形、非线性作用下具有准确地识别、定位、捕获以及分离各个尺度特征尤其是小尺度局部特征能力的数值工具&#xff0c;这之中包…

上海晋名室外危化品暂存柜成都项目落地

近日又有一台SAVEST室外危化品暂存柜项目成功验收交付使用。 用户单位是一家专注于兽用消毒剂原料和表面活性剂研发、生产的高新技术企业。用户在日常工作运营中涉及到危化品的室外安全储存问题。 3月底用户在寻找解决方案的过程中搜索到上海晋名的室外暂存柜系列后挺感兴趣的…

【Java Web】Vite构建前端目录结构

目录 一、Vite概述 二、Vite构建Vue3工程化项目 三、ViteVue3项目目录结构 四、ViteVue3项目组件&#xff08;SFC入门&#xff09; 五、ViteVue3样式导入方式 六、ViteVue3响应式数据和setup语法糖 一、Vite概述 Vite是一种新型前端构建工具,能够显著提升前端开发体验;Vite结合…

编码注入

Url&#xff1a;http://www.xxxxxxxx/newsdetail.php?idMjgxOA 判断参数Id存在数字型注入,试了报错注入不行&#xff0c;只能去盲注了 验证Poc1&#xff1a;idMTg4OS8x 等同于&#xff1a;id1889/1 poc2&#xff1a;idMTg4OS8w 等同于&#xff1a;id1889/0 /1 /0 用asci…

Redis-实战篇-实现商铺缓存与数据库的双写一致(超时剔除和主动更新)

文章目录 1、给查询商铺的缓存添加超时剔除和主动更新的策略2、根据id查询店铺2.1、queryById2.2、RedisConstants.java 3、根据id修改店铺3.1、ShopController.java3.2、update 1、给查询商铺的缓存添加超时剔除和主动更新的策略 修改ShopController中的业务逻辑&#xff0c;满…

Windows环境本地部署开源在线演示文稿应用PPTist并实现远程访问

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

维基百科:12种维基百科推广技术让你成为行业专家

维基百科&#xff08;Wikipedia&#xff09;作为全球最大的免费网络百科全书&#xff0c;已经成为人们获取知识的重要源泉之一。对于想要在特定领域成为行业专家的人来说&#xff0c;利用维基百科进行推广是一种非常有效的方式。本文将介绍12种维基百科推广技术&#xff0c;帮助…