LLM 在预训练时不可能直接训练原始文本,由于文本并不能直接参与计算,需要利用“嵌入”技术把原始文本转换为张量。LLM 往往使用自己训练的嵌入模型(权重,不是分词器),而不是用 Word2Vec ,是因为其对特定任务进行了优化。
下载数据。
需要构建所谓的“嵌入”作为输入,输入嵌入 = 单词嵌入+ 位置嵌入。
嵌入是由两部分组成的,首先来解决单词嵌入。
单词嵌入
单词嵌入其实就是把单词翻译成向量的过程,因为语料是中文所以采用 ChatGLM 的分词器,负责把一个长句子中按照他的规则进行分词,并提供类似 20119 的索引。
tokenizer = ChatGLMTokenizer(vocab_file='../chatglm_tokenizer/tokenizer.model') text_id=tokenizer.encode(text,add_special_tokens=False) text_id.append(tokenizer.special_tokens['<eos>'])
然后通过矩阵变换转换成向量(output_dim = 256)。
vocab_size=64793 output_dim = 256 token_embedding_layer = torch.nn.Embedding(vocab_size, output_dim)
位置嵌入
位置嵌入有多种,绝对位置嵌入是其中最简单的,也是 GPT-2 采用的,所以我们只需要创建另一个嵌入层。
context_length = max_length pos_embedding_layer = torch.nn.Embedding(context_length, output_dim) pos_embeddings = pos_embedding_layer(torch.arange(max_length)) # torch.arange(max_length) -> tensor([0, 1, 2, 3]) print(pos_embeddings.shape)
![notion image](https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff0b6533a-5f55-4686-98e9-32d10eb4212b%2F1fdfa0b4-531c-4865-8882-45ddc2bfe1b7%2F68747470733a2f2f73656261737469616e72617363686b612e636f6d2f696d616765732f4c4c4d732d66726f6d2d736372617463682d696d616765732f636830325f636f6d707265737365642f31382e77656270.webp?table=block&id=8c7071bd-7381-443f-8ece-63c0611933a9&cache=v2)
把二者加起来就是最终结果。
input_embeddings = token_embeddings + pos_embeddings
运行代码
cd 02/ python .\main.py