sgl-project/sglang · error · ValueError

PD DCP transfer requires decode_prefix_len to align to the v

Error message

PD DCP transfer requires decode_prefix_len to align to the virtual DCP page size ({virtual_page_size}), got {decode_prefix_len}

What it means

build_dcp_token_transfer_plan maps token positions onto DCP virtual pages (physical_page_size * dcp_size). It requires decode_prefix_len to be a multiple of the virtual page size so token positions align to page boundaries on all DCP ranks; otherwise the rank mapping math would be wrong.

Source

Thrown at python/sglang/srt/disaggregation/common/utils.py:157

class DCPTokenTransferPlan:
    src_token_indices: npt.NDArray[np.int64]
    dst_token_indices: npt.NDArray[np.int64]


def build_dcp_token_transfer_plan(
    src_page_indices: npt.NDArray[np.int32],
    dst_page_indices: npt.NDArray[np.int32],
    *,
    physical_page_size: int,
    dcp_size: int,
    dcp_rank: int,
    src_page_offset: int = 0,
    decode_prefix_len: int = 0,
    num_kv_tokens: Optional[int] = None,
) -> DCPTokenTransferPlan:
    virtual_page_size = physical_page_size * dcp_size
    if decode_prefix_len % virtual_page_size != 0:
        raise ValueError(
            "PD DCP transfer requires decode_prefix_len to align to the virtual "
            f"DCP page size ({virtual_page_size}), got {decode_prefix_len}"
        )

    src_pages = np.asarray(src_page_indices, dtype=np.int64)
    dst_pages = np.asarray(dst_page_indices, dtype=np.int64)
    source_capacity = src_pages.size * physical_page_size
    if num_kv_tokens is None:
        num_kv_tokens = source_capacity
    if not 0 <= num_kv_tokens <= source_capacity:
        raise ValueError(
            "num_kv_tokens must fit in the provided source pages, "
            f"got tokens={num_kv_tokens}, capacity={source_capacity}"
        )
    if src_pages.size == 0:
        empty = np.empty((0,), dtype=np.int64)
        return DCPTokenTransferPlan(empty, empty.copy())

View on GitHub (pinned to 0132848349)

Solutions

  1. Pad decode_prefix_len up to the next virtual page boundary before building the plan
  2. Verify page_size and dcp_size on both sides so the virtual page size matches what produced the prefix
  3. Ensure prefix cache entries only keep aligned lengths when DCP is in use

Example fix

# before
plan = build_dcp_token_transfer_plan(
    physical_page_size=page_size, dcp_size=dcp_size,
    decode_prefix_len=100, ...)  # virtual page 64 -> raises
# after
vpage = page_size * dcp_size
decode_prefix_len = ((100 + vpage - 1) // vpage) * vpage
plan = build_dcp_token_transfer_plan(
    physical_page_size=page_size, dcp_size=dcp_size,
    decode_prefix_len=decode_prefix_len, ...)
Defensive patterns

Strategy: validation

Validate before calling

vpage = physical_page_size * dcp_size
assert decode_prefix_len % vpage == 0, f'prefix {decode_prefix_len} not aligned to {vpage}'

Prevention

When it happens

Trigger: Calling send_kvcache_dcp with a decode_prefix_len not divisible by virtual_page_size = physical_page_size * dcp_size — e.g. prefix 100 with page_size 16 and dcp_size 4 (virtual 64).

Common situations: Prefix caching returning a non-aligned prefix length; chunked prefill leaving a partial virtual page; mismatched page_size between the servers shifting the prefix boundary.

Related errors


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