Embedding 到底要不要每次都做?从分词到向量空间的完整指南
面向读者:正在学习 NLP、RAG 和大模型工程的开发者
本文回答四个问题:
- 有没有像 ImageNet 一样,别人已经把词向量做好了?
- 文本进入 NLP 模型时,是先分词还是先 Embedding?
- 使用预训练向量后,为什么很多场景仍然需要做 Embedding?
- 一个词的向量坐标,究竟怎样一步步计算和训练出来?
先讲一个故事:词语城的地图师
很久以前,有一座叫“词语城”的城市。
城里住着许多词语居民:
- “苹果”住在水果市场,也可能出现在科技街;
- 英文单词 “bank” 既可能指存钱的地方,也可能指河岸;
- “喜欢”“检索”“模型”这些词,彼此之间也有远近关系。
有一天,一个新词来到城门口。守门人不能直接把这个词交给计算机,因为计算机看不懂“苹果”这两个字。于是,城里的第一位工作人员给它发了一张号码牌:
苹果 → 314这张号码牌只是身份证编号,不代表“苹果”比“香蕉”更大,也不代表它们之间没有关系。
接着,地图师把这个词放到城市地图里:
- 水果市场里的苹果,靠近梨、香蕉和水果;
- 科技街里的 Apple,靠近手机、电脑和公司;
- 同一个词在不同句子里,可能被地图师放到不同的位置。
图 1:先给词语发号码牌,再把它放到语义地图中。
这张图就是今天要讲的 Embedding 的直觉:把文字放进一个可以计算距离的向量空间。
不过,地图师不是靠手工画地图。它会先读大量文本,观察哪些词经常一起出现,再通过训练逐渐调整每个词的坐标。读到足够多的例子后,“猫”和“狗”通常会比“猫”和“数据库”更接近。
故事里的“号码牌”和“地图坐标”对应两个不同步骤:
文字 → token 编号 → 向量坐标这也是初学者最容易混淆的地方:token ID 只是编号,Embedding 才是向量表示。
先说结论
有现成的预训练词向量和 Embedding 模型,但它们不能让 Embedding 这一步永久消失。
原因很简单:
- “下载好的词向量”通常是一张可以查表的向量字典;
- “Embedding”也可以指把一条新文本送进模型,计算出它在向量空间中的位置;
- 大模型内部还自带一张Token Embedding 矩阵,文本输入时必须先转成 token ID,再从矩阵中取出向量;
- RAG 中还要把新文档和用户的新问题编码到同一个向量空间,否则无法进行向量检索。
可以把它理解成:
别人已经帮你修好了“地图”和“坐标系”,但你拿到一条新地址时,仍然要把这条地址定位到地图上。
Embedding 到底是什么
计算机看到的不是“猫”“汽车”“喜欢”这些词,而是数字。
最简单的表示方法是给每个词分配一个整数:
猫 → 17 汽车 → 231 喜欢 → 904整数只是编号,并没有表达语义。猫=17并不代表猫比汽车更小,也不代表猫和汽车没有关系。
Embedding 的作用,是把编号转换成一串连续数字:
猫 → [0.21, -0.77, 0.35, ...] 汽车 → [0.18, -0.12, 0.91, ...] 喜欢 → [-0.43, 0.66, 0.08, ...]这串数字就是向量。向量之间的距离或夹角,可以用来近似表达语义相似度。
图 2:真实向量空间维度很高,这里用二维投影帮助理解“距离”和“方向”。
上图只画了二维,真实模型通常是 384、768、1024 甚至更高维。二维图只是为了让人类看懂“相似的东西会靠近”这个直觉。
一个关键误区
Embedding 不是“把词翻译成一个固定的数学答案”。
它更像是一个经过大量语料训练出来的坐标系统:
- 语义相近的词,方向往往更接近;
- 常出现在相似上下文的词,往往更接近;
- 向量空间里的方向可能对应某些语法或语义变化;
- 具体效果取决于训练语料、模型结构、训练目标和使用场景。
Word2Vec 的论文提出了从大规模文本中学习连续词表示的方法;GloVe 则利用全局词共现统计学习词向量。Word2Vec 论文 、Stanford GloVe 项目
文本进入模型时,先分词还是先 Embedding?
答案是:先 Tokenize,再把 token 转成 ID,最后查 Embedding 矩阵。
原始文本 ↓ 文本规范化 ↓ Tokenizer 分词 / 切分 token ↓ token 转整数 ID ↓ Embedding 矩阵查表 ↓ Transformer、RNN 或其他 NLP 模型图 3:文本先经过 Tokenizer,得到 token ID,再查 Embedding 矩阵。
“分词”不一定等于按词切分
中文学习者很容易把 Tokenizer 理解成传统中文分词:
我喜欢自然语言处理 → 我 / 喜欢 / 自然语言 / 处理但现代大模型更多使用子词(subword)或字节级 token。常见算法包括:
- BPE(Byte Pair Encoding)
- WordPiece
- Unigram
- Byte-level BPE
Hugging Face 文档明确区分了预分词、子词切分、token 到整数 ID 等步骤;BPE、Unigram 和 WordPiece 都是常见的子词算法。Hugging Face Tokenization Algorithms
因此,一句话可能切成:
我喜欢RAG → [“我”, “喜欢”, “R”, “AG”]也可能切成:
我喜欢RAG → [“我”, “喜欢”, “RAG”]具体结果由模型自己的词表和 Tokenizer 决定。
为什么不直接按“完整单词”切分
因为完整词表会遇到三个问题:
- 新词很多,词表会不断膨胀;
- 拼写变化、专业术语、代码、网址很难全部收录;
- 一个生僻词如果完全不在词表中,就只能变成未知词。
子词方法允许模型把生僻词拆成已知的小片段。例如英文中的:
unbelievable → un + believe + able这样,即使模型没有见过完整单词,也可能利用已经学过的子词来处理它。
Embedding 矩阵到底是什么
假设词表一共有 50,000 个 token,每个 token 用 768 个数字表示,那么模型里就有一张矩阵:
Embedding 矩阵形状 = [50000, 768]可以把它想象成一个通讯录:
| token ID | 对应向量 |
|---|---|
| 0 | [0.12, -0.03, ...] |
| 1 | [-0.44, 0.81, ...] |
| 2 | [0.27, 0.19, ...] |
| … | … |
| 49999 | [0.05, -0.66, ...] |
当 Tokenizer 输出:
input_ids=[314,9821,441]模型会从矩阵中取出第 314、9821、441 行:
x=embedding_table[input_ids]这一步本质上是查表,不等于每次重新训练一个 Embedding 模型。
这张矩阵从哪里来
有两种情况:
情况 A:训练自己的 NLP 模型
一开始随机初始化 Embedding 矩阵,然后在训练过程中不断更新:
预测错误 ↓ 计算损失 ↓ 反向传播 ↓ 更新 Embedding 矩阵你不需要手工为每个词填写向量。
情况 B:加载预训练模型
直接加载别人训练好的 Tokenizer 和模型权重:
fromtransformersimportAutoTokenizer,AutoModel tokenizer=AutoTokenizer.from_pretrained("your-model")model=AutoModel.from_pretrained("your-model")inputs=tokenizer("我喜欢 RAG",return_tensors="pt")outputs=model(**inputs)这时,Tokenizer、Embedding 矩阵和后续模型参数已经一起发布了。你只是把新文本转成 token,使用现成参数进行推理。
Hugging Face Model Hub 提供了大量可下载的预训练模型权重、Tokenizer 和模型卡片。Hugging Face Model Hub
手算一次:一个词怎样学到向量坐标?
回到“词语城”的故事:地图师究竟怎样调整“猫”的位置?下面把“训练得到向量”拆成一次可以复算的数字计算。
我们用经典的Word2Vec Skip-gram:输入中心词,预测附近出现的词。比如从“猫吃鱼”中,在足够大的上下文窗口内取出一个训练样本:中心词是“猫”,目标邻近词是“鱼”。这里直接给出已经分词并提取好的样本,不再展开分词算法。
为了手算,我们把演示模型的词表设为“猫、鱼、汽车”,向量设为 2 维。下面的初始参数由我们选定,用来模拟随机初始化;后面的概率、梯度和更新结果都按照公式计算。这不是一个已经训练好的真实中文词向量模型。
1. 先建词表,再准备两张参数表
| 词 | token ID |
|---|---|
| 猫 | 0 |
| 鱼 | 1 |
| 汽车 | 2 |
Skip-gram 训练时有两张参数表:输入 Embedding 表E,以及输出参数表U。每张表都是3 × 2:3 个词,每个词 2 个数字。
| 词 | 输入表 E:用作中心词时的向量 | 输出表 U:用作候选邻近词时的参数 |
|---|---|---|
| 猫 | [0.20, 0.10] | [0.10, -0.20] |
| 鱼 | [-0.10, 0.30] | [0.40, 0.50] |
| 汽车 | [0.40, -0.20] | [-0.30, 0.20] |
同一个词在两张表中的数字可以不同。本例把输入表E中的行作为最后保存的词向量;输出表U帮助完成预测任务。不同实现也可以对两张表的结果做进一步处理。
图 4:ID 用来找到输入表中的行;输出参数表用来给候选词打分,两者都在训练中学习。
输入“猫”后,先得到ID = 0,再取出输入表的第 0 行:
v = E[0] = [0.20, 0.10]如果用 one-hot 表示,等价于:
[1, 0, 0] × E = [0.20, 0.10]所以查表和 one-hot 矩阵乘法在这里得到相同结果。实际实现直接查表即可。
2. 点积:给每个候选邻近词打分
预测时,将“猫”的输入向量v与每个候选词的输出参数u做点积:对应维度相乘,再相加。
猫的分数 = [0.20, 0.10] · [0.10, -0.20] = 0.20 × 0.10 + 0.10 × (-0.20) = 0.00 鱼的分数 = [0.20, 0.10] · [0.40, 0.50] = 0.20 × 0.40 + 0.10 × 0.50 = 0.13 汽车分数 = [0.20, 0.10] · [-0.30, 0.20] = 0.20 × (-0.30) + 0.10 × 0.20 = -0.04得到三个预测分数:z = [0.00, 0.13, -0.04]。这些是预测邻近词的分数,不是已经归一化的概率,也不是“猫”和这些词的余弦相似度。
3. Softmax:把分数变成概率
Softmax 先对分数取指数,再除以所有指数的总和:
P(候选词 i | 猫) = exp(z_i) / Σ exp(z_j) exp(0.00) = 1.000000 exp(0.13) ≈ 1.138828 exp(-0.04) ≈ 0.960789 总和 ≈ 3.099618| 候选词 | 计算 | 预测概率 |
|---|---|---|
| 猫 | 1.000000 / 3.099618 | 0.322620 |
| 鱼 | 1.138828 / 3.099618 | 0.367409 |
| 汽车 | 0.960789 / 3.099618 | 0.309970 |
“鱼”的概率最高,但只有约 36.74%。这道训练题的正确答案就是“鱼”,因此我们要提高模型对它的预测概率。
图 5:沿箭头读一遍,就能看到“猫”的初始向量怎样参与预测,再根据误差得到一次更新后的向量。
4. 交叉熵:衡量预测有多差
正确答案按“猫、鱼、汽车”的顺序写成 one-hot 标记:
y = [0, 1, 0]对这个单样本,交叉熵损失就是正确答案概率的负对数:
L = -ln P(鱼 | 猫) = -ln(0.367409) ≈ 1.001279模型给“鱼”的概率越大,这个损失越小。下一步就是找到能让损失下降的参数调整方向。
5. 反向传播:梯度的两个数字究竟怎么算?
这里用到 Softmax 与交叉熵组合后的一个结果:损失对每个分数的导数等于预测概率 - 正确答案标记,即p - y。
猫:0.322620 - 0 = 0.322620 鱼:0.367409 - 1 = -0.632591 汽车:0.309970 - 0 = 0.309970这些数字先描述分数应该如何调整。要继续算“猫”的输入向量v,就把每个误差乘以对应的输出参数向量,然后相加。因为分数是z_i = v · u_i,它对v的导数是u_i:
g = ∂L/∂v = Σ (p_i - y_i) × u_i先分别计算三个候选词贡献的梯度:
猫的贡献: 0.322620 × [0.10, -0.20] ≈ [0.032262, -0.064524] 鱼的贡献: -0.632591 × [0.40, 0.50] ≈ [-0.253036, -0.316295] 汽车贡献: 0.309970 × [-0.30, 0.20] ≈ [-0.092991, 0.061994]把三个向量相加:
第 1 维:0.032262 - 0.253036 - 0.092991 ≈ -0.313765 第 2 维:-0.064524 - 0.316295 + 0.061994 ≈ -0.318825 g ≈ [-0.313765, -0.318825]各中间值四舍五入后可能有最后一位的差异;代码使用未舍入的值计算。这就是前面流程图中两个梯度数字的来源。梯度表示:当前损失对这两个坐标的变化有多敏感。
图 6:三个候选词各贡献一个二维向量,相加得到梯度,再逐维执行更新。
6. 梯度下降:真正移动“猫”的坐标
设学习率η = 0.1。学习率控制每次沿调整方向走多大一步。本例使用最简单的随机梯度下降(SGD)更新规则:
新向量 = 旧向量 - 学习率 × 梯度代入两个维度:
第 1 维:0.20 - 0.1 × (-0.313765) ≈ 0.231377 第 2 维:0.10 - 0.1 × (-0.318825) ≈ 0.131883 更新前的“猫”: [0.200000, 0.100000] 更新后的“猫”: [0.231377, 0.131883]这一次,词的向量坐标发生了可以算出来的变化。它是更新后的中间状态,还不是用一个训练样本就得到了最终语义向量。
实际训练也更新输出参数表U,其梯度为∂L/∂u_i = (p_i - y_i) × v。例如“鱼”的输出参数会变成:
鱼的输出参数梯度: -0.632591 × [0.20, 0.10] ≈ [-0.126518, -0.063259] 鱼的新输出参数: [0.40, 0.50] - 0.1 × [-0.126518, -0.063259] ≈ [0.412652, 0.506326]所有梯度都用本轮更新前的参数计算,再一起应用更新。按这个规则同时更新E中“猫”的行和U的三行后,重新算同一个样本:
| 指标 | 更新前 | 更新后 |
|---|---|---|
| `P(鱼 | 猫)` | 0.367409 |
损失L | 1.001279 | 0.977861 |
这个样本的正确答案概率提高了,损失下降了。一次训练更新有效,并不说明只训练一次就能理解“猫”的意思。
7. 用几十行 Python 复算,得到完全对应的结果
下面只用 Python 标准库,不需要安装深度学习框架。它演示一次训练更新,并同时更新输入向量和输出参数:
importmath words=["猫","鱼","汽车"]v=[0.20,0.10]# 输入表 E 中“猫”的一行U=[[0.10,-0.20],[0.40,0.50],[-0.30,0.20]]target=1# 正确邻近词“鱼”learning_rate=0.1defpredict(v,U):scores=[sum(a*bfora,binzip(v,u))foruinU]exp_scores=[math.exp(z-max(scores))forzinscores]probabilities=[e/sum(exp_scores)foreinexp_scores]returnscores,probabilities scores,p=predict(v,U)loss=-math.log(p[target])errors=[p[i]-(1ifi==targetelse0)foriinrange(3)]grad_v=[sum(errors[i]*U[i][j]foriinrange(3))forjinrange(2)]grad_U=[[errors[i]*v[j]forjinrange(2)]foriinrange(3)]# 同一训练步的梯度都用更新前的参数计算new_v=[v[j]-learning_rate*grad_v[j]forjinrange(2)]new_U=[[U[i][j]-learning_rate*grad_U[i][j]forjinrange(2)]foriinrange(3)]_,new_p=predict(new_v,new_U)print("初始概率:",[round(x,6)forxinp])print("输入向量梯度:",[round(x,6)forxingrad_v])print("更新后的猫向量:",[round(x,6)forxinnew_v])print("损失:",round(loss,6),"→",round(-math.log(new_p[target]),6))print("P(鱼):",round(p[target],6),"→",round(new_p[target],6))输出:
初始概率: [0.32262, 0.367409, 0.30997] 输入向量梯度: [-0.313765, -0.318825] 更新后的猫向量: [0.231377, 0.131883] 损失: 1.001279 → 0.977861 P(鱼): 0.367409 → 0.376115代码计算 Softmax 时减去最大分数,是为了数值稳定,得到的概率与上面的公式相同。
8. 从“一次更新”到“训练好的词向量”
接下来不断提取其他“中心词—邻近词”样本,重复预测、计算损失和更新。大量上下文提供约束,模型逐渐学出能帮助预测的向量。出现在相似上下文中的词,可能因此得到相似的输入表示。
训练结束后,把输入表E保存下来。本例使用“猫”时只需读取E[0],即可得到训练后的坐标。这个坐标没有固定的人类标准答案,也没有预先规定“第 1 维是动物属性、第 2 维是交通属性”;它由初始化、语料和训练过程共同决定。
这里展示的是Skip-gram + 完整 Softmax + SGD,适合第一次学习。真实词表很大时,Word2Vec 常用负采样等方式减少计算量;现代 Transformer 的 token Embedding 也作为参数参与训练,但后续网络和训练任务更加复杂,不能把上面的三词例子当作其完整计算过程。Word2Vec 原论文、Word2Vec 负采样论文、TensorFlow 官方实现教程
有没有类似 ImageNet 的“词向量网站”
有,而且不止一个。但它们对应的东西不同。
Word2Vec:经典词向量
Word2Vec 通过上下文预测学习词向量,经典做法包括:
- CBOW:根据上下文预测中心词;
- Skip-gram:根据中心词预测上下文。
它适合:
- 词语相似度;
- 传统文本分类;
- 关键词分析;
- 轻量 NLP 实验。
局限是:同一个词通常只有一个固定向量。
例如“苹果”:
苹果(水果) 苹果(科技公司)在传统 Word2Vec 中通常共享同一个向量,很难根据句子自动区分含义。
GloVe:基于共现统计的词向量
GloVe 使用词与词在大规模语料中的共现统计来学习向量。Stanford 官方页面提供了多个预训练版本,例如 Wikipedia、Gigaword、Common Crawl 和 Twitter 语料版本。Stanford GloVe 预训练向量
fastText:适合多语言和生僻词
fastText 不只把一个完整词当成原子单位,还利用字符 n-gram 学习词的组成,因此对拼写变化、生僻词和未登录词更友好。
fastText 官方提供了多语言预训练词向量,包括 157 种语言版本,也提供基于 Wikipedia 的 294 语言词向量页面。fastText 157 语言词向量 、fastText Wiki 词向量
腾讯 AI Lab 中文词向量
腾讯 AI Lab 曾公开中文和英文词、短语的预训练向量,提供 100 维和 200 维等版本。Tencent AI Lab Embedding Corpora
Hugging Face Hub:现在更像“模型商店”
如果把 ImageNet 理解成“标准数据集 + 预训练模型生态”,那么今天更接近这个角色的是 Hugging Face Hub:
- 可以搜索预训练模型;
- 可以查看模型用途和许可证;
- 可以下载 Tokenizer 和权重;
- 可以找到句子向量、跨语言向量、代码向量、图文向量等模型。
但它不是一份“人类所有词汇的最终坐标表”。模型通常有自己的词表、训练语料、向量维度和适用范围。
为什么不能做一张“全人类词汇总表”
这个想法很自然,但实际有几个限制。
词汇会持续变化
新产品、新网络用语、新技术、新人名每天都在出现。一张固定词表很快就会过时。
一个词可能有多个意思
I went to the bank to deposit money. We sat on the river bank.这里英文单词 “bank” 的含义不同。固定词向量无法只靠一个坐标完全表达这两种语境。
不同领域需要不同空间
医学、法律、金融和日常聊天中的词语关系不同:
“支架”在医学领域有一种关系 “支架”在软件工程中可能指另一种结构因此,Embedding 模型需要和任务、语料、语言、领域匹配。
词向量不等于知识库
Embedding 主要用于表达相似性和检索关系。它不等于:
- 事实数据库;
- 精确的百科知识;
- 可以逐条核对的法律条文;
- 永远正确的答案。
RAG 仍然需要把原文保存下来,向量只负责帮助找到相关内容。
静态词向量和上下文 Embedding 的区别
图 7:静态词向量通常一词一个坐标,上下文模型会根据句子重新计算表示。
在 RAG 中还要区分离线建库和在线查询:文档向量可以提前计算,用户的新问题通常要在请求到来时编码。
图 8:文档向量可以预先算好;每条新查询仍需进入同一个 Embedding 模型。
静态词向量
典型代表:
- Word2Vec
- GloVe
- fastText
特点:
同一个词 → 通常同一个向量优点:
- 体积小;
- 速度快;
- 可直接加载到传统 NLP 模型;
- 很适合学习 Embedding 原理。
缺点:
- 不能充分利用上下文;
- 难以处理一词多义;
- 可能和你的领域不匹配;
- 通常不能直接替代现代 Transformer 的输入层。
上下文 Embedding
典型来源:
- BERT、RoBERTa 等编码器模型;
- Sentence Transformers;
- 各种专门的文本向量模型;
- 大语言模型中间层或专门的 Embedding API。
特点:
同一个词 + 不同上下文 → 可能得到不同表示例如:
句子 A:我去银行存钱 句子 B:河边的银行很长模型会根据整句话产生不同的上下文表示。
Sentence Transformers 文档把 Embedding 用于语义相似度、语义搜索、聚类、分类和释义挖掘,并说明常见流程是先用双编码器快速召回,再用重排模型精排。Sentence Transformers 使用文档
为什么 RAG 里还是要做 Embedding
RAG 中通常有两个时间点:离线建库和在线查询。
离线阶段
文档只需要处理一次,除非文档发生变化:
chunks=split_documents(documents)chunk_vectors=embedding_model.encode(chunks)vector_db.insert(chunk_vectors,metadata=chunks)这一步可以:
- 批量处理;
- 后台执行;
- 缓存结果;
- 文档不变时不重复计算。
在线阶段
用户每提出一个新问题,就需要把问题放到同一个向量空间:
query_vector=embedding_model.encode(["公司的报销规则是什么?"])results=vector_db.search(query_vector,top_k=5)这里的“每次做 Embedding”通常指:
对新的查询文本做一次前向计算。
它不代表每次重新训练模型,也不代表每次重新生成整套词向量。
为什么查询和文档必须使用同一个空间
如果文档用模型 A 编码,查询用模型 B 编码,两个向量的坐标含义可能不同,距离就没有可比性。
文档向量:模型 A 的坐标系 查询向量:模型 B 的坐标系 ↓ 距离结果可能没有意义因此 RAG 通常要求:
- 文档和查询使用同一个 Embedding 模型;
- 使用同一套预处理方式;
- 使用相同的向量维度;
- 注意模型要求的 query/document 指令格式;
- 更换模型后重新构建索引。
一个最小可运行的句子 Embedding 示例
下面的示例使用 Sentence Transformers。模型名只是示例,生产环境应根据中文、英文、多语言、代码或领域数据选择并评估模型。
pipinstallsentence-transformersfromsentence_transformersimportSentenceTransformer# 示例模型:适合入门理解;生产环境请根据语言和任务选型model=SentenceTransformer("sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")sentences=["RAG 会先检索相关资料,再让大模型生成答案。","检索增强生成可以减少模型凭空编造。","卷积神经网络常用于图像识别。",]vectors=model.encode(sentences,normalize_embeddings=True)print(vectors.shape)# 结果是一个“每句话对应一个向量”的矩阵;具体维度以模型配置为准计算相似度:
fromsentence_transformers.utilimportcos_sim query=model.encode(["什么是检索增强生成?"],normalize_embeddings=True,)scores=cos_sim(query,vectors)[0]print(scores)注意:
- 模型推理需要计算资源;
- 文档向量可以提前算好并缓存;
- 查询向量通常在用户请求到来时计算;
- 如果请求量大,可以批量处理、并发处理或独立部署 Embedding 服务;
- 不能只看向量距离,还要评估召回率、答案准确率和业务指标。
写 NLP 模型时到底应该自己训练 Embedding 吗
可以按下面的决策表判断。
| 场景 | 推荐做法 |
|---|---|
| 学习 Embedding 原理 | 自己训练一个小型 Embedding 层 |
| 传统文本分类、情感分析 | 先尝试预训练词向量或预训练编码器 |
| 中文语义检索 | 使用中文或多语言预训练 Embedding 模型 |
| RAG 文档库 | 选择一个 Embedding 模型,批量编码并入库 |
| 领域语料和通用模型差异很大 | 先评测,必要时微调 Embedding 模型 |
| 训练一个大语言模型 | 使用模型配套 Tokenizer 和 Embedding 权重 |
| 只有少量数据 | 不建议从零训练词向量 |
初学阶段最容易犯的错误是:一看到 Embedding 就想“我是不是要重新训练一套所有词向量”。通常不需要。
更准确的理解是:
自己训练模型:Embedding 矩阵是模型参数,会随训练更新 使用预训练模型:Embedding 矩阵已经有了,推理时查表或前向计算 使用 RAG:新文档和新问题仍需用选定的 Embedding 模型编码最后总结
问题一:有没有现成词向量?
有:
- Word2Vec
- GloVe
- fastText
- 腾讯 AI Lab 中文词向量
- Hugging Face 上的各种预训练 Embedding 模型
问题二:是不是先分词?
是。现代流程通常是:
文本 → Tokenizer → token ID → Embedding → Transformer“分词”常常是子词切分,不一定是传统意义上的按词切分。
问题三:为什么还要 Embedding?
因为每条新文本都要被定位到向量空间中:
- 模型内部需要把 token ID 映射成向量;
- RAG 需要把新文档和新问题编码成向量;
- 语义搜索需要比较查询向量和文档向量;
- 句子和段落的向量不是一份永久不变的“全人类词典”。
真正应该记住的一句话是:
预训练模型让你不用从零训练 Embedding,但不能让新文本跳过 Tokenize 和向量化。
参考资料
- Hugging Face:Tokenization algorithms
- Hugging Face:The Model Hub
- Mikolov et al.:Word2Vec
- Stanford:GloVe
- fastText:Pre-trained vectors
- Tencent AI Lab:Embedding Corpora
- Sentence Transformers:Usage
- Hugging Face:Tokenizer API