李沐深度学习191集课程全解析:模块拆解、学习路径
吴恩达《面向开发者的提示词工程》
吴恩达 MCP 教程(Model Context Protocol)(一)
多模态大模型教程学习笔记 --- ViT · CLIP · SAM · GLIP · Stable Diffusion
一句话总结: RAG 的检索上限由底座决定。本模块讲透三件事:Embedding 如何把文本变成可计算语义的向量(word2vec 的 CBOW/Skip-gram、微调与 MTEB 评估);Rerank 如何用"双编码粗召回 + 交叉编码精排"两阶段架构把准确率拉满(CrossEncoder 微调、RankGPT、模型合并);以及向量数据库如何用相似度度量、ANN 索引(HNSW/IVF)和 k-means 实现毫秒检索,并给出 Chroma / Qdrant / Milvus / pgvector 的选型与代码。
素材覆盖说明: 模块四共 9 集(第 46-54 集),本地视频与字幕齐全,全部据字幕据实整理,无补全小节。
一、可视化导览
本模块的两阶段检索架构、word2vec 双架构、相似度度量、索引算法与向量库选型矩阵已整理成一张知识图谱:模块四 · Embedding · Rerank · 向量库 · 可视化图谱
1.1 为什么说检索的上限由底座决定
模块三我们讲了一整条检索增强链路,你可能会觉得,效果不好就去调提示词、调切分。但这一模块要告诉你一个更底层的事实:你在链路上层做的所有优化,能改善多少,其实被两个更基础的东西死死限制着。一个是把文本变成向量的那个模型,另一个是把候选结果重新排序的那个模型。如果连"两段话意思相近"这件最基本的事都算不准,后面再怎么调提示词都是白搭。这就是为什么本模块叫检索底座------它决定了整个系统的天花板,你在天花板下面再怎么努力,也高不过它。
打个比方。检索问答系统像一个图书管理员帮你找资料。你问一个问题,他先从成千上万本书里挑出可能相关的几十本粗看一遍,这就是粗召回;然后再从这几十本里仔细挑出最相关的三五本递给你,这就是精排。粗召回快但不够准,精排准但很慢。理想的管理员是:粗召回时宁可多挑几本也不漏掉,精排时慢一点但要挑得准。整个检索工程,就是在训练这个管理员的"眼力"------粗召回的眼力靠向量模型,精排的眼力靠重排模型。这一模块就是在讲这两种眼力是怎么练出来的。
1.2 两阶段架构为什么是工程标配
你可能会问:既然交叉编码精排更准,为什么不直接用它对全库逐篇打分?答案是算不过来。一个库里可能有几百万、几千万个文档,用户一问,要是对每篇都做一次又慢又贵的交叉编码打分,那用户得等好几分钟,成本也高得离谱。所以工程上必须分工:先用快的双编码模型,把文档向量提前离线算好存着,用户一问只算问题向量、去库里快速找近似的几十个,这一步很快;再用准的交叉编码,只对这几十个候选慢慢精挑细选。快和准的矛盾,就这样被拆成两步化解了。理解了这个矛盾,你就理解了为什么需要向量库、为什么需要重排------它们都是这个矛盾的产物。
**记忆钩子:**粗召回要"快而全",宁可多捞;精排要"准而精",从候选里挑真相关的。两者不是替代,而是配合。
二、视频清单(9 集 · 约 2.3 小时)
| 集 | 标题 | 时长 | 核心内容 |
|---|---|---|---|
| 46 | Embedding 原理:word2vec、CBOW | 16:13 | 稠密向量、语义空间、CBOW/Skip-gram、PyTorch 手写 |
| 47 | Embedding 模型训练:llamaindex 微调 | 22:02 | QA 对生成、SentenceTransformers、AutoTrain |
| 48 | Embedding 模型评估:MRR、MTEB | 20:38 | MRR/hit_rate、MTEB、C-MTEB、主流模型 |
| 49 | Rerank 原理(一)交叉编码与双编码 | 15:07 | 两阶段检索、bi/cross-encoder、ANN/HNSW |
| 50 | Rerank 微调(二)rankGPT | 15:24 | triplet、FlagEmbedding、LM-cocktail、point/list/pair |
| 51 | 向量数据库简介与相似性测量 | 15:21 | 向量库流程、索引类型、欧式/余弦/点积 |
| 52 | 相似性搜索算法:k-means、肘部法则 | 18:29 | k-means、肘部法则、k-means++、Kernel k-means |
| 53 | 向量数据库选型 | 09:27 | 专业库 vs 传统库、分片复制、选型考量 |
| 54 | 向量数据库代码示例:chroma 与 qdrant | 07:19 | Chroma 原生 API、Spring AI、Qdrant 代码 |
三、Embedding 原理
3.1 从 one-hot 到稠密向量
embedding 就是把一个物体(词、句子、图片等)表示为低维、稠密的浮点向量 。对比 one-hot:one-hot 维度随词表膨胀(维度灾难)、任意两个词向量正交、语义上毫无关系;稠密向量维度可控,且语义相近的物体在空间中距离相近,还能做向量运算:
经典语义类比:king − man + woman ≈ queen。向量空间里"国王减去男性再加女性"得到的向量,恰好落在"女王"附近------说明关系被编码进了向量方向。
3.2 word2vec 的两种架构(2013,Google)
| 架构 | CBOW 连续词袋 | Skip-gram 跳字 |
|---|---|---|
| 预测方向 | 给上下文 → 预测中心词(完形填空) | 给中心词 → 预测上下文 |
| 输入处理 | 上下文词向量需求和 / 取平均 | 输入不求和 |
| 适用 | 训练更快,高频词表现好 | 小数据、低频词表现更好 |
网络结构:输入 one-hot(V 维)× 权重矩阵 W(V×N)→ 隐藏层(N 维,即 embedding 维度)× W'(N×V)→ softmax 输出,用交叉熵损失训练;训练完后矩阵 W 就是词向量表。课程用 PyTorch 手写了一个最小示例(batch_size、embedding_dim、Adam、学习率 1e-4、约 2000 步)。现代 embedding 模型大多基于 Transformer。
python
import torch
import torch.nn as nn
import torch.optim as optim
超参数
vocab_size = 5000 # 词表大小 V
embedding_dim = 128 # embedding 维度 N
batch_size = 64
num_steps = 2000
lr = 1e-4
class Word2VecCBOW(nn.Module):
def init(self, vocab_size, embedding_dim):
super().init()
# W: V x N,训练完即为词向量表
self.in_embed = nn.Embedding(vocab_size, embedding_dim)
# W': N x V,输出层
self.out_embed = nn.Linear(embedding_dim, vocab_size, bias=False)
def forward(self, context_ids):
# context_ids: (batch, context_window)
emb = self.in_embed(context_ids) # (batch, window, N)
hidden = emb.mean(dim=1) # 上下文向量取平均
logits = self.out_embed(hidden) # (batch, V)
return logits
model = Word2VecCBOW(vocab_size, embedding_dim)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=lr)
伪代码训练循环
for step in range(num_steps):
context_ids, center_ids = get_batch(batch_size) # 取一批上下文与中心词
logits = model(context_ids)
loss = criterion(logits, center_ids)
optimizer.zero_grad()
loss.backward()
optimizer.step()
训练完成后,词向量表即 model.in_embed.weight
word_vectors = model.in_embed.weight.detach()
3.3 为什么稠密向量能"算"出语义
从一热编码到稠密向量,是一个巨大的观念跨越。一热编码把每个词当成空间里一根互相垂直的坐标轴,任意两个词之间永远是正交的,算出来它们"毫不相关"------这显然不符合我们对语言的直觉,猫和狗明明比猫和汽车更接近。稠密向量的想法是:把每个词放进一个低得多的空间里,让意思相近的词在这个空间里自然靠得近。那模型怎么知道谁和谁近?答案藏在上下文里。它看了海量文本后发现,猫和狗常常出现在相似的语境里,于是慢慢把它们的向量训得靠近。这就是分布式假设的精髓:一个词的意思,由它周围经常出现的词决定。
更妙的是,训出来的向量空间里,方向本身就编码了关系。课程举的那个经典例子,国王减去男性加上女性,得到的向量几乎正好落在女王附近。这说明模型不只是记住了"谁和谁像",还把"男女性别差异"这种关系学进了向量的某个方向里。这在当时是个惊人的发现,也是现代一切语义检索的地基。今天你用的各种句子向量模型,思想源头都在这里。
3.4 为什么今天还用不到手搓词向量
课程带你手写了一遍词向量训练,这是为了让你理解原理,但实际做项目时,你几乎不会自己去训词向量。原因很现实:现在的句子向量模型,都是在海量数据上用大算力预训练好的、并且在权威榜单上反复评测过的成熟模型,直接拿来用,效果远好于你自己从零训。手写训练的价值,是让你明白"向量为什么能表语义"这件事不是魔法,而是从语料里学来的,从而在自己的领域效果不好时,知道可以通过领域微调去改善它。
3.5 什么时候才需要微调向量模型
不是一上来就微调。先用现成的开源中文模型,在你自己那二三十个测试问题上跑一遍,算算命中率和排名指标。如果通用模型在你的专业领域表现已经够用,就别动它,省下来的精力去调切分和精排。只有当你发现,通用模型就是理解不了你这个领域的特殊术语、召回总是差那么点意思,才值得考虑用领域文档生成问答对去微调。而且记住课程反复强调的:微调完必须拿没参与训练的验证集来打分,不然就是自欺欺人。
**一句话:**向量模型是地基,先用现成的,地基确实不够用了再考虑加固,而不是一上来就重浇地基。
四、Embedding 微调
4.1 用 LlamaIndex 微调
-
用 SimpleDirectoryReader 读入领域文档(如证券法 PDF),SentenceSplitter 切分。
-
让 LLM 基于文本自动生成问答对(generate_qa_embedding_pairs)。
-
封装为 EmbeddingQAFinetuneDataset。
-
用 SentenceTransformersFinetuneEngine 以 BGE 等为底模微调。
python
from llama_index.core import SimpleDirectoryReader
from llama_index.core.node_parser import SentenceSplitter
from llama_index.finetuning import generate_qa_embedding_pairs
from llama_index.finetuning import SentenceTransformersFinetuneEngine
from llama_index.core import Settings
from llama_index.llms.openai import OpenAI
Settings.llm = OpenAI(model="gpt-4o-mini")
1. 读入领域文档并切分
documents = SimpleDirectoryReader("./data").load_data()
splitter = SentenceSplitter(chunk_size=512, chunk_overlap=50)
nodes = splitter.get_nodes_from_documents(documents)
2. 让 LLM 自动生成问答对
qa_dataset = generate_qa_embedding_pairs(
nodes=nodes,
llm=Settings.llm,
)
3. 封装为 EmbeddingQAFinetuneDataset(generate_qa_embedding_pairs 已返回该类型)
qa_dataset.save_json("qa_dataset.json")
4. 以 BGE 为底模微调
finetune_engine = SentenceTransformersFinetuneEngine(
qa_dataset,
model_id="BAAI/bge-small-zh-v1.5",
model_output_path="./bge-finetuned",
epochs=2,
batch_size=16,
)
finetune_engine.finetune()
embed_model = finetune_engine.get_finetuned_model()
4.2 用 AutoTrain 微调(HuggingFace 开源)
-
提供 Web UI(默认端口 8080),需配置 HF token 环境变量、安装 git-lfs。
-
任务要选 ST 开头的 sentence-transformer 类任务。
-
数据格式:pair(成对)、pair_class(成对带类别)、score(带分数)、triplet(anchor 锚点 / positive 正例 / negative 负例)、QA。CSV 或 JSON 均可。
-
参数:fp16 / bf16 看显卡、cosine 相似度调度、batch size、epoch、学习率约 1e-4、用梯度累积模拟更大 batch。
-
注意:LlamaIndex 生成的数据集格式与 AutoTrain 不完全兼容,subset 用冒号、split 格式需按要求调整。
bash
# 安装并启动 AutoTrain 的 Web UI
pip install autotrain-advanced
export HF_TOKEN=your_huggingface_token
autotrain app --port 8080 --host 0.0.0.0
json
[
{
"query": "证券法对信息披露的要求是什么?",
"positive": "发行人应当依法披露信息,内容真实、准确、完整。",
"negative": "证券交易应当在依法设立的场所进行。"
}
]
评估微调效果必须使用未被训练污染过的验证集,否则指标虚高、上线即失效。
五、Embedding 评估
-
**hit_rate@k:**正确结果是否出现在 Top-K 中。
-
MRR(Mean Reciprocal Rank,平均倒数排名): 对每个查询取正确结果排名 rank 的倒数 1/rank,再对所有查询求平均:
MRR = Σ(1/rank_i) / 查询数。正确答案排得越靠前分越高。 -
**precision / recall@k:**Top-K 中的精确率与召回率。
python
def hit_rate_at_k(ranks, k):
"""ranks: 每个查询中正确结果的排名列表(1 起)"""
return sum(1 for r in ranks if r <= k) / len(ranks)
def mrr(ranks):
"""平均倒数排名"""
return sum(1.0 / r for r in ranks) / len(ranks)
示例:5 个查询,正确结果分别排在第 1、3、2、10、1 位
ranks = [1, 3, 2, 10, 1]
print("hit_rate@3 =", hit_rate_at_k(ranks, 3)) # 0.8
print("MRR =", mrr(ranks)) # 0.634
| 榜单 / 模型 | 说明 |
|---|---|
| MTEB | HuggingFace 国际大规模 embedding 榜单:8 类任务、56 个数据集、上千模型、100+ 语言 |
| C-MTEB | 中文榜单:6 类任务、35 个数据集(2023.9 论文),选中文模型主要看它 |
| OpenAI | text-embedding-3-large(3072 维,可指定降到 256 维)、small(1536)、ada-002 |
| 开源代表 | 阿里 GTE、智源 BGE / BGE-M3、E5、网易有道 BCE(需在其官网下载,不在 HF) |
MTEB 支持自定义 encoder、任务与数据集(继承 AbsTaskReranking 等基类)并提交榜单。embedding 模型体积通常几个 G 即可,不必追最大。
六、Rerank 原理:两阶段检索(核心)
| 对比 | Bi-encoder 双编码器 | Cross-encoder 交叉编码器 |
|---|---|---|
| 编码方式 | query 与文档各自独立编码成向量,再算相似度 | query 与每篇文档拼在一起同时过 BERT 打分 |
| 能否预计算 | 文档向量可离线算好,查询时只编码 query | 不能预计算,每对都要实时算 |
| 速度 / 精度 | 快、精度略低 | 慢、成本高,但精度高(上下文长度多为 512) |
| 用途 | 建索引、粗召回、搜索 | Rerank 精排,医疗/法律等高精度场景 |
标准两阶段: 第一阶段用 bi-encoder + ANN 从全库快速粗召回,把候选集放大到约 Top 30 (宁多勿漏);第二阶段用 cross-encoder 对这 30 篇逐一精排,取 Top 3 / 5。在 LlamaIndex 中用 SentenceTransformerRerank(如网易 BCE rerank base v1)作为 node_postprocessor,设 top_n=15,也可手动 postprocess_nodes。
python
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.core.postprocessor import SentenceTransformerRerank
1. 构建向量索引(bi-encoder 粗召回)
documents = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(documents)
2. 配置 cross-encoder 精排
reranker = SentenceTransformerRerank(
model="BAAI/bge-reranker-base",
top_n=5,
)
3. 查询:先粗召回 Top30,再精排取 Top5
query_engine = index.as_query_engine(
similarity_top_k=30,
node_postprocessors=[reranker],
)
response = query_engine.query("证券法对信息披露的要求是什么?")
print(response)
向量库能做到毫秒检索,靠的是 ANN(近似最近邻) 而非暴力扫描,主流是 HNSW(分层小世界导航图),千万级数据也能毫秒返回;其他还有 LSH、KD 树 / 球树等。
七、Rerank 微调与大模型重排
7.1 CrossEncoder 微调
-
训练数据为 triplet:每条含一个 query、一个正例 positive、1~4 个负例 negative,JSONL 格式。
-
用
CrossEncoder(num_labels=1)(输出一个相关性分)+ InputExample + InformationRetrievalEvaluator 训练评估。 -
**FlagEmbedding(微软):**数据字段缩写为 query / pos / neg,train_group_size = 1 个正例 + (group_size−1) 个负例。
-
模型合并 LM-cocktail: 把基础模型与领域微调模型按权重(如各 0.5)混合,能有效缓解小数据微调带来的灾难性遗忘。
-
用 AutoTrain 微调 rerank 时选 triplet 任务 + rerank 底模;评估沿用 C-MTEB 的 Reranking 任务。
7.2 用大模型重排(RankGPT)的三种策略
|-----------------|-----------------------------------------------------------------------------------------------------------------|
| Pointwise 点 | query 配单篇文档,让模型逐篇判断"相不相关 / 相关程度" |
| Listwise 列表 | 把文档列表整体交给模型排序(GPT-4 zero-shot 即可)。受上下文长度限制用滑动窗口:窗口 4、步长 2,每次保留最相关的 2 篇,再与未比较文档重排------经验上 Top2 较准、Top4 不一定准 |
| Pairwise 成对 | 每次给两篇文档,让模型比较哪篇更相关;LlamaIndex 提供 RankGPTRerank |
八、向量数据库与相似度度量
向量库存的是一维浮点数组(float16 / float32),并把原始数据一并保存。流程:embedding 生成 → 存储 → 建索引 → 相似度检索。
三种相似度度量
| 度量 | 公式 | 特点 |
|---|---|---|
| 欧几里得距离 | √Σ(x₂−x₁)² | 两点直线距离,考虑向量长度(模长) |
| 余弦相似度 | A·B / (|A|·|B|) | 只看方向、对长度不敏感;范围 -1~1:1 同向、0 正交、-1 反向 |
| 点积 / 内积 | A · B | 未归一化、对长度敏感;>0 正相关、=0 正交、<0 负相关 |
常见索引类型
-
**FLAT:**暴力精确扫描,精度最高、最慢,适合小数据。
-
**IVF(倒排聚类):**先聚类再只搜最近的若干簇;变体 IVF_FLAT、IVFPQ(乘积量化压缩)。
-
**KD 树 / 球树:**用矩形 / 球形区域递归划分空间并剪枝。
-
**HNSW:**分层小世界图,性能与召回平衡好,工程主流。
-
LSH: 局部敏感哈希,相似向量落同桶;**PQ:**乘积量化压缩省空间。
九、相似性搜索算法:k-means
IVF 聚类的基础是 k-means,算法步骤:
-
随机选 K 个初始质心;
-
把每个点按欧式距离分配到最近质心所在簇;
-
重新计算每个簇的质心(簇内均值);
-
重复 2-3 直到质心收敛。
-
**缺点:**对 K 值和初始质心敏感、容易陷入局部最优。
-
**选 K ------ 肘部法则(Elbow):**随 K 增大,簇内误差平方和 SSE 下降,下降曲线的"拐点"即较理想的 K;也可用轮廓系数。
-
**初始化 ------ k-means++:**让各初始质心相互尽可能远(按距离平方做轮盘法概率选择下一个质心),显著改善局部最优。
-
**Kernel k-means:**用核函数把数据映射到高维空间,使原本线性不可分的数据变得可分,适合小规模复杂分布。
-
工程技巧:用 numpy 广播
data[:, np.newaxis]把 200×2 扩成 200×3×2,批量计算每个点到 3 个质心的距离。应用包括图像分割、文档聚类、客户细分。
十、向量数据库选型与代码
10.1 向量库 vs 向量数据库
向量库(库) 如 faiss、hnswlib、Annoy,偏静态索引:faiss 和 Annoy 只支持查询,hnswlib 支持增删改查(CRUD)、可视为精简版;向量数据库 在库之上还支持 CRUD、分片、复制、容错与分布式。分布式靠分片 (按向量相似性分区)+ 复制(多副本保可用)。
10.2 选型矩阵
| 方案 | 特点与适用 |
|---|---|
| Qdrant(推荐) | 可大可小、性能好、生态可;本地支持内存模式(:memory:)免起 server,生产用 Docker(端口 6333) |
| Milvus | 功能全面、适合大规模分布式集群,但学习曲线较陡、偏重 |
| Chroma | 单机轻量、Windows 下无需 WSL/Docker,入门门槛最低,但只支持单机 |
| Pinecone | 闭源云服务、性能 OK,不能本地部署 |
| Typesense / OpenSearch | Typesense 用 C++ 编写,可作为 ES 替代;OpenSearch 支持向量 |
| faiss / hnswlib / Annoy | 嵌入式/离线场景;Annoy 适合小规模、内存受限环境 |
| pgvector | 需 PostgreSQL,支持约 2000 维;已用 PG 时最省事 |
| ES / Mongo / ClickHouse / Redis | ES 7.0 起支持 dense_vector + HNSW/ANN;Mongo Atlas 仅云;ClickHouse 偏 OLAP、向量能力仍实验阶段偏弱;Redis 用 redissearch 模块 |
选型原则: 专业向量库支持高达 6 万多维与丰富 ANN 索引;传统库一般只到约 2000 维、适合 10 万级向量的补充场景。向量是主角 → 专业向量库(可再配传统库);向量只是小补充 → 直接用 pgvector 等一个库搞定。基准可参考 Qdrant benchmark 与 ann-benchmarks。
10.4 三种相似度到底怎么选
向量库建索引时要选一种距离度量,新手常被这三个名词绕晕。其实抓住一个区别就够了:这个度量在不在意向量的长度。欧氏距离在意,它算的是两点之间的直线长度,向量越长离得越远。余弦相似度完全不在意长度,它只看两个向量指向的方向是不是一致,所以把一个向量拉长一倍,余弦相似度一点不变。点积介于两者之间,它既看方向也看长度。那到底用哪个?经验是:如果你在模型里已经把向量归一化过了(也就是每个向量都缩到同样长度),那点积和余弦其实等价,随便用;如果没归一化,而你又只想比较方向、不想让长文档占便宜,就用余弦。工程里余弦是最常见的默认选择。
10.5 向量库为什么能做到毫秒级
库里有几百万向量,用户一问要立刻返回最近的几个,靠的不是笨办法逐个算距离------那叫暴力扫描,几百万个算下来太慢了。真正的秘密是近似最近邻索引:它放弃了"必须找到绝对最近"这个执念,换成"花极小代价找到差不多最近的那几个"。主流的分层小世界图,原理有点像在城市里找路:它建了好几层路网,上层是稀少的高速公路负责快速跨越大范围,下层是密集的街道负责精确定位,查询时从高速层往下逐层靠近目标,几步就到了。这种结构在千万级数据上也能毫秒返回,代价是极小概率漏掉真正的最近邻,但实际业务里完全够用。
10.6 聚类为什么和向量检索有关
你可能纳闷,课程里为什么要单独讲一遍聚类。因为另一种常用索引思路,就是先拿聚类算法把几百万向量分成几百个簇,每个簇存一个代表中心。查询时不用扫全库,只要先找到离查询最近的几个簇中心,然后只在这几个簇内部细找就行了------一下子把搜索范围缩小了几十倍。这个把数据分成簇的算法,就是聚类。课程讲的怎么选簇的个数、怎么改进初始中心,都是为了让这个分簇既分得均匀又不浪费。理解了这点,你就把分散的几集串成了一条线:聚类是为索引服务的,索引是为快速检索服务的。
**选型再强调:**向量是你系统的主角,就上专业向量库;向量只是顺手加的小功能,别为它单独养一套新运维,直接在你已经用的数据库上加向量能力最省事。
10.3 代码示例
-
Chroma 原生 API:
pip install chromadb,create client → get_or_create_collection → add(自动做 embedding、可带 metadata)→ query(支持 CRUD 与元数据过滤),JS/Python 均支持。 -
Qdrant:
pip install qdrant-client,轻量可本地内存模式或指定路径,生产拉 Docker 镜像 run 端口 6333;create_collection 指定向量 size 与距离度量,create_index 指定 cosine / HNSW 参数,支持 upsert / query / delete,可从零实现 RAG(更灵活但代码量更大)。 -
Spring AI(Java 栈): 借鉴 LangChain/LlamaIndex,统一大模型接口、支持 Ollama、各向量库、嵌入模型、函数调用、多模态与 ETL;做简单 RAG 够用,但复杂优化力不从心。AI 核心仍建议 Python 技术栈------工具链、GPU 生态与最新算法最全。
十一、核心概念速查表
| 概念 | 一句话理解 |
|---|---|
| embedding | 把物体映射为低维稠密向量,语义相近则距离相近 |
| CBOW / Skip-gram | 上下文预测中心词 / 中心词预测上下文 |
| MRR | 平均倒数排名 Σ(1/rank)/查询数 |
| MTEB / C-MTEB | 国际 / 中文 embedding 权威榜单 |
| bi / cross-encoder | 独立编码算相似度(快、粗召回)/ 拼接编码打分(准、精排) |
| 两阶段检索 | 双编码粗召回 Top30 → 交叉编码精排 Top3/5 |
| triplet | 锚点 + 正例 + 负例的重排训练样本 |
| LM-cocktail | 按权重合并基础与微调模型,缓解灾难性遗忘 |
| 三种相似度 | 欧氏距离(看长度)/ 余弦(看方向)/ 点积(未归一化) |
| HNSW / IVF | 分层小世界图 / 倒排聚类,两类主流 ANN 索引 |
| 肘部法则 / k-means++ | 选 K 的拐点法 / 改进初始质心避免局部最优 |
十二、学习打卡
-
能说清 one-hot 与稠密 embedding 的区别,并举出 king-man+woman=queen 的含义
-
能对比 CBOW 与 Skip-gram 的预测方向、输入处理与适用场景
-
能描述 word2vec 网络结构(V→N→V、softmax、交叉熵)
-
能用 LlamaIndex 生成 QA 对并微调一个 embedding,或用 AutoTrain 跑通 ST 任务
-
能写出 MRR 公式并解释 hit_rate@k,知道选中文模型看 C-MTEB
-
能清楚对比 bi-encoder 与 cross-encoder,并说出"粗召回 Top30→精排 Top5"流程
-
能用 triplet 数据 + CrossEncoder 微调一个 rerank,知道 LM-cocktail 解决什么
-
能区分 pointwise / listwise / pairwise 三种大模型重排及滑动窗口的作用
-
能写出并区分欧氏距离、余弦相似度、点积,知道各自对长度是否敏感
-
能说清 FLAT/IVF/HNSW/LSH/PQ 的取舍,以及 k-means、肘部法则、k-means++
-
能根据"向量是否为主角"在 Qdrant/Milvus/Chroma/pgvector 间做出选型
-
能用 Chroma 或 Qdrant 代码完成 add/query 的最小检索闭环
**学习建议:**本模块公式和概念密集,建议结合模块三一起学------先在 RAG 里看到"召回不准、排序不好"的现象,再回到本模块理解 embedding 与 rerank 如何决定上限。动手上至少完成三件事:① 用 Chroma 跑通最小向量检索;② 在 RAG 中加一个 cross-encoder rerank 对比前后效果;③ 用 C-MTEB 思路在自己的验证集上算一次 MRR/hit_rate。
十三、面试常考与实战补充
13.1 一道经典面试题:为什么粗召回和精排要分开
这道题几乎必问。标准答法是:因为快和准是一对矛盾。精排用的交叉编码虽然准,但它必须把问题和每篇文档拼在一起完整算一遍,没法提前离线算好,文档一多就慢到不可用;粗召回用的双编码可以把所有文档提前算好向量存着,查询时极快,但因为问题和文档是分开编码的、没充分交互,精度有限。所以工程上让双编码负责从全库快速捞一个不小的候选集,再让交叉编码从容地在小候选集里精挑。这样既不牺牲速度,又保住了精度。能把这个矛盾讲清楚,就说明你真懂了两阶段架构。
13.2 怎么判断要不要上重排
很多人问,是不是所有项目都得上重排。判断标准很简单:看你的业务对准确率的要求有多高。如果只是内部小工具、答案差点无所谓,那粗召回够用就行,重排的钱可以不花。但只要是面向客户、涉及法律医疗金融这类答错代价大的场景,重排几乎必上------它是性价比最高的一步,往往花一点推理成本,就能把准确率明显拉上去。课程里那句"重排必上",就是这个意思。
13.3 给动手党的三个最小练习
第一,用最轻量的向量库,把自己十几篇文档加进去、做一次查询,亲眼看到它返回了哪几篇、为什么是这几篇。第二,在你的问答系统里加一个现成的重排模型,只取前几条,对比加之前和之后,模型拿到的资料有没有变得更相关。第三,拿你最关心的那几个问题,手动数一数正确答案排在第几位,算一遍那个倒数排名指标。这三件事做下来,本模块那些看似抽象的向量、索引、重排,就全变成你手上摸得着的东西了。
十四、整个课程的收尾
到这里,四个模块就全部走完了。回头看这条学习线:模块一认识了平台长什么样、能做哪几类应用;模块二钻进代码,看一个带工具和记忆的智能体是怎么用图编排起来的;模块三搭起了一整条检索增强的业务链路;模块四则一路钻到底,把决定召回上限的向量、重排和向量库讲透了。从会拖拖拽拽搭应用,到懂它背后为什么这么设计,你完成的是一次从使用者到工程实践者的跨越。
这条路还很长,但你已经有了完整的骨架。剩下的,就是在你自己真实的项目里,把这套东西一遍一遍地跑、调、量。记住我们反复强调的那条铁律:没有评测就没有优化,每一次改动都用数据说话。祝你在大模型应用这条路上,走得稳、走得远。
**毕业寄语:**这门课教的所有工具都会过时,但"先跑基线、再建评测、一次改一处、用数据判断"的工程思维永远不会。带着它,去做你自己的下一个项目吧。
-
我亲手跑通过一次最小向量检索闭环
-
我在自己的系统上对比过加重排前后的效果差异
-
我能向别人讲清楚为什么粗召回和精排要分成两步
十五、把底座讲得再透一点
15.1 向量到底是个什么东西
很多同学卡在"向量"这个词上,觉得它很玄。其实它一点不神秘。你可以把它想成一组数字,比如一串七百多个小数,每个小数代表文本在某个抽象维度上的得分。不同的词、不同的句子,就对应一串不同的得分。关键在于,这串得分不是人随便填的,而是模型从海量语料里自动学出来的,学得好的结果就是:意思越像的两段话,它们那串数字算出来的距离就越近。有了这串数字,"两段话像不像"这个模糊的问题,就变成了一个可以用计算器直接算出来的数学问题。这就是向量的全部意义------把语言变成数字,让计算机能算"语义"。
15.2 为什么中文要专门选中文模型
这是个特别实用的提醒。很多人图省事,随便下个网上很火的向量模型就用,结果中文效果怎么调都不理想。原因在于,一个模型对哪种语言学得好,取决于它主要拿什么语料训的。如果它绝大部分训练数据是英文,那它对英文句子的语义拿捏就准,但换成中文,它对中文里那些微妙的近义、反义、专业术语就钝了。所以做中文问答,一定要去看专门评测中文的那个权威榜单,挑榜上靠前的中文模型。这不是崇洋或者排外,而是一个朴素的道理:让一个专门学过中文的模型来读中文,才靠谱。课程实操里特意用中文向量模型,正是这个原因。
15.3 重排模型和粗排模型有什么本质区别
前面说了两阶段,这里再挖一层为什么交叉编码更准。区别在于,粗排模型在编码时,是把问题和文档各自单独处理完再碰头算个距离,问题和文档从头到尾没真正"照过面"。而精排的交叉编码,是把问题和候选文档缝在一起,同时送进模型,让模型在算这一对的时候,能同时看见两边的全部细节,反复权衡。你想,一个是分开看完再打个印象分,一个是把两份材料摆在一起逐条对照,哪个判断更准?显然是后者。代价就是后者慢得多,因为它每一对都得从头算一遍,没法提前准备。这就是为什么它只能用在几十个候选上,而不能用在全库上。
15.4 工程里那些"经验值"是怎么来的
课程里给了很多具体数字,比如粗召回取三十个、精排取前五、重排取十五个。你可能会问,为什么是三十不是五十。这些数字不是拍脑袋,而是大量工程实践攒出来的折中:取太少怕漏,取太多又把慢的精排拖垮、还可能带进噪声。实际项目里,这些数字都该你用自己的评测集去微调。课程给的是一个很好的起点,但不是金科玉律。理解这一点很重要:你学的不是一套死参数,而是一套"先粗后精、逐步收紧"的思想,参数要结合自己的数据定。
**提醒:**课程里的三十、前五这些数字是起点不是标准答案,到你自己的数据上,一定要用评测集重新校准。
十六、给学习者的落地心法
16.1 从"会用"到"懂为什么"的跨越
很多人学这类课程,最后停留在"我会在那个平台上点几下、把文档传上去、问答就出来了"。这当然有用,但在求职和真正做项目时,区分度恰恰来自那些"为什么"。为什么我的召回不准?是向量模型不懂我的术语,还是切分把句子切碎了?为什么加上重排后效果好这么多?因为它把问题和文档真正放一起对照了。你能把这些为什么讲清楚,就和只会点界面的人拉开了差距。这一模块的全部价值,就是帮你补齐这些为什么。
16.2 不要被名词吓住
这个模块名词特别多:双编码、交叉编码、分层小世界、倒排聚类、乘积量化、各种距离度量。第一次看确实头大。但你抓住一条主线就不慌了:所有这些名词,都在解决同一个矛盾------又要快、又要准、又要省地方。向量模型负责让"像不像"算得准;近似索引负责让"在几百万个里找最近"这件事变快;各种压缩手段负责让"存得下"这件事变省。你遇到任何一个新名词,先问它是在解决这三个问题里的哪一个,立刻就有了位置。
16.3 关于选型的真心话
面对那么多向量库,别纠结哪个"最好",没有最好,只有最合适。入门就用最轻量、本地能跑的那个,先把流程跑通,别在环境部署上耗掉所有热情。等你真的要扛生产数据了,再根据团队已经在用什么、数据量多大、要不要分布式这些现实问题来选。课程给的原则------向量是主角就上专业库,向量是点缀就复用已有数据库------足够你应对绝大多数情况了。
16.4 全课程最终回顾
五个分册,从一张学习地图开始,带你认识平台、写代码级智能体、搭检索链路、钻到检索最底层。如果现在让你用一句话总结这门课,那就是:大模型应用的工程落地,无外乎三件事------把流程编排好,把对的知识喂给模型,再用评测不断把它调得更好。工具会换,框架会升级,但这三件事的逻辑不变。愿你带着这份骨架,在自己的项目里长出真正的本事。
**最终寄语:**笔记合起来,动手开始吧。跑通第一个系统的那一刻,你就会发现,这门课讲的一切都活了过来。
-
我能一句话说清向量为什么能表示语义
-
我知道中文场景为什么必须优先选中文向量模型
-
我不再被双编码、交叉编码这些名词吓住,能说出各自解决什么矛盾
十七、常见疑问与答疑
17.1 我一定要学会训练模型吗
不一定。这是很多转行者的共同焦虑。课程带你手写一遍词向量、走一遍微调流程,目的是让你理解这些东西是怎么回事,不是要求你以后天天自己训模型。实际做项目时,九成的情况是:选一个现成的、在权威榜单上评测过的成熟模型直接用。你真正要掌握的,是会判断"什么时候现成的够用、什么时候不够用了该微调",以及微调之后怎么科学地验证效果。会调用、会选型、会评估,比会从零训练重要得多。别被"训练"两个字吓到,那是这一行里相对小众、也最烧钱的环节。
17.2 向量维度是不是越高越好
不是。维度高,理论上能编码更丰富的语义,但代价是存得更占地方、算得更慢,而且维度高到一定程度后,收益递减甚至反而因为噪声变多而变差。课程里也提到,有些服务甚至允许你把一个很高维的向量压缩到很低维,效果损失却很小。所以实践中,选什么维度主要看模型本身和你数据的特点,不是一味求大。和选模型一样,在自己的验证集上比一比,比看理论靠谱。
17.3 召回和精排,哪个更该先优化
如果两个只能保一个,先保粗召回的"全"。为什么?因为粗召回是第一道门,它要是把真正相关的文档一开始就漏掉了,后面精排再厉害也无米下锅。所以工程上粗召回宁可多捞一点、把阈值放宽,宁可让精排多处理几条,也不能在第一道门就把答案挡在外面。当然,粗召回也不是越宽越好,太宽会带进大量噪声、压垮精排。这个"宽到什么程度",同样要靠评测集去试。记住顺序:先保证不漏,再追求精准。
17.4 这套底座和大模型是什么关系
很多人会混淆:既然大模型这么强,为什么还要单独搞一套向量检索?因为大模型本身记不住你公司那堆私有文档,也不知道你昨天才更新的资料。向量检索这套底座,就是给大模型外接了一个"随取随用的知识库"。大模型负责理解和组织语言,向量底座负责快速把相关资料找出来递过去。两者是配合关系:底座决定了模型"能看到什么资料",模型决定了它"怎么用好这些资料"。底座差,模型再有本事也是巧妇难为无米之炊。这就是本模块反复强调"底座决定上限"的原因。
**答疑小结:**不用人人都去训模型;维度不是越高越好;先保粗召回不漏再谈精排;底座是给大模型外接知识库的。
十八、终章
至此,五本笔记全部完成。你已经从一个只听说过大模型的人,成长为能搭应用、懂智能体编排、会建检索链路、还明白向量与重排底层原理的实践者。这条路没有终点,但你已经握住了最关键的那张地图。接下来,去做你自己的项目,让这些知识在真实问题里生根发芽吧。
-
我不再害怕训练相关的概念,知道自己现阶段该掌握到什么程度
-
我理解了粗召回先保全、精排再求精的优化顺序
十九、写给坚持到这里的你
能把这五个分册一路学下来,本身就说明你有足够的耐心和定力。这类底层技术内容不轻松,概念密、公式多、还容易串。但你回头看,会发现它们其实非常成体系:从最上面怎么搭一个应用,到中间怎么编排一个会自己思考的智能体,再到怎么把企业的私有知识接进来,最后一路钻到最底层、看清楚向量和重排到底在算什么。这条线是完整的,每一环都咬着下一环。当你把最底层弄懂了,再回头看最上层那些平台按钮,心里就有底了------你知道每一个按钮背后,跑的是什么。
19.1 接下来该做什么
别急着马上学下一个新潮工具。趁现在记忆还新,挑一个你工作或学习里真实存在的小问题,用这门课学的东西,从头到尾做一个能用的小系统。比如把你手头一堆零散的文档,做成一个能问答的小助手。这个过程中你会真实地遇到切分怎么切、召回怎么调、重排加不加这些问题------而这些,正是本笔记反复强调的东西。做出来那一刻,你对这门课的理解会再上一个台阶。
19.2 记住最重要的那句话
整门课如果只让你带走一句话,那就是:没有评测,就没有优化。很多人调系统全凭感觉,今天换个模型、明天改个参数,效果时好时坏却不知道为什么。真正的工程师,是先攒一小批标准问题,每次改动都跑一遍、用数字说话。这个习惯,比记住任何一个具体模型名字都值钱。它会陪着你走完以后所有的技术生涯。
**最后的话:**技术会一直更新,但会学习、会动手、会用数据验证的人,永远不会被淘汰。祝你学有所成。
-
我已经开始动手做自己的第一个小系统
-
我把"先建评测集再优化"这条习惯记在了心里
二十、最后的小叮咛
读到这里,你已经把整个课程的笔记翻到了最后。这里没有新的知识点,只有几句想留给你的话。第一,别贪多。这门课信息量很大,与其试图一次全记住,不如把它当成一本工具书,做项目时遇到对应问题再回来查。第二,别轻视动手。看十遍不如亲手跑一遍,哪怕只是把别人的示例代码改两行、换份自己的文档跑通,收获也远大于纯看。第三,保持怀疑精神。笔记里写的一切参数、一切建议,都是某种情境下的经验,到了你自己的数据上,都要重新验证。真正的高手不是记住最多结论的人,而是知道每个结论背后有什么前提、什么时候会失效的人。
祝你在这条路上,既能抬头看清方向,也能低头把每一行代码、每一次检索、每一个指标都调扎实。我们更高处再见。
**本笔记正式结束。**愿你把它真正用起来,而不只是收藏起来。
二十一、结课祝福
五个分册,到这一册真的要合上了。回头望,你从这门课里带走的,不该只是几个名词、几行代码,而是一套看问题的方式:面对一个大模型应用,你会下意识地去拆它的流程、看它的知识从哪来、判断它有没有可量化的好坏标准。这种结构化的眼光,比任何一个具体工具都更能陪你走得远。
技术迭代很快,今天热门的框架明年可能就换了,但你学会的这套拆解、动手、验证的方法,会一直管用。大胆去用,勇敢去试,遇到问题就回来翻这本笔记。祝你学习顺利,早日做出让自己骄傲的作品。我们下门课再见。
**全系列完。**感谢你一路坚持到这里。
愿你在大模型应用这条路上,走得坚定、做得扎实,把每一个想法都变成真正能用的产品。坚持动手,保持好奇,用数据验证每一次优化。我们更高处相逢。
这册笔记的每一段,都是为了帮你把模糊的概念变成手上能用的本事。愿你多读多练,早日做出属于自己的作品。
全系列到此正式结束,祝你学习顺利、项目落地顺利,早日做出属于自己的优秀作品。
二十二、总结与参考资料
把整个模块收束成一句话:检索的上限由底座决定,而底座由向量模型、重排模型和向量库三块拼成。向量模型负责把文本变成可计算语义的稠密向量,重排模型负责在候选集里做精细判断,向量库负责在千万级数据上把"找最近"这件事做到毫秒级。三者各司其职,缺一不可。
22.1 核心要点回顾
- **Embedding:**从 one-hot 到稠密向量,语义相近则距离相近;word2vec 的 CBOW 与 Skip-gram 是理解"向量为什么能表语义"的起点,但工程上直接用成熟预训练模型,只在领域术语理解不足时才考虑微调。
- **微调与评估:**LlamaIndex 自动生成问答对、AutoTrain 走 ST 任务,两条路都能落地;评估必须用未参与训练的验证集,看 hit_rate@k 与 MRR,选中文模型优先参考 C-MTEB。
- **Rerank:**双编码粗召回(Top 30 左右,宁多勿漏)+ 交叉编码精排(Top 3/5),是快与准这对矛盾的工程解法;CrossEncoder 用 triplet 数据微调,大模型重排可用 pointwise / pairwise / listwise 三种策略。
- **向量库:**三种相似度度量抓住"在不在意向量长度"这一个区别即可;ANN 索引(HNSW、IVF、LSH、PQ)用近似换速度;选型原则是"向量是主角就上专业库,向量是点缀就复用已有数据库"。
- **工程心法:**没有评测就没有优化;先保粗召回不漏,再谈精排求准;课程里的三十、前五这些数字是起点,不是标准答案。
22.2 官方文档与权威榜单
| 资源 | 链接 | 用途 |
|---|---|---|
| LlamaIndex 官方文档 | docs.llamaindex.ai | 索引构建、微调引擎、node postprocessor 重排的完整 API |
| Sentence Transformers 文档 | sbert.net | 双编码 / 交叉编码模型训练、评估与 CrossEncoder 用法 |
| HuggingFace AutoTrain | huggingface.co/docs/autotrain | 无代码微调 ST 任务、数据格式与参数说明 |
| MTEB 榜单 | MTEB Leaderboard | 国际 embedding 模型横向对比,按任务类型筛选 |
| C-MTEB 中文榜单 | C-MTEB Leaderboard | 中文场景选模型的第一参考 |
| BGE 模型与 FlagEmbedding | github.com/FlagOpen/FlagEmbedding | BGE / BGE-M3 / BCE 系列 embedding 与 reranker 的官方实现 |
| Qdrant 文档 | qdrant.tech/documentation | 集合创建、距离度量、HNSW 参数与过滤查询 |
| Chroma 文档 | docs.trychroma.com | 轻量本地向量库的快速上手与 CRUD |
| Milvus 文档 | milvus.io/docs | 大规模分布式向量检索、索引类型与部署方案 |
| Faiss | Faiss Wiki | 各类 ANN 索引原理与选型指南,理解底层机制的最佳读物 |
| ann-benchmarks | ann-benchmarks.com | 主流 ANN 算法在召回率与吞吐上的横向基准 |
22.3 推荐阅读资料
- **word2vec 原始论文:**Mikolov 等《Efficient Estimation of Word Representations in Vector Space》(2013)与《Distributed Representations of Words and Phrases and their Compositionality》(2013),CBOW 与 Skip-gram 的出处,篇幅不长,值得通读。
- **Sentence-BERT:**Reimers 与 Gurevych《Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks》(2019),双编码器做语义相似度的奠基工作,也是理解 bi-encoder 与 cross-encoder 分工的必读。
- **MTEB 论文:**Muennighoff 等《MTEB: Massive Text Embedding Benchmark》(2022),讲清 8 类任务、56 个数据集的评测设计,读完就知道榜单分数该怎么看。
- **C-MTEB 论文:**Xiao 等《C-Pack: Packed Resources For General Chinese Embeddings》(2023),中文 embedding 评测体系与 BGE 系列的来源。
- **HNSW 论文:**Malkov 与 Yashunin《Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs》,分层小世界图的原理与参数含义。
- **RankGPT:**Sun 等《Is ChatGPT Good at Search? Investigating Large Language Models as Re-Ranking Agents》(2023),listwise 重排与滑动窗口策略的原始出处。
- **LM-cocktail:**Xiao 等《LM-Cocktail: Resilient Tuning of Language Models via Model Merging》(2023),理解模型合并如何缓解灾难性遗忘。
- **RAG 综述:**Gao 等《Retrieval-Augmented Generation for Large Language Models: A Survey》(2023),把检索、增强、生成三段串成完整图景,适合作为本模块的上层索引。
22.4 下一步的实践建议
- 用 Chroma 或 Qdrant 搭一个最小检索闭环,把十几篇自己的文档灌进去,观察返回结果与相似度分数。
- 在同一份数据上叠加一个现成的 cross-encoder reranker,用 hit_rate@5 与 MRR 对比加与不加的差异。
- 把评测集固定下来(二三十个真实问题即可),之后每次换模型、调参数都跑一遍,用数字判断改动是否有效。
- 只有当通用中文模型在你的领域明显不够用时,才走 LlamaIndex 或 AutoTrain 的微调路线,并用独立验证集验收。
**结语:**工具会换,榜单会变,但"先跑基线、再建评测、一次改一处、用数据判断"这套方法不会过时。把这份参考资料当成你的工具箱,遇到具体问题时按图索骥,比一次性读完更有价值。