当大语言模型的基础架构搭建后,如何高效释放其理论潜能成为新的攻坚方向。前几章我们系统剖析了从零构建大语言模型的核心技术路径——这类以Transformer为骨架的深度神经网络,最初专攻自然语言理解与生成,如今已加速向多模态形态演进。然而,当模型规模突破百亿参数量级时,工程层面的挑战已跃升为制约模型效能释放的关键瓶颈。从本章开始,我们将深入大模型工业化落地的工程实践,工程能力是将学术论文中的SOTA指标转化为产业生产力的关键密钥, 这些内容涉及数据收集与处理、并行策略、计算优化、内存管理、稳定训练技术、容错机制等内容。
本篇从数据预处理讲起。
数据是构建大预言模型的根基,没有数据,一切无从谈起。收集大量不同种类和来源的自然语言语料对于创建高效的LLM至关重要。当前的LLM主要使用多个公共文本数据集极其组合作为其预训练语料库。
所使用的预训练数据可以分为两大类:通用数据和专业数据。大多数LLM使用网页、书籍和对话等通用数据作为其预训练语料库,因为这类数据丰富、多样且易于获取,这有助于提高LLM的语言建模和泛化能力。同时,一些LLM使用诸如多语言数据、科学数据等特定领域的数据集,以赋予LLM解决垂直领域问题的能力。除此之外,还有大语言模型自合成数据集。
通用数据源(覆盖广泛领域的基础语料)
- Common Crawl• 最大的开源网页抓取数据集,原始数据达45TB,经严格过滤后保留约15%高质量内容(如C4数据集)。
- 维基百科• 高质量百科全书文本,覆盖多语言和学科领域,常作为模型的起点数据。
- 书籍与期刊• 虚构与非虚构书籍(如Project Gutenberg、Books3)提升模型叙事连贯性。
- 社交媒体与论坛• Reddit、Stack Exchange等问答平台提供真实对话数据,优化模型的指令遵循能力。
垂直领域数据源(专业场景增强)
- 开源代码库• GitHub、GitLab代码数据提升模型逻辑推理能力。
- 科学文献与行业数据• 科学领域:arXiv数学论文、PubMed医学文献,帮助模型处理复杂符号和公式。• 行业数据:法律判决文书、金融报告、医疗记录(需脱敏)提升特定领域适应性。
- 多语言数据• 中文数据如WanJuan、SkyPile-150B(含166万个中文网页),解决非英语语料稀缺问题。• 多语言混合训练(如BLOOM模型)需平衡语言比例,避免方言干扰。
大语言模型自合成数据集(补充性数据源)
由于大型语言模型规模变得越来越大,训练LLM有可能会耗尽我们所拥有的所有数据。目前已有企业选择使用通过LLM的自合成数据进行训练。Cosmopedia 是一个由Mixtral-8x7B-Instruct-v0.1生成,包含教科书、博文、故事、帖子和WikiHow文章的数据集。该数据集包含超过3000万个文件和250亿个tokens,据考证是由HuggingFac用了10k张H100生成的迄今为止最大的开放合成数据集。
上文曾提到,像LLaMa、GPT等模型,会对收集到的预训练数据进行去重、过滤等操作,这是因为原始训练数据集就像开采出来的原油,需要精炼和提纯。
“数据和特征决定了机器学习算法的上限,而模型和算法只是不断逼近这个上限”,这一论断在大语言模型时代依旧成立。当收集了丰富的文本数据之后,为了确保数据的质量和效用,还需要对数据进行清洗,从而消除低质量、冗余、无关甚可能有害的数据,因为”garbage in garbage out“。
数据清洗主要用于过滤低质量或者提取特定任务需要(中文-日文翻译)的数据,而对于数据的质量,不同的文本类型有不同的评判标准。对于网页数据,我们希望网页内容完整,剔除嵌入广告以及多余的HTML元素标签;对于对话数据,我们希望词语连贯,剔除多余的表情(emjoi)符号; 对于代码数据,我们希望剔除多余的非代码、非注释类格式信息等等。
常用的数据清洗包括语种过滤、格式修正、低质量过滤、敏感信息过滤、毒害信息过滤等。
语种过滤
语种过滤,在训练特定目标语言为主导的大语言模型时,通常要过滤掉其他语言的文本数据,比如训练中文大模型时,需要剔除掉其他语种,但需要注意的是,英文开放数据在规模、领域覆盖度及标注规范上具有显著优势(如Common Crawl、Wikipedia等),其结构化程度高且噪声率低,当前双语大模型的技术路线已形成“英文筑基-目标语言精调”的范式,这一策略既能利用英文数据的规模效应,又能通过迁移学习释放目标语言的潜力。
Facebook开源的深度学习工具,支持176种语言,压缩模型仅917KB
import fasttext
model = fasttext.load_model('lid.176.ftz') # 需要提前下载该模型
model.predict("Das ist ein Test") # 输出('__label__de', 0.98)
- 集成了BERT、XLM-R等预训练模型,支持零样本跨语言检测
from transformers import pipeline
classifier = pipeline("text-classification", model="papluca/xlm-roberta-base-language-detection")
classifier("我爱你中国")
输出 [{'label': 'zh', 'score': 0.9751690626144409}]
格式过滤
- 移除 HTML/XML 标签、特殊符号、乱码;
- 统一编码格式(如 针对中文同一使用UTF-8);
- 修复断行、空格等排版问题;
- 保留表格、数学公式等内容形式;
内容过滤
内容过滤用于剔除无效,或信息量低的文本。
- 删除过短文本(如 <100 字符)或长文本中的低信息密度段落。低信息密度段落指文本中有效语义信息占比低的片段,表现为:
- 重复冗余:相同语义的多次重复(如”快来买!立即抢购!现在下单!”)
- 通用模板:适用于任何场景的套话(如”根据相关法律法规…”)
- 情绪填充:大量感叹词/表情符号(如”天啊!!!太棒了😍😍😍”)
- 空洞描述:缺乏具体细节的叙述(如”这个产品非常好用,效果显著”),
可以使信息熵来计算文本的信息度量,Shannon熵公式:
\(H(X)=−∑p(x_i)log2p(x_i)\)
import math
from collections import Counter
def calculate_entropy(text):
# 中英文混合处理
chars = [c for c in text if c.strip()]
freq = Counter(chars)
total = len(chars)
return -sum( (count/total)*math.log2(count/total) for count in freq.values() )
阈值参考:中文:正常文本熵值 3.5-4.8,低于3.0可能为低信息英文:正常文本熵值 4.0-5.0,低于3.5需警惕
- 过滤广告文本(通过重复关键词检测)
- 屏蔽含大量乱码、无意义符号( 比如表情符号)的内容
from langdetect import detect
import re
def clean_short_text(text, min_length=100):
# 基础清洗
text = re.sub(r'\s+', ' ', text).strip()
# 多语言兼容的短文本过滤
if len(text) < min_length:
try:
# 排除有效短文本类型(如诗歌/指令)
if detect(text) in ['zh-cn','ja'] and contains_meaningful_chinese(text):
return text
return None
except: return None
# 长文本低信息密度检测
sentences = [s for s in re.split(r'[.!?。!?]', text) if s]
low_info_count = sum(1 for s in sentences if is_low_info(s))
# 保留高信息密度部分(可调阈值)
if low_info_count / len(sentences) > 0.7:
return " ".join([s for s in sentences if not is_low_info(s)])
return text
def is_low_info(sentence):
"""基于信息熵与停用词比例的混合检测"""
stopword_ratio = sum(1 for w in sentence.split() if w in stopwords) / len(sentence.split())
entropy = calculate_shannon_entropy(sentence)
return stopword_ratio > 0.6 or entropy < 2.5
敏感信息过滤
- 基于预定义黑名单(涉政、暴力、色情等关键词)过滤数据;
- 电话号码,邮箱地址,以及 IP 地址等隐私信息;
内容去重
- 文档级去重(MinHash/LSH 算法检测相似文档)
from datasketch import MinHashLSH
# 初始化LSH索引(相似度阈值0.7)
lsh = MinHashLSH(threshold=0.7, num_perm=128)
def doc_to_minhash(text, num_perm=128):
m = MinHash(num_perm=num_perm)
for word in text.split():
m.update(word.encode('utf-8'))
return m
# 添加文档到索引
documents = ["doc1 text...", "doc2 text..."]
for idx, doc in enumerate(documents):
mh = doc_to_minhash(doc)
lsh.insert(f"doc_{idx}", mh)
# 查询相似文档
query_doc = "query text..."
query_hash = doc_to_minhash(query_doc)
result = lsh.query(query_hash) # 返回相似文档ID列表
- 段落级去重(13-gram 重复字符 >50% 时剔除,与论文方法类似);
- 句子级别去重,删除包含重复单词和短语的低质量句子;
- 模糊去重,语义相似度检测(如 SimHash)避免近义重复;
毒性模型检测
- 使用类似 FastText 的分类器评估文本毒性;
from transformers import pipeline
# 加载模型
classifier = pipeline("text-classification", model="unitary/toxic-bert")
# 检测结果
print(classifier("This is an explicit threat."))
以上,数据清洗的基本流程。下面我们继续讨论,在实际生产场景,如何高效的处理大规模/超大规模数据集。