首页
/ llama.cpp 多模态实战:MiniCPM-V 2.6 的模型转换、量化与推理全流程

llama.cpp 多模态实战:MiniCPM-V 2.6 的模型转换、量化与推理全流程

2026-09-04 19:14:41作者:申梦珏Efrain

MiniCPM-V 2.6 是 openbmb 推出的轻量级视觉语言模型,llama.cpp 通过其多模态子项目(libmtmd + llama-mtmd-cli)完整支持了该模型的本地推理。本文以仓库中 docs/multimodal/minicpmv2.6.md 的操作指南为主体,逐步讲清"PyTorch 权重 → GGUF → 量化 → 图像推理"的完整链路,并结合 tools/mtmd/legacy-models 下的转换脚本源码与 tools/mtmd/mtmd-cli.cpp 的实现,补充每个步骤背后的参数含义与底层原理,读完即可在自己的机器上跑通 MiniCPM-V 2.6 的看图问答。

一、整体流程:为什么要拆成"模型 + mmproj"两个文件

llama.cpp 的多模态支持被设计为一个独立子项目,其核心思想(见 tools/mtmd/README.md)是:图像先由一个独立的多模态投影器(multimodal projector,即 mmproj 文件)编码为 embedding,再喂给语言模型。这样做的目的是把各视觉模型差异很大的预处理与投影逻辑隔离在核心 libllama 之外。

因此运行 MiniCPM-V 2.6 需要准备两个 GGUF 文件:

  1. 语言模型文件ggml-model-*.gguf)——由标准 convert_hf_to_gguf.py 产出;
  2. 投影器文件mmproj-model-f16.gguf)——由 MiniCPM-V 专用脚本产出,内部同时封装了 SigLIP 视觉编码器(ViT)与 resampler 投影器。

由于 MiniCPM-V 2.6 属于仓库所称的"旧架构"(legacy)模型,convert_hf_to_gguf.py --mmproj 通吃式转换尚不适用它,需要用 tools/mtmd/legacy-models 下的专用脚本(该目录的定位见 tools/mtmd/README.md 中的说明)。tools/mtmd/README.md 也把 docs/multimodal/minicpmv2.6.md 列为官方支持的旧模型指南之一。

整个流水线的产物关系如下:

MiniCPM-V-2_6/                 ← HF 下载的 PyTorch 原始模型
├── minicpmv.projector         ← 步骤1: surgery 脚本抽取 resampler 权重
├── minicpmv.clip              ← 步骤1: surgery 脚本抽取 vpm(ViT) 权重
├── model/                     ← 步骤1: 剥离出的纯 LLM 部分
│   └── ggml-model-f16.gguf    ← 步骤3: convert_hf_to_gguf.py 产出
├── mmproj-model-f16.gguf      ← 步骤2: 图像编码器转 GGUF 产出
└── ggml-model-Q4_K_M.gguf     ← 步骤4: llama-quantize 产出

二、准备模型与构建 llama.cpp

2.1 下载 PyTorch 模型

从 Hugging Face 的 openbmb/MiniCPM-V-2_6 仓库下载完整 PyTorch 权重到 MiniCPM-V-2_6 文件夹(-m ../MiniCPM-V-2_6 均以此为基准路径,可按实际位置调整)。

2.2 编译 llama.cpp

克隆仓库后用 CMake 构建(原文档标注其 README 核对时间为 20250206,若用法有出入以官方构建文档为准):

git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp

cmake -B build
cmake --build build --config Release

构建产物在 build/bin/ 下,后续会用到其中两个二进制:llama-quantize(量化)与 llama-mtmd-cli(多模态推理入口)。llama-mtmd-cli 的用法横幅明确声明了必填参数与 GPU 卸载开关(见 tools/mtmd/mtmd-cli.cpp):

-m and --mmproj are required
-hf user/repo can replace both -m and --mmproj in most cases
to disable using GPU for mmproj model, add --no-mmproj-offload

也就是说:-m--mmproj 缺一不可;mmproj 默认会卸载到 GPU,显存紧张时可加 --no-mmproj-offload 让视觉编码器留在 CPU。

三、模型转换四步

3.1 第一步:surgery 脚本"解剖"原始权重

python ./tools/mtmd/legacy-models/minicpmv-surgery.py -m ../MiniCPM-V-2_6

这一步是 MiniCPM-V 系列转换的特殊之处:HF 上的 MiniCPM-V 权重是"视觉编码器 + resampler + LLM 揉在一起"的单体 checkpoint,不能直接喂给 convert_hf_to_gguf.pytools/mtmd/legacy-models/minicpmv-surgery.py 读取源码可以看到它做了三件事:

  1. 抽取投影器权重:筛选所有以 resampler 开头的张量,存为 minicpmv.projector。若模型 config 中存在 scale_embresampler.proj 会先除以 scale_emb 做归一(minicpmv-surgery.py 的 L19-L20),这保证了后续 GGUF 推理与 PyTorch 前向数值一致;
  2. 抽取视觉编码器权重:筛选以 vpm 开头的张量(MiniCPM-V 中 ViT 模块的前缀),去掉前缀后存为 minicpmv.clip(L23-L26);
  3. 剥离出纯 LLM:改写 model.llm.config.auto_map 后把 LLM 部分与 tokenizer 保存到 {模型目录}/model 子目录(L33-L43),使其变成一个可被 convert_hf_to_gguf.py 识别的常规 LLaMA 风格模型。

脚本结尾也会打印提示:接下来可以把 model/ 转成常规 GGUF,并用 minicpmv.projector 准备 mmproj 文件。

3.2 第二步:图像编码器转 mmproj GGUF

python ./tools/mtmd/legacy-models/minicpmv-convert-image-encoder-to-gguf.py \
    -m ../MiniCPM-V-2_6 \
    --minicpmv-projector ../MiniCPM-V-2_6/minicpmv.projector \
    --output-dir ../MiniCPM-V-2_6/ \
    --minicpmv_version 3

脚本参数中值得展开的有两处:

  • --minicpmv-projector:指定上一步产出的 minicpmv.projector 路径。一旦给出该参数,脚本就把输出文件的中间名设为 mmproj-,并写入 clip.has_minicpmv_projector = trueclip.projector_type = "resampler"clip.minicpmv_version 三个 GGUF 元数据(见 minicpmv-convert-image-encoder-to-gguf.py 的 L663-L691)。这正是运行时 libmtmd 区分"这是 MiniCPM-V 的 resampler 型图像编码器"的依据;
  • --minicpmv_version 3:版本号按模型区分——MiniCPM-V-2 用 1、MiniCPM-V-2.5 用 2、MiniCPM-V-2.6 用 3、MiniCPM-o-2.6 用 4、MiniCPM-V 4.0 用 5、MiniCPM-o-4.0 用 6(脚本 help 原文,同文件 L504)。版本 3 对应 SigLIP 视觉编码器:源码中 minicpmv_version == 3 时构造的是 SiglipVisionTransformer(L629-L631),且当找不到 config.json 时的兜底参数为 emb_dim=3584、27 个视觉块(L601-L603)。如果找得到 config.json,脚本会优先从其中读取 hidden_sizevision_config 等真实配置(L570-L589),兜底值仅用于缺 config 的场景。

产物为 {模型目录}/mmproj-model-f16.gguf(默认 f16,可用 --use-f32 改为 f32)。

3.3 第三步:LLM 部分转 GGUF

python ./convert_hf_to_gguf.py ../MiniCPM-V-2_6/model

surgery 之后 model/ 已是"常规 LLM"目录,标准转换脚本 convert_hf_to_gguf.py 即可工作,产出 ../MiniCPM-V-2_6/model/ggml-model-f16.gguf

3.4 第四步:量化出 int4 版本

# quantize int4 version
./build/bin/llama-quantize ../MiniCPM-V-2_6/model/ggml-model-f16.gguf \
    ../MiniCPM-V-2_6/model/ggml-model-Q4_K_M.gguf Q4_K_M

Q4_K_M 是 llama.cpp 常用的 4-bit k-quant 档位,体积约为 f16 的 1/4,适合显存/内存有限的主机;对精度要求高时可直接用 f16 版本推理(第四节的单轮示例用的就是 f16 模型)。

四、推理:llama-mtmd-cli 的两种运行方式

libmtmd 时代,各模型专用的 CLI(如早期的 minicpmv-cli)已被统一的 llama-mtmd-cli 取代(演进过程见 tools/mtmd/README.md 的时间线部分)。MiniCPM-V 2.6 的推理命令如下。

4.1 单轮问答模式(Linux / Mac)

./build/bin/llama-mtmd-cli \
    -m ../MiniCPM-V-2_6/model/ggml-model-f16.gguf \
    --mmproj ../MiniCPM-V-2_6/mmproj-model-f16.gguf \
    -c 4096 \
    --temp 0.7 --top-p 0.8 --top-k 100 --repeat-penalty 1.05 \
    --image xx.jpg \
    -p "What is in the image?"

参数说明:

参数 含义
-m 语言模型 GGUF,必填
--mmproj 图像编码器/投影器 GGUF,必填;缺失时 CLI 会直接报错(mtmd-cli.cpp 的 L401-L404)
-c 4096 上下文长度
--temp / --top-p / --top-k 采样温度、核采样、top-k 截断,取值即文档推荐的 MiniCPM-V 2.6 生成配置
--repeat-penalty 1.05 轻微重复惩罚
--image 输入图像路径
-p 单轮提示词,给出后执行一次生成

4.2 会话模式

./build/bin/llama-mtmd-cli \
    -m ../MiniCPM-V-2_6/model/ggml-model-Q4_K_M.gguf \
    --mmproj ../MiniCPM-V-2_6/mmproj-model-f16.gguf

不带 -p 时进入交互式会话,可多轮对话并随时粘贴图像路径。此例使用量化后的 Q4_K_M 模型,说明量化版同样支持完整推理流程。

4.3 图像在推理中如何被消费(源码视角)

tools/mtmd/models/minicpmv.cpp 的构图代码看,MiniCPM-V 系列的 mmproj 前向包含两个阶段:

  1. ViT 阶段:图像 patch 过 build_vit(学习式位置嵌入 position_embeddings 通过 positions 索引选取),得到 patch 级视觉特征;
  2. resampler 阶段:这实际上是一台小型 Transformer——mm_model_query 提供可学习查询向量,ViT 特征经 mm_model_kv_proj 投影为 K/V,K 上叠加按 2D patch 坐标构造的正弦位置嵌入(omega/pos_h/pos_w,对应 HF 侧 resampler 的实现),做多头注意力(d_head = 128,缩放因子 1/sqrt(128))后经 mm_model_ln_post 归一化、mm_model_proj 投影,输出固定数量的视觉 embedding(minicpmv.cpp 的 L38-L111)。

这些 embedding 替代 prompt 中占位 token 的位置一起进入语言模型,这正是"图像能回答 'What is in the image?'" 的底层机制。

五、注意事项与适用前提

  • 版本对齐--minicpmv_version 必须与实际模型版本严格对应(2.6 传 3),传错会导致加载错误的 ViT 配置。脚本 help 中的完整对照表(1→MiniCPM-V-2,2→2.5,3→2.6,4→o-2.6,5→V 4.0,6→o-4.0)可直接当速查表使用;
  • mmproj 与模型必须配套mmproj-model-f16.gguf 由同一份原始权重导出,跨版本混用无保证;
  • GPU 卸载mmproj 默认走 GPU,可用 --no-mmproj-offload 关闭(用法横幅见 mtmd-cli.cpp);
  • 环境前提:surgery 与编码器转换脚本依赖 Python 环境中的 transformerstorch 等库(脚本头部直接 import torch 并调用 AutoModel.from_pretrained,且对远程代码使用 trust_remote_code=True);
  • 预量化模型:若不想自己转换,openbmb 在 HF 上提供 MiniCPM-V-2_6-gguf 预转换产物;更完整的预量化多模态模型列表可参考 docs/multimodal.md
  • 同系列对照阅读:MiniCPM-V 2.5(docs/multimodal/minicpmv2.5.md)与 MiniCPM-V 4.0(docs/multimodal/minicpmv4.0.md)的转换流程类似但版本号与视觉编码器不同,MiniCPM-V 4.6 等新架构已可走 convert_hf_to_gguf.py --mmproj 直转(见 tools/mtmd/README.md)。

至此,从 PyTorch 权重到 Q4_K_M 量化模型、从 surgery 解剖到 resampler 构图,MiniCPM-V 2.6 在 llama.cpp 中的完整生命周期都已覆盖。按第三节四步转换、第四节命令推理,即可在 Linux 或 Mac 上完成图像问答。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.83 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.79 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
988
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384