File size: 22,272 Bytes
67495fe | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 | # PDFSystem-MNBVC · PRD
> PB 级 PDF → 预训练数据处理系统
> 对标 HuggingFace FinePDFs · 面向 MNBVC 中文语料
> v0.1 · 2026-04-11
---
## 0. TL;DR
构建一套可在 10–100 GPU 小集群上长期稳定运行的 PDF → 预训练数据处理系统,将 PB 级原始 PDF 高质量、高吞吐、低成本地转换为结构化中文预训练数据。
关键取舍:
- **双路径 + 前置分流**:用 CPU 上 ≤10 ms 的 XGBoost 路由器把 ~90% 的页面送入 CPU 文本路径(PyMuPDF),只让 ~10% 的页面看到 GPU(借鉴 FinePDFs)。
- **小模型够用**:GPU 路径主选 **MinerU 2.5-Pro 1.2B**(中文字符 F1 0.965,A100 2.12 fps),备选 **PaddleOCR-VL 0.9B**(吞吐快 15.8%)。不调用任何商业 API。
- **编排复用**:直接使用 `datatrove`(FinePDFs 同款),省去自研编排器 80% 的工作量。
- **资源反推**:1 PB 原始 PDF ≈ 5 亿文档 ≈ 100 亿页,在 100 × A100 + 32 节点 CPU 集群下全量处理墙钟约 2 个月。
---
## 1. 背景与目标
MNBVC 是一个长期收集中文语料的开源项目,累积的原始 PDF 已逼近 PB 量级且仍在增长。这些 PDF 覆盖学术论文、政府公文、行业报告、电子书、扫描古籍、报纸期刊等极其异质的来源,是中文大模型预训练数据中一座尚未被充分开采的金矿。
本项目目标是把这些 PDF 转成可直接用于大模型预训练的结构化文本,并保持完整的可复现性与可追溯性。设计上重度借鉴 HuggingFace 2025 年开源的 FinePDFs(475M 文档、1733 语种、3T tokens)的工程经验,同时针对中文语料、有限算力与本地部署做关键取舍。
### 1.1 关键非功能目标
| 维度 | 目标 |
| --- | --- |
| 吞吐 | 10–100 GPU 集群下,单月可消化 50–500 TB 原始 PDF |
| 成本 | GPU 成本占比 ≤ 35%,其余由 CPU 路径承担 |
| 质量 | 中文 OCR 字符 F1 ≥ 0.95;阅读顺序还原正确率 ≥ 0.90 |
| 可复现 | 任意 shard 可独立重跑且产物字节级一致 |
| 断点续跑 | 允许任意节点失败,整体进度不丢 |
| 合规 | PII 自动脱敏、来源可追溯、license 元数据完整保留 |
### 1.2 非目标
- 不做多模态数据抽取(图像、图表作为语义单元进入训练数据),这是未来版本的事。
- 不做实时处理,整体是 batch pipeline。
- 不做训练侧的数据混合策略,那是下游训练框架的职责。
---
## 2. 关键设计洞察
在画架构图之前,先把 FinePDFs 等先行项目踩过的坑提炼为六条贯穿全局的设计原则。后续每一个模块的取舍都要回到这六条做合理性检验。
### 2.1 分流先行:90% 的页面不该看到 GPU
FinePDFs 团队最重要的工程发现是:一份普通的 PDF 语料里,绝大多数页面其实是 born-digital 的,只有约 5–10% 是扫描件或文本流损坏的页面。如果用统一的 GPU OCR 流水线处理全部页面,整个项目的 GPU 成本会比理论下限高 10–20 倍。本系统沿用 FinePDFs 的 XGBoost OCR 路由器思路,这是整个成本模型的命门。
### 2.2 小模型已经够用:拒绝商业 API 与百亿 VLM
2025 H2–2026 Q1 的开源社区里,MinerU 2.5-Pro 1.2B(OpenDataLab)和 PaddleOCR-VL 0.9B(百度)这两个亚 1.5B 参数的解耦式 VLM 已经在 OmniDocBench 上全面超越 Gemini 2.5 Pro 等闭源大模型,尤其是 MinerU 2.5 在中文文档上拿下 0.965 的字符 F1。一张 A100 80G 可以并行驻留 16 个以上的 1.2B 模型副本。
### 2.3 CPU 与 GPU 必须分车道
PyMuPDF 在单核上的吞吐是 10–30 PDF/秒,MinerU 2.5 在单卡 A100 上是 2.12 页/秒。两者吞吐差三个数量级。如果共享同一个调度器和队列,慢的一端会立刻变成快的一端的瓶颈(典型 head-of-line blocking)。系统为 CPU 与 GPU 各开独立通道,中间用对象存储 staging 解耦,反压机制让快通道根据慢通道水位自动节流。
### 2.4 以页为最小调度单位,文档只是聚合视图
一份 PDF 内部的页面同质性远低于直觉。一篇论文常常前 10 页 born-digital、最后附录的扫描表格是图像。如果以"文档"为最小单位,会强迫整篇文档走最重的那条路径。本系统以"页"为最小处理单元、以"文档"为最终聚合单元。
### 2.5 廉价过滤前置:不要对垃圾页跑 OCR
语种识别、长度过滤、模板化页面(页眉页脚、版权页、空白页)这些动作都能在 CPU 路径里以毫秒级成本完成。把它们前置在 OCR 之前,可以再砍掉 20–40% 的 GPU 工作量。
### 2.6 idempotent + checkpoint:失败是常态
在 100 GPU × 数月的时间窗口里,节点失败、网络抖动、显存 OOM、模型 NaN、对象存储限流都是必然事件。每个 stage 都设计为幂等(同一输入 → 同一输出)+ shard 级 manifest checkpoint,任意时刻杀掉所有 worker 重启都能从断点继续。
---
## 3. 总体架构
6 个串行 stage + 3 层数据存储。串行只是逻辑视图——实际上每个 stage 内部有大量并行 worker,相邻 stage 之间通过对象存储解耦,可以异步推进。
### 3.1 数据流
```text
原始 PDF 对象存储
│
▼
[Stage 0] Ingestion & Sharding ── manifest.parquet (sha256, size, src)
│
▼
[Stage 1] Triage Classifier (CPU, XGBoost)
│
├── TEXT_OK ──▶ [Stage 2A] CPU 文本路径
│ PyMuPDF + 轻量 layout
│ │
│ ▼
│ Markdown + meta
│
├── NEEDS_OCR ─▶ [Stage 2B] GPU 视觉路径
│ PP-DocLayoutV3 + MinerU 2.5 / PaddleOCR-VL
│ │
│ ▼
│ Markdown + meta
│
└── REJECT ───▶ Quarantine bucket(人工/重训)
│
▼
[Stage 3] Postprocess: 阅读顺序、跨页合并、公式表格归一
│
▼
[Stage 4] Quality / Lang / PII / Dedup(精确 + MinHash)
│
▼
[Stage 5] 输出打包:Parquet shards + JSONL + Markdown 抽样
```
### 3.2 三层存储
- **L0 原始层(cold)**:S3/OSS/MinIO,PB 级,原始 PDF 不可变,按 sha256 前缀分目录。
- **L1 中间层(warm)**:对象存储 + Parquet/JSONL 分片,存放每个 stage 的中间产物。L1 设计为可丢弃——任意时刻清空都能用上游重建。
- **L2 输出层(hot)**:最终 Parquet 数据集,按语种 / 来源 / 质量分桶,供训练框架和 HuggingFace datasets 直接消费。
---
## 4. 模块详解
### 4.1 Stage 0:数据接入与切片
入库时流式扫描计算 sha256、大小、来源 URL、首个 PDF Producer 字段,写入 `manifest.parquet`。这个 manifest 是后续所有 stage 的唯一 source of truth。
- **Sharding**:按 sha256 前两位 hex 切成 256 个 shard(再细可到 1024),每 shard 200 万–500 万个 PDF,单 worker 处理粒度可控。
- **前置精确去重**:同 sha256 只保留一条。
- **PDF 健康检查**:用 PyMuPDF 尝试 open + pages,捕获损坏文件并打 tag,避免后续 worker 反复崩。
### 4.2 Stage 1:PDF 分流分类器
整个系统省钱最重要的模块,直接复刻 FinePDFs 的 OCR Predictor 思路。XGBoost 是有意为之的选择——纯 CPU 推理 ≤10 ms/PDF,模型几 MB,部署零负担。
**特征**(CPU 提取,全部来自 PyMuPDF):
- 内嵌文本字节数 / PDF 总字节数(关键比值,扫描件接近 0)
- 页面数、平均页面像素面积、是否含字体子集
- 图像对象总面积 / 页面总面积
- ToUnicode CMap 缺失率(中文古籍 / 老 PDF 的关键信号)
- 第一页、中间页、最后一页可提取文本长度三元组
- PDF Producer / Creator 字段(Word / LaTeX / 扫描软件 / Office)
- XObject 数量与 Form XObject 占比
**输出 3 类标签**:
- `TEXT_OK` → 走 Stage 2A
- `NEEDS_OCR` → 走 Stage 2B
- `REJECT` → 损坏 / 加密 / 0 页 / 全空白,进 quarantine
训练数据:5–10 万份人工标注 + 启发式弱标注。目标精确率 ≥ 95%、召回率 ≥ 90%。误判 TEXT_OK 但实际抽不出文字的样本会经 Stage 2A 的失败回退送回 Stage 2B。
### 4.3 Stage 2A:CPU 文本路径
目标是用最少的 CPU 时间把可提取文本流的 PDF 转成结构良好的 Markdown。FinePDFs 在这一路径上用的是 Docling + Layout Heron int8 量化版;本系统做两点中文本土化调整:
- **解析后端**:PyMuPDF 1.27+(基于 MuPDF 1.27.x)。中文 cmap 处理和文本流还原比 Docling 默认后端更稳,每核 10–30 PDF/秒。
- **轻量布局**:PP-DocLayoutV3 的 ONNX int8 量化版,CPU 推理 ~50 ms/页;triage 非常干净时可 fallback 到纯启发式(bbox 列数聚类 + 字号聚类)。
- **阅读顺序**:双栏检测 + 段落合并 + 跨页折行还原。
- **失败回退**:若提取出的字符数小于阈值(如 < 0.3 × 期望字符数),自动改写 manifest 把该 PDF 丢回 Stage 2B。这是 triage 误差的安全网。
### 4.4 Stage 2B:GPU 视觉路径
处理真正难啃的部分:扫描件、图像 PDF、文本流损坏、版式极端的页面。
**主选:MinerU 2.5-Pro 1.2B**
- 中文字符 F1 0.965(OmniDocBench 中文 SOTA)
- 解耦式 VLM:先布局再 patch-level OCR,对长页友好
- 吞吐:A100 80G vLLM async 2.12 页/s;H200 4.47 页/s
- 端到端覆盖文本 / 表格 / 公式 / 图像区,输出结构化 JSON → Markdown
- 显存占用 fp16 ≈ 3 GB,A100 80G 可并行 16+ 副本
**备选 / 混部:PaddleOCR-VL 0.9B**
- 吞吐比 MinerU 2.5 高 15.8%,显存比 dots.ocr 省 40%
- OmniDocBench v1.5 总分 92.56(高于 MinerU 2.5 的 90.67)
- 中文略弱于 MinerU 2.5,但在多语种与吞吐敏感场景上更好
**调度策略**:路由器在 Stage 1 输出之外再附一个二级 hint——主语种为中文且含较多公式表格 → MinerU 2.5;其它 → PaddleOCR-VL。两套模型共享同一 worker pool,只是加载不同权重。
**推理引擎与批处理**:
- 生产环境用 **LMDeploy**(FinePDFs 同款,比 vLLM 省显存、首 token 延迟更低)
- 动态 batching:max batch 16、max seq 8192、超长页强制切块
- 常驻模型:worker 一次加载、长生命周期
- 失败兜底:单页 OOM 自动降 batch 重试 ≤ 2 次后写 quarantine
### 4.5 Stage 3:后处理
无论来自 CPU 还是 GPU 路径,都进入统一的后处理流水线:
- 阅读顺序最终重排(跨页表格合并、脚注挂回正文、双栏交错修正)
- 段落合并(基于行尾标点与中文断句规则修复折行)
- 公式归一(LaTeX 用 KaTeX / MathJax 解析校验,失败的退化为图像占位)
- 表格归一(HTML / Markdown 双格式存储,行列校验失败的转 image-placeholder)
- Unicode 归一(NFC + 全半角统一 + 控制字符剔除 + 零宽字符清理)
- 元数据补全(每段记录来源页码、bbox、置信度)
### 4.6 Stage 4:质量过滤、语种、PII、去重
#### 4.6.1 语种识别
GlotLID(FinePDFs 同款),**段落级**而非文档级——一篇中英混排的论文里,参考文献段打 en,正文打 zh,下游可以分别处理。
#### 4.6.2 启发式质量过滤
- 重复 n-gram 比例(去除 OCR 串行错位产物)
- 非 CJK / 非 ASCII 符号比例(去除符号噪声)
- 行长方差与平均行长(去除 OCR 抖动)
- URL / email 占比、纯数字占比(去除目录页 / 广告页)
- 最短文档长度阈值(按语种自适应:zh ≥ 200 chars,en ≥ 500 chars)
#### 4.6.3 模型质量分类器
训练中文版 EduScore:fastText 起步 → DeBERTa-v3-tiny 升级。训练数据用高质量中文教育/百科语料 vs 论坛灌水/SEO 文本做对比。每段打 0–5 分,下游训练时按分桶 mix。
#### 4.6.4 PII 脱敏
- 正则:身份证 18 位、手机号、银行卡(Luhn 校验)、邮箱、IPv4/IPv6
- 中国特化:车牌号、统一社会信用代码、护照号
- 命名实体兜底:MiniLM / BERT-tiny NER,仅在正则未命中时启用
- 策略:替换为 `⟨PII:phone⟩` 等占位符,原值哈希存入审计表(不入训练数据)
#### 4.6.5 去重
- 第一遍精确去重:sha256(Stage 0 完成)
- 第二遍内容精确去重:normalize 后文本的 md5
- 第三遍模糊去重:MinHash LSH(5-gram、num_hashes=128、threshold 0.85),`datatrove` 的 minhash block 可直接复用
- **跨 shard 是全局 shuffle 唯一点**:需要一个独立 pass,是整个 pipeline 里最昂贵的单个 stage
### 4.7 Stage 5:输出打包
最终对外的数据集采用 **Parquet 主格式 + JSONL 副格式 + Markdown 抽样存档**三件套。
- Parquet 分片:~1 GB / shard,按 `lang / source / quality_bucket` 分桶
- schema:`id, lang, source, text_md, text_plain, meta(json), quality_score, dedup_cluster_id, pii_redacted(bool)`
- 命名约定:`pdfsystem_mnbvc/v1/lang=zh/source=arxiv/qb=high/shard-00001.parquet`
- JSONL:与 Parquet 1:1 镜像,便于 grep / 抽样审计
- Markdown 抽样存档:每 shard 随机抽 0.1% 文档落盘原始 Markdown,长期保留作为人工审核基线
---
## 5. 编排与资源调度
编排框架直接选用 **datatrove**(FinePDFs 同款),它原生提供 Slurm 后端、shard 级 manifest checkpoint、minhash block 等关键能力。集群层面支持 Slurm 与 Kubernetes 双后端。
### 5.1 队列拓扑
- **Lane A(CPU)**:节点级数据并行,每节点 64–128 worker;节点本地 NVMe 做热数据缓存;产出写入 L1。
- **Lane B(GPU)**:每张 GPU 一个 worker 进程,模型常驻;输入来自 Stage 1 直接喂入或 Lane A 的失败回退。
- **Lane C(global ops)**:MinHash dedup、跨 shard 合并这类 shuffle 操作单独排队,避开 A/B 的高吞吐节奏。
### 5.2 反压与水位
Lane A 吞吐远高于 Lane B。如果不加控制,Lane B 的 staging 队列会无限增长。系统在 staging 桶上设置 **high / low watermark**:超过 high watermark 时 Lane A worker 主动 sleep,掉到 low watermark 再恢复。简单可靠,避免引入复杂的消息中间件。
### 5.3 Checkpoint 与断点续跑
- 每个 shard 完成后写一条 manifest record:`{shard_id, stage, status, output_path, n_docs, n_tokens, sha256}`
- worker 启动时先扫 manifest,跳过已完成的 shard
- 中间层产物本身就是 checkpoint,允许某个 stage 部分失败后只重跑该 stage
---
## 6. 资源预算(PB 级反推)
以 1 PB 原始 PDF 为单位,参数取自 FinePDFs 公开数据与 MinerU 2.5 / PaddleOCR-VL 公开 benchmark。数量级估算,用于反推集群规模而非签 SLA。
### 6.1 数据量估算
| 指标 | 假设值 | 推导 |
| --- | --- | --- |
| 原始数据 | 1 PB | 目标输入 |
| 平均 PDF 大小 | 2 MB | MNBVC 抽样观测 |
| PDF 总数 | ≈ 5 × 10⁸ | 1 PB ÷ 2 MB |
| 平均页数 / PDF | 20 | 学术 + 报告混合 |
| 页面总数 | ≈ 1.0 × 10¹⁰ | 5e8 × 20 |
| 分流比例 | 90% CPU / 10% GPU | FinePDFs 经验,中文略偏 GPU |
| CPU 路径页数 | 9 × 10⁹ | |
| GPU 路径页数 | 1 × 10⁹ | |
### 6.2 CPU 路径预算
| 项 | 数值 | 说明 |
| --- | --- | --- |
| PyMuPDF 吞吐 | ~30 页/s/core | 现代数字 PDF,单核 |
| 所需 core·秒 | 3.0 × 10⁸ | 9e9 ÷ 30 |
| 所需 core·小时 | ≈ 8.3 × 10⁴ | |
| 32 节点 × 64 core | 2048 core 并行 | |
| CPU 路径墙钟 | ≈ 40 小时纯计算 | 不含 IO |
| 现实墙钟 | 1–2 周 | 含对象存储与 manifest 开销 |
### 6.3 GPU 路径预算
| 项 | 数值 | 说明 |
| --- | --- | --- |
| MinerU 2.5 吞吐 | ~2 页/s/A100 | 公开 2.12 fps |
| 所需 GPU·秒 | 5 × 10⁸ | 1e9 ÷ 2 |
| 所需 GPU·小时 | ≈ 1.39 × 10⁵ | |
| 50 × A100 满载 | ~115 天 | 理想吞吐 |
| 100 × A100 满载 | ~58 天 | 推荐配置 |
| 100 × H200 满载 | ~26 天 | 高端配置 |
**结论**:100 A100 + 32 节点 CPU 规模下,1 PB 原始 PDF 全量处理墙钟约 2 个月;100 H200 可压到 1 个月以内。与 FinePDFs 团队公开的处理周期数量级一致。
### 6.4 存储预算
- L0 原始:1 PB(不可压缩)
- L1 中间:~30 TB(每 PDF ~60 KB Markdown + meta)
- L2 输出 Parquet:~15 TB(zstd 压缩)
- Manifest + 索引:~50 GB
---
## 7. 存储与数据布局
```text
s3://pdfsystem-mnbvc/
├── L0_raw/ # 原始 PDF,不可变
│ └── ab/cd/abcd1234....pdf # 按 sha256 前 4 位分目录
├── L1_intermediate/
│ ├── stage1_triage/ # XGBoost 路由结果
│ │ └── shard-00001.parquet
│ ├── stage2a_text/ # CPU 路径产物
│ ├── stage2b_vision/ # GPU 路径产物
│ ├── stage3_postproc/
│ └── stage4_quality/
├── L2_output/
│ └── v1/lang=zh/source=arxiv/qb=high/shard-00001.parquet
├── manifest/
│ ├── ingest.parquet # Stage 0 写入
│ └── stage_status.parquet # 全 stage 状态
└── audit/
├── pii_hash_table.parquet # 不可逆审计
└── md_samples/ # 0.1% 抽样 Markdown
```
---
## 8. 可观测、容错、质量保证
### 8.1 指标
- 吞吐:每 stage 的 docs/s、pages/s、bytes/s(shard × worker 维度)
- 路由分布:`TEXT_OK / NEEDS_OCR / REJECT` 三类比例随时间变化
- 回退率:Stage 2A → 2B 回退占比(拐点立即告警)
- GPU 利用率:SM busy %、显存占用、batch 平均长度
- 失败率:按 stage 与失败原因分类计数
- 成本:估算的 GPU·小时 / TB 原始数据
### 8.2 质量回归
维护一份 **500 份手工对齐的中文 PDF 基准集**(学术 / 报告 / 扫描古籍 / 报纸 / 双栏论文各 100 份),每天对当天 pipeline 输出做一次自动 diff,超阈值触发人工复核。这是防止"悄悄变烂"的最重要防线。
### 8.3 故障策略
| 粒度 | 策略 |
| --- | --- |
| worker | 单页失败 retry 3 次,仍失败写 quarantine |
| 节点 | 心跳超时由调度器自动重排 |
| shard | manifest 标记 failed,人工审视后决定重跑或丢弃 |
| 全局 | 每周回看 quarantine 桶,按错误聚类决定是否升级 triage 分类器 |
---
## 9. 参考方案对比
| 方案 | 类型 | 中文 | 吞吐 | License | 本系统位置 |
| --- | --- | --- | --- | --- | --- |
| PyMuPDF / MuPDF | CPU 文本 | 好 | 10–30 PDF/s/core | AGPL | Stage 2A 主力 |
| Docling Heron int8 | CPU 布局 | 中 | 依赖 OpenVINO | MIT | 可选 |
| PP-DocLayoutV3 | 布局检测 | 好 | CPU/GPU 均可 | Apache 2.0 | Stage 2B 布局头 |
| **MinerU 2.5-Pro 1.2B** | VLM 端到端 | **极佳** | 2.12 fps@A100 | Apache 2.0 | **Stage 2B 主选** |
| PaddleOCR-VL 0.9B | VLM 端到端 | 好 | 比 MinerU 快 15.8% | Apache 2.0 | Stage 2B 备选 |
| RolmOCR | OCR | 中 | 需 vLLM / LMDeploy | Apache 2.0 | FinePDFs 原选,不用 |
| olmOCR | OCR | 中 | — | Apache 2.0 | baseline |
| Gemini 2.5 Pro | 闭源 API | 好 | API 限速 | 商业 | 不采用(成本 / 合规) |
---
## 10. 实施路线图
### P0 · 单机 PoC(2 周)
- 1 万份多样化 PDF 走通端到端 6 个 stage
- MinerU 2.5 + PyMuPDF 双路径独立验证
- 产出第一批 Parquet shard,人工对比抽样
- **交付物**:可运行的 docker compose + Jupyter 验证 notebook
### P1 · 分类器与 datatrove 集成(4 周)
- 标注 5–10 万份 PDF 训练 XGBoost triage 分类器
- 接入 `datatrove`,跑通单 shard 的 6-stage Slurm 作业
- 实现 manifest checkpoint 与回退闭环
- **交付物**:100 万 PDF 试运行报告 + 成本估算
### P2 · 10 GPU 集群试点(6 周)
- 1 TB 原始 PDF 全链路压测
- 调通反压、重跑、quarantine 流程
- 中文质量回归基准集上线
- **交付物**:可对外发布的 v0.1 数据集 + 评测报告
### P3 · PB 全量与持续迭代(持续)
- 100 GPU 满载推进到 PB 量级
- 按月发布 v0.2、v0.3,每版带 CHANGELOG 与质量 diff
- 长尾专项:竖排古籍、繁体、表格密集型行业报告
- 社区贡献:开源 triage 分类器与中文 EduScore
---
## 11. 风险与开放问题
- **中文古籍与竖排**:MinerU 2.5 在横排中文表现极好,但竖排古籍未经专门评测。P3 阶段计划微调一个古籍专用 LoRA。
- **公式与表格忠实度**:LaTeX 还原失败的样本比例需要持续监控;P2 质量回归基准集要专门覆盖公式表格密集的论文。
- **数据来源合规**:PB 级语料的来源 license 必须随数据流转保留,输出 Parquet 独立列存储。
- **MinerU 2.5 商用授权**:Apache 2.0,但需关注 OpenDataLab 后续版本条款,保留 PaddleOCR-VL 作为热备。
- **PII 召回率**:中文 PII 模式比英文复杂(地址、姓名),正则不够,可能需要小模型 NER 兜底。
- **对象存储成本**:PB 级数据 + 中间层 + 输出层每月存储与流量费用需在 P0 阶段完成 TCO 估算。
---
## 附录 A · 参考资料
- [FinePDFs 数据集](https://huggingface.co/datasets/HuggingFaceFW/finepdfs)
- [FinePDFs 博客](https://huggingface.co/spaces/HuggingFaceFW/FinePDFsBlog)
- [FinePDFs 代码库](https://github.com/huggingface/finepdfs)
- [MinerU 2.5 Pro 1.2B](https://modelscope.cn/models/OpenDataLab/MinerU2.5-Pro-2604-1.2B)
- [MinerU 2.5 论文 (arXiv:2509.22186)](https://arxiv.org/abs/2509.22186)
- [PaddleOCR-VL 论文 (arXiv:2510.14528)](https://arxiv.org/abs/2510.14528)
- [PP-DocLayoutV3](https://huggingface.co/PaddlePaddle/PP-DocLayoutV3)
- [MuPDF 1.27 文档](https://mupdf.readthedocs.io/en/1.27.2/)
- [datatrove](https://github.com/huggingface/datatrove)
- [MinerU 项目主页](https://github.com/opendatalab/MinerU)
- [OmniDocBench](https://github.com/opendatalab/OmniDocBench)
|