kizumi_header_banner_img

欢迎来到99的小站!

加载中

文章导读

Attention is all you need – #4.5 Tokenizer 与 Embedding


avatar
windows9999 2026年10月25日 17

Attention is all you need – #4.5 Tokenizer 与 Embedding

前言

OMG我忘了还要先学怎么得到正确答案和怎么把词转换成向量了,这篇博客我就来研究研究嘿嘿

Tokenizer

Tokenizer 究竟是什么呢?

Tokenizer 负责将文本拆分为 Token,并把这些 Token 转换为整数 ID。随后,Embedding 层根据这些 ID,从可训练的 Embedding 矩阵中取出对应向量,作为神经网络的输入。

比如:

vocab = {
    "我": 0,
    "爱": 1,
    "你": 2
}

text = "我爱你"
tokens = [vocab[ch] for ch in text]

print(tokens)  # [0, 1, 2]

不过这样一个一个设定也太累了,我们可以直接扫描训练语料,按照字符首次出现的顺序建立词表

corpus = "我爱你你爱我"

chars = list(dict.fromkeys(corpus))

vocab = {ch: i for i, ch in enumerate(chars)}

Embedding

Embedding 是一个形状为 V\times d 的可训练矩阵。前向传播时,根据 Token ID 查找对应行,将长度为 T 的序列转换为 T\times d 的向量矩阵。

它是一个可训练的参数矩阵,用来将离散的 Token ID 映射为连续的向量表示

\boxed{E\in\mathbb{R}^{V\times d_{\text{model}}}}

其中:

  • E:Embedding 矩阵
  • V:词表大小(Vocabulary Size)
  • d_{\text{model}}:每个 Token 对应的向量维度
  • E_{i,j}:第 i 个 Token 的向量中,第 j 个分量

矩阵的每一行对应一个 Token 的向量。

假设 99GPT v0:

  • 词表大小 V=4
  • 向量维度 d_{\text{model}}=3

那么:

E= \begin{bmatrix} 0.2 & 0.5 & -0.1\\ 0.8 & -0.3 & 0.6\\ -0.4 & 0.9 & 0.2\\ 0.1 & 0.7 & -0.5 \end{bmatrix}

假设 Token「我」的 ID 是 2,那么:

\operatorname{Embedding}(2)=E_{2,:} \\ =\begin{bmatrix}-0.4&0.9&0.2\end{bmatrix}

如果有多个 Token ID ,假设输入 Token ID 序列是:

T=[2,3,0]

直接取出对应的三行:

X=E[T]

于是:

\boxed{X\in\mathbb{R}^{n\times d_{\text{model}}}}

其中 n 是输入序列的 Token 数量。

Embedding 矩阵不是固定的词典,而是通过反向传播不断学习的参数。

初始化时每行可以是随机向量,训练过程中根据 Loss 的梯度更新被使用的行,从而逐渐形成有用的 Token 表示。

来一道题~

假设 99GPT 的词表有 100 个 Token,每个 Token 对应 64 维向量,输入句子被编码成 5 个 Token ID。

Embedding 矩阵 E 和输出矩阵 X 的维度分别是什么?

答案是 E:100\times64,\quad X:5\times64 !

Embedding的反向传播

先记住一句话:

Embedding 的反向传播,本质上就是把输入向量的梯度累加回 Embedding 矩阵对应的行。

假设:

E= \begin{bmatrix} 0.2&0.5\\ 0.8&0.3\\ 0.4&0.9 \end{bmatrix}

输入 Token ID 为:

T=[0,2]

那么前向传播:

X=E[T]= \begin{bmatrix} 0.2&0.5\\ 0.4&0.9 \end{bmatrix}

前向传播之后不是得返回梯度嘛,梯度这时候回来了,最终传给 Embedding 输出 X 的梯度为:

\frac{\partial L}{\partial X}= \begin{bmatrix} 0.6&-0.2\\ 0.1&0.4 \end{bmatrix}

因为 X 的第 0 行来自 E 的第 0 行,第 1 行来自 E 的第 2 行,因此直接把梯度放回对应位置:

\boxed{ \frac{\partial L}{\partial E}= \begin{bmatrix} 0.6&-0.2\\ 0&0\\ 0.1&0.4 \end{bmatrix} }

从链式法则来理解

回忆你之前学习的神经网络:

\frac{\partial L}{\partial w} = \frac{\partial L}{\partial x} \frac{\partial x}{\partial w}

Embedding 也是一样。

对于 X_{k,j}=E_{T_k,j},有:

\frac{\partial L}{\partial E_{i,j}} = \sum_{k:T_k=i} \frac{\partial L}{\partial X_{k,j}}

说人话就是

某个 Token ID 在输入中出现几次,就把那些位置传回来的梯度全部累加到同一行。

比如:

T=[0,0,2]

如果前两个位置的梯度分别为:

[0.2,0.3],\qquad[0.5,-0.1]

那么E 的第 0 行梯度就是:

[0.2,0.3]+[0.5,-0.1]=[0.7,0.2]

最后和神经网络一样,通过学习率更新:

\boxed{E_{\text{new}}=E-\eta\frac{\partial L}{\partial E}}

这就是基本的Tokenizer和Embedding!!!



评论(1)

查看评论列表

发表评论

表情 颜文字
插入代码
津ICP备2026002186号-1