首页
/ textgen 多模态(视觉)模型实战指南:从 mmproj 加载到视觉 API 的完整流程

textgen 多模态(视觉)模型实战指南:从 mmproj 加载到视觉 API 的完整流程

2026-09-05 17:09:44作者:钟日瑜

本文基于 textgen 官方文档 [docs/Multimodal Tutorial.md](https://gitcode.com/GitHub_Trending/te/textgen/blob/79b46b80ec7ec98141c570dbc26f867fdfc39ead/docs/Multimodal Tutorial.md?utm_source=gitcode_repo_files) 整理并扩充,系统讲解如何在 textgen 中启用视觉理解能力:以 llama.cpp 加载「GGUF 模型 + mmproj 视觉投影文件」为主线,覆盖 ExLlamaV3 原生多模态加载方式,并给出可直接使用的 OpenAI 兼容视觉 API 调用示例。读完本文,你可以独立完成一个本地多模态模型的下载、加载、对话测试,以及通过 /v1/chat/completions 接口向模型传入图片。

一、textgen 中的两条多模态技术路线

textgen 支持两种让本地 LLM「看懂图片」的方式,二者对文件的要求不同:

路线 模型格式 额外文件要求 底层实现
llama.cpp GGUF 需要配套的 mmproj-*.gguf 视觉投影文件 启动 llama-server 时附加 --mmproj 参数
ExLlamaV3(非 HF 版) EXL3 不需要任何额外文件 模型配置内置 vision_config,原生加载视觉组件

两条路线在代码中的入口可以清楚看到:

  • llama.cpp 路线:modules/llama_cpp_server.py 中,当用户设置了 mmproj 时,会在启动 llama-server 的命令后追加 --mmproj <path> 参数(见 cmd += ["--mmproj", str(path)],位于第 479–489 行附近),由 llama.cpp 后端完成图片 embedding;
  • ExLlamaV3 路线:modules/exllamav3.py 在加载模型时检查 config.config_dict 中是否包含 vision_config 字段,若有则通过 Model.from_config(config, component="vision") 单独加载视觉组件(第 185–199 行附近)。

两条路线最终都会把图片转换为嵌入/占位符注入生成流程,这一点在 modules/image_utils.py 和两个 loader 的 _process_images_for_generation 方法中实现。

二、快速上手:llama.cpp(GGUF + mmproj)方式

这是官方教程给出的标准流程,共 5 步。

1. 找到一个带视觉能力的高精度多模态模型

带视觉能力的 GGUF 模型通常会与一个 mmproj 文件一起上传到 Hugging Face。mmproj(multimodal projector)是把视觉编码器输出投影到语言模型词向量空间的连接层,必须与语言模型版本严格配套,混用不同模型家族的 mmproj 会得到无意义输出。

官方文档示例使用的是 unsloth/gemma-3-4b-it-GGUF 这个仓库,其中同时包含:

  • 语言模型文件:gemma-3-4b-it-Q4_K_S.gguf
  • 视觉投影文件:mmproj-F16.gguf

2. 下载语言模型到 user_data/models

将示例仓库中的 gemma-3-4b-it-Q4_K_S.gguf 下载到 textgen/user_data/models 目录。textgen 启动时会扫描该目录列出所有可用模型(目录中的 占位文件 即提示模型应放在这里)。

3. 下载配套的 mmproj 文件到 user_data/mmproj

mmproj-F16.gguf 下载到 textgen/user_data/mmproj 目录,并重命名为 mmproj-gemma-3-4b-it-F16.gguf,便于识别对应关系。这个命名规范不是随意的:从源码看,modules/utils.py 中的 get_available_mmproj() 函数会列出 user_data/mmproj/ 下的全部文件,以及主模型目录中所有以 mmproj- 开头、以 .gguf.bin 结尾的文件(is_mmproj_file 判断逻辑见第 207–209 行),这些信息直接构成 Model 页面上 "Multimodal (vision)" 下拉框的候选项。

4. 加载模型

  1. 启动 Web UI(可通过 server.pycmd_linux.sh / start_linux.sh 等脚本启动);
  2. 进入 Model 标签页;
  3. 在 Model 下拉框中选择 GGUF 语言模型;
  4. 展开 "Multimodal (vision)" 折叠面板,在下拉菜单中选择上一步下载的 mmproj 文件;
  5. 点击 Load 加载。

该下拉框在代码中的定义位于 modules/ui_model_menu.py 第 96–99 行,其提示文字也说明了扫描范围:"Lists files placed in user_data/mmproj//, plus any mmproj-*.gguf files found in your main models folder"。

此外还有两个实用细节,来自 modules/models_settings.py 第 242–253 行的自动检测逻辑:

  • mmproj 自动探测:当你使用 llama.cpp loader 且尚未为该模型保存过 mmproj 设置时,系统会调用 find_sibling_mmproj() 检查模型所在目录中是否存在恰好一个 mmproj-* 文件,若存在会自动填充到 state['mmproj']。也就是说,把语言模型和 mmproj 放在同一目录时可能无需手动选择;
  • 命令行方式:也可以不经过 UI,直接通过启动参数指定。modules/shared.py 第 99 行定义了 --mmproj 参数("Path to the mmproj file for vision models"),例如 python server.py --model path/to/model.gguf --mmproj mmproj-gemma-3-4b-it-F16.gguf。mmproj 路径解析支持三种写法:绝对/相对路径、user_data/mmproj/ 下的裸文件名、或主模型目录中的文件名(见 modules/llama_cpp_server.py 第 479–489 行)。

更多 llama.cpp loader 参数(gpu_layersctx_sizecache_type 等)可参考 [docs/04 - Model Tab.md](https://gitcode.com/GitHub_Trending/te/textgen/blob/79b46b80ec7ec98141c570dbc26f867fdfc39ead/docs/04 - Model Tab.md?utm_source=gitcode_repo_files)。

5. 发送带图片的消息

在 Chat 页点击输入框旁的 📎 图标选择本地图片作为附件,然后正常发送消息即可,模型会基于图片内容回复。从源码结构看,这条路径的数据流是:

  1. 前端把图片编码为 base64 的 image_attachments 随消息提交,modules/chat.py 第 1213–1224 行将其收集到 state['image_attachments']
  2. llama.cpp 后端在 modules/llama_cpp_server.py_process_images_for_generation 中把附件转成 PIL 图像,再通过 convert_pil_to_base64 打包进发给 llama-server 的 multimodal_data 字段(第 182–197 行);
  3. 该文件中还有一处与上下文长度相关的细节:IMAGE_TOKEN_COST_ESTIMATE = 600,即每张图按约 600 个 token 估算成本并计入 last_prompt_token_count,用于提示/截断逻辑。因此图片数量过多时可能更快触及 ctx_size 上限。

三、使用 ExLlamaV3 加载多模态模型

多模态同样支持 ExLlamaV3 loader(文档中特指非 HF 的 ExLlamaV3,而非 ExLlamav3_HF)。这种方式最大的便利是:无需任何额外的 mmproj 文件,直接加载一个多模态 EXL3 模型并发送图片即可。

官方文档给出的可用模型示例包括 turboderp/gemma-3-27b-it-exl3turboderp/Mistral-Small-3.1-24B-Instruct-2503-exl3(Hugging Face 同名仓库)。

modules/exllamav3.py 的实现看,其工作机制是:

  • 加载阶段:若模型配置含 vision_config,先于主模型加载视觉组件(注释明确说明"Load vision and draft before the main model so autosplit"顺序),并缓存到 self.vision_model
  • 生成阶段:_process_images_for_generation(第 256 行起)按优先级收集三类图片来源——WebUI 的 image_attachments、OpenAI API 的 raw_images、或消息列表中的 image_url 内容——调用 vision_model.get_image_embeddings() 生成图像嵌入,并以 ie.text_alias 作为占位符替换提示词中的图像标记,最终把 embeddings 传入生成请求。

也就是说,ExLlamaV3 路线的图片理解在本地进程内完成,而 llama.cpp 路线是把图片传给独立的 llama-server 进程处理。

四、多模态 API 示例(llama.cpp 与 ExLlamaV3 通用)

textgen 内置 OpenAI 兼容 API(默认端口 5000),视觉请求同样通过标准接口发送。完整示例见 [docs/12 - OpenAI API.md](https://gitcode.com/GitHub_Trending/te/textgen/blob/79b46b80ec7ec98141c570dbc26f867fdfc39ead/docs/12 - OpenAI API.md?utm_source=gitcode_repo_files) 的 "Multimodal/vision" 小节,这里摘录其核心用法。

方式一:/v1/chat/completions(官方推荐)

curl http://127.0.0.1:5000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "role": "user",
        "content": [
          {"type": "text", "text": "Please describe what you see in this image."},
          {"type": "image_url", "image_url": {"url": "https://example.com/cat.png"}}
        ]
      }
    ],
    "temperature": 0.6,
    "top_p": 0.95,
    "top_k": 20
  }'

content 是一个数组,按顺序混合 textimage_url 两种类型的内容块,与 OpenAI 的多模态消息格式一致。

方式二:/v1/completions

同样支持 messages 格式的混合内容数组,且支持一张消息中传多张图片(多个 image_url 块)。

Base64 图片格式

不想引用外部 URL 时,把 image_urlurl 值替换为 Data URL 格式即可:

data:image/FORMAT;base64,BASE64_STRING

其中 FORMAT 是图片格式(pngjpeggif 等),BASE64_STRING 是图片的 base64 编码。这一解析逻辑正是 modules/image_utils.pyprocess_message_content()decode_base64_image() 实现的:data:image/ 前缀走 base64 解码,http 前缀则通过 safe_get 拉取远程图片(超时 10 秒),其他格式会记录警告并跳过。

五、实践要点小结

  1. mmproj 必须与语言模型配套:不同模型家族、不同量化版本的 mmproj 不要混用,建议重命名时带上模型标识(如 mmproj-gemma-3-4b-it-F16.gguf);
  2. 两个扫描目录user_data/mmproj/ 和主模型目录下的 mmproj-*.gguf 文件都会进入下拉框候选,同一模型目录中存在恰好一个 mmproj 时还会被自动选中;
  3. 上下文预算:llama.cpp 路线下每张图按约 600 token 估算,多图对话要留意 ctx_size 是否足够;
  4. loader 选择:有 EXL3 多模态模型且希望零额外文件时选 ExLlamaV3;只有 GGUF 资源时走 llama.cpp + mmproj 路线;
  5. API 入口统一:无论哪种 loader,视觉请求都通过 /v1/chat/completions(推荐)或 /v1/completionsimage_url 内容块发送,兼容标准 OpenAI 客户端。
登录后查看全文
热门项目推荐
相关项目推荐