
Crawl4LLM 内存优化百万级文档爬取不爆内存的 5 个关键设计【免费下载链接】Crawl4LLMOfficial repository for Craw4LLM: Efficient Web Crawling for LLM Pretraining项目地址: https://gitcode.com/gh_mirrors/cr/Crawl4LLM当你用 Crawl4LLM 这个面向 LLM 预训练的网页爬虫工具试图从 ClueWeb22 语料中筛选出百万级文档时最怕的不是速度慢而是内存爆掉OOM。Crawl4LLM 内存优化方案的核心思路其实很简单不把整个世界装进内存而是边爬边丢、分批处理。本文带你用 10 分钟看懂这套开源爬虫工具的底层设计学会如何配置参数让你的机器在百万级文档爬取任务中稳如泰山。先搞清楚内存都浪费在哪了在讲优化之前先看一个典型爬取流程。Crawl4LLM 的爬虫主循环写在 crawl.py 中每一轮迭代做四件事从优先队列中弹出本轮要处理的文档 ID抓取这些文档的出链outlinks给新文档打分长度、fastText 质量分等把新文档重新压回队列如果每一步都把「文档全文 评分 队列 已访问集合」全部留在内存里爬 2000 万文档README 示例max_num_docs: 20000000时内存消耗将以GB 甚至 TB 计直接 OOM 崩溃。Crawl4LLM 的聪明之处在于它从头到尾只把「文档 ID 一个轻量评分字典」放在内存里文档正文用完即丢。秘密一max_num_in_mem_docs分批评分内存天花板由你说了算这是 Crawl4LLM 内存优化最关键的一处设计。在 crawler.py 的get_scores_for_docs方法中爬虫会把待评分的文档 ID 列表按块切割docids_partitions [ docids[i : i self.max_num_in_mem_docs] for i in range(0, len(docids), self.max_num_in_mem_docs) ]什么意思假设你一次性拿到了 50 万个新出链而max_num_in_mem_docs设为 10 万那么这批文档会被切成 5 份一次只加载和评分 10 万篇处理完再处理下一份。这个参数在启动命令中通过--max_num_in_mem_docs传入默认值是 100 万crawl.py。配置 YAML 里也可以直接写max_num_in_mem_docs: 100000 # 每批最多驻留内存的文档数调参建议内存小的机器调低到 5 万10 万内存充裕128GB再考虑保持默认。这个值直接决定了「单批峰值内存」是防爆内存的第一道保险。秘密二评分完立刻del document.text正文用完即丢很多人爬网页会顺手把 HTML 或纯文本存进对象里越攒越多。Crawl4LLM 反其道而行在 crawler.py 的_get_scores_for_docs里所有评分器跑完后会执行这样一行for document in results: del document.text评分一结束文档正文立刻从内存中删除只留下docid和annotations各评分器的分数。文档正文通常是内存占用的大头一篇网页正文可能几 KB几十 KB百万篇就是几十 GB。用完即丢是这套系统能撑住百万级文档爬取的根本原因。而且注意 corpus_interface.pyUnifiedGetter.get_doc每次都是按需从磁盘读取单篇文档读完就释放永远不会出现「整个语料库驻留内存」的情况。秘密三评分器按需加载正文能省则省不是所有评分都需要正文在 document_rater.py 中RandomRater随机评分和InlinkCountRater入链计数的_require_doc_text False根本不需要读取文档正文只有DocumentLengthRater和FasttextRater才需要正文Crawl4LLM 会在初始化时检查crawler.pyself.require_doc_content any(rater.require_doc_text() for rater in self.quality_raters)如果所有评分器都不需要正文代码直接跳过get_doc的磁盘读取crawler.py既省内存又省 IO。所以如果只是做随机采样或入链优先的基线爬取README 中的 Baseline Crawlers内存占用会低一个数量级。秘密四visited集合去重避免队列无限膨胀爬虫另一个内存杀手是重复文档。Crawl4LLM 在 crawler.py 的find_outinks中做三重去重出链先去重成集合set(outlinks)减去已经访问过的visited集合outlinks - self.visited只有「未访问过」的文档才会进入评分和入队流程每次新文档入队时也会同步加入visitedcrawler.py。虽然visited本身要占内存但它阻止了队列里堆积重复文档从源头控制住内存增长——这个集合用几十 MB 换回了可能几十 GB 的重复内容。秘密五save_state_every定期快照崩溃也能续爬爬 2000 万文档可能要跑很多天中途断电、OOM 怎么办Crawl4LLM 提供了状态快照机制配置save_state_every: 400每 400 轮迭代就把队列 visited 集合 已选文档数序列化保存到state_000400.pkl等文件crawler.py恢复时用--resume_from_state state_000400.pkl通过 crawler.py 的init_or_resume_state重新加载队列和已访问集合从断点继续这虽然不是直接的「省内存」手段但它是长期大任务的内存风险管理策略即使峰值内存估算失误导致进程被杀最多损失 400 轮的工作量而不是从头再来。快照文件还支持评分器变更后的自动重算Recomputing scores for all docs in the queue非常贴心。一份可以直接抄的「防爆内存」配置清单把上面所有秘密组合起来一份面向百万级文档爬取的稳妥配置长这样参考 README.md 的 Crawl4LLM 示例cw22_root_path: /mnt/ssd/clueweb22 seed_docs_file: seed.txt output_dir: crawl_results/seed_10k_crawl_20m_dclm_fasttext num_selected_docs_per_iter: 10000 num_workers: 16 # 按你的 CPU 核数调整 save_state_every: 400 # 定期快照崩溃可续 max_num_docs: 20000000 # 目标爬取 2000 万文档 max_num_in_mem_docs: 100000 # 每批驻留内存上限防爆内存关键参数 selection_method: dclm_fasttext_score order: desc wandb: false # 不需要可视化日志就关掉 rating_methods: - type: length - type: fasttext_score rater_name: dclm_fasttext_score model_path: fasttext_scorers/openhermes_reddit_eli5_vs_rw_v2_bigram_200k_train.bin五个调参要点速查参数作用内存紧张时怎么调max_num_in_mem_docs单批驻留内存的文档数从 100000 降到 50000num_workers并行进程数从 16 降到 48每个 worker 都有独立内存开销save_state_every快照间隔调小如 100减少崩溃损失rating_methods评分器组合尽量少用需要正文的评分器max_num_docs目标文档总数按实际需求设定别盲目求大另外README 有一条重要提示ClueWeb22 数据务必放在 SSD 上README.md因为爬虫是高频随机读机械盘会拖慢 IO 并导致文档对象在内存里积压更久。内存优化之外这套设计还教会我们什么Crawl4LLM 的内存优化思路其实可以总结成三句通用原则任何做大规模数据处理的工具都适用数据边界意识永远明确「什么必须常驻内存什么可以流式处理」正文就是典型的流式数据生命周期管理对象用完立即释放del document.text 显式gc.collect()见 crawler.py可恢复性设计大型任务必须有状态快照否则一次崩溃就是全部重来如果你正准备用 Crawl4LLM 构建 LLM 预训练数据集它的论文《Crawl4LLM: Efficient Web Crawling for LLM Pretraining》就是干这个的先把max_num_in_mem_docs调小、把save_state_every打开再开始跑。百万级文档爬取不爆内存靠的不是一台超级服务器而是这 5 个精心设计的细节。想要自己上手验证克隆仓库后从 README.md 的 Prerequisite 开始装依赖然后按照本文的配置清单创建你的第一个 YAML 文件跑一次小规模的python crawl.py crawl --config 你的配置.yaml观察日志里的Partition 1: xxx docs输出——你就能亲眼看到分批处理在如何保护你的内存了。【免费下载链接】Crawl4LLMOfficial repository for Craw4LLM: Efficient Web Crawling for LLM Pretraining项目地址: https://gitcode.com/gh_mirrors/cr/Crawl4LLM创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考