执行摘要
- 一句话:为 Mistral Medium 3.5 添加 EAGLE 推测解码支持
- 推荐动作:建议精读
mistral_eagle.py 和 mistral_utils.py 中的配置分支设计,了解如何利用已有的 Llama EAGLE 框架支持新模型。该 PR 展示了 weight name remapping 和 quant_config 传递的实践,值得参考。
功能与动机
Mistral Medium 3.5 官方提供了 EAGLE draft 模型,SGLang 此前不支持该模型的推测解码。本 PR 旨在利用已有的 Llama EAGLE 基础设施,快速为 Mistral GQA 模型添加 EAGLE 支持,从而提升推理吞吐量,尤其是在低并发延迟敏感场景下。
实现拆解
- 新增 Mistral EAGLE 模型类 (
python/sglang/srt/models/mistral_eagle.py):新建 MistralEagleModel 和 MistralForCausalLMEagle,继承自 nn.Module 和 LlamaForCausalLMEagle。其核心差异在于:使用标准 LlamaDecoderLayer(而非 layernorm-less 变体)以匹配 Mistral checkpoint 中的 attention_norm;使用 RowParallelLinear 作为融合层以加载 FP8 权值;实现 _remap_mistral_to_llama 将 Mistral 原生权重名映射到 SGLang 格式。
- 修改配置适配逻辑 (
python/sglang/srt/utils/hf_transformers/mistral_utils.py):在 adapt_config_dict 中引入 is_mla_eagle 判断,将原 is_eagle and not is_moe 分支拆分为 MLA Eagle(走 MistralLarge3ForCausalLMEagle)和 GQA Eagle(走 MistralForCausalLMEagle,model_type=mistral)。同时更新 is_mistral_model 函数,使得包含 'mistral' 和 'eagle' 的模型名也能触发自定义配置解析。
- 为 llava 添加 embed/head 访问接口 (
python/sglang/srt/models/llava.py):新增 get_embed_and_head 和 set_embed_and_head 方法,委托给内部的 language_model,以便 EAGLE 框架可以与目标模型共享 embed 和 lm_head。
- 更新交互式部署示例 (
docs_new/src/snippets/autoregressive/mistral-medium-3-5-deployment.jsx):在选项中加入 speculative 开关,启用后自动添加 --dtype bfloat16 和 EAGLE 相关参数。
- 更新 cookbook 文档 (
docs_new/cookbook/autoregressive/Mistral/Mistral-Medium-3.5.mdx):新增第 3.3 节,详细说明 EAGLE 的配置命令、注意事项(如必须指定 --dtype bfloat16)以及内存开销。
关键文件:
python/sglang/srt/models/mistral_eagle.py(模块 模型层;类别 source;类型 data-contract;符号 MistralEagleModel, init, forward, MistralForCausalLMEagle): 新增文件,包含核心 EAGLE draft 模型实现,是 PR 的核心变更。
python/sglang/srt/models/llava.py(模块 模型层;类别 source;类型 data-contract;符号 get_embed_and_head, set_embed_and_head): 新增 get_embed_and_head / set_embed_and_head 方法以实现 embed/head 共享,是实现 EAGLE 的必要接口。
python/sglang/srt/utils/hf_transformers/mistral_utils.py(模块 配置适配;类别 source;类型 core-logic;符号 adapt_config_dict, is_mistral_model): 配置适配层新增 GQA Eagle 分支,区分 MLA 和 GQA 两种 Eagle 模型,是正确加载 Mistral Medium 3.5 Eagle 的关键。
docs_new/src/snippets/autoregressive/mistral-medium-3-5-deployment.jsx(模块 文档;类别 infra;类型 core-logic): 交互式部署示例新增 EAGLE 开关,方便用户生成带推测解码的启动命令。
docs_new/cookbook/autoregressive/Mistral/Mistral-Medium-3.5.mdx(模块 文档;类别 infra;类型 core-logic): cookbook 文档新增 EAGLE 部署说明和注意事项,是用户使用的官方指南。
关键符号:MistralEagleModel.init, MistralEagleModel.forward, MistralForCausalLMEagle.load_weights, MistralForCausalLMEagle._remap_mistral_to_llama, adapt_config_dict, is_mistral_model, get_embed_and_head, set_embed_and_head
关键源码片段
python/sglang/srt/models/llava.py
新增 get_embed_and_head / set_embed_and_head 方法以实现 embed/head 共享,是实现 EAGLE 的必要接口。
# python/sglang/srt/models/llava.py (partial)
def get_embed_and_head(self):
# Spec-decode plumbing: expose the LM's embed/head so the EAGLE draft
# can share them with the target. self.language_model is a Llama-family
# CausalLM that defines this method.
return self.language_model.get_embed_and_head()
def set_embed_and_head(self, embed, head):
self.language_model.set_embed_and_head(embed, head)
python/sglang/srt/utils/hf_transformers/mistral_utils.py
配置适配层新增 GQA Eagle 分支,区分 MLA 和 GQA 两种 Eagle 模型,是正确加载 Mistral Medium 3.5 Eagle 的关键。
# python/sglang/srt/utils/hf_transformers/mistral_utils.py (partial)
is_eagle = "eagle" in model.lower()
is_mla_eagle = is_eagle and any(
config_dict.get(k) is not None
for k in ("kv_lora_rank", "q_lora_rank", "v_head_dim")
)
if is_eagle and not is_moe and is_mla_eagle:
# Dense MLA EAGLE draft model (e.g. Mistral Small 4 EAGLE).
config_dict["model_type"] = "deepseek_v3"
config_dict["architectures"] = ["MistralLarge3ForCausalLMEagle"]
# ... MoE dummy fields ...
elif is_eagle and not is_moe:
# Dense GQA EAGLE draft model (e.g. Mistral Medium 3.5 EAGLE).
config_dict["architectures"] = ["MistralForCausalLMEagle"]
config_dict["model_type"] = "mistral"
config_dict["rope_is_neox_style"] = False
# Clean up MLA keys that might be None to avoid shadowing defaults
for mla_key in (
"q_lora_rank",
"qk_rope_head_dim",
"qk_nope_head_dim",
"kv_lora_rank",
"v_head_dim",
):
if config_dict.get(mla_key) is None:
config_dict.pop(mla_key, None)
评论区精华
该 PR 没有 review 评论,变更直接合并,可能是内部快速跟进。
风险与影响
- 风险:
- 配置兼容性:
mistral_utils.py 中增加的条件分支可能影响其他 Mistral 模型的加载,尤其是之前被归类为 MLA Eagle 的模型(如 Mistral Small 4)。需要确保 is_mla_eagle 的检测键(kv_lora_rank 等)在旧 checkpoint 中不存在时才走 GQA 分支。
- embed/head 共享:
llava.py 新增的方法依赖于 language_model 具有 get_embed_and_head 和 set_embed_and_head,如果 language_model 不是 Llama-family 模型则会失败。当前 llava 的 language_model 通常是 Llama,风险较低。
- 文档准确性:cookbook 中给出的 docker 镜像标签(
dev-mistral-medium-3.5)尚未在 latest 中,用户可能用到过时版本。
- 缺少测试:没有新增的单元测试或集成测试,回归风险主要通过人肉验证。
- 影响:对用户:支持 Mistral Medium 3.5 的 EAGLE 推测解码,提升延迟性能。对系统:新增一个模型文件,修改两个共享模块(mistral_utils 和 llava),影响范围较小。对团队:为后续添加其他 Mistral EAGLE 模型(如 Mistral Small 4)提供了可复用的模式。影响程度中等。
- 风险标记:配置分支影响其他 Mistral 模型, llava 接口依赖隐含假设, 缺少单元测试, 文档中 Docker 镜像标签非稳定
关联脉络
- PR #24027 Bugfix: 同一作者之前的 PR,修复了 Mistral GQA 相关问题,与本 PR 都涉及 mistral_utils.py 和 mistral_eagle.py(新增)。
- PR #23890 [spec decoding] add extra attribute 'spec_hidden_size': EAGLE 相关的基础设施变更,修改了多处 speculative 文件,为本 PR 中的 EAGLE 支持提供铺垫。
参与讨论