Prhub

#23811 [Feature] Xiaomi MiMo-V2.5 day0 support

原始 PR 作者 Abatom 合并时间 2026-05-01 00:02 文件变更 16 提交数 65 评论 55 代码增减 +4369 / -87

执行摘要

为 Xiaomi MiMo-V2.5 添加多模态与 EAGLE 推测解码支持

XiaomiMiMo/MiMo-V2.5 是一个新的多模态大模型,支持图像、视频、音频理解。需要在 SGLang 中提供 day-0 支持以便用户部署推理。PR body 指出这包括注册模型架构、多模态处理器、推测解码集成等。

此 PR 是小米模型的完整集成,值得详细审阅,特别是 fused-qkv 装载模式、多模态处理器设计以及 VisionAttention 增强。合并后应关注 Gemma4 和其他多模态模型的回归测试。

讨论亮点

Review 中主要讨论了以下问题:

  • softmax_scale 移除风险(JustinTong0323):VisionAttention 重构中丢弃了 softmax_scale 参数,导致 Gemma4 视觉注意力退化。Abatom 后续修复了此问题。
  • VideoData 包装兼容性(JustinTong0323):append_video 强制包装 VideoData 可能破坏下游处理器(moss_vl、qwen_vl 等)。Abatom 通过仅在有 preprocess_kwargs 时包装来修复。
  • decord 死代码(JustinTong0323):mimo_v2_omni.pyimport decord 块从未使用,已移除。
  • TP 强制硬编码(Abatom/JustinTong0323):最初硬编码要求 TP=4,后改为从配置派生,支持 Pro 版本 TP=8。
  • 测试稳定性:MMMU 测试因 lmms-eval 与推理解析器不兼容而被移除。

实现拆解

实现分以下主要步骤:

  1. 模型架构实现:在 python/sglang/srt/models/mimo_v2.py 中新增 MiMoV2ForCausalLM 类,支持混合 SWA/全注意力、MoE、fused-qkv 装载。同时修改 mimo_v2_nextn.py 支持 MTP 推测解码。
  2. 视觉模块:新增 python/sglang/srt/models/mimo_vl.py,包含 MiMoVLVisionConfigMiMoVisionPatchEmbedMiMoVisionBlockMiMoVisionTransformer,复用上游 VisionAttention 并扩展 sink 和 window 支持。
  3. 音频模块:新增 python/sglang/srt/models/mimo_audio.py,包含 MiMoAudioEncoderMiMoAudioTokenizer 等,独立于模型主路径。
  4. 多模态处理器:新增 python/sglang/srt/multimodal/processors/mimo_v2.py,处理图像、视频、音频的下载/解码/预处理,输出 MultimodalProcessorOutput
  5. 配置与集成:在 model_config.py 添加 MiMoV2 架构检测和 fused-qkv 期望 TP 大小推导;在 server_args.py 强制 attention TP 对齐;修改 mm_utils.py 支持列表特征的共享内存包装/解包;修改 VisionAttention 以支持 window_size 和 sink。
  6. 测试:新增 test/registered/8-gpu-models/test_mimo_models.py 中的 GSM8K 和 MMMU 测试。
文件 模块 状态 重要度
python/sglang/srt/models/mimo_v2.py 模型层 modified 9.18
python/sglang/srt/models/mimo_vl.py 视觉模块 added 9.36
python/sglang/srt/multimodal/processors/mimo_v2.py 多模态处理 added 9.25

关键符号

load_mimo_v2_qkv_proj_weight get_mimo_v2_fused_qkv_expected_tp_size MiMoProcessor.process_mm_data_async DynamicFrequencyUpdate wrapper MiMoVisionTransformer.forward

关键源码片段

python/sglang/srt/models/mimo_v2.py data-contract

核心模型文件,包含 MiMoV2ForCausalLM 主模型和 fused-qkv 装载逻辑

# python/sglang/srt/models/mimo_v2.py (excerpt)def load_mimo_v2_qkv_proj_weight(
    name, param, loaded_weight, expected_fused_tp_size: Optional[int] = None
):
    # 检查点已经分片,直接装载
    if loaded_weight.shape == param.shape:
        default_weight_loader(param, loaded_weight)
        return
​
    # 验证维度兼容性
    if loaded_weight.ndim != param.ndim or loaded_weight.shape[1:] != param.shape[1:]:
        raise ValueError(f"qkv_proj weight {name}: unexpected shape ...")
​
    tp_size = get_attention_tp_size()
    tp_rank = get_attention_tp_rank()
    # 如果指定了期望 TP 大小,验证一致性
    if expected_fused_tp_size is not None and tp_size != expected_fused_tp_size:
        raise ValueError(f"MiMoV2 fused qkv_proj checkpoint is TP={expected_fused_tp_size}-"
                         f"interleaved; got attention tp_size={tp_size} while loading {name}.")
    # 检查完整融合形状
    fused_shape = (param.shape[0] * tp_size, *param.shape[1:])
    if tuple(loaded_weight.shape) != fused_shape:
        raise ValueError(...)
    # 按当前 TP 分片装载
    default_weight_loader(param, loaded_weight.chunk(tp_size, dim=0)[tp_rank])
python/sglang/srt/models/mimo_vl.py data-contract

视觉 Transformer 实现,包括自定义 VisionConfig、PatchEmbed、VisionBlock

# python/sglang/srt/models/mimo_vl.py (excerpt)class MiMoVLVisionConfig(PretrainedConfig):
    model_type = "mimovl"
    base_config_key = "vision_config"
​
    def __init__(self, depth=28, hidden_size=1280, hidden_act="silu",
                 intermediate_size=4608, num_heads=32, in_channels=3,
                 patch_size=16, spatial_merge_size=2, temporal_patch_size=2,
                 tokens_per_second=2, window_size=128, out_hidden_size=2048,
                 fullatt_block_indexes=[7,15,23,31], initializer_range=0.02,
                 kv_channels=64, qk_channels=64, num_query_groups=4,
                 num_key_value_heads=8, vit_window_attn_types=None,
                 visual_token_window_size=64, **kwargs):
        super().__init__(**kwargs)
        self.depth = depth
        self.hidden_size = hidden_size
        # ... 具体赋值
        self.vit_window_attn_types = vit_window_attn_types or [-1] * depth
        self.visual_token_window_size = visual_token_window_sizeclass MiMoVisionPatchEmbed(nn.Module):
    def __init__(self, patch_size=16, temporal_patch_size=2, in_channels=3, embed_dim=1536):
        super().__init__()
        kernel_size = [temporal_patch_size, patch_size, patch_size]
        self.proj = nn.Conv3d(in_channels, embed_dim, kernel_size=kernel_size,
                              stride=kernel_size, bias=False)
        self.proj_weight_linear_format = None
​
    @torch.no_grad()
    def sync_proj_weight_linear_format(self):
        # 缓存线性格式权重以加速 forward
        self.proj_weight_linear_format = self.proj.weight.view(self.embed_dim, -1)
​
    def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
        # 使用线性层替代 conv3d
        target_dtype = self.proj.weight.dtype
        hidden_states = F.linear(hidden_states.to(dtype=target_dtype),
                                 self.proj_weight_linear_format)
        return hidden_states

评论区精华

VisionAttention softmax_scale 丢失 正确性

JustinTong0323 指出 VisionAttention 重构中 softmax_scale 未被传递给 flash_attn_varlen_func,导致 Gemma4 视觉注意力使用默认 scale。Abatom 承诺修复。

结论:已修复,添加了 softmax_scale=softmax_scale 到 fa_kwargs。 · 已解决

append_video VideoData 包装兼容性 设计

JustinTong0323 指出 append_video 强制包装 VideoData 可能破坏 moss_vl、qwen_vl 等处理器,这些处理器期望 str 或 dict。Abatom 修复为仅在有 preprocess_kwargs 时包装。

结论:已修复,添加条件检查。 · 已解决

decord 死代码 other

JustinTong0323 指出 mimo_v2_omni.py 中 import decord 块从未使用,建议移除。

结论:已移除。 · 已解决

TP 强制硬编码 vs 配置派生 设计

最初 hardcode TP=4,但 MiMo-V2.5-Pro 需要 TP=8。Abatom 和 JustinTong0323 讨论后改为从 config 派生 expected_tp_size,支持两个变体。

结论:通过 get_mimo_v2_fused_qkv_expected_tp_size 从 num_key_value_heads 派生。 · 已解决

风险与影响

  1. VisionAttention 回归:修改 VisionAttention 引入 window_size 参数和重构,可能影响其他依赖该模块的模型(如 Gemma4)。已通过修复 softmax_scale 缓解。
  2. 共享内存序列化mm_utils.py 中 wrap/unwrap 支持列表特征,可能与其他已知使用 Tensor 特征的多模态模型不兼容。
  3. TP 强制约束:fused-qkv 检查点强制特定 TP 大小,限制了用户自由选择 TP 的能力,并可能影响未来量化版本(lukealonso 提及)。
  4. MTP 稳定性:多层 EAGLE 推测解码需要仔细调试,测试中发现 accept_length 属性命名不匹配等问题。
  5. 解耦性:音频编码器强依赖 CUDA,在 CPU 推理时会引发运行时错误。

直接影响用户:只有使用 XiaomiMiMo/MiMo-V2.5 或 MiMo-V2.5-Pro 模型的用户。但 VisionAttention 和 mm_utils 的修改影响所有使用这些公共模块的多模态模型。团队需要确保这些通用变更不引入退化。

VisionAttention 回归风险 共享内存序列化兼容性 TP 强制限制灵活性 MTP 稳定性 CUDA 硬依赖

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论