The Driver That Didn't Match: Fixing a Silent NCCL Hang in a Blackwell GPU Cluster
In the middle of deploying a 122-billion-parameter language model across four NVIDIA RTX PRO 6000 Blackwell GPUs, the server stalled. Not with a crash, not with an error message, but with a quiet, indefinite hang at the phrase "Init torch distributed begin." The model—Qwen3.5-122B-A10B, a 234 GB BF16 MoE architecture—had been downloaded, the service file written, and the server started. And then nothing. The logs simply stopped advancing. This is the story of the single message that diagnosed and fixed the root cause: a silent version mismatch between the NVIDIA kernel module and the userspace libraries running inside an LXC container.
The Setup: A Complex Multi-GPU Topology
The infrastructure was anything but simple. The Proxmox host had been reconfigured to split eight RTX PRO 6000 Blackwell GPUs between two environments: four GPUs on NUMA node 0 remained bound to the NVIDIA driver for an LXC container running SGLang, while the other four on NUMA node 1 were passed through via vfio-pci to a confidential computing VM using SEV-SNP. This split had been orchestrated by a different agent, which had also upgraded the host's NVIDIA driver to version 590.48.01 to support the Blackwell GPUs properly. The LXC container, however, had been set up earlier and still ran userspace NVIDIA packages from the 565 series. The kernel module—shared from the host into the container—was version 590.48.01, but the libraries that CUDA and NCCL actually called at runtime were from 565.57.01.
This mismatch was invisible to casual inspection. The container's nvidia-smi reported "Driver Version: 590.48.01" because the SMI tool queries the kernel module directly. But the nvidia-smi binary itself was the 565 version, and the libnvidia-ml.so that NCCL loaded at runtime was the 565 variant. The system was living a double life.
The Hang That Led to the Fix
The assistant had been methodically working through the deployment. After the user requested the Qwen3.5-122B-A10B model with tensor parallelism of 4, MTP speculative decoding, tool calling, and reasoning parsers ([msg 6100]), the assistant had researched the model architecture, downloaded all 39 safetensor shards totaling 234 GB, crafted a systemd service file, and started the server. The first attempt crashed with a clear error about missing flags for MTP with hybrid GDN models. That was fixed. The second attempt started cleanly—and then hung.
When the user asked "crashed?" ([msg 6120]), the assistant investigated and found the server was alive but stuck. The logs showed "Init torch distributed begin" but never completed. The process had zero CPU usage for over ten minutes. The GPUs showed only 1 GB of memory used each—the weights hadn't even started loading. Something was blocking NCCL's distributed initialization before any actual communication could happen.
The user then provided the crucial hint: "So on the proxmox host we have made some changes to the driver, maybe we need to update in the VM to match?" ([msg 6138]). This was the turning point.
Systematic Diagnosis
The assistant immediately pivoted to investigate. It checked the host's driver version (590.48.01), then the container's kernel module version (also 590.48.01, since it's shared), and then the container's userspace packages. The discrepancy was stark:
- Kernel module: 590.48.01
- Installed userspace packages: libnvidia-compute-565, libnvidia-decode-565, nvidia-utils-565 The
nvidia-smioutput told the story: "NVIDIA-SMI 565.57.01 | Driver Version: 590.48.01". The SMI tool was from the 565 package, but the driver it talked to was 590. The container had bothlibnvidia-ml.so.565.57.01andlibnvidia-ml.so.590.48.01on disk (the latter bind-mounted from the host), butldconfigpointed to the 565 variant. NCCL, loading at runtime through the dynamic linker, would pick up the 565 library—and then attempt to communicate with a 590 kernel module. The result was undefined behavior, manifesting as a hang during NCCL's peer discovery phase. The user clarified that the mismatch was collateral damage from another agent's work: "note this is because another agent was deploying the 4 other GPUs to a CC VM" ([msg 6142]). The host driver upgrade had been done for the VM passthrough setup, and the LXC container hadn't been updated to match.## The Subject Message: A Precise Package Upgrade The subject message ([msg 6146]) is the assistant's response to discovering this mismatch. Having verified that the 590.48.01 packages were available in the Ubuntu apt repositories, the assistant executed a single, focused command:
[assistant] 590.48.01 packages are available in apt. Let me install them and remove the old 565 ones: [bash] ssh root@10.1.230.174 'apt-get update -qq && apt-get install -y libnvidia-compute-590 libnvidia-decode-590 nvidia-utils-590 2>&1 | tail -15' Unpacking libnvidia-compute-590:amd64 (590.48.01-0ubuntu0.24.04.1) ... Selecting previously unselected package libnvidia-decode-590:amd64. Preparing to unpack .../4-libnvidia-decode-590_590.48.01-0ubuntu0.24.04.1_amd64.deb ... Unpacking libnvidia-decode-590:amd64 (590.48.01-0ubuntu0.24.04.1) ... Selecting previously unselected package nvidia-utils-590. Preparing to unpack .../5-nvidia-utils-590_590.48.01-0ubuntu0.24.04.1_amd64.deb ... Unpacking nvidia-utils-590 (590.48.01-0ubuntu0.24.04.1)...
The command is deceptively simple: three packages, one apt-get invocation. But the reasoning behind it reveals a deep understanding of the NVIDIA driver architecture. The assistant chose to install libnvidia-compute-590 (the core compute libraries including CUDA runtime and NCCL dependencies), libnvidia-decode-590 (video decode libraries, needed for any media processing), and nvidia-utils-590 (the tools like nvidia-smi). It did not install a new kernel module—because the kernel module is shared from the host and already at 590.48.01. It did not install a full driver package or reboot. The fix was purely in userspace.
Assumptions and Decisions
The assistant made several important assumptions in this message. First, it assumed that the NCCL hang was caused by the userspace/kernel version mismatch rather than by any other issue like network configuration, firewall rules, or the SGLANG_ENABLE_SPEC_V2=1 environment variable that had been added for MTP support. This was a reasonable inference given the timing—the hang occurred during NCCL's distributed initialization, which is exactly when the runtime libraries are loaded and used.
Second, the assistant assumed that simply installing the 590 userspace packages would be sufficient, without needing to remove the 565 packages first. This turned out to be correct: in the following message ([msg 6147]), the assistant attempted to remove the 565 packages and found they were already gone—the 590 packages had replaced them cleanly via apt's package management.
Third, the assistant assumed that the packages were available in the standard Ubuntu repositories. It had verified this in the previous message ([msg 6145]) by running apt-cache policy libnvidia-compute-590, which showed the candidate version 590.48.01-0ubuntu0.24.04.1 from the noble-updates and noble-security repositories. This was a critical validation step before running the install.
One potential mistake was that the assistant did not explicitly verify that the installed packages would resolve the NCCL hang before restarting the server. It proceeded directly from installation to restart without, for example, running a quick NCCL test or checking that the library linkage had updated. However, this was mitigated by the subsequent verification steps: in [msg 6147], the assistant confirmed that nvidia-smi now showed "NVIDIA-SMI 590.48.01" matching the driver version, and in [msg 6148], it ran ldconfig and verified the library path.
Input Knowledge Required
To understand this message, the reader needs knowledge of the NVIDIA driver architecture, specifically the split between the kernel module (which manages the hardware and is shared into containers) and the userspace libraries (which provide the CUDA runtime, NCCL, and other APIs and must match the kernel module version). The reader also needs to understand that NCCL (NVIDIA Collective Communications Library) initializes distributed communication among GPUs by loading libnvidia-ml.so at runtime, and that a version mismatch can cause silent hangs rather than clear error messages.
Knowledge of LXC container technology is also relevant: containers share the host kernel and kernel modules, but userspace libraries are typically installed inside the container and can differ from the host. This is a common source of subtle bugs in GPU-accelerated container deployments.
Output Knowledge Created
This message created a concrete fix: the NVIDIA userspace packages in the LXC container were upgraded from version 565.57.01 to 590.48.01, matching the host kernel module. The output also includes the confirmation of successful installation—the dpkg unpacking messages showing each package being installed.
More broadly, the message established a diagnostic pattern for future issues: when NCCL hangs during initialization on a system with containerized GPU access, check for a driver version mismatch between the kernel module and userspace libraries. This pattern would prove valuable in the subsequent segment, where the assistant would encounter a different NCCL hang caused by P2P DMA corruption under SEV-SNP IOMMU.
The Thinking Process
The assistant's reasoning, visible across the sequence of messages leading to this one, shows a systematic debugging approach. When the server first hung, the assistant checked process status, GPU memory usage, and logs. It noticed the process was alive but consuming zero CPU—a sign of a blocking system call rather than computation. It considered whether the SGLANG_ENABLE_SPEC_V2=1 environment variable was causing a deadlock and tried running without MTP. When the user suggested a driver mismatch, the assistant didn't just blindly upgrade—it first verified the host version, then the container's kernel module version, then the container's installed packages, then the apt availability of matching packages. Each step narrowed the hypothesis space.
The message itself reflects a decision to fix the root cause rather than apply a workaround. The assistant could have tried to force the container to use the bind-mounted 590 libraries by manipulating LD_LIBRARY_PATH or ldconfig. Instead, it chose to properly install the matching packages via apt, ensuring a clean, persistent, and maintainable configuration. This is the mark of an engineer thinking about long-term system health rather than just getting the immediate benchmark to run.
Aftermath
The fix worked. In the following messages, the assistant verified that nvidia-smi now showed matching versions, restarted the server, and the model loaded successfully. The NCCL hang was gone. But this was not the end of the NCCL issues in this segment—the assistant would later encounter a different NCCL hang caused by P2P DMA corruption under SEV-SNP IOMMU, requiring NCCL_P2P_DISABLE=1 as a workaround. That second issue was fundamentally different: it was a hardware virtualization problem rather than a software version mismatch. The diagnostic skill developed in this message—checking the driver version consistency first—would serve as a baseline before investigating more exotic causes.
Conclusion
The message at index 6146 is a textbook example of diagnosing and fixing a silent infrastructure bug. The symptom was a hang; the root cause was a version mismatch invisible to surface-level inspection. The fix was precise, minimal, and permanent. The reasoning process—hypothesize, verify, validate, act—is the essence of systems debugging. And the lesson is timeless: when distributed GPU initialization hangs, always check that your userspace libraries speak the same version as your kernel module.