llama.cpp 中运行 LLaVA 多模态模型:llama-mtmd-cli 使用与 1.5/1.6 模型转换实战指南

llama.cpp 中运行 LLaVA 多模态模型:llama-mtmd-cli 使用与 1.5/1.6 模型转换实战指南 llama.cpp 中运行 LLaVA 多模态模型llama-mtmd-cli 使用与 1.5/1.6 模型转换实战指南【免费下载链接】llama.cppLLM inference in C/C项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp本文围绕 llama.cpp 官方的 LLaVA 支持文档docs/multimodal/llava.md讲解如何在 llama.cpp 中运行 LLaVA v1.5 与 v1.6 视觉语言模型包括llama-mtmd-cli的构建与运行、从 PyTorch 权重到 GGUF 的完整拆分与转换流程llava_surgery.py/llava_surgery_v2.py/convert_image_encoder_to_gguf.py、vicuna 聊天模板的使用并结合tools/mtmd源码剖析 CLIP 视觉编码器与 LLaVA 投影器projector在 GGML 计算图中的实现。读完本文你可以独立完成 LLaVA 1.5/1.6 模型的本地推理部署与权重转换。支持范围与模型来源llama.cpp 当前实现支持 LLaVA v1.5 系列模型如 llava-v1.5-7b/13b以及 LLaVA v1.6 系列涵盖 7B 到 34B 的多种规格。官方文档同时提供了两类模型的预转换 GGUF 版本7b、13b 及 llava-1.6 的 7b-34b 系列可直接下载使用无需自行转换。需要注意 llama.cpp 的多模态支持是一个处于快速迭代中的子项目tools/mtmd/README.md 中明确提示“very heavy developmentbreaking changes are expected”。LLaVA 是最早引入的多模态模型其llava.cpp/clip.cpp架构后来被扩展为统一的多模态库libmtmd并整合进单一命令行工具llama-mtmd-cli。运行 LLaVAllama-mtmd-cli构建与启动首先构建llama-mtmd-cli二进制文件它是tools/mtmd下的统一多模态 CLI取代了早期的llava-cli。构建完成后直接运行./llama-mtmd-cli即可查看用法。文档给出的典型运行命令./llama-mtmd-cli -m ../llava-v1.5-7b/ggml-model-f16.gguf \ --mmproj ../llava-v1.5-7b/mmproj-model-f16.gguf \ --chat-template vicuna关键要点两个 GGUF 文件缺一不可-m指定语言模型 GGUF--mmproj指定多模态投影器multimodal projector文件。这与 tools/mtmd/README.md 的说明一致——运行多模态模型通常需要两个 GGUF标准语言模型文件和对应的mmproj文件后者负责图像编码与投影。建议低温度采样文档明确建议--temp 0.1左右的低温度以获得更好的回答质量。GPU 卸载使用常规的-ngl参数将层卸载到 GPU与纯文本推理一致。LLaVA 1.6 需要更大上下文llava-1.6 比 1.5 需要更多上下文至少 3000文档建议直接-c 4096运行。批处理提示词llava-1.6 从批量提示处理batched prompt processing中获益明显使用默认设置即可。聊天模板vicuna对 llava-1.5 和 llava-1.6都需要使用vicuna聊天模板即添加--chat-template vicuna。在源码中可以看到对应的处理逻辑tools/mtmd/mtmd-cli.cpp 在加载旧 LLaVA 模型时会提示For old llava models, you may need to use --chat-template vicuna并在params.chat_template vicuna时启用相应模板。区分当前运行的是 1.5 还是 1.6运行时提示词处理前会打印一条视觉编码信息可以据此判断模式LLaVA 1.5encode_image_with_clip: image embedding created: 576 tokensLLaVA 1.6大于 576encode_image_with_clip: image embedding created: 2880 tokens也可以直接观察 prompt 实际消耗的 token 数llava-1.6 会显示 1000 个 token。这个差异源于两个版本图像分辨率策略不同1.5 使用 CLIP 固定分辨率输出 24×24576 个 patch token源码注释中可见 shape[1, 576, 1024]见 tools/mtmd/models/llava.cpp而 1.6 采用多分辨率切片token 数相应成倍增加。因此 1.6 才会出现“至少 3000 上下文”的要求。LLaVA 1.5 模型转换流程完整流程是把一个 LLaVA 模型拆成 LLaMA 语言部分和 CLIP 视觉编码 投影器部分再分别转换为 GGUF。第 1 步克隆 LLaVA 模型和 CLIP 模型可用 HuggingFace 仓库git clone llava-v1.5-7b 仓库地址 git clone clip-vit-large-patch14-336 仓库地址第 2 步安装所需 Python 依赖pip install -r tools/mtmd/requirements.txt该依赖文件tools/mtmd/requirements.txt包含 pillow、torch、torchvision 以及 legacy 转换脚本所需的依赖。第 3 步用llava_surgery.py将 LLaVA 模型拆分为 LLaMA 和 multimodal projector 两部分python ./tools/mtmd/llava_surgery.py -m ../llava-v1.5-7b脚本位于 tools/mtmd/legacy-models/llava_surgery.py-m参数指向 LLaVA v1.5 模型目录。第 4 步用convert_image_encoder_to_gguf.py把视觉编码器CLIP ViT LLaVA projector转换为 GGUFpython ./tools/mtmd/convert_image_encoder_to_gguf.py -m ../clip-vit-large-patch14-336 \ --llava-projector ../llava-v1.5-7b/llava.projector --output-dir ../llava-v1.5-7b第 5 步用examples/convert_legacy_llama.py把 LLaVA 中的 LLaMA 部分转换为 GGUFpython ./examples/convert_legacy_llama.py ../llava-v1.5-7b --skip-unknown完成后llava-v1.5-7b目录中同时包含语言模型 GGUFggml-model-f16.gguf和视觉编码 GGUFmmproj-model-f16.gguf即可按上文方式运行。LLaVA 1.6 GGUF 转换流程llava-1.6 的模型结构是 HuggingFace transformers 的ImageTextToText格式视觉塔内嵌在模型中因此流程略有不同使用llava_surgery_v2.py1) 克隆 LLaVA 1.6 模型例如git clone llava-v1.6-vicuna-7b 仓库地址2) 安装 Python 依赖同上pip install -r tools/mtmd/requirements.txt3) 运行llava_surgery_v2.py拆分模型。该脚本tools/mtmd/legacy-models/llava_surgery_v2.py同时支持 llava-1.5 的 pytorch 与 safetensors 格式模型python tools/mtmd/llava_surgery_v2.py -C -m ../llava-v1.6-vicuna-7b/其中-C--clean-vision-tower表示从模型文件中移除视觉塔。运行后模型目录中会生成llava.projector和llava.clip两个文件。4) 组装一个独立的 ViT 目录把llava.clip复制为vit/pytorch_model.bin把llava.projector复制进vit/并放入匹配的 ViT 配置文件文档以 cmp-nct 的 llava-1.6-gguf 仓库中提供的config_vit.json为例mkdir vit cp ../llava-v1.6-vicuna-7b/llava.clip vit/pytorch_model.bin cp ../llava-v1.6-vicuna-7b/llava.projector vit/ # 将对应的 ViT 配置文件下载/复制为 vit/config.json5) 生成视觉 GGUF 模型。与 1.5 相比差别在于需要额外加--clip-model-is-vision参数告诉编码器现在处理的是纯视觉模型部分python ./tools/mtmd/convert_image_encoder_to_gguf.py -m vit \ --llava-projector vit/llava.projector --output-dir vit --clip-model-is-vision6) 转换语言模型部分python ./examples/convert_legacy_llama.py ../llava-v1.6-vicuna-7b/ --skip-unknown7) 运行 CLI./llama-mtmd-cli -m ../llava-v1.6-vicuna-7b/ggml-model-f16.gguf \ --mmproj vit/mmproj-model-f16.gguf记得按需加-c 40961.6 需要至少约 3000 上下文以及-ngl做 GPU 卸载。语言模型不兼容 legacy 转换脚本时文档给出了备用方案——如果第 6 步中语言模型与 legacy 转换脚本不兼容最简便的做法是用 transformers 加载模型并仅导出其中的 LLM 部分import transformers model_path ... llm_export_path ... tokenizer transformers.AutoTokenizer.from_pretrained(model_path) model transformers.AutoModelForImageTextToText.from_pretrained(model_path) tokenizer.save_pretrained(llm_export_path) model.language_model.save_pretrained(llm_export_path)然后用覆盖面更广的 convert_hf_to_gguf.py 转换导出的 LLM。源码级剖析CLIP 编码与 LLaVA 投影器如何实现从源码结构看LLaVA 的视觉编码核心位于 tools/mtmd/models/llava.cpp 的clip_graph_llava::build()中注释标明该图被 llava、granite 和 glm 共用。其执行链路为输入准备仅支持方形 patch 网格GGML_ASSERT(n_patches_x n_patches_y)。若有 class embedding将其与 patch embedding 沿第 1 维拼接再加上按 position 索引取出的位置编码。Transformer 层循环逐层执行 pre-LayerNorm → 多头自注意力Q/K/V 投影 reshape 到[d_head, n_head, n_pos]→ 残差 → LayerNorm2 → FFN支持 gate 分支→ 残差。取特征层默认取倒数第二层hparams.n_layer - 1作为投影器输入这与 LLaVA 原设计一致部分变体如 granite可显式指定多个 feature layer 并堆叠。LLaVA 投影器当hparams.has_llava_projector时先按 patch 索引取回 576 个视觉 token注释中标明 shape[1, 576, 1024]再按投影器类型执行PROJECTOR_TYPE_MLP标准 LLaVA 两线形层 GELUmm_0_w→ GELU → 可选mm_2_w对应llava.projector中的权重PROJECTOR_TYPE_MLP_NORM带 LayerNorm 的四线形层版本其余类型如 MobileVLM 的 LDP/LDPV2、GLM-Edge 卷积投影器也复用同一张图但 LLaVA 本身只用 MLP 类型。投影后的视觉 embedding 随后进语言模型替换 prompt 中的图像占位符——这也解释了为什么 1.5 会打印 576 个 image token。llava_surgery.py/llava_surgery_v2.py脚本位于 tools/mtmd/legacy-models/的作用正是在 Python 侧把上述“CLIP 视觉塔权重”“projector 权重”“LLM 权重”分离到不同文件中再由convert_image_encoder_to_gguf.py与convert_legacy_llama.py分别打包成mmproj-*.gguf与ggml-model-*.gguf与 C 侧加载的张量命名一一对应。实用检查清单运行前确认两份文件LLM 的ggml-model-f16.gguf 视觉的mmproj-model-f16.gguf加--chat-template vicuna1.5 与 1.6 通用建议--temp 0.1GPU 上用-ngl卸载llava-1.6 加-c 4096并留意 prompt 中 1000 的图像 token 占用通过image embedding created: N tokens日志确认模式576 为 1.52880 及以上为 1.6语言模型若无法用 legacy 脚本转换改用 transformers 导出 LLM 后用 convert_hf_to_gguf.py。相关文档与代码入口原始文档docs/multimodal/llava.md多模态总览docs/multimodal.md、tools/mtmd/README.md视觉编码实现tools/mtmd/models/llava.cpp、tools/mtmd/clip.cpp拆分脚本tools/mtmd/legacy-models/llava_surgery.py、tools/mtmd/legacy-models/llava_surgery_v2.py编码转换tools/mtmd/legacy-models/convert_image_encoder_to_gguf.pyLLM 转换examples/convert_legacy_llama.py、convert_hf_to_gguf.pyCLI 入口tools/mtmd/mtmd-cli.cpp【免费下载链接】llama.cppLLM inference in C/C项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考