LLMOps: 生产环境下的大语言模型管理——大语言模型(LLM)数据工程

187 阅读48分钟

本章将介绍数据工程、数据管理实践,以及现有的数据库工具和系统。内容主要面向希望转型为LLMOps工程师或领导公司数据工程工作的数据工程师、DevOps工程师和MLOps工程师。读完本章后,你将对数据工程的基础知识以及LLM相关的最佳实践有较为全面的理解。

数据工程与LLM的兴起

20世纪60年代末,英国计算机科学家埃德加·F·科德(Edgar F. Codd)在IBM工作时,受其关于自复制计算机的博士研究启发,对数据排列理论产生了浓厚兴趣。1970年,他发表了题为《大型共享数据银行的关系数据模型》的IBM内部论文,首次提出了我们今天所知的关系数据库概念。例如,传统的销售表中每条记录包含了产品和客户的所有信息,而关系数据库则将数据分散存储于多个相关表中:客户表、产品表和销售表。这样,如果客户地址发生变化,不必修改所有相关销售记录,只需更新客户表即可,这大大降低了操作成本。

尽管IBM当时未立即对此产生热情,但这篇论文吸引了许多计算机科学家和业余爱好者的关注,其中包括Oracle创始人拉里·埃里森(Larry Ellison),他开发并销售了第一个兼容IBM主机的关系数据库。IBM也开发了查询语言,最初称为SEQUEL,后更名为结构化查询语言(SQL),成为行业标准。1981年,科德因其在关系数据库领域的贡献获得了计算机科学界最高荣誉图灵奖。看到关系数据库的流行及管理需求,IBM于1983年推出了自家的数据库管理系统DB2。关系数据库迅速成为行业标准,广泛用于索引、目录管理等业务。负责这些系统的专业人员称为数据库管理员(DBA)。伴随云计算发展,2010年代“数据工程师”一职开始流行。

科德还参与撰写了一篇名为《向用户分析师提供OLAP:IT使命》的论文,首次提出了联机分析处理(OLAP)一词,用于描述快速处理和查询多维数据的系统,成为现代数据处理系统的基础。

1990年,蒂姆·伯纳斯-李(Tim Berners-Lee)发明了万维网,极大增加了数据生成量。虽然大量数据是结构化的(如邮政编码等固定长度和类型数据),但也有很多是非结构化的,如音乐、文章和视频。关系数据库将信息组织为具有预定义列和强数据类型的表格,适合高度结构化数据和复杂的基于SQL的多表连接查询,且提供ACID(原子性、一致性、隔离性、持久性)保障,广泛应用于银行、库存管理和传统业务系统等事务处理领域,但对互联网中的非结构化数据支持不足。

为应对关系数据库在处理大规模、快速变化或结构松散数据时的不足,非关系型数据库(NoSQL)应运而生。键值存储通过唯一键快速检索数据;其中,文档数据库以自包含的JSON文档存储每条记录,允许各文档结构多样,适用于内容管理、商品目录等字段多变的场景,这在互联网数据中非常常见。键值数据库还支持以二进制大对象(BLOB)形式存储视频、图片等二进制文件,适合新型数据环境。

此外,还有图数据库和向量数据库。图数据库以节点和边存储关联实体,支持如社交网络“朋友的朋友”查询、供应链影响分析、文档关系发现等毫秒级路径搜索。向量数据库则存储和索引高维向量(嵌入),这些向量捕获文本、图像、音频等内容的语义意义,通过近似最近邻算法返回与查询向量最相近的条目,广泛应用于语义搜索、推荐系统、图像/音频相似度匹配及为LLM提示提供上下文的检索增强生成(RAG)流程。

现代应用通常综合使用多种数据库:关系数据库负责事务处理,文档或键值存储处理半结构化内容和媒体,图数据库存储复杂关系,向量数据库处理基于语义相似性的检索。数据工程师的主要工作之一就是在这些数据库类型间找到合理的平衡,并结合数据支持具体应用。

LLM兴起前,数据科学家和分析师通常使用较简单的NLP技术,将文本转为数值特征供传统机器学习处理。常用方法包括词袋模型(BoW)和词频-逆文档频率(TF-IDF)。BoW以稀疏矩阵表示文档中单词出现频次,忽略词序,TF-IDF进一步根据词语在整个语料库中的稀有度加权,减弱常见词影响,突出信息性词汇。

这些矩阵通常存储为结构化或二进制数据格式,并借助如Pandas、NumPy(矩阵操作)以及Parquet、HDF5(存储和查询大规模预处理数据集)等工具处理。在生产环境中,PostgreSQL、MongoDB、Elasticsearch等数据库被广泛用于存储、索引和查询NLP数据,支持搜索引擎、推荐系统、情感分析、文本分类等应用。

LLM的兴起离不开嵌入技术的发展。正如第一章介绍,嵌入算法将文本数据转化为实数向量,编码语义信息,使语义相似的词语在向量空间中更为接近。这推动了向量数据库的出现,能够存储向量及相关元数据,利用机器学习算法进行高效查询。第二章提到,LLMOps旨在打造生产环境中可靠、稳健、可扩展的LLM应用,但“垃圾进,垃圾出”这句老话同样适用:模型的表现取决于数据质量,而LLMOps的成熟度也依赖于数据工程系统的成熟度。

数据管理早期主要关注数据获取、存储和检索,机器学习和LLM加入了数据转换为适当表示形式的新环节,要求更多技能。为此,企业有两条路径:招聘LLM工程师并提升技能,或招聘数据工程师并让其融入LLM团队,培训为LLMOps工程师。

无论哪种方式,任务特定模型向任务无关模型的转变将持续推进。数据市场巨大且不断增长,涉足LLM领域的公司亟需具备专业能力的数据工程人才来管理数据工程系统。

DataOps工程师角色

DataOps工程师通常具备数据工程师或数据科学家的背景,并在应对领域组成、数据量和数据质量的大规模复杂性方面拥有额外的专业知识。他们熟练掌握诸如全局去重和动态数据选择等高级技术,以支持持续微调。

针对LLM的数据工程涉及设计、开发和管理数据管道及基础设施,以支持模型的训练、评估和部署。DataOps工程师负责实现和优化规模定律,平衡数据质量与数量的权衡,并管理多样且大规模的数据集。然而,他们的职责不仅限于数据管道管理,而是对LLM的数据生命周期进行整体协调,从数据获取到部署,持续改进模型性能,面对高度复杂且不断演进的环境。

这一专业方向标志着数据工程和管理实践的重大进化,要求数据工程师日常工作更加复杂且有针对性。在LLM时代之前,数据工程主要是将定义明确、以结构化数据为主的操作型数据通过管道传输到数据仓库和数据湖,以供报告或分析使用。重点在于批量ETL/ELT作业、维度建模、缓慢变化维度以及治理实践,这些治理主要关注数据质量是否符合模式规范、引用完整性及基本去重。非结构化文本可能存储于数据湖,但很少被视为核心数据;搜索和分析负载依然围绕行、列和聚合SQL进行。

以LLM为中心的负载彻底改变了这一格局。原始材料变成了异构文本、代码、图像、音频和聊天日志,这些内容的价值取决于语义丰富度——即内容的信息价值,而非刚性结构。数据管道必须对内容进行分词、分块、嵌入和版本控制;将其存储在用于相似度搜索的向量索引中;并应用个人身份信息过滤、有害内容检测及许可约束。团队不再是运行传统的ETL作业,而是执行持续的数据摄取和重新嵌入循环,保证RAG系统的新鲜度,并记录每个提示-响应对,以便评估输入输出、改进系统未来表现。在此背景下,数据质量通过基于事实的可靠性、偏差指标进行判断,这需要自动化的红队测试和人机协同审查(HITL),而非以往单纯的数据结构违规检查。

因此,现代数据工程技术栈融合了传统仓库、对象存储、向量数据库和特征存储。Airflow、Dagster等编排框架与LLMOps工具共存,治理范围扩展到模型卡、数据集营养标签以及每个token的法律来源追踪。支持LLM的数据工程已从“行列的管道工”转变为“语言和知识的拥有者与守护者”。

数据工程直接影响机器学习应用及LLM的性能。训练时使用的数据的质量、类型和数量决定了模型的有效性。这里有两个额外的挑战:其一,几乎所有LLM数据都是非结构化的;其二,数据量大幅增加。这两点使得某些任务难度大增。例如,在传统机器学习中,可以通过剔除年龄为负数或超过130岁的异常记录来检查输入数据的异常值。而对非结构化数据来说,这种检查变得极其困难,令LLM的数据管理比非生成式机器学习模型的数据工程复杂得多。

数据管理

数据管理侧重于管理组织的数据资产,而数据工程则涉及设计和构建用于数据存储、处理和分析的基础设施。一个高效的LLM数据工程团队需要同时配备专注于数据管理的DataOps工程师和专注于数据管道设计与管理的数据工程师(见图4-1)。两者协同工作,整合多样的数据源,帮助LLM更好地学习,并避免幻觉和偏见等问题的发生。

image.png

针对LLM的数据管理有两种基本方法:静态和动态。静态数据管理意味着在整个训练过程中保持数据集不变。这可能导致数据重复且无法适应模型不断变化的需求。动态数据管理则是在模型训练过程中持续更新和调整数据。这种方法更灵活,但更难处理,因为它需要持续关注数据的质量和相关性。

一些方法会在训练期间动态调整数据集。例如,动态数据裁剪会随着训练进展剔除较少用处的样本,二分类器可以基于模型执行指令的效果判断是否提前停止训练。其他技术则包括选择能提供最多信息的任务,或通过迭代过程不断细化任务。

合成数据

截至目前,一些新型模型,如微软的 Phi-4 和 DeepSeek-R1,在使用合成数据时表现出了性能提升。合成数据是指从现有数据自动生成的数据,同时保持其统计特性。举例来说,从包含100名真实篮球运动员身高、位置和得分记录的数据集中,可以利用统计技术生成大量与现有运动员相似的虚拟运动员数据,以扩充数据集。为了合成用于训练LLM的长文本,DataOps工程师常用旧一代的文本生成模型。

正如之前提到的,任务构成时,数量与质量的平衡是关键。更大的数据集通常意味着更多样且更高质量的数据,这通常会带来更好的性能,但同时也要求高效的数据处理管道。为了构建强大的模型,DataOps工程师需要掌握自动化编排,在合适的时机自动应用这些技术。

LLM数据管道

那么传统机器学习和LLM之间发生了什么变化?为什么我们需要不同的数据管道?

正如所述,传统机器学习通常处理结构化数据——有条理地组织在表格或电子表格中的数字。数据来源包括数据库、传感器或API。这些数据干净、易于管理且直观。传统机器学习依赖特征工程,数据工程师将原始数据转化为有用的数值特征,供模型用于预测。这个过程高度依赖人工操作。

在大多数情况下,传统机器学习处理的数据集较小,不需要海量数据,且可以用传统CPU或GPU完成处理。这种方法高效且易于控制,适用于任务明确、需要清晰预测或分类的问题,其中数据是结构化的,且问题边界明确。

但对于LLM来说,数据是非结构化的——文本杂乱无章、范围广泛且无序,比如文章、代码和社交媒体帖子。数据来源从网页抓取、文档库到文本API不等。这是一场信息洪流,远比传统机器学习中清晰的电子表格混乱得多。现实世界的数据是非结构化的。比如,假设你正在用新闻网站的数据训练模型(需获得适当许可)。你访问几个新闻网站时,常会看到广告、图片、解释性框、相关新闻框、编辑推荐列表等各种元素与正文交错,且格式各异。此外,新闻网站的数据集体量庞大,需要强大的GPU甚至专用硬件(如TPU)来处理。这是规模化的数据,处理能力必须匹配。

另一个区别是,传统机器学习模型通常有明确的性能指标,如精度和召回率,而LLM需要生成类人内容,判断输出是否类人常常需要人工评估。这比处理结构化数据的模型需要更多实验。比如,结构化数据可以通过剔除异常值或错误样本来轻松提升模型性能,因为某些数据类别明显更有价值。但现有研究尚未明确哪些类别的数据对LLM训练更有价值;例如,即使包含错误信息的文本,只要句子结构良好,也可能有用。

除了处理非结构化数据和需求更强算力,LLMOps工程师还需设计实验优化输入数据,并评估期望的输出效果。

训练大型语言模型(LLM)

从宏观角度看,训练LLM包括两个步骤:预训练和指令微调(见图4-2)。在预训练阶段,模型学习语言的一般规则和事实——包括语法、句法、风格以及领域知识。这一步发生在你要求模型遵循指令或针对某个任务进行专门训练之前。预训练通常采用遮挡法:从数据块中随机隐藏一个词,训练机器学习模型去猜测该词。目标是训练一个能最大限度减少猜词错误的模型。

微调阶段通常是通过提供一组复杂的指令和预期答案来完成的。此步骤的目标是训练模型,尽可能减少答案中的错误。正如机器学习中的传统做法一样,数据越好,结果越佳,因此本章余下部分将重点讨论确保数据工程高质量的策略。

image.png

原始的数据工程生命周期

传统上,机器学习团队的数据工程生命周期(DELC)如图4-3所示。DELC包括五个阶段,将原始数据转化为可供分析师、数据科学家、机器学习工程师及其他人员使用的有用最终产品。因此,在大型语言模型(LLM)出现之前,数据工程师的职责主要是开发和维护数据管道,并确保数据质量。

image.png

当时,DELC 的五个关键组成部分是:

生成
这涉及与生成数据的团队和流程协作。例如,如果数据是通过 API 或调查生成的,工程师需要与负责构建该 API 或调查的团队合作,确保生成的数据质量高。此环节还包括在需要时创建合成数据。

采集
包括收集数据并将其传输到合适的数据存储中。

存储
工程师将数据合并到数据湖中,并存储在数据库里。

转换
包括数据清洗,处理异常值、缺失数据和重复数据的过程。

服务
将转换后的数据提供给最终用户和/或数据科学团队使用。

数据工程中出现的新问题

为 LLMOps 创建数据工程生命周期(见图4-4)需要回答许多新的问题,而这些问题在现有的数据工程文献和实践中仍未得到充分解决。

image.png

本章将通过解决以下问题,逐步构建一个新的数据工程生命周期(DELC)框架:

  • 对于你的 LLM 应用,理想的数据组成是什么样的?
  • 哪种规模定律适用于你?
  • 可接受的数据重复率是多少?
  • 应该使用哪些技术来进行数据质量过滤?
  • 应该使用哪些模型来去除数据中的重复项?
  • 如何处理有毒和带偏见的数据?
  • 需要多少数据多样性?
  • 生成合成数据时,如何设计最优的提示(prompt)?
  • 应该如何监控数据的老化情况?

如果你对其中某些术语还不熟悉,不用担心,下一节会详细介绍这些内容。实际上,在本章后半部分,你还将学习如何系统地思考和解决这些问题。但首先,让我们逐一来探讨这些新出现的关注点。

数据组成

公开可用的训练数据集通常包含来自多个领域的多样化数据。这种多领域方法在大型语言模型(LLM)中很常见。早期的训练语料库由高度多样化的数据组成,包括网页和维基百科等来源,因其覆盖面广和内容丰富而受到重视。然而,随着对数据质量的关注增加,更加专业且高质量的内容变得必要,比如书籍和学术论文。这一转变是为了满足语言模型执行高级任务和展现更强能力的需求。
最新的研究显示,训练同时包含计算机代码和非结构化文本的LLM在处理非结构化任务时表现更好。事实证明,LLM在相对结构化的代码数据上学到的知识,也能迁移到非结构化任务中。同时,LLM生成代码的能力有所提升,软件工程师和数据科学家们广泛使用诸如GitHub Copilot之类的工具。这些创新使得代码和数学文本等领域最近在总训练数据中的占比有所增加。
这一趋势表明,随着时间推移,训练数据集中纳入更广泛领域的数据,赋予LLM更多样化和强大的能力。研究表明,适当混合的多领域训练数据集对于开发具有强大泛化能力的模型至关重要。
截至目前,研究人员正在制定指导原则,以确定预训练中最佳的领域混合比例。早期的尝试结合了精心设计的实验和直觉推理;最新进展则引入了自动化方法,为不同领域分配权重,形成合适的目标分布。

规模定律

即使在LLM广泛应用之前,训练数据集大小与基于Transformer的语言模型性能之间的关系,已经引起了研究者的广泛关注。训练模型的目标是最小化损失,也就是模型预测错误的比例。例如,若模型需猜测“I was very thirsty so I drank…”中的下一个词,猜测“bookshelf”会比猜测“water”带来更大的损失。Kaplan等人在2020年指出,语言模型的损失服从幂律关系,即某一数量随另一数量的固定指数幂成比例变化。例如球体积与半径的三次方成幂律关系。在语言模型中,损失与训练数据集大小或模型大小(参数数量)呈幂律关系,前提是两者都不是瓶颈且训练计算预算充足。
数学表达为:

Loss(1N)αLoss(1D)βLoss \propto \left(\frac{1}{N}\right)^\alpha \quad \text{或} \quad Loss \propto \left(\frac{1}{D}\right)^\beta

其中,

  • NN 表示模型大小
  • DD 表示训练数据集大小
  • α\alphaβ\beta 是依赖于具体模型和数据集的常数

Kaplan等人得出结论:只要模型大小和训练数据集大小同步扩展,模型损失会按可预测的方式降低。此外,他们建议在保持足够计算预算的情况下,为了保持最佳性能,模型大小和训练数据集大小应大致按相同比例增长。

他们还分析了在固定计算预算 CC 下的资源最优分配,发现最佳训练数据集大小和模型大小应满足关系:

DoptC0.27,NoptC0.73D_{opt} \propto C^{0.27} \quad , \quad N_{opt} \propto C^{0.73}

这表明在计算预算固定时,模型大小应比训练数据集大小增长更快,以达到最佳性能。

随着LLM变得更大且被广泛采用,如何从计算预算中提取最佳训练效果变得更加重要。基于Kaplan的研究,Hoffmann等人用更大规模的语言模型进行了实验,提出了新的规模定律,通常称为Chinchilla规模定律,强调了模型大小与训练数据量之间的权衡。该定律指出,许多现有LLM(如GPT-3)相较于其大小而言训练不足,即模型参数过多而训练数据不足。该定律建议,要实现最佳性能,应在增加参数数量和扩大训练数据量之间找到平衡,当计算预算固定时,应优先扩展数据规模。

遵循该原则的模型在训练数据充足的情况下,能获得比仅增加模型规模但数据不足的模型更好的性能,同时所需计算资源更少。这一见解推动了LLM研究的重点从单纯追求更大模型,转向在模型规模和数据量之间更高效地分配计算资源。

数据重复

尽管早期关于规模定律的研究集中于模型在独特数据上仅训练一个周期的情况,近期研究开始探讨训练数据集中重复数据的影响。随着模型不断增大,对高质量训练数据的需求也在增加,因此出现了对高质量数据资源可能耗尽的担忧。

为应对这些问题,一些研究考察了在整个数据集上进行多周期重复预训练的影响。这些研究提出了重复训练的规模定律,指出随着重复次数增加和模型规模变大,性能收益递减。模型在连续多个训练周期中性能下降的现象被称为多周期退化。这种退化受到数据集大小、模型参数和训练目标等因素的影响。研究人员尝试使用经典的数据改进技术来提升训练数据的有效性,但大多数方法效果有限,唯有“dropout”技术显示了一定的益处。

数据质量
在LLM预训练中,为确保数据集干净且有效,会采用多种质量控制技术,包括质量过滤、去重和有害内容过滤。此外,数据多样性和数据时效性也对提升LLM性能十分重要。
以下是对这些关键点的详细说明:

质量过滤 公共数据集往往包含低质量数据,可能妨碍LLM训练。以Common Crawl为例,它是一个公开的网络爬取数据存档,包含大量原始网页数据,包括博客文章、新闻、论坛讨论,甚至垃圾信息或无关网页。虽然这些数据覆盖广泛,但质量参差不齐,Common Crawl数据常包含过时、冗余或格式不规范的文本,以及带有偏见、错误信息或冒犯性内容。

去重
去重指确保数据集中无重复或冗余内容。此过程重要性体现在几个方面。首先,它减少模型记忆具体短语或实例的风险,使模型更能概括数据中的模式,而非死记硬背。其次,去重能最大限度地减少训练集与测试集的重叠(当训练数据和测试数据中存在相同或极为相似内容时),避免测试集变得不具挑战性,从而导致性能指标虚高。最后,移除不必要的重复,使模型能专注于多样化和独特的内容,从而提升泛化能力。去重旨在帮助模型达到低困惑度(perplexity),即模型对下一个词的预测准确度更高。

有害内容和偏见过滤
有害内容过滤旨在剔除粗鲁、不尊重或可能导致负面交互的内容。由于原始文本语料中常包含有害内容,有害内容过滤帮助防止LLM生成有害输出。此类过滤一般采用启发式、规则以及n-gram分类器等方法。尽管有害内容过滤能有效降低生成有害文本的风险,但有时也会削弱模型的泛化能力和识别有害内容的能力。
实际上,恰当过滤内容非常困难。例如,涉及边缘群体的文本常包含被视为有害的词汇,过滤这些词汇的文档可能会丢失对边缘群体有用的信息,从而加剧数据中的边缘化问题,这给构建公平的LLM带来了挑战。

数据多样性
数据多样性确保模型能学习多种语言风格、文化背景和知识领域。例如,包含科学论文、创意写作、法律文件、社交媒体及对话文本,能帮助模型在不同场景中做出恰当回应。此外,语言多样性——涵盖多种语言、方言和地区表达——确保模型具备全球适用性和有效性。缺乏足够多样性会导致LLM过于狭窄或带偏见,降低其实用性和公平性。
实现数据多样性面临重大挑战。公共数据集往往过度代表某些语言、地区或群体,而忽视其他。例如,像Common Crawl这样的网络数据集通常过度偏重英语和非正式文本,许多语言和正式写作风格被低估。

数据时效性
当前LLM通常使用较新数据进行预训练,因为某些知识具有时间敏感性。预训练数据与评估数据之间的时间差会导致性能估计不准确。尤其对大型模型而言,这一问题难以通过微调纠正,强调了在预训练过程中考虑数据时效性的重要性。

在预训练LLM时,领域组成、数据数量和数据质量之间的平衡非常复杂,存在诸多相互依赖关系。

截至目前,研究人员提出了规模定律,帮助理解数据数量、领域组成和数据质量如何共同影响模型性能。2024年的一项研究显示,在总数据量保持不变时,数据质量与模型规模呈正相关。这些相互作用使得优化单一因素往往会影响其他因素,因此平衡这些因素需要做出各种权衡。举例来说,增加数据量可能导致数据质量下降(若新增数据相关性较低或噪声较多);而聚焦高质量数据可能减少可用的训练数据总量。在固定计算预算下,这种权衡更为明显,因为优化一方面可能需要牺牲另一方面。

此外,跨领域的全局去重增加了复杂性。虽然去重对于减少冗余、提升模型效率至关重要,但若去重不够精准,也可能误删有价值的信息。一项研究表明,相较于其他领域,质量更高且多样性更丰富的领域对模型性能提升更有益,进一步加剧了选择的复杂性。
最后,领域组成、数据数量和数据质量之间的关系并非静态。这些因素动态且协同作用,意味着一项变化可能对其他方面产生不可预测的影响。这种复杂性使得没有一刀切的策略可供遵循。优化LLM训练需要根据具体模型目标和约束持续调整和微调。

本章后续将介绍一个可根据需求调整的通用预处理流程,并将在后面讲解指令型数据集预处理的具体挑战。

用于LLM的一般数据预处理流程

本流程包含10个基本步骤。不过在开始之前,有一个“第0步”:定义你如何衡量成功。完成所有步骤后,你如何知道这个过程是否奏效,新的版本是否优于之前的版本?这些技术将在第7章详细讨论,这里先介绍一个基本的衡量方法。

首先,建立一小组核心指标,可以在每次流水线运行后计算。一个快速的方法是准备一组已知正确答案的提示,便于快速评估,范围从简单问题如“2+2等于多少?”、“法国的首都是哪里?”到复杂问题如“请用是或否回答:这是一张鸟的图片吗?”或“请用是或否回答:汤姆·克鲁斯是玛丽·李·普菲弗的儿子吗?”这些易于计算的答案相当于烟雾报警器,一旦数据采集、去重或权重调整出现问题,模型异常会立刻显现。

此外,还应定期用传统基准测试评估LLM,例如“大规模多任务语言理解”(MMLU,见第7章)以及安全和偏见检测提示(见第8章)。允许有些许波动,但在训练过程中,应确保整体指标趋于上升,而不是停滞不前或在调整某个预处理步骤后急剧下降。

下面进入具体的10个预处理步骤:

步骤1:数据目录化
首先,需要明确你到底需要什么样的数据。终极目标是什么?模型将如何应用?这些答案将指导你选择预训练数据。早期定义好数据类型、语言、领域和质量标准,就能设定明确目标,而不是盲目收集数据。将数据源组织到数据库中,方便后续为收集的数据打标签。

步骤2:检查隐私和法律合规性
确保数据采集和使用符合数据隐私法律和法规要求。这不仅是保护自己,更是尊重数据及其代表的人群。确保所用数据有适当许可,并将许可信息记录在数据库,方便后续为数据打标签。

步骤3:数据过滤
不是所有数据都一样,数据源的质量非常关键。可考虑多种来源——网站、书籍、学术论文等,但确保它们符合预设标准。可靠且准确的数据至关重要。例如,CulturaX语料库通过黑名单过滤有害内容,是早期风险缓解的优秀范例。专业过滤器甚至云端解决方案可助你在开始前剔除低质量源。你可以选择直接丢弃未用数据,或者在数据库中标记为已过滤,后者占用更多存储但便于后续增删过滤器。

数据清理的几个核心规则

  • 评估句子完整性。不完整的句子(缺标点或语义不通)需过滤,因不具备实用价值。
  • 删除个人隐私信息(PII),完全剥离或用占位符替代,保护隐私最重要。
  • 删除暴力、色情等有害内容,责任在于内容过滤。
  • 移除异常符号,任何无关或异常字符都是噪声。
  • 去除技术杂乱,如HTML、CSS、JavaScript标识符,干扰内容质量。
  • 删除含有花括号的句子,常为占位符或无用数据。
  • 剔除过短句子,太简短的句子可能缺少上下文,影响理解。
  • 删除冗余内容,如导航栏、“点赞”按钮等无关文本。
  • 去除包含特定不希望出现词汇的文本,识别并清除不合适内容。

步骤4:数据去重
数据采集成功与否取决于策略。时间范围多长?数据规模多大?采集频率如何?提前回答这些问题,能在保持实时性的同时收集多样化数据。云平台提供的可扩展数据管理非常适合此需求。去重时,你也可选择直接丢弃重复数据或在数据库中标记为重复。

去重方法
在去重——即删除重复或冗余数据——方面,有几种关键方法值得关注:

  • 词频-逆文档频率(TF-IDF)软去重
    该方法比较文本中词汇的频率与整个数据集中的词频。如果两个文本的TF-IDF得分高度相似,则删除其中一个。某些词在单个文本中出现频率高但在整个语料库中出现较少,则赋予较高权重,表明它们对该文档非常重要。
  • MinHash
    该算法估计两组文本的相似度。它使用随机哈希生成一组最小哈希值,然后比较这些值以估计相似性。计算和存储效率高,适合大规模数据集。
  • SimHash
    该算法将文本特征向量转换为固定长度的哈希码,通过比较哈希码的距离来衡量文本相似度,距离越近文本越相似。它在保持计算轻量化的同时,提供可靠的文本相似度计算。

还有许多其他处理重复数据的方法。一种简单而有效的方式是删除连续出现的重复句子,只保留第一个实例。你还可以删除数据集中具有相同URL的文档。另一种流行方法是结合MinHashLSH和n-gram技术,如果相似度超过某个阈值(通常约为0.8)则标记为重复内容。

这些方法各有优势,但目标一致:剔除不必要、重复和无关内容,保持数据精简聚焦。数据越干净,模型表现越好。

步骤5:数据收集
真正的工作从这里开始。使用网页爬虫、API和其他工具从已确定的来源收集数据(务必核查服务条款,避免侵犯版权)。无论是HTML解析还是PDF文本提取,都要确保数据干净且结构化。常用做法是使用经过精选的数据集,如Falcon或CommonCrawl。CommonCrawl提供WARC格式数据,包含网页的全部原始数据,也有WET格式,仅包含正文纯文本。即使自建数据集,遵循这些格式也有助于利用GitHub上众多处理相关格式的工具。

收集数据时,别忘了添加前面步骤产生的元数据。

步骤6:编码检测
确保文本编码正确是必不可少的。错误编码可能破坏数据,且编码错误往往表面正常,难以察觉,甚至只影响文本中的少数字符,导致乱码。可以使用如开源的Chardet等编码检测工具,确保以正确编码处理文本文件,避免在看到模型输出时才发现错误。将编码信息添加到第5步采集数据的元数据中。

步骤7:语言检测
接下来,使用语言检测工具(如lingua-py)识别数据中的语言,并按语言划分数据子集。了解训练数据的语言情况非常重要,同时检查所用LLM对目标语言的覆盖度。例如,训练一个说葡萄牙语的模型时,应保证有足够的葡萄牙语数据。将语言信息添加到元数据。

步骤8:切分(Chunking)
在收集好原始数据,确保能正确读取编码和语言后,就该将数据拆分为可用的小块。抽取文本元素并将其拆解成易处理的块。大多数模型对输入文本长度有限制,因此需要将文本分割成小于最大长度的块。

切分方法多样:

  • 固定大小切分:编码简单,但可能会拆开完整思想。
  • 基于句子的切分:适合有明确独立思想的文档。
  • 基于段落的切分:保持更宽泛上下文,但块体积大于句子切分。

还有更高级的切分技术。例如,可以使用现有LLM对每个块进行情感分析和主题识别,添加元数据;或者将整篇文档提交给LLM,让其返回切分块。更复杂的“代理切分”方法则让LLM模拟分析师提问,并记录使用频率最高的块。

注意,用LLM切分计算资源消耗较大。无论用哪种方法,切分块都应包含之前步骤的所有元数据,如数据来源、许可、编码和语言。

步骤9:备份数据
看似简单,但定期备份是关键保障。数据丢失可能非常严重,定期备份保证你总有备份可用。

步骤10:执行维护和更新
最后,这不是一次性的过程。你的数据收集系统需要持续维护。通过定期更新数据源或改进策略,进行持续的更新和优化,确保数据保持新鲜和相关。持续改进是关键。

这些步骤可以用于生成预处理好的原始数据块,既适用于预训练,也适用于微调阶段。第5章将详细讲解LLM训练。为了快速了解生成微调数据的方法,接下来我们会介绍向量化。

向量化

向量化是将文本数据转换为高维数值表示(即向量)的过程,这些向量捕捉了文本的核心特征。英文中“embedding”一词常与“vectorizing”(向量化)交替使用,作为名词时也指向量本身。

生成向量后,它们可以存储在向量数据库中。向量化的概念早在LLM出现之前就已流行,例如ElasticSearch在2019年就支持了向量搜索,允许用户查询与给定文本相似的文本。现今的向量数据库扩展了向量存储和搜索的能力,可处理海量数据集。

一个理想的嵌入过程(即嵌入模型)应能有效捕捉语义差异:词义或短语相近时生成的向量应彼此接近,词义相异时向量应相距较远。

如果你按照前文介绍的10个步骤生成了数据集,那么在第8步得到的多个文本块就可以通过使用嵌入模型添加向量字段来丰富数据。

生成嵌入的模型有很多选择。一种方法是直接上传数据到向量数据库(下一节会详细讲解);另一种是用像OpenAI的text-embedding-3-large或BERT这样的模型自行生成自定义嵌入,然后将结果存入向量数据库。最佳方法取决于你的具体需求。

举例来说,OpenAI的text-embedding-3-small算法最多可接受8191个token的输入,输出一个长度为1536的实数向量,输入大小不影响输出向量长度。比如,一个只有两个字符(如“no”)的token,会输出1536维向量;一个包含8000字符的段落,也输出1536维向量。因此,如果你第8步生成的文本块长度大约在8000字符以内(平均一个token约等于4个字符),该模型是不错的选择。但如果文本块很短,比如100字符,则使用该模型可能会浪费资源,此时较小的嵌入模型(如BERT)可能能以更低成本达到同样性能。

向量化在LLM中有一个重要应用场景:检索增强生成(Retrieval-Augmented Generation,简称RAG)。RAG通过先在数据集中搜索与查询相似的文本块,再利用LLM“粘合”检索到的文本块生成自然的答案,从而提升生成质量。向量数据库显著加快了检索步骤的速度。我们将在第6章详细介绍RAG应用,但现在先来讨论向量数据库。

向量数据库

在许多应用中,你需要找到与某些文本相似的文本。例如,在亚马逊搜索商品时,你可能想找到类似的产品。向量数据库通过寻找语义相似的文本,使这变得简单。一个向量数据库能够将亚马逊上“带USB充电口的笔记本电脑背包”这一搜索请求,关联到标记为“技术友好型日用背包,17英寸,内置移动电源”的商品,即使关键词完全不匹配。

对于很多搜索应用来说,未必非得用向量数据库。除非你的数据集非常庞大(比如训练大型语言模型或者运行全球电商网站时),否则正如特斯拉前AI主管、OpenAI创始团队成员Andrej Karpathy所建议的:启动一个项目时,可能只需要免费的Python库NumPy就够了。

向量数据库专门用来存储向量(embedding),并快速搜索与给定向量相近的向量。想象你有一堆数据——可能是文本、图像,或者两者混合。第一步是把它们向量化。一旦完成,数据库会以便于查找相似数据点的方式存储这些向量,这个过程称为索引。当你提交一个文本查询时,查询本身也会被向量化,数据库通过执行最近邻搜索,计算该查询向量与存储向量之间的距离,从而找到最相似的条目。

向量数据库允许你同时存储元数据和数据的向量表示。你可以利用元数据先缩小搜索空间,再执行向量相似度搜索,这样能显著提升查询效率,特别是在大数据集场景下。比如,如果你已知查询文本的语言,且元数据中有语言字段,就可以用它来提升搜索性能。

选择向量数据库时,需要考虑的因素包括可扩展性、容错能力、索引技术的可用性以及成本。表4-1详细列出了这些特性。

表4-1 向量数据库选择参考

特性描述常见指标索引技术(影响)
可扩展性处理不断增长的数据量和查询负载能力吞吐量(每秒查询数)、延迟、存储容量水平扩展能力(影响吞吐量)、分片策略(影响查询效率)
容错能力发生故障时保持可用的能力正常运行时间百分比、恢复时间(MTTR)数据复制(保证数据可用)、高可用功能(减少停机时间)
索引技术在高维向量空间中高效搜索的方法搜索准确率、搜索速度度量树(HNSW、VP树):适合中等数据量与维度;哈希(LSH):快速近似搜索但精度有折中;倒排文件(IVF):结合元数据过滤提升速度

维护数据新鲜度

预处理流水线的第10步是保持数据最新。让索引与底层数据的实时变化同步很有挑战,方法从“询问时告知是否有变更”到“变更发生时即时通知”不等。最简单的是轮询(polling):周期性查询源数据,比较最新快照与数据库中的数据。虽然易理解且适合数据量和新鲜度要求不高的场景,但会浪费资源反复查询且引入查询间隔的延迟。例如,每年更新一次数据,检测变化至少需要一年时间。

更精确的替代是变更数据捕获(CDC),直接读取源系统的事务日志、提交日志或其他反映新鲜度的元数据(如文档最后修改时间)。不必遍历所有文档,只处理发生变更的文档列表,从而减少无意义的检查和带宽浪费。

当数据生产者能主动推送信息时,就进入事件驱动和流式处理模式。在事件驱动更新模型中,数据拥有者发送“商品描述已变更”或“文章已更新”等消息,每个事件都是自包含的,可立即触发数据库更新。

LlamaIndex
LlamaIndex(最初于2022年底作为GPT Index发布)是一个开源数据框架,能将数据接入任何大型语言模型(LLM)工作流。它负责繁琐的底层工作:加载多种格式数据、分块、生成向量表示、索引及向量检索。

你可以用LlamaIndex预处理数据并生成向量表示。再配合独立的CDC或事件驱动更新流水线捕捉实时数据变更。此流水线可触发变更数据的向量重生成,并通过API(如果支持)更新向量数据库。

生成微调数据集

如果你仅仅完成了数据预处理部分提到的10个步骤,就已经拥有了足够的数据来进行你的大型语言模型(LLM)的预训练阶段。然而,对于几乎所有实际应用来说,你需要让你的LLM不仅仅是猜测被遮蔽的词汇。LLM最常见的任务是回答问题,而为此你需要提供一组问题及其对应的预期答案。这类数据集称为指令数据集(instruction dataset)或微调训练数据集(fine-tuning training dataset)。

创建微调训练数据集主要有以下四种方法:

  1. 手动策划
    这是最直接的方式。你和你的团队亲自策划和设计数据集,仔细挑选和撰写每条指令以满足需求。这个过程既慢又费力,但它让你完全掌控数据,尤其适合需要高度定制或针对特定任务的数据集。
  2. 收集并改进现有开源数据集
    既然已有有价值的数据,何必重新发明轮子?你可以利用开源数据集,对其进行筛选和优化以更好地适应你的需求。这是一个不牺牲质量的捷径,特别是当你通过策略性的改进提升它们时。通过微调现有数据,你实际上是在利用社区的集体成果来加速自己的进展。
  3. 用LLM生成
    你可以使用大型语言模型来生成指令微调数据集。为此,你需要将你的数据块存储在向量数据库中。下一节会详细介绍这一过程。
  4. 混合方法
    最后,不要忘了结合这些方法的优势。你可以将手动创建、开源数据集策划和模型生成结合起来,全面覆盖你的需求。一种简单的混合方式是将各种数据集直接拼接在一起。这种混合方法提供了灵活性,让你根据具体任务利用每种方法的优势。

微调数据集大致分为两类:

  • 通用指令微调数据集:范围广泛,涵盖多个领域的多种任务,目的是提升模型遵循一般指令的能力,使其更具通用性。数据集越广,模型理解和执行各种指令的能力越强。
  • 领域专用指令微调数据集:聚焦特定领域,专为某些专业领域设计。例如,医学指令数据集会训练模型处理诊断或医疗辅助等任务。专注于特定领域能提升模型在该领域的专业水平。

自动生成指令微调数据集

步骤1:预处理与向量化
推荐使用 LlamaIndex 来处理你的大规模文本语料。LlamaIndex 可以执行之前通用流程中提到的许多预处理步骤,如分词和清洗。同时,它还能为语料中的每个文本块生成高质量的向量表示。这些文档向量可以存储在多种数据库中。

步骤2:构建检索机制
编写一个简单程序,输入一个问题时,从步骤1中创建的向量数据库中检索出与该问题最相关的文本块。你可以直接使用 LlamaIndex 提供的 VectorIndexRetriever 功能来实现。

步骤3:生成问题
将整篇文档(而非单个文本块)提交给已有的大型语言模型(LLM),让它生成一组能由该文档回答的问题。文档可能需要拆分成多个部分,但这些部分通常要比数据库中的文本块大得多。比如,文本块通常包含约8000字符(便于生成向量嵌入),而 GPT-4o 能为约40万个字符的文档生成问题列表。

步骤4:请现有的LLM判断最佳答案
将步骤3生成的每个问题提交给步骤2中编写的检索程序,得到与问题密切相关的一组文本块。然后把该问题和这组答案文本块一起提交给已有的LLM,要求它从中选出包含最佳答案的文本块,并基于该块生成一份清晰完整的回答。你可以让LLM以JSON格式输出,形式如:{"instruction": <问题>, "input": "", "output": <答案>}。重复此流程,直到获得所需数量的示例。

生成问答后,进行基本的质量检查:通过计算文本级别余弦相似度去重几乎重复的问答对,过滤掉引入检索文本中未包含信息的答案,然后随机抽查一小部分,确保自动过滤器校准准确。若想让数据集更丰富,可以让LLM对同一文本块提出更深入的后续问题,或要求以有效JSON等受限格式返回答案——这两种策略都能教会微调模型处理更复杂的指令。

整个流程在资源有限时可以简化。针对小规模语料,可以用轻量库(如BERT)预先计算嵌入,跳过检索步骤,由LLM直接从单段文本生成问题及答案,并用余弦相似度验证答案与原文的贴近度。

如果你的数据不是静态的怎么办?

尽管没有万能方案,以下是处理动态数据的一些建议:

  • 集成实时数据流。利用低延迟消息协议,如 Kafka 或 Apache Pulsar,实现高效数据传输。
  • 按时间窗口(上下文窗口)对数据分段,时间窗口大小应与数据更新频率匹配,并以时间戳作为元数据,告知LLM数据的时效性。例如,你可能有一周前的数据集、几个月前的数据集和历史数据集,它们可以存放在同一数据库中,通过不同元数据标签区分。
  • 为不同时间戳的数据维护独立训练管道,节省重复训练成本。例如,每天对一周前的数据进行微调,但对几个月前的数据则每周训练一次。
  • 实施数据版本管理,跟踪不同LLM训练数据迭代,必要时可方便地回滚到历史版本。

结论

本章讨论了大型语言模型(LLM)端到端的数据工程流水线。虽然针对LLM的数据工程仍处于初期阶段,但本章提供的建议和指导能为你奠定扎实的基础,助你在各个环节优化数据流水线,以适应具体的应用场景。

参考文献

  • Chang, Ernie, 等。“Scaling Parameter-Constrained Language Models with Quality Data”,arXiv,2024年10月。
  • Chardet。无日期。“Chardet: 通用字符编码检测器”,访问时间:2025年5月21日。
  • Codd, E. F. “A Relational Model of Data for Large Shared Data Banks”,ACM通讯13(6):377–87(1970年)。
  • Common Crawl。无日期。Common Crawl,访问时间:2025年5月21日。
  • Dodge, Jesse, 等。“Documenting Large Webtext Corpora: A Case Study on the Colossal Clean Crawled Corpus”,arXiv,2021年9月。
  • Gao, Yunfan, 等。“Retrieval-Augmented Generation for Large Language Models: A Survey”,arXiv,2024年3月27日。
  • Hoffmann, Jordan, 等。“Training Compute-Optimal Large Language Models”,arXiv,2022年3月。
  • Kaplan, Jared, 等。“Scaling Laws for Neural Language Models”,arXiv,2020年1月。
  • Lee, Cinoo, 等。“People Who Share Encounters with Racism Are Silenced Online by Humans and Machines, but a Guideline-Reframing Intervention Holds Promise”,《美国国家科学院院刊》121(38):e2322764121(2024年)。
  • LlamaIndex。无日期。“Vector Stores”,访问时间:2025年5月21日。
  • Ma, Yingwei, 等。“At Which Training Stage Does Code Data Help LLMs Reasoning?”,arXiv,2023年9月。
  • Nguyen, Thuat, 等。“CulturaX: A Cleaned, Enormous, and Multilingual Dataset for Large Language Models in 167 Languages”,arXiv,2023年9月。
  • OpenAI平台。无日期。“Vector Embeddings”,访问时间:2025年5月21日。
  • Pemistahl。无日期。lingua-py,访问时间:2025年5月21日。
  • Penedo, Guilherme, 等。“The RefinedWeb Dataset for Falcon LLM: Outperforming Curated Corpora with Web Data, and Web Data Only”,arXiv,2023年6月。
  • Reis, Joe 和 Matt Housley。《数据工程基础》,O’Reilly,2022年。
  • Salley, C., 等。“Providing OLAP to User-Analysts: An IT Mandate”(1998年)。
  • Wang, Zige, 等。“Data Management for Large Language Models: A Survey”,arXiv,2024年8月。
  • WARC规格。无日期。“The WARC Format 1.0”,访问时间:2025年5月21日。
  • Xu, Yipei, 等。“Source Prompt: Coordinated Pre-Training of Language Models on Diverse Corpora from Multiple Sources”,arXiv,2023年11月。
  • Xue, Fuzhao, 等。“To Repeat or Not to Repeat: Insights from Scaling LLM Under Token-Crisis”,arXiv,2023年10月。
  • Yang, Rui, 等。“RAGVA: Engineering Retrieval Augmented Generation-Based Virtual Assistants in Practice”,arXiv,2025年2月。

进一步阅读

  • Gao, Leo, 等。“The Pile: An 800GB Dataset of Diverse Text for Language Modeling”,arXiv,2020年12月。