xiaonan.dev / open-source / llama-cpp

llama.cpp 贡献记录

一个跨平台 C/C++ 推理项目;其多模态层会把图像与音频输入转换为模型可处理的内容块。

Issue 与 PR 是可公开核验的记录;页面状态是时间快照,不会把本地通过写成已经发布。

查看贡献记录

本仓库的贡献记录

01 / 01
从下方选择一条记录。随着同一仓库的贡献增加,记录条会横向扩展;阅读区始终只聚焦当前的一条完整 case study。

tools/mtmd · libmtmd audio tokenization

贡献角色参与调查者,非主要负责人;尚未提交实现

调查单采样音频的可恢复错误边界

对 libmtmd 音频边界的一项暂定、非主要调查:结构上合法的单采样 PCM bitmap 会触发进程级断言,把异常请求升级为 server 可用性故障。

上游进度DRAFT / PROVISIONAL。Issue 仍为 Open,尚无 PR。静态根因证据与候选边界已记录,但这是非主要调查;运行复现、实现、测试、审查与采用均仍开放。
Issue
#27693
Pull Request
尚未创建
所属模块
tools/mtmd · libmtmd audio tokenization

系统背景

llama.cpp 是一个跨平台 C/C++ 推理项目,涵盖模型加载、本地与 server 推理、CPU/GPU 后端以及多模态输入。问题位于 libmtmd——媒体进入模型前的准备层,不在 backend kernel 或文本生成循环中。

音频路径中,llama-server 接收 OpenAI-compatible 的 input_audio 文件;mtmd_helper 通过 miniaudio 将 WAV/MP3/FLAC 解码成单声道 F32 PCM;libmtmd 创建 audio bitmap,随后 mtmd_tokenize 选择 model-specific preprocessor,将媒体转换成 multimodal chunks 与 audio tokens。

音频输入仍属 experimental,且共享 tokenizer 会选择多种 preprocessor。这意味着共享边界检查不能因为某一模型也许会为超短信号补零,就悄悄扩大所有音频模型的可接受输入域。

触发与影响

Issue 报告描述了 Voxtral 路径上的一个 16 kHz 单声道 WAV,解码后恰好只有一个 sample。一个 mono F32 sample 会形成合法的四字节 buffer:nx == 1、buf.size() == sizeof(float),且 buffer 仍然正确对齐。

当前 tokenizer 已把 nx == 0 作为可恢复的空输入错误,但后面又要求 buf.size() > sizeof(float)。对一个 sample 而言,4 > 4 为假,因此 GGML_ASSERT 会走到 ggml_abort,而不是返回一次请求错误。

上游报告中 CLI 会退出、server 在一次请求后失去 /health;这些运行结果属于作者报告,尚非我的本地复现。我当前参与确认的是静态路径与剩余验收门禁,而不是宣称已在 Windows 复现或已经修复。

根本原因

底层 bitmap 并没有损坏。它的字节数是 nx * sizeof(float),所以单采样对象满足表示与对齐不变量。真正的问题是:一个用户可控的最小长度问题,被写成了会终止整个进程的内部内存断言。

把 > 简单改成 >= 虽能避开这条特定断言,却会把单采样信号送入所有 model-specific preprocessor。Whisper-style 路径可能补零;Conformer、Parakeet、Granite Speech、Qwen3 TTS 等路径则有不同的 frame、normalisation 或最小长度语义。静态证据不足以支持全局放行。

错误边界还必须覆盖 /input_tokens 使用的 placeholder bitmap。若只根据 real buffer 修复,同一个 sample count 可能在 token-count 与正常 completion 路径产生不一致行为。

修复与边界

目前没有源码修改。暂定方向是在共享 audio-tokenization 边界以现有的 LOG_ERR + return-error 契约拒绝 nx < 2,并放在 real-buffer 与 placeholder 分流之前。这样异常输入会变成可恢复的请求失败,而不会继续到 abort。

已有的对齐断言仍保留为内部不变量。正常 nx >= 2 的音频仍进入完全相同的 preprocessor 路径;该方案也避免为所有音频模型定义单采样的数值行为。

这是设计候选,而不是实现完成声明。任何代码之前都需要基线复现、对 zero-sample 错误文案作出明确选择、验证 real-buffer 与 placeholder,并补上一条修复前失败、修复后通过的回归测试。

为什么这样设计

本记录被刻意标为非主要贡献。主要贡献候选已转向 Issue #27697;#27693 保留为有据可查的调查与规划参与,不代表我主导了这个 bug 或未来的 patch。

我没有把方案压缩成一个字符的 >= 修改,因为共享边界服务于语义不同的多个 preprocessor。更安全的范围是让异常外部请求可恢复,而不是为所有模型宣称一个未经验证的最小音频策略。

页面保留“上游报告”“静态源码证据”和“运行时门禁仍开放”的区别。当前没有实现、本地 commit、PR、CI 结果、维护者审查或合并可供宣称。

验证证据

  1. 01

    截至 2026-08-27 11:40 AEST,上游 Issue 为 Open、标签为 bug-unconfirmed,且没有关联的 Development branch 或 PR。macOS abort 属于 Issue 作者的来源报告,并非我的本地复现结果。

  2. 02

    在本地基线 11cd988 上的静态源码核对确认了可达路径:解码后的 mono F32 PCM 形成 audio bitmap;nx == 1 产生四字节;tools/mtmd/mtmd.cpp 在可恢复的 nx == 0 分支之后仍使用严格的 > sizeof(float) 断言。

  3. 03

    本记录没有执行 fetch、构建、模型运行、源码修改、回归测试、commit、push、PR 或 CI。Windows 基线复现、server 存活检查、placeholder 覆盖以及完整 0/1/2/正常音频矩阵仍均为开放门禁。

上游进度

  1. 静态源码路径

    已在本地基线 11cd988 核对

  2. 本地复现

    尚未运行

  3. 实现与回归测试

    仅有候选设计

  4. Pull Request

    尚未创建