“把文本变成向量”背后发生了什么

这页不跳过任何关键前因,专门解释”文本为什么能表示成向量""维度到底是什么""为什么语义检索常用余弦相似度”。

标签:Embedding 直觉 | 向量空间 | 余弦相似度 | 小白友好

这页负责数学原理和概念直觉推导(向量空间、余弦、Embedding),不负责术语速查。


这页解决什么

  • 解释”文本为什么能变成向量”,并把余弦相似度和语义检索连接成一条完整因果链。
  • 必须记住的结论:向量不是标签而是语义空间中的方向;余弦更适合比较主题一致而长度不同的文本。
  • 读完后的动作:去看 V1 代码讲解,然后运行最小 RAG 循环,观察 query 和文档的相似度排序。

01 计算机为什么”只能做数学”

你手机里的”张三”,手机认识他吗

你手机里存了 500 个联系人。手机认识”张三”这个人吗?

不认识。 它只是记住了一串数字:13812345678

你在屏幕上看到的”张三”,只是手机把那串数字”翻译”给你看的显示效果。手机从来不理解”张三是谁”——它只存数字,只处理数字。

这不只是手机的限制,而是所有计算机的本质

你现在看的这段文字,也是数字

计算机的底层只有 0 和 1。所有东西,最终都是数字:

  • 你看的视频 → 每一帧都是像素颜色值(一堆数字)
  • 你听的音乐 → 声波振幅的采样值(一堆数字)
  • 你发的消息 → 每个汉字都有编号,“你”是 20320,“好”是 22909

计算机处理的一切,最终都是数字的加减乘除。 它从来不”看”,不”听”,不”理解”——只是算。

那”意思”呢?

“猫很可爱”和”小猫咪特别萌”,你知道这两句话意思一样

但在计算机眼里,这是两串完全不同的汉字编号,没有任何联系。让计算机比较这两句话”有多像”,它只会傻掉——没有规则告诉它”可爱”和”萌”是同一个意思。

核心矛盾:我们需要计算机理解语义,但计算机只会处理数字。

解决思路自然浮现:把”意思”也变成数字。 而且不是随便变——要让数字之间的关系,能反映语义之间的关系。 意思相近的文字 → 变成的数字要”方向相近”。这就是向量要做的事。

随便编号为什么不行

把”猫”编号为 1,“狗”编号为 2,“量子力学”编号为 3——

计算机会认为猫和狗的差距(1)等于狗和量子力学的差距(1)。但现实是猫和狗非常相关,猫和量子力学几乎没关系。

普通编号只是给事物贴标签,不能表达它们之间的关系。 需要一种更好的数字表示:相关的事物在数字层面也”挨在一起”。


02 什么是向量

用两个维度描述食物

用”甜度”和”辣度”两个维度,可以在坐标图上定位任何食物:

  • 番茄:甜度中等,辣度几乎为零 → [5, 0]
  • 糖醋排骨:甜度高,辣度低 → [8, 1]
  • 辣椒:甜度低,辣度极高 → [1, 9]

画在坐标图上,每种食物都是图上的一个点(更精确说是从原点出发的一个方向)。番茄和糖醋排骨挨得很近,因为都偏甜。辣椒在另一个角落。

向量就是:从原点出发的一条有方向的线,用一组数字表示坐标。 两条线的夹角越小,方向越相近——语义越相近。 余弦相似度量的正是这个夹角有多小(cos 0° = 1,cos 90° = 0)。

真实 Embedding 不是 2 维,而是 1024 维(BGE-M3)或 1536 维(text-embedding-3-small)。道理完全一样,只是维度更多,能捕捉更复杂的语义关系。


03 1024 个维度,每个代表什么意思

先纠正一个几乎所有人第一次都会犯的误解: 不是每个维度单独代表”动物相关性""甜度""是否有生命”这类可命名的特征。 单个维度对人类来说完全不可读,没有名字,没有独立意义。

彩色照片是怎么存的——RGB 三个数字

每个像素存三个数字:红 R、绿 G、蓝 B。没有任何一个数字单独”是”某种颜色。是三个数字的组合决定了颜色。

颜色值结果
R=255, G=0, B=0红色(只有 R 有值)
R=255, G=255, B=0黄色(R 和 G 都有值,两者合力)
R=70, G=130, B=180钢蓝色(三个数字合力,任何单个数字单独没意义)

Embedding 向量做的是同一件事,从 3 维扩到 1024 维

“猫” 的向量:[0.023, -0.018, 0.045, 0.012, ... (共1024个数字)]

  • 没有哪个数字单独”是”动物相关性。
  • 没有哪个数字单独”是”可爱程度。
  • 没有任何一个维度有名字。

是 1024 个数字作为整体,在高维空间里的方向,决定了语义。

研究者偶尔发现某几个维度大致对应”性别”或”时态”这类概念,但这是偶然观察到的,不是设计出来的。神经网络自己找到这种表示方式,这些维度对人类不可读,是黑盒。

更准确的说法:1024 个数字合在一起,是这段文字语义的”数字指纹”。 就像一张照片里每个像素的 RGB 组合在一起才是那张照片, 向量的 1024 个数字组合在一起才是那段文字的语义。 任何单个数字单独拿出来,都毫无意义。


04 “变成向量”具体是怎么发生的

一个关键假设:意思由上下文决定

1954 年,语言学家 Zellig Harris 提出了一个假设,后来成为所有词向量技术的根基:

“一个词的意思,可以从它经常出现的上下文来理解。”

  • “猫”经常和”养猫""猫粮""猫爪""可爱”一起出现。
  • “狗”经常和”养狗""狗粮""狗爪""可爱”一起出现。
  • 两者上下文高度重叠 → 意思相近。
  • “量子力学”的上下文是”波函数""叠加态""薛定谔”——和”猫”几乎不重叠。

神经网络从数十亿条文字里学这个关系

Embedding 模型是一个神经网络,在数十亿条文本上训练。

训练任务的本质是:“给你一段话,预测哪些段话和它相关。”

通过反复调整参数,让相关文本的向量越来越近,不相关的越来越远。训练完成后固定下来——你喂给它一段文字,它输出 1024 维的语义指纹。

文本输入 → Embedding Model → 输出向量 (1024维)
"猫很可爱"   BGE-M3 / text-emb-3   [ 0.023, -0.018, 0.045, 0.012,
             数十亿文本训练而成        0.031, -0.009, ... 共1024个 ]
             1024维 / 1536维         固定长度的语义指纹

05 这是谁发明的,怎么想到的

向量表示语义,不是一个人想到的,是三个时代接力的结果。

1843 年 — 哈密顿(Hamilton)· 爱尔兰数学家

研究怎么用数字描述三维空间中的旋转,发展出”向量”的数学概念。之后格拉斯曼系统化,吉布斯和亥维赛变成了今天物理课本里的样子。这时候向量只是”描述空间方向和长度的工具”,跟语言没有任何关系。

1954 年 — Zellig Harris · 美国语言学家

提出”分布式语义假设”:“一个词的意思,由它经常出现的上下文决定。”

这是纯语言学假设,不是技术。但它埋下了几十年后所有词向量技术的种子。没有这个假设,就没有后面的一切。

2013 年 ★ — Tomas Mikolov · 谷歌研究员 · 真正的转折点

发表论文,提出 Word2Vec

他用神经网络训练一个任务:“给你一个词,预测它周围会出现什么词”。训练完之后,他没有关注输出,而是提取网络内部学到的参数——发现这些参数本身就是高质量的语义向量。

他展示了一个震惊所有人的例子:

国王 − 男人 + 女人 = 皇后

向量做加减法,结果在语义上完全正确。这说明向量真的学到了语义关系,不是随机数字。整个 AI 学界都傻了。

2018+ — BERT / GPT 时代 → 句子级 Embedding

Word2Vec 只能给单个词生成向量。BERT 等模型开始生成整句话、整段文章的向量,同一个词在不同语境里有不同的向量(“苹果手机”里的”苹果”和”苹果树”里的不一样)。

RAG 用的 BGE-M3、text-embedding-3,就是这条路走到今天的结果。

一句话总结: 数学家发明了向量来描述空间(1843) → 语言学家发现意思可以由上下文定义(1954) → Mikolov 用神经网络把两件事合在一起,“国王−男人+女人=皇后”(2013) → 今天的 Embedding 模型继承了这一切


06 1024 维能装多少词,维度能无限大吗

1024 维的空间,远比你想象的大

这个问题其实问反了——不是”能装多少词”,而是”空间够不够用”。

类比:地球表面用经度和纬度两个维度就能定位任意一个点。全球 80 亿人每人一个独立地址,两维就装得下,绰绰有余。不是因为地球只有 80 亿个格子,而是坐标是连续的,理论上有无限个位置。

1024 维浮点数空间,能放下的不同位置数量,比宇宙里所有原子数量还大几百个数量级。

装下人类所有语言的所有词和句子,绰绰有余。 真正决定质量的不是维度够不够大,而是训练数据够不够多——语义相近的内容有没有被放到真正相近的位置上。

BGE-M3 用 1024 维,在中文场景里经常比 text-embedding-3-large(3072维)还好。 维度多不代表理解力强。瓶颈永远是训练质量,不是空间大小。

维度能无限加吗?不能。有三堵墙:

第一堵墙:维度诅咒

数学上已经证明的现象:维度越高,“近”和”远”的区别越模糊。

在二维平面,邻居和远邻差别明显。但维度极高时,所有点之间的距离趋向相等——没什么东西明显更近或更远,“最相似”和”完全无关”越来越难区分。

第二堵墙:数据不够填满

维度越高,需要的训练样本越多才能有效覆盖整个空间。

1 亿条训练语料,能有效填满的语义空间大概只需要几百到几千维。再加维度,大量空间没有样本覆盖,模型不知道那些方向该放什么——等于浪费,反而引入噪声。

第三堵墙:成本线性增长

每次检索都要算余弦相似度。1024 维算一次,3072 维要贵 3 倍。如果有 1000 万个文档,每次查询和它们全部算一遍——维度翻 3 倍,系统慢 3 倍,存储费用翻 3 倍。成本是工程现实,不能无视。

维度三问 · 总结

  • 问:每个维度代表什么特征?→ 没有名字,不可读。1024个数字整体才有意义。如同 RGB 三个数字整体决定颜色,单个数字单独没意义。
  • 问:1024维能装多少词?→ 问反了。空间容量远超需求。瓶颈是训练质量,不是空间大小。
  • 问:维度可以无限大吗?→ 不行。三堵墙:维度诅咒(太高近远难分)、数据不够填满(浪费引入噪声)、成本线性增长。

07 为什么用余弦相似度,不用欧氏距离

各自在量什么

欧氏距离:两点之间的直线距离。量的是”你们离得多远”。

余弦相似度:两向量夹角的余弦值。完全不看距离,只看角度——“你们指的方向有多接近”。夹角 0° → cos=1(完全相同方向);夹角 90° → cos=0(垂直,无关)。

文本长度会影响向量模长,但不影响语义

“猫很可爱”(4个字)和”猫咪非常可爱,毛茸茸,爱睡觉,还会捉老鼠”(20个字),语义几乎一样——都在说猫很可爱。

但后者文字多,模型处理了更多 token,输出向量的模长(长度)更大

如果用欧氏距离,这两句话”距离”会很大,尽管语义几乎相同。两篇主题完全不同但都很短的文章,欧氏距离反而可能更小——这不是我们要的。

欧氏距离余弦相似度
公式√Σ(aᵢ − bᵢ)²(A·B) / (
量的是两点间的直线距离两向量方向的夹角
问题/优势文本越长 → 向量模长越大 → 欧氏距离越大,即使语义完全相同也一样分母
结论❌ 被文本长度干扰✅ 只看方向,不受长度影响

完整逻辑链 · 从零到余弦

01  计算机只处理数字,无法直接比较文字意思(手机只记号码,不认识张三)
    ↓ 需要把"意思"转化成数字
02  向量是"带方向的数字",方向相近 = 语义相近(食物坐标系)
    ↓ 普通编号不能反映语义关系
03  1024维向量没有每个维度的名字,是整体决定语义(类比 RGB 颜色)
    ↓ 神经网络训练学会这种表示
04  分布式假设(1954) + Word2Vec(2013) = 现代 Embedding 技术的根基
    ↓ 维度太高会遇到维度诅咒 + 数据 + 成本三堵墙
05  "比较语义" = "比较向量方向",但欧氏距离被文本长度干扰
    ↓ 余弦相似度的分母消除了模长影响,只看方向
✓  余弦相似度是 RAG 语义检索的正确工具

08 国内模型选型与快速接入

推荐方案(最省事):硅基流动(SiliconFlow)

一个 key 同时提供 BGE-M3 embedding + Qwen chat,OpenAI 协议兼容,只改 base_url。有免费额度。

提供商Embedding 模型Chat 模型协议费用适用
硅基流动 ★BAAI/bge-m3 (1024维)Qwen2.5-7BOpenAI兼容有免费额度课程首选
智谱 AIembedding-3 (2048维)GLM-4-Flash原生SDKFlash免费中文强
通义千问text-embedding-v3Qwen-PlusOpenAI兼容按量计费企业稳定
DeepSeek❌ 无embeddingDeepSeek-ChatOpenAI兼容极低价格配合硅基流动

快速接入(硅基流动 · 5 分钟跑通)

# 1. 安装
pip install openai numpy
 
# 2. 注册并获取 key:https://siliconflow.cn
export SILICONFLOW_API_KEY="sf-xxx"
 
# 3. 修改 code/00_配置提供商_先改这个.py
# PROVIDER = "siliconflow"
 
# 4. 验证连通性
python code/00_配置提供商_先改这个.py
 
# 5. 运行课程代码(无需其他改动)
python code/01_v1_最小RAG循环.py

读完这一页后

  • 你现在应该会:解释为什么语义检索需要 embedding,为什么相似度通常用余弦而不是欧氏距离。
  • 马上做的实验:运行 code/01_v1_最小RAG循环.py,观察 query 和文档的相似度排序。
  • 继续阅读:代码讲解 V1 · 知识地图 · 文档索引