sgl-project/sglang · error · ValueError

Dynamic LoRA currently supports only one adapter per target.

Error message

Dynamic LoRA currently supports only one adapter per target. Use merge_mode='merge' for multiple adapters.

What it means

In dynamic merge mode LoRA weights stay unmerged and are applied at runtime, which the implementation only supports for a single adapter per target. If _should_merge_lora_for_layers resolves to non-merged and multiple nicknames target the same module set, this error is raised.

Source

Thrown at python/sglang/multimodal_gen/runtime/pipelines_core/lora/pipeline.py:1043

            tgt_nicknames = [lora_nicknames[i] for i in idx_list]
            tgt_paths = [
                lora_paths[i] or self.loaded_adapter_paths.get(lora_nicknames[i])
                for i in idx_list
            ]
            tgt_strengths = [strengths[i] for i in idx_list]

            merged_name = (
                ",".join(tgt_nicknames) if len(tgt_nicknames) > 1 else tgt_nicknames[0]
            )

            # Skip if LoRA configuration matches exactly (including order and strength)
            # Since all modules for the same target apply the same config, checking one is sufficient
            first_module_name, first_lora_layers_dict = target_modules[0]
            first_effective_merge_weights = self._should_merge_lora_for_layers(
                first_module_name, first_lora_layers_dict, merge_mode
            )
            if not first_effective_merge_weights and len(tgt_nicknames) > 1:
                raise ValueError(
                    "Dynamic LoRA currently supports only one adapter per target. "
                    "Use merge_mode='merge' for multiple adapters."
                )

            merge_weights_by_module = {}
            for module_name, lora_layers_dict in target_modules:
                merge_weights_by_module[module_name] = (
                    first_effective_merge_weights
                    if module_name == first_module_name
                    else self._should_merge_lora_for_layers(
                        module_name, lora_layers_dict, merge_mode
                    )
                )

            if self._check_lora_config_matches(
                first_module_name,
                tgt_nicknames,
                tgt_strengths,

View on GitHub (pinned to 0132848349)

Solutions

  1. Pass merge_mode='merge' so adapters are merged into base weights
  2. Restrict each target to a single adapter in dynamic mode

Example fix

# before
pipeline.set_lora(lora_paths=[pa,pb], lora_nicknames=['a','b'], targets=['attn'])  # default dynamic
# after
pipeline.set_lora(lora_paths=[pa,pb], lora_nicknames=['a','b'], targets=['attn'], merge_mode='merge')
Defensive patterns

Strategy: validation

Validate before calling

from collections import Counter
cnt = Counter(nickname for _, tgt in assignments for nickname in tgt)
if any(v > 1 for v in cnt.values()): merge_mode = 'merge'

Prevention

When it happens

Trigger: set_lora with two adapters sharing a target and merge_mode='dynamic' (or server default dynamic), e.g. lora_nicknames=['a','b'], targets=['attn'] for both.

Common situations: Composing multiple style adapters on the same layers without specifying merge mode; server default lora_merge_mode is 'dynamic' and user adds a second adapter.

Related errors


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