ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

KoboldCpp 多模态调试指南:用 mtmd-debug 工具与 PyTorch 对照验证编码(encode)与预处理(preprocess)管线

KoboldCpp 多模态调试指南:用 mtmd-debug 工具与 PyTorch 对照验证编码(encode)与预处理(preprocess)管线 人工智能大模型本地部署模型推理服务【免费下载链接】koboldcppRun GGUF models easily with a KoboldAI UI. One File. Zero Install.项目地址https://gitcode.com/gh_mirrors/ko/koboldcpp点击查看免费下载本文以 KoboldCpp 仓库中的 mtmd-debug 调试文档 为主体围绕多模态视觉/音频推理管线的两大核心阶段——encode pass 与 preprocess pass系统讲解 mtmd-debug 命令行工具的使用方法、可用测试图案、PyTorch 对照脚本以及其背后的源码实现原理。读完本文你将掌握如何用合成输入纯色、棋盘格、彩虹、正弦波等对视觉编码器和音频预处理链路进行可复现的逐层排查并能够借助cb_eval调试回调输出中间 embedding 与参考实现进行比对。一、背景mtmd 的两阶段多模态管线在 KoboldCpp 中mtmdmulti-modal模块负责加载视觉vision与音频audio投影模型为语言模型提供图文音多模态输入能力。从 mtmd-debug.h 的 API 注释可以看到多模态推理被明确拆分为两个阶段encode编码阶段输入是已经预处理好的 f32 浮点数据如归一化后的像素值或音频采样值经过视觉/音频塔vision/audio tower与投影层后输出可供语言模型消费的 embedding。调试时通过cb_eval回调打印中间值。preprocess预处理阶段输入是原始数据如 uint8 的 RGB 像素、float 的 PCM 音频采样经归一化、缩放、分块tiling、梅尔频谱mel spectrogram等变换后得到编码阶段所需的 f32 张量。两个阶段的调试分工不同preprocess 负责确认原始输入 → 模型输入张量的变换是否正确encode 负责确认张量 → embedding的计算是否正确。下面的调试工具正是围绕这两条链路设计的。二、调试工具概览mtmd-debug 的编译与命令行用法mtmd-debug是仓库中一个仅供内部调试、不面向公开使用的命令行可执行程序源码位于 tools/mtmd/debug/mtmd-debug.cpp 与 tools/mtmd/debug/mtmd-debug.h。其头部注释明确写着INTERNAL TOOL FOR DEBUGGING PURPOSES ONLY / NOT INTENDED FOR PUBLIC USE即它是一个内部调试工具不面向公开使用mtmd 的调试 API 同样被标注为 Do not raise issues related to this debugging API不要针对该调试 API 提交 issue。2.1 基本用法源码中show_additional_info()mtmd-debug.cpp给出了完整的用法说明Usage: mtmd-debug -m model --mmproj mmproj -p mode -n size --image image --audio audio各参数含义如下参数含义说明-m model主语言模型路径加载基础 LLM用于构造 llama 上下文--mmproj mmproj多模态投影模型路径视觉/音频塔的 GGUF 文件必填缺失时工具直接报错退出-p mode调试模式encode默认或preproc见下文-n size输入尺寸图像为每边像素数图像始终为正方形音频为采样点数必须大于 0--image image图像测试图案见 2.3 节--audio audio音频测试图案见 2.4 节注意源码注释特别说明we repurpose some args from other examples, they will have different meaning here——该工具复用了 llama 示例程序的若干命令行参数但含义已完全不同例如用-p表示调试模式、用-n表示输入尺寸切勿与其他示例混淆。从 mtmd-debug.cpp 的main()可以看到程序初始化流程先解析通用参数common_params_parse示例类型为LLAMA_EXAMPLE_MTMD加载主模型再用mtmd_init_from_file()加载投影模型并把image_min_tokens/image_max_tokens、flash_attn_type、warmup、n_threads等透传给mtmd_context_params。其中关键的一步是// always enable debug callback mparams.cb_eval_user_data cb_data; mparams.cb_eval common_debug_cb_eval;即工具无条件启用调试回调common_debug_cb_eval位于 common/debug.h这正是 encode pass 中间 embedding 能被打印出来的机制。2.2 两种模式的差异-p encode默认跳过预处理直接把构造好的 f32 数据喂给编码器。此时--image提供的是 f32 浮点像素行内按 R、G、B 交错排列值域 0.01.0--audio提供的是 f32 采样值。-p preproc只跑预处理。此时--image提供的是 uint8 原始 RGB 像素值域 0255--audio提供的是 float PCM 采样。2.3 图像测试图案encode 模式源码mtmd-debug.cpp支持以下图案全部由代码即时生成无需准备真实图片图案名生成规则black全黑像素值 0.0fwhite全白像素值 1.0fgray全灰像素值 0.5fred/green/blue仅对应通道为 1.0f其余为 0.0fcb棋盘格checkerboard按(x y) % 2交替 1.0f 与 0.0frainbow类似树莓派开机图的彩虹图案由 HSV → RGB 转换生成见下文其中rainbow的生成逻辑在 C 端mtmd-debug.cpp与 PyTorch 端见 3.3 节是逐像素等价的以图像中心为原点用atan2(dy, dx)计算色相hue用到中心的距离归一化饱和度saturation再通过标准的 HSV 六段扇形i6 % 6的 switch转换为 RGB。2.4 音频测试图案模式图案名生成规则encodeone/zero/half全 1.0f / 全 0.0f / 全 0.5f 的采样序列encode1010方波式棋盘格按索引奇偶交替 1.0f 与 0.0fpreproc440440 Hz 标准音正弦波sin(2π·440·i / sample_rate)采样率取自mtmd_get_audio_sample_rate()编码阶段的音频输入会被**广播broadcast**以匹配梅尔频带数n_mel在 mtmd.cpp 中输入序列按audio_buf[j * audio_nx i] input[i]复制到n_mel行构造出nx 采样点数、ny n_mel的二维张量再送入编码器。三、调试 encode passPyTorch 参考对照encode 阶段的核心诉求是同一输入张量mtmd 的编码器输出应与 HuggingFace 参考模型的last_hidden_state一致。为此调试文档提供了两段可以直接在参考模型上运行的 PyTorch 脚本用合成图案作为输入打印输出的形状与数值与 mtmd-debug 工具的打印结果逐一比对。3.1 灰图gray image参考脚本mtmd-debug.md 中给出的是原始、未经预处理的灰图示例在编码阶段 mtmd-debug 已把gray展开为全 0.5f 的 f32 像素因此此处直接用 0.5 填充即可对齐from transformers import AutoModel model AutoModel.from_pretrained(...) def test_vision(): img_size 896 # number of patches per side pixel_values torch.zeros(1, 3, img_size, img_size) 0.5 # gray image with torch.no_grad(): outputs model.model.get_image_features(pixel_valuespixel_values) print(last_hidden_state shape:, outputs.last_hidden_state.shape) print(last_hidden_state:, outputs.last_hidden_state) test_vision()关键点img_size 896表示每边 patch 数量需要与 mtmd-debug 的-n 896对应即两边各 896 个像素不同模型应替换为各自的实际图像尺寸。torch.zeros(1, 3, img_size, img_size) 0.5构造 1×3×896×896 的全 0.5 灰度张量与 C 端gray图案每像素三通道均为 0.5f完全一致。用torch.no_grad()关闭梯度通过model.model.get_image_features(pixel_values...)拿到last_hidden_state后打印形状与数值。3.2 彩虹图rainbow image参考脚本mtmd-debug.md 给出的彩虹图脚本可以在同样的img_size 896下生成一个径向 HSV → RGB的彩色图案用于暴露与颜色通道处理相关的编码差异import torch import math def make_rainbow(img_size): cx, cy img_size / 2.0, img_size / 2.0 max_dist math.sqrt(cx * cx cy * cy) img torch.zeros(1, 3, img_size, img_size) for y in range(img_size): for x in range(img_size): dx, dy x - cx, y - cy hue math.atan2(dy, dx) / (2 * math.pi) if hue 0: hue 1 sat math.sqrt(dx * dx dy * dy) / max_dist sat min(sat, 1.0) h6 hue * 6 i6 int(h6) f h6 - i6 p 1 - sat q 1 - sat * f t 1 - sat * (1 - f) rgb [(1,t,p),(q,1,p),(p,1,t),(p,q,1),(t,p,1),(1,p,q)][i6 % 6] img[0, 0, y, x] rgb[0] img[0, 1, y, x] rgb[1] img[0, 2, y, x] rgb[2] return img img_size 896 pixel_values make_rainbow(img_size) with torch.no_grad(): outputs model.model.get_image_features(pixel_valuespixel_values) print(last_hidden_state:, outputs.last_hidden_state)这段脚本与 C 端rainbow图案的实现mtmd-debug.cpp逐行对应同样的atan2色相、同样的距离归一化饱和度、同样的六段扇形查表连(1,t,p),(q,1,p),(p,1,t),(p,q,1),(t,p,1),(1,p,q)这 6 组 RGB 三元组都完全一致从而保证同一张图在两边输入。3.3 encode pass 的源码实现当 mtmd-debug 运行在 encode 模式时最终会进入 mtmd.cpp 的mtmd_debug_encode_impl()static void mtmd_debug_encode_impl(mtmd_context * ctx, clip_ctx * ctx_clip, clip_image_f32 image) { clip_set_debug_output_embeddings(ctx_clip, true); int n_mmproj_embd clip_n_mmproj_embd(ctx_clip); int n_tokens clip_n_output_tokens(ctx_clip, image); std::vectorfloat embd_output(n_tokens * n_mmproj_embd, 0.0f); bool ok clip_image_encode(ctx_clip, ctx-n_threads, image, embd_output); if (!ok) { LOG_ERR(%s: failed to encode image\n, __func__); } }其核心机制clip_set_debug_output_embeddings(ctx_clip, true)开启调试输出 embedding开关使得编码过程中的中间结果能够经cb_eval回调即工具在初始化时注册的common_debug_cb_eval打印出来。分配输出缓冲根据clip_n_mmproj_embd()投影后的 embedding 维度与clip_n_output_tokens()输出 token 数分配n_tokens * n_mmproj_embd的缓冲区。执行编码调用clip_image_encode()完成视觉/音频塔的前向计算将结果写入缓冲区。打印出的 embedding 形状/数值即可与 3.1、3.2 节 PyTorch 脚本打印的last_hidden_state进行逐元素比对。图像分支mtmd_debug_encode_image()mtmd.cpp会把image.size() × 3的行交错 RGB 缓冲平铺成一维img_buf再构造clip_image_f32音频分支mtmd_debug_encode_audio()mtmd.cpp则按上文所述先把单通道采样广播到n_mel行。两个分支都先检查ctx-ctx_v/ctx-ctx_a是否存在即投影模型是否支持对应模态不支持时打印 model does not support vision/audio input。四、调试 preprocess pass预处理阶段的诉求是原始图像/音频经过归一化、分块、频谱变换后得到的中间张量应符合模型预期。文档中该小节标注为(TODO)但工具本身已实现了完整的 preproc 模式结合源码可以补全全部细节。4.1 图像预处理preproc 模式下的图像输入是 uint8 原始像素mtmd-debug.cpp图案名uint8 填充值black0white255gray128cb按(x y) % 2交替 0 与 255其实现位于mtmd_debug_preprocess_image()mtmd.cppclip_image_u8 img_u8; img_u8.set_size({nx, ny}, false); img_u8.cpy_buf(rgb_values); GGML_ASSERT(ctx-image_preproc ! nullptr); mtmd_image_preproc_out preproc_out ctx-image_preproc-preprocess(img_u8); clip_image_f32_batch batch_f32; batch_f32.is_audio false; for (auto entry : preproc_out.entries) { batch_f32.entries.push_back(std::move(entry)); }可见它把原始 RGB 缓冲打包为clip_image_u8后交给ctx-image_preproc-preprocess()处理得到若干预处理产物preproc_out.entries随后逐条打印每个 entry 的nx、ny尺寸。如果你调试的模型会在预处理阶段做动态分块tiling或分辨率缩放就能在此确认分块数量与每块尺寸是否符合预期。源码中的 TODO 注释better way to dump entry content?表明当前版本只打印各 entry 的尺寸信息尚未提供内容级 dump比对内容可借助 encode 模式的中间输出完成。4.2 音频预处理preproc 模式下的音频输入是 float PCM 采样mtmd-debug.cppone/zero/half为全 1.0/0.0/0.5 常量440为 440 Hz 正弦波。其实现位于mtmd_debug_preprocess_audio()mtmd.cppstd::vectormtmd_audio_mel mel_spec_chunks; bool ok ctx-audio_preproc-preprocess(samples.data(), samples.size(), mel_spec_chunks); if (!ok) { ... return; } LOG_INF(%s: preprocessed audio to %zu mel spec chunks\n, __func__, mel_spec_chunks.size()); for (size_t i 0; i mel_spec_chunks.size(); i) { LOG_INF(%s: mel spec chunk %zu has n_len%d, n_mel%d\n, __func__, i, mel_spec_chunks[i].n_len, mel_spec_chunks[i].n_mel); // dump mel entries: data is stored as [n_mel][n_len] (mel-major) const auto mel mel_spec_chunks[i]; for (int m 0; m mel.n_mel; m) { for (int t 0; t mel.n_len; t) { LOG_INF(mel[%zu][m%d][t%d] %f\n, i, m, t, mel.data[m * mel.n_len t]); } } }音频预处理的核心产物是梅尔频谱分块mel spectrogram chunks原始 PCM 经ctx-audio_preproc-preprocess()变换后被切分为若干mel块每块有n_len时间帧数与n_mel梅尔频带数两个维度。与图像分支不同音频分支会逐元素 dump 全部 mel 值数据按[n_mel][n_len]的 mel-major 顺序存储可直接与 PyTorch 端torchaudio/ HF 特征提取器输出的 mel 谱对比。五、调试 API 的设计边界与使用注意从 mtmd-debug.h 与 mtmd.cpp 的注释可以看出这套调试 API 是刻意与正式 API 隔离的头文件与源码均标注 INTERNAL HEADER / TOOL FOR DEBUGGING PURPOSES ONLY / NOT INTENDED FOR PUBLIC USE并要求不要针对调试 API 提交 issue四个调试入口mtmd_debug_encode_image、mtmd_debug_encode_audio、mtmd_debug_preprocess_image、mtmd_debug_preprocess_audio统一以MTMD_API导出encode 系列接收预处理后的 f32 值preprocess 系列接收原始输入值——两者输入契约完全不同使用前务必确认当前阶段。实际排查时的推荐流程先跑 preproc 模式用white/gray/cb图案确认图像分块尺寸用440正弦波确认 mel 块的时间帧数与频带数再跑 encode 模式用相同尺寸的gray或rainbow图案把打印的 embedding 与 3.1/3.2 节 PyTorch 脚本的last_hidden_state对照若数值对不上可在 PyTorch 侧调整预处理归一化、中心裁剪、分块策略逐一缩小差异来源注意-n在两种模式中含义一致但输入类型不同encode 为 f32、preproc 为 uint8/float PCM--image与--audio至少指定其一且--mmproj为必填参数。六、小结mtmd-debug 是 KoboldCpp 多模态子系统中定位编码结果不符与预处理产物不符两类问题的利器它用纯合成图案绕开真实数据集的不可控性用-p encode/-p preproc两个模式把两阶段管线分开排查用cb_eval调试回调把中间 embedding 暴露给开发者并在 mtmd-debug.md 中给出逐像素等价的 PyTorch 参考脚本。对于在 KoboldCpp 上移植、适配新视觉/音频塔的开发者而言这套合成输入 中间输出 参考实现三方对照的方法论同样适用于其他多模态推理框架的调试。相关文件速查调试文档tools/mtmd/debug/mtmd-debug.md调试工具入口tools/mtmd/debug/mtmd-debug.cpp、tools/mtmd/debug/mtmd-debug.h调试 API 实现tools/mtmd/mtmd.cpp调试回调定义common/debug.hmtmd 上下文参数cb_eval、image_min_tokens等tools/mtmd/mtmd.h赞分享人工智能大模型本地部署模型推理服务【免费下载链接】koboldcppRun GGUF models easily with a KoboldAI UI. One File. Zero Install.项目地址https://gitcode.com/gh_mirrors/ko/koboldcpp点击查看免费下载相关推荐10分钟搭建Galaxy环境从安装到运行的完整教程10分钟搭建Galaxy环境从安装到运行的完整教程 Galaxy是一个功能强大的数据密集型科学平台专为科研人员和数据分析师设计。本教程将带你快速搭建Galaik_llama.cpp 多模态推理完全指南libmtmd、mmproj 与 llama-mtmd-cli 实战ik_llama.cpp 多模态推理完全指南libmtmd、mmproj 与 llama mtmd cli 实战 导读 本文面向希望在本仓库ik_llama人工智能大模型推理引擎本地部署模型量化高级功能工具调用与多模态内容处理高级功能工具调用与多模态内容处理 本文详细介绍了AI SDK Core的高级功能包括工具调用Tool Calling机制、多模态内容处理、AI图像生成功人工智能AI 应用AI Agent工具调用MCP Clients上一篇TouchVisualizer 项目常见问题解决方案下一篇3步实战用acme.sh与AWS Route 53实现零配置SSL证书自动化创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表