A high-throughput and memory-efficient inference and serving engine for LLMs
Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git
Synced Nov 5, 07:15 UTC
[Gemma4][Bugfix]: Enable Gemma4ForCasualLM to load lora adapters correctly (#38844)
Signed-off-by: ShubyM <shubymishra20@gmail.com>
ShubyM committed
Apr 11, 2026 at 02:06 UTC
92feb9991d153bb36f2be802cc7eaac33f8f4695
2 files changed
+40
tests/lora/test_lora_checkpoints.py
+23
@@ -5,7 +5,9 @@ import pytest
5
6
from vllm.lora.lora_model import LoRAModel
7
from vllm.lora.peft_helper import PEFTHelper
8
+from vllm.lora.utils import parse_fine_tuned_lora_name
9
from vllm.model_executor.models.baichuan import BaiChuanBaseForCausalLM
10
+from vllm.model_executor.models.gemma4 import Gemma4ForCausalLM
11
from vllm.model_executor.models.utils import WeightsMapper
12
13
lora_lst = ["baichuan7B", "baichuan7B-zero", "baichuan7B-zero-regex", "chatglm3-6b"]
@@ -128,3 +130,24 @@ def test_lora_weights_mapping(baichuan_lora_files):
130
for name in lora_model.loras:
131
assert name.startswith(hf_to_vllm_mapper.orig_to_new_prefix["model."])
132
assert ".baichuan_layers." in name
133
+
134
+
135
+def test_gemma4_lora_weights_mapping():
136
+ mapper = Gemma4ForCausalLM.hf_to_vllm_mapper
137
+ name = "base_model.model.model.language_model.layers.9.mlp.down_proj.lora_A.weight"
138
+ assert parse_fine_tuned_lora_name(name, mapper) == (
139
+ "model.layers.9.mlp.down_proj",
140
+ True,
141
+ )
142
+
143
+
144
+def test_gemma4_moe_lora_weights_mapping():
145
+ mapper = Gemma4ForCausalLM.hf_to_vllm_mapper
146
+ name = (
147
+ "base_model.model.model.language_model.layers.9.moe.experts."
148
+ "gate_up_proj.lora_B.weight"
149
+ )
150
+ assert parse_fine_tuned_lora_name(name, mapper) == (
151
+ "model.layers.9.moe.gate_up_proj",
152
+ False,
153
+ )
vllm/model_executor/models/gemma4.py
+17
@@ -69,6 +69,7 @@ from .interfaces import (
69
)
70
from .utils import (
71
AutoWeightsLoader,
72
+ WeightsMapper,
73
extract_layer_index,
74
is_pp_missing_parameter,
75
make_layers,
@@ -1397,6 +1398,22 @@ class Gemma4Model(nn.Module, EagleModelMixin):
1398
class Gemma4ForCausalLM(
1399
nn.Module, SupportsLoRA, SupportsPP, MixtureOfExperts, SupportsEagle3
1400
):
1401
+ hf_to_vllm_mapper = WeightsMapper(
1402
+ orig_to_new_prefix={
1403
+ # Gemma4ForConditionalGeneration already loads the text stack
1404
+ # from `model.language_model.*`. We reuse that same checkpoint
1405
+ # and adapter naming for the text-only Gemma4ForCausalLM path,
1406
+ # so LoRA keys from the conditional wrapper map onto `model.*`.
1407
+ "model.language_model.": "model.",
1408
+ },
1409
+ orig_to_new_substr={
1410
+ # Gemma4ForConditionalGeneration names MoE adapter targets under
1411
+ # `...moe.experts.*`, while the text-only model exposes them
1412
+ # under `...moe.*`.
1413
+ ".moe.experts.gate_up_proj": ".moe.gate_up_proj",
1414
+ ".moe.experts.down_proj": ".moe.down_proj",
1415
+ },
1416
+ )
1417
# Note: qkv_proj packing applies to non-k_eq_v layers (sliding
1418
# attention and full attention without k_eq_v). k_eq_v layers use
1419
# separate q_proj + k_proj without packing.