@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 92feb9991d
Fork 0

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.