训练
- 语料
- 本站术语表 15,307 个字节
- 合并规则
- 300 GPT-2 50,000
- 起点
- 256 个字节符号
全部步骤
从字节开始
分词器在模型之前就从文本中学出来。这里的文本是本站的英文术语表:15,307 个字节,预切分成 3,216 个词。训练从每个字节一个符号开始:共 256 个,没有任何未知符号。
15,307 个字节 · 词表 256统计每一对相邻符号
统计每一对相邻符号出现的次数,只在词内部统计,并按每个词出现的次数加权。这里最常见的一对是 Ġ + t,共 426 次。
在词内部统计相邻对合并最常见的一对,重复
把这一对在所有地方替换成一个新符号,加入词表,然后重新计数。每次合并就是一条规则,按顺序保存。随着 300 条合并规则被学出,看示例词如何从字节合成更大的片段。
300 次合并 · 词表 556词表大小与序列长度
合并越多,每个词的词元越少,同样的上下文就能装下更多文本;但每个新词元都需要在嵌入矩阵和输出层中各占一行。GPT-2 停在 50,000 次合并;LLaMA 3 大约有 128,000 个词元。
每词更少的词元 vs 更大的词表GPT-2 的合并规则
GPT-2 的前几条合并规则(来自它真实的 merges.txt,在 40 GB 网页文本上学出)开头和我们的很像:空格与常见字母相连,“h e”、“i n”。编码一个新词时就按这个顺序重放合并。
GPT-2:50,000 次合并,50,257 个词元
代码
words = Counter(regex.findall(PAT, text)) # pre-split, counted
vocab = {w: tuple(w.encode()) for w in words} # every word as bytes
merges = []
for _ in range(num_merges):
pairs = Counter()
for w, n in words.items():
for a, b in zip(vocab[w], vocab[w][1:]): pairs[a, b] += n
best = max(pairs, key=pairs.get)
merges.append(best) # the rule, in order
vocab = {w: merge(s, best) for w, s in vocab.items()}