如何获取GPU设备拓扑及连接吞吐量信息?
nvidia-smi topo -m仅返回GPU间的连接类型,不直接提供吞吐数值,你可以通过以下几种方式获取对应连接的吞吐权重:
1. 结合GPU型号查官方规格
不同GPU的NVLink、PCIe版本对应固定的峰值吞吐,比如:
- NVLink:A100的NVLink 4.0单链路吞吐为50GB/s,8链路绑定后总吞吐400GB/s;V100的NVLink 3.0单链路为30GB/s。
- PCIe:PCIe 4.0 x16单向吞吐32GB/s,PCIe 3.0 x16为16GB/s。
你可以根据nvidia-smi topo -m里的连接类型匹配对应值: - 标记
NV#的,用单链路吞吐×#得到总吞吐; PIX/PXB这类PCIe连接,结合GPU的PCIe版本和链路宽度计算;SYS跨NUMA的PCIe连接,需考虑CPU interlink(如QPI/UPI)带宽,通常比纯PCIe低,比如QPI 2.0单向9.6GB/s,实际有效吞吐需打折扣。
2. 使用NVIDIA Management Library (NVML) 编程获取
NVML提供API可直接查询GPU间的连接带宽,比解析命令行输出更可靠:
- 调用
nvmlDeviceGetPcieThroughput()获取PCIe的峰值或实时吞吐; - 调用
nvmlDeviceGetNvLinkState()和nvmlDeviceGetNvLinkBandwidth()获取NVLink的带宽信息; - 遍历所有GPU对,调用API即可构建带权重的拓扑图。
示例伪代码思路:
import pynvml pynvml.nvmlInit() device_count = pynvml.nvmlDeviceGetCount() topology_graph = {} for i in range(device_count): handle_i = pynvml.nvmlDeviceGetHandleByIndex(i) topology_graph[i] = {} for j in range(device_count): if i == j: topology_graph[i][j] = {"type": "Self", "throughput": 0} continue # 检查NVLink连接 try: if pynvml.nvmlDeviceGetNvLinkState(handle_i, j) == pynvml.NVML_NVLINK_STATE_UP: bandwidth = pynvml.nvmlDeviceGetNvLinkBandwidth(handle_i, j) topology_graph[i][j] = {"type": "NVLink", "throughput": bandwidth} continue except pynvml.NVMLError: pass # 检查PCIe连接 pcie_tx = pynvml.nvmlDeviceGetPcieThroughput(handle_i, pynvml.NVML_PCIE_UTIL_TX) ancestor_type = pynvml.nvmlDeviceGetTopologyCommonAncestor(handle_i, pynvml.nvmlDeviceGetHandleByIndex(j)) topology_graph[i][j] = {"type": parse_ancestor_type(ancestor_type), "throughput": pcie_tx} pynvml.nvmlShutdown()
3. 解析实时监控命令输出
如果需要运行时的实际吞吐(而非峰值),可以解析nvidia-smi dmon或nvidia-smi pmon的输出:
nvidia-smi dmon -s p输出PCIe收发吞吐;nvidia-smi dmon -s n输出NVLink吞吐;
提取对应GPU对的传输数据作为动态权重。
附你提供的nvidia-smi topo -m中文输出:
GPU0 GPU1 GPU2 GPU3 GPU4 GPU5 CPU亲和性 NUMA亲和性GPU0 X PIX PIX SYS SYS SYS 0-11 0
GPU1 PIX X PIX SYS SYS SYS 0-11 0
GPU2 PIX PIX X SYS SYS SYS 0-11 0
GPU3 SYS SYS SYS X PIX PIX 12-23 1
GPU4 SYS SYS SYS PIX X PIX 12-23 1
GPU5 SYS SYS SYS PIX PIX X 12-23 1图例:
X = 自身
SYS = 连接需经过PCIe以及NUMA节点间的SMP互连(如QPI/UPI)
NODE = 连接需经过PCIe以及同一NUMA节点内PCIe主桥之间的互连
PHB = 连接需经过PCIe以及PCIe主桥(通常是CPU)
PXB = 连接需经过多个PCIe桥(不经过PCIe主桥)
PIX = 连接最多经过一个PCIe桥
NV# = 连接经过一组绑定的#条NVLink
内容的提问来源于stack exchange,提问作者Aditya Kaushik

