From d896aa54ee1efbb4dfb4fbf0210d8a9c9e4df4e9 Mon Sep 17 00:00:00 2001 From: Beichen-Ma Date: Thu, 21 Aug 2025 05:31:17 +0000 Subject: [PATCH 1/3] Add target module validation for init adapters --- python/sglang/srt/lora/lora_manager.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/python/sglang/srt/lora/lora_manager.py b/python/sglang/srt/lora/lora_manager.py index ef1120d1e8a..54025b0aa56 100644 --- a/python/sglang/srt/lora/lora_manager.py +++ b/python/sglang/srt/lora/lora_manager.py @@ -422,6 +422,28 @@ def init_lora_shapes( if target_modules is not None: self.target_modules = set(target_modules) + user_normalized_modules = get_normalized_target_modules(self.target_modules) + for lora_id, config in self.configs.items(): + if not isinstance(config.target_modules, list): + raise ValueError( + f"SGLang currently only supports inferring LoRA target modules when a list of " + "suffixes is provided in `target_modules` field of PEFT config. Please explicitly " + "specify `--lora-target-modules` during server startup. You can specify `all` to " + "enable all support modules types. " + ) + config_normalized_modules = get_normalized_target_modules( + config.target_modules + ) + if not config_normalized_modules.issubset(user_normalized_modules): + unsupported_modules = ( + config_normalized_modules - user_normalized_modules + ) + raise ValueError( + f"LoRA adapter '{lora_id}' contains target modules {sorted(unsupported_modules)} " + f"that are not included in the specified --lora-target-modules {sorted(user_normalized_modules)}. " + f"Please update --lora-target-modules to include all required modules: " + f"{sorted(user_normalized_modules | config_normalized_modules)}, or use 'all' to enable all supported modules." + ) else: self.target_modules = set() for config in self.configs.values(): From 02b3f708d90f1c25f3c06f749c50a2493ecfd76c Mon Sep 17 00:00:00 2001 From: Beichen-Ma Date: Thu, 21 Aug 2025 08:09:55 +0000 Subject: [PATCH 2/3] refine --- python/sglang/srt/lora/lora_manager.py | 37 +++++++++++++------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/python/sglang/srt/lora/lora_manager.py b/python/sglang/srt/lora/lora_manager.py index 54025b0aa56..9b0736eddf3 100644 --- a/python/sglang/srt/lora/lora_manager.py +++ b/python/sglang/srt/lora/lora_manager.py @@ -423,14 +423,20 @@ def init_lora_shapes( if target_modules is not None: self.target_modules = set(target_modules) user_normalized_modules = get_normalized_target_modules(self.target_modules) - for lora_id, config in self.configs.items(): - if not isinstance(config.target_modules, list): - raise ValueError( - f"SGLang currently only supports inferring LoRA target modules when a list of " - "suffixes is provided in `target_modules` field of PEFT config. Please explicitly " - "specify `--lora-target-modules` during server startup. You can specify `all` to " - "enable all support modules types. " - ) + else: + self.target_modules = set() + user_normalized_modules = None + + for lora_id, config in self.configs.items(): + if not isinstance(config.target_modules, list): + raise ValueError( + f"SGLang currently only supports inferring LoRA target modules when a list of " + "suffixes is provided in `target_modules` field of PEFT config. Please explicitly " + "specify `--lora-target-modules` during server startup. You can specify `all` to " + "enable all support modules types. " + ) + + if target_modules is not None: config_normalized_modules = get_normalized_target_modules( config.target_modules ) @@ -438,23 +444,16 @@ def init_lora_shapes( unsupported_modules = ( config_normalized_modules - user_normalized_modules ) + lora_name = self.lora_refs[lora_id].lora_name raise ValueError( - f"LoRA adapter '{lora_id}' contains target modules {sorted(unsupported_modules)} " + f"LoRA adapter '{lora_name}' contains target modules {sorted(unsupported_modules)} " f"that are not included in the specified --lora-target-modules {sorted(user_normalized_modules)}. " f"Please update --lora-target-modules to include all required modules: " f"{sorted(user_normalized_modules | config_normalized_modules)}, or use 'all' to enable all supported modules." ) - else: - self.target_modules = set() - for config in self.configs.values(): - if not isinstance(config.target_modules, list): - raise ValueError( - f"SGLang currently only supports inferring LoRA target modules when a list of " - "suffixes is provided in `target_modules` field of PEFT config. Please explicitly " - "specify `--lora-target-modules` during server startup. You can specify `all` to " - "enable all support modules types. " - ) + else: self.target_modules.update(config.target_modules) + self.target_modules = get_normalized_target_modules(self.target_modules) if max_lora_rank is not None: From 7107b2a13e7317fb1b4408bd7940a457c39fb9bb Mon Sep 17 00:00:00 2001 From: Lifu Huang Date: Thu, 21 Aug 2025 14:03:17 -0700 Subject: [PATCH 3/3] Refactor to eliminate redundant `get_normalized_target_modules` calls. --- python/sglang/srt/lora/lora_manager.py | 30 +++++++++++--------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/python/sglang/srt/lora/lora_manager.py b/python/sglang/srt/lora/lora_manager.py index 9b0736eddf3..cca20a9a617 100644 --- a/python/sglang/srt/lora/lora_manager.py +++ b/python/sglang/srt/lora/lora_manager.py @@ -420,13 +420,8 @@ def init_lora_shapes( ): """Infer LoRA target modules and max_lora_rank from loaded adapters if not provided.""" - if target_modules is not None: - self.target_modules = set(target_modules) - user_normalized_modules = get_normalized_target_modules(self.target_modules) - else: - self.target_modules = set() - user_normalized_modules = None - + self.target_modules = get_normalized_target_modules(target_modules) if target_modules else set() + for lora_id, config in self.configs.items(): if not isinstance(config.target_modules, list): raise ValueError( @@ -436,25 +431,26 @@ def init_lora_shapes( "enable all support modules types. " ) + adapter_target_modules = get_normalized_target_modules( + config.target_modules + ) + if target_modules is not None: - config_normalized_modules = get_normalized_target_modules( - config.target_modules - ) - if not config_normalized_modules.issubset(user_normalized_modules): + # When `--lora-target-modules` is provided, validate adapter target modules is a subset of the specified target modules. + if not adapter_target_modules.issubset(self.target_modules): unsupported_modules = ( - config_normalized_modules - user_normalized_modules + adapter_target_modules - self.target_modules ) lora_name = self.lora_refs[lora_id].lora_name raise ValueError( f"LoRA adapter '{lora_name}' contains target modules {sorted(unsupported_modules)} " - f"that are not included in the specified --lora-target-modules {sorted(user_normalized_modules)}. " + f"that are not included in the specified --lora-target-modules {sorted(self.target_modules)}. " f"Please update --lora-target-modules to include all required modules: " - f"{sorted(user_normalized_modules | config_normalized_modules)}, or use 'all' to enable all supported modules." + f"{sorted(self.target_modules | adapter_target_modules)}, or use 'all' to enable all supported modules." ) else: - self.target_modules.update(config.target_modules) - - self.target_modules = get_normalized_target_modules(self.target_modules) + # Otherwise, infer target_modules from adapter configs. + self.target_modules.update(adapter_target_modules) if max_lora_rank is not None: self.max_lora_rank = max_lora_rank