“把文本变成向量”背后发生了什么
这页不跳过任何关键前因,专门解释”文本为什么能表示成向量""维度到底是什么""为什么语义检索常用余弦相似度”。
标签: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-7B | OpenAI兼容 | 有免费额度 | 课程首选 |
| 智谱 AI | embedding-3 (2048维) | GLM-4-Flash | 原生SDK | Flash免费 | 中文强 |
| 通义千问 | text-embedding-v3 | Qwen-Plus | OpenAI兼容 | 按量计费 | 企业稳定 |
| DeepSeek | ❌ 无embedding | DeepSeek-Chat | OpenAI兼容 | 极低价格 | 配合硅基流动 |
快速接入(硅基流动 · 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 · 知识地图 · 文档索引