{"record":{"id":"76f2c3fcf87b9ee2","repo":"sgl-project/sglang","slug":"interleaved-fc1-n-must-be-even-got-n","errorCode":null,"errorMessage":"Interleaved FC1 N must be even, got {n}","messagePattern":"Interleaved FC1 N must be even, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/quantization/nvfp4_gemm_swiglu_nvfp4_quant.py","lineNumber":2880,"sourceCode":"            \"nvfp4_gemm_swiglu_nvfp4_quant currently supports NVFP4 input \"\n            \"and output only\"\n        )\n    if a.device.type != \"cuda\" or b.device.type != \"cuda\":\n        raise ValueError(\"nvfp4_gemm_swiglu_nvfp4_quant requires CUDA tensors\")\n\n    major, minor = get_compute_capability(a.device)\n    if major != 10:\n        raise ValueError(\n            f\"nvfp4_gemm_swiglu_nvfp4_quant requires SM100, got SM{major}{minor}\"\n        )\n\n    m = a.shape[0]\n    k = a.shape[1] * 2\n    n = b.shape[0]\n    if b.shape[1] * 2 != k:\n        raise ValueError(f\"Shape mismatch: A K={k}, B K={b.shape[1] * 2}\")\n    if n % 2 != 0:\n        raise ValueError(f\"Interleaved FC1 N must be even, got {n}\")\n\n    l = 1\n    n_out = n // 2\n    if n_out % sf_vec_size != 0:\n        raise ValueError(\n            f\"Output N={n_out} must be divisible by sf_vec_size={sf_vec_size}\"\n        )\n    scale_n_out = n_out // sf_vec_size\n    padded_m = _round_up(m, 128)\n    padded_scale_n = _round_up(scale_n_out, 4)\n\n    ab_dtype_cutlass = get_cutlass_dtype(ab_dtype)\n    sf_dtype_cutlass = get_cutlass_dtype(sf_dtype)\n    c_dtype_cutlass = get_cutlass_dtype(c_dtype)\n\n    if m <= 128:\n        mma_tiler_mn, cluster_shape_mn = (128, 128), (1, 2)\n    else:","sourceCodeStart":2862,"sourceCodeEnd":2898,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/quantization/nvfp4_gemm_swiglu_nvfp4_quant.py#L2862-L2898","documentation":"After SwiGLU the kernel halves the output N; because linear and gate rows are interleaved in pairs, the interleaved FC1 N dimension must be even. An odd N means the interleave layout is malformed and output scale-factor indexing would break.","triggerScenarios":"Calling nvfp4_gemm_swiglu_nvfp4_quant with b.shape[0] (interleaved N) odd — typically because interleave_linear_and_gate was skipped or applied with wrong group_size, leaving a concatenated rather than interleaved layout.","commonSituations":"Forgetting to run interleave_linear_and_gate on FC1 weights during process_weights_after_loading, or hand-building b for a test with odd row count.","solutions":["Ensure FC1 weights go through interleave_linear_and_gate before this op","Verify b.shape[0] == 2*intermediate_size (even by construction)"],"exampleFix":"# before\nb = torch.cat([linear_w, gate_w], dim=0)\nout = nvfp4_gemm_swiglu_nvfp4_quant(a, b, ...)\n# after\nb = interleave_linear_and_gate(torch.cat([linear_w, gate_w], dim=0), group_size)\nout = nvfp4_gemm_swiglu_nvfp4_quant(a, b, ...)","handlingStrategy":"validation","validationCode":"assert b.shape[0] % 2 == 0","typeGuard":"def interleaved_n_ok(b): return b.shape[0] % 2 == 0","tryCatchPattern":null,"preventionTips":["Always run interleave_linear_and_gate during weight postprocessing","Add a repack smoke test per model"],"tags":["nvfp4","shape-validation","swiglu","weight-layout"],"backgroundTag":"tensor-shape-validation","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}