跳到正文
博客园· 丨渍丨·· 4 小时前AI 评分12

AI 基础科普:从神经网络、LLM 到训练与推理

AI基础 - 丨渍丨

AI 导读

一篇面向入门者的 AI 基础科普,梳理了神经网络输入层、隐藏层、输出层与权重、激活函数、反向传播的关系,并解释梯度消失与梯度爆炸的成因。文章还介绍 LLM 按 token 续写、上下文窗口与多模态编码器,区分预训练、SFT、RLHF、DPO 及 LoRA、QLoRA 微调,并说明推理阶段的 KV Cache 与投机解码。

正文

什么是 AI

AI(Artificial Intelligence,人工智能)可以先理解成一组能力,让计算机在某些任务上表现出「类似智能」的行为。

机器学习

学习方式 有没有标准答案 典型场景
监督学习 有 垃圾邮件识别、房价预测、图像分类
无监督学习 没有 用户分群、异常检测、数据压缩
强化学习 延迟的奖励信号 游戏 AI、机器人控制、推荐系统

Mermaid Diagram

 深度学习

深度学习的核心是神经网络(Neural Network)。这个名字来源于生物学——人脑里有大约 860 亿个神经元,互相连接形成网络。人工神经网络是一种大大简化的数学模拟,但基本思想很像:很多简单的计算单元连在一起,通过层层传递,最终输出一个复杂判断。

不要被「神经」两个字吓到。你可以把神经网络想象成一个工厂流水线,每一层工人负责一道工序,层层加工,最后产出结果。

Mermaid Diagram

输入层(Input Layer):接收原始数据。如果是图像,输入层的每个节点对应一个像素点的亮度或颜色值。如果是文本,输入的是每个词对应的数字编码。

隐藏层(Hidden Layer):真正干活的地方。这一层的每个「神经元」都会对上一层的输出做加权求和,再通过一个激活函数决定是否「开火」——把信号往下传递。

你可以把隐藏层理解为流水线的中间工序。第一层可能识别"这里有条横线",第二层识别"横线加竖线像是个耳朵",第三层识别"耳朵加圆脑袋大概率是猫"。层数越多,能识别的模式越抽象、越复杂。

输出层(Output Layer):给出最终判断。猫狗分类任务里,输出层有两个节点,分别输出"是猫的概率"和"是狗的概率"。哪个概率高,模型就选哪个。

权重:每个连接的「重要性分数」

层与层之间的每条连线,都有一个数值叫权重(Weight)。它决定上一层某个信号对下一层某个神经元的影响有多大。

打个比方:判断一个人会不会违约,你考虑了三个特征——收入、负债率、学历。你觉得收入最重要,给它的权重是 0.6;负债率次之,权重 0.3;学历相对次要,权重 0.1。神经网络里的权重就是这个逻辑,只不过它有成千上万个特征和连接,权重的值是训练过程中自动调整出来的,而不是人定的。

训练神经网络的过程,本质上就是不断调整这些权重的过程。调对了,模型输出就准;调错了,就继续改。算法用来调权重的方法叫反向传播(Backpropagation):模型做完一题,对照答案算出差多少,然后从输出层往回一层一层地「追责」,告诉每一层该往哪个方向改。

激活函数:决定要不要传递信号

如果神经元只是简单地把输入加起来,那多层和一层没什么区别——多层嵌套后仍然是线性运算,学不到复杂规律。

激活函数(Activation Function)的作用就是打破这种线性。它像一个开关:输入信号够强,就输出一个非零值;不够强,就输出零或接近零。

ReLU(修正线性单元)是最常用的激活函数之一:输入大于零,原样输出;输入小于等于零,输出零。就像公司审批流程——预算超过门槛才往上递,不够门槛直接驳回。

这种非线性让神经网络能拟合各种弯曲、复杂的关系,而不是只能画直线。

梯度消失与梯度爆炸:深层网络的「走极端」问题

层数多了之后,有一个训练上的大麻烦——梯度消失与梯度爆炸。

反向传播时,梯度要从输出层一层一层往回传。如果每层都乘以一个小于 1 的系数,传到最前面几层时梯度就接近零了,权重根本得不到更新,这就是梯度消失。反过来,如果每层乘以一个大于 1 的系数,梯度会越乘越大,变成天文数字,权重一下子蹦飞了,这就是梯度爆炸。

「深度」指的是神经网络的隐藏层很多。传统神经网络可能只有 1~2 个隐藏层,而深度学习模型动辄几十层、上百层,甚至上千层。

层数多带来的好处是:模型能学习不同抽象层次的特征。

以图像识别为例:

  • 第 1~2 层:识别边缘、颜色块、简单纹理
  • 第 3~5 层:识别眼睛、耳朵、轮子、翅膀等基本部件
  • 第 6~10 层:识别「猫脸」「汽车轮廓」「建筑结构」等整体概念
  • 更深层:理解场景关系,比如「一只猫趴在沙发上」

什么是 LLM

LM(Large Language Model,大语言模型)可以先理解成一台巨大的语言续写机器。它根据上下文预测后面最可能接什么,再一个 token 一个 token 地写下去。

image

一句话在模型身体里走一圈

Mermaid Diagram

Token 文本的切片单位。模型处理文字时,会沿着 token 一步步往前走。例子,人工智能可能被切成「人工」和「智能」。

参数  模型内部可调整的数字。训练就是反复调整这些数字,让模型越来越会预测。参数更像一大片被训练出来的语言肌肉,别把它想成一条条知识卡片。

上下文窗口 模型一次能看到多少信息。窗口越大,它能同时参考的前文、文件、代码越多。窗口变大,信息容量会变宽;抓错重点、漏看细节的情况仍然会发生。

多模态 AI 

 多模态 AI(Multimodal AI)就是让 AI 同时处理文字、图片、语音和视频,把不同形式的信息放到同一张理解地图里。

Mermaid Diagram

编码器(Encoder)。编码器就是把原始信息转换成向量表示的模块。图像编码器负责把图片变成向量,音频编码器负责把声音变成向量,文本编码器负责把文字变成向量。模型真正处理的是这些转换后的表示——它从来没有直接「看到」图片或「听到」声音。

模型、数据、训练与推理

模型(Model)像一套会计算的规则,数据(Data)是它看过的材料,训练(Training)负责把规则调出来,推理(Inference)就是训练好的模型真正开始回答问题。

Mermaid Diagram

模型:一套会计算的复杂规则

可以先理解成一个数学函数:你给它输入,它给你输出。

text 输入:一张猫的图片 → [模型] → 输出:猫,置信度 99% 输入:一段中文句子 → [模型] → 输出:对应英文翻译 输入:请解释量子计算 → [模型] → 输出:一段解释文字

参数是什么 

模型内部有很多参数(Parameter)。你可以把参数想成一堆旋钮。训练前,旋钮的状态基本是随机的;训练中,系统会不断调整这些旋钮;训练后,旋钮组合就变成了模型的能力。

数据:模型真正吃进去的东西

数据(Data)是模型学习的原料。

对于大语言模型来说,最常见的数据是文本和代码;对于多模态模型,还会加入图片、音频、视频。数据进入模型前,通常会先被处理成 token、图像块、音频特征等形式。

训练:预测、犯错、改参数

训练(Training)就是让模型从数据中学习规律,并不断调整参数。

对语言模型来说,最基础的训练任务很朴素:预测下一个 token。

比如给模型一句话:

text 深圳今天的天气很

模型会猜下一个 token 可能是「热」「好」「潮湿」。训练系统会拿模型预测和真实文本对比,算出误差,再通过反向传播(Backpropagation)调整参数。

Mermaid Diagram

预训练、后训练、微调:三件事别混

Mermaid Diagram

预训练:先学通用能力

预训练(Pre-training)像通识教育。模型先读海量文本、代码和多模态材料,学语言规律、常识、知识关联和基础推理能力。

预训练得到的模型叫基座模型(Base Model)。基座模型通常会续写文本,但未必适合直接聊天。你问它「帮我总结这篇文章」,它可能顺着你的话继续补一篇文章,没有按你的要求给摘要。

监督微调(Supervised Fine-Tuning,SFT)像看标准答案。人类准备一批「指令 → 理想回答」样本,让模型学习应该怎样回应用户。

RLHF(Reinforcement Learning from Human Feedback,基于人类反馈的强化学习)是让模型从人类偏好里学习。

InstructGPT 论文给过一个经典流程:

  1. 收集标注员写的 prompt 和用户通过 API 提交的 prompt;
  2. 让标注员写出理想回答,用来做监督微调;
  3. 对同一个问题生成多个回答,让人类排序;
  4. 用这些偏好排序继续训练模型。

RLHF 很强,但工程上比较复杂。后来出现了 DPO(Direct Preference Optimization,直接偏好优化)。DPO 论文把传统 RLHF 里「训练奖励模型 + 强化学习优化」的流程,改成直接用偏好数据优化语言模型,目标是更简单、更稳定、更轻量。

LoRA 和 QLoRA:普通人更常听到的微调

很多企业说「我们基于开源模型微调了一个行业模型」,大概率没有从零训练,只是在已有基座模型上做参数高效微调。

LoRA(Low-Rank Adaptation,低秩适配)就是常见方法之一。LoRA 论文的做法是冻结原模型权重,只训练额外加入的小矩阵。论文摘要里提到,对 GPT-3 175B 这类规模模型,LoRA 相比全量微调可以把可训练参数减少 10,000 倍,GPU 显存需求降低 3 倍。

QLoRA(Quantized LoRA,量化 LoRA)进一步把大模型以 4-bit 形式量化,再训练 LoRA 适配器。QLoRA 论文提到,它能把 65B 参数模型微调压到单张 48GB GPU 上,还提出了 NF4、double quantization、paged optimizers 等技巧。

这就是为什么普通团队也能「微调大模型」。它们通常没有重新训练整个模型,只是在已有模型旁边加了一层便宜得多的适配器。

推理:模型真正开始干活

维度 训练 推理
目标 学习规律,调整参数 使用规律,生成结果
参数 会更新 通常固定
成本 一次投入巨大 按调用持续消耗
时间尺度 几天到几个月 毫秒到分钟
典型场景 训练 GPT、LLaMA、DeepSeek 用户聊天、代码补全、RAG 问答

Mermaid Diagram

工程上有很多推理优化方法。

比如 KV Cache。模型生成第 100 个 token 时,不想把前 99 个 token 的注意力结果全部重算一遍,于是会缓存前面的 Key/Value。这样速度更快,但显存压力也会变大。

还有 投机解码(Speculative Decoding)。Speculative Sampling 论文的做法是让一个更快的小模型先草拟几个 token,再让大模型并行验证。论文在 Chinchilla 70B 上报告了 2–2.5 倍解码加速,而且不修改目标模型本身。

最小示例:教一个模型认识「猫」

用一个小例子把这几个概念串起来。

假设你要做一个识别猫的模型。

环节 在这个例子里是什么
模型 一个能处理图片的神经网络
数据 很多猫、狗、兔子、鸟的照片
标签 每张图对应的答案,比如「猫」或「狗」
训练 模型猜答案,猜错就调参数
推理 看到一张新照片,判断里面是不是猫

一个大模型从训练到上线,大概会经历什么

Mermaid Diagram

Token、Embedding 与上下文窗口

Mermaid Diagram

Token(词元)可以先理解成模型处理文本时使用的「文本颗粒」。它可能是一个字、一个词、一个词根、一个标点,也可能是一段字节。

Embedding(嵌入 / 向量表示)做的事,就是把文本、图片、音频或其他对象变成一串数字。语义相近的内容,在向量空间里距离更近;语义差很远的内容,距离更远。

Embedding 能做什么

常见用途可以这样看:

场景 怎么用 embedding
语义搜索 把问题和文档都转成向量,找距离最近的文档
聚类 把相似评论、工单、用户反馈自动归类
推荐 找和用户已读内容相近的文章或商品
去重 找语义重复但文字不同的内容
分类 用文本向量和标签向量的相似度判断类别
RAG 先检索相关片段,再交给大模型回答

上下文窗口:模型一次能看的工作台  上下文窗口(Context Window)可以理解成模型一次生成答案时能参考的 token 总容量。

text 上下文窗口 ≈ 系统提示词 + 历史对话 + 当前输入 + 工具结果 + 本轮输出

三者关系:从文本到回答

Token、Embedding、上下文窗口不是三块孤立知识。它们正好对应模型处理信息的三个层面。

Mermaid Diagram

Prompt、上下文和记忆

Prompt负责说明这次任务,上下文决定模型当前能看到什么,记忆负责把长期信息重新带回现场。

Mermaid Diagram

模型回答时,会把当前可见的上下文一起拿来判断。

Mermaid Diagram

温度与采样参数

温度、Top-k、Top-p决定模型从候选 token 里怎么选下一个 token。它们不负责增加知识,负责控制输出时的随机性、稳定性和多样性。

模型每次生成下一个 token 时,会先给大量候选 token 打分,再把分数变成概率。解码策略负责回答一个很具体的问题:下一步到底选谁?

Mermaid Diagram

可以先记一句人话:Prompt 决定模型往哪儿走,采样参数决定它走得稳不稳、散不散。

模型生成文字时,到底在选什么

LLM 是一类自回归语言模型。它每次只做一件事:根据当前上下文预测下一个 token。

在 Hugging Face 的 generation strategies 文档里,decoding strategy 被定义为决定模型如何选择下一个生成 token 的规则。最简单的规则叫 Greedy Search(贪心搜索):每一步都选概率最高的 token。

这听起来很合理。

问题也从这里开始。

贪心每一步都选最可能的词,短答案通常很稳,长文本却容易变得机械、重复。Hugging Face 文档里直接提醒:greedy search 适合较短、创意优先级不高的任务,生成长序列时可能开始重复。Hugging Face 的经典文章 How to generate text 也展示过 GPT-2 生成时反复出现同一句话的例子。

这就是采样参数存在的原因。它们让模型不要只盯着概率最高的那个 token,而是在一个可控范围内保留变化。

Temperature:控制随机性,不控制事实性

它只改变模型从已有概率分布里怎么选 token。事实任务里,低温通常更稳;创意任务里,高温通常更有变化。可如果模型没见过、上下文没给、检索没查到,温度再低也可能编。

Top-k:只从前 k 个里抽

Top-k sampling 的规则很直接:模型把所有候选 token 按概率排序,只保留前 k 个,其他候选概率设为 0,再从剩下的候选里抽样。

Mermaid Diagram

Top-p:按累计概率动态截断

Top-p sampling 也叫 Nucleus Sampling(核采样)。它不固定保留几个候选,会保留一个「累计概率达到 p 的最小候选集合」。

Top-p 的好处是动态。模型很确定时,候选池会自动变小。模型不确定时,候选池会自动变大。

Mermaid Diagram

Top-k 和 Top-p 怎么配

一种路线是只调一个主旋钮。

Anthropic 文档把 top_p 和 top_k 都标为高级用法,普通场景优先用 temperature 会更直观。很多产品界面也只露出 temperature,因为它最好理解。

另一种路线是组合使用。

Hugging Face 的 How to generate text 给过组合示例:top_k=50 加 top_p=0.95。这样 Top-k 先限制最低质量的长尾,Top-p 再根据累计概率动态收缩候选池。

两种路线都能用。新手建议按这个顺序来:

  1. 先用默认参数跑一遍;
  2. 输出太跳,先降 temperature;
  3. 低温后仍有怪词,再收紧 top_p 或 top_k;
  4. 只改一个参数,记录变化;
  5. 找到稳定范围后再微调。

别一口气把 temperature、top_p、top_k 全拧到极端值。那样很难判断到底是哪一个参数带来了变化。

任务 Temperature Top-p Top-k 说明
分类、抽取、固定标签 0 - 0.2 默认或偏低 默认或偏低 目标是稳定,不追求花样
代码生成、配置生成 0 - 0.3 0.7 - 0.9 默认或 20 - 50 先保证一致性,再看是否需要变化
事实问答、资料总结 0.2 - 0.5 0.8 - 0.95 默认 温度低一点,重点靠上下文和引用约束
翻译、改写 0.3 - 0.7 0.8 - 0.95 默认 保留语义,允许措辞变化
日常聊天 0.5 - 0.9 0.9 - 0.95 默认或 40 - 50 需要自然度和一点变化
标题、口号、命名 0.8 - 1.2 0.9 - 0.98 40 - 100 多生成几个候选更重要
诗歌、故事、脑洞 0.9 以上 0.95 左右 50 以上 接受少量跑飞,靠人工挑选

一个简单决策流程

Mermaid Diagram

幻觉

层次 怎么判断 例子
与现实冲突 现实世界里查不到或事实相反 编造不存在的公司收购
与材料冲突 用户给的文档里没有,甚至相反 总结合同时新增了一条付款条款
无法验证 看起来合理,但找不到来源 捏造论文、链接、采访原话

开发者可以这样做

层面 做法 适合场景
数据 建可靠知识库,清理过期和重复资料 企业问答、客服
检索 评估召回率、重排效果和引用命中 RAG 系统
生成 限制回答范围,要求引用证据 事实问答
输出 做格式校验、来源校验、事实核查 报告、公告、代码
权限 高风险工具调用前人工确认 Agent、自动化工作流
评测 建幻觉测试集和回归测试 产品迭代
监控 记录用户反馈和错误案例 线上系统

普通用户可以这样做

做法 Prompt 写法 作用
允许它停下来 如果资料不足,请说「无法确认」 减少硬猜
限定来源 只基于我提供的材料回答 避免混入外部印象
先要证据 先列出原文引用,再回答 让结论有支点
要求标注不确定 把无法确认的信息单独列出 防止混进正文
降低温度 事实任务用低 temperature 让输出更稳
多跑几次对比 同一问题生成 3 次,看差异 找出不稳定点
关键内容人工核查 对数字、引用、结论逐条查源 防止错用

Prompt 到底是什么

Prompt(提示词)是你输入给 AI 模型的文本,用来告诉模型你想让它做什么。

更准确地说,Prompt 是一种输入设计(Input Design)——你不是在"跟 AI 聊天",而是在给 AI 下发一份任务说明书。模型根据说明书里的信息,生成对应的输出。

为什么 Prompt 很重要

同一个模型,不同的 Prompt,结果可以天差地别。

我们用 GPT-4o(OpenAI 2024 年发布的多模态大模型)做一个对比实验。需求都是一样的:解释什么是 RAG。

Prompt 版本 A(随意型):

RAG 是什么?

模型可能会给出一篇 500 字的技术解释,充满术语,对小白很不友好。因为它不知道你的背景,只能按"最通用的方式"回答。

Prompt 版本 B(结构化型):

角色:你是面向小白的技术科普作者。 任务:解释 RAG(Retrieval-Augmented Generation,检索增强生成)这个概念。 要求: 1. 先说明它解决什么问题 2. 用一个生活化的比喻来解释原理 3. 列出 1 个常见使用场景 4. 控制在 200 字以内

这次的输出会清晰很多:有场景、有比喻、有结构、有字数控制。模型知道"读者是谁""该用什么风格""多长算够",所以不会乱发挥。

这就是 Prompt 的价值:它不改变模型本身的能力,但能让模型把能力用在对的地方。

Prompt 的核心组件

Mermaid Diagram

角色(Role):你希望模型扮演谁

任务(Task):你要模型做什么

约束(Constraint):不能做什么、必须满足什么

输出格式(Output Format):结果长什么样

示例(Example):给模型看"好的回答"长什么样

最小模板:直接套用

如果你记不住那么多理论,直接用这个模板填空就行:

text 角色:你是一位[具体身份]。 任务:请[具体动作][对象/内容]。 背景:[补充必要的上下文信息,如读者是谁、使用场景是什么] 约束: 1. [第一条限制,如长度、风格] 2. [第二条限制,如必须包含/不能出现] 3. [第三条限制] 输出格式:[段落/列表/表格/JSON/Markdown 等]

text 角色:你是一位高中物理老师。 任务:请用牛顿三定律解释为什么坐公交车没座位时要抓紧扶手。 背景:面向高一学生,他们刚学完牛顿定律但还不习惯联系生活。 约束: 1. 用通俗中文,不要直接用公式符号(可以用文字描述公式含义) 2. 不超过 300 字 3. 举一个公交车急刹车的具体例子 输出格式:一段完整的讲解文字,分成"现象—原理—结论"三部分。

Prompt 模板

Prompt 模板(Prompt Template) 是一种带有占位符(placeholder)的 Prompt 结构,你把固定部分写好,把变化部分留空,每次使用时填入具体内容即可。

Mermaid Diagram

简单记法:

  • 太长不想看 → 总结
  • 这样说不太合适 → 改写
  • 这是哪一类 → 分类
  • 把XX挑出来 → 抽取

LLM 的三个天然局限

要理解为什么需要 RAG,先要理解 LLM 本身有哪些做不到的事:

局限 1:知识有截止日期

LLM 的训练数据有一个截止时间。GPT-4o 的知识截止于 2023 年 10 月左右。如果你问「2025 年发布的 iPhone 17 有什么新功能」,它不可能知道,因为训练时这台手机还没发布。

局限 2:看不到私有数据

你的公司文档、产品手册、用户协议、内部知识库——LLM 一概不知。它的训练数据来自互联网公开内容,不包含任何非公开信息。

局限 3:不知道的它会「编」

当 LLM 被问到不知道的问题时,它倾向于自信地给出看起来合理的错误答案。这种现象叫幻觉(Hallucination)。不是模型故意撒谎,而是它的工作机制就是「根据上下文预测最合理的下一个词」。如果没有相关信息,它会预测一个「听起来靠谱」的答案。

RAG 通过提供真实的参考资料来缓解这三个问题:用检索获取最新信息、用私有知识库补充模型盲区、用原文减少编造空间。

文档切分

文档切分(Chunking)是把长文本切成小片段的过程——切得好,检索才能找得准;切得不好,后面的所有优化都救不回来。

切分的「粗细」直接影响检索效果:

粒度 典型大小 优点 缺点
粗粒度 按章节或段落 上下文完整,不会切断关键语句 可能包含无关信息,检索精度下降
中粒度 固定字符数(如 300~500) 统一,便于批量处理 可能从句子中间切断
细粒度 按句子或语义段落 精确匹配用户问题 缺少上下文,信息可能不完整

什么是向量

向量是一组浮点数,比如 [0.023, -0.157, 0.892, ...](通常 256~3072 维)。每个维度代表文本在某个潜在「语义方向」上的分量。

Mermaid Diagram

相似度计算

余弦相似度(Cosine Similarity)

衡量两个向量在方向上的夹角大小,不考虑向量长度(模长)。

cos(a, b) = (a · b) / (|a| × |b|)

取值范围 含义
1 方向完全一致(语义最接近)
0 正交,不相关
-1 方向完全相反(语义最远)

Python 实现:

```python import numpy as np

def cosine_similarity(a, b): return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

vec_a = np.array([0.2, -0.1, 0.5]) vec_b = np.array([0.3, -0.2, 0.4]) print(f"余弦相似度:{cosine_similarity(vec_a, vec_b):.4f}") ```

适用场景:语义搜索、文本相似度判断、信息检索。这是 RAG 中最常用的指标,因为它只关心方向(语义倾向),不受文本长度影响。

OpenAI embeddings 已经归一化

OpenAI 的 text-embedding-3-small 和 text-embedding-3-large 输出默认是 L2 归一化的(模长为 1)。此时余弦相似度等价于点积,可以省去分母计算。

点积相似度(Dot Product / Inner Product)

直接计算两个向量的内积:

dot(a, b) = a₁b₁ + a₂b₂ + ... + aₙbₙ

```python def dot_product(a, b): return np.dot(a, b)

print(f"点积:{dot_product(vec_a, vec_b):.4f}") ```

特点 说明
与余弦的关系 当向量已 L2 归一化时,点积 = 余弦相似度
未归一化时 同时受方向和模长影响——模长长的向量更容易得高分
取值范围 无固定边界,取决于向量维度和数值范围

适用场景: - 向量已归一化时:直接替代余弦相似度,计算更快(省一次模长运算) - 向量未归一化时:适合对「高频/长文档」有偏好的场景(如长文本比短文本更值得被检索到)

欧氏距离(Euclidean Distance / L2)

衡量两个向量在多维空间中的直线距离。距离越小越相似。

L2(a, b) = √[(a₁ - b₁)² + (a₂ - b₂)² + ... + (aₙ - bₙ)²]

```python def euclidean_distance(a, b): return np.linalg.norm(a - b)

def euclidean_similarity(a, b): """将距离转为相似度分数,方便统一比较""" return 1 / (1 + euclidean_distance(a, b)) ```

与余弦相似度的关键区别:

维度 余弦相似度 欧氏距离
关注点 方向夹角 绝对距离
受向量长度影响 否 是
举例 (1,0) 与 (10,0) 的 cos=1,完全相同 (1,0) 与 (10,0) 的 L2=9,差异很大

适用场景:当向量长度本身携带语义信息时(比如向量的模长代表「信息量」或「置信度」),欧氏距离能同时捕捉方向和大小的差异。

曼哈顿距离(Manhattan Distance / L1)

计算两个向量在各维度上的绝对差之和:

L1(a, b) = |a₁ - b₁| + |a₂ - b₂| + ... + |aₙ - bₙ|

python def manhattan_distance(a, b): return np.sum(np.abs(a - b))

与欧氏距离对比:曼哈顿距离对单个维度的异常差异不那么敏感(不取平方)。在高维空间中,曼哈顿距离有时比欧氏距离更稳定(缓解「维度灾难」)。但 Embedding 检索中较少直接使用曼哈顿距离。

各指标对比总结

```python import numpy as np

def compare_metrics(a, b): """一次性输出多种相似度指标""" cos = np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)) dot = np.dot(a, b) l2 = np.linalg.norm(a - b) l1 = np.sum(np.abs(a - b))

return {
    "余弦相似度": cos,
    "点积": dot,
    "欧氏距离": l2,
    "欧氏相似度": 1 / (1 + l2),
    "曼哈顿距离": l1,
}

v1 = np.array([0.2, -0.1, 0.5]) v2 = np.array([0.3, -0.2, 0.4]) v3 = np.array([-0.5, 0.8, 0.1])

for name, val in compare_metrics(v1, v2).items(): print(f"{name}: {val:.4f}") ```

在 RAG 实践中,余弦相似度是默认选择,其次是点积(向量归一化后等效于余弦)。欧氏距离作为补充,适合向量长度携带信息的场景。向量数据库(FAISS、Milvus 等)通常同时支持多种距离度量,可以在建索引时通过参数指定。

向量数据库

工具 类型 规模 特点
Chroma 本地嵌入式 小规模 简单易用,适合原型
FAISS 本地库 中大规模 Meta 开源,性能好
Milvus 分布式 大规模 云原生,功能完整
Weaviate 分布式 中大规模 原生支持多种 Embedding 模型
Qdrant 分布式 中大规模 Rust 实现,性能优异
PostgreSQL + pgvector 扩展 中规模 如果你已经在用 Postgres

检索的基本流程

Mermaid Diagram

维度 语义检索(Semantic / Dense) 关键词检索(Lexical / Sparse)
原理 用 Embedding 模型理解语义 用 BM25/TF-IDF 匹配关键词
优势 理解同义词、近义表达 精确匹配专有名词(如产品型号)
劣势 对罕见词和专有名词敏感度低 不理解语义,「苹果」搜不到「iPhone」
场景 开放域问答、多轮对话 搜索文档标题、代码片段
工具 向量数据库 Elasticsearch、Whoosh

实践中,很多系统采用混合检索(Hybrid Search / Multi-Recall)——同时用语义检索和关键词检索,分别取 Top-K,然后合并去重。混合检索往往比单一方式更鲁棒。

评估检索有两个来自信息检索的经典指标:

  • 精确率(Precision,查准率):返回的 K 个结果中,有多少是真正相关的
  • 召回率(Recall,查全率):知识库中所有相关文档,被检索回来的占比

重排

重排(Rerank)是对初步检索结果进行二次排序的过程,用更精确的模型将最相关的文档片段排在前面。

重排的本质是用精度换时间:把需要高精度的运算限制在少量候选项上。

Mermaid Diagram

第一阶段(检索):用 Embedding 模型快速召回 Top-50 ~ Top-100

第二阶段(重排):用交叉编码器(Cross-Encoder)对每个候选逐条打分,只保留 Top-3 ~ Top-5

重排的工作原理

输入是问题和文档拼接后的文本对,输出是 0~1 之间的相关度分数。模型能同时看到问题中的每个词和文档中的每个词,捕捉它们之间的交互关系。这就是为什么交叉编码器比双编码器精度更高的原因。

生成

生成阶段的任务是:把资料、问题和指令精确地编排在一起,让 LLM 知道自己的角色、知道哪些是事实依据、知道什么情况下该说「不知道」。

一个标准的 RAG Prompt 包含三部分:

  1. 指令(Instruction):告诉 LLM 它的角色和任务
  2. 资料(Context):检索到的文档片段
  3. 问题(Question):用户的原问题

来源:博客园 · cnblogs.com