Crawl4LLM 自定义扩展:手把手教你实现专属文档评分器
【免费下载链接】Crawl4LLMOfficial repository for "Craw4LLM: Efficient Web Crawling for LLM Pretraining"项目地址: https://gitcode.com/gh_mirrors/cr/Crawl4LLM
Crawl4LLM 是一个面向 LLM 预训练的高效网页爬虫框架,而文档评分器(Document Rater)正是决定它"往哪爬、爬什么"的核心组件。本文手把手教你通过自定义扩展,实现属于自己的专属文档评分器,让爬虫精准筛选高质量训练语料。整个过程只需理解 3 个步骤:继承基类、实现打分逻辑、在配置文件中注册,零基础也能快速上手。
Crawl4LLM 是什么?为什么文档评分器是爬虫的"大脑" 🧠
Crawl4LLM 出自论文《Crawl4LLM: Efficient Web Crawling for LLM Pretraining》,目标是解决一个经典难题:互联网上网页海量,但适合做大模型预训练语料的高质量页面只是少数。
传统爬虫用广度优先(BFS)或随机策略抓取,效率很低。Crawl4LLM 的思路是"边爬边打分":每发现一批新网页,先用文档评分器给它们打分,再按分数决定下一步优先抓取谁。评分器就像爬虫的大脑,直接决定了最终语料库的质量。
整个核心流程是:
- 从种子文档(如 seed.txt)出发,抓取第一批文档
- 用评分器给每个文档打分,写入优先级队列
- 每轮从队列顶部弹出最高分的文档,顺着它的外链继续扩展
- 重复直到达到目标文档数量
评分逻辑集中在 document_rater.py,队列与调度逻辑在 crawler.py,入口和配置解析在 crawl.py。
内置 5 种文档评分器速览 📋
上手自定义之前,先看看框架自带的评分器,理解"评分器"到底长什么样。它们全部继承自DocumentRater基类(document_rater.py):
| 评分器 | 类型标识 | 打分依据 | 需要文档正文 |
|---|---|---|---|
RandomRater | random_score | 随机数 | ❌ |
DocumentLengthRater | length | 文本长度 | ✅ |
InlinkCountRater | inlink_count | 入链数量 | ❌ |
FasttextRater | fasttext_score | fastText 模型预测 | ✅ |
EnsembleRater | ensemble_score | 多个评分器加权求和 | ❌ |
从表格可以看出,评分器的差异在于打分依据:有的只依赖链接结构(入链数),有的需要读取正文(长度、模型打分),有的甚至可以随机(作为基线对比)。自定义扩展的本质,就是定义你自己的"打分依据"。
理解评分器核心机制:打分、注解与排序 🔧
要实现自定义评分器,必须先理解三个小概念:
1. 打分:每个评分器接收一批Document对象,返回同样数量、但带上了分数注解的Document。文档的字段定义在 corpus_interface.py。
2. 注解:分数以annotations字典的形式挂在文档上,键是评分器名称,值是分数。框架里用DocumentAnnotation管理(corpus_interface.py),多个评分器可以同时打分,互不覆盖。
3. 排序:crawl.py中的DocumentAnnotation.set_compare_method(args.selection_method, args.order)(crawl.py)决定用哪个评分器的分数作为队列排序依据,以及升序还是降序。这就是配置里的selection_method字段。
评分器基类提供了_annotate_doc方法(document_rater.py),它自动帮你把分数写入注解,还支持附加归一化后的分数。自定义评分器时,你只需要实现__call__方法,其余交给基类。
手把手实现自定义文档评分器(3 个步骤)🛠️
下面以"独特词比例评分器"为例:它计算文档中去重后的词数占总词数的比例,比例越高,说明内容越丰富、重复越低,越适合做训练语料。这个例子足够简单,又能完整体现自定义扩展的全部要点。
第 1 步:继承 DocumentRater 基类
新建一个my_raters.py文件(放在项目根目录即可),写入以下代码:
from document_rater import DocumentRater from corpus_interface import Document class UniqueWordRatioRater(DocumentRater): # 类型标识,配置文件中用这个字符串引用 _name = "unique_word_ratio" # 打分需要读取正文 _require_doc_text = True def __call__(self, docs: list[Document]) -> list[Document]: results = [] for doc in docs: words = (doc.text or "").lower().split() ratio = len(set(words)) / len(words) if words else 0.0 results.append(self._annotate_doc(doc, ratio)) return results关键点只有三个:
- 继承
DocumentRater,设置_name(配置文件的type字段)和_require_doc_text - 实现
__call__,输入文档列表、输出打过分注解的文档列表 - 用
self._annotate_doc(doc, score)把分数写进注解,基类会自动处理一切
第 2 步:在配置文件中注册并启用
评分器不是"写出来就能用",需要在 crawl.py 的initialize_quality_raters函数中注册,让它能根据配置里的type字符串创建实例。在match type_:中加一个分支:
case "unique_word_ratio": quality_raters.append(UniqueWordRatioRater(normalizer=normalizer))然后在configs/目录下创建自己的 yaml 配置文件,在rating_methods列表中加入新评分器:
cw22_root_path: <path_to_clueweb22_a> seed_docs_file: seed.txt output_dir: crawl_results/seed_10k_crawl_my_rater num_selected_docs_per_iter: 10000 num_workers: 16 max_num_docs: 20000000 selection_method: unique_word_ratio # 用自定义评分器决定抓取优先级 order: desc rating_methods: - type: length - type: unique_word_ratio # 我们的自定义评分器注意selection_method必须填unique_word_ratio,这样爬虫的优先级队列才会按你的分数排序。
第 3 步:运行爬虫验证效果
先按 README 准备好环境:申请 ClueWeb22 数据集、Python 3.10+ 虚拟环境、安装依赖,然后执行:
git clone https://gitcode.com/gh_mirrors/cr/Crawl4LLM cd Crawl4LLM python crawl.py crawl --config configs/你的配置文件.yaml爬虫运行后,每个迭代选取的文档 id 会写入output_dir下的iter_*.docids.txt,可以用 fetch_docs.py 拉取对应正文,再送入 DCLM 框架做预训练评测。一个专属评分器就正式上线了!🎉
进阶技巧:分数归一化与集成评分 ⚡
自定义评分器上线后,你可能还会遇到两个常见需求:分数尺度不统一和单一评分器不够稳。
归一化:不同评分器的分数范围差异巨大(长度可能是几万,独特词比例是 0~1)。Crawl4LLM 内置了两种归一化器(normalizer.py):ZScoreNormalizer(zscore)和MinMaxNormalizer(minmax)。在配置中给评分器挂一个归一化器即可:
rating_methods: - type: unique_word_ratio normalizer: type: minmax min_score: 0.0 max_score: 1.0归一化后的分数会以{rater_name}_normalized为键额外存入注解,方便与其他评分器对比或集成。
集成评分:EnsembleRater支持把多个评分器的分数按权重求和(document_rater.py),这是提升评分稳定性的经典做法:
rating_methods: - type: unique_word_ratio - type: length - type: ensemble_score rater_name: my_ensemble raters_and_weights: - rater_name: unique_word_ratio weight: 0.7 - rater_name: length weight: 0.3验证与调试:用相关性图评估评分器 📊
怎么知道自定义评分器"靠不靠谱"?项目提供了一个非常好用的评估模式:rate模式(utils.py)。它会读入种子文档,用配置中所有评分器打分,并生成一张评分器两两之间的 Spearman 相关性图,保存为correlations.png。
python crawl.py rate --config configs/你的配置文件.yaml这张图能帮你回答三个问题:
- 我的评分器和现有评分器高度相关吗?(如果和
length相关度 0.9,说明没带来新信息) - 我的分数分布合理吗?(查看对角线上的分布直方图)
- 归一化效果如何?(
normalized分数应大致落在同一尺度)
建议在正式大规模爬取前,先用这个小数据集验证评分器行为,避免跑几天才发现方向错了。
常见问题与排查技巧 ❓
Q1:报错 "Unknown rating method"?说明评分器没有在 crawl.py 的match分支里注册,回去检查第 2 步。
Q2:自定义评分器不生效,队列排序没变化?检查 yaml 里selection_method是否等于评分器的_name,且order方向是否正确(desc降序、asc升序)。
Q3:我的评分器需要读正文,会不会拖慢爬虫?会。_require_doc_text = True会让爬虫为每个候选文档拉取正文(crawler.py)。建议评分器尽量轻量,或用num_workers并行加速;不需要正文的评分器(如inlink_count)则快得多。
Q4:能否中途更换评分器?可以。爬虫支持保存状态文件(save_state_every配置),恢复时会自动检测评分器是否变化,并重算队列中所有文档的分数(crawler.py)。
总结:你的爬虫,你的评分规则 🚀
Crawl4LLM 的自定义扩展机制非常清爽:继承DocumentRater基类 → 实现__call__打分 → 在crawl.py注册 → yaml 配置启用,四步即可让爬虫按你的规则筛选网页。无论是想要过滤低质页面、偏好长文本,还是引入自己的机器学习模型打分,这套机制都能无缝支持。
现在就去定制你的专属文档评分器吧,让 Crawl4LLM 为你抓取最适合 LLM 预训练的高质量语料!
【免费下载链接】Crawl4LLMOfficial repository for "Craw4LLM: Efficient Web Crawling for LLM Pretraining"项目地址: https://gitcode.com/gh_mirrors/cr/Crawl4LLM
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考