Linux GPU(Graphics Processing Unit, 图形处理单元)
使用相关介绍
相关术语
- PCIe
CPU(Central Processing Unit)
通用目的处理器,逻辑控制能力强,算力相对弱
GPU(Graphics Processing Unit, 图形处理器)
工作原理,在 CPU 的指挥下工作
- GPU 在计算机中相当于一个外部的、专用功能的独立处理设备,通常需要从内存中提交数据到显存,调用显卡的并发计算脚本(从 .cu 编译),再通过从显卡中拷贝计算结果回本地,然后进行下一步计算
- 图片参考
NPU(Neural Processing Unit)
硬件实现神经网络运算, 比如张量运算、卷积、点积、激活函数、多维矩阵运算等(参考)
TPU(Tensor Processing Unit)
功能同上,Google 实现
- NVLink
NVSwitch
是 NVIDIA 的一款交换芯片,封装在 GPU module 上
NVLink Switch
是将 NVSwitch 从 GPU module 拆出来的独立设备,跨主机连接 GPU 设备
HBM(High Bandwidth Memory)
将多个 DDR 芯片堆叠之后与 GPU 芯片封装到一起(参考)
- 解决 GPU 显存和普通内存(DDR)在主板上,通过 PCIe 连接到处理器(PCIe 是瓶颈)
NVIDIA Management Library (NVML, NVIDIA 管理库)
详情
cuDNN
cuDNN (NVIDIA CUDA® Deep Neural Network library)
是 NVIDIA
专门针对深度神经网络(Deep Neural Networks)
中的基础操作而设计基于 GPU
的加速库。它可以集成到更高级别的机器学习框架中,如 Tensorflow 等。强调性能、易用性和低内存开销。
TensorRT
是 NVIDIA 推出的一套专为深度学习推理打造的 SDK
- 在推理阶段,基于
TensorRT
的应用可以提供同比单一 CPU 平台高达 40 倍的加速效果
NVIDIA 型号
DGX(Deep Learning GPU-Accelerated eXperience)
是 NVIDIA 的一款深度学习计算服务器
HGX(High-Performance GPU Accelerator)
是 NVIDIA 的一款高性能计算服务器(参考)
- SXM(Server PCI Express Module) 是一种 high bandwidth socket 解决方案,用于将 Nvidia 计算加速器连接到系统中
- SXM 模块通常用于 NVIDIA 的数据中心 GPU 产品,如 Tesla V100、Tesla A100 等。
- NVIDIA DRIVE Orin SoC(系统级芯片)可提供每秒 254 TOPS(万亿次运算),是智能自动驾驶芯片
DGX A100 拓扑
NVIDIA GPU 查看
$ lspci | grep -i vga
00:02.0 VGA compatible controller: Device 1234:1111 (rev 02)
00:06.0 VGA compatible controller: NVIDIA Corporation GP102 [GeForce GTX 1080 Ti] (rev a1)
00:07.0 VGA compatible controller: NVIDIA Corporation GP102 [GeForce GTX 1080 Ti] (rev a1)
$ lspci | grep -i nvidia
00:06.0 VGA compatible controller: NVIDIA Corporation GP102 [GeForce GTX 1080 Ti] (rev a1)
00:07.0 VGA compatible controller: NVIDIA Corporation GP102 [GeForce GTX 1080 Ti] (rev a1)
$ lspci -v -s 00:06.0 # 00:06.0 位置代号
00:06.0 VGA compatible controller: NVIDIA Corporation GP102 [GeForce GTX 1080 Ti] (rev a1) (prog-if 00 [VGA controller])
Subsystem: Dell GP102 [GeForce GTX 1080 Ti]
Physical Slot: 6
Flags: bus master, fast devsel, latency 0, IRQ 33
Memory at fc000000 (32-bit, non-prefetchable) [size=16M]
Memory at d0000000 (64-bit, prefetchable) [size=256M]
Memory at f0000000 (64-bit, prefetchable) [size=32M]
I/O ports at c000 [size=128]
[virtual] Expansion ROM at fe000000 [disabled] [size=512K]
Capabilities: [60] Power Management version 3
Capabilities: [68] MSI: Enable+ Count=1/1 Maskable- 64bit+
Capabilities: [78] Express Legacy Endpoint, MSI 00
Kernel driver in use: nvidia
Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
Nvidia Driver
- Nvidia Driver 是在宿主机上安装的驱动程序
- 驱动下载地址:https://www.nvidia.cn/drivers/lookup/
- 禁用系统自带的
nouveau
模块
$ lsmod | grep nouveau
$ vim /usr/lib/modprobe.d/blacklist-nouveau.conf
blacklist nouveau
options nouveau modeset=0
$ dracut -force
$ reboot
- Install NVIDIA Driver via apt-get(也使用 runfile 安装部署)
# 查看支持的驱动
sudo ubuntu-drivers devices
# 安装驱动
sudo apt-get install nvidia-driver-418 nvidia-modprobe
- 由于 Linux 一切设备皆文件,安装完 Driver 后,可以在 /dev 目录下看到相关文件:
$ ls /dev | grep nvidia
nvidia0 nvidia1 nvidiactl nvidia-uvm nvidia-uvm-tools
- 安装完成后,可以使用
nvidia-smi
命令
- GPU 驱动卸载
/usr/bin/nvidia-uninstall
CUDA samples 程序测试
- BandwidthTest 测试 GPU 卡与主机 server、GPU 与 GPU 卡之间的显存带宽
cd /usr/local/cuda/samples/1_Utilities/bandwidthTest/
make
./bandwidthTest
- P2pBandwidthLatencyTest 测试 GPU 卡之间的带宽
cd /usr/local/cuda/samples/1_Utilities/p2pBandwidthLatencyTest/
make
./p2pBandwidthLatencyTest
- BatchCuBlas 为 GPU 浮点运算能力测试、加压
cd /usr/local/cuda/samples/7_CUDALibraries/batchCUBLAS/
make
./batchCUBLAS -m8192 -n8192 -k8192 ##默认测试ID号为0的GPU卡
./batchCUBLAS -m8192 -n8192 -k8192 --device=1 ##指定测试ID号为1的GPU卡
CUDA
CUDA(Compute Unified Device Architecture,统一计算设备架构)
是 Nvidia 提供的一个并发计算平台框架和编程模型,使得使用 GPU 进行通用计算变得简单和优雅
CUDA
是由英伟达 NVIDIA
所推出的一种集成技术,是该公司对于 GPGPU
的正式名称。通过该技术用户可利用 NVIDIA
的 GeForce 8
以后的 GPU
和较新的 Quadro GPU
进行计算。
CUDA
可以看作是一个工作台,上面配有很多工具,如锤子、螺丝刀等。cuDNN
是基于 CUDA
的深度学习 GPU 加速库,它就相当于工作的工具,比如扳手。
- CUDA 安装
- 安装 CUDA
# 交互式
sudo chmod +x cuda_12.1.1_530.30.02_linux.run
sudo ./cuda_12.1.1_530.30.02_linux.run
# 非交互式
sudo ./cuda_12.1.1_530.30.02_linux.run --toolkit --samples --silent
查看 CUDA 版本
- 检查 CUDA 安装版本
nvcc(Nvidia CUDA Compiler, NVIDIA CUDA编译器)
nvcc -V
# 或
nvcc --version
# 或
cat /usr/local/cuda/version.txt
测试 CUDA Samples
cd /usr/local/cuda-12.1/extras/demo_suite
# 显示Result=PASS表示安装成功
./deviceQuery
- CUDA Toolkit包括:
- bin
- Compiler
- Libraries
- CUDA Samples
- CUDA Driver
Compute capability
- Compute capability 是 CUDA 和驱动交互时候的一个概念
- PS: PyTorch 的环境变量
TORCH_CUDA_ARCH_LIST="7.0;7.5;8.6"
可以指定算力(compute capability),解决 RuntimeError: CUDA error: no kernel image is available for execution on the device
问题
测试脚本:
$ echo "Torch Version: $(python -c 'import torch; print(torch.__version__)'), Is CUDA Available: $(python -c 'import torch; print(torch.cuda.is_available())')"
Torch Version: 1.8.1+cu101, Is CUDA Available: True # +cu101 表示是适配 cuda 10.1 的版本
cuda 卸载
/usr/local/cuda/bin/cuda-uninstaller
cuda execution failed with error: 209: no kernel image is available for execution on the device
或错误日志:
RuntimeError: CUDA error: no kernel image is available for execution on the device
- 原因:安装的 cuda 和 torch 版本和显卡不适配;算力不匹配
- 参考
- 解决方式:使用环境变量指定
TORCH_CUDA_ARCH_LIST="7.5 8.0"
NVLink
nvidia-smi nvlink 命令
NVLINK 监控指标
- FOR GPU <-> NVLINK (Bps)
- FOR GPU <-> PCI (Bps)
- DCGM_FI_PROF_PCIE_TX_BYTES
- DCGM_FI_PROF_PCIE_RX_BYTES
NVLINK 带宽测试脚本
import torch
import numpy as np
device = torch.device("cuda")
n_gpus = 8
data_size = 1024 * 1024 * 1024 # 1 GB
speed_matrix = np.zeros((n_gpus, n_gpus))
for i in range(n_gpus):
for j in range(i + 1, n_gpus):
print(f"Testing communication between GPU {i} and GPU {j}...")
with torch.cuda.device(i):
data = torch.randn(data_size, device=device)
torch.cuda.synchronize()
with torch.cuda.device(j):
result = torch.randn(data_size, device=device)
torch.cuda.synchronize()
with torch.cuda.device(i):
start = torch.cuda.Event(enable_timing=True)
end = torch.cuda.Event(enable_timing=True)
start.record()
result.copy_(data)
end.record()
torch.cuda.synchronize()
elapsed_time_ms = start.elapsed_time(end)
transfer_rate = data_size / elapsed_time_ms * 1000 * 8 / 1e9
speed_matrix[i][j] = transfer_rate
speed_matrix[j][i] = transfer_rate
print(speed_matrix)
- A800 机器理论 NVLINK 全互通带宽为 400GB/s,实际测试可达 370GB/s
NCCL
- NVIDIA
集合通信库 (NCCL, Nvidia Collective multi-GPU Communication Library)
可实现针对 NVIDIA GPU 和网络进行性能优化的多 GPU 和多节点通信基元。NCCL 提供了 all-gather、all-reduce、broadcast、reduce、reduce-scatter、point-to-point send 和 receive 等例程,这些例程均经过优化,可通过节点内的 PCIe 和 NVLink 高速互联以及节点间的 NVIDIA Mellanox 网络实现高带宽和低延迟
- 环境变量(更多参考)
NCCL_IB_HCA=mlx5_1:1,mlx5_2:1,mlx5_3:1,mlx5_4:1
要使用的环境中 RDMA 网卡
NCCL_SOCKET_IFNAME
指定用于通信的 IP 接口 设置成主机的 host 网卡,可通过 ip a
查找,推荐配置为:NCCL_SOCKET_IFNAME=eth1
NCCL_IB_DISABLE=0
是否关闭 RDMA 通信
- 设置成 1 来启用 TCP 通信(非 RDMA),推荐配置为:NCCL_IB_DISABLE=0
NCCL_DEBUG=INFO
NCCL 日志级别
- 通过日志中出现的
NCCL INFO Using internal Network [IB|Socket]
判断走的什么协议(参考)
unable to load libnccl-net.so : libnccl-net.so: cannot open shared object file: No such file or directory
是正常的(参考)
- 更多 https://developer.nvidia.cn/nccl
NCCL 测试
NCCL(Nvidia Collective Communication Library)
是 NVIDIA 的集合通信库,支持安装在单个节点或多个节点的大量 GPU 卡上,实现多个 GPU 的快速通信
- NCCL Tests 是一个测试工具集,可以用来评估 NCCL 的运行性能和正确性
wget https://github.com/NVIDIA/nccl-tests/archive/refs/tags/v2.10.1.tar.gz
tar -zxvf v2.10.1.tar.gz
cd nccl-tests-2.10.1
make
# 8 GPUs (-g 8), scanning from 8 Bytes to 128MBytes
./build/all_reduce_perf -b 8 -e 128M -f 2 -g 8
# ./build/all_reduce_perf -b 256M -e 8G -f 2 -g 8 -n 100 -w 20
GPUDirect
- GPUDirect 是 NVIDIA 开发的一项技术,实现 GPU 与其他设备(例如网络接口卡(NIC) 和存储设备)之间的直接通信和数据传输,而不涉及 CPU 内存中转
- GPU Direct 技术包括:
GPUDirect Storage
允许存储设备和 GPU 之间进行直接数据传输,绕过 CPU,减少数据传输的延迟和 CPU 开销
GPUDirect P2P(Peer-to-Peer)
参考
- 主要用于单机 GPU 间的高速通信,它使得 GPU 可以通过 PCI Express 直接访问目标 GPU 的显存,避免了通过拷贝到 CPU host memory 作为中转,大大降低了数据交换的延迟
- NVLink 是 NVIDIA 于 2016 年发布,解决 PCIe 的带宽瓶颈,加速多个 GPU 之间或 GPU 与其他设备(如 CPU、内存等)之间的通信,通过 NVSwitch + NVLink 实现 GPU 全连接
- NVIDIA 开发的
NCCL(NVIDIA Collective Communications Library)
提供了针对 GPUDirect P2P 的特别优化
GPUDirect RDMA
结合 GPU 加速计算和 RDMA(Remote Direct Memory Access)
技术,实现在跨节点 GPU 和 RDMA 网络设备之间直接进行数据传输和通信的能力
- GPUDirect 视频
MIG
GPU MIG(Multi-Instance GPU)
功能允许 NVIDIA GPU 安全地划分为多达七个独立的 GPU 实例,用于 CUDA 应用程序,为多个用户提供独立的 GPU 资源以实现最佳 GPU 利用率,每个实例均与各自的高带宽显存、缓存和计算核心完全隔离
- 配置
- Enable VT
- Enable IOMMU
- Enable Access Control Services
# 启用 MIG 模式
nvidia-smi -mig 1
# 查看 GPU 实例配置文件
nvidia-smi mig –lgip
# 创建2个ID为5和14的GPU实例
nvidia-smi mig -cgi 5,14
# 列出的GPU实例
nvidia-smi mig –lgi
其他
- nvidia-peermem kernel module,为基于英伟达 InfiniBand 的 HCA(主机通道适配器)提供了对英伟达 GPU 显存的直接点对点读写访问功能
nvidia-smi topo -p2p n
Streaming Multiprocessor(SM)
F&Q
nvidia-smi 执行慢的问题
执行如下命令可以有效提高速度:
sudo nvidia-persistenced --persistence-mode
或
sudo nvidia-smi -pm 1
也可以配置在 /etc/rc.local
中,实现开机启动
No CMAKE_CUDA_COMPILER could be found
C++ 依赖 cuda 编译时,错误
CMake Error at CMakeLists.txt:4 (project):
No CMAKE_CUDA_COMPILER could be found.
Tell CMake where to find the compiler by setting either the environment
variable "CUDACXX" or the CMake cache entry CMAKE_CUDA_COMPILER to the full
path to the compiler, or to the compiler name if it is in the PATH.
解决方式:
export PATH=/usr/local/cuda/bin:$PATH
如何指定 GPU
训练模型时,使用如下变量设置使用的 GPU 编号
export CUDA_VISIBLE_DEVICES=0
export CUDA_VISIBLE_DEVICES=0,1
os.environ["CUDA_VISIBLE_DEVICES"] = '0,1' # 一般在程序开头设置
Unable to determine the device handle for GPU 0000:06:00.0
解决方式: