sgl-project/sglang · error · ValueError

Index buffer transfer expects page-aligned indices for DSA.

Error message

Index buffer transfer expects page-aligned indices for DSA.

What it means

DSA index buffer transfers move whole pages between host and device, so the flat token indices must be a multiple of page_size. _get_indexer_page_indices validates this and converts token indices to page indices by reshape(-1, page_size)[:, 0] // page_size.

Source

Thrown at python/sglang/srt/mem_cache/pool_host/dsa.py:209

        self.staging_buffer = torch.empty(
            (
                staging_page_capacity,
                self.layer_num,
                1,
                self.indexer_page_stride_size,
            ),
            dtype=self.indexer_dtype,
            device=self.device_pool.device,
        )

    def get_hybrid_pool_buffer(self):
        return [self.index_k_with_scale_buffer]

    def _get_indexer_page_indices(self, host_indices, device_indices):
        if host_indices.numel() == 0:
            return host_indices, device_indices
        if host_indices.numel() % self.page_size != 0:
            raise ValueError(
                "Index buffer transfer expects page-aligned indices for DSA."
            )
        host_page_indices = (
            host_indices.reshape(-1, self.page_size)[:, 0] // self.page_size
        )
        device_page_indices = (
            device_indices.reshape(-1, self.page_size)[:, 0] // self.page_size
        )
        return host_page_indices, device_page_indices

    def load_to_device_per_layer(
        self,
        device_pool,
        host_indices,
        device_indices,
        layer_id,
        io_backend,
        *,

View on GitHub (pinned to 0132848349)

Solutions

  1. Ensure transfer batches are padded/rounded up to whole pages before calling transfer APIs
  2. Verify the page_size used to generate indices matches the pool's page_size
  3. Fix the calling scheduler/evictor to never emit partial pages

Example fix

# before
host_indices = torch.tensor([0,1,2])  # page_size=4
# after
host_indices = host_indices[: len(host_indices) // page_size * page_size]  # drop partial page
Defensive patterns

Strategy: validation

Validate before calling

assert host_indices.numel() % page_size == 0

Prevention

When it happens

Trigger: Calling load_to_device_per_layer / backup_from_device_all_layer with host_indices whose length is not divisible by the DSA page size (partial page at the end of the batch).

Common situations: Custom or edge-case eviction/writeback paths that batch a non-page-aligned number of tokens; page_size misconfiguration where indices were computed with a different page size than the pool's.

Related errors


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