每一个模型都是对其数据的一场赌注。无论你是在从零预训练、在某个领域上微调、组装一个检索语料库,还是构建一个评测集,你从网络上采集之物的质量与广度,都为这个模型能做到什么设下了一个上限。而以一个模型所需的规模采集网络数据——跨越数百万页面和许多地区——会撞上每一个大型爬虫都会碰到的同一批基础设施问题:按 IP 计的速率限制、随地理而变的内容,以及越来越封锁任何看起来像自动化爬虫之物的站点。住宅代理正是让那次爬取成为可能的那一层采集层,而这里就是它们嵌入之处,连同它们并不解决的那些部分——对 AI 数据而言,那些部分比平常更要紧。
AI 团队真正采集的是什么
采集的形态随目标而变。预训练与持续预训练的语料库,是横跨公开网络一大片区域的、广而高量的文本拉取。领域微调更窄也更深,是对某项任务所看重的那些站点做一次聚焦的爬取。为一个 RAG 系统所用的检索语料库,是经过策展并按计划刷新的,好让索引不至于过时。评测与基准集更小,却需要有代表性且干净。多模态工作在文本之上再加上图像和其他资产。它们全都共有的,是底下的一层采集层:可靠地取回大量公开页面,从它们真正所在之处取。那一层不论其上坐着什么都是同一层,也正是本文余下所谈的。
规模:为什么一个 IP 爬不动整个网络
网络不欢迎一个单一地址去拉取数百万页面。大多数站点强制执行按 IP 的速率限制,而一个从单一位置把一切都发出去的爬虫,会在几分钟内被限速、随后被封禁,爬取也就远远够不到一个模型所需的量就停住了。即便在限额宽松之处,单一连接也是一个瓶颈,面对一个以数百万文档来计的语料库。
把爬取分散到许多住宅 IP 上,正是把一缕细流变成一个语料库的东西。每个 IP 都舒舒服服地待在它自己的按 IP 限额之内,而你的聚合吞吐量随着池子扩张——这正是任何高流量采集器所倚赖的负载均衡逻辑,也正是无限并发连接的用途。要点不是去压垮任何单个站点,而是把一次大规模、有礼的爬取分散到足够多的地址上,好让任何一个目标从其中任何一个地址看到的,都不过是一份寻常的流量。
代表性:一个语料库只有你采集之处那么宽
这是特属于训练数据、又容易搞错的部分。一个模型学的是喂给它之物的分布,所以一个完全从单一位置采集来的语料库,继承的是那个位置的那一片网络。许多站点按地区提供不同的内容:本地化页面、不同语言、按地区划分的目录、价格与可得性,有时甚至是完全不同的首页。从单一国家爬取网络,你就系统性地对那个国家看不到的一切采样不足,而那份偏斜会被烘焙进模型里。
国家定位、以及在要紧时的城市级定位,让你能采集每个地区真实用户所看到的页面版本,于是你的语料库反映的是你真正想要的地理与语言分布,而不是你的爬虫恰好在哪里运行这个偶然。如果多语言覆盖或地区平衡是一个目标,这就不是锦上添花,而是一个有代表性的数据集与一个失衡的数据集之间的分野。那同一个以合法方式抵达随地区而变的内容的地理定位,正是你从一开始就把广度筑进数据里的方式。
在站点对爬虫加固之际保持可达
站点对自动化采集已明显变得更具防御性,而这份加固里有相当一部分正是冲着 AI 爬虫来的。已知的数据中心 IP 段和明显的机器人信号会被很快封锁,而一些最大的站点如今会质询或拒绝那些看起来不像寻常人类访客的流量。一次从数据中心地址运行的爬取,越来越多地返回的是封锁与质询页面,而不是内容。
住宅代理把请求经由真实的、家庭级 IP 路由,于是每个请求看起来像一个寻常访客,而不像数据中心里的一台服务器,而信誉良好的干净地址能顺畅通过,被标记的则会遭到质询。这必要,却不充分:IP 把你送到门口,其余则是要表现得像一个真实客户端,这意味着合乎情理的请求速率、对触发封锁的信号的诚实处理,以及不因为你能就去猛砸一个目标。目标是像一个浏览器那样采集公开数据,而不是硬闯一个已经决定不愿被爬取的站点。
新鲜度:语料库会变陈旧
一个数据集是一张快照,而网络在动。检索语料库尤其需要定期的刷新爬取,好让索引反映其来源的当前状态,而持续预训练则依赖于把新出现之物纳进来。这让采集成为一条持续运行的流水线,而非一次性的活儿,而一条持续运行的流水线,需要挺过那些随时间劣化的路由。在某个给定 IP 上侦测到一次封锁、一个超时,或一次质询,就退役那条路由,改在一条新鲜的上继续——这正是让一次长跑爬取保持存活的故障转移模式。这一切都不该盲干,所以要监控这条流水线:成功率、覆盖度,以及按来源的错误模式,会在一个目标改变了它的防御、或爬取的一个切片正在无声失败时告诉你,赶在那个缺口以缺失数据的形式出现在下一轮训练之前。
负责任地采集
诚实的那一部分——而对 AI 数据来说,它并非可选。住宅代理是采集基础设施,它们不是许可。负责任地构建一个语料库,意味着只采集公开数据、尊重每个站点的 robots 指令与服务条款,并有礼地爬取,带上速率限制与退避,好让你永不劣化你所依赖的那些站点。同样重要、且与你在技术上能否取回一个页面相分离的,是权利的问题:能够采集数据,和有权在其上训练,并不是同一回事,而版权、许可,以及个人数据规则,都是坐落在采集层之上的真实约束,把它们弄对是团队的责任。以谨慎、并在法律之内对待个人与敏感数据。代理解决的是在规模上抵达公开页面的”如何”,而”采什么”与”是否可以”,是你依然拥有的决定,认真对待它们,正是把一个站得住脚的数据集与一份负债区分开来的东西。
一套最小的有礼爬取
一个轮换住宅代理对你的爬虫看来就是个寻常代理。定位住在 gateway 的用户名里,所以一个不带会话标识的美国出口会按请求轮换,把爬取分散到池子各处:
import timeimport requests
PROXY = "http://customer-USERNAME-country-us:PASSWORD@p.shifter.io:443"proxies = {"http": PROXY, "https": PROXY}
def fetch(url): r = requests.get(url, proxies=proxies, timeout=20, headers={"User-Agent": "research-crawler/1.0"}) r.raise_for_status() return r.text
for url in urls: # your queue of public pages try: html = fetch(url) store(html) # persist for the corpus except requests.HTTPError: retry_later(url) # on a block or timeout, back off and requeue time.sleep(1.0) # be polite; do not hammer a single origin把队列铺开,好让没有哪个站点从一个 IP 看到一阵爆发;遇到错误就退避,而不是硬着重试;而为了多语言或地区覆盖,用不同的国家定位跑同一次爬取。通用的客户端模式从用 Python 使用住宅代理那篇指南里一路承接过来,而在一个语料库需要会话一致的多页取回之处,一个粘性会话会为那一段序列守住一个 IP。
底线
为 AI 与 LLM 训练采集网络数据,受三件事的约束:一个模型所需的规模,单一 IP 够不到;一个好语料库所要求的代表性,单一位置无法捕捉;以及那道不断升高的反爬防御之墙,数据中心地址越来越翻不过去。住宅代理对这三者都作答。把爬取分散到一个大池子里,好让每个 IP 都保持有礼、而聚合得以扩张;定位到国家与城市,好让语料库反映你真正想要的地理与语言;经由干净的、家庭级 IP 路由,好让请求看起来像寻常访客;并带上监控做故障转移,好让一次持续的刷新爬取一直跑下去。然后去做代理不做的那一部分:只采集公开数据、尊重 robots 与条款、有礼地爬取,并把许可与隐私放在采集层之上——它们本就该在那里。
那一层采集层,正是住宅代理的用途——一个由真实的、家庭级 IP 组成的大池子,带国家与城市定位,并在一段序列需要时带粘性会话。按 GB 计价意味着你为自己真正拉取的数据付费,这很契合一个从聚焦的领域爬取、直到以数百万页面来计的语料库都能覆盖的工作负载。