sgl-project/sglang · error · RuntimeError

DSV4 target and draft pools must share the SWA index mapping

Error message

DSV4 target and draft pools must share the SWA index mapping

What it means

In the non-unified-KV DSV4 path, target and draft pools must share the exact same full_to_swa_index_mapping object. If the draft pool has its own mapping, indices computed on one side would not resolve on the other during state transfer, so setup_state_kv_args raises RuntimeError.

Source

Thrown at python/sglang/srt/disaggregation/utils.py:1180

                draft_token_to_kv_pool.unified_swa_window,
                draft_token_to_kv_pool.unified_swa_ring_size,
                draft_token_to_kv_pool.unified_swa_pages,
            )
            if target_geometry != draft_geometry:
                raise RuntimeError(
                    "DSV4 target and draft pools must share SWA ring geometry: "
                    f"target={target_geometry}, draft={draft_geometry}"
                )
            draft_ptrs, draft_lens, draft_item_lens = (
                draft_token_to_kv_pool.get_unified_swa_ring_buf_infos()
            )
            draft_state_type = StateType.SWA_RING
        else:
            if (
                token_to_kv_pool.full_to_swa_index_mapping
                is not draft_token_to_kv_pool.full_to_swa_index_mapping
            ):
                raise RuntimeError(
                    "DSV4 target and draft pools must share the SWA index mapping"
                )
            target_geometry = (
                token_to_kv_pool.page_size,
                token_to_kv_pool.sliding_window,
            )
            draft_geometry = (
                draft_token_to_kv_pool.page_size,
                draft_token_to_kv_pool.sliding_window,
            )
            if target_geometry != draft_geometry:
                raise RuntimeError(
                    "DSV4 target and draft pools must share paged SWA geometry: "
                    f"target={target_geometry}, draft={draft_geometry}"
                )
            draft_ptrs, draft_lens, draft_item_lens = (
                draft_token_to_kv_pool.get_state_buf_infos()
            )

View on GitHub (pinned to 0132848349)

Solutions

  1. Construct the draft pool with the target pool's full_to_swa_index_mapping object passed in (shared reference)
  2. Upgrade/patch the code that builds the NextN pool so it shares the mapping
  3. Disable speculative decoding if sharing cannot be arranged

Example fix

# before
draft_pool = DeepSeekV4TokenToKVPool(..., full_to_swa_index_mapping=None)  # own mapping
# after
draft_pool = DeepSeekV4TokenToKVPool(..., full_to_swa_index_mapping=target_pool.full_to_swa_index_mapping)
Defensive patterns

Strategy: type-guard

Validate before calling

assert target_pool.full_to_swa_index_mapping is draft_pool.full_to_swa_index_mapping, "draft must share SWA index mapping"

Type guard

def shares_swa_mapping(target, draft) -> bool:
    return target.full_to_swa_index_mapping is draft.full_to_swa_index_mapping

Prevention

When it happens

Trigger: DSV4 disaggregation with spec decoding where the draft DeepSeekV4TokenToKVPool allocated its own full_to_swa_index_mapping tensor instead of being constructed with a reference to the target's mapping.

Common situations: Draft pool constructed independently (fresh mapping) rather than sharing the target pool's mapping; refactors that pass a copied/cloned mapping; version change in pool constructor defaults.

Related errors


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