知识库后台分析性能优化方案

从并发模型、LLM 调用、OCR、断点续跑和关系推断等方面,系统优化知识库后台分析性能。

随着知识库资料规模增长,后台分析耗时会逐渐成为影响用户体验的关键因素。尤其是长文档、扫描版 PDF,以及多人同时提交任务时,串行执行模式会放大模型调用、OCR 和失败重试带来的延迟。

本文结合 AiCat 当前知识图谱分析流程,从任务调度、文本分块、大模型调用、OCR、关系推断和结果持久化等方面,给出一套分阶段、可验证的性能优化方案。

一、当前分析流程

知识库后台分析大致分为以下几个阶段:

  1. 用户上传 PDF、Word、Markdown、文本文件或 Git 仓库。
  2. 后台 Worker 从数据库领取一个排队中的项目。
  3. 提取文件正文;扫描 PDF 的弱文本页进入 OCR。
  4. 将正文切分成约 4500 字的文本块。
  5. 逐块调用大模型,抽取知识节点和局部关系。
  6. 合并并去重节点,补充跨分块关系。
  7. 清理无效关系和前置关系环路,生成图谱布局。
  8. 将节点、关系和质量报告写入数据库。
  9. 更新项目状态,并发送飞书完成通知。

现有流程能够保证证据约束和结果完整性,但在任务调度与模型调用层面仍以串行为主,因此存在较大的优化空间。

二、主要性能瓶颈

1. 项目之间串行执行

当前后台只有一个知识库 Worker。同一时间只能分析一个项目,后续任务必须等待前一个项目完全结束。

当多人同时提交资料时,即使单个任务耗时没有变化,用户感知到的排队时间也会快速增长。

2. 单个项目的分块串行调用模型

正文被切分为多个文本块后,系统会等待当前分块分析结束,再处理下一个分块。因此,一份文档的模型阶段耗时近似为:

总耗时 ≈ 分块 1 耗时 + 分块 2 耗时 + ... + 分块 N 耗时

例如,一份文档被切成 20 块,单块平均需要 15 秒,仅分块抽取阶段理论上就需要约 300 秒。

3. 单次模型输出较重

当前每个分块要求模型生成较多知识节点、描述、证据和关系,同时允许较大的输出 token 上限。输出内容越长,模型生成时间和发生格式错误的概率越高。

4. 失败重试会成倍放大耗时

模型请求失败后最多重试三次;如果仍然失败,还会把原分块拆成更小的子块并重新分析。

该机制有助于提高正文覆盖率,但网络超时、限流或 JSON 格式错误都可能让一个分块的耗时增加数倍。

5. 全量关系推断上下文过大

分块抽取完成后,系统会将全部节点交给模型进行关系补充。大文档产生的节点越多,这一步的输入上下文和输出内容就越大,可能成为后期的新瓶颈。

6. 扫描 PDF 的 OCR 逐页执行

系统已经采用“原生文本优先、弱文本页才 OCR”的策略,但需要 OCR 的页面仍然逐页处理。扫描版 PDF 页数较多时,模型分析开始前就可能消耗较长时间。

7. HTTP 连接没有充分复用

如果每次模型调用都重新建立 HTTP 连接,会额外产生 TCP、TLS 和连接初始化成本。分块较多时,这些小开销会持续累积。

三、优化目标

本次优化建议围绕以下目标展开:

  • 普通文本 PDF 的总分析耗时降低 50%~70%。
  • 支持至少两个知识库项目同时分析。
  • 服务重启后能够从已完成的分块继续执行。
  • 减少无效重试和重复模型调用。
  • 保持现有节点质量、证据覆盖率和关系完整度。
  • 让用户能够看到真实进度、队列位置和预计剩余时间。

四、第一阶段:低风险快速优化

第一阶段优先处理改动小、收益明显的部分,预计开发时间为 1~2 天。

1. 增加分阶段性能指标

首先应记录各阶段的真实耗时,包括:

  • 文件解析耗时;
  • OCR 总耗时及单页耗时;
  • 文本分块数量;
  • 每个分块的模型调用耗时;
  • 模型输入、输出 token 数量;
  • 重试次数及错误类型;
  • 关系推断耗时;
  • 数据库保存耗时;
  • 项目排队时间与总处理时间。

只有建立稳定的性能基线,才能判断优化是否真正有效,避免只凭主观感受调整参数。

2. 对文本分块进行有界并发

各文本块之间基本相互独立,可以并发调用模型。建议增加配置:

KNOWLEDGE_CHUNK_CONCURRENCY=4

推荐初始值:

模型类型建议并发数说明
DeepSeek / Agnes 等云端 API3~4可根据服务限流逐步提高到 6~8
Ollama 单 GPU1~2并发过高可能争抢显存并降低吞吐量
Ollama 多 GPU 或高性能推理服务2~4需要通过压测确定最优值

并发完成后,系统仍应按照原始分块序号合并结果,以保证结果可复现,并继续执行现有的证据校验、节点去重和覆盖率门禁。

3. 复用 HTTP 连接

使用共享的 httpx.Client 或 httpx.AsyncClient 调用云端模型,让请求复用连接池,减少重复建立连接的开销。

连接池还应配置:

  • 最大连接数;
  • 最大空闲连接数;
  • 连接超时;
  • 读取超时;
  • 客户端关闭与服务退出处理。

4. 缩减不必要的模型输出

分块抽取阶段可以将输出上限从 8192 tokens 调整到约 3000~4096 tokens,再根据真实截断率校准。

同时可以精简提示词中的重复描述,并控制单块最多节点数。目标不是简单减少知识点,而是避免模型输出冗长、重复的说明和低价值关系。

5. 优化重试策略

重试应根据错误类型决定,而不是所有异常都完整重试:

  • 超时、HTTP 429 和服务端 5xx:指数退避后重试;
  • 网络瞬断:有限重试;
  • JSON 格式错误:优先进行一次轻量修复或格式纠正;
  • 参数错误、鉴权失败和额度不足:立即失败并明确提示;
  • 内容超过上下文限制:直接缩小分块后重试。

建议采用带随机抖动的指数退避:

1 秒 → 2 秒 → 4 秒

这样可以减少限流期间多个请求同时重试造成的“惊群”问题。

五、第二阶段:提升多用户吞吐量

第二阶段预计开发时间为 2~4 天,重点解决多个项目排队的问题。

1. 将单 Worker 改为 Worker 池

建议增加以下配置:

KNOWLEDGE_WORKER_CONCURRENCY=2
KNOWLEDGE_CHUNK_CONCURRENCY=4

当前数据库使用 FOR UPDATE SKIP LOCKED 领取任务,已经具备支持多 Worker 安全抢占任务的基础。多个 Worker 可以各自领取不同项目,而不会重复处理同一条任务。

2. 建立全局并发限制

项目并发和分块并发不能简单相乘后无限增长。例如两个项目分别开启四个分块并发,系统可能同时发出八个模型请求。

因此应设置全局信号量或令牌桶:

KNOWLEDGE_LLM_MAX_CONCURRENCY=6

所有项目共享该上限,防止超过云端 API 限流,也避免本地 GPU 显存被同时占满。

3. 按资源类型拆分队列

建议把任务拆成两类资源队列:

  • CPU/OCR 队列:负责文件解析、页面渲染和 OCR,并发较低;
  • LLM 队列:负责知识抽取和关系生成,根据 API 或 GPU 容量设置并发。

这样可以避免扫描 PDF 长时间占用唯一 Worker,也能让已经完成解析的文本项目更快进入模型阶段。

六、第三阶段:分块持久化与断点续跑

第三阶段预计开发时间为 3~5 天,是长期收益最大的一项改造。

1. 新增分块任务表

可以新增 knowledge_project_chunks 表,保存以下信息:

  • 项目 ID;
  • 分块序号;
  • 起止位置;
  • 文本内容或文本哈希;
  • 状态;
  • 尝试次数;
  • 使用的模型;
  • 提示词版本;
  • 节点和关系提取结果;
  • 开始时间、结束时间;
  • 错误类型和错误信息。

2. 实现断点续跑

Worker 只领取未完成或允许重试的分块。服务重启后,已经成功的分块不再调用模型,只继续执行剩余任务。

3. 增加内容缓存

缓存键可以由以下内容共同组成:

文本哈希 + 模型名称 + 提示词版本 + 抽取参数版本

这样可以支持:

  • 相同资料重复提交时复用结果;
  • 文档只修改部分内容时,仅重新分析变化的分块;
  • 修改提示词或模型后,自动使旧缓存失效;
  • 对失败分块进行单独重试。

4. 保证任务幂等性

分块任务应使用明确的状态流转:

pending → processing → succeeded
                    ↘ retry
                    ↘ failed

领取任务时记录租约时间。如果 Worker 异常退出,超过租约的 processing 任务可以安全地回到 retry 状态。

七、第四阶段:分层关系推断

当节点数量增加时,不应把全部节点一次性交给模型。建议将关系推断改成分层流程:

  1. 每个文本块提取局部节点和关系;
  2. 按章节合并并去重节点;
  3. 分章节补充内部关系;
  4. 为每个章节生成简短摘要和关键节点列表;
  5. 只使用章节摘要与关键节点推断跨章节关系;
  6. 最后在本地完成去重、置信度过滤、环路清理和布局。

这种 Map-Reduce 式处理可以显著降低单次请求的上下文长度,并避免节点较多时关系推断超时。

还可以根据以下规则减少不必要的候选节点组合:

  • 优先处理相同章节和相邻章节;
  • 使用关键词、向量相似度或实体类型筛选候选节点;
  • 已经存在高置信度直接关系的节点不重复推断;
  • 跨章节只保留教学意义较强的前置、包含和对比关系。

八、OCR 优化方案

OCR 应作为独立阶段统计和优化,避免将 OCR 慢误判为大模型慢。

1. 保留混合提取策略

继续使用“原生文本优先,仅弱文本页 OCR”的方案。可靠文本页不应进入 OCR,也不应初始化不必要的 OCR 推理过程。

2. 增加页面缓存

OCR 缓存可以采用以下键:

文件哈希 + 页码 + OCR 模型版本 + DPI

重复分析同一份 PDF 时,可以直接复用页面识别结果。

3. 谨慎增加并发

PDF 页面渲染可以使用 2~4 个工作线程,但 OCR 推理需要结合引擎线程安全和硬件资源进行控制。

如果 OCR 实例不能安全地跨线程共享,应使用独立进程或每个 Worker 独立实例,不能直接在多个线程中共用同一个实例。

4. 提供快速模式

对速度优先的场景,可以将 OCR DPI 从 160 调整为 130~150,并用固定样本验证识别准确率是否仍然满足要求。

九、前端体验优化

即使后台性能得到提升,用户仍需要明确知道任务进行到哪一步。建议展示:

  • 当前队列位置;
  • 已完成分块数和总分块数;
  • 当前阶段:解析、OCR、知识抽取、关系整理或保存;
  • 已耗时和预计剩余时间;
  • 是否发生重试;
  • 任务失败时的可操作建议。

预计剩余时间可以基于同类型任务的历史 P50 或当前任务已完成分块的平均耗时动态计算。

十、推荐实施顺序

优先级改造项预期效果风险预计工作量
P0增加各阶段耗时与 token 指标找到真实瓶颈,建立基线很低0.5~1 天
P0复用 HTTP 连接降低云端调用开销很低0.5 天
P0分块有界并发单项目提速约 2~4 倍中1 天
P0优化输出上限和重试策略降低单块耗时与异常放大低1 天
P1Worker 池并行项目提升多人使用时的吞吐量中1~2 天
P1全局并发和限流控制保证服务稳定性中1 天
P1分块持久化与断点续跑避免重复分析中3~5 天
P2分层关系推断优化超大文档中2~3 天
P2OCR 缓存和安全并发加速扫描 PDF中2~3 天

十一、验收与压测方案

建议准备三类固定样本:

  1. 20 页、带可靠文本层的 PDF;
  2. 100 页、带可靠文本层的 PDF;
  3. 50 页扫描版 PDF。

改造前后分别执行多轮测试,并记录:

  • 排队时间;
  • 文件解析时间;
  • OCR 时间;
  • 分块数量;
  • 分块调用平均耗时与 P95 耗时;
  • 输入和输出 token 数量;
  • 重试次数;
  • 关系推断时间;
  • 数据库保存时间;
  • 项目总耗时;
  • 节点数与关系数;
  • 来源覆盖率;
  • API 失败率和限流率;
  • CPU、内存、GPU 和显存峰值。

建议首期验收标准如下:

  • 普通文本 PDF 总耗时降低 50%~70%;
  • 至少两个项目可以同时分析;
  • 服务重启后不重复处理已成功分块;
  • 不出现超出供应商限流的大量失败;
  • 节点数量、关系数量和来源覆盖率不低于现有版本;
  • 在相同测试资料下,分析结果质量保持稳定。

十二、风险与控制措施

API 限流风险

分块并发可能触发云端模型限流。必须设置全局并发上限,并对 HTTP 429 使用带随机抖动的指数退避。

本地 GPU 资源竞争

Ollama 并发过高可能导致显存不足或单请求延迟上升。应通过压测确定最优并发,而不是直接套用云端 API 的配置。

结果合并不稳定

并发任务完成顺序不固定。合并时必须使用原始分块序号,并保证去重和关系清理逻辑具有确定性。

数据一致性风险

多 Worker 模式下,应继续使用数据库事务和 FOR UPDATE SKIP LOCKED 领取任务。分块结果写入需要唯一约束和幂等更新,避免重复数据。

优化导致质量下降

减少输出 token、扩大文本分块或减少重试都可能影响结果质量。因此每项性能调整都需要同时比较节点数、关系数、证据有效率和正文覆盖率。

十三、总结

AiCat 知识库分析慢的核心原因并不是单一模型性能问题,而是项目调度、分块调用、失败重试、OCR 和关系推断整体以串行方式组合在一起。

最适合优先落地的一组改造是:

  1. 增加分阶段耗时和 token 指标;
  2. 使用共享 HTTP Client;
  3. 实现文本分块的有界并发;
  4. 优化输出上限和错误分类重试;
  5. 增加全局并发保护。

这一阶段改动范围相对可控,通常可以获得第一轮最大的性能收益。随后再推进 Worker 池、分块持久化、断点续跑和分层关系推断,逐步把当前单机串行流程演进为可并发、可恢复、可观测的后台分析系统。

发表评论