📄 omni-macos: On-Device Omni-Modal Search on Apple Silicon
标签:#音频检索 #多模态模型 #高效推理 #开源工具 #模型压缩
7.2/10 | 创新 1.2/2 | 严谨 1.1/1.5 | 实验 0.8/1.5 | 清晰 0.8/1 | 影响 0.5/1.5 | 开源 1.2/1.5 | 复现 0.3/0.5 | 工程 1.3/1.5
✅ 7.2/10 | 前50% | 文档类型:系统技术报告 | 评分置信度:高 | #音频检索 | #多模态模型 | #高效推理 #开源工具 | arxiv
👥 作者与机构
- 第一作者:Han Xiao(Jina AI by Elastic,来自论文署名行)
- 通讯作者:未说明(论文未明确标注通讯作者)
- 作者列表:Han Xiao(Jina AI by Elastic)
💡 毒舌点评
工程完成度确实高,把“隐私、持续索引、交互延迟、统一内存预算”做成一个可运行的原生 macOS 系统,并且每个机制都给了跨五台机器的测量。但论文始终没有与任何既有检索系统做端到端质量对比,检索质量只靠“与自身 bf16 扫描的一致性”来间接说明,更像一份优秀的系统报告而非完整的检索研究。作为审稿人,我愿意接收为系统展示/工程论文,但不会把它当作检索质量或 SOTA 的证据。
📌 核心摘要
论文提出 omni-macos,一个完全运行在 Apple Silicon 上的多模态本地语义搜索系统。解决的问题是:服务器式嵌入和索引对私人文件不可接受,而本地文件搜索必须同时满足持续索引、交互延迟和用户可设置内存上限。方法上,系统在单个 Swift 进程中运行 jina-embeddings-v5-omni 编码器、文件监听/爬取、向量存储和搜索 UI,所有文件、查询和向量都不离开本机;核心机制包括基于 chunk 哈希的编辑复用、击键驱动的 anticipatory shaping、4-bit 驻留副本加精确重排的 rerank funnel、以及把内存上限传播到所有统一内存分配器的 cap propagation。相比已有 ANNS 或缓存类工作,它把“隐私、索引时效、交互延迟、内存预算”作为统一系统问题处理,而不是只优化单一组件。实验在五台 Mac(内存 16–512 GB、GPU 10–80 核)的真实语料上进行:文本查询中位 4.8–37.4 ms,append 复用节省 86.0–87.6% 时间,tail-row narrowing 提升吞吐 5.3–6.6%,搜索与索引并发下 p99 在四台机器上下降 78–93%、第五台下降 45%。但论文未提供与任何外部检索系统的公平对比,检索质量只用 recall@10 与自身 bf16 扫描的一致性间接验证。实际意义在于提供一个可离线、私有、可被本地 agent 调用的搜索基础设施;主要局限是真实语料高度异质、部分机器样本量极小,M4 Pro 没有音频文件,音频/语音只是多模态之一,领域专用结论有限。
下图展示了omni-macos系统在实际本地文件上的搜索结果示例。

图中显示了对查询’porsche sports car’返回的多模态结果,包括PDF、HTML、XML、源代码、Markdown和照片,直观验证了系统通过共享嵌入空间实现跨文件类型的统一语义搜索能力。
🔗 开源详情
- 代码:https://github.com/hanxiao/omni-macos(Apache 2.0;仓库内含 headless 命令行工具,可复现 generated-corpus 测量)
- 模型权重:https://huggingface.co/collections/jinaai/jina-embeddings-v5-omni-69f336b985c156b1d757029e(jina-embeddings-v5-omni-nano,0.95B;jina-embeddings-v5-omni-small,1.57B;论文未注明权重许可证)
- 数据集:论文中未提及公开数据集。实验使用各机器本机文件(未公开)和固定生成语料;论文未提供下载链接/生成脚本。
- Demo:论文中未提及在线 Demo;应用为本地 macOS 原生程序,界面见 Figure 1。
- 复现材料:代码仓库 Apache 2.0 开源;仓库 headless CLI 可复现生成语料上的测量;论文报告所有机器使用同一 build、array framework 0.31.3 与同一 encoder;附录 A.6 等包含内存上限下的 transient 测量;标签方法说明见 https://hanxiao.io/ttc-embedding-image-tagging-2026/ 和 https://www.youtube.com/watch?v=ItVQqeNeR5M
- 论文中引用的开源项目:UMAP(https://github.com/lmcinnes/umap)、SQLite(https://www.sqlite.org/)、FAISS(https://github.com/facebookresearch/faiss,对应 Johnson et al. 2021)、HNSW(https://github.com/nmslib/hnswlib,对应 Malkov & Yashunin 2020)。论文正文未给出后两者的 URL,按引文对应列出。
🏗️ 方法概述和架构
整体流程是一个单进程、双路径的系统。索引路径由全量爬取或文件系统事件触发:先抽取内容、按固定字符网格切 chunk、计算 hash,只对 hash 未命中的 chunk 做编码器前向传播,得到向量后写入 delta store;查询路径由搜索框、拖拽文件、本地 MCP 服务或 agent 工具触发:先把 query 编码为向量,再扫描驻留的 4-bit 副本,选出 top-C 粗排候选,最后用精确向量重排并返回。两条路径通过同一个非抢占二类 gate 串行访问 GPU,因此不会同时占用加速器。
编码器是论文用 Swift/Metal 自实现的 jina-embeddings-v5-omni,有 nano(0.95B,768 维)和 small(1.57B,1024 维)两档。它把检索 LoRA adapter 在加载时合并进 base:\(W += (\alpha/r)BA\),所以运行时只有一组稠密权重。精度按张量选择:主干 matmul/attention 用 bf16,视觉塔 residual stream 保留 fp32,attention 输入用 bf16 operand 但 fp32 累加。实现还做了 kernel launch 合并,例如把同一图像的多个 attention window 拼成块对角一次调用;以及 tail-row narrowing:因为 embedding 只取最后 token 的 pooled row,所以 attention 之后的后置 norm、MLP、残差和最终 norm 可以只在这 1 行上计算,而不是在整个序列上计算,对 nano 可省约 6.25% 算力。
chunk 级复用模块是降低持续索引成本的关键。chunk 按从文件开头计算的固定字符网格切割,因此 append 时除最后一个 chunk 外所有边界不变,mid-file 插入则只有前缀存活。每个 chunk 的 row 旁边记录 hash,hash key 覆盖 chunk 文本、长度、overlap 和 embedding 维度,但不包含 encoder 身份;换模型时必须强制重索引,避免同维度不同编码器产生别名。复用查找在串行侧而非并发 decode 阶段执行,因为后者没有为 retrieved vectors 预留 byte budget。
交互调度上,系统利用 GPU command buffer 提交后不可取消的特点,只做 admission control。键击先去抖,随后打出一个 activity window;在该窗口内,索引器把文本 batch 切成更小单元,并每个单元取一次 gate,图像/音频路径则每次只持有 gate 对应单个 item。这样查询最多只需等待一个小单元,而不是一整批。论文承认这会增加 launch 次数,可能抬高中位延迟,但显著压低了尾部延迟。
存储侧采用 rerank funnel:不建 ANN 图索引,因为连续编辑会让图结构持续失效且图索引内存不可控;图索引在 degree 32、base layer 两倍度数的设置下约需 256 bytes/vector,四百万 chunks 时约 0.95 GB。所有向量按行存放;驻留的是一个 4-bit group-quantized replica,精确向量放在 file-backed mmap 中,按页载入。查询时扫描 4-bit 副本,按 coarse score 取 top-C(C=1920,独立于 N),再对 shortlist 用精确向量重排。can’t-win prune 在展开精确向量前,用当前第 K 名分数过滤不可能进入 top-K 的候选行;idle fold 只在写入暂停和搜索不活跃时把新行折入驻留矩阵。持久化用 WAL 模式,崩溃最多丢最近事务,并靠单调计数器拒绝过期的 sidecar。
内存上限传播是系统级设计。用户设置一个总 cap,该 cap 被分配到扫描矩阵表示选择、解码媒体 byte gate、vision packing budget、buffer cache、数据库 page cache、转换临时缓冲区等所有能发现的 unified-memory 分配器。矩阵 dtype 转换按 slab 进行,避免在源矩阵旁边再物化一整个目标矩阵;数据库 compaction 期间临时缩小 page cache,结束后再恢复。论文特别强调不存在枚举这些 allocator 的声明式接口,因此该列表只能经验性发现,且单个 allocator 用一个数字并不总是够用。
💡 核心创新点
- 单进程、纯本地、真正离线的 omni-modal 搜索系统:之前几乎所有多模态编码、索引、检索组件都假设服务器。omni-macos 把 encoder、watcher、index、store、UI 全部放进一个 macOS 进程,网络断掉仍可用。收益是 privacy by construction,而不是靠访问控制或策略承诺。
- 面向编辑历史的 chunk 级 hash 复用:之前要么整文件重嵌入,要么只做 whole-object cache。固定字符网格使 append 几乎全量复用,mid-file 插入约复用一半。论文实测 append 复用节省 86.0–87.6% 的索引时间,watcher 路径下 append 节省 97.9% GPU token。
- 面向非抢占 GPU 的 anticipatory shaping:由于 command buffer 无法取消或降级,只能把优先级表达在 admission 上。用去抖后的键击活动窗口提前把索引 batch 切小,使查询最多等一个小单元。实测搜索与索引并发时 p99 在四台机器上下降 78–93%,第五台下降 45%,同时承认中位延迟可能变差。
- 4-bit 驻留副本 + 精确重排的 rerank funnel:不用 ANN,避免图索引的持续失效和额外内存;扫 4-bit 副本再对固定 shortlist 精确重排。相比 bf16 全扫描,矩阵缩小到约 1/4,在 0.25M–4M chunks 上 recall@10 与全扫描一致或更好。
- Cap propagation:把一个用户可见内存上限传播到所有共享 unified-memory 的 allocator,包括应用代码没有显式分配的 buffer cache 和 page cache。矩阵转换、视频 staging、compaction 等瞬态峰值也纳入预算;compaction 峰值在五台机器上一致减少约 73.5–76.4 MB。
📊 实验结果
论文用两类语料:五台机器各自的真实本地文件,以及一个由 seed 生成、跨机器固定的 4,616 文件语料。注意:论文没有提供与任何外部检索系统(本地或服务器端)的端到端质量对比,以下全部为系统自报结果。下表保留论文中五台机器上的代表性任务延迟(p50;Search while indexing p99 单列)。
| 任务(ms) | M3 Ultra | M4 Pro | M4 | M3 Pro | M2 |
|---|---|---|---|---|---|
| Filename query(p50) | 2.3 | 2.4 | 4.6 | 3.3 | 31.1 |
| Text query(p50) | 4.8 | 9.0 | 9.4 | 7.9 | 37.4 |
| Find similar(p50) | 2.1 | 0.4 | 4.6 | 3.3 | 31.0 |
| Image query(p50) | 44.2 | 301 | 805 | 560 | 243 |
| Video query(p50) | 165 | 972 | 662 | 464 | 1080 |
| Search while indexing(p50) | 6.9 | 12.0 | 12.8 | 46.7 | 127 |
| Search while indexing(p99) | 48.8 | 68.2 | 776 | 570 | 427 |
附表:论文在固定 6 GB cap、同一生成语料上的机制消融,数值为相对该机制关闭时的收益。这些是论文自己实现“开/关”对比,不是与 SOTA 系统的比较。
| 机制 | M3 Ultra | M4 Pro | M4 | M3 Pro | M2 |
|---|---|---|---|---|---|
| Reuse, append(时间节省 %) | 86.0 | 86.8 | 87.6 | 87.5 | 87.6 |
| Reuse, mid-file(时间节省 %) | 43.1 | 42.5 | 41.1 | 42.6 | 40.1 |
| Tail-row narrowing(吞吐提升 %) | 5.3 | 6.6 | 6.2 | 6.2 | 6.2 |
| Can’t-win prune(延迟节省 %) | 21.1 | 16.2 | −9.5 | 32.7 | 12.3 |
| Idle fold(fold 时间节省 %) | 52.7 | 40.8 | 37.1 | 36.0 | 28.8 |
| Compaction peak saved(MB) | 76.4 | 74.2 | 73.5 | 75.8 | 76.3 |
全文关键数字还包括:全量索引时 accelerator busy 为 97.7–99.7%,说明索引时间基本就是 encoder 时间;索引吞吐为 9,221–83,848 tokens/s,每 GPU 核 922–1,348 tokens/s;funnel 在 0.25M–4M chunks 上 recall@10 与 bf16 全扫描一致或更好,例如 25 万 chunks 时 0.9812 vs 0.9828,400 万 chunks 时 0.9594 vs 0.9687,且矩阵缩小到约 1/4;小内存机器约 250k chunks 时 funnel 就开始优于全扫描,M3 Ultra 要到 500k–1M chunks 才交叉。M4 Pro 语料只有 7,726 chunks、93 张图,并且没有音频文件,audio query 行为空;M3 Pro 只有 12 个多 chunk 文本文件,相应 p99 缺失。
🔬 细节详述
- 训练数据:未说明。论文没有训练新模型,使用 jina-embeddings-v5-omni 预训练权重,原始训练数据不属本文范围。
- 损失函数:不适用。系统不训练、不微调 encoder,没有新损失函数。
- 训练策略:不适用。仅加载 retrieval adapter 并合并到 base:
\(W += (\alpha/r)BA\),加载后为单一稠密权重。 - 关键超参数:jina-embeddings-v5-omni-nano 为 0.95B、768 维;small 为 1.57B、1024 维。chunk 按固定字符网格切分,并带 overlap;hash key 覆盖 chunk 文本、长度、overlap 与 embedding 维度,但不含 encoder 身份。
- 检索超参数:shortlist 下限 1024、上限 4096,界面请求 60 个结果,论文固定 C=1920;4-bit replica 为按行 group-quantized;精确向量用 file-backed mmap;消融实验统一 pin 6 GB 内存 cap。
- 调度参数:图 2 标注显示 debounce 约 180 ms,activity window 约 2 s;索引器在活动窗口内减小 text batch,图像/音频路径按单 item 持有 gate。
- 推理硬件:五台 Apple silicon Mac。M3 Ultra:80 GPU 核,512 GB;M4 Pro:20 GPU 核,48 GB;M4:10 GPU 核,16 GB;M3 Pro:14 GPU 核,18 GB;M2:10 GPU 核,16 GB。操作系统版本分别为 26.5.1、26.5.1、15.7.3、26.5.0、15.6.1。
- 推理细节:GPU 侧使用 Metal command buffer,一次提交后不可取消;查询路径先编码 query,再扫描 4-bit 驻留矩阵,取 top-C 后用精确向量重排;媒体查询先解码再走对应塔,单 item 不 batch;索引路径与查询路径通过二类非抢占 gate 串行。
- 正则化或稳定训练技巧:不适用。系统侧稳定技巧包括 WAL、单调 chunk mutation counter、idle fold、compaction 前缩小 page cache、dtype 转换按 slab 进行、视频帧以 bytes 而非 fp32 staging。
⚖️ 评分理由
创新性 (1.2/2):[A_METHOD] 将 omni-modal 编码器、持续索引、4-bit funnel 和 cap propagation 集成到单进程纯本地系统,并把隐私、索引时效、交互延迟和内存上限作为统一问题处理,属于工程组合型新能力而非单点模型创新。
技术严谨性 (1.1/1.5):[A_METHOD] 对 chunk 哈希复用、tail-row narrowing、非抢占 GPU admission control、4-bit 副本精确重排和统一内存 cap 传播均有明确机制描述与因果推导;但 hash key 不含 encoder 身份、需强制重索引,以及 cap 依赖经验性发现 allocator 列表,显示设计边界依赖人工枚举。
实验充分性 (0.8/1.5):[A_RESULTS] 在五台 Mac 上报告了延迟、吞吐、消融和峰值内存等系统测量,且 funnel 有 0.25M–4M chunks 的规模扫描;但没有与任何外部检索系统的端到端公平对比,检索质量仅以与自身 bf16 扫描的 recall@10 一致性间接说明,真实语料间规模与模态构成差异极大。
清晰度 (0.8/1):[A_SUMMARY] 系统架构、双路径流程和机制消融表组织清晰,核心数字能直接支撑结论;但真实语料不可比、M4 Pro 无音频文件、M3 Pro 样本极小等边界条件分散在表格和附录,读者需自行拼接才能判断结论适用范围。
影响力 (0.5/1.5):[A_SUMMARY] 系统提供可离线、私有、可被本地 agent 调用的搜索基础设施,对隐私敏感的个人文件检索有实际价值;但论文未展示与既有检索系统的质量/延迟/内存综合优势,且音频/语音只是多模态之一,未提供音频检索质量证据。
开源 (1.2/1.5):[A_OPEN] 代码仓库 Apache 2.0 开放,包含 headless 命令行工具可复现生成语料测量;但实验数据集未公开、无生成脚本,模型权重来自外部集合且论文未注明权重许可证,核心产物开放但数据集配套不完整。
可复现性 (0.3/0.5):[A_OPEN] 论文披露了五台机器硬件、同一 build、array framework 0.31.3 和固定生成语料,并给出 headless 测量途径;但 Search while indexing 负载协议细节(并发写入文件数、batch 大小、活动窗口控制、重复次数)缺失,真实语料也未公开,关键评测配置不完整。
工程/实践价值 (1.3/1.5):[A_METHOD] 单 Swift 进程内实现 Metal 编码器、文件监听、向量存储与搜索 UI,并通过 gate、cap propagation、WAL、slab 转换和 compaction 控制实现可运行系统;五台机器上索引吞吐、并发 p99 和内存峰值均有测量支撑,工程完成度高。
🚨 局限与问题
- 论文明确承认的局限:
- chunk 复用对 mid-file 插入只有约一半收益;论文统计两个仓库最近 150 个 commit,可复用 chunk 仅 34.1% 和 39.4%。
- anticipatory shaping 会因更小的 batch 和更多 launch 提高中位延迟,论文以“尾部下降”换取“交互不卡顿”为理由接受该代价。
- can’t-win prune 在 M4 上是 −9.5% 延迟,即对该语料反而有害。
- 两阶段 selection 在真实向量上会损失 1.2–2.4 个 recall 点,因此系统保留精确 selection。
- compaction 期间 page cache 需要临时缩小,否则峰值会突破 cap;scan-matrix dtype 转换需要 slab 化,否则会产生不随索引规模增长但可观的 777 MB 瞬态峰值。
- 审稿人发现的潜在问题:
- 没有与任何外部检索系统对比:不做 ANN 的决策在个人文件规模下合理,但没有量化相比 HNSW、IVF 或服务器端向量库的检索质量/延迟/内存综合差距。
- 检索质量评估缺位:funnel 的 recall@10 是“与自身 bf16 全扫描的一致性”,不是真实 query 的语义检索质量;对“找得到用户想找的文件”这一核心目标缺乏证据。
- 真实语料之间完全不可比:M4 Pro 只有 7,726 chunks 而 M2 有 3.8M,视频/音频/扫描 PDF 比例也差异巨大,M4 Pro 没有音频文件,因此跨机器比较更多是系统行为展示,而不是统计显著的对比。
- “No file, query or vector ever leaves machine”依赖所有第三方依赖均无隐藏网络行为,论文没有提供依赖审计或网络调用白名单。
- 论文没有给出“Search while indexing”负载的完整协议细节,例如同时写入的文件数、batch 大小、活动窗口时长如何控制、重复运行次数;这会影响机制收益的可复现性。