ML1.6 实现 GPT 并结合 Tokenizer

1. 说明

完整路径

  1. 先实现一个简易 GPT 模型,见:https://pangruitao.com/post/4920
  2. 再学习 Tokenizer 的方法,实现了一个直接基于 BPE 算法的 Tokenizer :https://pangruitao.com/post/4960
    • 训练 Tokenizer 以后,将训练结果保存到文件,供后续 GPT 使用
  3. 修改 GPT 词汇表大小和前后处理,以利用之前训练的 Tokenizer:见本文

2. Jupyter Notebook

gpt_with_tokenizer

3. 备注

加了自己训练的 Tokenizer 以后文本的质量看起来高了不少(相比于之前的按字符编码)。
但是还是存在一些问题:

  1. 过拟合:从 GPT 训练的损失变化可以看出,训练集的拟合一直在变好,但是验证集的情况却在大概 2000 次训练后就有些收敛了
    • 主要因为当前模型参数有 10M,而文本才仅 2M,token后才 1M。
    • 应对的话需要找更多的训练文本
  2. Tokenizer 能达到目的,但运行比较慢
    • 当前仅能运用单核CPU慢慢检索和替换。对实际的超长文本而言,需要切割文本并行处理。
  3. 可以加一些特殊 Token,去达到一些特殊目的
    • 如标记文章结束、回答结束
      • 训练时有利于让模型区分结束前后
      • 推理时可以用于结束的判断
  4. Tokenizer 本身还有很多优化和改良空间/技巧
    • 如 GPT-2 论文里指出的,如果词汇表稍大,由于词频较高,可能会把 ‘dog!’ ‘dog?’ ‘dog.’ 这种看成一个subword,这是不希望的。openai 是通过正则表达式切割不同的字符手动避免的这种情况。
    • 如 LLaMA 做 tokenize 的时候还会运用各种技巧,如把前方带空格的 ‘ dog’ 和不带空格的 ‘dog’ 都当成一个。

发表评论