CS336: Language Models From Scratch (Spring 2025)

0.开场白

为什么要从基础的角度学习大模型?我们可以用prompt操纵训练好的模型,但直接使用毕竟是高度抽象的,我们有必要深入了解其实现细节。想要理解大模型,最好的方法就是重建一个大模型。

我们自制的小模型是否有效果?不一定,因为参数量的不同,不同的层(如MLP,MHA)的计算量大不相同,我们的所做的优化在参数扩大后不一定起作用。另外,模型存在“涌现”现象,在计算量达到一定量后,模型的表现会突然变好,所以模型必须有一定的参数量。

这门课的重点是什么?1.全面从底层了解大模型;2.给定计算资源和时间限制,明白怎么去高效的训练模型。


1.课程主要内容

1.1Basics

得到一个能运行的简易pipeline,包括tokenizer(BPE算法)、model architecture(Transformer架构及其各个组件)、training(优化器、学习率等等)。

1.2Systems

如何进一步优化。kernels(数据在内存和GPU之间的传送)、parallelism(多卡训练)、inference(使用模型)

1.3scaling laws

FLOPs和模型参量量,和训练使用token量成线性关系。

1.4data

如何选择并处理数据、如何进行模型评估

1.5alignment

将基础模型进行对齐,让其学会follow instructions、具有一定风格、避免输出有害内容。包括SFT、RLHF。


2.Tokenization

模型只能对数值进行运算,而人类需要自然语言进行输入输出。tokenizer就是负责将自然语言(string)转换为tokens(list(int)),以便传入模型。

一个训练好的tokenizer可以对句子进行编码,可以将数组解码回句子。

compress_ratio:字节数/token数,它表示一个token平均对应几个字节。

以下是tokenizer曾使用过的方法:

chatacter_tokenizer:一个简单的想法是:将每个字符直接转换为对应的Unicode。

Unicode是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。

这样做可行,但是token对应的数值范围会变得非常大;而且有很多字符并不常用,存在稀疏的问题。

byte_tokenizer:那么,也可以将句子全部转换为字节。英文字母对应一个字节,有些emoji(:earth_asia:)则对应四个字节。如果使用UTF-8编码,所有的数值都会限制在0-255之间。数值大、稀疏的问题解决了,但是token序列会很长。

word-based tokenization:将句子分为单词,然后对单词编码。但是,单词是无上限的,而且无法处理写错单词(UNK)的情况。

BPE:现在最常用的方法,最早应用于GPT-2。先使用word-based tokenization将句子进行粗略的拆分,然后在每一个分块上使用BPE算法。BPE算法可以简单理解为:把常用的字符组进行聚合,使用一个token表示;不常用的则用多个token表示。

BPE原理及实现:minbpe:BPE算法的极简实现