大模型训练第一步:数据准备全流程与工程实践

发布时间:2026/10/20 9:07:09
大模型训练第一步:数据准备全流程与工程实践 1. 大模型训练第一步到底在干什么很多人第一次接触大模型训练脑子里浮现的画面是一排排显卡嗡嗡作响然后模型就“变聪明”了。实际上在显卡真正开始跑之前有一件更枯燥、更耗时、也更容易被低估的事情——数据准备。我见过不少团队模型结构调了三个月loss 曲线还是不收敛最后发现问题出在数据上要么脏得离谱要么格式乱七八糟要么量根本不够。所以这个系列的第一篇我想把数据准备这件事掰开揉碎讲清楚。所谓 LLM 的数据准备说白了就是把互联网上、书籍里、代码仓库中那些原始文本经过采集、清洗、去重、过滤、配比、分词、打包这一整套流程变成模型能“吃”的 token 序列。它解决的核心问题是让模型在有限算力下见到尽可能高质量、多样化、无重复的语言样本。这件事适合谁看如果你是刚入行做算法工程的同学或者想自己动手训一个小模型练手的开发者又或者你只是好奇 ChatGPT 这类东西背后的数据从哪来这篇都能给你一个能落地的全景图。我个人的经验是数据准备阶段的工作量往往占到整个训练项目的六成以上。而且它不像调模型那样有即时反馈你清洗了一周数据可能指标只涨了零点几个点但如果不做模型直接废掉。下面我按实际工程顺序把这条链路完整走一遍。2. 数据来源与采集原料从哪来2.1 常见语料类型与各自特点大模型的“食物”大致分几类每类的处理难度和用途都不一样。我整理了一张表方便你对照理解。语料类型典型来源优点主要问题网页文本公开网页抓取量大、覆盖广、时效新噪声多、广告多、重复高书籍文献电子书、论文语言规范、逻辑连贯版权敏感、格式复杂代码仓库开源代码托管平台结构强、利于推理能力注释混杂、许可证问题问答社区技术论坛、问答站口语化、贴近真实对话质量参差、水帖多百科类在线百科事实性强、中立量相对有限网页文本是绝对主力通常占到一个通用大模型预训练语料的七八成。但它的脏也是出了名的导航栏、版权声明、弹窗文字、乱码、外链堆砌全混在一起。书籍和论文质量高但获取和清洗成本大而且版权是个绕不开的坎实际项目中要么用已授权数据要么用公开版权过期的内容。代码数据这几年越来越受重视因为它能显著提升模型的逻辑推理和结构化输出能力很多团队会专门配比百分之十到二十的代码语料。2.2 采集环节的实操要点采集不是简单地“把网页存下来”。我踩过的坑里最常见的就是采集频率和礼貌性问题。你如果对一个站点疯狂发请求轻则被封 IP重则收到警告。合理的做法是控制并发、加延迟、遵守站点的 robots 协议。虽然我们是做技术但基本的规矩要守。另一个要点是原始数据的留存格式。我建议采集阶段就统一存成 JSONL每行一条记录字段至少包含url、timestamp、raw_html、text。为什么要留raw_html因为后面清洗规则可能会变如果你只存了提取后的文本想重新提取就得再抓一遍成本极高。留一份原始快照等于给自己留了后悔药。提示采集阶段一定要记录来源 URL 和时间戳后面做去重、质量过滤、溯源都靠它。没有这两个字段数据基本等于废料。还有一点采集要分批次、分来源打标签。比如这批是新闻站那批是论坛标签留着后面做数据配比时用。我见过有人把所有来源混成一锅粥最后想调整某个领域的比例根本无从下手。3. 数据清洗把垃圾挡在门外3.1 清洗的核心目标与优先级清洗的目标不是把数据洗得“完美”而是在保留语言多样性的前提下去掉明显有害和无用的部分。这里有个误区很多人追求极致干净结果把口语化、带点错别字但很自然的表达也洗掉了模型反而变得死板。所以清洗要有优先级。我的优先级排序是先去掉完全无意义的乱码、纯符号再去掉明显有害的违规内容、垃圾广告然后处理格式问题HTML 残留、多余空白最后才考虑语言层面的规整。顺序不能乱否则你会在细节上浪费大量时间。3.2 具体清洗步骤与代码示例第一步是HTML 解析与正文提取。原始网页里真正有用的正文可能只占百分之十几。常用的做法是用解析库把 DOM 树建出来然后根据标签密度、文本长度等启发式规则定位正文块。下面是一个简化示例from bs4 import BeautifulSoup import re def extract_main_text(html): soup BeautifulSoup(html, html.parser) # 去掉脚本、样式、导航等明显非正文标签 for tag in soup([script, style, nav, footer, header, aside]): tag.decompose() # 取所有段落文本 paragraphs soup.find_all(p) text \n.join(p.get_text() for p in paragraphs) # 压缩多余空白 text re.sub(r\s, , text).strip() return text这段代码很粗糙但能过滤掉大部分噪声。实际工程中会用更复杂的正文提取算法比如基于文本密度的打分或者用训练好的小模型来判断哪块是正文。第二步是去重。去重分三个层次完全重复、近似重复、模板重复。完全重复用哈希就行一行hashlib.md5(text.encode()).hexdigest()搞定。近似重复要用 MinHash 或 SimHash计算文档间的相似度超过阈值就保留一份。模板重复最隐蔽比如同一个新闻站的不同页面正文不同但页脚、免责声明一模一样这种要在句子级别做去重。from datasketch import MinHash, MinHashLSH def get_minhash(text, num_perm128): m MinHash(num_permnum_perm) for token in set(text.split()): m.update(token.encode(utf8)) return m lsh MinHashLSH(threshold0.8, num_perm128) # 对每篇文档计算 minhash 并插入查询时能快速找到近似重复第三步是质量过滤。这一步决定数据的天花板。常见的过滤规则包括文本长度过短或过长都剔除、符号与字母比例异常剔除、包含大量重复字符剔除、语言检测非目标语言剔除。我一般会设一个“困惑度”阈值用一个小型语言模型给每段文本打分困惑度太高的说明语言不通顺直接扔掉。注意质量过滤的阈值不要一刀切。代码数据和自然语言的统计特征完全不同要分开设规则。我见过有人用同一套规则过滤代码结果把大量正常代码当垃圾扔了。3.3 清洗中的常见陷阱第一个陷阱是过度清洗导致数据同质化。如果你把所有口语、方言、网络用语都过滤掉模型就学不会这些表达生成的内容会非常“新闻联播”。所以清洗规则要留有余地宁可保留一点噪声也不要误杀多样性。第二个陷阱是忽略编码问题。网页编码五花八门UTF-8、GBK、Latin-1 混在一起处理不当就会出现乱码。我的做法是统一转成 UTF-8遇到无法解码的字符用替换策略而不是直接丢弃整篇文档。第三个陷阱是清洗顺序错误。比如你先做了语言检测但文本里还残留 HTML 标签检测结果就会偏。正确的顺序是解析正文 → 去重 → 基础清洗 → 质量过滤 → 语言检测。每一步都建立在上一步干净的基础上。4. 数据配比与格式化让模型营养均衡4.1 为什么要做数据配比数据配比是很多人忽略但极其关键的一步。你手里可能有网页、书籍、代码、问答四类数据如果直接按采集量混在一起网页可能占九成模型就会变成一个“网页复读机”代码能力和对话能力都很差。配比的目的就是人为控制不同领域数据的比例让模型各项能力均衡发展。业界常见的通用模型配比大致是网页文本六到七成书籍和论文一成到一成五代码一成到两成问答和对话数据半成到一成。这不是铁律要根据你的目标调整。如果你想要一个编程助手代码比例可以拉到三成以上如果想要一个客服机器人对话数据就要加重。4.2 配比的计算与采样方法配比不是简单地把数据按比例抽出来混合因为不同来源的数据量差异巨大。实际操作中我们通常先给每个来源定一个“目标 token 数”然后从该来源中采样出对应数量。假设总目标是一万亿 token网页占 65%那就是六千五百亿。如果网页清洗后有两万亿 token你就需要从中随机采样六千五百亿。采样时要注意分层采样比如按域名、按时间、按语言分层避免某个大站点的数据垄断整个网页部分。import random def sample_by_target(docs, target_tokens, tokenizer): random.shuffle(docs) selected [] total 0 for doc in docs: n len(tokenizer.encode(doc[text])) if total n target_tokens: break selected.append(doc) total n return selected这段代码是简化版实际中还要考虑去重后的唯一性、各子领域的配额等。我一般会维护一个配比表每类数据设上下限采样时动态调整。4.3 格式化与分词打包数据配比完成后要转成模型训练需要的格式。现在主流做法是先把所有文本拼成一个超长的 token 流然后按固定长度切块。比如设定序列长度 4096就把 token 流每 4096 个切一段。这样做的好处是没有 padding 浪费训练效率最高。但拼接也有讲究。不同文档之间要加分隔符比如|endoftext|让模型知道这里换文档了。否则模型会把上一篇的结尾和下一篇的开头当成连续内容学出奇怪的关联。def pack_tokens(docs, tokenizer, seq_len4096, eos_token|endoftext|): buffer [] for doc in docs: ids tokenizer.encode(doc[text]) buffer.extend(ids) buffer.append(tokenizer.encode(eos_token)[0]) while len(buffer) seq_len: yield buffer[:seq_len] buffer buffer[seq_len:]分词器的选择也很关键。中文场景下词表大小、是否支持多语言、对代码的切分效果都要考虑。我一般会先用小规模数据训一个分词器看看压缩率平均每个 token 对应多少字符压缩率太低说明词表不合适训练成本会飙升。提示打包前一定要做一次全局 shuffle。如果数据是按来源顺序排列的打包后每个 batch 可能全是同一类数据训练时 loss 会剧烈震荡。5. 实操全流程与参数记录5.1 一条完整的数据流水线把前面几步串起来一条典型的数据流水线是这样的采集从多个来源抓取原始数据存为 JSONL保留 URL 和时间戳。正文提取解析 HTML提取正文去掉导航、广告等。基础清洗统一编码去除乱码、控制字符、多余空白。去重完全重复用哈希近似重复用 MinHash句子级模板去重。质量过滤长度、符号比例、困惑度、语言检测多重过滤。敏感与有害内容过滤按规则和分类器剔除违规内容。配比采样按目标比例从各来源采样。分词打包训练或加载分词器转成 token 流按序列长度切块。全局 shuffle打乱顺序写入最终训练文件。每一步都要有日志和统计。我习惯在每一步后输出一份报告输入多少条、输出多少条、剔除了多少、剔除原因分布。这份报告在排查问题时价值巨大。5.2 关键参数的计算与选择序列长度怎么定这取决于你的算力和目标。序列越长模型能处理的上下文越长但显存和计算量是平方级增长。一般预训练阶段用 2048 到 8192 之间。我个人的经验是如果算力有限先用 2048 跑通流程后面再逐步加长。词表大小怎么定太小会导致一个词被切成很多 token序列变长太大则 embedding 层参数多训练慢。中文为主的模型词表通常在五万到十万之间。可以用 BPE 或 Unigram 算法在采样数据上训练看压缩率来调。去重阈值怎么定MinHash 的相似度阈值一般设在 0.7 到 0.9 之间。太低会误删不同文档太高则去重不彻底。我一般先用小样本人工检查确定一个合理值再全量跑。5.3 实操现场记录我拿一个模拟项目举例。假设我们要为一个中文通用模型准备五百亿 token 的预训练数据。采集阶段拿到约两亿条网页记录原始体积约 2TB。正文提取后剩 1.2TB去重后剩 800GB质量过滤后剩 600GB。按配比采样网页取 65%书籍 15%代码 15%问答 5%。分词后统计平均压缩率约 1.5 字符每 token最终得到约五百亿 token。整个过程在一台 32 核机器上跑了大约三天瓶颈在去重和困惑度计算。这个过程中最大的坑是内存。MinHash 去重如果全量加载内存直接爆掉。解决办法是分片处理每片算完 MinHash 后只保留签名再合并。困惑度计算也是要批量推理不能一条条来。6. 常见问题与排查技巧实录6.1 数据准备高频问题速查表问题现象可能原因排查与解决模型 loss 不降数据太脏或重复太多检查去重率、质量过滤报告生成内容重复训练数据模板重复高加强句子级去重模型只会说一种风格数据同质化严重调整配比增加多样性来源训练速度慢序列 padding 多改用 token 流打包中文输出乱码编码未统一全量转 UTF-8检查分词器代码能力差代码语料比例低提高代码数据占比显存溢出序列过长或 batch 过大降低序列长度或梯度累积6.2 独家避坑技巧第一个技巧先小后大。不要一上来就处理全量数据。先抽一万条跑通全流程看看每一步的输出是否符合预期再放大到全量。我见过太多人直接跑全量跑到一半发现规则有问题三天白干。第二个技巧保留中间产物。每一步的输出都存下来哪怕占空间。因为后面调参时你可能需要回到某一步重新处理如果中间产物没了就得从头再来。第三个技巧人工抽检。自动化指标再好看也要定期人工看样本。我一般每个阶段随机抽一百条逐条读看看有没有奇怪的残留。机器判断不了的语义问题只有人眼能发现。第四个技巧版本化管理。数据流水线的每一步都要有版本号配置文件、代码、输出都要对应。否则你改了规则却忘了哪份数据是用哪版规则生成的实验无法复现。注意数据准备阶段最忌讳“差不多就行”。这里的每一个疏忽都会在训练阶段被放大成几倍的时间浪费。宁可前期慢一点也不要后期返工。6.3 一个真实的排查案例某次实验模型训练到一半 loss 突然飙升。排查后发现是数据流水线在某个批次混入了一批未清洗的原始 HTML里面全是标签和脚本。原因是那批数据的来源标签写错了被错误地跳过了清洗步骤。解决办法是加一道校验任何进入训练文件的样本都要通过一个“最小质量检查”比如不能包含连续的特殊符号、不能有 HTML 标签残留。这个检查很便宜但能挡住大部分低级错误。这件事给我的教训是流水线的每一步都要有防御性校验不能假设上游一定正确。数据工程和写代码一样边界情况永远比你想的多。7. 数据质量评估与迭代7.1 怎么判断数据准备得好不好数据准备不是一次性的而是一个迭代过程。评估数据质量我一般看几个指标去重率、平均长度分布、语言分布、困惑度分布、各来源占比。这些指标要和你的目标对齐。比如目标是一个中文模型那中文占比就应该在九成以上如果发现英文占了三成说明语言过滤有问题。除了统计指标还要做下游任务验证。最直接的办法是用一小部分数据训一个微型模型看它在几个基准任务上的表现。如果微型模型表现异常大概率是数据问题。这个方法成本不高但能提前暴露大问题。7.2 迭代优化的方向数据准备的迭代通常围绕几个方向提高质量、增加多样性、修正配比、降低成本。提高质量可以引入更强的分类器来过滤增加多样性可以拓展来源修正配比要根据下游表现调整降低成本则靠优化流水线效率比如用分布式处理去重。我个人的习惯是每轮训练后都回头看看数据报告找出表现最差的领域针对性地补充或清洗那部分数据。这个过程可能重复很多轮但每一轮都会让模型更稳。数据准备这件事说到底就是用工程手段把混乱的原始信息变成有序的训练信号。它没有模型结构那么光鲜但决定了模型的上限。你把数据这关过了后面的训练才有意义。下一篇我会接着讲模型结构设计和训练策略那是另一个同样深不见底的坑。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询