PowerInfer 多模态推理实战:libmtmd 图像与音频输入的配置与使用指南
2026/9/24 23:13:50 网站建设 项目流程
  • 人工智能
  • 大模型
  • 推理引擎
  • 本地部署

【免费下载链接】PowerInfer

High-speed Large Language Model Serving for Local Deployment

项目地址:https://gitcode.com/gh_mirrors/po/PowerInfer
点击查看免费下载

多模态能力让本地部署的大语言模型能够直接"看见"图片、"听见"音频,从而支撑视觉问答、图文理解、语音交互等场景。本文以仓库smallthinker/docs/multimodal.md为核心,系统讲解libmtmd多模态支持的工作原理、llama-mtmd-clillama-server两种入口的启用方式、全部命令行参数与预量化模型清单,并结合仓库源码深入剖析其底层数据流,帮助读者从零开始跑通本地多模态推理。

一、多模态支持概览:libmtmd 与两种使用入口

根据 smallthinker/docs/multimodal.md,本项目(smallthinker子树,对应 llama.cpp 生态的多模态实现)通过libmtmd库提供多模态输入支持。当前支持两种模态:

  • 图像(image):稳定可用,是主要支持对象;
  • 音频(audio):高度实验性(highly experimental),输出质量可能有所下降。

目前有两个工具支持该特性:

  1. llama-mtmd-cli:命令行交互工具,详见 smallthinker/tools/mtmd/README.md;
  2. llama-server:HTTP 服务,通过 OpenAI 兼容的/chat/completionsAPI 提供多模态推理,详见 smallthinker/tools/server/README.md。

从 smallthinker/tools/mtmd/README.md 的历史梳理可以看到,多模态支持最初以 LLaVA 为起点(llava.cpp+clip.cpp+llava-cli),随后陆续加入 MobileVLM、Qwen2-VL、MiniCPM-V、Gemma 3 等架构。由于各模型的 chat template 差异越来越大,llava-cli难以统一支撑,社区一度演化出qwen2vl-climinicpmv-cligemma3-cli等各自独立的二进制。libmtmd的引入正是为了统一这些碎片化的入口:它提供单一、统一的多模态命令行界面,同时支持音频与图像输入。在 smallthinker/tools/mtmd/CMakeLists.txt 中可以看到,llama-llava-clillama-gemma3-clillama-minicpmv-clillama-qwen2vl-cli现在都仅由deprecation-warning.cpp编译而成,即这些旧工具已被统一到llama-mtmd-cli之下。

注意:多模态支持在llama.cpp生态中属于重度开发中的子项目libmtmd的 API 处于实验阶段,预期会有破坏性变更(breaking changes),官方也明确提示与 API 使用相关的问题可能得到较低优先级支持。

二、核心概念:mmproj 多模态投影器

理解多模态推理,首先要理解mmproj(multimodal projector)这个文件。

为什么需要两个 GGUF 文件

多模态支持的工作方式是:使用一个独立的模型组件把图像编码为 embeddings,再把 embeddings 喂给语言模型。这种设计让多模态组件与核心libllama库解耦,从而获得更快、更独立的开发迭代速度。

虽然现代视觉模型大多基于 Vision Transformer(ViT),但各自的预处理与投影步骤差异很大,把这种复杂多样性直接集成进libllama目前仍有挑战。因此,运行一个多模态模型通常需要两个 GGUF 文件:

  1. 标准语言模型文件(text model);
  2. 对应的多模态投影器文件(mmproj),负责图像编码与投影。

mmproj 文件是按模型架构特异性的——不同架构(Gemma 3、SmolVLM、Pixtral、Qwen2-VL、InternVL 等)的 mmproj 不能混用。

如何获取 mmproj

对于新架构模型,可以使用convert_hf_to_gguf.py配合--mmproj标志从 Hugging Face checkpoint 转换得到 mmproj 文件,支持的模型包括 Gemma 3、SmolVLM / SmolVLM2、Pixtral 12B、Qwen2-VL / Qwen2.5-VL、Mistral Small 3.1 24B、InternVL 2.5 / 3 等(注意:InternVL3-*-hf变体不支持转换,仅支持非 HF 版本;InternLM2Model纯文本模型不支持)。

对于 LLaVA、MobileVLM、GLM-Edge、MiniCPM-V 2.5 / 2.6、MiniCPM-o 2.6、IBM Granite Vision 等老架构,则需参考 smallthinker/docs/multimodal 目录下各自的指南(如 llava.md、gemma3.md),转换脚本位于 smallthinker/tools/mtmd/legacy-models 下(如llava_surgery.pyminicpmv-convert-image-encoder-to-gguf.py等)。

对于想快速上手的用户,绝大多数常用多模态模型都已有官方预量化版本(见下文第六节),直接通过-hf下载即可,无需自行转换。

三、启用多模态的两种方式与完整参数说明

根据 smallthinker/docs/multimodal.md,启用多模态有以下两种方法:

方式一:使用-hf自动拉取模型与投影器

使用-hf选项加载受支持的模型(列表见下文预量化模型清单),系统会自动下载配套的 mmproj:

  • 若用-hf加载模型但想禁用多模态,加--no-mmproj
  • 若用-hf加载模型但想指定自定义 mmproj 文件,加--mmproj local_file.gguf

方式二:本地文件显式指定

使用-m model.gguf指定文本模型,配合--mmproj file.gguf指定多模态投影器。

关键参数与默认行为

从 smallthinker/tools/server/README.md 的参数表中可以提取出与多模态相关的完整参数及其环境变量对应关系:

参数说明环境变量
-hf, -hfr, --hf-repo <user>/<model>[:quant]Hugging Face 模型仓库;quant可选、大小写不敏感,默认Q4_K_M,若仓库中没有 Q4_K_M 则回退到仓库第一个文件;mmproj 可用时也会自动下载,可通过--no-mmproj禁用LLAMA_ARG_HF_REPO
--mmproj FILE多模态投影器文件路径;使用-hf时可省略LLAMA_ARG_MMPROJ
--mmproj-url URL多模态投影器文件的 URLLLAMA_ARG_MMPROJ_URL
--no-mmproj显式禁用多模态投影器,适合与-hf一起使用LLAMA_ARG_NO_MMPROJ
--no-mmproj-offload不将多模态投影器卸载(offload)到 GPULLAMA_ARG_NO_MMPROJ_OFFLOAD

默认行为:多模态投影器默认会被 offload 到 GPU 上运行;如需禁用 GPU offload,追加--no-mmproj-offload(例如显存紧张、或在纯 CPU 环境运行时)。

官方示例命令

# 命令行工具的基本用法 llama-mtmd-cli -hf ggml-org/gemma-3-4b-it-GGUF # 服务端的基本用法 llama-server -hf ggml-org/gemma-3-4b-it-GGUF # 使用本地文件 llama-server -m gemma-3-4b-it-Q4_K_M.gguf --mmproj mmproj-gemma-3-4b-it-Q4_K_M.gguf # 不使用 GPU offload llama-server -hf ggml-org/gemma-3-4b-it-GGUF --no-mmproj-offload

四、命令行工具 llama-mtmd-cli 使用详解

llama-mtmd-cli是当前统一的多模态命令行入口。从 smallthinker/tools/mtmd/mtmd-cli.cpp 的用法说明看,其完整形态为:

llama-mtmd-cli [options] -m <model> --mmproj <mmproj> --image <image> --audio <audio> -p <prompt>

约束条件:

  • -m--mmproj是必需的(除非用-hf user/repo替代二者);
  • --image--audio-p均为可选:若都不提供,CLI 会进入聊天模式(chat mode)
  • 需要禁用 mmproj 的 GPU 使用时追加--no-mmproj-offload
  • 若同时提供-p--image,则进入单轮(single-turn)模式,处理完一次问答即结束。

单轮模式与媒体标记(marker)

单轮模式下,代码会自动检测 prompt 中是否包含默认媒体标记mtmd_default_marker()(默认标记为<__media__>),若没有则把每个--image依次追加到 prompt 末尾。也就是说,图片会以<__media__>占位符的形式嵌入对话文本流中,libmtmd在 tokenize 阶段会将该标记替换为图像 token 序列。

聊天模式与交互命令

进入聊天模式后,CLI 会输出可用命令(依据模型能力动态显示):

> /image <path> 加载一张图片 > /audio <path> 加载一段音频 > /clear 清空聊天历史 > /quit 或 /exit 退出程序

其中/image/audio仅在该模型(mmproj)支持对应模态时才会出现在帮助中——这正是通过mtmd_support_vision()/mtmd_support_audio()运行时检测的。

旧模型与 chat template

从 smallthinker/tools/mtmd/mtmd-cli.cpp 可以看到,如果模型本身没有内置 chat template,运行时会报错并提示用户显式指定,例如:

  • 旧版 LLaVA 模型:--chat-template vicuna
  • MobileVLM:--chat-template deepseek
  • Mistral Small 3.1:--chat-template mistral-v7

这一点与 smallthinker/tools/mtmd/tests.sh 中测试矩阵的做法一致(如second-state/Llava-v1.5-7B-GGUFvicuna)。

五、服务端 llama-server 与 OpenAI 兼容 API

llama-server在 smallthinker/tools/server/README.md 中被明确标注为支持多模态,其/v1/chat/completions接口提供了两种图像输入途径:

1.image_urlcontent part(推荐)

如果模型支持多模态,可以直接在messages的 content 中使用image_url类型的 content part 传入媒体文件,base64 数据与远程 URL 都支持

2.image_data+ id 引用

服务端同样支持通过image_data数组传入 base64 编码的图像数据,并在 prompt 中以[img-<id>]占位符引用。示例:构造{..., "image_data": [{"data": "<BASE64_STRING>", "id": 12}]}后,在 prompt 中写USER:[img-12]Describe the image in detail.\nASSISTANT:[img-12]会被替换为 id 为 12 的图片的 embeddings。该方式仅用于多模态模型(如 LLaVA)。

环境变量配置

llama-server还支持通过环境变量完成多模态配置,便于容器化部署(如 Docker Compose):

LLAMA_ARG_MODEL: /models/my_model.gguf LLAMA_ARG_MMPROJ: /models/mmproj.gguf # 多模态投影器 LLAMA_ARG_CTX_SIZE: 4096 LLAMA_ARG_N_PARALLEL: 2

六、预量化模型清单

以下模型大多默认带Q4_K_M量化,可直接通过-hf加载,可在ggml-org的 Hugging Face 多模态 GGUF 集合页中查找。(tool_name)替换为你要使用的二进制名llama-mtmd-clillama-server)。

注意:部分模型需要较大的上下文窗口,例如加-c 8192

视觉模型(Vision models)

# Gemma 3 (tool_name) -hf ggml-org/gemma-3-4b-it-GGUF (tool_name) -hf ggml-org/gemma-3-12b-it-GGUF (tool_name) -hf ggml-org/gemma-3-27b-it-GGUF # SmolVLM (tool_name) -hf ggml-org/SmolVLM-Instruct-GGUF (tool_name) -hf ggml-org/SmolVLM-256M-Instruct-GGUF (tool_name) -hf ggml-org/SmolVLM-500M-Instruct-GGUF (tool_name) -hf ggml-org/SmolVLM2-2.2B-Instruct-GGUF (tool_name) -hf ggml-org/SmolVLM2-256M-Video-Instruct-GGUF (tool_name) -hf ggml-org/SmolVLM2-500M-Video-Instruct-GGUF # Pixtral 12B (tool_name) -hf ggml-org/pixtral-12b-GGUF # Qwen 2 VL (tool_name) -hf ggml-org/Qwen2-VL-2B-Instruct-GGUF (tool_name) -hf ggml-org/Qwen2-VL-7B-Instruct-GGUF # Qwen 2.5 VL (tool_name) -hf ggml-org/Qwen2.5-VL-3B-Instruct-GGUF (tool_name) -hf ggml-org/Qwen2.5-VL-7B-Instruct-GGUF (tool_name) -hf ggml-org/Qwen2.5-VL-32B-Instruct-GGUF (tool_name) -hf ggml-org/Qwen2.5-VL-72B-Instruct-GGUF # Mistral Small 3.1 24B(IQ2_M 量化) (tool_name) -hf ggml-org/Mistral-Small-3.1-24B-Instruct-2503-GGUF # InternVL 2.5 和 3 (tool_name) -hf ggml-org/InternVL2_5-1B-GGUF (tool_name) -hf ggml-org/InternVL2_5-4B-GGUF (tool_name) -hf ggml-org/InternVL3-1B-Instruct-GGUF (tool_name) -hf ggml-org/InternVL3-2B-Instruct-GGUF (tool_name) -hf ggml-org/InternVL3-8B-Instruct-GGUF (tool_name) -hf ggml-org/InternVL3-14B-Instruct-GGUF # Llama 4 Scout (tool_name) -hf ggml-org/Llama-4-Scout-17B-16E-Instruct-GGUF # Moondream2 20250414 版本 (tool_name) -hf ggml-org/moondream2-20250414-GGUF

音频模型(Audio models)

# Ultravox 0.5 (tool_name) -hf ggml-org/ultravox-v0_5-llama-3_2-1b-GGUF (tool_name) -hf ggml-org/ultravox-v0_5-llama-3_1-8b-GGUF # Qwen2-Audio 和 SeaLLM-Audio # 注意:这两个模型没有预量化 GGUF,因为效果很差

混合模态(Mixed modalities)

# Qwen2.5 Omni # 能力:音频输入、视觉输入 (tool_name) -hf ggml-org/Qwen2.5-Omni-3B-GGUF (tool_name) -hf ggml-org/Qwen2.5-Omni-7B-GGUF

从 smallthinker/tools/mtmd/tests.sh 可以看到官方测试矩阵覆盖了上述绝大部分模型,并且按体积分为三档:默认(如 SmolVLM-500M、Gemma 3 4B、InternVL2_5-1B、Ultravox 1B 等)、big(如 Pixtral-12B、Qwen2-VL-7B、InternVL3-14B 等,用./tests.sh big触发)与huge(如 Qwen2.5-VL-72B、Llama-4-Scout,用./tests.sh huge触发)。测试图片为test-1.jpeg,音频为test-2.mp3,结果日志保存在output/目录。

七、源码级原理:libmtmd 的数据流

smallthinker/tools/mtmd/mtmd.h 完整定义了libmtmd的 C API,其核心数据流可以概括为:bitmap → input chunks → encode → llama_decode

1. bitmap:统一封装图像与音频

mtmd_bitmap是对多模态原始数据的统一抽象:

  • 若为图像:数据长度为nx * ny * 3,按RGBRGBRGB...排列;
  • 若为音频:数据长度为n_samples * sizeof(float),为 PCM F32 格式。

mtmd_helper_bitmap_init_from_file()可从文件直接构造 bitmap,支持格式为:图像(stb_image 支持的 jpg、png、bmp、gif 等)、音频(miniaudio 支持的 wav、mp3、flac),音频文件通过 magic bytes 自动识别。bitmap 还支持可选的id(便于 KV cache 追踪,例如基于像素数据计算图像哈希)。

2. mtmd_tokenize:把 prompt 切分为 chunks

mtmd_tokenize()接收文本 prompt 与 bitmap 列表,输出一个mtmd_input_chunks列表。输入文本必须包含默认媒体标记(<__media__>),标记会被替换为媒体 chunk。例如:

"here is an image: <__media__>\ndescribe it in detail."

会被拆成 3 个 chunk:

  1. 文本"here is an image: <start_of_image>"
  2. 图像/音频 token
  3. 文本"<end_of_image>\ndescribe it in detail."

约束与返回码:

  • bitmap 数量必须与 prompt 中标记数量一致,否则返回 1;
  • 图像预处理出错返回 2;
  • 成功返回 0;
  • 该函数线程安全(共享 ctx)。

chunk 类型由mtmd_input_chunk_type枚举定义:MTMD_INPUT_CHUNK_TYPE_TEXT/_IMAGE/_AUDIO。对 M-RoPE 类模型(如 Qwen2-VL),chunk 还记录时间维位置数n_pos(M-RoPE 恒为 1,其他模型等于 token 数)。

3. 编码与解码

  • mtmd_encode_chunk()对图像/音频 chunk 执行编码,mtmd_get_output_embd()取出上次 encode 的输出 embeddings(字节数 =llama_model_n_embd(model) * n_tokens * sizeof(float));
  • smallthinker/tools/mtmd/mtmd-helper.h 中的mtmd_helper_eval_chunks()把完整流程串起来:对文本 chunk 执行llama_decode(),对媒体 chunk 执行mtmd_encode()后再取 embeddings 喂给llama_decode(),并自动处理批处理与前后解码设置(例如Gemma 3 需要非因果注意力 non-causal attention,Qwen2-VL 类模型使用M-RoPE,这些都可以通过mtmd_decode_use_non_causal()mtmd_decode_use_mrope()运行时查询)。

4. 底层 clip 实现

libmtmd构建于clip.cpp之上(继承自原llava.cpp的视觉编码基础设施)。从 smallthinker/tools/mtmd/clip.h 可见,clip 层同时维护视觉(vision)与音频(audio)两个上下文(clip_init返回ctx_v/ctx_a),并通过clip_has_vision_encoder()clip_has_audio_encoder()clip_has_whisper_encoder()判断能力;同时提供clip_is_minicpmv()clip_is_glm()clip_is_qwen2vl()clip_is_llava()clip_is_gemma3()等架构识别函数,用于区分不同架构在预处理、patch merge、位置编码上的差异。音频分支(mtmd-audio.cpp)会做 Mel 频谱预处理,采样率可通过mtmd_get_audio_bitrate()查询(如 Whisper 为 16000 Hz)。

5. 构建目标

在 smallthinker/tools/mtmd/CMakeLists.txt 中,libmtmd作为库(add_library(mtmd ...),链接ggmlllama)与llama-mtmd-cli可执行文件一起构建,可通过以下命令完成:

cmake -B build cmake --build build --config Release -t llama-mtmd-cli cmake --build build --config Release -t llama-server

llama-server的二进制位于./build/bin/llama-serverllama-mtmd-cli同理。

八、注意事项与限制

  1. 音频高度实验性libmtmd的音频支持仍在早期阶段,质量可能不达预期;文档明确标注 Qwen2-Audio 与 SeaLLM-Audio 因效果很差而未提供预量化 GGUF。
  2. 上下文窗口:多模态模型(尤其是视频类与超大视觉模型)需要较大上下文,例如官方建议-c 8192;测试脚本中对 32B+ 参数模型标注了"在我的机器上无法运行"的硬件前提,72B / Llama-4-Scout 等巨型模型对显存与算力要求很高。
  3. mmproj 的 GPU offload:默认 mmproj 会 offload 到 GPU,显存不足时可加--no-mmproj-offload改为 CPU 推理(性能会下降)。
  4. chat template:旧模型(LLaVA、MobileVLM 等)没有内置 chat template,必须用--chat-template显式指定;部分模型存在损坏的 chat template(如测试脚本中注释掉的 Yi-VL-6B),不可直接使用。
  5. API 稳定性libmtmd是实验性 API,破坏性变更频繁;mtmd.h中多个函数(如mtmd_encodemtmd_image_tokens_get_*)已标注TODO: deprecate,未来可能调整。

综上,只需两条路径即可上手:追求快速验证用llama-mtmd-cli -hf ggml-org/...一行命令,追求服务化部署用llama-server配合 OpenAI 兼容 API。结合本文的参数表、模型清单与源码级数据流分析,读者可以针对具体模型与硬件环境,完成多模态推理从选型、配置到部署的全流程。

  • 人工智能
  • 大模型
  • 推理引擎
  • 本地部署

【免费下载链接】PowerInfer

High-speed Large Language Model Serving for Local Deployment

项目地址:https://gitcode.com/gh_mirrors/po/PowerInfer
点击查看免费下载

相关推荐

上一篇:F´ 健康检查模式(Health Checking Pattern)实践指南:用 Svc.Health 守护飞行软件关键组件
下一篇:终极指南:如何高效部署Django Unfold到生产环境

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询