完整学习LLM(五):Embedding是什么,为什么文本能变成向量 完整学习LLM(五):Embedding是什么,为什么文本能变成向量好家伙, 先贴一篇好文章 https://developers.openai.com/api/docs/guides/embeddings (openai团队写的,值得信赖)上一篇我们聊了 Token.当时说到一句话:文字进入模型之前,要先变成 token.模型生成答案时,也是一个 token 一个 token 往外接.但这里还有一个问题:Token 之后是什么?模型不能只拿着文字碎片干活.它最终还是要把这些东西变成数字.更准确一点:变成向量.这就引出了今天的主题:Embedding 是什么?为什么文本能变成向量?为什么 RAG 能根据语义找到相似文档?这篇就专门拆这个问题.0.背景:为什么我会关心Embedding我最早接触 Embedding,其实是在看 RAG.RAG 的流程大概是:用户提问- 系统检索相关资料- 把资料交给大模型- 大模型基于资料回答这里最神奇的一步是:系统怎么知道哪些资料相关?如果只是关键词搜索,那很好理解.比如用户问:战斗监控接口怎么部署?系统去搜:战斗监控部署接口这样能搜到一部分.但很多时候,用户问法和文档写法不一样.比如用户问:怎么查看战斗服运行状态?文档里写的是:battle monitor 用于观察战斗服务健康情况.关键词不完全一样.但意思接近.这时候就需要语义检索.而语义检索背后的关键,就是 Embedding.1.先别想复杂:Embedding就是把文本变成向量先给一个最简单的定义:Embedding 把文本、图片、音频等内容变成一组数字向量.这组数字长得大概像这样:[0.12, -0.08, 0.31, 0.44, ...]它不是给人看的.它是给模型和程序算的.比如一段文本:RAG 是让大模型先检索资料再回答问题.经过 embedding 模型之后,会变成一个向量.另一段文本:检索增强生成可以在回答前查找外部知识.也会变成一个向量.这两句话字面上不完全一样.但意思很接近.所以它们对应的向量应该也比较接近.这就是 Embedding 最核心的价值:把语义变成可以计算距离的数字.2.为什么文本要变成向量因为计算机擅长算数字.不擅长直接理解:这句话和那句话意思像不像.如果文本被变成向量,那我们就可以计算:两个向量的距离两个向量的夹角两个向量的相似度比如:文本A: RAG 是什么文本B: 检索增强生成是什么文本C: 我想喝一杯咖啡从语义上看:A 和 B 更接近.A 和 C 更远.Embedding 要做的事情,就是让这种语义关系在数字空间里也能体现出来.也就是说:意思接近的文本,向量距离更近.意思不相关的文本,向量距离更远.当然这只是直觉解释.真实的向量维度可能很高,不是二维图能画出来的.但我们可以先用二维图理解:3.Embedding和RAG怎么连起来RAG 里通常会先做一件事:把文档切块.比如一份部署文档很长.系统不会直接把整篇文档当成一个整体.而是切成很多片段:chunk 1: 项目背景chunk 2: Docker Compose 配置chunk 3: PostgreSQL 配置chunk 4: Nginx 反向代理chunk 5: 健康检查接口然后每个 chunk 都生成一个 embedding 向量.这些向量会被存到向量库里.用户提问时:战斗监控接口怎么部署?系统也会把这个问题变成一个向量.然后拿这个问题向量,去向量库里找最接近的文档向量.找到以后,再把对应的文档片段拿出来给大模型.流程大概是:这就是为什么我前面说:Embedding 是 RAG 的底层能力之一.没有 Embedding,RAG 就很难做语义检索.最多只能做关键词搜索.4.Embedding和Token是什么关系上一篇讲 Token.这一篇讲 Embedding.它们很容易混在一起.我现在这样理解:Token 是文本切分单位.Embedding 是把文本表示成向量.比如:我想学习大模型先可能被切成:[我] [想] [学习] [大模型]这是 token 层面.之后模型会把这些 token 转成它能计算的表示.如果是专门做检索的 embedding 模型,它通常会把一段文本压成一个向量.比如:我想学习大模型 - [0.12, -0.08, 0.31, ...]所以不要把它们混成一件事.Token 更像是切分.Embedding 更像是编码后的语义坐标.5.为什么向量能表示语义这里就会稍微有点抽象.Embedding 不是人手写出来的.不是我们给每个词规定:大模型 [1, 0, 0]RAG [0, 1, 0]咖啡 [0, 0, 1]这样太粗糙.真实的 Embedding 是模型训练出来的.它会从大量文本中学习:哪些词经常出现在相似上下文里哪些句子表达相近含义哪些概念之间有关系这类思想很早就有.比如 Word2Vec 论文里就强调,词向量可以从大量文本中学到词之间的关系.后来 Sentence-BERT 这类工作,又把句子级别的语义相似做得更适合检索和匹配.所以 Embedding 背后不是魔法.它是通过训练,把语言里的统计关系和语义关系压到向量空间里.直觉上可以这样记:模型见过足够多文本之后,会学到哪些表达在语义上更接近,再把这种接近关系编码进向量.6.相似度是怎么比较的有了向量以后,就可以比较相似度.常见方式之一叫:余弦相似度先不急着看公式.直觉上就是看两个向量方向像不像.如果方向接近,说明语义可能接近.如果方向差很远,说明语义可能不相关.还是用前面的例子.用户问:RAG 是什么?知识库里有三段文档:文档A: RAG 是检索增强生成.文档B: Docker Compose 用于编排容器.文档C: 奶茶和咖啡都属于饮品.系统不会直接拿这三段文字和问题做字符串比较.它会先做四次 embedding:问题: RAG 是什么?- 问题向量 Q文档A: RAG 是检索增强生成.- 文档向量 A文档B: Docker Compose 用于编排容器.- 文档向量 B文档C: 奶茶和咖啡都属于饮品.- 文档向量 C然后比较:Q 和 A 的相似度Q 和 B 的相似度Q 和 C 的相似度假设算出来的结果是:Q vs A 0.91Q vs B 0.36Q vs C 0.12这个数字可以先粗暴理解成:越接近 1,越相似.越接近 0,越不相关.所以系统排序时会得到:第 1 名: 文档A 0.91第 2 名: 文档B 0.36第 3 名: 文档C 0.12如果我们设置:TopK 1系统就只拿文档A.如果设置:TopK 2系统可能会拿文档A和文档B.但这里要注意:相似度高,只代表更可能相关.不代表它一定能回答问题.比如文档B虽然和 Docker 有关,和 RAG 问题也许有一点技术背景上的关系,但它并不能回答:RAG 是什么?所以在 RAG 系统里,相似度比较通常只是第一步.后面还可能需要:重排 rerank过滤低分片段让模型判断片段是否真的能回答问题显示引用来源再换一个更贴近项目的例子.用户问:战斗监控接口怎么部署?文档里有这些片段:文档A: battle monitor 服务需要配置 PostgreSQL 和 Nginx.文档B: 战斗服运行状态可以通过监控接口查看.文档C: 装备表里 attack 字段表示攻击力.关键词看起来不一定完全一样.比如用户说的是:战斗监控接口文档A里写的是:battle monitor 服务但 embedding 可能能判断它们语义接近.所以系统可能给出:问题向量 vs 文档A 0.88问题向量 vs 文档B 0.74问题向量 vs 文档C 0.21这时候系统就会优先拿:文档A文档B交给大模型.大模型再基于这两个片段组织回答.所以完整流程更像:用户问题- 变成问题向量- 和文档向量逐个算相似度- 按分数排序- 取 TopK- 把片段交给大模型- 大模型组织答案这就是语义检索.它不是在问:有没有完全一样的关键词?而是在问:哪段文本和用户问题在语义空间里更接近?这也是 Embedding 能支撑 RAG 的原因.7.Embedding适合做什么Embedding 很适合这些任务:语义搜索相似问题匹配文档去重推荐系统聚类分析RAG 检索根据问题找相关资料比如我有很多学习笔记.用户问:大模型为什么会胡说?文档里可能没有完全一样的标题.但有几篇文章讲过:幻觉RAG上下文不足模型生成机制Embedding 检索就可能把这些文章找出来.因为它找的不是完全一样的关键词.而是语义上相关的内容.8.Embedding不适合做什么Embedding 也有边界.它不适合做精确计算.比如:找出攻击力大于 50 的装备统计一共有多少条记录按价格从高到低排序判断某个权限是否允许这些问题应该交给数据库或程序.Embedding 可以辅助理解:用户想查装备配置用户条件是攻击力 50但最终筛选应该走结构化查询.这点和我之前写 RAG 边界时讲的一样.Embedding 解决的是:语义相似不是:精确筛选严格计算权限判断9.容易踩的坑第一个坑:以为Embedding能理解所有东西.不一定.如果文本太短、上下文太少,向量可能不够准确.第二个坑:以为相似度高就一定是正确答案.相似度高只说明它可能相关.不代表它一定能回答问题.第三个坑:文档切块太随意.chunk 切不好,embedding 再强也可能召回错误片段.第四个坑:只用向量检索,不做重排.复杂问题里,第一轮向量召回不一定够准.后面可能还需要 rerank.第五个坑:拿Embedding做数据库该做的事.比如数值筛选、排序、统计.这些还是应该让数据库来.10.这些引用到底说明了什么这里我想把参考资料说得更直白一点.不然只放几个论文和官方文档,看起来很专业,但对刚开始学习的人不一定有帮助.我引用这些资料,主要不是为了堆出处.而是为了说明几个关键点.第一个参考是 OpenAI 的 Embeddings 文档.它主要说明的是:Embedding 可以把文本变成数字向量.这些向量可以用来做搜索、聚类、推荐、分类等任务.也就是说,我们这篇文章里讲的:文本 - 向量 - 比较相似度不是我自己编出来的理解.这是 embedding 在实际 API 里最常见的用法.第二个参考是 Google 的机器学习课程.它主要说明的是:Embedding 是一种把复杂对象表示成向量的方法.这里的复杂对象可以是词,也可以是其他离散特征.对我们这篇文章来说,只需要记住:Embedding 的目的,是把原本不好计算的东西,变成可以计算距离的向量.第三个参考是 Word2Vec 论文.这篇论文比较早,也比较经典.它对我们理解 Embedding 的帮助是:词不是只能用编号表示.词也可以被训练成有语义关系的向量.比如:意思接近的词,向量可以更接近.经常出现在类似上下文里的词,模型可以学到它们之间的关系.我们不需要一开始就读懂论文公式.先知道它说明了一个方向就够了:语言可以被训练成向量空间里的表示.第四个参考是 Sentence-BERT.它主要和句子级别的语义相似有关.Word2Vec 更偏词.但 RAG 里我们经常比较的不是单个词,而是一段话、一小块文档、一个问题.所以 Sentence-BERT 对这篇文章的意义是:不只是词可以变向量.句子和文本片段也可以变成适合比较相似度的向量.这就和 RAG 更接近了.因为 RAG 检索时常见的问题就是:用户问题 和 哪个文档片段语义最接近?所以这些引用放在一起,我现在会这样理解:OpenAI 文档告诉我 Embedding 在工程里怎么用.Google 课程告诉我 Embedding 是一种向量表示方法.Word2Vec 告诉我词可以学成向量.Sentence-BERT 告诉我句子和文本片段也可以做语义向量.最后落到这篇文章上,就是一句话:Embedding 不是一个新鲜噱头.它是把文本变成可计算语义表示的一类基础方法.RAG 只是把这个能力用得非常明显.11.总结这篇主要想记住一句话:Embedding 是把文本变成向量,让语义相似可以被计算.它解决的问题是:这段文本和哪段文本意思更接近?这个问题应该找哪些资料?这些文档能不能按语义聚在一起?它不解决的问题是:精确筛选严格计算权限判断数据库排序所以放到项目里,我会这样分工:Embedding 负责找相关资料.数据库负责精确查询.大模型负责组织答案.最后一句话总结:Token 让文本进入模型.Embedding 让文本拥有可计算的语义位置.下一篇方向:上下文窗口是什么?为什么模型会忘东西?