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/lib64chmod 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 torchprint("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.pyimport os
import torch
import torch.distributed as distos.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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习】机器学习重要方法——迁移学习:理论、方法与实践

文章目录 迁移学习:理论、方法与实践引言第一章 迁移学习的基本概念1.1 什么是迁移学习1.2 迁移学习的类型1.3 迁移学习的优势 第二章 迁移学习的核心方法2.1 特征重用(Feature Reuse)2.2 微调(Fine-Tuning)2.3 领域适…

【启明智显分享】典型的HMI应用实现方案:帮你更好地主控选型!

HMI是操作者与机器/系统间资讯传递和交换的主要桥梁。HMI系统通常能提供丰富的资讯,例如温度、压力、制造流程步骤以及材料的计量数据。还能显示设备中物料的确切位置或储存槽内的液位数据等讯息。无论是在工业自动化还是医疗、商业等重要行业领域,HMI都…

【前端项目笔记】6 参数管理

参数管理 效果展示: 在开发功能之前先创建分支goods_params cls 清空终端 git branch 查看所有分支 git checkout -b goods_params 新建分支goods_params git push -u origin goods_params 把本地的新分支推送到云端origin并命名为goods_params 参数管理需要维…

一个易于使用、与Android系统良好整合的多合一游戏模拟器

大家好,今天给大家分享的是一个易于使用、与Android系统良好整合的多合一游戏模拟器 Lemuroid。 Lemuroid 是一个专为Android平台设计的开源游戏模拟器项目,它基于强大的Libretro框架,旨在提供广泛的兼容性和卓越的用户体验。 项目介绍 Lem…

如何安装多版本CUDA?

首先聊一个题外话:前几天在csdn上看到的一个话题”安装pytorch一定要去nvidia官网下载安装cuda和cudnn吗?“ 我相信任何一个刚开始接触或者从事深度学习的炼丹者都会从安装cuda开始,现在网上随便一搜如何安装pytorch,蹦出来教程提…

pd虚拟机 Parallels Desktop 19 for Mac 破解版小白安装使用指南

Parallels Desktop 19 for Mac 乃是一款适配于 Mac 的虚拟化软件。它能让您在 Mac 计算机上同时运行多个操作系统。您可借此创建虚拟机,并于其中装设不同的操作系统,如 Windows、Linux 或 macOS。使用 Parallels Desktop 19 mac 版时,您可在 …

无线麦克风推荐哪些品牌,一文揭秘无线麦克风领夹哪个牌子好!

​究竟该如何选择麦克风呢?又该如何挑选无线麦克呢?询问我关于麦克风选择问题的人着实不少。对于那些仅仅是想要简单地自我娱乐的朋友而言,着实没必要去折腾,直接使用手机自带的麦克风便可以了。 但若是处于想要直播、拍摄短视频…

【Termius】详细说明MacOS中的SSH的客户端利器Termius

希望文章能给到你启发和灵感~ 如果觉得有帮助的话,点赞+关注+收藏支持一下博主哦~ 阅读指南 开篇说明一、基础环境说明1.1 硬件环境1.2 软件环境二、软件的安装2.1 Termius界面介绍2.1.1 Hosts 主机列表2.1.2 SFTP 文件传输2.1.3 Port ForWarding 端口转发2.1.4 Snippets 片…

为什么带货主播,他突然就不吃香了?

为什么带货主播他突然就不吃香了?工资骤降50%。 相比 2023 年初主播的平均薪资降了50%,那不管你是头部主播还是腰部主播,全部都降薪了。那尾部主播就更不用说了,有的主播他的时薪已经低到 20 块钱一个小时,还不如大学…

U-boot相关基础知识

U-boot和Bootloader之间的关系 U-Boot是Bootloader的一种实现,它专门用于嵌入式系统,特别是那些基于ARM、MIPS等处理器的系统。U-Boot提供了丰富的硬件支持和功能,使得开发者能够轻松地初始化硬件、加载操作系统内核,并进行一些基…

【漏洞复现】安美数字酒店宽带运营系统——命令执行漏洞(CNVD-2021-37784)

声明:本文档或演示材料仅供教育和教学目的使用,任何个人或组织使用本文档中的信息进行非法活动,均与本文档的作者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 安美数字酒店宽带运营系统 server_ping.php 存在远程命令执行漏洞&#…

一文带你了解什么是【点击劫持】

点击劫持,意思就是你点击网页的时候,有人劫持你,对没错,劫持你的信息,甚至劫持你的马内,劫持你的理想,劫持你的肉体,劫持你的灵魂。就是这么可怕。 目录 1 如何实现假网站 1.1 if…

“未来独角兽” | 安全狗入选福建省数字经济核心产业创新企业名单

近日,福建省数据管理局公布了入选2024年度全省数字经济核心产业创新企业名单。 作为国内云原生安全领导厂商,安全狗凭借自身在云安全领域的卓越表现和创新实力入选,获得“未来独角兽”称号。 据悉,此次对“未来独角兽”的评选条件…

计算机视觉(CV)技术:优势、挑战与前景

摘要 计算机视觉作为人工智能的关键领域之一,正迅速改变我们的生活和工作方式。本文将探讨CV技术的主要优势、面临的挑战以及未来的发展方向。 关键词 计算机视觉, 人工智能, 数据处理, 自动化, 伦理问题 目录 引言计算机视觉技术的优势计算机视觉技术的挑战实…

内网穿透小工具

内网穿透小工具 前言 当在本地或者虚拟机,内网搭建了项目,数据库。可是在外网无法访问。下面的两款小工具可以暂时实现内网穿透能力。(不支持自定义域名,但是不限制隧道数量!且免费!免费!免费…

云主机相比物理机有哪些优势

随着信息技术的飞速发展,云计算技术逐渐成为现代企业的核心驱动力。其中,云主机作为云计算的重要组成部分,以其高性能、高可用性和灵活便捷的特性,成为企业IT架构的新选择。今天我们就来了解探讨云主机相比传统主机,有…

#### 广告投放 ####

以巨量引擎为例: 计费模式 eCPM(expected Cost Per Mile,估计千次展示收入) 概括: ecpm为千次展示的预估收益,是广告平台用来给广告排序的指标。 注意是展示而不是千次点击收益,展示了可能不…

文献解读-基因编辑-第十二期|《CRISPR-detector:快速、准确地检测、可视化和注释基因组编辑事件引起的全基因组范围突变》

关键词:基因组变异检测;全基因组测序;基因编辑; 文献简介 标题(英文):CRISPR-detector: fast and accurate detection, visualization, and annotation of genome-wide mutations induced by g…

Zynq7000系列FPGA中的DMA控制器——PL外设请求接口

图9-4中展示了PL外设请求接口主要由两部分组成:PL外设请求总线和DMAC确认总线。这两部分分别使用特定的前缀进行标识,具体如下: PL外设请求总线(PL Peripheral Request Bus): 前缀:DR功能&…

免费Logo在线生成:必试的6款工具

logo对企业来说非常重要。一个好的logo免费设计在线生成器往往会给企业带来无形的利润。因此,许多企业非常重视自己公司的logo。作为一名设计师,如果能找到一个好的logo免费设计在线生成器,势必会给实际的logo设计带来事半功倍的效果。本文精…