打补丁让 vLLM 支持 lm_head LoRA:GEV-26B-Decide-NVFP4 单引擎部署内幕与 2 个关键 Patch 剖析
【免费下载链接】GEV-26B-Decide-NVFP4项目地址: https://ai.gitcode.com/hf_mirrors/autotrust/GEV-26B-Decide-NVFP4
GEV-26B-Decide-NVFP4 是基于 Gemma-4 的开源决策模型的 NVFP4 量化版:用单引擎部署就能同时提供 45ms 即时决策(System 1)与自适应深度思考(System 2)。本文剖析它的部署内幕——只需打补丁让 vLLM 支持 lm_head LoRA(2 个关键 Patch),就能让"决策头"和"思考大脑"共享同一个推理引擎,并把 50 GB 的模型压进 17 GB 显存。
📦 模型速览:NVFP4 量化,26B 决策模型只要 17 GB
GEV-26B-Decide 是一个"类型化决策模型":对文本或图片提出是非题、0–5 分评分、2–256 选项选择题,直接输出每个选项的校准概率,而不生成一段文本。它的底层是一个 26B MoE(30 层 × 128 专家 = 3840 个路由专家)。
NVFP4 版本只量化了占比最大的路由专家权重,其余部分(注意力、稠密 MLP、路由器、视觉塔、lm_head、System 1 适配器、决策头)全部保持 bf16 不变。量化配置见 hf_quant_config.json,其中lm_head被明确列入排除清单——这一点后面会解释为什么重要:
| 指标 | bf16 原版 | NVFP4 版 |
|---|---|---|
| 下载体积 | 49.5 GB | 18 GB |
| vLLM 权重显存 | 51.1 GiB | 17.1 GiB(−66%) |
也就是说,整模型可以塞进一张 24 GB 显卡,还能留出空间给上下文。
🧠 单引擎部署核心思路:把决策头伪装成 lm_head LoRA
这个项目的巧妙之处在于"一个 vLLM 引擎,两个系统":
- System 2(思考大脑):未改动的 Gemma-4 基座模型,走标准 OpenAI 接口,可思考、可看图;
- System 1(即时决策):加载名为
jev-decision的 LoRA 模块,一次前向就输出概率分布,中位数 45ms。
关键问题在于:System 1 的"决策头"是一个 24 槽位的线性读出层(head.safetensors,2816 → 24),在 vLLM 里并没有现成的加载位置。作者的解法(见 serve_decide.py 的设计说明):
- 把基座 LoRA 和决策头一起打包进一个 PEFT 适配器——适配器 adapter_vllm/adapter_config.json 的
target_modules里赫然包含lm_head; - 决策逻辑不再自定义算子,而是读取 lm_head-LoRA 之后、verbalizer 词元(
true/false、0–5、A–P)的 logprobs,再叠加偏置与温度,得到最终概率。槽位布局与读出细节记录在 adapter_vllm/decision_head.json。
这样 vLLM 的推理内核完全不用写新代码,直接复用标准的 processed logprobs 通路。
但这条路在当时的 vLLM 上根本跑不通,障碍有两个,对应 patches/vllm-gemma4-lm-head-lora.patch 中的 2 个提交。
🔧 Patch 1:放开词表上限 + 声明 lm_head 为 embedding 模块
改动一:LoRA 词表上限 258048 → 262144
vLLM 的 logits 处理器有一个硬性检查:启用 LoRA 时词表大小必须 ≤ 258048,否则直接抛异常。而 Gemma-4 的词表恰好是262,144——超出上限 4000,服务启动即失败。
Patch 1 把上限改为 262144(patch 第 16–25 行),并注明"已通过 Gemma-4-26B-A4B 的输出一致性验证"——即放开上限后,输出分布与未改动前完全一致。
改动二:用 embedding_modules 映射 lm_head LoRA
由于 Gemma-4 的 lm_head 与输入嵌入共享权重(tied weights),vLLM 默认不知道该如何把 PEFT 里lm_head这个 LoRA 目标挂到 logits 处理器上。Patch 1 在 Gemma-4 模型类中补充了一段声明(patch 第 37–43 行):
embedding_modules = { "lm_head": "output_embeddings", }它把 PEFT 的lm_headLoRA 目标映射到 vLLM 的 logits-processor LoRA 包装器上。因为 lm_head 与输入嵌入同权重,LoRA 增量只作用在输出 logits 上(且发生在 Gemma 最终 logits soft-cap 之前):不激活 LoRA 时,输入嵌入和基座 logits 完全不受影响——这正是"单引擎双系统"能干净共存的前提。
🐛 Patch 2:修复 Gemma-4 模块别名导致的 LoRA 静默重置
如果说 Patch 1 是"启动不了",Patch 2 修的是一个更阴险的"悄悄算错"。
Bug 原理:两条路径指向同一个 LoRA 包装器
Gemma-4 的模型结构里,同一个物理层有两个模块路径可以访问到(model.layers.N和model.self_decoder.decoder_layers.N)。vLLM 的 LoRA 管理器激活适配器时,会遍历所有模块路径逐个写入权重;两条别名路径最终指向同一个物理 LoRA 包装器,于是后写入的那条路径(没有权重)调用了reset_lora,把刚加载好的权重清零——没有报错、没有日志,只是概率输出全错。
修复方式:按物理模块去重
Patch 2(patch 第 51–87 行)在上游 vLLM 39816 号 PR 的基础上做了回移修复:激活时用id(module)识别物理模块,每个物理模块只保留一个条目,并且优先选择带有权重的路径,确保任何别名都不会重置刚加载的权重。
这类"静默失败"bug 对新手尤其危险:服务正常启动、请求正常返回,唯一线索是概率分布和预期对不上。
⚡ 部署实操:serve.sh 一键启动单引擎
两个 Patch 打上后,部署只需要一行命令(完整说明见 README.md 的 Quick Start 一节):
hf download autotrust/GEV-26B-Decide-NVFP4 --local-dir GEV-26B-Decide-NVFP4 MODEL_DIR=GEV-26B-Decide-NVFP4 bash GEV-26B-Decide-NVFP4/serve.sh # vLLM 起在 :8000serve.sh 的本质是标准 vLLM OpenAI 服务加几个关键参数:
--enable-lora --max-lora-rank 32 --lora-modules jev-decision=<模型目录>/adapter_vllm --logprobs-mode processed_logprobs --max-logprobs 256--lora-modules jev-decision=...:挂载决策 LoRA(就是 Patch 让 vLLM 能加载的那个 lm_head LoRA);--logprobs-mode processed_logprobs:读取经过 lm_head LoRA 修正后的 logprobs,决策概率正是从这里算出;- serve_decide.py 在标准接口之外新增了
POST /v1/decide,支持thinking: "auto"的自适应思考。
对新手友好的地方:vLLM 自动从 config.json / hf_quant_config.json 读取出 NVFP4 量化方式,无需任何量化参数;启动日志里能看到modelopt_fp4与所选 MoE 内核。B200 上是原生 W4A4 内核,RTX 5090/PRO 6000 走 CUTLASS FP4,H100/A100 则退回 Marlin W4A16,全部自动。
❓ 新手常见问题
Q:必须打补丁吗?不行的话怎么办?单引擎 vLLM 部署必须打 Patch。如果不想动 vLLM,可以走transformers + peft路径(README.md 的 Usage 一节),但那需要 bf16 原版权重,且没有决策服务接口。
Q:需要哪个版本的 vLLM?带 Gemma-4 支持的 vLLM 开发构建(2026 年 9 月版已验证),在 vLLM 源码目录中应用补丁:git apply patches/vllm-gemma4-lm-head-lora.patch。
Q:量化会影响决策概率吗?不会。hf_quant_config.json 排除了 lm_head、注意力与稠密 MLP,lm_head LoRA 运行在 bf16 权重上;vLLM 引擎与 transformers 引擎在 300 个留出决策上平均最大概率差仅 0.015。
Q:显存要多少?权重 17.1 GiB,24 GB 显卡即可运行短上下文;--gpu-memory-utilization与MAX_MODEL_LEN可按卡调整(例如MAX_MODEL_LEN=32768)。
Q:温度配置用哪个文件?默认用 calibration.json;若要根据置信度自动门控动作,请改用按真值校准的 calibration_gold.json。
小结
GEV-26B-Decide-NVFP4 的单引擎部署内幕可以浓缩成三步:
- NVFP4 只量化路由专家,把 26B MoE 压进 17 GB,lm_head 保持 bf16 不动;
- 决策头伪装成 lm_head LoRA塞进标准 PEFT 适配器,让 vLLM 无需新算子;
- 2 个 Patch——放开词表上限并声明
embedding_modules(让它能加载)、按物理模块去重(让权重不被别名静默重置)——让整条通路在 Gemma-4 上既跑得起来、又算得对。
最终效果:一个引擎、一套权重,文本与图像两用,System 1 中位 45ms 出概率,System 2 在想清楚的时候才花时间思考。
【免费下载链接】GEV-26B-Decide-NVFP4项目地址: https://ai.gitcode.com/hf_mirrors/autotrust/GEV-26B-Decide-NVFP4
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考