【LLM】从零开始学大语言模型 | 2 | 词嵌入
从 One-Hot 到词嵌入:让计算机理解文字的语义空间 自然语言处理要解决的第一件事,其实非常朴素:怎样把人类语言变成计算机能够计算、能够学习、能够比较的数学对象。 一句话看起来很简单,比如:我喜欢吃苹果。但对计算机来说,这串文字本身并不能直接参与矩阵乘法、梯度下降和概率计算。计算机擅长处理的是数字,尤其是连续的、可以进行加减乘除和求导的数值。因此,自然语言处理的第一步,就是把“文字符号”转换成“数值表示”。 这篇文章将从最基础的 One-Hot 编码讲起,逐步过渡到现代深度学习中广泛使用的词嵌入,也就是 Word Embedding。我们会解释为什么 One-Hot 编码虽然简单却不够好,词向量为什么能够表达语义,Word2Vec 是如何训练出词向量的,以及现代大模型中的 Embedding 层和中文 Tokenization 又是怎么一回事。 理解这些内容,是后续理解 Transformer、注意力机制以及大语言模型中各种矩阵运算的重要前提。 一、计算机的“文字障碍” 计算机本质上处理的是数字。更准确地说,是基于二进制数值进行算术运算和逻辑运算。如果我们把一句话直接交给模型,例如:我喜欢吃苹果模型并不能天然理解“我”“喜欢”“吃”“苹果”这些符号意味着什么。它们只是字符,是离散的语言单位。 这里至少有三个困难。 1. 文字是离散符号 语言中的词或者字,本质上是离散符号。我们可以说“苹果”和“香蕉”都是水果,但很难说“苹果”比“香蕉”大多少。数字则不同。对于数值 3 和 5,我们可以说 5 比 3 大,差值是 2。这种连续性让数学运算变得自然。但词语之间没有这种天然的数值大小关系。因此,我们需要人为设计一种数值表示,使离散符号能够进入连续数学空间。 2. 词汇量很大,容易造成维度灾难 人类语言的词汇量非常庞大。中文有常用字、生僻字、词语、成语、专有名词;英文有单词、词形变化、缩写、外来词。一个实际语言系统的词表规模可能从几万到几十万不等。如果用最朴素的方法,每个词占用一个独立维度,那么向量维度会变得非常高。假设词表有 10 万个词,那么每个词都需要一个 10 万维向量来表示。这会带来严重的稀疏性和计算负担。 3. 普通编码无法表达语义关系 人类语言中,词与词之间存在复杂关系。例如: “猫”和“狗”都是常见动物; “苹果”和“香蕉”都是水果; “医生”和“医院”经常共同出现; “国王”和“女王”之间存在性别对应关系。 如果只是简单给每个词编号,计算机无法知道这些关系。我们需要一种表示方法,使得语义相近的词在数值空间中也更接近。 换句话说,我们希望把离散符号变成连续的、低维的、带有语义结构的数学对象,通常是向量。这就是词嵌入要解决的问题。 二、One-Hot编码:最朴素的词表示方法 最直观的想法是:给词典里的每个词编号,然后用一个向量来表示它。 假设我们的词典只有 4 个词["苹果", "香蕉", "猫", "狗"],我们可以这样表示: 1 2 3 4 苹果 = [1, 0, 0, 0] 香蕉 = [0, 1, 0, 0] 猫 = [0, 0, 1, 0] 狗 = [0, 0, 0, 1] 这种表示方法叫作 One-Hot 编码,也叫独热编码 它的意思是:每个词对应一个向量,向量中只有一个位置是 1,其余位置全是 0。这个 1 的位置代表该词在词表中的编号 如果词表大小为 $V$,那么每个词都可以表示成一个 $V$ 维向量。设某个词的索引为 $i$,则它的 One-Hot 向量记作: ...