Pulpie: 用于网页清洗的帕累托最优模型

Pulpie: 用于网页清洗的帕累托最优模型

Pulpie 是一个帕累托最优模型家族,旨在通过移除导航、广告和页脚等模板内容(boilerplate)来从 HTML 页面中提取主体内容。通过使用编码器(encoder)架构而非解码器(decoder),Pulpie 在实现最先进(SOTA)提取质量的同时,将成本降低至 Dripper 等领先提取器的 1/20。

面向 LLM 训练与推理的高影响力数据清洗

对于大语言模型(LLMs)的预训练和推理阶段,干净的数据都至关重要。研究表明,基于模型的提取在保留代码块和公式等结构化内容方面显著优于基于启发式(heuristic)的方法,而启发式方法往往会破坏这些数据。

根据 AICC (Ma et al., 2025),仅改进提取器本身就能带来模型准确率的可衡量提升。在一个基于模型提取语料库训练的模型,在 13 个基准测试中的平均准确率比在 FineWeb 和 RefinedWeb 等重度过滤语料库上训练的模型高出 1.08 个百分点。

在推理阶段,上下文窗口中的噪声会干扰模型的回答。单个无关段落就可能降低准确率和效率,这使得高质量的清洗对于 RAG 流水线至关重要。

架构转变:从带宽受限转向计算受限

Pulpie 的效率提升源于其架构。像 Dripper 这样的读取式提取器使用解码器一次一个 token 地输出标签,这使其受限于带宽且成本高昂;而 Pulpie 使用编码器在单次前向传播中为每个 HTML 块进行标注。这使得瓶颈从内存带宽转向了计算,而这在现代 GPU 上效率显著更高。

这种架构差异在像 NVIDIA L4 这样较便宜的 GPU 上尤为明显。在 L4 上,pulpie-orange-small 每秒处理 13.7 个页面,而 Dripper 仅为 0.68 个页面/秒。当扩展到十亿级页面规模时,这将导致巨大的成本差异:

| Setup | Pages/sec (L4) | Cost / 1B pages (L4) | | :--- | :--- | :--- | | | Pulpie Small | 13.7 | ~$7,900 | | Dripper | 0.68 | ~$159,000 |

模型家族与性能基准

Pulpie 由一个教师模型和两个蒸馏后的学生模型组成。所有模型都基于 EuroBERT 构建,并使用 <|sep|> 块标记架构。

模型规格

Model Parameters ROUGE-5 F1 Notes
Pulpie Orange Large 2.1B 0.873 教师模型
Pulpie Orange Base 610M 0.863 从 Large 蒸馏
Pulpie Orange Small 210M 0.862 生产环境推荐

质量比较

在 WebMainBench 英文子集上,Pulpie Orange Small 的质量与 Dripper 持平(0.862 vs 0.864 ROUGE-5 F1),但体积仅为后者的三分之一。Pulpie 对长页面的处理能力也优于 Dripper;由于 Pulpie 将块打包成 8,192-token 的块,它不会像 Dripper 那样因 32k-token 上下文窗口失效而导致在 135 个页面上返回空结果。

训练与蒸馏流水线

Pulpie 模型是使用从 16,670 个英文 Common Crawl 页面创建的高质量合成数据集训练的。每个页面使用 MinerU-HTML 进行分块,并由 DeepSeek V3.2 进行内容或内容模板(content-boilerplate)标注。为了确保标签质量,通过 Dripper 0.6B 进行交叉验证,仅保留两个标注器在至少 70% 的块上达成一致的页面。

  1. 教师训练:使用类权重交叉熵(class-weighted cross-entropy)在验证数据集上对 EuroBERT-2.1B 模型进行微调,以处理数据不平衡问题(内容率仅为 28.6%)。
  2. 蒸馏:在温度系数为 2.0 的情况下,结合 KL 散度损失(KL-divergence loss,权重 0.7)和硬标签交叉熵(hard-label cross-entropy,权重 0.3)将 2.1B 的教师模型蒸馏为 Base (610M) 和 Small (210M) 模型。

实现与使用

Pulpie 可作为 Python 包使用,并在 Hugging Face 上开源。用户可以根据对速度与质量的需求选择模型大小。

from pulpie import Extractor

# 默认为 Pulpie Orange Small
extractor = Extractor()
result = extractor.extract(html)

print(result.markdown) # 清洁的 markdown 输出

对于批量处理,Pipeline 类允许 CPU 预处理与 GPU 推理重叠进行:

from pulpie import Extractor, Pipeline, PageInput

pipeline = Pipeline(model="small")
results = pipeline.extract_batch(
    [PageInput(html=h, page_id=i) for i, h in enumerate(pages)]
)

社区反馈

虽然该项目的发布因其架构洞察力而受到称赞,但一些社区成员质疑了相比于简单的 CSS 选择器或 Markdown 转换器,进行基于模型的提取是否有必要。然而,作者提供的数据显示,像 Trafilatura 这样的启发式工具在 ROUGE-5 F1 上的得分(0.619)显著低于 Pulpie Orange Small (0.862),这说明了在网页规模清洗任务中,质量上的差距。

Sources