MiniCPMO45 模型模块详解

MiniCPMO45 是系统的核心模型模块,实现了多模态大语言模型的推理能力,支持文本、图像、音频、视频输入和文本、音频输出。

模块结构

MiniCPMO45/
├── configuration_minicpmo.py       # 模型配置定义
├── modeling_minicpmo.py            # 主模型实现
├── modeling_minicpmo_unified.py    # 统一模型(支持热切换)
├── modeling_navit_siglip.py        # SigLIP 视觉编码器
├── processing_minicpmo.py          # 多模态处理器
├── tokenization_minicpmo_fast.py   # 快速分词器
├── utils.py                        # 工具函数
├── tokenizer_config.json           # 分词器配置
├── generation_config.json          # 生成配置
├── preprocessor_config.json        # 预处理器配置
├── special_tokens_map.json         # 特殊 token 映射
└── added_tokens.json               # 扩展 token

多模态架构总览

graph TB
    subgraph inputLayer [输入层]
        TextIn["文本输入"]
        ImageIn["图像输入"]
        AudioIn["音频输入\n(16kHz)"]
        VideoIn["视频输入\n(自动提取帧+音频)"]
    end

    subgraph encoderLayer [编码器层]
        Tokenizer["Qwen2 Tokenizer"]
        VPM["SigLIP Vision Encoder\n(ViT)"]
        Resampler["Resampler\n(Perceiver)"]
        APM["Whisper Audio Encoder"]
        AudioProj["Audio Projection\nMultiModalProjector"]
    end

    subgraph fusionLayer [融合层]
        Embedding["多模态 Embedding 融合"]
    end

    subgraph llmLayer [语言模型]
        LLM["Qwen3 LLM Backbone\n(Causal LM)"]
    end

    subgraph outputLayer [输出层]
        TextOut["文本输出"]
        TTSBlock["TTS 模块"]
        T2W["Token2Wav"]
        AudioOut["音频输出\n(24kHz)"]
    end

    TextIn --> Tokenizer --> Embedding
    ImageIn --> VPM --> Resampler --> Embedding
    AudioIn --> APM --> AudioProj --> Embedding
    VideoIn -->|"帧"| VPM
    VideoIn -->|"音频段"| APM
    Embedding --> LLM
    LLM --> TextOut
    LLM --> TTSBlock
    TTSBlock --> T2W --> AudioOut

核心模型结构

MiniCPMO 是整个系统的核心类(继承自 Qwen3PreTrainedModel),内部组合了 6 个子模块,各负责一个模态或功能:

各子模块可通过配置项 init_vision / init_audio / init_tts 独立启用或禁用。

统一模型与模式切换

modeling_minicpmo_unified.py 中的 MiniCPMO 在上述基础上增加了统一模式管理,通过 ProcessorMode 枚举在三种模式间热切换:

切换通过 set_mode(mode) 完成,仅重置会话状态(KV Cache、Token2Wav 缓存等),不重新加载模型权重,因此切换开销极低。


输入编码

文本编码

文本输入经 Qwen2 Tokenizer 分词后,通过 llm.model.embed_tokens 转换为嵌入向量。嵌入后会乘以可选的 scale_emb 缩放因子。

视觉编码(图像与视频)

图像处理分三步:

  1. 图像切片MiniCPMVImageProcessor)— 大图按 MiniCPMVSliceConfig 配置切分为多个 patch(最多 max_slice_nums=9 块,每块 448×448),保留一份全局缩略图。这使模型能处理高分辨率图像。
  2. VPM 编码SiglipVisionTransformer)— 每个 patch 经 SigLIP ViT 编码。ViT 由 SiglipVisionEmbeddings(Conv2d patch embedding + 位置编码)和多层 SiglipEncoder(多头自注意力 + FFN)组成,支持 Flash Attention 2 加速。输出为可变长度的 patch 特征序列。
  3. Resampler 压缩Resampler)— 使用可学习的查询向量(默认 64 个)对 VPM 输出做交叉注意力,将可变长度的视觉特征压缩为固定长度。位置信息通过 2D sincos 位置编码注入。输出形状为 (num_queries, embed_dim)

视频被拆解为帧序列 + 音频段,帧走视觉编码路径,音频段走音频编码路径。

音频编码

音频处理分三步:

  1. 梅尔频谱提取MiniCPMAAudioProcessor)— 输入 16kHz 音频,提取 80 维梅尔频谱特征。
  2. APM 编码MiniCPMWhisperEncoder)— 基于 Whisper 的编码器,先经两层 1D 卷积(Conv1 stride=1 → GELU → Conv2 stride=2)下采样,再经多层 Transformer 编码器层处理。支持 KV Cache 实现流式音频编码,可通过 prefix_extra_frames / suffix_extra_frames 添加上下文重叠。
  3. 投影 + 池化MultiModalProjector(Linear → ReLU → Linear)将音频特征映射到 LLM 嵌入维度,随后 AvgPool1d(步长 audio_pool_step=5)进一步压缩序列长度。

多模态嵌入融合

各模态编码完成后,通过两步融合汇入统一的嵌入序列:

  1. 视觉融合get_vllm_embedding)— 文本序列中预留了视觉占位符 token。通过 image_bound(记录每个图像占位符的起止位置),将对应位置的文本嵌入替换为 Resampler 输出的视觉嵌入(scatter 操作)。
  2. 音频融合get_omni_embedding)— 在视觉融合后的序列上,通过 audio_bounds(记录音频占位符的起止位置),将对应位置的嵌入替换为音频编码器输出的音频嵌入。

融合后得到统一的 inputs_embeds(包含文本 + 视觉 + 音频),送入 LLM 进行因果推理。


语言模型推理

融合后的 inputs_embeds 送入 Qwen3ForCausalLM 进行自回归生成。LLM 不区分输入来自哪个模态——所有模态在融合后共享同一嵌入空间。

文本生成支持两种模式:


输出生成

文本输出

LLM 直接输出 token 序列,经 Tokenizer 解码为文本。

语音合成(TTS)

当需要语音输出时,LLM 的隐状态经 MiniCPMTTS 模块转换为音频 token,再由声码器合成波形。

MiniCPMTTS 架构

输入布局为 [Text BOS | Speaker Embedding | Text Tokens | Audio BOS | Audio Tokens...],模型自回归地预测音频 token 序列。

四种注意力模式(通过 attention_type 配置):

Token2Wav 声码器 — 将 TTS 输出的音频 token 转换为 24kHz 波形。支持流式(逐块转换)和非流式(批量转换)两种模式。


双工能力(DuplexCapability)

DuplexCapability 是一个组合组件(非继承),通过 self.model 引用主模型 MiniCPMO 的全部参数,以 model.duplex 方式访问。它实现了实时的听-说交互。

三步工作流程

  1. prepare — 初始化双工会话。预填充系统提示词到 KV Cache,加载 TTS 参考音频(用于声音克隆),注册特殊 token(<|listen|>, <|speak|>, <|tts_bos|>, <|tts_eos|> 等)。
  2. streaming_prefill — 逐块预填充。每个时间步将音频特征和/或视频帧编码后填入 KV Cache,使模型持续"听到"输入。
  3. streaming_generate — 逐步生成。每步模型决定继续"听"(输出 listen token)还是开始"说"(输出 speak token 后接文本和音频 token)。生成的音频 token 通过 Token2Wav 实时转换为波形。

滑动窗口策略

长时间双工对话中,KV Cache 会持续增长。通过滑动窗口策略控制内存:


配置参考

MiniCPMOConfig

继承自 Qwen3Config,包含四个子配置:

关键参数

MiniCPMTTSConfig