ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

双卡2080Ti NVLink实战:从硬件安装到性能调优全记录

双卡2080Ti NVLink实战:从硬件安装到性能调优全记录 开箱之前先确认一个事情2080Ti 是消费级显卡里极为少见地保留 NVLink 接口的型号两张卡用专用桥接器连起来以后显存叠加到 22GB卡间通信带宽也远远甩开 PCIe这让它成了很多小成本 AI 训练和推理方案里的“神卡”。我这次在 Ubuntu 22.04 下把双卡 2080Ti NVLink 从驱动、桥接、P2P 检测到真实训练场景全部过了一遍踩的坑不少但最终性能提升非常明显。这篇文章就是完整记录从硬件怎么挑、系统怎么配、桥怎么装、性能怎么测到故障怎么排按顺序写清楚给同样想上双卡 NVLink 的朋友一份能直接照着做的攻略。1. 方案概览与硬件环境清单1.1 双卡 NVLink 能带来什么先说说为什么要折腾这个方案。单张 2080Ti 是 11GB 显存跑一些 13B 级别模型的 4bit 量化推理刚好够但想做微调或者跑更大的 batch显存就捉襟见肘。两张卡连上 NVLink 以后显存容量直接翻倍变成 22GB很多原本放不下的模型可以塞进去了。更重要的是卡间通信带宽。正常情况下两张显卡之间交换数据要走 PCIePCIe 4.0 x16 的单向带宽大约 16GB/s实际有效吞吐还要打折。而 2080Ti 的 NVLink 接口官方标称双向带宽 100GB/s单向大约 50GB/s 的量级是 PCIe 的好几倍。这个差距在数据并行训练里特别明显因为每个 step 结束都要做梯度同步通信时间占比一高双卡加速比就会严重下滑。NVLink 把通信瓶颈从 PCIe 带宽提升到接近显存带宽的量级双卡训练才能跑出接近线性的加速比。我拿到的实际数据也可以说明问题用 CUDA 自带的 P2P 带宽测试纯 PCIe 模式下两张卡的单向带宽只有 5GB/s 左右插上 NVLink 桥接器以后稳定跑到 22GB/s双向接近 44GB/s。这个差距反映到真实训练里小模型可能不明显模型一大会非常显著通信开销从“拖后腿”变成“基本无感”。1.2 硬件清单与选购避坑整个方案对硬件的要求说高不高说低也有几个硬门槛。我先列一份我当时用的清单部件型号/规格说明CPUIntel Core i7-12700K需要足够 PCIe 通道主流平台建议 40 条左右主板华硕 Z690-PPCIe x16 插槽间距要匹配桥接器位距显卡一技嘉 2080Ti 11G两张卡尽量同品牌同型号、同 BIOS显卡二技嘉 2080Ti 11G显存版本最好一致避免兼容问题NVLink 桥接器NVIDIA 官方 2-Slot 桥根据插槽间距选择 2-Slot 或 3-Slot电源振华 1000W 金牌全模组双卡满载功耗不容小觑系统盘三星 980 Pro 1TB装系统和 CUDA 工具链数据盘西数 SN570 4TBAI 数据集基本都很大硬件上有几个容易翻车的点我提醒一下。第一两张显卡尽量选同品牌同型号。不同品牌甚至不同批次的核心、显存颗粒、BIOS 在少数情况下会导致 NVLink 链路不稳定或者触发驱动层面的兼容性警告。我朋友用一张七彩虹加一张影驰的 2080Ti 试过NVLink 能识别但跑压力测试时偶尔掉链路后来换成同品牌同批次才彻底稳定。第二NVLink 桥接器的位距必须和主板插槽间距匹配。主板上两个 PCIe x16 物理插槽之间可能隔一个插槽位也可能隔两个桥接器分 2-Slot 和 3-Slot 两种规格。买之前用尺量一下两个插槽之间的距离最稳妥别买回来发现短一截。第三电源功率尽量留足。两张 2080Ti 同时满载单卡功耗按 260W 算加上 CPU、主板、硬盘整机峰值功耗轻松超过 700W850W 电源是底线1000W 更安心。我最初用 750W 电源跑双卡压力测试时直接重启换了 1000W 就再没出现过。最后是机箱风道。NVLink 桥接器会占用卡之间的一些空间两张卡贴得近散热压力比单卡大不少。建议机箱前后风道顺畅有条件的话在显卡下方加一个向上吹的机箱风扇不然温度一高显卡会主动降频性能测试数据就不好看了。2. 系统与基础软件环境搭建2.1 Ubuntu 22.04 安装时值得注意的两件事很多人觉得装系统太基础没必要讲但在这套方案里系统安装阶段有两个小选择会直接影响后面驱动的顺利程度我单独拿出来说。第一件是 BIOS 里务必关闭 Secure Boot。Ubuntu 22.04 默认支持 Secure Boot但如果开着第三方驱动模块尤其是 NVIDIA 的 DKMS 模块加载时经常遇到签名验证失败表现就是驱动装好了重启后nvidia-smi还是提示未加载。与其在后面跟签名问题纠缠不如在 BIOS 里一上来就关掉。不同主板的设置路径不一样一般在 Boot 或 Security 菜单下改成 Disabled 就行。第二件是分区时给系统盘和数据集预留合理空间。双卡训练模型、缓存数据集都会大量占用磁盘系统盘至少 100GB数据盘越大越好。我习惯单独挂一块数据盘把数据集、conda 环境、模型权重都放里面避免系统盘爆掉之后排查半天。系统装好后先用下面这组命令把基础依赖补齐这是编译驱动模块和 CUDA 工具链的前置条件。sudo apt update sudo apt install -y build-essential dkms linux-headers-$(uname -r)linux-headers-$(uname -r)这个是重中之重NVIDIA 驱动安装时要把内核模块nvidia.ko编译并注册到当前内核没有对应的 headers 文件安装过程会直接报错说找不到内核源码。dkms的作用是让驱动模块跟着内核版本自动重建升级内核后不需要手动重装驱动强烈建议一起装上。2.2 显卡驱动安装runfile 方式最可控Ubuntu 下安装 NVIDIA 驱动有两条路一条是sudo ubuntu-drivers autoinstall或sudo apt install nvidia-driver-535另一条是从官网下载 runfile 手动安装。我推荐 runfile 方式原因很现实apt 方式安装的驱动版本往往不是最新的而且会依赖 Ubuntu 的更新源如果系统源出现问题驱动状态很难排查。Runfile 方式把驱动安装的所有环节都摆在你面前安装日志也全出问题容易定位。我用的驱动版本是 535.154.05这个版本在 Ubuntu 22.04 和 Turing 架构上表现稳定。如果你用的是魔改 22GB 版 2080Ti需要注意驱动版本选择部分魔改卡需要回退到 470 系列或厂家定制的驱动直接上 535 可能识别不了 22GB 显存这一点在群里已经看到不少人踩过。安装前先屏蔽开源驱动 nouveau否则两个驱动会冲突。方法如下sudo tee /etc/modprobe.d/blacklist-nouveau.conf EOF blacklist nouveau options nouveau modeset0 EOF sudo update-initramfs -u屏蔽完成后重启此时系统会暂时没有图形界面驱动。重启后确认一下 nouveau 确实没加载lsmod | grep nouveau没有任何输出就说明屏蔽成功。然后切换到纯文本终端按 CtrlAltF3 进入 tty登录后执行sudo service gdm3 stop sudo ./NVIDIA-Linux-x86_64-535.154.05.run --dkms --silent--silent是静默安装不需要手动回答一堆问题--dkms让模块用 dkms 方式安装后续升级内核省事。安装完成后 reboot再执行nvidia-smi如果能看到两张 2080Ti 的型号、显存 11GB、驱动版本号和 CUDA 版本号驱动部分就过了。要注意runfile 安装过程中如果提示 “The distribution-provided pre-install script failed”多半是 nouveau 没屏蔽干净或者缺少 build-essential回到上一步检查即可。2.3 CUDA 开发环境安装驱动装好了但跑 AI 训练还需要 CUDA 工具链。这里很多人分不清驱动和 CUDA Toolkit 的关系驱动是底层运行库CUDA Toolkit 是编译和运行 CUDA 程序所需的编译器、库文件、头文件等。驱动中的 CUDA 版本号和实际安装的 Toolkit 版本可以不同只要 Toolkit 版本不高于驱动支持的版本就行。我安装的是 CUDA 12.4。下载 runfile 安装即可不要在系统环境变量里手动写死 CUDA 路径让安装器自动写入/usr/local/cuda的软链接会省心很多sudo ./cuda_12.4.0_550.54.14_linux.run --toolkit --silent --override安装完成后把 CUDA bin 目录和库目录加进.bashrcexport PATH/usr/local/cuda/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda/lib64:$LD_LIBRARY_PATH然后执行nvcc -V如果能看到版本信息说明工具链就绪。cuDNN 如果只是用 PyTorch 做训练PyTorch 会自带配套的 cuDNN不需要单独装如果要用 TensorFlow 或者自己编译一些底层算子再按需安装。3. 双卡 NVLink 桥接与连通性验证3.1 物理安装 NVLink 桥接器软件环境准备好以后先把机器关机断电开始物理安装 NVLink 桥接器。这一步看着简单实际上非常容易出错。顺序上有讲究先把两张显卡分别插到主板的 PCIe x16 插槽上供电线接好然后再装桥接器。如果先把桥安装到显卡上再一起插主板很容易因为桥的存在导致显卡无法完全插入插槽或者受力不均压坏 PCIe 金手指。桥接器本身有方向性。NVIDIA 的 2-Slot NVLink 桥一端是平整的金手指另一端中间有一个小的凹槽设计防止装反。安装时先对准两张卡上方的 NVLink 接口确保桥两端的金手指完全覆盖接口然后用手均匀用力向下按听到两边卡扣“咔”一声才算到位。千万不要只按一端否则另一端没有完全咬合开机后链路识别不稳定。装好之后不要急着开机先目测一下桥梁两端是否水平、卡扣是否锁紧。如果桥没对准方向或者只压下去一半最直观的结果就是后面nvidia-smi nvlink -c显示链路未连接或者连接状态是 0。这种硬件问题比软件问题更难排查所以物理安装阶段认真一点后面能省很多时间。3.2 用 nvidia-smi 检查驱动与双卡状态开机进入系统后先执行nvidia-smi确认两张卡都被正确识别。正常情况会看到两张 NVIDIA GeForce RTX 2080 Ti显存 11GB驱动版本一致温度转速等信息都能读出来。如果只看到一张卡先检查 PCIe 插槽本身或者换一个插槽试试。如果两张卡都显示但报 “ERR!” 状态优先看是不是供电线没插好或者电源功率不足。另外某些主板默认把第二条 PCIe x16 插槽设置为 x4 模式这不影响 NVLink 链路但是会影响 PCIe P2P 的备用通路和部分数据的传输效率建议进入 BIOS 把两个插槽都设为 x8 或 x16 模式也就是所谓的 PCIe bifurcation 设置。确认显卡本身没问题后使用nvidia-smi -q | grep -i Multi GPU可以查看两张卡的拓扑情况不过更直接的是下面要说的 NVLink 命令行工具。3.3 确认 NVLink 链路是否成功这是整套配置里最关键的一步检查两条 NVLink 通道是否真正建立。NVIDIA 驱动自带 NVLink 管理接口直接用两个命令就行。nvidia-smi nvlink -s这个命令输出每一张卡的 NVLink 链路状态包括每一条链路的发送和接收速率。在 2080Ti 上正常会看到两个 peer因为 2080Ti 有两条 NVLink 连接每条链路状态为 Active速率通常显示在 25 GB/s 左右。另一个命令更直接nvidia-smi nvlink -c输出内容会列出每张卡和其他卡之间的 NVLink 连接情况。如果看到 “Connected” 或类似的正常状态说明桥接器的物理连接和驱动的逻辑识别都通过了。如果看到 “Disconnected” 或者连接数为 0大概率是桥没装好、装反了或者两张卡不在相邻的 PCIe 插槽上导致桥的长度不够。还有一个容易忽视的点NVLink 桥接器存在一个最低高度要求机箱显卡位如果弯曲严重桥的两个卡扣可能无法同时锁住。我曾经遇到过一个问题显卡尾部太重导致卡轻微下垂桥的一端扣住了另一端却差一点没扣上链路状态时好时坏。后来用显卡支架顶住尾部解决了。3.4 开启 P2P 通信与 NCCL 依赖NVLink 在 Linux 下的核心价值是让两张卡之间可以直接通过 NVLink 做内存访问P2P不需要经过 CPU 和系统内存中转。对 AI 训练来说通信库 NCCL 会自动识别 NVLink 连接并优先使用它做卡间通信。P2P 功能在驱动层面默认是检测到 NVLink 链路就自动开启的不需要像 Windows 那样额外设置 SLI。但如果通过容器跑训练需要确保传入NVIDIA_DRIVER_CAPABILITIEScompute,utility环境变量否则容器可能拿不到 NVIDIA 管理库和 P2P 支持。命令行跑的话注意不要让进程被 cgroup 限制在某些 CPU 核心上导致 NUMA 访问异常进而影响 P2P 性能。验证 P2P 是否可用可以用一个很标准的 CUDA 示例程序也可以直接跳过验证跑性能测试因为性能测试本身会报告 P2P 状态。不过我还是建议先单独确认 P2P 支持状态这是后面所有性能测试的基础。/usr/local/cuda/extras/demo_suite/p2pBandwidthLatencyTest这个工具会枚举系统里所有支持 P2P 的 GPU 对然后测试它们之间的带宽和延迟。如果输出中显示P2PDisabled说明 NVLink 链路没被正确识别需要回到 3.3 检查链路状态如果显示P2PEnabled就可以进入性能测试阶段了。4. NVLink 性能实测4.1 用 CUDA 自带 P2P 工具测带宽我推荐从 CUDA 自带的p2pBandwidthLatencyTest开始因为它是 NVIDIA 官方发布的测试程序不需要额外安装任何库结果也最有参考性。直接运行/usr/local/cuda/extras/demo_suite/p2pBandwidthLatencyTest输出会很长重点看 Device 0 与 Device 1 之间的结果。关注这几个指标D2D (Device 0 - Device 1)单向 P2P 带宽。D2D (Device 1 - Device 0)反方向带宽。Bidirectional双向同时传输的带宽。我实测插上 NVLink 桥后的数值大致是单向 22.5GB/s双向 44GB/s 左右P2P 状态 EnabledLatency 在微秒级别。作为对比拔掉桥接器之后同一个测试单向带宽只有 5GB/s 上下双向不到 9GB/s。这个数据对比非常直观NVLink 的价值一下就体现出来了。如果你测出来的数字远低于我上面给的量级比如单向只有 8-10GB/s先别急着怀疑硬件。检查一下进程是不是被限制在了某个 CPU 核心上或者主板有没有把两张卡分别接到了 CPU 和芯片组之下。P2P 连接必须经过 CPU 内部的 Root Complex如果两张卡不在同一个 Root Complex 下即使有 NVLink 也可能走不到最佳路径。4.2 编译 nccl-tests 测多卡通信整体性能P2P 带宽测试只是最底层的通信能力真正影响分布式训练的是 NCCL 库在多卡之间做集体通信时的表现。NCCL 自己有一个配套的性能测试项目叫 nccl-tests强烈建议编译一份之后无论是验证设备还是调优训练通信它都是必备工具。编译之前需要先安装好 NCCL。我推荐用源码编译一份最新版 NCCL原因很简单apt 仓库里的 NCCL 版本往往落后于最新的性能优化而且源码编译能让 NCCL_HOME 路径完全可控方便后面 nccl-tests 链接。git clone https://github.com/NVIDIA/nccl.git cd nccl make -j$(nproc) CUDA_HOME/usr/local/cuda sudo make install然后编译 nccl-testsgit clone https://github.com/NVIDIA/nccl-tests.git cd nccl-tests make CUDA_HOME/usr/local/cuda NCCL_HOME/usr/local编译大概几分钟之后在build目录下会有多个可执行文件其中all_reduce_perf最常用。测试双卡 Ring all_reduce./build/all_reduce_perf -b 8M -e 128M -f 2 -g 2参数含义-b数据量的起始值-e结束值-f每次翻倍因子-g每节点 GPU 数。输出会显示不同数据量下的 bus bandwidth数字越大越好。我的测试结果中8MB 到 128MB 区间bus bandwidth 稳定在 30GB/s 以上数据量更大时略有波动但整体维持在高位。如果没有 NVLink同样的测试 bus bandwidth 通常在 10GB/s 左右差距立竿见影。如果你还想看 NVLink 到底比 PCIe 快多少可以拔掉桥接器再跑一次同样的命令对比两组数据会非常直观。4.3 PyTorch DDP 训练实测从吞吐看 NVLink 的真实价值底层带宽数据好看但最终还是要回到真实场景。我用一个标准的 PyTorch DDP 数据并行训练脚本测试了实际加速比这里贴出关键环节。环境准备很简单安装带 CUDA 的 PyTorchpip install torch torchvision --index-url https://download.pytorch.org/whl/cu124训练脚本里最核心的部分就一个分布式初始化加 DDP 包装import torch import torch.distributed as dist import torch.nn as nn from torch.nn.parallel import DistributedDataParallel as DDP dist.init_process_group(backendnccl) local_rank int(os.environ[LOCAL_RANK]) torch.cuda.set_device(local_rank) model ResNet18().cuda() model DDP(model, device_ids[local_rank])然后通过torchrun启动torchrun --nproc_per_node2 train.py通信库会自动检测 NVLink 链路优先使用 NVLink 做梯度 allreduce。我用的数据是 CIFAR-10 加一个 ResNet-18batch size 128单卡 baseline 每 epoch 耗时大约 65 秒双卡 NVLink 模式下稳定在 36 秒左右加速比接近 1.8 倍。作为对比拔掉 NVLink 桥只走 PCIe 的时候同样双卡任务需要 48 秒左右加速比只有约 1.35 倍原因就是梯度同步消耗了大量时间。这个实验最有价值的一点在于它把 NVLink 到底带来了多少提升量化了出来一个普通的 ResNet18 分类任务双卡加速比从 1.35 倍提升到 1.8 倍提升超过 30%。如果换成通信更密集的小模型或者更大的 batch这个差距还会进一步拉大。5. 常见问题与排查经验5.1 NVLink 链路状态异常先给一个排查速查表现象可能原因解决办法nvidia-smi nvlink -c显示 Disconnected桥接器未锁紧或装反重新断电安装确认两边卡扣到位nvidia-smi nvlink -s设备数为 0驱动版本不匹配或桥损坏升级 GPU 驱动到同一版本更换桥接器测试链路时好时坏显卡下垂、桥接触不良加入显卡支架重新插拔桥接器P2P 测试报 Disabled两张卡不在同一 Root Complex调整插槽让双卡走 CPU 直连通道排查链路慢的时候先把驱动版本统一再确认桥接器安装到位这两个因素覆盖了九成以上的问题。偶尔也遇到过主板 BIOS 在 PCIe speed 设置上太激进导致链路异常这时候把 PCIe 从 Gen4 降为 Gen3 试试。5.2 双卡训练时 NCCL 报错或 P2P 不可用训练脚本跑起来以后如果 NCCL 初始化报错最常见的提示是NCCL WARN P2P initialization failed这句话后面通常还会跟着一个 “throughput may be lower than expected” 的警告。遇到这个情况第一反应是用调试模式定位export NCCL_DEBUGINFO重新运行训练脚本日志里会打印 NCCL 对每条链路的检测结果能看到它有没有识别到 NVLink。如果日志里根本不识别 NVLink回到链路检测命令确认硬件连接如果识别到了但 P2P 还是失败尝试加上export NCCL_P2P_LEVELNV强制 NCCL 只在 NVLink 上走 P2P排除 PCIe 路径的干扰。这种问题在容器场景下更常见检查一下容器启动时是不是漏掉了--gpus all或者NVIDIA_DRIVER_CAPABILITIES环境变量。另一个容易被忽略的问题/dev/shm空间太小。NCCL 需要共享内存做缓冲默认如果/dev/shm只有 64MB遇到稍大的模型就会直接报 shared memory 不足。单机多卡场景建议用 Docker 启动时加--shm-size16g或者宿主机直接跑的话扩大/dev/shm。5.3 双卡训练吞吐不升反降这个问题通常被误认为是 NVLink 没生效实际上多数时候是数据加载和多进程工作没做好。双卡 DDP 是每个进程独立加载数据如果 DataLoader 的num_workers0两张卡就共用主进程 I/O瓶颈全在 CPU 数据传输上GPU 根本吃不饱。建议至少设置为DataLoader(dataset, batch_size128, num_workers4, pin_memoryTrue)另外双卡模式下 total batch size 翻倍学习率也要跟着调整否则模型收敛变慢甚至发散。还有一个我用过的简单技巧如果只是测试通信性能不要用真实训练脚本直接用 nccl-tests 看总线带宽判断 NVLink 是否生效比训练 loss 更可靠。5.4 电源、温控和整机稳定性双卡满载后整机功耗远超单卡如果电源余量不足表现很可能是跑一段时间后机器突然重启。这个问题我踩过750W 电源带双卡单卡压力测试没问题双卡同时跑高负载必重启。换 1000W 后彻底解决。如果不想换电源可以用功耗限制暂时扛住sudo nvidia-smi -i 0 -pl 220 sudo nvidia-smi -i 1 -pl 220把两张卡功耗限制在 220W 左右牺牲一点性能换取整机稳定。温度方面80 度以下比较安全超过 85 度建议检查机箱风道和显卡积灰情况。NVLink 桥接器本身不发热但它把两张卡紧贴在一起还会挡住一部分风扇气流的路径所以散热设计要额外上心。最后再分享两个小经验这套配置跑通之后我最深的体会是NVLink 性能能不能发挥出来硬件安装占一半软件识别占另一半。桥接器插上以后一定要用nvidia-smi nvlink -c确认链路状态再用 nccl-tests 做一次基准测试把这两个数据记录在案以后有任何性能波动拉出来对比就知道问题出在哪一层。另外一个小技巧装完驱动程序后顺手在 BIOS 里打开 Resizable BAR。它在部分场景下能再提升几个百分点的吞吐尤其对 PyTorch 里显存分配比较频繁的任务有帮助。操作很简单BIOS 里找到 Re-Size BAR Support 把它设为 Enabled 就行。如果你也打算用两张 2080Ti 组 NVLink 跑 AI 任务按照这套流程走基本能避开我踩过的大部分坑。后续如果想进一步压榨性能还可以尝试模型并行配合 NVLink 点对点通信省去 batch 同步的开销那又是另一个值得折腾的方向了。
返回列表