ARTICLE DETAIL

资讯详情

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

llama.cpp mtmd-debug 调试指南:用 PyTorch 对照验证多模态模型的 encode 与 preprocess 两条流水线

llama.cpp mtmd-debug 调试指南:用 PyTorch 对照验证多模态模型的 encode 与 preprocess 两条流水线 llama.cpp mtmd-debug 调试指南用 PyTorch 对照验证多模态模型的 encode 与 preprocess 两条流水线【免费下载链接】llama.cppLLM inference in C/C项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp本文基于 llama.cpp 仓库中的 mtmd-debug.md 撰写讲解llama-mtmd-debug这个内部调试工具的使用方法它如何用确定性合成输入灰图、彩虹图、正弦波音频驱动多模态模型的 encode 与预处理两条流水线并给出与 HuggingFace transformers 的get_image_features逐值对照的 PyTorch 代码帮助你在移植或修改 vision/audio 投影模型时定位数值偏差出在哪一层。1. mtmd-debug 的定位多模态流水线上的最小可复现实验台在 llama.cpp 的多模态子项目中运行一个视觉模型需要两个 GGUF 文件语言模型文件与多模态投影文件mmproj负责图像/音频编码与投影。整个数据通路可以拆成两段预处理preprocess阶段把原始字节uint8_tRGB 图像、PCM 音频采样转换成模型可接受的归一化浮点张量图像归一化、resize、mel 频谱等编码encode阶段把预处理后的 f32 张量送入 ViT 投影头输出喂给语言模型的 embedding。一旦模型输出与 PyTorch 参考实现对不上问题通常出在上述两段之一。mtmd-debug.md 给出的正是这套对照实验方法而实现载体是仓库中的调试二进制llama-mtmd-debug见 tools/mtmd/CMakeLists.txt 中add_executable(llama-mtmd-debug debug/mtmd-debug.cpp)其入口源码为 tools/mtmd/debug/mtmd-debug.cpp。需要注意工具自身的边界声明mtmd-debug.cpp 开头注释写明 INTERNAL TOOL FOR DEBUGGING PURPOSES ONLY / NOT INTENDED FOR PUBLIC USEmtmd-debug.h 同样声明这是内部调试 API、不建议就此 API 提交 issue。它复用了common_params的其他示例参数但语义有变源码注释原文we repurpose some args from other examples, they will have different meaning here。2. 命令行接口参数、模式与合成输入按 mtmd-debug.cpp 中show_additional_info打印的用法说明标准调用形式为Usage: llama-mtmd-debug -m model --mmproj mmproj -p mode -n size --image image --audio audio参数语义注意与普通示例的差异-m model语言模型 GGUF--mmproj mmproj多模态投影 GGUF必填缺失时会报错退出见 mtmd-debug.cpp-p mode调试模式取值为encode默认调试编码阶段或preproc调试预处理阶段-n size图像时为该边每侧的像素数始终构造正方形图像音频时为采样点数--image name/--audio name合成输入的名称二者至少指定其一。工具在初始化时会把 mmproj 加载参数固定为调试姿态强制开启计时mparams.print_timings true、透传image_min_tokens/image_max_tokens/flash_attn_type等参数并无条件注册调试回调源码注释always enable debug callback见 mtmd-debug.cpp使计算图中每个张量求值后都经过common_debug_cb_eval输出原理见第 4 节。2.1 encode 模式可用的合成输入encode模式下直接构造已预处理好的 f32 值跳过预处理图像输入均为n×n×3的浮点像素--image取值生成的图像white/black/gray全图填充 1.0f / 0.0f / 0.5fred/green/blue仅对应单通道为 1.0f其余通道 0cbcheckerboard 棋盘格1.0f 与 0.0f 交替rainbow类树莓派 Logo 的 HSV 彩虹圆盘色相由角度决定、饱和度由半径决定见 mtmd-debug.cpp 中的 HSB→RGB 分支表音频输入构造长度为n的 f32 采样序列one/zero/half分别填充 1.0f / 0.0f / 0.5f1010为 0/1 交替方波。构造完成后分别调用mtmd_debug_encode_image/mtmd_debug_encode_audio见 mtmd-debug.cpp。2.2 preproc 模式可用的合成输入preproc模式-p preproc的输入是原始数据图像为uint8_tRGBwhite255、black0、gray128、cb棋盘格 0/255 交替音频为 f32 PCM 采样one/zero/half以及440——440 Hz 正弦波频率换算使用mtmd_get_audio_sample_rate从 mmproj 的 hparams 中读取的采样率见 mtmd-debug.cpp 与 mtmd.cpp。工具随后调用mtmd_debug_preprocess_image/mtmd_debug_preprocess_audio见 mtmd-debug.cpp。提示mtmd-debug.md原文档中 Debugging preprocess pass 一节尚标注为 TODO但从 mtmd.cpp 的当前实现看预处理调试路径已具备完整实现图像会经image_preproc-preprocess输出 f32 batch 并逐 entry 打印尺寸音频会经audio_preproc-preprocess转成 mel 频谱分块并按mel[i][m][t]逐个值打印可直接按上表使用。3. PyTorch 对照端encode 阶段的参考实现mtmd-debug.md 的核心内容是用 transformers 复刻 C 端 encode 阶段的输入得到参考last_hidden_state。两份示例都使用与llama-mtmd-debug相同的 896×896 输入从而保证 ViT 输出 token 数一致便于逐项比对。3.1 灰图示例对应 C 端--image gray0.5f 填充的 PyTorch 等价输入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()要点pixel_values直接是 f32 归一化值0.5 灰度与 C 端mtmd_debug_encode_image接收的已预处理 f32 像素处于同一数据面因此输出可以直接比较。注意原文档中img_size 896的注释写的是 number of patches per side实际它是像素边长以 patch size 16 计对应 56×56 个 patch。3.2 彩虹图示例彩虹图用于验证空间结构敏感的路径卷积/patch 切分、位置编码、归一化顺序比纯色图更能暴露实现差异。PyTorch 版逐像素执行与 mtmd-debug.cpp 中 C 版完全相同的 HSV→RGB 算法hue atan2(dy,dx)映射到 0..1sat 半径/最大半径再按六个扇区插值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)4. C 端的观测手段从源码看它打印了什么理解工具能证明什么需要看它内部的三类观测点1逐张量的中间值回调。mtmd-debug初始化时把common_debug_cb_eval挂为 ggml 调度器求值回调mtmd-debug.cpp。该回调定义在 common/debug.h实现在 common/debug.cpp它对计算图中每个被处理的张量逐维展开打印数值大张量会按...折叠中间部分并支持通过common_debug_cb_user_data传入正则filter_patterns只打印匹配的张量、以及abort_on_nan在遇到 NaN 时立即中止会话。也就是说encode 阶段每个算子卷积、归一化、注意力、投影 MLP的输出都可以直接肉眼检查定位从哪一层开始数值发散。2最终 embedding 摘要。encode 路径的实现mtmd_debug_encode_implmtmd.cpp先调用clip_set_debug_output_embeddings(ctx_clip, true)再执行clip_image_encode。在 clip.cpp 中该开关也可由环境变量MTMD_DEBUG_EMBEDDINGS触发见 clip.cpp会让最终投影 embedding 以 MTMD_DEBUG_EMBEDDINGS 段落打印张量形状[n_embd, n_tokens]、第 0 个 token 的前 16 个与后 16 个值、以及整体统计量mean / std / min / max / sum。这些统计量提供了与 PyTorch 端last_hidden_state做快速粗比对先对统计量、再对首 token 前几个值的锚点。3预处理阶段的结构信息。mtmd_debug_preprocess_imagemtmd.cpp把clip_image_u8送入模型的image_preproc-preprocess打印预处理后 batch 的 entry 数量与每个 entry 的nx×ny尺寸mtmd_debug_preprocess_audiomtmd.cpp则打印每个 mel 分块的n_len×n_mel并逐值转储 mel 数据mel-major 布局。这与 transformers 的processor输出pixel_values/input_features处于同一比较面。5. 实操流程与比对建议结合上述机制一个完整的 encode 调试流程是构建编译时启用 tools默认构建即会产出llama-mtmd-debug见 tools/mtmd/CMakeLists.txt产物名为llama-mtmd-debugC 侧llama-mtmd-debug -m 模型.gguf --mmproj mmproj.gguf -p encode -n 896 --image gray或rainbow从输出中记录MTMD_DEBUG_EMBEDDINGS段落的 shape、统计量与首 token 片段必要时结合cb_eval的逐张量打印检查中间层PyTorch 侧按第 3 节代码对同一输入调用model.model.get_image_features打印last_hidden_state的 shape、均值/标准差与前 16 个值定位统计量mean/std/min/max一致 → 输出基本对齐统计量接近但个别值偏移 → 检查量化与 f16/f32 精度差统计量量级就不同 → 用逐张量打印二分定位到具体算子通常是归一化统计mean/std、patch 展平顺序或投影层权重布局问题。preproc侧同理C 端跑-p preproc -n size --image gray与 transformers 中processor对同一原始图像产生的pixel_values比对形状与数值。6. 适用前提与限制该工具依赖一个可加载的 mmproj且 mmproj 中的视觉/音频模型决定行为encode 音频路径要求 mmproj 含音频分支否则mtmd_debug_encode_audio报 model does not support audio input见 mtmd.cpp图像路径则要求含视觉分支图像输入永远是正方形nx ny且 encode 模式假设输入已完成预处理——它接收的就是预处理后的 f32 值与 mtmd-debug.h 中的注释一致音频 encode 输入会被按n_mel_bins广播成[n_samples, n_mel]频谱形状mtmd.cpp即合成音频在 C 端是伪 mel输入与真实音频经preprocess得到的 mel 频谱不同仅用于打通 encode 通路工具属于内部调试设施参数语义复用了通用示例参数-p表示模式而非 prompt、-n表示尺寸而非生成长度不要把它当作面向终端用户的接口使用。7. 小结mtmd-debug.md 描述的方法论可以概括为一句话用确定性合成输入把 encode 与 preprocess 两条路径各自钉死再用 PyTorchget_image_features作为参考 oracle 做逐值比对。C 侧的 mtmd-debug.cpp 提供了从纯色到彩虹图的图像激励与方波/正弦的音频激励mtmd.cpp 中的四个mtmd_debug_*入口分别作用于预处理后与预处理前两个数据面配合 common/debug.cpp 的逐张量打印和 clip.cpp 的 embedding 摘要覆盖了一个多模态投影实现从原始字节到语言模型 embedding的全链路可观测性。对于正在为 llama.cpp 移植新 vision/audio 模型的开发者这套对照实验是排查数值偏差的第一站。【免费下载链接】llama.cppLLM inference in C/C项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表