Transformer架构原理的菜鸟学习之路01——输入词嵌入(input embedding)

张开发
2026/4/20 14:52:23 15 分钟阅读

分享文章

Transformer架构原理的菜鸟学习之路01——输入词嵌入(input embedding)
我们从《Attention Is All You Need》那篇经典论文当中的编码器-解码器结构示意图的Inputs部分开始顺着箭头指向一一谈起首先要谈的就是Input Embedding输入词嵌入。没有一项全新的技术会凭空产生在Transformer架构诞生之前自然语言处理NLP模型例如Word2Vec早已广泛使用输入词嵌入技术。Transformer的创新之处在于开创了动态上下文词嵌入代替静态词嵌入的新范式。一、词表在正式探讨输入词嵌入之前首先要讲一下词表的概念在经典 Transformer以及绝大多数基于 Token 的 NLP 模型中词表都是模型架构的“地基”。词表是一个离散的映射表它包含了模型在训练前通过分词算法从海量语料中统计归纳出的所有Token中文公认的翻译为词元。每个Token对应一个唯一的整数编号。词表内容在模型训练开始前就已确定本身并不包含可学习的参数。词表的大小是模型的一个关键超参数它决定了模型能直接识别与表达的“词汇”总量。如果没有预先定义好的词表输入嵌入层Input Embedding Layer就无法构建模型也就无法初始化。我们可以请大模型生成一个查询GPT-4词表的程序# pip install tiktoken # 先安装 import tiktoken # ① 选择对应模型的 tokenizer enc tiktoken.encoding_for_model(gpt-4) # GPT‑4 # enc tiktoken.encoding_for_model(gpt-3.5-turbo) # GPT‑3.5 # ② 查看词表大小 vocab_size len(enc._mergeable_ranks) # 私有属性但公开可用 print(词表大小Token 数:, vocab_size) # 约 100,000 # ③ 列出前 N 条示例 20 条词表内容 for i, token in enumerate(enc._mergeable_ranks.keys()): #if i 20: break print(i, -, token)​​​​​​经过相当长的一段时间的等待我们就可以查看GPT-4的词表长度100256100Ktoken的顺序编号为0~100255也就是说明该模型能够识别的不同token数量上限为100256个。BERT / RoBERTa约 30,000 - 50,265BERT-base的词汇表通常为30,522个tokenRoBERTa的词汇表扩展至约50,265个tokenGPT系列40,000 - 约 100,000GPT-1词汇表为40,000GPT-2扩展至50,257GPT-4等后续模型据信进一步扩大约100K二、词嵌入众所周知计算机不能直接处理文本等信息故而需要先将其数字化为0、1编码。与之类似 大模型也不可能直接“读懂文本”也需要先将文本转换为模型能够看懂的数字向量词嵌入矩阵。随机生成的词嵌入矩阵对语言的段落、文本、单词的含义一无所知不能表达任何语义信息。我们可以使用Python的PyTorch库生成一个简单的Python程序模拟生成词嵌入表。为了后面验证的方便暂且设置嵌入维度100。import torch import torch.nn as nn # Transformer经典配置词汇表10000词嵌入维度512 vocab_size 10000 d_model 100 # 【核心】创建词嵌入层内部就是随机初始化的矩阵 embedding nn.Embedding(vocab_size, d_model) # 查看初始权重全是随机数 print(初始词嵌入矩阵前2行) print(embedding.weight[:2]) # 输出2行512列的随机向量随机初始化词嵌入矩阵第1行[-1.3733, 0.4495, -0.0771, 0.3698, -1.6959, -0.2821, -0.8875, 0.8115, -0.2193, -0.0729, 0.9815, 0.3891, 0.3280, 1.7729, 2.1530, 1.1492, 0.1678, 0.1782, -0.9906, -0.0387, 1.2132, 0.5514, -0.5893, 0.5342, -1.5082, -0.8268, 0.2504, -0.9111, -1.6653, 1.1402, -0.3704, -1.8449, -2.6438, 1.7788, -0.8923, 0.9224, 0.3797, 1.2837, -0.8440, 1.0131, -2.2577, -0.2050, -0.3591, 0.6755, -1.3041, -0.1148, 1.5228, -0.8987, -0.4183, -0.4292, 0.2030, 1.4788, 0.5475, -0.1155, 0.7294, 0.3461, -0.3203, -1.0219, 1.0988, 1.1669, 0.8631, 0.1367, -0.0606, -0.3082, -1.7180, -0.4303, 0.2233, -0.5944, -0.0604, -0.6190, 0.6817, -0.7429, -0.2533, 0.1235, 0.3690, -0.0836, -0.6077, 1.9320, -1.6618, -0.8639, 0.8634, -0.1090, 0.9075, -0.8088, -0.0651, 2.5026, 0.7189, 0.2619, 1.3061, -0.8456, 0.9355, -0.2115, -1.4427, 0.5955, -1.9372, -1.3172, 1.4857, 0.4590, -0.8914, -0.4586]仅凭我们的观察很难发现其中的奥秘。有问题找AI我们请大模型帮我们分析这组数据是否符合正态分布样本量 n100均值 ≈−0.064标准差 ≈1.06偏度 ≈ -0.05接近对称峰度 ≈ -0.10接近正态峰度 0均值接近 0标准差接近 1偏度、峰度都接近正态分布的特征如果仍然还有疑惑还可以请大模型帮助我们使用Python语言绘制直观的图像看看是否就是我们熟悉的正态分布模样import numpy as np import matplotlib.pyplot as plt import seaborn as sns from scipy import stats # 1. 准备数据 data np.array([-1.3733, 0.4495, -0.0771, 0.3698, -1.6959, -0.2821, -0.8875, 0.8115, -0.2193, -0.0729, 0.9815, 0.3891, 0.3280, 1.7729, 2.1530, 1.1492, 0.1678, 0.1782, -0.9906, -0.0387, 1.2132, 0.5514, -0.5893, 0.5342, -1.5082, -0.8268, 0.2504, -0.9111, -1.6653, 1.1402, -0.3704, -1.8449, -2.6438, 1.7788, -0.8923, 0.9224, 0.3797, 1.2837, -0.8440, 1.0131, -2.2577, -0.2050, -0.3591, 0.6755, -1.3041, -0.1148, 1.5228, -0.8987, -0.4183, -0.4292, 0.2030, 1.4788, 0.5475, -0.1155, 0.7294, 0.3461, -0.3203, -1.0219, 1.0988, 1.1669, 0.8631, 0.1367, -0.0606, -0.3082, -1.7180, -0.4303, 0.2233, -0.5944, -0.0604, -0.6190, 0.6817, -0.7429, -0.2533, 0.1235, 0.3690, -0.0836, -0.6077, 1.9320, -1.6618, -0.8639, 0.8634, -0.1090, 0.9075, -0.8088, -0.0651, 2.5026, 0.7189, 0.2619, 1.3061, -0.8456, 0.9355, -0.2115, -1.4427, 0.5955, -1.9372, -1.3172, 1.4857, 0.4590, -0.8914, -0.4586]) # 2. 设置绘图风格 sns.set(stylewhitegrid) # 设置网格背景 # 设置中文字体路径 plt.rcParams[font.sans-serif] [SimHei] # SimHei 是黑体的意思你也可以尝试 Microsoft YaHei 等其他中文字体 plt.rcParams[axes.unicode_minus] False # 正确显示负号 plt.figure(figsize(10, 6)) # 3. 绘制直方图 # densityTrue 表示绘制概率密度以便与曲线面积对应 # bins15 表示分15个桶可以根据数据量调整 plt.hist(data, bins15, densityTrue, alpha0.6, colorskyblue, edgecolorblack, label数据直方图) # 4. 计算拟合曲线的参数 mu, sigma np.mean(data), np.std(data) x np.linspace(min(data), max(data), 100) # 生成x轴数据点 # 计算对应的正态分布概率密度 y值 y stats.norm.pdf(x, mu, sigma) # 5. 绘制正态拟合曲线 plt.plot(x, y, r-, linewidth2, labelf正态拟合曲线\n($\mu${mu:.2f}, $\sigma${sigma:.2f})) # 6. 添加图例和标题 plt.title(数据正态分布拟合验证图, fontsize16) plt.xlabel(数值, fontsize12) plt.ylabel(概率密度, fontsize12) plt.legend() # 显示图例 # 显示图形 plt.show()数据维度越大越接近正态分布足以说明输入词嵌入的随机矩阵并不是漫无目的随机而是符合严格的数学规律。当然具体的随机生成算法会随着Transformer架构相关技术的发展演进而不断变化。三、维度和语义观察我们自己以及身边的人不难发现极其聪明与很不聪明的人毕竟只是少数绝大多数都是像我一样的普通人这何尝不是一种广泛存在的正态分布。我们的智力水平基础与脑容量显著相关这是人类进化历程与脑科学研究的基本共识。词表的大小和词嵌入维度的高低共同构成大模型的基础“脑容量”我们可以把词嵌入向量想象成给每个词语画一张全面、立体的画像就像我们描述一个人不能只说性别或年龄要结合身高、性格、爱好、职业等很多特征才能更完整地认识一个人。词向量的每一个维度就是一个隐藏特征可能代表褒贬义、时态、主动被动、抽象还是具体、情感强弱、积极消极等等维度越多画像越细致入微。两个词向量越接近就说明它们在语义上越像就像两个性格爱好高度相似的人。Transformer 就是通过对比这些 “语义画像”理解词语之间的关系从而“读懂”整句话的含义。Transformer架构诞生之前的自然语言处理模型Word2Vec词嵌入维度只有200左右我们不难理解复杂语义理解难度与计算速度等瓶颈所在。直到自注意力机制、并行计算等技术的迭代革新有更高的数据维度、更快的计算速度支撑的Transformer方才得以引领生成式人工智能的一日千里、推陈出新。Word2Vec通常设置在 200 维左右BERT-Base维度为 768 维DeepSeek V2 Lite其隐空间维度为 2048 维DeepSeek V3嵌入维度达到了 7168 维GPT-3其 Token 维度高达 12288 维Llama 3向量维度达到了 16384 维高维度的向量表示为更复杂的语义联系提供了更大的可能性这些维度的划分通常不是人类手动定义而是模型通过阅读海量文本自己“悟”出来的。比如模型可能会发现在某个维度上“高兴”、“快乐”、“兴奋”的数值都很高而“悲伤”、“痛苦”的数值很低那么这个维度就自动代表了“积极情感”而在另一个维度上“昨天”、“过去”、“曾经”可能数值很高而“明天”很低这个维度就代表了“时间性”。转自https://mp.weixin.qq.com/s/ga-YMSLzPyigLLPhTX2ttg

更多文章