PowerInfer 多模态推理指南:MiniCPM-o 2.6 图像能力转换与 llama-mtmd-cli 本地部署
【免费下载链接】PowerInferHigh-speed Large Language Model Serving for Local Deployment项目地址: https://gitcode.com/gh_mirrors/po/PowerInfer
MiniCPM-o 2.6 是 OpenBMB 推出的支持图像输入的端侧多模态大模型,本指南以仓库中 smallthinker/docs/multimodal/minicpmo2.6.md 为骨架,完整讲解从 Hugging Face 下载 PyTorch 权重、执行模型拆分手术、转换为 GGUF 与 mmproj 视觉投影文件、量化压缩,到使用llama-mtmd-cli进行单轮问答与多轮对话的完整本地部署流程。读完本文,你将掌握一套可复现的 MiniCPM-o 2.6 端侧多模态推理方案,并理解libmtmd视觉编码器与语言模型协同工作的底层原理。
一、背景:MiniCPM-o 2.6 与当前支持范围
MiniCPM-o 2.6 属于 MiniCPM 系列的多模态模型。需要首先明确的是:当前仓库中的该篇指南只支持 minicpm-omni 的图像能力(image capabilities),全模态(音频、视频等)支持仍在规划中,后续会尽快更新完整模式。因此本文所有操作均围绕"图像理解"这一能力展开。
在仓库的smallthinker子项目中,多模态能力由libmtmd库统一提供(替代早期的llava.cpp),其历史演进可参考 smallthinker/tools/mtmd/README.md:从 LLaVA 1.5 起步,经历 MobileVLM、多个模型专属 CLI(如minicpmv-cli)的碎片化阶段,最终由mtmd-cli统一为单一入口。目前支持多模态输入的工具主要有两个(见 smallthinker/docs/multimodal.md):
llama-mtmd-cli:命令行交互工具;llama-server:通过 OpenAI 兼容的/chat/completionsAPI 提供服务。
本文聚焦llama-mtmd-cli在 MiniCPM-o 2.6 上的实战。
二、准备工作:模型下载与环境要求
2.1 下载 PyTorch 模型
将 MiniCPM-o-2_6 的 PyTorch 权重下载到本地MiniCPM-o-2_6文件夹:
# 使用 huggingface_hub 或 git lfs 将模型克隆到 MiniCPM-o-2_6 目录 git lfs install git clone https://huggingface.co/openbmb/MiniCPM-o-2_6下载完成后目录中应包含完整的 transformers 权重文件(*.safetensors、config.json、added_tokens.json、分词器文件等),后续的"手术"脚本将直接读取该目录。
2.2 获取构建产物:编译 llama.cpp(PowerInfer 的 smallthinker 子项目)
本仓库根目录即为 PowerInfer 项目,其中smallthinker/子目录维护着独立的 llama.cpp 分支代码(多模态工具位于 smallthinker/tools/mtmd)。编译方式与官方 llama.cpp 一致,使用 CMake:
git clone https://github.com/ggerganov/llama.cpp cd llama.cpp cmake -B build cmake --build build --config Release说明:原文档撰写于 20250206,若使用过程中命令或参数存在差异,请以本仓库 smallthinker/tools/mtmd/CMakeLists.txt 中实际构建的目标为准。构建完成后,
build/bin/目录下会生成llama-mtmd-cli可执行文件(以及llama-llava-cli、llama-gemma3-cli、llama-minicpmv-cli、llama-qwen2vl-cli等仅输出废弃提示的兼容二进制,见 CMakeLists.txt)。
从构建脚本可见,llama-mtmd-cli由mtmd-cli.cpp编译而来,并链接了common与mtmd两个库;mtmd库则由mtmd.cpp、mtmd-audio.cpp、clip.cpp、mtmd-helper.cpp等源文件构成,依赖ggml与llama核心库——这正是"视觉编码器与语言模型解耦"的架构体现。
三、核心概念:为什么需要两个 GGUF 文件(mmproj)
在动手转换前,先理解llama.cpp多模态方案的设计思想(详见 smallthinker/tools/mtmd/README.md 的 "What is mmproj" 一节):
- 多模态推理时,图像先由一个独立的视觉编码器编码为 embedding,再喂给语言模型;
- 这种设计使多模态组件与核心
libllama解耦,可以独立、快速地迭代; - 现代视觉模型虽然大多基于 ViT(Vision Transformer),但各自的前处理和投影步骤差异很大,直接整合进
libllama难度较高。
因此运行一个多模态模型通常需要两个文件:
- 语言模型 GGUF:标准文本模型文件;
- mmproj(multimodal projector)GGUF:负责图像编码与投影的视觉投影器文件。
在llama-mtmd-cli的源码 smallthinker/tools/mtmd/mtmd-cli.cpp 中,init_vision_context通过mtmd_init_from_file从--mmproj指定的路径加载视觉模型,并默认将其放行到 GPU(可通过--no-mmproj-offload关闭)。加载失败时程序会直接报错退出。
四、模型转换:从 PyTorch 到 GGUF 三步走
MiniCPM-o 2.6 不能直接用原始 transformers 权重运行,需要依次执行三个脚本完成转换(官方也提供了转换好的 GGUF 版本 可直接下载,省去本步骤)。
步骤 1:模型手术(surgery)——拆出视觉组件与 LLM
python ./tools/mtmd/minicpmv-surgery.py -m ../MiniCPM-o-2_6注:原文档中的脚本路径为
tools/mtmd/minicpmv-surgery.py,在本仓库中对应位置为 smallthinker/tools/mtmd/legacy-models/minicpmv-surgery.py。
阅读该脚本源码可以清晰看到"手术"做了什么(minicpmv-surgery.py):
- 加载完整模型后,把张量名以
resampler开头的部分(即多模态投影器权重)抽取出来,转成 float32 保存为minicpmv.projector; - 把张量名以
vpm开头的部分(视觉编码器权重)抽取出来,去掉vpm.前缀后保存为minicpmv.clip; - 将 LLM 部分通过
model.llm.save_pretrained保存到model/子目录,同时保存分词器; - 特别地,脚本会清空
added_tokens.json(注释说明这是为了移除额外 token 以便转换 Mistral 系模型)。
执行完毕后,MiniCPM-o-2_6/下会出现minicpmv.projector、minicpmv.clip和model/三个关键产物。
步骤 2:转换视觉编码器 + 投影器为 mmproj GGUF
python ./tools/mtmd/minicpmv-convert-image-encoder-to-gguf.py -m ../MiniCPM-o-2_6 --minicpmv-projector ../MiniCPM-o-2_6/minicpmv.projector --output-dir ../MiniCPM-o-2_6/ --image-mean 0.5 0.5 0.5 --image-std 0.5 0.5 0.5 --minicpmv_version 4对应仓库脚本为 smallthinker/tools/mtmd/legacy-models/minicpmv-convert-image-encoder-to-gguf.py。几个关键参数说明如下:
-m/--model-dir:模型目录(必填),脚本会从中读取minicpmv.clip;--minicpmv-projector:上一步生成的minicpmv.projector路径;一旦指定,输出即为"图像编码器"文件(文件名前缀mmproj-);--output-dir:输出目录,默认与模型目录相同;--image-mean / --image-std:图像归一化参数。MiniCPM-o 2.6 使用0.5 0.5 0.5(而非 CLIP 默认的0.48145466 0.4578275 0.40821073,脚本中通过 default_image_mean/default_image_std 定义),这两组值会被写入 GGUF 元数据clip.vision.image_mean/clip.vision.image_std,供推理时图像预处理使用;--minicpmv_version:版本标记,MiniCPM-o 2.6 必须使用 4。脚本中版本与视觉架构的对应关系(源码 L546-L579)为:- 1 = MiniCPM-V-2:emb_dim 2304,block_count 26;
- 2 = MiniCPM-V-2.5:emb_dim 4096,block_count 27;
- 3 = MiniCPM-V-2.6:emb_dim 3584,block_count 27,使用 SiglipVisionTransformer;
- 4 = MiniCPM-o-2.6:emb_dim 3584,block_count 27,同样使用 SiglipVisionTransformer(即 SigLIP 视觉塔,hidden_size 1152、patch_size 14、图像尺寸 980)。
转换脚本还会做投影器张量重命名(resampler.attn.in_proj_*拆分为 q/k/v、resampler.proj转置等,见_replace_name_resampler),并在 GGUF 头中写入clip.has_minicpmv_projector = true、clip.projector_type = "resampler"、clip.minicpmv_version = 4等元数据,最终输出mmproj-model-f16.gguf。
步骤 3:转换语言模型为 GGUF
python ./convert_hf_to_gguf.py ../MiniCPM-o-2_6/model对应仓库脚本为 smallthinker/convert_hf_to_gguf.py。这里转换的是步骤 1 产生的model/子目录(纯 LLM 部分),默认输出ggml-model-f16.gguf。需要说明的是,该转换脚本还支持--mmproj参数(见 源码 L6526-L6536),可直接为部分视觉模型导出mmproj-前缀的文件,但 MiniCPM-o 2.6 需要按照上述"手术 + 独立转换脚本"的流程处理视觉部分。
可选:量化 int4 版本
./build/bin/llama-quantize ../MiniCPM-o-2_6/model/ggml-model-f16.gguf ../MiniCPM-o-2_6/model/ggml-model-Q4_K_M.gguf Q4_K_M使用llama-quantize将 f16 语言模型量化为Q4_K_M格式,可显著减小体积、降低内存占用。注意量化仅针对语言模型 GGUF;mmproj 视觉投影文件通常保持 f16 即可(其张量较小,量化收益有限)。
五、推理实战:llama-mtmd-cli 的两种运行模式
转换完成后,MiniCPM-o-2_6/目录下应有:
model/ggml-model-f16.gguf(及可选model/ggml-model-Q4_K_M.gguf)mmproj-model-f16.gguf
下面在 Linux 或 macOS 上运行推理。从 mtmd-cli.cpp 源码可以看到两条硬性约束:-m与--mmproj为必填参数(缺--mmproj会直接打印用法并退出);若同时提供-p提示词与--image图片,则进入单轮模式,否则进入对话模式。
5.1 单轮模式:一次问答识别一张图
./build/bin/llama-mtmd-cli -m ../MiniCPM-o-2_6/model/ggml-model-f16.gguf --mmproj ../MiniCPM-o-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 路径;-c 4096:上下文长度,多模态场景建议 4096 起步;--temp 0.7、--top-p 0.8、--top-k 100:采样参数,控制生成多样性与质量(注意mtmd-cli的默认 temp 是 0.2,见 源码 L252,此处显式覆盖);--repeat-penalty 1.05:重复惩罚;--image xx.jpg:输入图片路径(可多次指定多张图);-p "...":用户提示词。
源码中单轮模式的处理逻辑(mtmd-cli.cpp L291-L311)值得留意:若提示词中未包含图像占位标记,程序会为每张图片自动追加默认标记<__image__>(mtmd_default_marker(),其宏定义为MTMD_DEFAULT_IMAGE_MARKER,见 mtmd.h L42)。也就是说你甚至可以不写标记,直接让图片与文本一起送入模型。
5.2 对话模式:多轮图文聊天
./build/bin/llama-mtmd-cli -m ../MiniCPM-o-2_6/model/ggml-model-Q4_K_M.gguf --mmproj ../MiniCPM-o-2_6/mmproj-model-f16.gguf不传-p与--image即进入交互式聊天。启动后支持以下内置命令(源码 L313-L323):
/image <path>:加载一张图片(mtmd_support_vision返回支持时才会显示该命令);/audio <path>:加载一段音频(仅当视觉模型支持音频时显示;MiniCPM-o 2.6 当前只启用图像能力,因此该命令通常不会出现);/clear:清空对话历史(内部调用llama_kv_self_seq_rm保留 BOS 后删除历史 KV);/quit或/exit:退出程序。
多轮对话中图片会通过<__image__>标记嵌入到消息内容中参与编码,模型即可基于图片继续多轮问答。/clear之后n_past归零、KV 缓存清空,可重新开启一轮全新会话。
六、底层原理速览:图像如何进入语言模型
结合源码,可以把 MiniCPM-o 2.6 图像推理的完整链路概括为四步:
- 加载:
llama-mtmd-cli通过common_init_from_params初始化语言模型,再经mtmd_init_from_file加载 mmproj 视觉模型(mtmd-cli.cpp L89-L140); - 编码:
mtmd_tokenize接收文本、位图(bitmap)等输入块,由视觉编码器将图像编码为图像 embedding; - 拼接与评估:
mtmd_helper_eval_chunks将文本 token 与图像 embedding 按占位标记顺序拼接成输入块,一并喂给llama_decode做前向计算(mtmd-cli.cpp L199-L246); - 生成:
common_sampler_sample+common_sampler_accept逐 token 采样输出,遇到 EOG(end-of-generation)token 或反提示词(antiprompt,如旧版 vicuna 模板的ASSISTANT:)时停止(mtmd-cli.cpp L163-L197)。
其中视觉部分读取 GGUF 中写入的image_mean、image_std、minicpmv_version等元数据完成图像归一化与架构选择,保证"转换期参数"与"推理期预处理"严格一致——这也是为什么第 4 步必须正确传入--image-mean 0.5 0.5 0.5 --image-std 0.5 0.5 0.5 --minicpmv_version 4。
另外,仓库中还提供了 smallthinker/tools/mtmd/tests.sh 与测试图片 smallthinker/tools/mtmd/test-1.jpeg,可用于快速验证构建出的llama-mtmd-cli功能是否正常。
七、常见问题与注意事项
--mmproj缺失报错:llama-mtmd-cli强制要求--mmproj,多模态推理必须同时提供语言模型与视觉投影器两个文件;若用-hf user/repo方式加载则多数情况可同时推导两者(见 mtmd-cli.cpp L41-L47)。- 版本号写错导致加载失败:
--minicpmv_version决定视觉塔架构(3 与 4 均用 SigLIP,但张量结构与投影器不同),MiniCPM-o 2.6 必须为 4;写错会出现张量名不匹配或加载报错。 - 上下文长度:图像会占用较多 token,
-c 4096是稳妥起点,长对话可适当增大。 - 全模态支持:当前 MiniCPM-o 2.6 仅启用了图像能力,音频等全模态能力待上游更新,请勿期望当前版本支持音频输入。
- 本项目为镜像仓库、只读:本文所有转换、构建、运行操作均在本地进行,不涉及修改仓库内容。
八、总结
本指南完整覆盖了 MiniCPM-o 2.6 在 PowerInfer(smallthinker 子项目)上从模型下载、三步转换(手术拆分 → 视觉编码器转 GGUF → 语言模型转 GGUF)、可选 int4 量化,到llama-mtmd-cli单轮/对话双模式推理的全流程,并深入到 minicpmv-surgery.py、minicpmv-convert-image-encoder-to-gguf.py 与 mtmd-cli.cpp 的源码实现,解释了 mmproj 双文件机制、resampler 投影器张量处理、SigLIP 视觉塔版本映射与图像占位标记的工作原理。按照本文步骤操作,即可在本地用 GGUF 格式高效运行 MiniCPM-o 2.6 的图像理解能力;更多多模态模型支持情况可查阅 smallthinker/docs/multimodal.md 与 smallthinker/tools/mtmd/README.md。
【免费下载链接】PowerInferHigh-speed Large Language Model Serving for Local Deployment项目地址: https://gitcode.com/gh_mirrors/po/PowerInfer
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考