跳转到内容

性能调优

如果 OMem 能用、只是感觉慢,或者你撞上了 provider 限流,又或者 ingest 占的内存比你想要的多,看这一页。每一节都是一个现象 → 对应那个能解决它的旋钮。(要看全部字段的完整参考,见 配置 schema;这一页是”我到底该改哪个”的视角。)

先问一句:是真慢,还是只是在干活?

Section titled “先问一句:是真慢,还是只是在干活?”

调之前,先搞清楚时间花在哪了——omem ingest watch 会把每个阶段跑完一个亮一个。一个看起来卡住了的任务,通常无非是这么几种:qmd 模型在冷加载、一个大 PDF 在做 OCR、或者一次慢的 Loop 拉取——都在意料之中,没一个值得”调”。要调,也只调一种成片出现的慢,别为偶发的一次较劲。

现象: ingest 时报 429 rate limit;条目失败、重试。

旋钮: 调低全局 LLM 上限——真正给 API 调用踩刹车的就是它:

Terminal window
omem config set llm.global_concurrency 2 # 默认 4;还限流就再往下调
omem config set parser.vlm_global_concurrency 2

这两个是跨进程的天花板,管的是同时进行的 LLM / 视觉调用。各 kind 的 worker 池(ingest.curate_concurrencyingest.kind_concurrency)抬高的是并行度,而这两个全局上限框住的才是真正打到 provider 的调用——所以为了限流,调低全局上限,别动那些池子。

现象: 一整次跑下来,比你想要的久(不是某一个条目卡住)。

实际在发生什么: 大部分时间花在 LLM 整理上,而这受 llm.global_concurrency 限制。如果你的 provider 扛得住,调高它能让 ingest 快起来:

Terminal window
omem config set llm.global_concurrency 16 # 前提是你的 provider 允许

不过记住,大多数重跑本来就很便宜——整理缓存 会把没变过的条目整个跳过。如果一次重跑很慢,看看 omem ingest history:一堆 recuringest 说明在干真活;一堆 cache 说明它已经很快了,墙上时钟那点时间,只是绕不开的新条目而已。

现象: omem query 要好几秒,不是几毫秒。

默认的 fts5 索引大约 50 ms 就答上来——要是都慢,那就是别的地方出问题了(查 omem doctor)。慢查询几乎一定意味着你打开了 qmd,它的几种模式是拿速度换精度:

模式速度什么时候用
bm25最快你要的就是接近关键词那样的速度
no-rerank快(热起来后)日常首选——有语义召回,又没有 reranker 那点延迟
full最慢精度拉满,而你扛得住 reranker
Terminal window
omem config set plugins.qmd.query_mode no-rerank

打开 qmd 后头一次查询总是慢(它要下载 ~2.2 GB 的模型,就这一次)。这不是调优问题——是一次性的开销。见 检索

现象: 碰到图片多的文档,内存往上爬。

旋钮: OCR 跑在一个子进程里,每 N 张图片就重启一次,好把内存框住。默认值(20)已经偏保守,你很少需要动它,但如果内存还在爬:

Terminal window
omem config set parser.ocr_subprocess_batch 10 # 重启得更勤 = 峰值更低

另外还有个每篇文档的图片上限(parser.max_images_per_doc,默认 200),它宁可把长尾跳过,也不让内存膨胀——任何被跳过的都会记进日志,绝不闷声不响。

  • worker 池curate_concurrency / kind_concurrency)——反正全局上限框住了真实成本;抬高池子很少有用,还可能让限流更糟。
  • fts5——它本来就快,没什么可调的。质量来自 qmd,不来自调 fts5。
  • 首次跑的开销——头一次 ingest 和头一次 qmd 查询,天生就慢(把所有东西看一遍、把模型下一次)。那不是稳态性能。