The Virtual Topology Mirage: Chasing PCIe P2P in a Proxmox VM with 8 Blackwell GPUs

In the high-stakes world of multi-GPU machine learning inference, communication between GPUs is the invisible bottleneck that can make or break performance. When deploying a model like GLM-5-NVFP4 across 8 NVIDIA RTX PRO 6000 Blackwell GPUs, every microsecond of cross-GPU latency compounds across hundreds of all-reduce operations per inference step. This article examines a pivotal moment in a debugging session where an AI assistant, after hours of battling IOMMU groups, ACS settings, and BAR allocation failures, arrives at a clear-eyed understanding of the VM's PCIe topology and proposes an ambitious—and potentially futile—next step: building virtual PCIe switches to trick the NVIDIA driver into seeing a more favorable topology.

The Message in Context

The subject message, <msg id=375>, is the assistant's response after the user has been relentlessly pushing to get P2P (peer-to-peer) DMA working between GPUs in a Proxmox virtual machine. The conversation leading up to this point has been a journey of escalating complexity. Earlier segments covered installing NVIDIA drivers, resolving flash-attn build issues, deploying the GLM-5-NVFP4 model with SGLang, and discovering that the model crashes during decode due to NaN values—a problem eventually traced to attention backend compatibility. But the deeper, more insidious performance problem has been cross-GPU communication latency.

The user had shared the bare-metal nvidia-smi topo output showing a clean NUMA topology: GPUs 0-3 on NUMA node 0 with NODE interconnects, GPUs 4-7 on NUMA node 1 with NODE interconnects, and cross-socket links showing SYS. In the VM, however, all GPU pairs showed PHB—a flat topology that gives NCCL no information to optimize communication locality. The assistant had already investigated ACS disabling, IOMMU group merging, and kernel parameters, only to conclude that the hardware topology (each GPU on its own PCIe root complex on the ASUS ESC8000A-E13 motherboard) fundamentally prevents P2P in a VM.

Decoding the PCIe Topology Map

The message begins with the assistant laying out the VM's PCIe topology in a clear, structured format:

Now I can see the full picture. The VM has GPUs at: - 00:10.0 → bus 01 (hostpci0) — PCIe Root Port group 1 - 00:10.1 → bus 02 (hostpci1) - 00:10.2 → bus 03 (hostpci2) - 00:10.3 → bus 04 (hostpci3) - 00:1c.0 → bus 05 (hostpci4) — PCIe Root Port group 2 (ICH9 PCIe ports) - 00:1c.1 → bus 06 (hostpci5) - 00:1c.2 → bus 07 (hostpci6) - 00:1c.3 → bus 08 (hostpci7)

This mapping reveals something important: the eight GPUs are split across two groups of PCIe root ports. The first four (hostpci0 through hostpci3) hang off the PCIe root port at 00:10.[0-3], while the second four (hostpci4 through hostpci7) hang off a different set of root ports at 00:1c.[0-3]. The latter group uses ICH9 PCIe ports, which is a clue about the underlying QEMU chipset emulation.

The assistant correctly identifies the critical open question: are hostpci0-3 the NUMA 0 GPUs and hostpci4-7 the NUMA 1 GPUs? This is the linchpin of the entire topology optimization effort. If the mapping aligns—the first four physical GPUs (at PCI addresses 01:00.0, 11:00.0, 61:00.0, 71:00.0 on the host, all on NUMA 0) happen to be assigned to hostpci0-3, and the NUMA 1 GPUs (81:00.0, 91:00.0, e1:00.0, f1:00.0) to hostpci4-7—then the virtual topology already mirrors the physical NUMA split, and the assistant can build virtual PCIe switches to expose it. If the mapping is scrambled, the task becomes significantly harder.

The Reasoning Process: From Observation to Action

What makes this message particularly interesting is the reasoning arc it reveals. The assistant has been through several phases of understanding:

Phase 1: Naive optimism. Earlier in the conversation, the assistant believed that enabling IOMMU passthrough (iommu=pt) and migrating the VM to the Q35 chipset with pcie=1 might improve P2P capability. This was based on a reasonable assumption: that the right virtual PCIe configuration would allow VFIO to expose P2P DMA between passed-through devices.

Phase 2: Disillusionment. After testing, the assistant discovered that the bandwidth numbers were virtually identical before and after the changes—~33 GB/s for 4MB transfers and a ~13µs latency floor for small transfers. The assistant correctly diagnosed this as the inherent cost of GPU→host memory→GPU staged copies through the QEMU/KVM virtual device model. The honest assessment was damning: "P2P (direct GPU-to-GPU DMA) cannot be enabled in this VM setup."

Phase 3: Strategic pivot. Despite concluding that P2P is impossible, the assistant now proposes a different goal: not true P2P, but a virtual topology that would give NCCL better information for optimizing communication patterns. The key insight is that even without hardware P2P, NCCL can make smarter scheduling decisions if it knows which GPUs share a NUMA node. Getting NODE instead of PHB for intra-socket pairs, and SYS instead of PHB for cross-socket pairs, would allow NCCL to prefer local transfers and minimize cross-socket traffic.

The Proposed Solution: Virtual PCIe Switches via Custom QEMU Args

The second half of the message proposes a concrete—and invasive—next step:

Also, to build the virtual PCIe switch topology properly, I need to understand — are you comfortable with me writing custom QEMU args on the host to create virtual PCIe expander buses and switches (similar to the NVIDIA guide)? This would involve stopping the VM, changing the config with qm set 128 -args '...', and restarting. It's the only way to get NODE/SYS distinction in the VM.

This proposal draws on NVIDIA's own documentation for configuring virtual machines for AI inference, which describes using pcie-switch-upstream-port and pcie-switch-downstream-port QEMU devices to create virtual PCIe switches. The idea is to group GPUs behind virtual switches that mirror the physical NUMA topology, so the NVIDIA driver reports NODE or PIX instead of PHB.

The assistant is careful to set expectations: this approach is "the only way to get NODE/SYS distinction in the VM." It's an admission that the earlier, simpler approaches (Q35 chipset, pcie=1, iommu=pt) were insufficient, and that only a deeply customized QEMU configuration—bypassing Proxmox's standard hostpci syntax—can achieve the desired topology.

Assumptions and Potential Pitfalls

The message rests on several assumptions that deserve scrutiny:

Assumption 1: The resource mapping file will reveal a clean NUMA split. The assistant assumes that the pro6000.cfg mapping file will show a one-to-one correspondence between hostpci indices and physical PCI addresses that aligns with the NUMA topology. If the mapping is scrambled—say, hostpci0 maps to a NUMA 1 GPU and hostpci1 to a NUMA 0 GPU—then the two groups of root ports wouldn't correspond to the two NUMA nodes, and the virtual switch topology would need to be more complex.

Assumption 2: Virtual PCIe switches will actually improve performance. This is the most significant assumption, and one that the assistant itself questioned earlier in the conversation. In <msg id=369>, the assistant stated: "Creating virtual PCIe switches would change what nvidia-smi topo reports (from NS to PIX), but the actual data path wouldn't change — transfers would still go GPU→host mem→GPU with the same ~13µs latency." Yet now the assistant is proposing exactly this approach. The shift in reasoning is subtle but important: the goal is no longer to change the data path but to change NCCL's scheduling. NCCL uses topology information to choose communication algorithms (ring vs. tree, chunk sizes, pipeline depth). A topology that distinguishes intra-socket from cross-socket links could allow NCCL to make better choices, even if the underlying hardware path is unchanged.

Assumption 3: Custom QEMU args are compatible with Proxmox's management layer. Proxmox uses qm commands and configuration files to manage VMs. Adding raw -args bypasses the standard configuration path and could cause issues with future VM management operations (migration, backup, template creation). The assistant acknowledges this by asking for explicit user consent.

The Input Knowledge Required

To fully understand this message, the reader needs knowledge of:

The Output Knowledge Created

This message produces several important pieces of knowledge:

  1. A complete map of the VM's virtual PCIe topology, showing which QEMU root port corresponds to which GPU bus and which hostpci index.
  2. A testable hypothesis about NUMA mapping: that hostpci0-3 correspond to NUMA 0 and hostpci4-7 to NUMA 1, pending verification via the mapping file.
  3. A concrete action plan: read the mapping file, verify the NUMA alignment, then construct custom QEMU args to build virtual PCIe switches.
  4. An explicit request for user consent, acknowledging the invasive nature of the proposed change.

The Deeper Narrative: Virtualization's Hard Limits

Beneath the technical details, this message tells a story about the fundamental tension between virtualization and high-performance GPU computing. The assistant has spent hours—across multiple conversation segments—trying to solve a problem that may ultimately be unsolvable within the constraints of a virtualized environment. Each layer peeled back reveals another constraint: first the chipset, then the IOMMU, then ACS, then the hardware topology itself.

The message at <msg id=375> represents a moment of clarity and a strategic pivot. The assistant has accepted that true P2P is impossible and is now pursuing the next-best thing: a topology that gives NCCL better information, even if the underlying data path remains unchanged. It's a pragmatic compromise between the ideal (direct GPU-to-GPU DMA) and the achievable (better-informed NCCL scheduling).

Whether this compromise will yield meaningful performance improvements remains to be seen. The 13µs latency floor for small transfers—the fundamental bottleneck imposed by the GPU→host→GPU data path—may prove resistant to topology tricks. But in the world of ML inference optimization, even a 10-20% improvement in all-reduce throughput can translate to significant end-to-end latency reductions for large models.

Conclusion

The assistant's message at <msg id=375> is a masterclass in systematic debugging under constraints. It demonstrates how to read a complex PCIe topology, formulate testable hypotheses, and propose targeted interventions while honestly acknowledging their limitations. The proposed virtual PCIe switch approach may or may not improve performance, but the reasoning process itself—moving from naive optimism through disillusionment to a nuanced, pragmatic strategy—is a valuable model for anyone debugging multi-GPU performance in virtualized environments.

The next step, reading the Proxmox mapping file, will determine whether the topology puzzle can be solved with a clean mapping or whether further complexity awaits. Either way, the message captures a critical inflection point in the conversation: the moment when the assistant stops trying to enable P2P and starts trying to simulate it.