2026/2/14 10:32:56
网站建设
项目流程
做简单视频网站自己看,建站程序选择,用dw做音乐网站,高级前端开发在线培训本文不讨论模型结构#xff0c;而只回答一个看似简单、但极其关键的问题#xff1a; 大语言模型#xff08;LLM#xff09;训练时#xff0c;究竟在“吃”什么样的数据#xff1f;这些数据是如何被构造出来的#xff1f; 在之前的文章中#xff08;【LLM基础教程】从…本文不讨论模型结构而只回答一个看似简单、但极其关键的问题大语言模型LLM训练时究竟在“吃”什么样的数据这些数据是如何被构造出来的 在之前的文章中【LLM基础教程】从序列切分到上下文窗口02_三种数据切分方法我们讨论了序列建模中的数据切分策略滑动窗口、随机采样、顺序采样那更多发生在DataLoader / 序列级别。而当模型规模上升到 LLM 之后数据问题会整体上移一个层级从“怎么切序列”变成了“怎么组织 token 级别的训练样本”。 本文将系统梳理 LLM 训练数据集的构造流程并刻意与传统 RNN / 小模型的数据加载方式做区分。一、先澄清一个常见误解LLM 并不是在“读文章” 从人类直觉出发我们很容易认为模型是不是一篇一篇地读文档、学会理解整篇文章 但在实际训练中LLM 并不知道什么是“文章”或“段落”。对模型来说最小单位是token唯一训练目标是next-token prediction模型真正看到的是这样的形式[ t 0 , t 1 , ⋯ , t k − 1 ] → t k [t_0, t_1, \cdots, t_{k-1}] \to t_k[t0,t1,⋯,tk−1]→tk无论这些 token 原本来自同一篇文章不同文章甚至不同语种在模型眼中它们只是一个有限长度的 token 序列。二、为什么 LLM 不能使用 stride1 的滑动窗口为什么在 LLM 规模下“理论上正确”的滑动窗口在工程上彻底不可行2.1 Attention 复杂度被放大 Transformer 的核心是 Attention其计算复杂度为O ( n 2 ) O(n^2)O(n2) 如果使用stride1的滑动窗口同一个 token 会被反复参与 attention 计算上下文高度重叠单位 token 的有效梯度贡献迅速下降换句话说算力被浪费在大量重复上下文上。2.2 LLM 的工程目标已经发生变化 在 LLM 训练中更重要的不是是否覆盖所有可能的上下文窗口。而是在有限算力下让尽可能多的不同 token被“看到一次”。 因此LLM 的核心数据目标是最大化 token throughput而不是样本数量。三、从文档到 Token BlockLLM 的真实数据流水线 从原始语料到模型真正使用的数据LLM 的训练数据通常会经历如下流水线 下面我们沿着这条流水线逐步拆解。3.1 Dataset 阶段先把“文档”变成“高价值 token” 在 LLM 中数据处理的第一步发生在Dataset 构建阶段而不是训练时。常见操作包括文档清洗HTML、乱码、模板语言过滤去重exact / fuzzy长度裁剪这些步骤的目标只有一个提高“每一个 token 的训练价值”。此阶段的输出仍然是文档集合尚未转化为模型可以直接消费的训练样本。3.2 Tokenize 之后文档边界为什么会消失 经过 tokenizer 后每篇文档会被转换为 token ID 序列。 此时系统往往会做一件非常“反直觉”的事情不再强行保留文档边界。多个文档的 token 会被拼接成一个或多个长 token 流token streamDoc A tokens | Doc B tokens | Doc C tokens | ...原因很简单模型并不具备“文档”这一概念只感知 token 序列强行保留边界会导致大量 padding从而显著降低 token 利用率从这一刻开始“文档”这一人类语义单位正式退出训练视角。3.3 切 blocknum_steps 思想在 LLM 中的升级版 接下来系统会将长 token 流切分为固定长度的 token blockblock_sizecontext_window#e.g. 4096 / 8192切分方式通常是不重叠顺序切分[t0... t4095][t4096... t8191]...这一步本质上对应我们在RNN 中熟悉的num_steps T只是切分的位置从DataLoader上移到了Dataset 构建阶段。这一变化并非算法思想的转变而是工程规模的必然结果LLM 的训练语料规模达到 TB / PB 级训练通常运行在大规模分布式系统中训练时动态切分长文本会成为严重的 I/O 和计算瓶颈因此LLM 选择将序列切分这一高频、确定性的操作提前固化到 Dataset 构建阶段从而提高 token 吞吐率降低训练阶段的系统复杂度保证大规模并行训练的稳定性3.4 Packed Sequence提高 token 利用率的关键技巧Packed sequence 并不是把多篇文档“混在一起训练”而是通过 attention mask在同一个 block 内并行训练多条彼此独立的序列从而最大化 token 利用率。 现实中文档长度往往无法整除block_size如果处理不当将造成大量算力浪费。(1) padding到底浪费了什么 假设block_size 16有三篇文档token 长度分别是Doc A:10tokens Doc B:4tokens Doc C:6tokens如果不做 packed sequence而是“一篇文档一个 block”Block1:[A A A A A A A A A A PAD PAD PAD PAD PAD PAD]Block2:[B B B B PAD PAD PAD PAD PAD PAD PAD PAD PAD PAD PAD PAD]Block3:[C C C C C C PAD PAD PAD PAD PAD PAD PAD PAD PAD PAD]问题在于每个block都在计算attention大量 token 是 PADPAD token没有任何训练价值attention 复杂度是KaTeX parse error: Expected EOF, got _ at position 24: …{O}(\text{block_̲size}^2)PAD 也会参与计算算力被浪费在“空位置”上这在 LLM 里是不可接受的。(2) 不能把不同文档拼在一起吗 你可能会自然地问那我把 Doc A、B、C 直接拼起来不就好了** 比如[A A A A A A A A A A | B B B B | C C]**问题来了**如果什么都不做模型会认为Doc B 的 token可以 attend 到 Doc A 的 tokenDoc C 的 token可以 attend 到 Doc A、B 的 token这意味着模型在学习“一篇文章的结尾逻辑上可以接另一篇完全无关的文章”这显然是错误的上下文假设。(3) Packed Sequence 真正在做什么 Packed sequence 的核心不是“拼接”而是物理上拼在一起逻辑上彼此隔离。在构造 block 时Block: [DocA_tail | DocB_head | DocC_head]这样做可以填满 block避免 padding提高 token 密度真正起作用的是attention maskDoc A 的 token❌ 看不到 Doc B / CDoc B 的 token❌ 看不到 Doc A❌ 看不到 Doc CDoc C 的 token❌ 看不到 Doc A / B用“视野”来理解就是Doc A tokens: [只能看到 A] Doc B tokens: [只能看到 B] Doc C tokens: [只能看到 C]它们处在同一个 block 中但在 attention 里是多条完全独立的序列。(4) 为什么这一步如此重要 Packed sequence 同时解决了三个 LLM 级别的问题token 利用率几乎没有 padding每个 attention 计算都在“算有效 token”吞吐率throughputattention 复杂度不变单位算力学习到的 token 数显著增加不破坏语言建模假设next-token prediction 仍然成立不会引入“跨文档胡乱接话”的错误信号 如果说切 block 解决的是「序列长度如何规模化」那么 packed sequence 解决的就是「如何不浪费每一个算出来的 attention」3.5 随机性从哪里来 在前面的文章里我们讲过随机采样random sampling的核心目的是为了打破样本之间的强相关性。 在 LLM 中随机性不再通过滑动窗口制造而是通过文档、token 与 block 的多层 shuffle 实现目标始终只有一个避免模型被局部顺序强相关性主导。文档级 shuffleDataset 构建时在 tokenize 之前或之后文档顺序会被打乱多语料源会被混合于是 token 流本身就已经是“非连续语义”的。在 LLM 预训练中✅会打乱Doc A / Doc B / Doc C 的出现顺序❌不会打乱Doc A 内部 token 的顺序假设你有三个文档Doc A: [a1 a2 a3 a4] Doc B: [b1 b2 b3] Doc C: [c1 c2 c3 c4 c5]Dataset 层面会做的是[A, B, C] → [C, A, B]即这一步只改变文档之间的相对位置而每个文档内部 token 顺序严格保持next-token 预测仍然合法Token block 级 shuffle训练时即使 block 是顺序切的Block 1: [t0 ... t4095] Block 2: [t4096 ... t8191] Block 3: [t8192 ...]在真正送进模型前Block 17 Block 3 Block 204 Block 58 ...模型看到的 block 顺序是随机的而不是原始文本顺序。多 epoch 的重新混合每一轮训练文档会重新 shuffleblock 重新排列packed sequence 重新组合于是同一个 token在不同 epoch 中往往会和“不同的邻居”一起出现。这正是 LLM 版的“随机采样”。四、训练 vs 推理为什么你“感觉”模型是顺序的 一个非常容易被忽略的事实是阶段数据形态核心目标训练并行、打乱的 token blocktoken 吞吐最大化推理严格顺序 token连贯生成推理阶段通过KV Cache避免重复计算历史 token表现得“像顺序采样”但这是一种系统级优化而不是训练数据的构造方式。五、结语 当你真正理解这一点语言模型训练本质上是在用有限上下文近似学习无限长序列的统计规律 你就会发现无论是 RNN 时代的num_steps还是 LLM 时代的 token block本质上解决的都是同一个问题。