2. NVLink链路状态查询
任务目标
在配备NVLink的GPU服务器上,查询每对GPU之间NVLink链路的实时状态(活跃/空闲/错误),并打印当前带宽利用率。本案例使用NVIDIA官方NVML(NV Management Library)的Python绑定实现,无需额外安装驱动组件。
环境依赖
- NVIDIA驱动(≥450.80.02),已加载nvidia_uvm内核模块
- Python 3.6+,安装
pynvml:pip install pynvml - 双卡或更多GPU互联(NVLink拓扑),单卡环境将输出提示信息
关键完整代码
import pynvml
import time
def get_nvlink_status():
pynvml.nvmlInit()
try:
device_count = pynvml.nvmlDeviceGetCount()
if device_count < 2:
print(f"检测到 {device_count} 块GPU,NVLink查询需要至少2块GPU")
return
print(f"共检测到 {device_count} 块GPU,开始查询NVLink链路状态...\n")
for i in range(device_count):
handle_i = pynvml.nvmlDeviceGetHandleByIndex(i)
try:
# 获取该GPU的NVLink链路数(每条链路对应一个link)
link_count = pynvml.nvmlDeviceGetMaxLinkWidth(handle_i) # 实际为lane数,非链路数
# 正确方式:遍历可能的link id (0-5),NVLink最大支持6条链路
active_links = 0
total_links = 0
for link_id in range(6):
try:
# 查询链路状态
state = pynvml.nvmlDeviceGetNvLinkState(handle_i, link_id)
total_links += 1
if state == pynvml.NVML_NVLINK_STATUS_ACTIVE:
active_links += 1
# 查询该链路的收发速率(单位KB/s)
rx, tx = pynvml.nvmlDeviceGetNvLinkUtilizationCounter(handle_i, link_id, 0)
# 计算总带宽利用率(假设每条链路单向最大25GB/s = 26214400 KB/s)
rx_rate = rx / 1024 / 1024 # 转换为GB/s
tx_rate = tx / 1024 / 1024
print(f"GPU {i} Link {link_id}: 活跃 | RX {rx_rate:.2f} GB/s | TX {tx_rate:.2f} GB/s")
else:
print(f"GPU {i} Link {link_id}: 空闲")
except pynvml.NVMLError_NotSupported:
break # 该GPU不支持更多链路
except pynvml.NVMLError_InvalidArgument:
continue # 超出实际链路数
if total_links == 0:
print(f"GPU {i}: 未检测到NVLink链路")
else:
print(f"GPU {i}: {active_links}/{total_links} 条链路活跃\n")
except pynvml.NVMLError_NotSupported:
print(f"GPU {i}: 不支持NVLink查询")
finally:
pynvml.nvmlShutdown()
if __name__ == "__main__":
get_nvlink_status()
运行方式
python nvlink_status.py
验证方法与判定标准
- 正常输出:每块GPU会列出其所有NVLink链路(通常为0-5),每条链路显示“活跃”或“空闲”状态;活跃链路附带实时RX/TX速率(GB/s)。
- 功能验证:在GPU间运行NCCL全规约测试(如
nccl-tests的all_reduce_perf),同时执行本脚本,应观察到对应链路RX/TX速率显著上升(>1 GB/s),证明带宽利用率读取有效。 - 错误链路检测:若某条链路硬件故障,NVML会返回错误状态(非ACTIVE/INACTIVE),脚本会将其归类为“空闲”——实际工程中应区分错误状态,本案例为最小演示,仅区分活跃与非活跃。
- 预期输出示例(双卡A100环境):
共检测到 2 块GPU,开始查询NVLink链路状态...
GPU 0 Link 0: 活跃 | RX 0.00 GB/s | TX 0.00 GB/s
GPU 0 Link 1: 活跃 | RX 0.00 GB/s | TX 0.00 GB/s
GPU 0 Link 2: 活跃 | RX 0.00 GB/s | TX 0.00 GB/s
GPU 0: 3/3 条链路活跃
GPU 1 Link 0: 活跃 | RX 0.00 GB/s | TX 0.00 GB/s
GPU 1 Link 1: 活跃 | RX 0.00 GB/s | TX 0.00 GB/s
GPU 1 Link 2: 活跃 | RX 0.00 GB/s | TX 0.00 GB/s
GPU 1: 3/3 条链路活跃
常见问题
- ImportError: No module named 'pynvml':执行
pip install pynvml。 - NVMLError_LibraryNotFound:确认NVIDIA驱动已正确安装,
nvidia-smi可正常运行。 - 所有链路显示空闲但GPU间通信正常:检查是否使用了NVLink(而非PCIe),可用
nvidia-smi nvlink -s交叉验证。 - 速率始终为0:NVML计数器默认不启用,需先调用
nvmlDeviceSetNvLinkUtilizationControl使能。本案例为最小演示,未包含该步骤;如需实时速率,请参考NVML文档启用计数器。