1788 字
9 分钟
[CS336] A1 Chapter 7 Experiments

7 Experiments#

现在是时候将所有内容整合起来,并在预训练数据集上训练小型语言模型了。

7.1 How to Run Experiments and Deliverables#

要理解 Transformer 架构组件背后的原理,最好的方法就是实际对其进行修改并自行运行。亲自动手实践是无可替代的。

为此,能够迅速、持续地进行实验并记录所做操作非常重要。为了能够迅速进行实验,我们将在一个小型模型(约 1700 万个总参数)和简单的数据集(TinyStories)上进行多次实验。为了保持一致性,您需要逐步去除组件并以系统的方式调整超参数,并且为了记录结果,我们将要求您提交实验的日志以及与每个实验相关的学习曲线。

为了能够提交损失曲线,请确保定期评估验证损失,并记录步骤数量和实际运行时间。您可能会发现诸如 Weights and Biases 这样的日志记录基础设施很有帮助。


Problem (experiment_log): Experiment logging

对于您的训练和评估代码,构建实验跟踪基础设施,以便能够根据梯度步数和实际运行时间来跟踪您的实验和损失曲线。


7.2 TinyStories#

我们将从一个非常简单的数据集(TinyStories)开始,在这个数据集上,模型的训练速度会很快,而且我们还能观察到一些有趣的现象。获取该数据集的说明内容在第 1 节中。下面就是这个数据集的示例情况。


Example (tinystories_example): One example from TinyStories

Once upon a time there was a little boy named Ben. Ben loved to explore the world around him. He saw many amazing things, like beautiful vases that were on display in a store. One day, Ben was walking through the store when he came across a very special vase. When Ben saw it he was amazed! He said, “Wow, that is a really amazing vase! Can I buy it?” The shopkeeper smiled and said, “Of course you can. You can take it home and show all your friends how amazing it is!” So Ben took the vase home and he was so proud of it! He called his friends over and showed them the amazing vase. All his friends thought the vase was beautiful and couldn’t believe how lucky Ben was. And that’s how Ben found an amazing vase in the store!


7.2.1 Hyperparameter tuning#

我们将向您介绍一些初始阶段的非常基础的超参数,并请您为其他参数找到一些适用的设置。

Vocab size 10000。典型的词汇量大小在数万到数十万之间。您应该对此进行调整,并观察词汇量和模型表现的变化情况。

Context length 为 256。对于诸如 TinyStories 这样的简单数据集,可能不需要太长的序列长度,但对于后续的 OpenWebText 数据集,您可能需要对此进行调整。尝试对此进行调整,并观察其对每次迭代的运行时间和最终困惑度的影响。

d_model 512。这比许多小型 Transformer 论文中使用的 768 个维度略小,但会使运算速度加快。

d_ff 1344。这大约是 83dmodel\frac{8}{3}d_{model},同时是 64 的倍数,这有利于 GPU 性能。

RoPE theta 参数 10000。

Layers 和 heads 为 4 层,16 个头。这样总共将有约 1700 万个非嵌入参数,这是一个相当小的 Transformer。

处理的总 token 数 为 327,680,000(您的 batch size × 总步数 × context length 应大致等于这个值)。

您应该进行一些试验和调整,以找到以下其他超参数的良好默认值:学习率学习率预热、其他 AdamW 的超参数(β1\beta_1β2\beta_2ϵ\epsilon)以及权重衰减。您可以在其中找到一些此类超参数的典型设置方案。

7.2.2 Putting it together#

现在,您可以将所有内容整合在一起,即获取一个经过训练的 BPE 分词器,对训练数据集进行分词,并在您编写的训练循环中运行它。

重要提示:如果您的实现是正确且高效的,上述超参数应能在 1 个 H100 GPU 上运行约 30 至 40 分钟。如果您运行时间过长,请检查并确保您的数据加载、检查点保存或验证损失代码没有成为您运行时间的瓶颈,并且您的实现已正确进行批处理。

7.2.3 Tips and tricks for debugging model architectures#

我们强烈建议您熟练掌握您所使用的集成开发环境(IDE)自带的调试器(例如 VSCode/Zed),因为与使用打印语句进行调试相比,使用内置调试器能节省您大量时间。如果您使用的是文本编辑器,可以使用像 ipdb 这样的工具。在调试模型架构时,还有一些其他的好习惯:

  • 在开发任何神经网络架构时,一个常见的第一步是将模型过度拟合到单个小批量数据上。如果 您的实现是正确的,您应该能够迅速将训练损失降低至接近零的水平。
  • 在模型的各个组件中设置调试断点,并检查中间张量的形状,以确保它们符合您的预期。
  • 监控激活值、模型权重和梯度的范数,以确保它们不会出现爆炸或消失的情况。

现在让我们改变 batch size,看看这会对训练过程产生什么影响。Batch size 非常重要——它能让我们通过进行更大的矩阵乘法来从 GPU 中获得更高的效率,但是否真的意味着我们总是希望 batch size 很大呢?让我们进行一些实验来找出答案。


Problem (batch_size_experiment): Batch size variations (2 H100 hrs)

将 batch size 从 1 一直调整到 GPU 内存上限的值。至少尝试几个介于两者之间的批次大小,比如常见的 64 和 128 这样的值。


有了你的解码器,我们现在就可以生成文本了!我们将根据模型生成内容,并看看效果如何。作为参考,您应该得到的输出至少要和下面的示例一样好。


Example (ts_generate_example): Sample output from a TinyStories language model

Once upon a time, there was a pretty girl named Lily. She loved to eat gum, especially the big black one. One day, Lily’s mom asked her to help cook dinner. Lily was so excited! She loved to help her mom. Lily’s mom made a big pot of soup for dinner. Lily was so happy and said, “Thank you, Mommy! I love you.” She helped her mom pour the soup into a big bowl. After dinner, Lily’s mom made some yummy soup. Lily loved it! She said, “Thank you, Mommy! This soup is so yummy!” Her mom smiled and said, “I’m glad you like it, Lily.” They finished cooking and continued to cook together. The end.


以下是确切的问题陈述以及我们所要求的内容:


Problem (generate): Generate text

使用您的解码器和您训练好的检查点,报告由您的模型生成的文本。您可能需要调整解码器的参数(如温度、top-p 等)以获得流畅的输出。

交付内容:至少 256 个“token”长度的文本(或者直到出现第一个 <|endoftext|>)的文本摘要,以及对这一输出的流畅性的一段简短评论,以及至少两个影响该输出好坏程度的因素。


[CS336] A1 Chapter 7 Experiments
https://lettle.cn/posts/7-experiments/
作者
Lettle
发布于
2026-05-29
许可协议
CC BY-NC-SA 4.0