本文经AI新媒体量子位(公众号ID:QbitAI)授权转载,转载请联系出处。现在只需60行代码,您就可以从0构建GPT!当年特斯拉前AI总监的minGPT和nanoGPT也需要300行代码。这个60行的GPT也是有名字的,博主给它取名为PicoGPT。不过与之前的minGPT和nanoGPT教程不同,今天要说的博主教程更侧重于代码实现部分,模型的权重已经训练好了。对此,博主解释说,本教程的重点是提供简单易懂的完整技术介绍。这对于不了解GPT背后概念的朋友来说非常友好。有网友称赞这个博客的介绍很清楚,尤其是第一部分。这篇介绍GPT模型的文章真好,比我之前看到的介绍还清楚,至少第一部分讨论了文本生成和采样。目前这个项目在GitHub上的star已经超过100,在HackerNews上的点击量也即将突破1000。让我们从什么是GPT开始。在介绍之前,我们还是需要说明一下,本教程并不是完全零门槛的。需要读者提前熟悉Python、NumPy和一些基本的训练神经网络。教程的重点是技术介绍,一共六个部分:什么是GPT?按照惯例,在正式搭建GPT之前,有必要对它做一些基本的介绍。教程从三个部分解释了GPT的工作原理:输入/输出、文本生成和训练。在这里,博主附上代码,甚至用了一些比喻,让读者更好的理解GPT。比如在输入部分,作者把句子比作一根绳子,tokenizer会把它分成小块(词),称为token。再比如,在生成文本的部分引入自动回归时,博主直接贴出代码:defgenerate(inputs,n_tokens_to_generate):for_inrange(n_tokens_to_generate):#auto-regressivedecodeloopoutput=gpt(inputs)#模型前向传递next_id=np.argmax(output[-1])#贪婪采样inputs=np.append(out,[next_id])#将预测附加到输入returnlist(inputs[len(inputs)-n_tokens_to_generate:])#只返回生成的IDsinput_ids=[1,0]#"not""all"output_ids=generate(input_ids,3)#output_ids=[2,4,6]output_tokens=[vocab[i]foriinoutput_ids]#“heroes”“wear”“capes”在每次迭代时,它都会将预测的token追加回输入,这个预测未来值并将它们追加回输入的过程就是GPT被描述为自动回归的原因。60行代码如何工作?了解了GPT的基本概念后,我直接快进到如何在电脑上运行这个PicoGPT。博主先扔了他那只有60行的代码:importnumpyasnpdefgpt2(inputs,wte,wpe,blocks,ln_f,n_head):pass#TODO:implementthisdefgenerate(inputs,params,n_head,n_tokens_to_generate):fromtqdmimporttqdmfor_intqdm(range(n_tokens_to_generate),"generating"):#自动回归解码循环logits=gpt2(inputs,**params,n_head=n_head)#模型正向传递next_id=np.argmax(logits[-1])#greedysamplinginputs=np.append(inputs,[next_id])#将预测附加到输入returnlist(inputs[len(inputs)-n_tokens_to_generate:])#只返回生成的idsdefmain(prompt:str,n_tokens_to_generate:int=40,model_size:str="124M",models_dir:str="models"):fromutilsimportload_encoder_hparams_and_params#从已发布的open-aigpt-2文件中加载编码器、hparams和paramsencoder、hparams、params=load_encoder_hparams_and_params(model_size,models_dir)#使用BPEt对输入字符串进行编码okenizerinput_ids=encoder.encode(prompt)#确保我们没有超过模型的最大序列长度assertlen(input_ids)+n_tokens_to_generate
