{"record":{"id":"516b4344f4f43b8b","repo":"sgl-project/sglang","slug":"dots-swa-latent-decode-requires-page-size-64-got","errorCode":null,"errorMessage":"Dots SWA latent decode requires page_size=64, got {backend.page_size}.","messagePattern":"Dots SWA latent decode requires page_size=64, got (.+?)\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/layers/attention/dots_hybrid_backend.py","lineNumber":363,"sourceCode":"            max_seqlen_k=metadata.max_seq_len_k,\n            softmax_scale=layer.scaling,\n            causal=True,\n            window_size=(layer.sliding_window_size, 0),\n            ver=self._active_backend.fa_impl_ver,\n        )\n        if pad_v_to_qk:\n            output = output[..., : layer.v_head_dim]\n        return output.reshape(-1, layer.tp_q_head_num * layer.v_head_dim)\n\n    def forward_swa_mla_absorbed(self, q, layer, forward_batch):\n        \"\"\"Run decode directly against the page64 latent SWA cache.\"\"\"\n        from sglang.srt.layers.attention.swa_mla_fallback.forward import (\n            forward_dense_kvlora_swa_torch_fallback,\n        )\n\n        backend = self.selected_backend(forward_batch)\n        if backend.page_size != 64:\n            raise RuntimeError(\n                \"Dots SWA latent decode requires page_size=64, \"\n                f\"got {backend.page_size}.\"\n            )\n\n        self.maybe_rebuild_metadata_after_dp_padding(forward_batch)\n        metadata = backend.forward_metadata\n        block_table = metadata.swa_page_table\n        if block_table is None:\n            raise RuntimeError(\"Dots SWA latent decode requires an SWA page table.\")\n        bs = forward_batch.batch_size\n        block_table = _normalize_page_table_rows(block_table, bs)\n        cache_seqlens = _normalize_cache_seqlens_rows(\n            metadata.cache_seqlens_int32,\n            forward_batch.seq_lens,\n            bs,\n        )\n        reshape_q = q.view(bs, -1, layer.tp_q_head_num, layer.head_dim)\n        k_cache = self.token_to_kv_pool.get_key_buffer(layer.layer_id)","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/layers/attention/dots_hybrid_backend.py#L345-L381","documentation":"The Dots hybrid SWA latent-decode path (forward_swa_mla_absorbed) assumes paged KV with page_size=64; its kernels index pages at that granularity. At runtime, if the selected backend's page_size differs, the forward raises RuntimeError before corrupting the KV cache.","triggerScenarios":"Calling forward_swa_mla_absorbed on a Dots hybrid model where backend.page_size != 64 — typically because the server was launched with --page-size 1/16/32 or the backend default resolved to another page size.","commonSituations":"Tuning page size for other models then serving a Dots hybrid checkpoint; mixing FlashInfer-style page-size overrides with the Dots SWA MLA kernels.","solutions":["Launch with --page-size 64","Remove any page-size override so a compatible default is chosen, if the default is 64","Avoid routing Dots SWA latent decode through a backend with a different page size"],"exampleFix":"# before\n--page-size 16  # Dots hybrid model\n# after\n--page-size 64","handlingStrategy":"validation","validationCode":"backend = self.selected_backend(forward_batch)\nassert backend.page_size == 64, \"launch Dots hybrid models with --page-size 64\"","typeGuard":"def dots_swa_compatible(page_size: int) -> bool:\n    return page_size == 64","tryCatchPattern":null,"preventionTips":["Set --page-size 64 in the model-specific launch template for Dots hybrids","Add a startup assertion on page_size for page-size-sensitive backends"],"tags":["dots-hybrid","swa-mla","page-size","attention-backend","sglang"],"backgroundTag":"page-size-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}