前面我们完成了一些基本概念,如果你对深度学习的基本原理还不了解,你可以通过这里获得更多信息,由于深度学习的教程汗牛充栋,因此我在这里不会重复,而是集中精力到chatgpt模型原理的分析,实现和实践上。ChatGPT基于一种叫transformer的深度学习模型,它又由一系列组件组合而成,对称我们将逐个剖析。首先我们看看transformer模型的基本结构:
不知你是否感觉这个图有种赛博朋克的科幻感。两个大方块左边那个叫encoder,也叫编码器,在深度学习中一种很常见的模式是,将输入数据经过一系列运算后转换成一种特定向量,用术语说叫lantent vector,这个向量往往记录了输入数据的特定属性,右边方块叫decoder,它的作用是解析encoder生成的中间向量,然后生成某种特定的输出。举个具体例子,警察在侦查案件时,往往会让目击者描述嫌疑人的长相特征,此时目击者就相当于encoder,他描述的特征比如“圆脸,卷发,高额头”等就相当于上面encoder的输出向量,然后公安部分有特定的刑侦人员通过这些特征把嫌疑人的相貌绘制出来,通常绘制的画像跟真实嫌疑人相貌有不小差距,但是由于它能捕捉特定特征,因此这种画像对警方追查嫌疑人也有很大帮助。
首先我们看第一步
inputs是模型的输入数据,对chatgpt来说输入就是一个单词或者句子,input embedding是对输入的一种预处理,它把输入的单词或句子转换成一个向量,这一步是NLP算法中一个重要的课题,前面我们描述过任何难以用传统数据结构描述的对象都可以用向量来表示,当一个词被转换成多维空间的向量时,我们就能通过研究向量在空间中的分布来了解它在语言中的特性,同时如果两个单词分别转换成向量后,如果他们对应的向量在空间上距离越接近,我们就认为他们之间的关系越紧密。
首先我们看看如何将单词转换为向量,这里我们使用BERT模型,它是谷歌大脑早期基础模型之一,通过它我们就能够直接将单词转换为向量。首先我们看一个句子:
The man is king and he loves dog, the woman is queen and she loves cat
在句子中有几个关键词,(man,woman), (king, queen), (dog, cat),可以看到每一组的两个词,它们在含义上互相接近,因此有理由预计如果将他们转换为向量,那么括号对里单词对应的向量在空间上的距离会相互接近,我们用代码检验一下:
from transformers import AutoTokenizer, AutoModel
import torch
from sklearn.metrics.pairwise import cosine_similarity
# Load the BERT tokenizer and model
tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased')
model = AutoModel.from_pretrained('bert-base-uncased')
words = ["man", "woman", "king", "queen", "cat", "dog"]
#embeddings = np.array([word2Vector(word).detach().numpy().reshape(1, -1).flatten() for word in words])
sentence = "The man is king and he loves dog, the woman is queen and she loves cat"
word1 = "man"
word2 = "woman"
word3 = "king"
word4 = "queen"
word5 = "cat"
word6 = "dog"
# Tokenize the sentence and words
tokens = tokenizer(sentence, return_tensors='pt')
word1_tokens = tokenizer(word1, return_tensors='pt')
word2_tokens = tokenizer(word2, return_tensors='pt')
word3_tokens = tokenizer(word3, return_tensors='pt')
word4_tokens = tokenizer(word4, return_tensors='pt')
word5_tokens = tokenizer(word5, return_tensors='pt')
word6_tokens = tokenizer(word6, return_tensors='pt')
# Get the embeddings for the sentence and words
sentence_embedding = model(**tokens).last_hidden_state.mean(dim=1).squeeze()
word1_embedding = model(**word1_tokens).last_hidden_state.mean(dim=1).squeeze()
word2_embedding = model(**word2_tokens).last_hidden_state.mean(dim=1).squeeze()
word3_embedding = model(**word3_tokens).last_hidden_state.mean(dim=