sgl-project/sglang · error · IndexError

Shared-sink LoRA slot out of range: {sorted(slot_ids)}

Error message

Shared-sink LoRA slot out of range: {sorted(slot_ids)}

What it means

Raised by _refresh_lora_operands when a requested shared-sink LoRA slot index is negative or >= the number of slots in the b_gate_up tensor (slots = b_gate_up.shape[0]). The slot pool size is fixed by the weight tensor, so any out-of-range id is rejected before buffers are zeroed/copied.

Source

Thrown at python/sglang/srt/models/inkling_common/lora.py:123

                "Shared-sink LoRA pool shape changed after initialization: "
                f"gate-up {tuple(self._w1_delta.shape)} -> {expected_gate_up}, "
                f"down-A {tuple(self._a_cat.shape)} -> {expected_down}"
            )

    def on_lora_slots_updated(self, slot_ids: set[int] | None) -> None:
        self._refresh_lora_operands(slot_ids)

    def _refresh_lora_operands(self, slot_ids: set[int] | None = None) -> None:
        if not self.set_lora or self._w1_delta is None or self._a_cat is None:
            return
        b_gate_up = self.gate_up_lora_b_weights
        a_down = self.down_lora_a_weights
        slots, n, two_f, rank = b_gate_up.shape
        f = two_f // 2
        if slot_ids is None:
            slot_ids = set(range(slots))
        elif any(slot < 0 or slot >= slots for slot in slot_ids):
            raise IndexError(f"Shared-sink LoRA slot out of range: {sorted(slot_ids)}")
        with torch.no_grad():
            gate_up = self._w1_delta.view(slots, n, f, 2, 2 * rank)
            a_cat = self._a_cat.view(slots, rank, n, a_down.shape[3])
            for slot in slot_ids:
                gate_up[slot].zero_()
                gate_up[slot, :, :, 0, :rank].copy_(b_gate_up[slot, :, :f, :])
                gate_up[slot, :, :, 1, rank:].copy_(b_gate_up[slot, :, f:, :])
                a_cat[slot].copy_(a_down[slot].permute(1, 0, 2))

    def slice_moe_lora_a_weights(
        self,
        weights: torch.Tensor | dict[int, torch.Tensor],
        tp_rank: int,
        target_module: str,
    ) -> torch.Tensor | dict[int, torch.Tensor]:
        if isinstance(weights, torch.Tensor) and weights.dim() == 2:
            if target_module == "gate_up_proj_moe":
                weights = weights.unsqueeze(0)

View on GitHub (pinned to 0132848349)

Solutions

  1. Check the slot count: ensure every id in slot_ids satisfies 0 <= slot < b_gate_up.shape[0] before calling set_lora_info/on_lora_slots_updated
  2. Re-align the LoRA slot allocation so the buffer's first dimension matches the scheduler's slot ids
  3. If passing None is intended, omit slot_ids so all slots are refreshed

Example fix

# before
model.set_lora_info(slot_ids=[0, 1, 2])  # buffer only has 2 slots
# after
assert all(0 <= s < b_gate_up.shape[0] for s in slot_ids)
model.set_lora_info(slot_ids=slot_ids)
Defensive patterns

Strategy: validation

Validate before calling

n_slots = b_gate_up.shape[0]
slot_ids = [s for s in slot_ids if 0 <= s < n_slots]  # or assert
assert all(0 <= s < n_slots for s in slot_ids), f"slots must be in [0, {n_slots})"

Try / catch

try:
    model.set_lora_info(...)
except IndexError as e:
    if 'LoRA slot out of range' in str(e):
        logger.error('Realigning LoRA slot pool'); raise

Prevention

When it happens

Trigger: Calling set_lora_info or on_lora_slots_updated with slot_ids containing an index outside range(b_gate_up.shape[0]); e.g. adapter metadata advertises more LoRA slots than the shared-sink buffer was allocated with.

Common situations: Mismatch between the number of LoRA slots configured at model init and the ids supplied by the LoRA scheduler after a config change; stale slot registry after resizing the LoRA pool.

Related errors


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