sgl-project/sglang · error · ValueError

Dual transformers for {model_name} must expose cache-dit blo

Error message

Dual transformers for {model_name} must expose cache-dit block attributes {adapter_spec.blocks_attr}. transformer has {transformer_blocks_attr}: {transformer_blocks is not None}, secondary transformer has {transformer_2_blocks_attr}: {transformer_2_blocks is not None}

What it means

Raised by enable_cache_on_dual_transformer when the adapter spec for the model expects specific block-list attributes (adapter_spec.blocks_attr, e.g. ('transformer_blocks', 'blocks')) on the primary and secondary transformers, but getattr returns None for at least one of them. cache-dit must wrap the actual nn.ModuleList of blocks to inject caching, so the attribute must exist and be non-None.

Source

Thrown at python/sglang/multimodal_gen/runtime/cache/cache_dit_integration.py:672

            compute_steps,
            cache_steps,
            secondary_config.steps_computation_policy,
        )

    parallelism_config = _build_parallelism_config(sp_group, tp_group)
    if parallelism_config is not None:
        _patch_cache_dit_similarity()

    _mark_transformer_parallelized(transformer, parallelism_config, sp_group, tp_group)
    _mark_transformer_parallelized(
        transformer_2, parallelism_config, sp_group, tp_group
    )

    transformer_blocks_attr, transformer_2_blocks_attr = adapter_spec.blocks_attr
    transformer_blocks = getattr(transformer, transformer_blocks_attr, None)
    transformer_2_blocks = getattr(transformer_2, transformer_2_blocks_attr, None)
    if transformer_blocks is None or transformer_2_blocks is None:
        raise ValueError(
            f"Dual transformers for {model_name} must expose cache-dit block "
            f"attributes {adapter_spec.blocks_attr}. "
            f"transformer has {transformer_blocks_attr}: "
            f"{transformer_blocks is not None}, secondary transformer has "
            f"{transformer_2_blocks_attr}: {transformer_2_blocks is not None}"
        )

    cache_dit.enable_cache(
        BlockAdapter(
            transformer=[transformer, transformer_2],
            blocks=[transformer_blocks, transformer_2_blocks],
            blocks_name=adapter_spec.blocks_name,
            forward_pattern=adapter_spec.forward_pattern,
            params_modifiers=[primary_modifier, secondary_modifier],
            check_forward_pattern=adapter_spec.check_forward_pattern,
            check_num_outputs=adapter_spec.check_num_outputs,
            has_separate_cfg=adapter_spec.has_separate_cfg,
        ),

View on GitHub (pinned to 0132848349)

Solutions

  1. Verify the attribute names on your transformer objects with hasattr/getattr and confirm they match adapter_spec.blocks_attr
  2. Load model weights/code with a version whose module layout matches the registered adapter spec (pin the matching sglang/model revisions)
  3. If you control the model, add the expected attribute as an alias property pointing at the real block list
  4. If the layout genuinely differs, register an updated blocks_attr spec or disable cache-dit

Example fix

# before
enable_cache_on_dual_transformer(t1, t2, model_name)  # ValueError: blocks attr missing

# after
spec = DUAL_TRANSFORMER_BLOCK_ADAPTER_SPECS[model_name]
for mod, attr in zip((t1, t2), spec.blocks_attr):
    assert getattr(mod, attr, None) is not None, f"{mod} missing {attr}"
enable_cache_on_dual_transformer(t1, t2, model_name)

# or alias in the model class:
# class MyTransformer: 
#     @property
#     def transformer_blocks(self): return self.layers
Defensive patterns

Strategy: validation

Validate before calling

from sglang.multimodal_gen.runtime.cache.cache_dit_integration import DUAL_TRANSFORMER_BLOCK_ADAPTER_SPECS
spec = DUAL_TRANSFORMER_BLOCK_ADAPTER_SPECS[model_name]
for mod, attr in zip((transformer, transformer_2), spec.blocks_attr):
    if getattr(mod, attr, None) is None:
        config = CacheDitConfig(enabled=False)  # layout mismatch; skip caching
        break

Type guard

def transformers_expose_blocks(t1, t2, spec) -> bool:
    return all(getattr(m, a, None) is not None for m, a in zip((t1, t2), spec.blocks_attr))

Try / catch

try:
    t1, t2 = enable_cache_on_dual_transformer(t1, t2, model_name, cfg, ...)
except ValueError as e:
    if "must expose cache-dit block attributes" in str(e):
        cfg = CacheDitConfig(enabled=False); run uncached
    else:
        raise

Prevention

When it happens

Trigger: Calling enable_cache_on_dual_transformer with transformer or transformer_2 instances whose class does not expose the attribute names declared in the model's DualTransformerBlockAdapterSpec (e.g. an architecture revision renamed blocks to layers, or a wrapper object hides the attribute).

Common situations: Upgrading the model implementation so a blocks attribute was renamed, loading a community/quantized variant with a different module layout, passing the wrong module (e.g. the full pipeline instead of the inner transformer) as transformer_2, or a spec/implementation version mismatch in sglang.

Related errors


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