Tracing the Failure: Debugging CUTLASS FP4 Tile Configurations on Blackwell SM120
Introduction
In the course of optimizing inference throughput for the GLM-5-NVFP4 model on 8× NVIDIA RTX PRO 6000 Blackwell GPUs, a critical performance bottleneck emerged: the CUTLASS FP4 grouped GEMM kernels—responsible for executing the Mixture-of-Experts (MoE) matrix multiplications that dominate decode time—were failing to initialize with larger tile configurations. Specifically, the M128×N256 and M256×N128 tile shapes crashed during kernel initialization with a generic "Error Internal" message, while the smaller 128×128 tiles worked correctly. This single message (msg 907) captures the moment the assistant pivots from high-level performance analysis to low-level kernel debugging, tracing the root cause of these failures through the CUTLASS codebase.
The Broader Context
To understand why this message matters, we must situate it within the larger optimization effort. The GLM-5-NVFP4 model is a massive MoE architecture with 256 experts, 8 of which are activated per token. During autoregressive decode, each expert processes a small batch of tokens—at 1024 concurrent requests, roughly 32 tokens per expert. These tiny GEMMs (dimensions roughly 32×2048×6144) have extremely low arithmetic intensity, achieving only 0.8–55 TFLOPS out of a theoretical dense peak of ~1,850 TFLOPS per GPU. The assistant had already determined that the model is compute-bound (not communication-bound) by benchmarking TP4+PP2 against TP8, and had identified that the failing larger tile configurations—M128×N256 and M256×N128—would improve data reuse and compute density for these small matrices. The user's directive, "Fix tiles, then try 2/3," set the assistant on a path to resolve the tile failures before exploring other optimization avenues like num_continuous_decode_steps and cuBLASLt FP4 paths.
The Message in Full
The subject message reads:
The failing tiles crash during initializeMoeGroupedGemm with "Error Internal" which likely means the CUTLASS collective builder can't find a valid configuration (SMEM overflow or unsupported schedule). Let me trace the actual initialization code:
>
``bash ssh root@10.1.230.174 'find /root/ml-env/lib/python3.12/site-packages/flashinfer/data/csrc -name "*.inl" -o -name "*.h" -o -name "*.cuh" | xargs grep -l "initializeMoeGroupedGemm\|Failed to initialize cutlass TMA WS" 2>/dev/null' ``
>
Output: /root/ml-env/lib/python3.12/site-packages/flashinfer/data/csrc/nv_internal/tensorrt_llm/kernels/cutlass_kernels/moe_gemm/launchers/moe_gemm_tma_ws_launcher.inl
At first glance, this appears to be a simple diagnostic step: search for the initialization function, find the file. But the reasoning packed into the opening sentence reveals a deep understanding of CUTLASS internals and a deliberate investigative strategy.
The Reasoning Process
The assistant's thinking is structured as a classic debugging chain: observe a symptom, hypothesize a root cause, then design an experiment to confirm or refute the hypothesis.
Symptom: The larger tile configurations (M128×N256 and M256×N128) crash with "Error Internal" during initializeMoeGroupedGemm. This error is not a CUDA runtime error (which would typically manifest as a kernel launch failure or illegal memory access) but rather an internal CUTLASS error raised during kernel compilation or configuration selection. The assistant recognizes this distinction immediately—the error occurs at initialization time, not at kernel launch time, which points to a configuration-space problem.
Hypothesis: The assistant proposes two possible mechanisms for the failure:
- Shared memory (SMEM) overflow: CUTLASS uses shared memory as a software-managed cache for tile data and pipeline stages. Larger tile dimensions require more shared memory for the accumulator, the epilogue, and the pipeline stages. The RTX PRO 6000 Blackwell GPUs (SM120 architecture) have 99 KB of shared memory per block (configurable up to 100 KB with the extended shared memory carveout). If the collective builder's auto-calculation determines that the required shared memory exceeds this budget, it cannot generate a valid kernel configuration.
- Unsupported schedule: CUTLASS uses "kernel schedules" that define the warp-level execution pattern (e.g., warp-specialized, persistent thread, etc.). For SM120, the assistant had previously discovered that CUTLASS falls back to
KernelScheduleAuto—an automatic scheduler—rather than using the hand-tuned 1SM/2SM warp-specialized schedules available for SM100. The auto scheduler may lack support for certain tile dimension combinations on this architecture, particularly for the FP4 data type with TMA (Tensor Memory Accelerator) warp-specialized kernels. The assistant does not commit to either hypothesis but instead chooses to trace the actual initialization code to find the precise failure point. This is a disciplined debugging approach: rather than guessing or attempting random fixes, the assistant goes to the source.
The Diagnostic Strategy
The bash command is carefully crafted. It searches across all CUTLASS-related source files (*.inl, *.h, *.cuh) in the FlashInfer package for two strings: initializeMoeGroupedGemm (the function name from the error) and Failed to initialize cutlass TMA WS (a possible error message string). The use of xargs grep -l (list only matching filenames) is efficient—it returns just the file paths, not the matching lines, which is appropriate for a first-pass search.
The result points to moe_gemm_tma_ws_launcher.inl, a 734-line CUTLASS template instantiation file that the assistant had examined earlier (msg 894–897). This file contains the INSTANTIATE_TMA_WARP_SPECIALIZED_MOE_GEMM macro invocations for each tile configuration, along with the collective builder logic that selects kernel schedules and computes shared memory requirements.
Input Knowledge Required
To fully understand this message, the reader needs knowledge spanning several domains:
- CUTLASS architecture: Understanding that CUTLASS uses a collective builder pattern where tile dimensions, data types, and kernel schedules are composed at compile time into a valid kernel configuration. The builder can fail if the configuration exceeds hardware limits or if no valid schedule exists for the combination.
- Blackwell SM120 shared memory limits: The RTX PRO 6000 Blackwell GPUs have 99 KB of shared memory per block, configurable to 100 KB with extended carveout. This is less than the 228 KB available on Hopper (SM90) GPUs, making SMEM pressure a more acute constraint for large tiles.
- FP4 quantization and TMA warp specialization: The kernels use FP4 (4-bit floating point) input data with TMA (Tensor Memory Accelerator) for data movement and warp-specialized execution where different warps handle data loading, computation, and epilogue operations. This combination imposes specific constraints on tile shapes and pipeline depths.
- MoE grouped GEMM semantics: The
initializeMoeGroupedGemmfunction initializes a kernel that processes multiple small GEMMs (one per expert) in a single fused launch, with a problem size array specifying the M, N, and K dimensions for each expert.
Output Knowledge Created
This message produces two concrete outputs:
- A confirmed file location: The initialization code lives in
/root/ml-env/lib/python3.12/site-packages/flashinfer/data/csrc/nv_internal/tensorrt_llm/kernels/cutlass_kernels/moe_gemm/launchers/moe_gemm_tma_ws_launcher.inl. This gives the assistant a precise target for deeper analysis. - A refined hypothesis: By connecting the "Error Internal" message to the collective builder's configuration search, the assistant establishes that the failure is not a runtime crash but a compile-time/initialization-time configuration failure. This distinction is crucial—it means the fix must come from either modifying the tile configuration parameters, adjusting the shared memory budget, or patching the CUTLASS schedule selection logic, rather than changing runtime parameters.
Assumptions and Potential Pitfalls
The assistant makes several assumptions that warrant scrutiny:
- The "Error Internal" originates from the CUTLASS collective builder. This is a reasonable inference given the context (initialization failure with specific tile dimensions), but it could also originate from the TensorRT-LLM wrapper code that calls the builder. If the error is in the wrapper's validation logic rather than CUTLASS proper, the fix might be different.
- SMEM overflow is the primary candidate. The assistant mentions this first, suggesting it is the leading hypothesis. However, subsequent investigation (msg 897) revealed that the
StageCountAutoCarveoutmechanism is used for SM120, which auto-computes pipeline stages based on available shared memory. If the auto-carveout can reduce the number of stages to fit within the budget, SMEM overflow might not be the actual cause—the failure could be in the schedule selection itself. - The fix is in the CUTLASS source files within FlashInfer. The assistant searches within the FlashInfer package, which vendors its own copy of TensorRT-LLM's CUTLASS kernels. If the actual bug is upstream in the CUTLASS library itself (e.g., missing SM120 tile instantiation in the CUDA kernel compiler), modifying the FlashInfer copy might not help without also patching the CUTLASS headers.
Significance Within the Optimization Journey
This message represents a critical transition point in the optimization effort. Prior to this, the assistant had been operating at the level of server parameters (--max-running-requests, --num-continuous-decode-steps, --mem-fraction-static) and benchmarking configurations (TP8 vs TP4+PP2). The discovery that the GPU was drawing only ~235W out of 600W TDP during inference—and that the CUTLASS kernels were achieving as little as 0.02% of peak FP4 throughput for small batch sizes—had already established that the primary problem was kernel efficiency, not server tuning.
The failing tile configurations are a concrete, fixable manifestation of this efficiency gap. If the M128×N256 and M256×N128 tiles can be made to work, they would allow each SM to process larger chunks of the GEMM per kernel invocation, increasing data reuse and reducing the number of global memory accesses. Even a modest improvement in per-expert GEMM efficiency would compound across the 8 activated experts per token and the hundreds of concurrent requests in flight.
Conclusion
Message 907 is a masterclass in disciplined debugging: observe the symptom, form a hypothesis grounded in architectural knowledge, and design a targeted experiment to trace the root cause. The assistant's decision to search the CUTLASS source code rather than blindly tweak parameters or apply workarounds reflects a systematic approach to performance optimization. The resulting file location—moe_gemm_tma_ws_launcher.inl—would become the target of deep analysis in subsequent messages, where the assistant would examine the StageCountAutoCarveout logic, the KernelScheduleAuto fallback, and the epilogue mode differences between working and failing tile configurations.
This message also illustrates a broader principle of ML infrastructure engineering: when faced with a performance wall, the most productive path forward is often to descend into the kernel code and understand why the hardware is not being fully utilized. The tile failure investigation would ultimately reveal that the Blackwell SM120 architecture lacks hand-tuned kernel schedules for FP4 grouped GEMMs, forcing CUTLASS to rely on an auto-scheduler that cannot exploit the full compute capability of the GPU. This finding would shape the assistant's subsequent optimization strategy, steering it toward alternative approaches like cuBLASLt FP4 paths and persistent kernel designs that bypass CUTLASS's limitations entirely.