01 / 提交模块总览
处理单位为源 PDF ZIP 对应的 group_id。Controller 持久化任务状态并提供源文件与产物传输;Worker 领取对应 Stage 的租约,后台续租,产物上传后确认完成。上图横向箭头表示产物依赖,实际由 Controller 中转,不是 Worker 之间直接调用。
4b7dbfc,129 个文件,+35,058 / −264 行。图中 Core、SQLite、PPLayout、GROBID、云端 GPU 是调用关系;并不表示这些依赖的全部实现均为本次新增。Markdown 转换器源码属于另一个仓库,不在本次提交范围。02 / 阶段边界与产物
| 阶段 | 输入 | 输出 | 代码入口 |
|---|---|---|---|
| Stage1 | 原始 PDF ZIP | *.parse.jsonl.gz *.layout.jsonl.gz | lease_pipeline_worker.py stage1_zip_pipeline.py |
| Stage2 AutoDL | 原始 PDF ZIP + Layout.gz | *.tab-eq-latex.jsonl.gz | stage2_autodl_worker.py |
| Stage2 本地 | 原始 PDF ZIP + Layout.gz | 同类表格 / 公式 JSONL.GZ | stage2_zip_pipeline.py |
| Stage3 | Parse.gz + Layout.gz + tab-eq-latex.gz | *.markdown.zip | stage3_markdown_worker.py |
| 抽查 | Markdown ZIP + 原始 PDF ZIP + Parse 数据 | 抽查记录、相似度、Diff | stage3_markdown_audit.py |
Stage3 的实际输入是三份 gzip JSON Lines,非三个 ZIP。各阶段另有 metrics 与 SUCCESS 标记;输出保留源 ZIP 的相对目录结构。后台 API 为 /api/v1/leases/*;产物接口为 /api/v1/artifacts/{lease_id}/{kind}。
03 / Stage1:独立队列与 Core 调用
Extract、Parse、Render、Layout、Finalize 各有有界队列和可独立配置的 Worker 数。Layout 按页派发,最后一页完成后进入 Finalize。Parse 出错会记录状态,仍进入 Render;单篇失败不直接中断整组,Worker 另有整组完成校验。
persist_pages=false 表示不上传页面 PNG 到存储后端,并非纯内存渲染。当前 Core 渲染会写本地缓存文件,Layout 后删除;是否位于 RAMDISK 取决于部署路径。JSON spool、解压 PDF 和聚合文件也使用本地路径。04 / Stage2 AutoDL:抽页、识别与原页码恢复
任务固定使用提交时的远端实例。状态文件保留任务号、实例地址、删除凭证与分片状态,权限为 0600。每个已验证分片先在本地保存,再主动删除云端缓存;删除失败保留状态供重试,整组成功后再清理本地分片。
抽页后远端页号指向“精简 PDF”。合并时通过 original_member_indexes 和 original_page_numbers 恢复到原 ZIP / 原 PDF,不能直接使用远端页号。尺寸不匹配的受支持异常会触发 Layout 坐标适配并重提;合并阶段恢复 bbox。
并发由服务脚本启动多个 slot,每个 slot 为独立 Worker。默认值为 2,可配置为 4 等值;不把某次部署配置写成代码固定上限。冷启动时等待前一个 slot 获得远端 job_id 后,才启动下一个 slot 的上传。单租约的分片循环与多 slot 并发是两个层次。
05 / Stage2 本地路径:排序、裁剪与分类识别
此路径使用本地 PyMuPDF 渲染裁剪;排序、调度和公式 / 表格队列在 stage2_zip_pipeline.py。推理后端由配置决定,可配合 MinerU batch router、Transformers 服务或 vLLM 启动脚本。该代码仍在提交中,不能据此推断线上本地 GPU Worker 已启用。不同调度模式的精确排序与等待策略以运行参数为准。
06 / Stage3:合并 Markdown 并上传
本仓库的 Stage3 Worker 管理输入下载、解压、子进程、打包、上传与租约,不在 Python 中重写 Markdown 生成算法。转换器路径由 --converter 指定并检查存在。其内部 Layout 上下文合并、SanitizeText、MergeParagraph、ReviseParaAttr 等算法不属于提交 4b7dbfc,因此此图仅画已核实的调用边界。
07 / 抽查:线上单 PDF 与批处理结果对比
字节一致、归一化一致、正文一致和相似度是不同指标。正文使用 token 多重集,降低段落顺序变化的影响;表格单独提取与归一化。状态 matched 由归一化结果决定,不能用正文相似度阈值代替。代码仍保留表格格式字段;是否在控制台展示是另一个层次。
抽查 Worker 直接读取租约给出的本地可见路径,需要原始 ZIP、Markdown ZIP 和 Parse 文件均可访问。样本按 group_id 作为随机种子选择,可复现。扫描件通过 Parse 文本情况标记 is_scanned,参与抽查并单独统计;线上调用失败记录为 online_failed。不一致样本保存两侧 Markdown 与 unified diff,页面支持查看原始 PDF。
08 / 运维、故障边界与阅读入口
| 模块 | 职责 | 代表文件 |
|---|---|---|
| 生命周期 | tini 子进程回收、裸服务守护、服务启停 | bare_service_guard.sh / *_service.sh / wisdoc_sshd_entrypoint.sh |
| 资源与调度 | NUMA Core/JVM、并发准入、Core 保护与监控 | numa_stage1_services.sh / stage1_core_guard.py / core/src/admission.rs |
| 磁盘与清理 | 空间与 inode 检查、旧临时数据和日志清理、失败补跑 | stage1_disk_guard.py / wisdoc_housekeeping.sh / requeue_stage1_disk_failures.py |
| Layout 路由 | Layout 服务池、转发及 nginx 示例 | wisdoc_layout_pool_service.sh / wisdoc_layout_tunnel_service.sh |
| 验证材料 | 队列、抽页映射、恢复、比较与服务脚本测试;历史性能记录 | scripts/test_*.py / docs/benchmarks/ |
单 PDF 可跳过的处理异常与整组损坏必须区分:AutoDL 的逐篇抽页错误会记录并跳过;ZIP/Layout 身份不匹配等输入完整性问题仍使租约失败。续租丢失后 Worker 不应上报成功;Stage1 / Stage3 会终止正在执行的流水线子进程。
本页依据提交源码静态梳理,不代表实时集群部署状态,也不构成新的性能或准确率验收。本文为独立 HTML,所有图均为内嵌 SVG,无 CDN、外部字体或脚本依赖。