预训练数据集
预训练数据集是决定大模型性能的关键因素,大量的高质量数据能提高模型的泛化能力和应用效果。
构建预训练数据集需要考虑的因素
数据规模:预训练数据集的规模对模型的性能具有直接影响,一般总体数据量需要达到10T token的级别。
数据多样性:预训练阶段需要接触到多种文本内容,包括文档、网页、代码、数学、多语言等。
数据质量:数据质量直接影响模型预训练的有效性和稳定性,需要对文本进行清洗,对于图片、表格、公式等元素需要做额外的处理。
数据来源
数据集的质量和多样性主要取决于数据来源的选择。常见的数据来源包括:
公开数据集:如维基百科、Common Crawl等大型通用文本数据集。这类数据资源庞大且容易获取。
领域特定数据:从技术文献库、领域文献、研究论文或行业报告中收集数据,适用于特定领域(如医学、法律、金融等)模型的预训练。
网络抓取:通过网络爬虫工具从特定网站抓取数据,尤其适合于需要最新或领域特定信息的场景。
自有数据:如企业内部的技术文档、客户服务记录等,这些数据能够使模型专门针对企业应用场景进行优化。
主流预训练数据集
Common Crawl
Common Crawl 是互联网上最大的开放语料库之一,自2008年起持续爬取网页数据。其PB级的数据规模使其成为大模型预训练的重要数据来源。
| 特性 | 说明 |
|---|---|
| 数据规模 | 每月约30-50亿页面,累积PB级 |
| 数据格式 | 原始网页HTML、WARC格式 |
| 数据特点 | 覆盖多种语言、主题和领域 |
| 主要挑战 | 包含大量噪声,需要深度清洗 |
典型应用:GPT-3、LLaMA、Falcon等模型都使用了Common Crawl作为主要数据来源。通常需要配合CCNet等工具进行质量过滤。
The Pile
The Pile 是EleutherAI构建的800GB英语文本数据集,包含22个子数据集,旨在提供多样化的高质量训练数据。
| 子数据集 | 说明 | 占比 |
|---|---|---|
| Pile-CC | Common Crawl子集 | 18.11% |
| PubMed Central | 生物医学文献 | 14.40% |
| Books3 | 书籍语料 | 12.07% |
| OpenWebText2 | 网页文本 | 10.01% |
| ArXiv | 学术论文 | 8.96% |
| GitHub | 代码数据 | 7.59% |
| FreeLaw | 法律文本 | 3.51% |
| Wikipedia | 百科全书 | 1.53% |
特点:数据来源多样,覆盖科学、代码、文学等多个领域,是学术研究中广泛使用的预训练数据集。
RedPajama
RedPajama 是Together AI发起的开源项目,旨在复现LLaMA的训练数据。目前已发布多个版本:
| 版本 | 数据规模 | 说明 |
|---|---|---|
| RedPajama-1T | 1.2T tokens | 复现LLaMA数据配方 |
| RedPajama-V2 | 30T tokens | 大规模原始网页数据 |
| RedPajama-Data | - | 配套的数据处理工具链 |
RedPajama-V2 的数据处理流程包括:启发式过滤、MinHash去重、质量过滤,提供了丰富的质量信号供用户自定义过滤。
FineWeb
FineWeb 是Hugging Face于2024年发布的高质量网页数据集,包含15T tokens的英语网页数据。
- 数据规模:15T tokens(约96个Common Crawl快照)
- 数据质量:经过多轮过滤和去重,质量高于Common Crawl原始数据
- 数据格式:Parquet格式,支持Hugging Face生态直接加载
FineWeb-Edu 是其子集,专注于教育类内容,通过LLM打分筛选高质量文本,适合训练教育和科学领域的模型。
StarCoder数据
StarCoder 系列数据集专注于代码数据,包含来自GitHub的多语言代码:
- The Stack:6.4TB代码数据,覆盖358种编程语言
- StarCoderData:经过过滤的高质量代码数据,包含许可证过滤和PII去除
中文预训练数据集
| 数据集 | 规模 | 说明 |
|---|---|---|
| WuDaoCorpora | 100GB | 智源研究院发布的中文语料 |
| CCI3 | - | 中文互联网语料 |
| SkyPile | - | 昆仑万维发布的中文网页数据 |
数据清洗
收集到的原始数据往往包含很多噪声和冗余信息,需要通过数据清洗保障数据质量,主要包括:
模型打分
llama3和qwen2的技术报告都提到,可以用打分模型对预训练质量打分。业界的普遍认知是,同等size下,BERT结构的模型的表征能力是强于transformer-decoder模型的。训练打分模型的数据可以由GPT标注得到,需要注意的是,code、markdown、latex等格式的数据会被打低分,应该提前摘出来。
打分模型训练不需要特别多的数据和很高的准确性,可以结合规则进行判断(例如数据长度,某个token的比例是否超过阈值,是否包含敏感词等)。
去重处理
消除重复的文本片段,以避免模型过度学习某些特定模式。需要去除训练集内部重复、训练集与测试集之间重复的n-grams、句子和段落。
常见算法:
- MinHash+LSH:文本去重的经典方法。MinHash将文本转换为特征指纹,LSH(Locality-Sensitive Hashing)用于快速近似最近邻搜索。适合处理大规模文本去重。
- BGE+分片聚类:语义去重方法。通过BGE模型获取文本的语义向量,然后对相似度高的文本进行聚类去重。
数据清洗要先确定需要多少训练数据,再确定去重的粒度。例如需要10T的训练数据,就卡80%的相似度阈值。需要5T的训练数据,就卡90%的相似度阈值。
去除噪声
如HTML标签、广告、目录、标点符号过度堆积、低质量url等。这些信息会干扰模型的训练,降低训练效果。常用工具:DataTrove、Trafilatura。
文本规范化
标准化文本格式,如统一的编码格式、消除特殊符号、处理数字或单位等。常用工具:Normalise、CN-Text-Normalizer。
数据清洗工具对比
| 工具 | 开发方 | 主要功能 | 适用场景 | 语言支持 |
|---|---|---|---|---|
| DataTrove | Hugging Face | 数据集构建和清洗全流程 | 大规模数据清洗 | 多语言 |
| Trafilatura | - | 网页正文提取 | HTML转纯文本 | 多语言 |
| CCNet | Meta | Common Crawl质量过滤 | 网页数据分类 | 多语言 |
| Dolma Toolkit | AI2 | 开放数据集工具链 | 数据清洗和处理 | 多语言 |
| text-dedup | - | 文本去重工具 | MinHash/精确去重 | 多语言 |
| NLTK/spaCy | 开源社区 | 文本预处理 | 通用NLP | 多语言 |
选择建议:大规模数据清洗优先使用 DataTrove(端到端方案),网页数据提取优先使用 Trafilatura,去重任务优先使用 text-dedup。
数据多样性
数据多样性体现在多个方面:任务多样性,语义多样性,语种多样性,数据来源多样性等。主要包含语言过滤、启发式过滤(类似粗筛,基于stopwords占比、字符重复率等规则过滤)、数据质量检测(类似精筛,可以通过大模型过滤)、领域知识注入、去重、有害内容去除、数据混合。
数据增强
在某些情况下,数据增强技术可以进一步提高数据集的多样性和丰富性,尤其是在数据规模不足的情况下。常见的数据增强技术包括:
同义词替换:在不改变语义的前提下,用同义词替换句子中的部分词汇。
句子顺序打乱:对文本中的句子顺序进行随机调整,增加训练数据的复杂性。
生成式增强:利用已有模型生成新的语料,通过多种生成方式扩展训练数据的规模。
数据配比
为了区分不同类型的数据,可以训练一个数据分类器。对每一个document进行类别判断,不用特别精准,把数据划分成新闻、百科、代码、markdown等类目即可,分类器模型依然可以选择使用BERT家族模型,训练数据量级一般要达到2w左右。针对不同类别的数据,做数据清洗时的阈值也不同。
预训练数据主要包含几部分:
通用知识:包含中文和英文知识。
逻辑数据:一般是数学数据和CoT数据。
代码数据:包含多种编程语言。
具体配比跟模型所需能力有关。
数据顺序
预训练的本质是教授模型知识,知识学习的顺序也很重要(先学高数再学泛函),相同数据采用不同顺序训练得到的模型能力是不同的。
数据顺序怎么确定? 参考《IN-CONTEXT PRETRAINING: LANGUAGE MODELING BEYOND DOCUMENT BOUNDARIES》中的观点,利用语义相似度,优先将最相似的document进行拼接,从而构成语义更加连贯流畅的上下文。
预训练数据经验总结
预训练需要大量的数据,如果有企业内自有数据,可以与大量的公开数据集混合进行训练。为了避免大模型遗忘自有数据,可以通过后续在自有数据上微调和对比学习的方式增强记忆。
数据配比和数据顺序一般先在小模型上实验,然后利用scaling law估计在大模型上的效果。
训练数据要兼顾质量和多样性,低质量数据不可能完全清洗干净,只能在选择阈值时尽可能提高信噪比。
预训练的数据是分块加载到内存的,一般块以B为单位,避免内存爆炸、损失爆炸等问题。
预训练阶段数据可以复用,数据处理时需要标注出每个数据被使用了多少次,使用过多的数据应该降低再被选中参与训练的概率。