引言Embedding是 LLM 的语义支柱它可以将原始文本转换为向量形式来方便模型理解。当你在使用 LLM 帮助您调试代码时你的输入文本、代码会被转换为高维向量从而将其中的语义转化成数学关系。本文主要介绍Embedding的基础知识带你一文了解Embedding。介绍什么是Embedding它们是如何从统计方法演变成为当前Embedding技术的了解它们在实践中的实现方式并介绍总结一些最重要的Embedding技术以及 LLM (DS-Qwen1.5B) 的Embedding在图表示中的样子。文章结构安排何为Embedding理想Embedding传统Embedding静态Embedding上下文Embeding大模型EmbeddingDS-Qwen1.5B EmbeddingEmbedding的图理解结论何为Embedding在自然语言处理 (NLP) 任务中处理文本需要将每个单词转换成对应的数字表示。大多数Embedding方法都归结为将单词或标记转换为向量。各种嵌入技术之间的区别在于它们如何处理这种“单词→向量”的转换。Embedding不仅适用于文本还可以应用于图像、音频甚至图数据。「广义上讲Embedding是将任何类型的数据转换为向量的过程」。当然每种模态的Embedding方法都各不相同且独一无二。在本文介绍的“Embedding”主要指的是文本Embedding。另外嵌入技术就是Embedding技术的翻译后面可能会出现嵌入和Embedding两种描述其实是一个意思。或许你在大型语言模型的语境中听说过Embedding但实际上Embedding的历史要悠久得多。以下是各种Embedding技术的概述在阅读有关Embedding的内容时会遇到**「静态Embedding与动态或上下文化Embedding」。区分标记Embedding即在 LLM 一开始就分配给输入标记的固定向量和模型更深层生成的上下文表示至关重要。虽然从技术上讲两者都是嵌入「但标记Embedding是静态的而中间隐藏状态会随着穿过模型的每一层而变化从而捕获输入的完整上下文」**。在某些研究文献中这些上下文输出也被称为“嵌入”这可能会造成混淆。以下是对Embedding的技术分类图示及相关代表技术/模型本文后面将各挑一项代表技术做详细的介绍。理想Embedding对于 LLM 来说Embedding可以被视为其语言的词典。好的Embedding可以让模型能够更好的理解人类语言。但是什么才是理想的嵌入技术呢以下是嵌入技术的两个主要特性「语义表示」某些类型的Embedding可以捕捉单词之间的语义关系。这意味着含义更接近的单词在向量空间中更接近。例如“猫”和“狗”的向量肯定比“狗”和“草莓”的向量更相似。「维度」嵌入向量的大小应该是多少15、50 还是 300找到合适的平衡点是关键。较小的向量较低维度在内存中保存或处理效率更高而较大的向量较高维度可以捕捉复杂的关系但容易出现过拟合。作为参考GPT-2 模型系列的嵌入大小至少为 768。传统Embedding几乎所有词向量嵌入技术都依赖于海量文本数据来提取词语之间的关系。此前词向量嵌入方法依赖于基于文本中词语出现频率的统计方法。这种方法基于这样的假设如果一对词语经常同时出现那么它们之间的关系必然更密切。这些方法简单易行计算量也不大。其中一种比较有代表性方法是TF-IDF。TF-IDF词频-逆文档频率TF-IDF 的理念是通过考虑两个因素来计算单词在文档中的重要性「词频 (TF)」词语在文档中出现的频率。TF 值越高表示词语对文档越重要。「逆文档频率 (IDF)」词语在文档中的稀缺性。这种方法是基于这样的假设出现在多篇文档中的词语的重要性低于仅出现在少数文档中的词语。TF-IDF 公式由两部分组成分别为词频 (TF) 、逆文档频率 (IDF)总体的计算公式如下其中 表示一个单词 表示一个文档 表示单词 在文档 中出现的次数 表示文档 中所有单词的总次数 表示语料库中总文档数 表示包含单词 的文档数。为了方便理解这里举个实际计算的示例假设我们有一个包含 10 篇文档的语料库而“cat”一词只出现在其中 2 篇文档中。 “cat” 的 IDF 为如果在某个文档中“cat”在总共 100 个单词中出现了 5 次则其 TF5/100 为 0.05。因此该文档中“cat”的最终 TF-IDF 得分为该得分告诉我们“cat”一词对于该特定文档相对于整个语料库的重要程度。得分越高表示该词在该文档中出现的频率越高并且在所有文档中相对较少出现因此其在表征文档内容方面可能更有意义。这里我们在 TinyShakespeare 数据集上使用 TF-IDF。为了模拟多文档我们将文档分成十个块相关代码如下# load the datasetwith open(tinyshakespeare.txt, r) as file: corpus file.read()print(fText corpus includes {len(corpus.split())} words.)# to simulate multiple documents, we chunk up the corpus into 10 piecesN len(corpus) // 10documents [corpus[i:iN] for i in range(0, len(corpus), N)]documents documents[:-1] #last document is residue# now we have N documents from the corpus# Text corpus includes 202651 words.from sklearn.feature_extraction.text import TfidfVectorizer# 默认会将文本中的单词转换为小写并去除停用词如the, is等。在这个例子中我们没有指定停用词因此它会处理所有单词。vectorizer TfidfVectorizer()#首先会计算每个单词在文档中的TF-IDF值。它会生成一个稀疏矩阵每一行代表一个文档每一列代表一个单词。稀疏矩阵中的值是该单词在对应文档中的TF-IDF值。embeddings vectorizer.fit_transform(documents)words vectorizer.get_feature_names_out()print(fWord count: {len(words)} e.g.: {words[:10]})print(fEmbedding shape: {embeddings.shape})### OUTPUT #### Word count: 11446 e.g.: [abandon abase abate abated abbey abbot abed abel abet abhor]# Embedding shape: (10, 11446)这为我们提供了一个 10 维的嵌入向量每个向量对应一个文档这里的文档可以理解为一句话。现在为了更好地理解 TF-IDF 嵌入向量我们使用 PCA 将 10 维空间映射到 2 维空间以便更好地进行可视化。关于这个嵌入向量空间有两点值得注意1.大多数单词都集中在一个特定的区域。这意味着在这种方法中大多数单词的嵌入向量都很相似。这表明这些嵌入向量缺乏表达力和独特性。2.这些嵌入向量之间没有语义联系。单词之间的距离与它们的含义无关。由于 TF-IDF 基于文档中单词的出现频率因此语义上接近的单词例如数字在向量空间中没有关联。TF-IDF 和类似统计方法的简单性使得它们在信息检索、关键词提取和基本文本分析等应用中非常有用。静态Embeddingword2vecword2vec是一种比TF-IDF更先进的技术。顾名思义它是一个旨在将单词转换为嵌入向量的网络。它通过定义一个辅助目标来实现这一点即优化网络的目标。例如「在CBOW连续词袋中word2vec网络被训练成在给定一个单词的相邻词作为输入时预测该单词」。其直观理解是你可以根据该单词周围的单词推断出该单词的嵌入。除了 CBOW 之外另一种变体是 Skipgram其工作原理完全相反它旨在通过给定特定单词作为输入来预测其邻近单词。word2vec的架构非常简单首先通过一个隐藏层从中提取嵌入然后外加一个输出层预测词汇表中所有单词的概率。表面上该网络被训练成根据相邻词预测正确的缺失词但实际上这是训练网络隐藏层并为每个单词找到正确嵌入向量。网络训练完成后最后一层可以被抛弃因为找出Embedding向量才是真正的目标。CBOW word2vec 的工作原理如下选择一个上下文窗口例如上图上下文窗口为4。将特定单词前后两个单词作为输入。将这四个上下文单词编码为one-hot向量。将编码后的向量传入隐藏层该层具有线性激活函数。聚合隐藏层的输出例如使用 lambda 均值函数。将聚合后的输出输入到最后一层该层使用 Softmax 预测每个可能单词的概率。选择概率最高的 token 作为网络的最终输出。隐藏层是存储Embedding的地方。当我们将一个单词的one-hot向量一个除了一个元素设置为 1 之外全为 0 的向量传入网络时这个特定的 1 会触发该单词的嵌入传递到下一层。下面是一个简洁 word2vec 网络实现。由于该网络依赖于上下文中词语之间的关系而不是像 TF-IDF 那样依赖于单词出现的频率因此它能够捕捉词语之间的语义关系。如果你比较感兴趣可以去Google官网下载训练好的模型版本下载链接https://code.google.com/archive/p/word2vec/。以下是实际使用 word2vec 的代码# 下载预训练的embedding向量模型看看它是如何使用的。import gensimmodel gensim.models.KeyedVectors.load_word2vec_format(GoogleNews-vectors-negative300.bin.gz, binaryTrue)print(fThe embedding size: {model.vector_size})print(fThe vocabulary size: {len(model)})# italy - rome london englandmodel.most_similar(positive[london, italy], negative[rome])### OUTPUT ###[(england, 0.5743448734283447), (europe, 0.537047266960144), (liverpool, 0.5141493678092957), (chelsea, 0.5138063430786133), (barcelona, 0.5128480792045593)]model.most_similar(positive[woman, doctor], negative[man])### OUTPUT ###[(gynecologist, 0.7093892097473145), (nurse, 0.6477287411689758), (doctors, 0.6471460461616516), (physician, 0.6438996195793152), (pediatrician, 0.6249487996101379)]为了高效地训练 word2vec尤其是在词汇量较大的情况下可以使用了一种称为负采样的优化技术。负采样不是在整个词汇表上计算完整的 softmax这计算成本很高而是通过只更新少量负样本即随机选择的与上下文无关的词语和正样本来简化任务。这可以让训练速度更快可扩展性更强。更多精彩内容-专注大模型、Agent、RAG等前沿分享上下文EmbeddingBERTBERT 全称为Bidirectional encoder representations from transformers在自然语言处理 (NLP) 领域BERT 无处不在。当前大模型的一些理念方法都会有BERT的影子彻底了解 BERT有利于提高你对大模型的理解。BERT 源自“Attention is all you need”一文中介绍的 Transformer 架构仅使用Transformer编码器通过预训练使其能够生成语义表征并理解语言。BERT可以解决QA问答、文本摘要、分类等任务。BERT 是一个仅使用编码器的 Transformer 模型由四个主要部分组成如上图所示分词器 (Tokenizer)将文本切分为整数序列。嵌入 (Embedding)将离散标记转换为向量的模块。编码器 (Encoder)一堆带有自注意力机制的 Transformer 模块。任务头 (Task Head)当编码器完成表征后这个特定于任务的头会处理这些表征以完成标记生成或分类任务。在预训练阶段BERT需要同时学习两个任务「掩码语言模型」Masked Language ModelMLM预测句子中被掩码的单词我之前 [MASKED] 过这本书 - 阅读过「下一句预测」Next Sentence PredictionNSP给定两个句子预测 A 是否在 B 之前。两句之间添加特殊 [SEP] 标记将两个句子分开这个任务类似于二分类。注意另一个特殊标记 [CLS]。这个特殊标记有助于分类任务。随着模型逐层处理输入[CLS] 成为所有输入标记的集合稍后可用于分类目的。BERT模型之所这么重要是因为它是基于Transformer的语境化动态嵌入的首批应用实例之一。当输入一个句子时BERT 模型的各层会利用自注意力机制和前馈机制来更新并整合句子中所有其它 token 的语境。每个 Transformer 层的最终输出是该单词的语境化表示。大模型Embedding当前Embedding仍然是大型语言模型的基础组件也是一个广义的术语。这里我们重点介绍“嵌入”即把词条转换为向量表征的模块而不是隐藏层中的潜在空间。嵌入在 LLM 中扮演什么角色其实大模型的Embedding属于上下文Embedding的一种。简单来说在基于 Transformer 的模型中“嵌入”一词可以指静态嵌入和动态上下文表征**「静态Embedding」**往往是在第一层生成并将词条嵌入表示词条的向量与位置嵌入编码词条在序列中位置的向量相结合比如BERT模型就是属于静态嵌入。动态上下文Embedding。当输入词条经过自注意力层和前馈层时它们的嵌入会被更新使其与上下文相关。这些动态表征根据词条周围的上下文来捕捉其含义。例如“Bank”一词既可以出现在“river bank”短语中也可以在“bank robbery”短语中。尽管“bank”这个词的标记嵌入在这两种情况下是相同的但它在网络各层中进行转换时就会考虑到“bank”出现的具体上下文。LLM的Embedding时在训练过程中进行优化的。虽然我们也可以使用 Word2Vec 等预训练模型为机器学习模型生成嵌入但 LLM 通常会生成自己的Embedding这些嵌入是输入层的一部分并在训练过程中进行更新。将嵌入优化作为 LLM 训练的一部分而不是使用 Word2Vec其优势在于这些嵌入会根据特定任务和数据进行优化。「LLM 中的嵌入层相当于一个向量索引表」。给定一个索引列表token id它会返回相应的嵌入参考样例如下图所示PyTorch 中大模型嵌入层的代码实现是使用 torch.nn.Embedding 完成的它充当一个简单的查找表。它无需进行one-hot编码而是直接使用索引作为输入其实该层与简单的线性层相比没有什么特别之处。嵌入层只是一个使用索引的线性层。上面介绍说无需one-hot编码其主要原因时如果采用one-hot编码其实原理时一样的直接采用索引会更方便。下面是采用one-hot编码获取嵌入向量的示例DS-Qwen1.5B的Embedding实际大模型Embedding层是怎么样的呢让我们剖析一下 Qwen 模型中 DeepSeek-R1 精简版的Embedding。首先从 Hugging Face 加载 deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B 模型并保存嵌入。import torchfrom transformers import AutoTokenizer, AutoModeltokenizer_name deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5Bmodel_name tokenizer_name# Load the tokenizertokenizer AutoTokenizer.from_pretrained(tokenizer_name)tokenizer.add_special_tokens({pad_token: [PAD]})# Load the pre-trained modelmodel AutoModel.from_pretrained(model_name)# Extract the embeddings layerembeddings model.get_input_embeddings()# Print out the embeddingsprint(fExtracted Embeddings Layer for {model_name}: {embeddings})# Save the embeddings layertorch.save(embeddings.state_dict(), embeddings_qwen.pth)然后加载使用Qwen1.5B模型的嵌入层。将嵌入与模型的其它部分分离、保存和加载的目的是为了更快、更高效地获取输入的嵌入而不是对模型进行完整的前向传递。class EmbeddingModel(nn.Module): def __init__(self, vocab_size, embedding_dim): super(EmbeddingModel, self).__init__() self.embedding nn.Embedding(num_embeddingsvocab_size, embedding_dimembedding_dim) def forward(self, input_ids): return self.embedding(input_ids)vocab_size 151936dimensions 1536embeddings_filename rembeddings_qwen.pthtokenizer_name deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5Btokenizer AutoTokenizer.from_pretrained(tokenizer_name)# Initialize the custom embedding modelmodel EmbeddingModel(vocab_size, dimensions)# Load the saved embeddings from the filesaved_embeddings torch.load(embeddings_filename)# Ensure the weight key exists in the saved embeddings dictionaryifweightnotin saved_embeddings: raise KeyError(The saved embeddings file does not contain weight key.)embeddings_tensor saved_embeddings[weight]# Check if the dimensions matchif embeddings_tensor.size() ! (vocab_size, dimensions): raise ValueError(fThe dimensions of the loaded embeddings do not match the models expected dimensions ({vocab_size}, {dimensions}).)# Assign the extracted embeddings tensor to the models embedding layermodel.embedding.weight.data embeddings_tensor# put the model in eval modemodel.eval()接着看一看如何将一个句子分词然后进行向量化def prompt_to_embeddings(prompt:str): # tokenize the input text tokens tokenizer(prompt, return_tensorspt) input_ids tokens[input_ids] # make a forward pass outputs model(input_ids) # directly use the embeddings layer to get embeddings for the input_ids embeddings outputs # print each token token_id_list tokenizer.encode(prompt, add_special_tokensTrue) token_str [tokenizer.decode(t_id, skip_special_tokensTrue) for t_id in token_id_list] return token_id_list, embeddings, token_strprint_tokens_and_embeddings(HTML coders are not considered programmers)在上面的代码中我们对句子进行了分词并打印了分词的嵌入。这些嵌入是 1536 维向量。这里有一个简单的示例以“HTML coders are not considered programmers”这句话为例。最后让我们看看如何找到与特定单词最相似的嵌入。由于嵌入是向量我们可以使用余弦相似度来找到与特定单词最相似的嵌入。然后我们可以使用 torch.topk 函数来找到前 k 个最相似的嵌入。def find_similar_embeddings(target_embedding, n10): Find the n most similar embeddings to the target embedding using cosine similarity Args: target_embedding: The embedding vector to compare against n: Number of similar embeddings to return (default 3) Returns: List of tuples containing (word, similarity_score) sorted by similarity # Convert target to tensor if not already ifnot isinstance(target_embedding, torch.Tensor): target_embedding torch.tensor(target_embedding) # Get all embeddings from the model all_embeddings model.embedding.weight # Compute cosine similarity between target and all embeddings similarities torch.nn.functional.cosine_similarity( target_embedding.unsqueeze(0), all_embeddings ) # Get top n similar embeddings top_n_similarities, top_n_indices torch.topk(similarities, n) # Convert to word-similarity pairs results [] for idx, score in zip(top_n_indices, top_n_similarities): word tokenizer.decode(idx) results.append((word, score.item())) return resultstoken_id_list, prompt_embeddings, prompt_token_str prompt_to_embeddings(USA and China are the most prominent countries in AI.)tokens_and_neighbors {}for i in range(1, len(prompt_embeddings[0])): token_results find_similar_embeddings(prompt_embeddings[0][i], n6) similar_embs [] for word, score in token_results: similar_embs.append(word.replace( , #)) tokens_and_neighbors[prompt_token_str[i]] similar_embsall_token_embeddings {}# Process each token and its neighborsfor token, neighbors in tokens_and_neighbors.items(): # Get embedding for the original token token_id, token_emb, _ prompt_to_embeddings(token) all_token_embeddings[token] token_emb[0][1] # Get embeddings for each neighbor token for neighbor in neighbors: # Replace # with space neighbor neighbor.replace(#, ) # Get embedding neighbor_id, neighbor_emb, _ prompt_to_embeddings(neighbor) all_token_embeddings[neighbor] neighbor_emb[0][1]Embeddings as Graphs我们如何看待嵌入一种方法是将嵌入层视为一个网络每个Token是一个节点如果两个Token的向量距离较近那么我们假设它们的节点可以通过边连接。例如我们将“*AI agents will be the most hot topic of artificial intelligence in 2025.*”这句话进行Token化将Token转换为Embedding向量然后找到与已有的每个嵌入最相似的20个嵌入则嵌入图如下实际上您可以在文章开头看到一个更全面的示例其中映射了50个标记及其最接近的标记。在上述图示例中我们忽略了“Token变体”。一个标记或单词可能有许多不同的变体每个变体都有各自的嵌入向量。例如标记“list”可能有许多不同的变体每个变体都有各自的嵌入例如“_list”、“List”等等。这些变体通常具有与原始标记非常相似的嵌入。下图是标记“列表”及其近邻包括其变体的图表。结论Embedding仍然是自然语言处理和现代大语言模型的基础部分之一。虽然在LLM 领域的研究每天都在探索新的方法和技术但Embedding在大型语言模型中却没有太大变化。尽管如此它们都是至关重要的「因为它是将文本、图像、语音等内容转换至大模型可理解维度的必经之路」。总之本文主要介绍了关于Embedding的基础知识以及它们从传统统计方法演变为当今大语言模型 (LLM) 用例的过程。通过本文希望能够帮助你对Embedding有一个全面的了解。想入门 AI 大模型却找不到清晰方向备考大厂 AI 岗还在四处搜集零散资料别再浪费时间啦2025 年AI 大模型全套学习资料已整理完毕从学习路线到面试真题从工具教程到行业报告一站式覆盖你的所有需求现在全部免费分享扫码免费领取全部内容一、学习必备100本大模型电子书26 份行业报告 600 套技术PPT帮你看透 AI 趋势想了解大模型的行业动态、商业落地案例大模型电子书这份资料帮你站在 “行业高度” 学 AI1. 100本大模型方向电子书2. 26 份行业研究报告覆盖多领域实践与趋势报告包含阿里、DeepSeek 等权威机构发布的核心内容涵盖职业趋势《AI 职业趋势报告》《中国 AI 人才粮仓模型解析》商业落地《生成式 AI 商业落地白皮书》《AI Agent 应用落地技术白皮书》领域细分《AGI 在金融领域的应用报告》《AI GC 实践案例集》行业监测《2024 年中国大模型季度监测报告》《2025 年中国技术市场发展趋势》。3. 600套技术大会 PPT听行业大咖讲实战PPT 整理自 2024-2025 年热门技术大会包含百度、腾讯、字节等企业的一线实践安全方向《端侧大模型的安全建设》《大模型驱动安全升级腾讯代码安全实践》产品与创新《大模型产品如何创新与创收》《AI 时代的新范式构建 AI 产品》多模态与 Agent《Step-Video 开源模型视频生成进展》《Agentic RAG 的现在与未来》工程落地《从原型到生产AgentOps 加速字节 AI 应用落地》《智能代码助手 CodeFuse 的架构设计》。二、求职必看大厂 AI 岗面试 “弹药库”300 真题 107 道面经直接抱走想冲字节、腾讯、阿里、蔚来等大厂 AI 岗这份面试资料帮你提前 “押题”拒绝临场慌1. 107 道大厂面经覆盖 Prompt、RAG、大模型应用工程师等热门岗位面经整理自 2021-2025 年真实面试场景包含 TPlink、字节、腾讯、蔚来、虾皮、中兴、科大讯飞、京东等企业的高频考题每道题都附带思路解析2. 102 道 AI 大模型真题直击大模型核心考点针对大模型专属考题从概念到实践全面覆盖帮你理清底层逻辑3. 97 道 LLMs 真题聚焦大型语言模型高频问题专门拆解 LLMs 的核心痛点与解决方案比如让很多人头疼的 “复读机问题”三、路线必明 AI 大模型学习路线图1 张图理清核心内容刚接触 AI 大模型不知道该从哪学起这份「AI大模型 学习路线图」直接帮你划重点不用再盲目摸索路线图涵盖 5 大核心板块从基础到进阶层层递进一步步带你从入门到进阶从理论到实战。L1阶段:启航篇丨极速破界AI新时代L1阶段了解大模型的基础知识以及大模型在各个行业的应用和分析学习理解大模型的核心原理、关键技术以及大模型应用场景。L2阶段攻坚篇丨RAG开发实战工坊L2阶段AI大模型RAG应用开发工程主要学习RAG检索增强生成包括Naive RAG、Advanced-RAG以及RAG性能评估还有GraphRAG在内的多个RAG热门项目的分析。L3阶段跃迁篇丨Agent智能体架构设计L3阶段大模型Agent应用架构进阶实现主要学习LangChain、 LIamaIndex框架也会学习到AutoGPT、 MetaGPT等多Agent系统打造Agent智能体。L4阶段精进篇丨模型微调与私有化部署L4阶段大模型的微调和私有化部署更加深入的探讨Transformer架构学习大模型的微调技术利用DeepSpeed、Lamam Factory等工具快速进行模型微调并通过Ollama、vLLM等推理部署框架实现模型的快速部署。L5阶段专题集丨特训篇 【录播课】四、资料领取全套内容免费抱走学 AI 不用再找第二份不管你是 0 基础想入门 AI 大模型还是有基础想冲刺大厂、了解行业趋势这份资料都能满足你现在只需按照提示操作就能免费领取扫码免费领取全部内容2025 年想抓住 AI 大模型的风口别犹豫这份免费资料就是你的 “起跑线”