sgl-project/sglang · error · RuntimeError

DSA indexer weights_proj LoRA is incompatible with piecewise

Error message

DSA indexer weights_proj LoRA is incompatible with piecewise/breakable CUDA graph; remove the explicit prefill cuda-graph backend override or drop indexer.weights_proj from the LoRA target modules.

What it means

Under a piecewise/breakable CUDA graph (PCG/BCG) prefill path, the DSA indexer runs as a single eager split op and cannot apply a LoRA adapter to the weights_proj projection inside that path. If weights_proj is among the LoRA target modules, the indexer raises with GRAPH_WEIGHTS_PROJ_LORA_ERROR instead of silently dropping the adapter.

Source

Thrown at python/sglang/srt/layers/attention/dsa/dsa_indexer.py:1651

        if (
            self.use_dsa_indexer_fusion
            and not in_piecewise_or_breakable_cuda_graph
            and forward_batch.attn_cp_metadata is None
        ):
            q_fp8, weights = self._fused_q_prepare_and_store(
                x, q_lora, positions, forward_batch, layer_id, act_quant
            )
        elif (
            is_graph_dsa_split_op_surface(forward_batch)
            and not self.dsa_enable_prefill_cp
        ):
            # Default path for non-CP prefill under PCG/BCG: run the whole indexer
            # (q/k proj, head gate, k-cache store, topk) as a single eager split op
            # instead of capturing it piecemeal in the graph. The split op is
            # fusion-aware, so this also covers the fused path here.
            if weights_proj_lora:
                raise RuntimeError(GRAPH_WEIGHTS_PROJ_LORA_ERROR)
            if return_indices:
                topk_result = torch.full(
                    (x.shape[0], self.index_topk),
                    -1,
                    device=x.device,
                    dtype=torch.int32,
                )
            else:
                topk_result = torch.empty(
                    (0, self.index_topk), device=x.device, dtype=torch.int32
                )
            graph_dispatch_fn = (
                bcg_dsa_indexer_prefill_split
                if is_in_breakable_cuda_graph()
                else pcg_dsa_indexer_prefill_split
            )
            graph_dispatch_fn(
                layer_id=layer_id,

View on GitHub (pinned to 0132848349)

Solutions

  1. Remove indexer.weights_proj from the LoRA target modules list
  2. Drop the explicit prefill cuda-graph backend override so the non-PCG path handles the weights_proj LoRA
  3. If wildcard target_modules are used, exclude the indexer submodule explicitly

Example fix

# before
"target_modules": [".*proj.*"]  # catches indexer.weights_proj under PCG
# after
"target_modules": ["q_proj", "k_proj", "v_proj", "o_proj"]
Defensive patterns

Strategy: validation

Validate before calling

lora_targets = set(lora_request.target_modules) if lora_request else set()
if "indexer.weights_proj" in lora_targets and using_piecewise_prefill_graph:
    lora_targets.discard("indexer.weights_proj")  # or drop the graph override

Type guard

def lora_compatible_with_pcg(target_modules) -> bool:
    return "indexer.weights_proj" not in target_modules

Prevention

When it happens

Trigger: Serving a DSA model (DeepSeek sparse attention) with a LoRA adapter whose target modules include indexer.weights_proj, while the prefill path runs under a piecewise/breakable CUDA graph (explicit prefill cuda-graph backend override selecting PCG/BCG).

Common situations: Applying an indexer-tuned LoRA on DeepSeek-V3.2 with --cuda-graph-backend overrides; LoRA configs that wildcard target_modules (e.g. '.*proj.*') catching indexer.weights_proj unintentionally.

Related errors


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