sgl-project/sglang · error · ValueError

Unsupported V4 paged host layout/backend: {self.layout}/{io_

Error message

Unsupported V4 paged host layout/backend: {self.layout}/{io_backend}

What it means

backup_from_device_all_layer copies all layers of KV data from device to host and dispatches on (self.layout, io_backend). An unsupported combination falls through to a ValueError naming both values.

Source

Thrown at python/sglang/srt/mem_cache/memory_pool_host.py:432

                )
        elif io_backend == "direct" and self.layout == "layer_first":
            transfer_kv_direct(
                src_layers=self.device_buffers,
                dst_layers=self.data_refs,
                src_indices=device_rows,
                dst_indices=host_rows,
                page_size=1,
            )
        elif io_backend == "direct" and self.layout == "page_first_direct":
            transfer_kv_all_layer_direct_lf_pf(
                src_ptrs=self.device_buffers,
                dst_ptrs=[self.kv_buffer],
                src_indices=device_rows,
                dst_indices=host_rows,
                page_size=1,
            )
        else:
            raise ValueError(
                f"Unsupported V4 paged host layout/backend: {self.layout}/{io_backend}"
            )

    def load_to_device_per_layer(
        self,
        device_pool,
        host_indices,
        device_indices,
        layer_id,
        io_backend,
        *,
        is_draft: bool = False,
    ):
        if not self._has_transfer_indices(host_indices, device_indices):
            return
        if (
            host_indices.numel() % self.slot_page_size != 0
            or device_indices.numel() % self.slot_page_size != 0

View on GitHub (pinned to 0132848349)

Solutions

  1. Check the implemented (layout, io_backend) branches in memory_pool_host.py and pass a supported io_backend (usually the default syscall path)
  2. Use a layout that has a copy path for your chosen backend (e.g. page_first_direct)
  3. Upgrade/downgrade SGLang so pool code and the caller's io_backend selection agree

Example fix

# before
pool.backup_from_device_all_layer(dev_rows, host_rows, io_backend="kdma")

# after
pool.backup_from_device_all_layer(dev_rows, host_rows, io_backend="syscall")
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED_PAIRS = {("page_first_direct", "syscall"), ("layer_first", "syscall")}
assert (pool.layout, io_backend) in SUPPORTED_PAIRS

Type guard

null

Try / catch

try:
    pool.backup_from_device_all_layer(...)
except ValueError as e:
    logger.error("unsupported transfer pair: %s", e)
    raise

Prevention

When it happens

Trigger: Calling backup_from_device_all_layer(...) when the pool's layout and the io_backend argument (e.g. 'syscall' vs 'kdma'/'batch_copy' variants) form a pair with no implemented copy path.

Common situations: Selecting a KDMA or experimental DMA io_backend with a layout that only supports syscall copies; mixing a pool constructed with one layout with transfer code paths expecting another; version mismatch where a backend branch was removed or renamed.

Related errors


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