sgl-project/sglang · error · ValueError

DFLASH config.layer_types must be a sequence of attention ty

Error message

DFLASH config.layer_types must be a sequence of attention type strings.

What it means

Raised by get_dflash_layer_types when config.layer_types exists but is not a non-string Sequence. The DFlash draft attention layout (full vs sliding attention layers) is derived from this list, so a plain string or a non-iterable/None-like value cannot be interpreted. This guards against malformed HF configs or wrong overrides.

Source

Thrown at python/sglang/srt/speculative/dflash_utils.py:401

        raise ValueError(
            "DFlash layer selection requires num_target_layers >= 4. "
            f"Got num_target_layers={num_target_layers}."
        )

    span = end - start
    return [
        int(round(start + (i * span) / (num_draft_layers - 1)))
        for i in range(num_draft_layers)
    ]


def get_dflash_layer_types(config: Any) -> Optional[Sequence[str]]:
    text_config = _get_text_config(config)
    layer_types = _cfg_get(text_config, "layer_types", _cfg_get(config, "layer_types"))
    if layer_types is None:
        return None
    if isinstance(layer_types, str) or not isinstance(layer_types, Sequence):
        raise ValueError(
            "DFLASH config.layer_types must be a sequence of attention type strings."
        )
    return layer_types


def get_dflash_attention_sliding_window_size(config: Any) -> Optional[int]:
    layer_types = get_dflash_layer_types(config)
    if layer_types is None or "sliding_attention" not in layer_types:
        return None

    text_config = _get_text_config(config)
    sliding_window = _cfg_get(
        text_config, "sliding_window", _cfg_get(config, "sliding_window")
    )
    if sliding_window is None and is_nemotron_35_draft_config(config):
        sliding_window = _get_dflash_config(config).get("swa_window_size")
    if sliding_window is None:
        raise ValueError(

View on GitHub (pinned to 0132848349)

Solutions

  1. Set config.layer_types (or text_config.layer_types) to a list, e.g. ["full_attention"] * 30 + ["sliding_attention"] * 2.
  2. If overriding via server args or a draft config, wrap the value in a list.
  3. Reload the config from the upstream model repo to rule out local corruption.

Example fix

# before
config.layer_types = "full_attention"
# after
config.layer_types = ["full_attention", "sliding_attention"]
Defensive patterns

Strategy: type-guard

Validate before calling

lt = getattr(getattr(config, 'text_config', config), 'layer_types', None)
if lt is not None and (isinstance(lt, str) or not isinstance(lt, (list, tuple))):
    raise TypeError('layer_types must be a list of strings')

Type guard

def is_valid_layer_types(v) -> bool:
    return v is None or (not isinstance(v, str) and isinstance(v, (list, tuple)) and all(isinstance(x, str) for x in v))

Prevention

When it happens

Trigger: get_dflash_layer_types(config) where text_config.layer_types (or config.layer_types) is a str like "full_attention" or a dict/int instead of a list of strings such as ["full_attention", "sliding_attention"].

Common situations: A hand-edited HF config.json where layer_types was written as a single string; a config override passing layer_types="sliding_attention"; a newer/older transformers version serializing the field differently.

Related errors


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