前言
大模型为什么需要 Embedding, Embedding 解决了什么问题,如何使用
大模型是怎么懂你的?
在日常使用 AI 产品进行聊天或者做其他事情时,你是否思考过一个问题,AI 是如何理解你提出的问题的呢?
比如对于 ChatGPT 这类国外的模型来说,你用中文提问的时候,他是把中文先转换成英文,然后用英文作为模型的输入来回答你的问题吗?反之又是如何进行呢?
再有当你问大模型 一加一等于几?
这个问题时和你问他 1+1=?
时,在已知回答必然相同的情况下,大模型内部是怎么处理这两个其实意思一样,当表达方式有差异的问题的呢?
要回答上面的问题,我们就得了解一下 LLm Embedding ,大模型的嵌入技术。
什么是 Embedding
嵌入技术是大模型理解和处理信息的基石,将非结构化的原始数据转化为结构化的、富含语义的数值向量
大模型嵌入技术是将文本、图像、音频等数据转换为计算机可理解的数值向量(即嵌入)的核心方法。文本嵌入专注于语言,将单词、句子等映射为向量,捕捉语义信息。多模态嵌入则更进一步,旨在将不同数据类型(如文本和图像)统一到同一向量空间,实现跨模态的理解与交互。
大型语言模型(如ChatGPT)处理中文时,会先将文本切分成token,再将token转换为富含语义和位置信息的嵌入向量,供模型后续处理。
而嵌入技术又分为 文本嵌入 和 多模态嵌入 ,顾名思义,文本嵌入专门用来处理纯文字的内容,而多模态嵌入将来自不同模态(如文本、图像、音频、视频等)的数据映射到一个统一的向量空间的技术。
文本嵌入
文本嵌入(Text Embedding)是将文本数据转换为数值向量 。这种转换使得计算机能够以数学方式理解和处理自然语言。其核心价值在于能够捕捉文本的语义信息,将语义上相似的文本映射到向量空间中相近的位置。
那么什么叫做语义相似呢?一图胜千言,举个例子 ,可以打开 projector.tensorflow.org 这个网站,之后随机选中屏幕中的一个词,比如这里的 bytes.
从图上可以看到,和 bytes 这个词意思相近或有关联的词,都和他离的比较近。两个词的相关性越强,在日常使用中经常一起用的概率越高,二者的在三维空间的距离就越小。
比如这里图里同样用红点标识的 byte
,bit
,以及相关的 ram
,binary
等等,甚至在右下角还有一个 allocatd。
用 projector.tensorflow.org 体验一番之后,相信你应该可以对 embedding 这个概念有了一个感性的认知,向量空间、多维度、语义相似这些概念通过这个三维空间的展现就可以理解了。
总结来说,embedding 就是将我们日常使用的文本用计算机更容易理解的数学方式进行了转换,而转换后的内容是一串数字。不同的词转换后的数字,也是不同的。但是这一长串数字却能笼统的表达他们在现实生活中的意义,下面再举个例子。
我们以 ["雷锋", "雷峰塔", "老婆", "老婆饼", "嫂子", "饺子", "狮子头", "蚂蚁上树", "狮子", "蚂蚁", "岳阳楼"]
这 11 个词为例,这些词你用传统的正则表达式或者其他什么方式,是无法让计算机搞懂的,有些词相差一个字,但是意思却相差十万八千里,我们用 Qwen3-Embedding-0.6B 这个有 1024 个维度的嵌入模型简单看一下效果。
用 Qwen3-Embedding 做文本嵌入
from transformers import AutoModel, AutoTokenizerimport torch# 加载Qwen3-Embedding模型model = AutoModel.from_pretrained("Qwen/Qwen3-Embedding-0.6B", trust_remote_code=True)tokenizer = AutoTokenizer.from_pretrained('Qwen/Qwen3-Embedding-0.6B', padding_side='left')# 待编码词汇words = ["雷锋", "雷峰塔", "老婆", "老婆饼", "嫂子", "饺子", "狮子头", "蚂蚁上树", "狮子", "蚂蚁", "岳阳楼"]# 生成embeddingembeddings = []for word in words: inputs = tokenizer(word, return_tensors="pt") with torch.no_grad(): output = model(**inputs) embeddings.append(output.last_hidden_state.mean(dim=1).squeeze().numpy())print(len(embeddings))print(embeddings[0].shape)print(embeddings[0])
输出
11(1024,)[ 1.3087157 -11.332913 -0.6359947 ... -4.4446354 -7.3631244 -0.6820622]
可以看到我们顺利对这 11 个词进行了嵌入,每一个词都对应一个 1024 大小的一维数组,至于里面的具体内容我们不用关心。我们将这些内容用图画出来。
from sklearn.decomposition import PCAimport matplotlib.pyplot as pltimport numpy as np# 将embedding转为numpy数组emb_array = np.array(embeddings)# 降维到2Dpca = PCA(n_components=2)result = pca.fit_transform(emb_array)# 用拼音/英文替代中文# 由于用 PCA 绘制时始终找不到可用的中文字体,因此这里做一下映射word_map = { "雷锋": "LeiFeng", "雷峰塔": "LeiFengTa", "老婆": "Wife", "老婆饼": "Wife Cake", "嫂子": "saozi", "饺子": "jiaozi", "狮子头": "shizitou", "蚂蚁上树": "mayishangshu", "狮子": "shizi", "蚂蚁": "ant", "岳阳楼": "yueyanglou"}# 绘制散点图plt.figure(figsize=(8, 6))for i, word in enumerate(words): plt.scatter(result[i, 0], result[i, 1], label=word, s=100) plt.annotate(word_map[word], (result[i, 0] + 0.02, result[i, 1] + 0.02))plt.title("Qwen3-Embedding Visualization")plt.xlabel("Dimension 1")plt.ylabel("Dimension 2")plt.grid(alpha=0.3)plt.show()
从这张图你就可以看到 embedding 有多么强大了。雷锋和雷峰塔,虽然看着像,但是在现实世界中一个人是,一个是建筑物,语义相差甚远,而通过嵌入之后,他们之间也是相隔甚远。而岳阳楼和雷锋塔,虽然看着不像,但是他们其实都是建筑物,因此离得近一些,类似的还有狮子和蚂蚁。
这里只是用 Qwen3-Embedding 参数最小的模型进行了测试,实际上有条件的话可以使用参数更多模型,效果也会更好。
这就是文本嵌入的意义,用多维向量表达语言中的内涵。
文本嵌入应用场景
文本嵌入技术凭借其将文本转换为富含语义信息的数值向量的能力,在自然语言处理领域有着广泛的应用。以下是一些具体的应用场景举例:
语义搜索(Semantic Search): 传统的搜索引擎主要依赖关键词匹配,而基于文本嵌入的语义搜索能够理解用户查询的真实意图和文档的深层含义。通过将查询文本和文档库中的文本都转换为嵌入向量,然后计算它们之间的余弦相似度或其他距离度量,可以找到与查询语义最相关的文档,即使查询和文档中没有完全相同的关键词。例如,用户搜索“如何做蛋糕”,语义搜索引擎也能返回包含“烘焙甜点步骤”或“自制生日蛋糕教程”的文档 。
文本相似度计算(Text Similarity):文本嵌入可以用于衡量两段文本之间的语义相似度。这在问答系统(判断用户问题与知识库中问题的相似度)、 plagiarism detection(检测文本抄袭)、推荐系统(推荐相似内容)等场景中非常有用。例如,在客服机器人中,可以将用户输入的问题与预设的标准问题库进行相似度计算,从而快速找到最匹配的答案 。
余弦相似度
通过 embedding 之后,文本或者句子转换成了一维向量,那么在程序里他是怎么计算这两个向量是否表达相近含义的呢,这就要借助余弦相似度,我们还是举个例子。
words = ["我喜欢你","我中意你","我爱你","我与你势不两立","今天是周日","今天礼拜天"]# 生成embeddingembeddings = []for word in words: inputs = tokenizer(word, return_tensors="pt") with torch.no_grad(): output = model(**inputs) embeddings.append(output.last_hidden_state.mean(dim=1).squeeze().numpy())
我们对 ["我喜欢你","我中意你","我爱你","我与你势不两立","今天是周日","今天礼拜天"]
这 6 个句子进行 embedding,然后计算其余弦相似度。
import numpy as npfrom sklearn.metrics.pairwise import cosine_similarity# 将embedding转为numpy数组emb_array = np.array(embeddings)sim_matrix = cosine_similarity(emb_array)print("相似度矩阵:")print(np.around(sim_matrix, 2))
相似度矩阵:[[1. 0.82 0.81 0.67 0.56 0.58] [0.82 1. 0.73 0.69 0.58 0.58] [0.81 0.73 1. 0.61 0.64 0.68] [0.67 0.69 0.61 1. 0.52 0.53] [0.56 0.58 0.64 0.52 1. 0.86] [0.58 0.58 0.68 0.53 0.86 1. ]]
我们来解读一下 sim_matrix 这个矩阵的结果
- 首先对角线都是 1,这很好理解,一个词和自身必然是完全相似的这个矩阵其实是对称的,这也很好理解,A 和 B 的相似度,与 B 和 A 相似度其实是一回事儿第一行
sim_matrix[0][0] = 1
sim_matrix[0][1] = 0.82
sim_matrix[0][2] = 0.81
这几个值比较接近,这和实际中 ["我喜欢你","我中意你","我爱你"]
这就几个表达意义相似非常符合,而和后面的几个表达相似度有较大差异。最后两个值 sim_matrix[0][4] = 0.56
sim_matrix[0][5] = 0.58
他们和前面的几个表达有差异。但是在 sim_matrix[4][5] = 0.86
,这个结果可以说是非常符合预期,周日
虽然和前面表达情感的词语义相差很多,但是他和 礼拜天
几乎就是同义词,因此他们之间的相似度很高。这就是计算向量之间是否相似的方法,是不是很巧妙。通过嵌入和余弦相似度,就很少会出现我换个问法,AI 怎么就不会了的囧境
文本分类(Text Classification):将文本(如新闻文章、产品评论、邮件)分到预定义的类别中。通过将文本转换为嵌入向量,然后将其作为特征输入到分类器(如逻辑回归、支持向量机或神经网络)中进行训练。例如,可以使用文本嵌入对电影评论进行情感分类(正面/负面),或者对新闻文章进行主题分类(体育、财经、娱乐等)。
命名实体识别(Named Entity Recognition, NER):识别文本中具有特定意义的实体,如人名、地名、组织机构名等。文本嵌入可以为模型提供词语及其上下文的语义信息,帮助模型更准确地识别实体边界和类型。
机器翻译(Machine Translation):将一种语言的文本自动翻译成另一种语言。现代的神经机器翻译模型(如基于 Transformer 的模型)大量使用文本嵌入技术。源语言和目标语言的词语都被映射到共享的或独立的嵌入空间,模型通过学习这些嵌入之间的关系来进行翻译。
问答系统(Question Answering):根据用户提出的问题,从给定的文本或知识库中查找或生成答案。文本嵌入用于理解问题和候选答案的语义。例如,在基于阅读理解的问答系统中,模型需要将问题与文章中的句子进行匹配,找到最相关的部分作为答案 。在检索增强生成(RAG)系统中,文本嵌入是核心组件之一 。
文本摘要(Text Summarization):自动生成文本的简短摘要,捕捉其主要内容。文本嵌入可以帮助模型理解文本的核心思想和重要信息。
推荐系统(Recommendation Systems):在新闻推荐、商品推荐等场景中,可以利用文本嵌入来表示新闻内容或商品描述,然后通过计算用户历史行为(如阅读过的新闻、购买过的商品)的嵌入与候选物品嵌入之间的相似度来进行推荐
应用场景虽然很多,但底层逻辑都依赖一个核心,对同一个概念和想法的不同表达方式都能做到更好的理解,能够举一反三。
这里再强调一下,无论是用中文还是英语,当我们向大模型提问的时候,他会先将文本切分成token,再将token转换为富含语义和位置信息的嵌入向量,然后再提供给后续的处理步骤。不存在什么将英文翻译成中文的步骤,对于一个强大的嵌入模型来说,bus
和 公交车
应该在向量空间中离得很近,而不是和什么数据总线混为一谈。
Embedding 将语义这个一样抽象的概念,从字符串这个维度转换到了向量这个维度,可以说是神来之笔,向量占用的内存空间相比字符串占用的空间减少了很多,而大语言模型,之所以能变大更强,Embedding 功不可没。
总结
任何内容给通过 Emebedding 之后的多维向量作为大模型后续流程的直接输入,将影响模型的整个输出。正确合适的输入才能有好的输出,因此 Embedding 是非常重要的,一旦 embedding 效果不好,无法正确领会用户输入的意图,无法将输入正确的表达为合适的向量,即便模型后续的部分再怎么强大也只能南辕北辙,离更好的答案越来越远。