9.4 文本嵌入与语义检索

上一节介绍了词嵌入的理论基础。本节进一步探讨如何将这些原理应用到实际的文本检索中——文本嵌入(Text Embedding)技术如何支撑 RAG 系统的语义检索能力。
9.4.1 从词向量到文档向量
词袋模型的局限
早期的文本表示方法是词袋模型(Bag of Words, BoW)。它把一段文字看作词语的集合,统计每个词出现的频率,忽略词序和语法结构。
词袋模型的一个变体是简单平均法:先为每个词分配一个向量(词向量),然后把句子中所有词向量取平均,作为句子的表示。
这种方法存在明显缺陷:
- 语序丢失:「央行加息」和「加息央行」得到相同的向量
- 语义稀释:句子越长,平均后的向量越趋向通用含义,区分度下降
- 无法处理多义词:「苹果」在「吃苹果」和「苹果公司」中的含义完全不同,但词向量相同
文本嵌入的目标
文本嵌入(Text Embedding)要解决的核心问题是:如何将任意长度的文本映射到固定维度的向量空间,使得语义相近的文本在向量空间中距离相近。
与简单平均不同,现代文本嵌入模型能够:
- 捕捉词序信息:「央行加息」和「加息预期」表达不同含义
- 理解上下文:同一个词在不同语境中获得不同表示
- 保持语义一致性:「降低利率」和「降息」应映射到相近位置
这正是 Transformer 架构带来的突破。
9.4.2 Transformer 编码器与文本表示
Self-Attention 的直观理解
Transformer 是 2017 年提出的神经网络架构,如今已成为自然语言处理的基础设施。其核心机制是自注意力(Self-Attention)。
自注意力的作用可以这样理解:在处理一个句子时,模型会让每个词关注句子中的其他词,根据相关性加权汇总信息。
以句子「央行宣布下调存款准备金率」为例:
- 「下调」会重点关注「央行」(谁下调)和「准备金率」(下调什么)
- 「准备金率」会关注「存款」(哪种准备金)和「下调」(发生什么变化)
- 每个词的最终表示融合了它与其他词的语义关联
这种机制使模型能够理解长距离依赖关系。在传统的循环神经网络中,句首和句尾的词很难建立直接联系;而在 Transformer 中,任意两个词都能直接建立关联。
Transformer 架构由 Vaswani 等人在论文「Attention Is All You Need」(2017)中提出。这篇论文的核心洞见是:仅用注意力机制就能构建高性能的序列模型,不需要循环或卷积结构。如今,几乎所有主流大语言模型(GPT、Claude、LLaMA)都基于 Transformer 架构。
BERT 与句子表示
BERT(Bidirectional Encoder Representations from Transformers,双向编码器表示)是 Google 于 2018 年推出的预训练语言模型。它专门用于生成文本的向量表示。
BERT 的核心设计是双向上下文建模。在处理一个词时,它同时考虑左侧和右侧的上下文。这与 GPT 类模型不同——GPT 只能看到左侧的词(用于生成下一个词),而 BERT 能综合利用完整的句子信息。
[CLS] Token 的作用
BERT 在输入文本的开头添加一个特殊标记 [CLS](Classification)。这个标记不代表任何具体的词,而是用于汇聚整个句子的语义信息。
处理流程如下:
输入: [CLS] 央行 宣布 降准 0.5 个 百分点 [SEP]
↓
Transformer 编码器(多层 Self-Attention)
↓
输出: [CLS]向量 央行向量 宣布向量 降准向量 ...
[CLS] 向量即为整个句子的语义表示[CLS] 位置的输出向量浓缩了句子的整体含义,可直接用于下游任务:文本分类、语义相似度计算、信息检索等。
编码器与生成模型的区别
理解 BERT 类编码器与 GPT 类生成模型的区别很重要:
| 特征 | 编码器(BERT 类) | 生成模型(GPT 类) |
|---|---|---|
| 注意力方向 | 双向(看完整句子) | 单向(只看左侧) |
| 主要任务 | 理解、分类、检索 | 生成、续写、对话 |
| 输出形式 | 固定维度向量 | 下一个 token 的概率分布 |
| 典型应用 | 文本嵌入、语义搜索 | 聊天机器人、内容生成 |
在 RAG 系统中,编码器负责将文档和查询转换为向量,用于相似度计算;生成模型负责基于检索结果生成最终回答。两者各司其职。
9.4.3 双编码器架构
查询与文档分别编码
在实际的语义检索系统中,通常采用双编码器架构(Bi-Encoder)。其核心思想是:用同一个编码器分别处理查询和文档,将它们映射到同一个向量空间。
查询编码:
"降准政策的影响" → 编码器 → 查询向量 (1024维)
文档编码:
"央行降准有助于释放流动性..." → 编码器 → 文档向量 (1024维)
相似度计算:
查询向量 · 文档向量 = 相似度分数这种架构的关键优势在于:文档向量可以离线预计算。知识库中的所有文档在索引阶段就完成向量化,存入向量数据库。检索时只需计算查询向量,然后与预存的文档向量比较,速度极快。
双编码器的权衡
双编码器架构有明显的优缺点:
| 优点 | 缺点 |
|---|---|
| 文档可离线索引,检索速度快 | 查询与文档独立编码,交互信息损失 |
| 支持大规模向量库(百万级) | 细粒度语义匹配能力有限 |
| 计算成本可控 | 对复杂查询(多条件、否定句)效果较差 |
这些缺点可以通过重排序(Reranking)来弥补。初检使用双编码器快速筛选候选文档,精排使用交叉编码器(Cross-Encoder)对查询-文档对进行联合建模,获得更精确的相关性判断。
9.4.4 余弦相似度的数学与直觉
定义与计算
余弦相似度(Cosine Similarity)衡量两个向量方向的一致程度。分子是两个向量的点积,分母是两个向量长度的乘积。这个比值等于两向量夹角的余弦值。
余弦函数的性质决定了相似度的取值范围:当两向量方向完全相同时,夹角为 0°,余弦值为 1;当两向量垂直时,夹角为 90°,余弦值为 0;当两向量方向完全相反时,夹角为 180°,余弦值为 -1。
为何用方向而非距离
一个自然的问题是:为什么不直接用欧氏距离衡量相似性?
欧氏距离计算两点之间的直线距离。问题在于,它对向量的长度敏感。假设两段文本语义相同,但其中一段更长,其向量的模长(长度)可能更大。用欧氏距离衡量,这两段文本反而显得不相似。
余弦相似度只关注方向,忽略长度。这意味着:
- 一篇 1000 字的政策解读和一段 100 字的摘要,只要表达的核心含义相同,余弦相似度就会很高
- 文本长度的差异不会干扰语义相似度的判断
这正是文本检索所需要的特性。用户的查询通常很短(一句话),而文档片段可能有几百字,但只要语义匹配,就应该被检索到。
数值范围与实际含义
余弦相似度的取值范围是 [-1, 1]:
| 相似度范围 | 含义 | 文本检索中的例子 |
|---|---|---|
| 0.85 - 1.0 | 高度相似 | 同义改写、精确匹配 |
| 0.65 - 0.85 | 相关 | 讨论同一话题的不同表述 |
| 0.4 - 0.65 | 弱相关 | 同一领域但话题不同 |
| 0 - 0.4 | 基本无关 | 不同领域的内容 |
| < 0 | 语义相反 | 在实际应用中较少见 |
在 RAG 系统中,通常设置相似度阈值(如 0.6),低于阈值的检索结果不予采纳。这个阈值需要根据具体场景调整——金融政策查询对精确度要求高,可以设置较高阈值;一般性问答可以适当放宽。
9.4.5 嵌入模型的选择
维度的权衡
嵌入模型输出的向量维度是一个重要的设计参数。维度越高,能够编码的语义信息越丰富,但计算和存储成本也越大。
| 维度 | 存储成本 | 检索速度 | 语义精度 | 适用场景 |
|---|---|---|---|---|
| 256-384 | 低 | 快 | 一般 | 原型开发、资源受限 |
| 512-768 | 中等 | 较快 | 良好 | 大多数生产应用 |
| 1024 | 中等偏高 | 中等 | 较高 | 高精度检索需求 |
| 3072-4096 | 高 | 较慢 | 最高 | 极致精度场景 |
对于金融文档检索,768-1024 维通常是合适的选择。维度过低会损失细微的语义差异(如区分「加息」和「降息」的政策取向),维度过高则带来不必要的计算开销。
多语言与中文优化
嵌入模型的训练数据决定了它对不同语言的处理能力。选择模型时需考虑:
- 英文为主的模型(如 all-MiniLM-L6-v2):英文效果好,中文能力有限
- 多语言模型(如 OpenAI text-embedding-3):覆盖多种语言,中文表现尚可
- 中文优化模型(如 bge-small-zh、text2vec-chinese):专门针对中文训练,中文效果最佳
金融领域存在大量中文专业术语(如「逆回购」「MLF」「LPR」),选用中文优化模型能更准确地理解这些概念。
主流嵌入模型概览
| 模型 | 提供方 | 维度 | 特点 | 推荐场景 |
|---|---|---|---|---|
| text-embedding-3-small | OpenAI | 1536 | 多语言、质量高 | 快速起步、API 调用 |
| text-embedding-3-large | OpenAI | 3072 | 最高精度 | 对精度要求极高 |
| bge-small-zh-v1.5 | BAAI | 512 | 中文优化、轻量 | 中文场景、本地部署 |
| bge-large-zh-v1.5 | BAAI | 1024 | 中文优化、高精度 | 高精度中文检索 |
| bge-m3 | BAAI | 1024 | 多检索模式 | 混合检索场景 |
| Qwen2.5-Embedding-0.6B | 阿里云 | 1024 | 中英双语、平衡 | 双语场景、本地部署 |
对于本书的学习者,推荐以下选择路径:
- 快速上手:使用 OpenAI text-embedding-3-small,通过 API 调用,无需本地配置
- 本地部署:使用 bge-small-zh-v1.5 或 Qwen2.5-Embedding-0.6B,免费且中文效果好
- 生产环境:根据实际测试结果选择,通常 bge-large-zh 或 text-embedding-3-large 表现最佳