sgl-project/sglang · error · ValueError

QuantConfig has static quantization, but found activation sc

Error message

QuantConfig has static quantization, but found activation scales are None.

What it means

For per-tensor FP8 MoE with static activation scheme, process_weights_after_loading requires w13_input_scale and w2_input_scale to be present; they were expected to be loaded from the checkpoint but are None (missing input_scale keys in the safetensors or weight remapping failed to bind them).

Source

Thrown at python/sglang/srt/layers/quantization/fp8.py:2062

                )
                w2_weight[expert, :, :], layer.w2_weight_scale[expert] = (
                    scaled_fp8_quant(layer.w2_weight.data[expert, :, :])
                )
            layer.w13_weight = torch.nn.Parameter(w13_weight, requires_grad=False)
            layer.w2_weight = torch.nn.Parameter(w2_weight, requires_grad=False)

            if _is_hip:
                self.process_weights_hip_scale_padding(layer)

        # If checkpoint is fp8, we need to handle that the
        # MoE kernels require single activation scale and single weight
        # scale for w13 per expert.
        else:
            # Fp8 moe kernels require a single activation scale.
            # We take the max of all the scales in case they differ.
            if self.quant_config.activation_scheme == "static":
                if layer.w13_input_scale is None or layer.w2_input_scale is None:
                    raise ValueError(
                        "QuantConfig has static quantization, but found "
                        "activation scales are None."
                    )
                if not all_close_1d(layer.w13_input_scale) or not all_close_1d(
                    layer.w2_input_scale
                ):
                    print_warning_once(
                        "Found input_scales that are not equal for "
                        "fp8 MoE layer. Using the maximum across experts "
                        "for each layer. "
                    )
                layer.w13_input_scale = torch.nn.Parameter(
                    layer.w13_input_scale.max(), requires_grad=False
                )
                layer.w2_input_scale = torch.nn.Parameter(
                    layer.w2_input_scale.max(), requires_grad=False
                )

View on GitHub (pinned to 0132848349)

Solutions

  1. Use a checkpoint that includes input_scale tensors for the MoE layers (standard FP8 static releases save them)
  2. Switch quantization_config activation_scheme to "dynamic" so no static scales are needed
  3. Inspect the safetensors index for missing *input_scale* keys and re-save/quantize with them

Example fix

// before
"quantization_config": {"activation_scheme": "static"}  // but no input_scale tensors saved
// after
"quantization_config": {"activation_scheme": "dynamic"}
Defensive patterns

Strategy: validation

Validate before calling

if quant_config.activation_scheme == "static":
    assert layer.w13_input_scale is not None and layer.w2_input_scale is not None, \
        "checkpoint missing MoE input_scale tensors; use dynamic scheme or a complete FP8 checkpoint"

Type guard

def moe_static_scales_present(layer) -> bool:
    return layer.w13_input_scale is not None and layer.w2_input_scale is not None

Try / catch

try:
    method.process_weights_after_loading(layer)
except ValueError as e:
    if "activation scales are None" in str(e):
        raise SystemExit("re-quantize with dynamic scheme or a complete checkpoint")
    raise

Prevention

When it happens

Trigger: Loading an FP8 MoE model with activation_scheme="static" whose safetensors lack input_scale tensors (or whose weight names don't match the remap table so scales never get bound), then reaching process_weights_after_loading.

Common situations: Checkpoints quantized without saving activation scales but with config claiming static; renamed weight keys after fine-tuning/merging; custom checkpoints produced by external quantizers that omit il_scale/input_scale tensors.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/9ae33320cc15e6a2. Report an issue: GitHub.