大模型背后的“炼金术”:一文读懂预训练数据准备的全流程
当我们在惊叹ChatGPT的惊艳表现时,很少有人知道,真正决定一个模型“智商”上限的,并非仅仅是参数量或算力,而是那个被称为“数据”的基石。今天,就让我们深入大语言模型的“数据工厂”,揭开预训练数据准备的神秘面纱。
在人工智能领域,大语言模型的崛起无疑是最引人注目的技术浪潮。从GPT系列到LLaMA,从PaLM到国产的YuLan,这些动辄千亿参数的庞然大物,展现出了惊人的语言理解与生成能力。然而,当我们把目光聚焦在这些模型身上时,往往忽略了一个至关重要的问题:这些模型的“智慧”究竟从何而来?
答案其实并不复杂——数据。正如一位资深AI研究员所说:“模型是算法,数据是燃料,没有高质量的燃料,再强大的引擎也无法发挥威力。”大语言模型的预训练阶段,就是让模型在海量文本数据中“浸泡”,学习语言的规律、知识的框架和世界的常识。而这个过程中的数据准备,堪称一场精细的“炼金术”。
一、数据来源:大模型的“精神食粮”从哪来?
想要训练一个强大的大语言模型,首先需要解决的就是“吃什么”的问题。根据目前主流模型的经验,预训练数据主要分为两大类:通用文本数据和专用文本数据。
1. 通用文本数据:构建基础能力的“主食”
网页数据是目前最为广泛使用的预训练数据来源。互联网就像一个永不枯竭的知识海洋,从新闻资讯到论坛讨论,从百科知识到个人博客,覆盖了人类生活的方方面面。以C4数据集为例,这个从Common Crawl网页快照中清洗出来的数据集,规模达到了800GB,成为众多大模型的“启蒙读物”。
书籍数据则提供了更为规范、深度和连贯的文本内容。无论是文学名著还是专业教材,书籍中蕴含的严密逻辑和丰富知识,能够帮助模型建立长程依赖关系,提升对复杂文本的理解能力。BookCorpus虽然只有5GB,却因其高质量的文本内容,成为许多早期大模型训练的重要组成部分。
对话文本的作用同样不可忽视。论坛帖子、社交媒体评论、客服对话记录等,这些真实的交流场景数据,能够帮助模型学习人类的沟通方式,为后续的人机对话能力打下基础。
2. 专用文本数据:提升专业能力的“营养品”
当模型具备了基础的通用能力后,如何让它在特定领域表现出色?这就需要在预训练语料中加入专门的“营养品”。
多语文本的加入,能够增强模型的多语言理解与生成能力。BLOOM模型使用了46种语言的数据,PaLM更是涵盖了122种语言,这让它们在翻译、跨语言摘要等任务中表现出色。更重要的是,多语言数据能够建立跨语言的语义关联,让模型真正理解不同语言之间的“共通之处”。
科学文本则为模型注入了自然科学和工程技术领域的专业知识。arXiv论文、科学教材、数学网页等资源,让模型能够掌握科学问答与推理的能力。但需要注意的是,科学文本中常常包含数学公式、蛋白质序列等特殊格式,需要专门的处理技术才能被模型有效学习。
代码数据的加入,则是近年来大语言模型能力提升的关键一环。GitHub上的开源代码、Stack Exchange上的编程问答,这些结构化的编程语言数据,不仅让模型学会了写代码,更重要的是提升了模型的结构化语义理解与逻辑推理能力。这也是为什么现在的AI能够编写程序、解决算法竞赛问题的原因所在。
二、数据预处理:从“原材料”到“精炼燃料”
收集到原始数据只是第一步,真正的挑战在于如何将这些“原材料”转化为高质量的“燃料”。这个预处理过程,就像是一个精密的过滤系统,需要经过多道工序的层层把关。
1. 质量过滤:剔除“杂质”
原始数据中充斥着大量低质量内容——自动生成的广告页面、格式混乱的HTML标签、毫无意义的重复文本、甚至包含错误信息的虚假内容。如果不加处理地直接喂给模型,后果可想而知。
基于启发式规则的方法,是质量过滤的第一道防线。这类方法通过设计精巧的规则来识别低质量数据:
- 语种过滤:如果目标是训练中英双语模型,就可以过滤掉其他语言的文本。但需要注意的是,即使以中文为主的模型,也应保留高质量的英文数据,因为英文数据的质量往往更高。
- 统计指标过滤:利用标点符号分布、符号与单词比率、句子长度等统计特征,可以快速识别异常文本。比如,如果一篇文章中符号与词元的比例超过0.1,很可能包含了大量无意义的特殊字符。
- 关键词过滤:针对不同来源的数据,可以制定精准的关键词规则。例如,在网页数据中过滤掉常见的HTML标签,在论坛数据中只保留点赞数达到一定数量的评论。
基于分类器的方法则更加智能。通过训练一个专门判断数据质量的分类器(可以使用FastText这样的轻量级模型,也可以使用BERT、LLaMA等预训练语言模型),能够更加精准地识别低质量内容。具体做法是:将维基百科等公认的高质量数据作为正样本,将含有不良内容或低质量特征的网页数据作为负样本,训练出能够自动判断文本质量的分类器。
在实际应用中,通常会采用组合策略:先用效率高的启发式规则进行快速筛选,再用精度更高的分类器进行精细过滤,这样既能保证效率,又能确保质量。
2. 敏感内容过滤:守住“安全底线”
除了低质量内容,原始数据中还可能包含有毒内容(如暴力、歧视性言论)和隐私信息(如姓名、地址、电话号码)。这些内容如果被模型学习,可能导致模型产生有害输出或泄露用户隐私。
过滤有毒内容,通常采用分类器方法。Jigsaw评论数据集提供了近16万条标注好的论坛评论,涵盖“有毒”、“严重有毒”、“有威胁”、“侮辱性”等多个类别,可以用来训练高效的毒性文本分类器。在设置分类阈值时,需要在精确度和召回率之间找到平衡——阈值太高可能漏掉有毒内容,阈值太低则可能误删大量正常文本。
过滤隐私内容,则主要依赖启发式规则。Dolma数据集的处理策略值得借鉴:对于邮箱地址、IP地址、电话号码这三类敏感信息,如果文档中少于五条,就用特定词元(如“EMAIL_ADDRESS[[]]”)进行替换;如果达到六条或以上,则直接删除整个文档。这种分层处理策略,既能保护隐私,又尽可能保留了有价值的文本内容。
3. 数据去重:避免“营养过剩”
你可能想不到,同一个网页内容可能会被多个URL收录,同一篇新闻可能会被多个数据集收录。如果不去重,模型就会反复学习完全相同的内容,这不仅浪费算力,更糟糕的是会导致“过度拟合”——模型过于偏爱某些重复出现的模式,影响其泛化能力。
研究显示,如果将语料中0.1%的数据重复100次,800M参数模型的性能会下降到相当于400M参数模型的程度。这就是重复数据带来的巨大伤害。
去重可以在不同粒度上进行:
- 文档级别去重:检测并删除高度相似或完全一致的文档。常用技术包括精确匹配(如后缀数组)和近似匹配(如MinHash算法)。MinHash通过计算集合的最小哈希值来估计相似度,避免了逐一比较所有元素的繁琐过程,特别适合处理超大规模数据集。
- 句子级别去重:在文档去重的基础上,进一步删除重复的句子。通过计算相邻句子间的n元组相似度,可以识别并过滤掉高度重复的句子。
三、数据对预训练效果的影响:不仅仅是“量”的问题
在训练大语言模型的过程中,数据的数量和质量都会对模型性能产生深远影响。
数据数量的影响
早期的KM扩展法则认为,增加模型参数比增加数据更重要,因此GPT-3虽然拥有175B参数,但只用了500B词元进行训练。然而,后来的Chinchilla扩展法则颠覆了这一认知:参数规模和数据规模应该同步增长。Chinchilla用1.4T词元训练70B参数的模型,展现出了比Gopher(280B参数,300B词元)更好的性能表现。
近年来,训练数据数量得到了前所未有的重视。LLaMA-2的7B模型就在2T词元上进行了预训练,远超Chinchilla法则给出的比例。更小的模型也开始使用高达1T级别的数据,而且研究者发现,这些模型似乎还没有达到学习数据量的上限。
数据质量的影响
数据质量的影响甚至比数量更为直接。Phi-1模型(1.3B参数)通过精心筛选高质量数据,并利用GPT-3.5生成“教科书级”补充数据,在HumanEval上取得了50.6%的pass@1准确率,这个成绩甚至超过了许多更大规模模型。
相反,低质量数据会导致训练不稳定、模型产生“幻象”(输出不准确或虚假信息)等一系列问题。例如,“灯泡是爱迪生发明的”这个广为流传的误解,如果出现在训练数据中,模型就可能在相关问题上给出误导性答案。
数据集污染问题
数据集污染是一个容易被忽视但影响巨大的问题。当评估基准中的测试数据意外出现在预训练语料中时,模型就相当于“提前知道了答案”,原本衡量零样本或少样本能力的评测,变成了领域内的测试任务,失去了公平性和参考价值。
研究表明,在测试集完全泄露的极端情况下,1.3B的小模型甚至能在大部分任务上超过正常评测的65B大模型。因此,无论是模型开发者还是基准测试维护者,都需要高度警惕数据重叠问题。
四、实践指南:如何构建高质量的数据预处理流水线
理论知识固然重要,但实际操作中的细节同样关键。以YuLan模型的数据处理框架YuLan-GARDEN为例,我们来看看具体如何实现这些预处理流程。
质量过滤实战
以语言过滤为例,可以通过加载预训练好的FastText语言分类器,为每个输入文本生成语言标签,不符合要求的数据将被过滤:
class FilterPassageByLangs():
def __init__(self):
# 加载fasttext语言分类器
self.language_identifier = LangIdentifier(model_path="lid.176.bin")
self.reject_threshold = 0.5
def filter_single_text(self, text: str, accept_lang_list: list) -> bool:
labels, scores = self.language_identifier.evaluate_single_text(text)
if scores[0] < self.reject_threshold:
labels = ["uk"]
accept_lang_list = [each.lower() for each in accept_lang_list]
if labels[0] not in accept_lang_list:
return True # 需要过滤
return False
去重实战
句子级去重可以通过计算相邻句子间的n元组Jaccard相似度来实现:
class CleanerDeduplicateByNgram():
def clean_single_text(self, text: str, n: int = 5, thre_sim: float = 0.95) -> str:
# 分割所有行
lines = [each for each in re.split('|'.join(map(re.escape, self.line_delimiter)), text) if each != '']
for idx, line in enumerate(lines):
# 计算每行的n元组
grams = [each for each in re.split('|'.join(map(re.escape, self.gram_delimiter)), line) if each != '']
computed_ngrams = list(ngrams(grams, min(len(grams), n)))
# 存储到lineinfo...
for idx, each in enumerate(lineinfo):
if last != {}:
# 计算相邻行的Jaccard相似度
ngrams_last, ngrams_cur = set(last["ngrams"]), set(each["ngrams"])
jaccard_sim = len(ngrams_last & ngrams_cur) / len(ngrams_last | ngrams_cur)
if jaccard_sim >= thre_sim:
# 相似度过高,过滤掉
continue
# 保留该行
隐私过滤实战
对于隐私信息,通常采用正则替换的方式进行处理:
class CleanerSubstitutePassageIDCard(CleanerBase):
def clean_single_text(self, text: str, repl_text: str = "**MASKED**IDCARD**") -> str:
# 使用正则表达式匹配身份证号,用特定字符串替换
return self._sub_re(text=text, re_text=REGEX_IDCARD, repl_text=repl_text)
总结:数据准备的四大核心原则
回顾整个预训练数据准备的过程,我们可以总结出四大核心原则:
1. 多元化与专业化并重
通用文本数据构建基础能力,专用文本数据提升专业表现。只有将两者有机结合,才能训练出既全面又有深度的模型。
2. 质量优于数量
高质量数据带来的收益远超单纯增加数据量。Phi-1的成功证明,即使参数规模不大,在“教科书级”数据上训练也能取得惊艳效果。
3. 安全性不容忽视
有毒内容和隐私信息必须严格过滤。这不仅关系到模型的合规性,更关系到用户信任和品牌声誉。
4. 持续迭代与优化
数据预处理不是一蹴而就的工作,需要不断采样、评估、调整的迭代过程。只有建立系统化的数据处理框架(如YuLan-GARDEN),才能在保证效率的同时持续提升数据质量。
正如一位AI领域资深专家所言:“未来大语言模型的竞争,不仅是算力和算法的竞争,更是数据工程的竞争。”掌握数据准备的“炼金术”,才能在AI浪潮中立于不败之地。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)