60行NumPy手搓GPT( 五 )


main函数主要处理:
fire.Fire(main)将我们的源文件转成一个命令行应用 , 然后就可以像这样运行我们的代码了: gpt2.py "somehere"
我们先在或者交互界面下看看, ,  , 运行:

from utils import load_encoder_hparams_and_paramsencoder, hparams, params = load_encoder_hparams_and_params("124M", "models")
上述代码将下载必要的模型及分词器文件[36]至/124M , 并且加载``,``,``[37] 。
编码器
我们的使用的是GPT-2中使用的BPE分词器:

>>> ids = encoder.encode("Not all heroes wear capes.")>>> ids[3673, 477, 10281, 5806, 1451, 274, 13]>>> encoder.decode(ids)"Not all heroes wear capes."
使用分词器的词汇表(存储于.) , 我们可以看看实际的token到底长啥样:

>>> [encoder.decoder[i] for i in ids]['Not', '?all', '?heroes', '?wear', '?cap', 'es', '.']
注意 , 有的时候我们的token是单词(比如:Not) , 有的时候虽然也是单词 , 但是可能会有一个空格在它前面(比如?all, `?`代表一个空格[38]) , 有时候是一个单词的一部分(比如:capes被分隔为?cap和es) , 还有可能它就是标点符号(比如:.) 。
BPE的一个好处是它可以编码任意字符串 。如果遇到了某些没有在词汇表里显示的字符串 , 那么BPE就会将其分割为它能够理解的子串:

>>> [encoder.decoder[i] for i in encoder.encode("zjqfl")]['z', 'j', 'q', 'fl']
我们还可以检查一下词汇表的大小:

>>> len(encoder.decoder)50257
词汇表以及决定字符串如何分解的字节对组合(byte-pair ) , 是通过训练分词器获得的 。当我们加载分词器 , 就会从一些文件加载已经训练好的词汇表和字节对组合 , 这些文件在我们运行的时候 , 随着模型文件被一起下载了 。你可以查看/124M/.json(词汇表)和/124M/vocab.bpe(字节对组合) 。
超参数
是一个字典 , 这个字典包含着我们模型的超参:

>>> hparams{"n_vocab": 50257, # number of tokens in our vocabulary"n_ctx": 1024, # maximum possible sequence length of the input"n_embd": 768, # embedding dimension (determines the "width" of the network)"n_head": 12, # number of attention heads (n_embd must be divisible by n_head)"n_layer": 12 # number of layers (determines the "depth" of the network)}
我们将在代码的注释中使用这些符号来表示各种的大小维度等等 。我们还会使用n_seq来表示输入序列的长度(即:n_seq = len()) 。
参数
是一个嵌套的json字典 , 该字典具有模型训练好的权重 。json的叶子节点是NumPy数组 。如果我们打印 ,  用他们的形状去表示数组 , 我们可以得到:

>>> import numpy as np>>> def shape_tree(d):>>>if isinstance(d, np.ndarray):>>>return list(d.shape)>>>elif isinstance(d, list):>>>return [shape_tree(v) for v in d]>>>elif isinstance(d, dict):>>>return {k: shape_tree(v) for k, v in d.items()}>>>else:>>>ValueError("uh oh")>>>>>> print(shape_tree(params)){"wpe": [1024, 768],"wte": [50257, 768],"ln_f": {"b": [768], "g": [768]},"blocks": [{"attn": {"c_attn": {"b": [2304], "w": [768, 2304]},"c_proj": {"b": [768], "w": [768, 768]},},"ln_1": {"b": [768], "g": [768]},"ln_2": {"b": [768], "g": [768]},"mlp": {"c_fc": {"b": [3072], "w": [768, 3072]},"c_proj": {"b": [768], "w": [3072, 768]},},},... # repeat for n_layers]}