什么是大语言模型?
大语言模型(LLM)是一种 人工智能模型,它被设计用来 理解和生成人类语言。 关键在于 “大” 和 “语言模型” 这两个词:
“大” (Large): 指的是模型具有 庞大的规模,主要体现在两个方面:
大规模的训练数据: LLM 是在海量的文本数据上训练出来的,这些数据通常包括互联网上的文本、书籍、文章、代码等等,数量级可以达到 TB 甚至 PB 级别。
大规模的参数量: 模型的内部结构(通常是基于 Transformer 架构的神经网络)拥有数亿、数十亿甚至数千亿的参数。参数越多,模型理论上可以学习和存储的信息就越多,能力也更强。
“语言模型” (Language Model): 指的是模型的核心任务是 预测文本序列的概率分布。 简单来说,给定一段文本(例如,句子的一部分),语言模型的目标是预测接下来最有可能出现的词语。 虽然目标看似简单,但为了做好这个预测,模型必须学习到语言的各种规律,包括:
语法规则: 词语的正确排列顺序,句子的结构。
语义信息: 词语和句子的含义,上下文的理解。
世界知识: 模型通过学习大量文本,间接地学习到了关于世界的知识。
语用信息: 语言在不同情境下的使用方式,风格,语气等等。
总的来说,LLM 就是通过学习海量文本数据,拥有了理解和生成人类语言能力的超大规模神经网络模型。
人工智能常见领域
计算机视觉 (CV):
图像分类、目标检测、图像分割、图像生成
常用模型:ResNet、YOLO、Mask R-CNN、GANs
自然语言处理 (NLP):
文本分类、情感分析、机器翻译、文本生成、问答系统
常用模型:Word2Vec、GloVe、BERT、Transformer、GPT
语音识别 (ASR):
语音转文本、语音合成
常用模型:DeepSpeech、Wav2Vec
推荐系统:
- 协同过滤、基于内容的推荐、混合推荐
强化学习 (RL):
马尔可夫决策过程 (MDP)
Q-learning、Deep Q-Network (DQN)
策略梯度
应用场景:推荐系统、金融交易、游戏等
时间序列分析
- 应用场景:预测股票价格、汇率走势和市场趋势、预测天气变化和气候变化预测交通流量和路况等
主流AI大模型
一、 文本生成与理解类模型 (以自然语言处理为主)
1. OpenAI GPT 系列 (GPT-3, GPT-3.5, GPT-4, GPT-4 Turbo等)
开发者: OpenAI
架构: Decoder-only Transformer (自回归模型)
训练数据: 海量的文本和代码数据,包括互联网文本、书籍、代码库等,规模庞大且质量高。
关键特点:
强大的文本生成能力: 在文本生成、代码生成、创意写作、对话等方面表现卓越,生成文本流畅自然,逻辑连贯。
上下文学习 (In-context Learning): 能够根据Prompt (提示词) 中的少量示例快速适应新任务,无需针对特定任务进行微调。
指令遵循能力 (Instruction Following): 经过指令微调 (Instruction Tuning) 后,能更好地理解和执行用户指令,并生成符合指令的输出。
多模态能力 (GPT-4): GPT-4 具备处理图像输入的能力,可以进行图像描述、视觉问答等任务,是真正的多模态大模型。
持续进化: OpenAI 不断迭代和更新 GPT 系列模型,性能持续提升,例如 GPT-4 Turbo 拥有更长的上下文窗口,更低的API价格。
优点:
顶尖的文本生成质量和理解能力。
强大的通用性和泛化能力,适用范围广泛。
成熟的 API 服务和生态系统,易于集成和使用。
持续创新和迭代,性能不断提升。
缺点:
API 访问成本相对较高 (特别是 GPT-4)。
模型细节和训练数据相对封闭 (特别是 GPT-4)。
有时会产生幻觉 (Hallucination),即生成不真实或与事实不符的内容。
在某些特定领域或专业任务上,可能不如领域特定模型。
对 Prompt 工程依赖性较高,需要精心设计 Prompt 才能发挥最佳性能。
2. Google PaLM 系列 (PaLM 2, Gemini 等)
开发者: Google
架构: Decoder-only Transformer (PaLM 2),Transformer-based (Gemini)
训练数据: 海量的文本和代码数据,规模庞大,并侧重于高质量、多语言和多领域数据。
关键特点:
强大的多语言能力: PaLM 2 在多语言理解和生成方面表现突出,支持超过100种语言。
强大的推理能力: Gemini 系列模型 (特别是 Gemini Ultra) 在多项基准测试中表现出色,展现了强大的推理和理解能力,尤其在数学、逻辑推理等方面。
多模态原生支持 (Gemini): Gemini 从设计之初就考虑了多模态,能够原生处理文本、图像、音频、视频等多种模态的数据,实现真正的多模态理解和生成。
Google 生态集成: 与 Google 搜索、Android 系统、Google Cloud 等生态系统深度集成,应用潜力巨大。
优点:
顶尖的多语言能力和强大的推理能力 (特别是 Gemini)。
原生多模态支持 (Gemini),具有广阔的应用前景。
背靠 Google 强大的技术实力和生态系统。
持续发展和迭代,Gemini 系列模型有望成为 GPT 系列的强有力竞争者。
缺点:
API 访问和生态系统相对 GPT 系列稍逊 (但正在快速发展)。
Gemini Ultra 的访问权限目前较为受限。
模型细节和训练数据相对封闭。
在某些特定任务上,可能需要进一步优化和微调。
3. Meta Llama 系列 (Llama 2, Llama 3 等)
开发者: Meta (原 Facebook)
架构: Decoder-only Transformer (Llama 2),Transformer-based (Llama 3)
训练数据: 大规模的公开可用的文本数据,侧重于透明度和可复现性。
关键特点:
开源和可商用: Llama 2 系列模型开源且允许商业用途,降低了使用门槛,促进了社区发展。 Llama 3 延续开源策略。
性能接近甚至在某些方面超越 GPT-3.5: Llama 2 在某些基准测试中表现出色,性能接近甚至在某些方面超越了 GPT-3.5。 Llama 3 更进一步,性能更强大。
多种尺寸版本: 提供多种参数规模的版本 (7B, 13B, 70B 等),满足不同资源和应用场景的需求。
社区支持和生态快速发展: 开源特性吸引了大量开发者和研究者参与,社区活跃,生态系统快速发展,涌现出各种基于 Llama 的应用和工具。
优点:
开源和可商用,极大降低了使用门槛。
高性能,在某些方面可媲美甚至超越闭源模型 (如 GPT-3.5)。
多种尺寸版本,灵活性高。
强大的社区支持和活跃的生态系统。
缺点:
性能上整体相比 GPT-4 和 Gemini 仍有差距 (但 Llama 3 正在缩小差距)。
在某些复杂任务或多模态任务上,能力相对较弱。
开源模型需要一定的技术能力进行部署和维护。
4. Anthropic Claude 系列 (Claude 2, Claude 3 等)
开发者: Anthropic
架构: Transformer-based (Claude 2, Claude 3)
训练数据: 大规模的文本和代码数据,侧重于安全性和负责任的AI开发。
关键特点:
强调安全和负责任的AI: Anthropic 致力于开发安全、可靠、对人类有益的AI模型,Claude 系列模型在安全性方面进行了特别设计和优化。
长上下文窗口: Claude 2 拥有超长的上下文窗口 (100K tokens, Claude 3 Opus 达到 200K tokens),能够处理更长的文本输入,例如整本书籍或长篇文档。 Claude 3 Sonnet 和 Haiku 的上下文窗口也达到 200K tokens。
强大的理解和推理能力: Claude 3 Opus 在复杂推理、数学、代码生成等方面表现出色,在某些基准测试中甚至超越了 GPT-4 和 Gemini Ultra。
多种版本 (Claude 3): Claude 3 系列提供 Opus (最强性能)、Sonnet (性能和速度平衡)、Haiku (最快速度和低成本) 三个版本,满足不同需求。
优点:
强调安全和负责任的AI开发理念。
超长的上下文窗口,擅长处理长文本输入。
强大的理解和推理能力 (特别是 Claude 3 Opus)。
Claude 3 系列提供多种版本,选择更灵活。
缺点:
API 访问和生态系统相对 GPT 系列和 Google 稍弱。
模型细节和训练数据相对封闭。
在某些任务上,例如代码生成,可能不如专门的代码生成模型。
5. Baidu ERNIE 系列 (ERNIE 3.0 Titan, ERNIE Bot 4.0 等)
开发者: 百度
架构: Transformer-based (ERNIE 3.0 Titan, ERNIE Bot 4.0)
训练数据: 大规模中文和英文文本数据,侧重于中文理解和生成能力。
关键特点:
强大的中文理解和生成能力: ERNIE 系列模型在中文 NLP 任务上表现出色,尤其在中文文本生成、中文问答、中文信息检索等方面。
知识增强 (Knowledge Enhanced): ERNIE 模型融入了知识图谱等知识信息,增强了模型的知识理解和推理能力。
多任务学习: ERNIE 模型采用多任务学习框架进行训练,提升了模型的通用性和泛化能力。
百度生态集成: 与百度搜索、百度智能云等生态系统深度集成,应用场景广泛。
优点:
顶尖的中文理解和生成能力,在中文 NLP 领域具有优势。
知识增强,提升了知识理解和推理能力。
百度生态集成,应用场景广泛。
针对中文市场和用户进行了优化。
缺点:
英文能力相对 GPT 系列和 Google 等模型稍弱。
模型细节和训练数据相对封闭。
国际化程度相对较低,主要服务于中文市场。
6. 清华大学 ChatGLM 系列 (ChatGLM3 等)
开发者: 清华大学 KEG 实验室
架构: Transformer-based (ChatGLM3)
训练数据: 大规模中英文文本数据,侧重于开源和研究。
关键特点:
开源和免费可商用 (部分版本): ChatGLM3 部分版本开源且免费可商用,降低了使用门槛,促进了学术研究和商业应用。
强大的中文能力: ChatGLM 系列模型在中文 NLP 任务上表现出色,尤其在中文对话、中文问答等方面。
轻量化版本 (ChatGLM3-6B): 提供轻量化版本 (ChatGLM3-6B),资源需求较低,可以在消费级硬件上部署和运行。
插件机制 (Tool API): ChatGLM3 提供了 Tool API,允许模型调用外部工具,扩展了模型的功能。
优点:
开源和免费可商用 (部分版本),便于研究和应用。
强大的中文能力,尤其在中文对话领域。
轻量化版本,资源需求低,易于部署。
插件机制,扩展了模型的功能。
缺点:
英文能力相对 GPT 系列和 Google 等模型稍弱。
模型规模相对较小,整体性能相比顶尖闭源模型仍有差距 (但轻量化和开源是其优势)。
生态系统和社区规模相对较小 (但正在快速发展)。
7. 智谱 AI ChatYuan 系列 (ChatYuan-Large 等)
开发者: 智谱 AI
架构: Transformer-based (ChatYuan-Large)
训练数据: 大规模中英文文本数据,侧重于中文通用能力。
关键特点:
强大的中文通用能力: ChatYuan 系列模型在中文通用能力方面表现出色,适用于多种中文 NLP 任务。
指令遵循和对话能力: 经过指令微调,具备较好的指令遵循能力和对话能力。
多领域应用: ChatYuan 模型应用于金融、法律、教育等多个领域。
优点:
强大的中文通用能力。
指令遵循和对话能力较好。
多领域应用场景。
缺点:
英文能力相对 GPT 系列和 Google 等模型稍弱。
模型细节和训练数据相对封闭。
社区和生态系统规模相对较小。
二、 代码生成类模型
1. OpenAI Codex (基于 GPT 系列)
开发者: OpenAI
架构: Decoder-only Transformer (基于 GPT 系列)
训练数据: 海量的代码数据,包括 GitHub 代码库、公开代码数据集等。
关键特点:
强大的代码生成能力: 能够根据自然语言描述或代码注释生成代码片段或完整程序。
支持多种编程语言: 支持 Python, JavaScript, C++, Java, Go 等多种主流编程语言。
代码补全和代码修复: 可以进行代码自动补全、代码错误检测和修复等任务。
集成于 GitHub Copilot 等工具: Codex 模型是 GitHub Copilot 等代码生成工具的核心引擎。
优点:
顶尖的代码生成质量和能力。
支持多种编程语言。
集成于流行的开发工具,易于使用。
缺点:
API 访问成本相对较高。
模型细节和训练数据相对封闭。
在某些复杂或特定领域的代码生成任务上,可能需要人工辅助。
2. Google Codey (基于 PaLM 2)
开发者: Google
架构: Decoder-only Transformer (基于 PaLM 2)
训练数据: 海量的代码数据,包括公开代码库、Google 内部代码数据等。
关键特点:
强大的代码生成和代码理解能力: Codey 模型在代码生成、代码补全、代码解释等方面表现出色。
多语言支持: 支持 Python, JavaScript, Java, Go, C++ 等多种编程语言,并侧重于多语言代码生成能力。
与 Google Cloud 集成: Codey 模型与 Google Cloud Codey API 和 Google Cloud Workbench 等工具集成,方便开发者使用。
优点:
强大的代码生成和代码理解能力。
多语言支持,尤其在多语言代码生成方面具有优势。
与 Google Cloud 生态集成,方便云端开发。
缺点:
API 访问和生态系统相对 OpenAI 稍逊 (但正在快速发展)。
模型细节和训练数据相对封闭。
在某些复杂或特定领域的代码生成任务上,可能需要人工辅助。
3. Meta Code Llama 系列 (Code Llama, Code Llama - Instruct 等)
开发者: Meta
架构: Decoder-only Transformer (基于 Llama 2)
训练数据: 海量的代码数据,包括公开代码库、Stack Overflow 等。
关键特点:
开源和免费可商用: Code Llama 系列模型开源且允许商业用途,降低了使用门槛。
多种尺寸版本: 提供多种参数规模的版本 (7B, 13B, 34B 等),满足不同资源和应用场景的需求。
指令微调版本 (Code Llama - Instruct): 提供指令微调版本,针对代码生成指令进行了优化,更易于使用。
支持多种编程语言: 支持 Python, C++, Java, PHP, TypeScript, C#, Bash, SQL 等多种编程语言。
优点:
开源和免费可商用,极大降低了使用门槛。
高性能的代码生成能力,可媲美闭源模型。
多种尺寸版本和指令微调版本,灵活性高。
基于 Llama 2 开源生态,社区支持良好。
缺点:
在某些极端复杂的代码生成任务上,可能不如顶尖闭源模型。
开源模型需要一定的技术能力进行部署和维护。
生态系统相对 OpenAI 和 Google 稍逊 (但正在快速发展)。
三、 多模态模型
1. OpenAI GPT-4 (多模态版本)
开发者: OpenAI
架构: Transformer-based (多模态 Transformer)
训练数据: 文本、图像、音频、视频等多种模态的数据。
关键特点:
原生多模态支持: 能够处理文本、图像输入,并生成文本输出,实现图像描述、视觉问答等多模态任务。
强大的多模态理解和生成能力: 在多模态任务上表现出色,例如图像描述准确生动,视觉问答逻辑清晰。
与 GPT 系列文本能力无缝衔接: 多模态能力与 GPT 系列强大的文本能力无缝衔接,可以实现更复杂的多模态应用。
优点:
顶尖的多模态理解和生成能力。
与 GPT 系列文本能力融合,应用潜力巨大。
成熟的 API 服务和生态系统。
缺点:
API 访问成本更高 (相比纯文本模型)。
模型细节和多模态训练数据相对封闭。
多模态能力仍处于发展初期,可能存在一些局限性。
2. Google Gemini 系列 (Gemini Ultra, Gemini Pro, Gemini Nano)
开发者: Google
架构: Transformer-based (原生多模态 Transformer)
训练数据: 文本、图像、音频、视频等多种模态的大规模数据。
关键特点:
原生多模态架构: Gemini 从设计之初就考虑了多模态,采用原生多模态 Transformer 架构,能够更有效地融合和处理多种模态的数据。
顶尖的多模态性能: Gemini Ultra 在多项多模态基准测试中表现出色,超越了 GPT-4 等模型。
多种尺寸版本: Gemini 系列提供 Ultra (最强性能), Pro (性能和效率平衡), Nano (移动端部署) 三个版本,满足不同需求。
Google 生态集成: 与 Google 搜索、Android 系统、Google Cloud 等生态系统深度集成,多模态应用场景广阔。
优点:
顶尖的多模态性能,在多模态领域具有领先优势。
原生多模态架构,更有效地融合和处理多模态数据。
多种尺寸版本,灵活性高。
背靠 Google 强大的技术实力和生态系统,应用前景广阔。
缺点:
Gemini Ultra 的访问权限目前较为受限。
API 访问和生态系统相对 GPT 系列稍逊 (但正在快速发展)。
模型细节和多模态训练数据相对封闭。
多模态能力仍处于发展初期,仍有提升空间。
总结与选择建议:
选择合适的AI大模型需要根据具体的应用场景、需求和资源情况进行权衡:
文本生成与理解任务:
追求顶尖性能和通用性: GPT-4 或 Gemini Ultra 是首选,但成本较高。
追求高性能和相对较低成本: GPT-3.5 Turbo, PaLM 2, Claude 3 Sonnet/Opus 是不错的选择。
追求开源和可商用: Llama 3 或 Code Llama 系列是最佳选择。
中文 NLP 任务: ERNIE Bot 4.0 或 ChatGLM3 系列在中文领域具有优势。
代码生成任务:
追求顶尖代码生成能力: Codex (GitHub Copilot) 或 Codey 是首选。
追求开源和可商用: Code Llama 系列是最佳选择。
多模态任务:
追求顶尖多模态性能: Gemini Ultra 或 GPT-4 (多模态版本) 是首选,但成本较高。
需要考虑成本和易用性: Gemini Pro 或 GPT-4 (多模态版本) 的API 也是可行的选择。
Prompt Engineering (提示工程)
1. 什么是 Prompt Engineering? (核心概念)
Prompt Engineering (提示工程) 关注于 设计和优化 “提示” (Prompts) ,以有效地引导大语言模型 (LLM) 产生期望的输出结果。
“Prompt” (提示): 指的是你提供给 LLM 的 输入文本,用来指示模型你想要它做什么。 Prompt 可以是一个问题、一个指令、一个不完整的句子、甚至是一段对话的开头。
“Engineering” (工程): 提示工程不仅仅是随意写几句话,而是一个 系统化、迭代优化 的过程。 它涉及到:
理解 LLM 的能力和局限性: 你需要知道 LLM 擅长什么,不擅长什么,才能设计出有效的 Prompt。
掌握 Prompt 设计技巧: 学习各种 Prompt 设计策略,例如清晰指令、上下文提供、角色扮演、少样本学习等等。
实验和迭代: 通过不断尝试不同的 Prompt,观察模型输出,并根据结果进行调整和优化,最终找到最佳的 Prompt。
可以把 Prompt 理解为与 LLM 沟通的 “语言” 或 “指令” 。 Prompt Engineering 就是学习如何用 LLM 能理解的语言,清晰、有效地告诉它你需要它做什么。
Prompt Engineering 的核心技巧和策略
以下是一些常用的 Prompt 设计技巧和策略:
清晰明确的指令 (Clear and Specific Instructions): 这是最基本也是最重要的原则。 Prompt 应该尽可能地清晰、明确、具体,避免歧义和模糊不清的表达。 告诉模型 做什么 (What to do)**,怎么做 (How to do it),输出什么格式 (Output format)**。
反例: “写一篇关于猫的文章。” (太笼统)
正例: “请写一篇 300 字左右的文章,介绍家猫的品种、生活习性以及如何照顾它们。文章的目标读者是想要养猫的初学者。文章风格应该轻松活泼。” (更具体、更清晰)
提供上下文信息 (Provide Context): 如果任务需要一定的背景知识或上下文,需要在 Prompt 中提供相关信息,帮助模型更好地理解你的意图。
- 例子: “用户评论:’这家餐厅的披萨很好吃,但是服务太慢了。’ 请根据这条评论,判断用户对这家餐厅的整体评价是正面、负面还是中性。” (提供了用户评论作为上下文)
角色扮演 (Role-Playing/Persona): 指示 LLM 扮演特定的角色,例如 “你是一个专业的客服人员”, “你是一个历史学家”, “你是一个代码助手” 等等。 这可以引导模型以更符合角色设定的风格和知识来生成回复。
- 例子: “请你扮演一个经验丰富的旅行顾问,为一位计划去日本旅游的游客推荐三个值得去的城市,并简要说明理由。”
指定输出格式 (Specify Output Format): 明确告诉模型你期望的输出格式,例如 “以列表形式输出”, “以 JSON 格式输出”, “生成一段代码” 等等。
- 例子: “请列出 5 部评分最高的科幻电影,并以 Markdown 列表形式输出,每项包括电影名称和评分。”
少样本学习 (Few-shot Learning): 在 Prompt 中提供一些 **示例 (Examples)**,展示你期望的输入和输出的对应关系。 这可以帮助 LLM 更好地理解任务,尤其是在任务比较复杂或难以用语言精确描述时。
例子:
1
2
3
4输入: "我今天心情很糟糕。" 情感: 负面
输入: "这部电影太精彩了!" 情感: 正面
输入: "天气晴朗。" 情感: 中性
输入: "我考试考砸了。" 情感:
思维链提示 (Chain-of-Thought Prompting): 对于需要复杂推理的任务,可以引导 LLM **逐步思考 (Step-by-step thinking)**。 在 Prompt 中要求模型解释它的思考过程,或者提供一些中间步骤的提示。 这可以显著提高 LLM 在推理任务上的表现。
- 例子: “问题:如果我有 3 个苹果和 2 个梨,我吃掉了一个苹果和一个梨,我还剩下多少水果? 请一步一步思考,并给出最终答案。”
约束和限制 (Constraints and Boundaries): 在 Prompt 中明确指定一些约束条件,例如 “字数限制为 100 字以内”, “回答必须基于以下材料”, “不要包含个人信息” 等等。 这有助于控制模型输出的范围和内容。
迭代优化 (Iterative Refinement): Prompt Engineering 是一个迭代的过程。 不要期望一次就能写出完美的 Prompt。 尝试不同的 Prompt,观察模型输出,分析结果,并根据需要进行调整和改进。 这是一个不断试错和优化的过程。
负面提示 (Negative Prompting, 较少使用,但在某些场景下有用): 告诉模型 **不要做什么 (What not to do)**。 例如, “请写一篇关于人工智能的文章,但不要涉及深度学习算法。” 这在一些特定的内容控制场景下可能有
大模型架构
Transformer架构及其变体 (Transformer & Variants):
核心思想: 基于自注意力机制 (Self-Attention Mechanism),能够并行处理序列数据,有效捕捉长距离依赖关系。
代表模型:
BERT (Bidirectional Encoder Representations from Transformers): Encoder-only架构,擅长理解语言表示,用于文本分类、命名实体识别、问答等任务。
GPT (Generative Pre-trained Transformer) 系列 (GPT-3, GPT-4等): Decoder-only架构,擅长生成文本,用于文本生成、对话、代码生成等任务。
T5 (Text-to-Text Transfer Transformer): Encoder-Decoder架构,将所有NLP任务都转化为文本到文本的生成任务,通用性强。
BART (Bidirectional and Auto-Regressive Transformer): Encoder-Decoder架构,结合了BERT的双向编码和GPT的自回归解码,擅长序列到序列的任务,如摘要、翻译等。
Transformer-XL (Transformer with Extra Long Context): 改进了Transformer处理长序列的能力,通过引入循环机制和相对位置编码,能够处理更长的上下文。
Longformer: 通过稀疏注意力机制 (Sparse Attention) 降低Transformer处理长序列的计算复杂度,提升效率。
Big Bird: 结合全局注意力、窗口注意力和随机注意力,进一步优化长序列处理能力。
Vision Transformer (ViT): 将Transformer应用于图像领域,将图像分割成Patch,作为序列输入Transformer进行处理,在图像分类等任务上取得了优秀成果。
Swin Transformer: 引入滑动窗口注意力机制 (Shifted Window Attention),在Vision Transformer基础上进一步提升了图像任务的性能,尤其在目标检测和语义分割等任务上表现出色。
特点:
并行计算: 自注意力机制允许并行计算序列中不同位置的信息,加速训练和推理。
长距离依赖: 自注意力机制能够直接捕捉序列中任意两个位置之间的依赖关系,有效处理长文本或长序列数据。
可扩展性强: Transformer架构易于扩展到更大的模型规模,通过增加层数、注意力头数和隐藏层维度来提升模型容量。
通用性: Transformer架构在自然语言处理、计算机视觉、语音识别等多个领域都取得了成功,展现了强大的通用性。
2. 循环神经网络及其变体 (RNN & Variants):
核心思想: 通过循环结构处理序列数据,记忆之前的状态信息,适用于处理变长序列。
代表模型:
LSTM (Long Short-Term Memory Networks): 长短期记忆网络,通过引入门控机制 (Gate Mechanism) 解决了传统RNN的梯度消失和梯度爆炸问题,能够有效捕捉长期依赖。
GRU (Gated Recurrent Unit): 门控循环单元,是LSTM的简化版本,在性能接近LSTM的同时,参数更少,计算效率更高。
双向RNN (Bidirectional RNN): 能够同时利用序列的前向和后向信息,更全面地理解序列上下文。
特点:
处理序列数据: 天然适合处理序列数据,如文本、语音、时间序列等。
记忆能力: 循环结构使其能够记忆之前的状态信息,捕捉序列的动态变化。
变长序列处理: 可以处理不同长度的输入序列。
局限性:
串行计算: RNN的计算是串行的,难以并行化,训练和推理速度较慢。
长距离依赖问题 (相对Transformer而言): 虽然LSTM和GRU缓解了梯度消失问题,但对于非常长的序列,仍然可能存在信息丢失或梯度衰减的问题,捕捉长距离依赖的能力相对Transformer较弱。
3. 卷积神经网络及其变体 (CNN & Variants):
核心思想: 通过卷积核提取局部特征,适用于处理图像、音频等网格状数据。
代表模型:
ResNet (Residual Network): 残差网络,通过引入残差连接 (Residual Connection) 解决了深层网络训练困难的问题,可以训练非常深的CNN网络。
EfficientNet: 高效网络,通过统一缩放网络深度、宽度和分辨率来优化网络性能和效率。
ConvNeXt: 受Vision Transformer启发,对ResNet进行现代化改造,使其在图像分类等任务上性能接近甚至超过Vision Transformer。
特点:
局部特征提取: 卷积核能够有效地提取局部特征,如边缘、纹理等。
参数共享: 卷积核在整个输入上共享参数,减少了模型参数量。
平移不变性: 卷积操作具有平移不变性,对于图像识别等任务非常有利。
局限性 (在处理长序列和全局依赖方面):
捕捉长距离依赖能力弱 (相对Transformer而言): CNN主要关注局部特征,捕捉长距离依赖关系需要堆叠多层卷积,效率较低。
不擅长处理序列数据 (直接使用时): 原始的CNN结构更适合处理网格状数据,直接应用于序列数据可能效果不如RNN或Transformer。
4. 混合架构 (Hybrid Architectures):
核心思想: 结合不同架构的优点,扬长避短,以适应更复杂的任务和场景。
代表模型:
Transformer-CNN混合架构: 例如将CNN作为Transformer的特征提取器,或者将Transformer用于处理CNN提取的特征,结合了CNN的局部特征提取能力和Transformer的全局依赖捕捉能力,常用于视觉和多模态任务。
RNN-Transformer混合架构: 例如使用RNN处理序列的局部信息,再用Transformer处理全局信息,或者将Transformer的输出作为RNN的输入,结合了RNN的序列建模能力和Transformer的长距离依赖捕捉能力。
MoE (Mixture of Experts) 架构: 并非独立的架构,而是一种模型扩展技术,可以将Transformer、CNN、RNN等作为专家模型,通过门控网络 (Gating Network) 动态选择不同的专家来处理不同的输入,提升模型容量和泛化能力。
特点:
性能更强: 结合不同架构的优点,通常能取得比单一架构更好的性能。
适应性更广: 能够适应更复杂的任务和场景。
设计更复杂: 混合架构的设计通常更复杂,需要仔细权衡不同组件的优缺点。
总结:
Transformer架构及其变体 目前是AI大模型的主流架构,尤其在自然语言处理领域占据主导地位,并在计算机视觉等领域也取得了显著进展。
RNN架构及其变体 在序列建模领域仍有应用价值,但在大规模模型中相对较少单独使用,更多的是作为混合架构的组件。
CNN架构及其变体 在计算机视觉领域仍然至关重要,也常被用作混合架构的特征提取器。
混合架构 是未来发展的重要趋势,能够结合不同架构的优势,构建更强大、更通用的AI模型。
预训练模型与微调 (Pre-training and Fine-tuning)
可以把预训练和微调比作 教育过程。 预训练就像是 通识教育,打下广泛的基础,而微调则是 专业教育,针对特定领域进行深入学习。
1. 预训练 (Pre-training) - 通识教育,打基础
概念: 预训练是训练大语言模型 (LLM) 的 第一阶段,也是最耗时和资源最多的阶段。 在这个阶段,模型会在 海量的通用文本数据 上进行训练,例如:
互联网上的网页文本 (Common Crawl)
书籍 (Books3)
维基百科 (Wikipedia)
新闻文章
代码库 (GitHub 代码)
等等
这些数据涵盖了各种主题、风格和语言形式,旨在让模型尽可能地 学习到通用的语言知识和世界知识。
目标: 预训练的目标是让模型 掌握语言的基本规律,例如:
语法规则: 如何正确地组织句子,词语之间的搭配关系。
语义信息: 词语和句子的含义,上下文的理解。
世界知识: 关于世界的常识,例如 “巴黎是法国的首都”, “苹果是一种水果” 等等。
语言风格和模式: 不同类型的文本 (例如新闻、小说、代码) 的特点。
预训练的最终产物就是一个 “预训练模型” (Pre-trained Model)。 这个模型已经具备了 初步的语言理解和生成能力,但它还 不擅长执行特定的任务,例如情感分析、机器翻译、问答等。 它更像是一个 通才,什么都会一点,但都不精。
预训练任务: 为了让模型学习到上述语言知识,预训练阶段通常会设计一些 自监督学习 (Self-supervised Learning) 任务。 这意味着训练数据本身就包含了标签,无需人工标注。 常见的预训练任务包括:
掩码语言模型 (Masked Language Modeling, MLM): (例如 BERT 使用的任务)
原理: 随机遮盖输入文本中的一部分词语 (例如用 [MASK] 替换),然后让模型 预测被遮盖的词语。
作用: 迫使模型理解上下文信息,学习词语之间的关系,从而掌握双向的语言表示能力。
例子: 输入: “The capital of France is [MASK].” 目标: 预测 [MASK] 为 “Paris”。
因果语言模型 (Causal Language Modeling, CLM): (例如 GPT 系列使用的主任务)
原理: 给定一段文本的前面部分,让模型 预测下一个词语。 模型需要根据已有的上下文,逐词生成后续的文本。
作用: 让模型学习生成连贯、流畅的文本,掌握单向的语言生成能力。
例子: 输入: “The capital of France is “ 目标: 预测下一个词为 “Paris”。 然后再预测 “Paris” 之后的下一个词,以此类推。
还有一些其他的预训练任务,例如 下一句预测 (Next Sentence Prediction, NSP) (BERT 早期使用,后来发现效果不明显), 对比学习 (Contrastive Learning) 等等。
2. 微调 (Fine-tuning) - 专业教育,精专领域
概念: 微调是训练 LLM 的 第二阶段,也是 任务适配阶段。 在预训练之后,如果我们想要让 LLM 在 特定的任务或领域 上表现出色,就需要进行微调。
目标: 微调的目标是让 预训练模型适应特定的下游任务,例如:
情感分析: 判断文本的情感倾向 (正面、负面、中性)。
机器翻译: 将文本从一种语言翻译成另一种语言。
问答系统: 回答用户提出的问题。
文本摘要: 将长文本压缩成简短的摘要。
对话生成: 生成与用户进行对话的回复。
代码生成: 根据自然语言描述生成代码。
等等,各种各样的 NLP 任务。
微调的产物就是一个 “微调模型” (Fine-tuned Model)。 这个模型在 特定任务上表现更优秀,但它的通用性可能会有所降低,因为它更专注于特定领域的知识和技能。 它更像是一个 专才,在特定领域非常精通。
微调数据: 微调需要使用 特定任务的标注数据。 例如,如果要做情感分析,就需要情感标注的数据集 (文本 + 情感标签)。 如果要做机器翻译,就需要平行语料库 (源语言文本 + 目标语言文本)。 微调数据量通常比预训练数据量小得多,但质量要求更高,需要与目标任务高度相关。
微调方法: 微调通常是在 预训练模型的基础上 进行的。 具体步骤如下:
选择预训练模型: 选择一个与目标任务相关的预训练模型作为基础模型。
准备微调数据: 准备特定任务的标注数据集。
修改模型结构 (可选): 根据任务需求,可能需要在预训练模型的基础上添加一些额外的层或修改模型的输出层。
训练模型: 使用微调数据,继续训练预训练模型。 但通常会 降低学习率,并 只训练模型的一部分参数 (例如只微调最后的几层),以避免过度修改预训练模型学到的通用知识。
评估模型: 在验证集或测试集上评估微调模型的性能,并进行调优。
为什么需要微调?
提高任务性能: 预训练模型虽然具备通用语言能力,但在特定任务上可能表现不够出色。 微调可以使模型更好地适应特定任务的需求,显著提高任务性能。
任务定制化: 不同的任务需要模型学习不同的知识和技能。 微调可以将预训练模型 “塑造成” 适用于特定任务的模型。
降低数据需求: 相比于从头开始训练模型,微调只需要少量特定任务的数据就能取得不错的效果。 这大大降低了数据和计算资源的成本。
3. 预训练 vs 微调 的关系总结
预训练是基础,微调是应用。 预训练提供了一个强大的语言模型骨架,微调则是在这个骨架上构建各种应用。
预训练关注通用性,微调关注特定性。 预训练学习通用语言知识,微调学习特定任务的技能。
预训练数据量大,微调数据量小但质量高。 预训练需要海量通用数据,微调需要少量高质量的特定任务数据。
预训练耗时耗资源,微调相对快速经济。 预训练需要大量的计算资源和时间,微调则相对经济高效。
什么是 Context Window (上下文窗口)
核心定义: Context Window,中文通常翻译为 上下文窗口 或 语境窗口,是指 大语言模型 (LLM) 在一次处理过程中,能够考虑的最大文本长度。 这个长度是以 token 数量 来衡量的,而不是字符数或单词数。
形象比喻: 你可以把 Context Window 想象成:
人的短期记忆: 我们人类的短期记忆容量是有限的,只能记住最近发生的事情。 Context Window 就像是 LLM 的 “短期记忆”,它只能记住最近输入的文本片段。
对话时的语境范围: 在对话中,我们理解当前对话内容,也依赖于之前的对话历史。 Context Window 决定了 LLM 在生成回复时,能够回顾和利用的对话历史的长度。
书签标记的阅读范围: 如果你正在阅读一本书,Context Window 就好比你在书页上用书签标记的一段范围。 LLM 在处理当前位置时,只能 “看到” 书签标记范围内的内容,而无法直接访问书签之外的内容。
为什么 Context Window 有长度限制?
Context Window 的长度限制,主要源于 Transformer 架构的 自注意力机制 (Self-Attention) 的 计算复杂性 和 硬件资源的限制。
自注意力机制的计算复杂度: Transformer 的自注意力机制,其计算复杂度与输入序列长度 (token 数量) 的 平方 成正比,即 **O(L^2)**,其中 L 是序列长度。
这意味着,如果序列长度增加一倍,自注意力计算量会增加到原来的 四倍。
当序列长度非常长时,自注意力计算会变得非常 耗时 且 占用大量内存 (显存)。
硬件资源的限制: 训练和运行 LLM 需要强大的计算资源 (GPU/TPU) 和内存 (显存)。 Context Window 越大,模型需要的计算资源和内存也越多。 受到硬件资源的限制,Context Window 的长度不可能无限增大。
训练效率和推理效率的权衡: 为了保证 LLM 的 训练效率 和 推理效率,需要对 Context Window 的长度进行限制。 过大的 Context Window 会显著降低模型的训练和推理速度,甚至导致模型无法在有限的硬件资源下运行。
Context Window 的单位: Token (词元)
重要概念:Tokenization (分词): 再次强调,Context Window 的长度是以 token 数量 来衡量的,而不是字符数或单词数。 这是因为 LLM 处理文本时,首先需要将文本 tokenize (分词) 成一个个的 **token (词元)**。
Token 的种类: Token 可以是单词、子词 (subword) 或字符,取决于具体的 Tokenization 算法 (例如 BPE, WordPiece, SentencePiece)。 例如,英文单词 “unbelievable” 可能被 tokenize 成 [“un”, “believ”, “able”] 三个 token。
不同语言的 Token 数量: 对于相同的文本内容,不同的语言,甚至不同的 Tokenizer,tokenize 后的 token 数量可能会有所不同。 通常来说,英文等空格分隔的语言,平均一个单词约等于 1.3-1.5 个 token。 中文、日文等非空格分隔的语言,tokenization 的方式更复杂,token 与单词的对应关系更不直接。
理解 Tokenization 的重要性: 理解 Tokenization 对于准确预估文本的 token 数量,以及合理利用 Context Window 非常重要。 可以使用在线的 Tokenizer 工具 (例如 OpenAI Tokenizer) 来计算文本的 token 数量。
4. Context Window 的大小范围 (不断增长)
早期 LLM: 早期的 LLM (例如 GPT-2, GPT-3) 的 Context Window 长度通常在 几百到几千个 token 左右 (例如 512, 1024, 2048, 4096 tokens)。
近年来 LLM 的发展: 随着技术的进步,特别是 Transformer 架构的优化和硬件的提升,Context Window 的长度正在迅速增长。 新的 LLM (例如 GPT-4, Claude 2, Claude 3, Llama 2, Llama 3, 一些开源模型) 的 Context Window 可以达到 数万甚至数十万 token (例如 8k, 16k, 32k, 100k, 200k tokens)。
Context Window 长度的未来趋势: 增大 Context Window 长度是 LLM 发展的重要趋势之一。 更大的 Context Window 将使 LLM 能够处理更复杂的任务,理解更长篇的上下文,并实现更丰富的应用场景。 但同时,也需要解决计算效率和资源消耗的问题。
Context Window 的影响 (重要性)
Context Window 的大小直接影响了 LLM 的能力和应用范围:
长文本处理能力: Context Window 越大,LLM 可以处理的文本长度越长。 例如,可以处理更长的文档、书籍、代码库、对话记录等。 对于需要理解长篇上下文的任务 (例如长文档问答、长篇故事续写、代码理解),更大的 Context Window 至关重要。
上下文理解范围: Context Window 限制了 LLM 在生成回复时能够考虑的上下文范围。 如果对话历史、文档内容超出了 Context Window,模型可能会 “忘记” 之前的上下文信息,导致回答不准确、对话不连贯、信息丢失等问题。
复杂推理能力: 对于需要复杂推理的任务 (例如多步推理、跨文档推理、长程依赖推理),更大的 Context Window 可以提供更多的上下文信息,帮助模型进行更深入、更准确的思考和推理。
记忆能力 (对话系统): 在对话系统中,Context Window 决定了模型的 “对话记忆” 能力。 更大的 Context Window 可以让对话机器人记住更长时间的对话历史,实现更连贯、更自然的对话体验。
应用场景拓展: 更大的 Context Window 为 LLM 开辟了更广阔的应用场景,例如:
长文档分析和问答: 处理法律文档、研究报告、技术手册等长篇文档。
大规模代码库分析和生成: 理解和生成更复杂的代码。
长篇故事创作和续写: 创作更复杂、更连贯的故事。
多轮对话和复杂对话流程: 实现更自然、更流畅的多轮对话。
如何处理长上下文 (超过 Context Window 限制)
即使 Context Window 在不断增大,但它仍然是一个有限的资源。 当我们需要处理超过 Context Window 长度的文本时,就需要采取一些策略来应对。 以下是一些常用的方法,并结合易懂的示例进行说明:
1. 文本摘要 (Summarization)
策略: 将长文本 压缩成更短的摘要,只保留关键信息,然后将摘要输入到 LLM 中。 这样可以显著缩减文本长度,使其符合 Context Window 的限制。
适用场景: 适用于需要处理长文档、长文章、书籍等场景,例如:
长文档问答: 先对长文档进行摘要,然后基于摘要进行问答。
信息检索: 对检索结果进行摘要,快速了解文档内容。
会议纪要生成: 对会议录音或记录进行摘要,提取会议要点。
示例:
原始长文本 (例如一篇长篇新闻报道): 假设是一篇关于 “某地发生特大洪水灾害” 的详细报道,内容包括灾害发生的时间、地点、原因、受灾情况、救援进展、后续重建计划等等,token 数量超过 10000。
摘要后的文本: 使用摘要算法 (可以是传统的摘要算法,也可以使用 LLM 本身进行摘要) 将长篇报道压缩成一段摘要,例如:
1
某地遭遇百年不遇特大洪水,造成严重人员伤亡和财产损失。洪水于 [时间] 爆发,原因是 [原因]。受灾最严重的地区包括 [地区1], [地区2], [地区3]。目前救援工作正在紧张进行中,已转移安置 [人数] 灾民。政府已启动紧急响应,并制定灾后重建计划。
摘要后的文本,token 数量可能只有几百,远远小于原始文本,可以轻松放入 Context Window。 然后,我们可以基于摘要后的文本,向 LLM 提问,例如: “这次洪水的主要原因是什么?”, “受灾最严重的地区有哪些?”, “政府的重建计划是什么?”
优点: 简单直接,有效缩减文本长度。
缺点: 摘要过程可能会丢失一些细节信息,摘要质量会影响后续任务的效果。
2. 文本分块/分段 (Chunking/Segmentation)
策略: 将长文本 分割成多个较小的段落或块 (chunks)**,每个块的长度都控制在 Context Window 限制之内。 然后,可以 **逐个处理每个块,或者 结合多个块的信息 进行处理。
适用场景: 适用于需要处理结构化长文本的场景,例如:
长文档问答: 将文档分割成段落,对每个段落进行索引,然后根据问题检索相关段落进行问答。
长篇故事续写: 将故事分割成章节,每次只输入前几个章节,让 LLM 续写下一个章节。
代码库分析: 将代码库分割成文件或函数,分别分析每个文件或函数。
分块方法:
固定大小分块 (Fixed-size Chunking): 按照固定的 token 数量或字符数量进行分块,例如每 500 个 token 分成一块。 简单直接,但可能破坏语义完整性。
语义分块 (Semantic Chunking): 根据文本的语义结构进行分块,例如按照段落、章节、句子等进行分割。 可以更好地保留语义完整性,但分块大小可能不均匀。
滑动窗口分块 (Sliding Window Chunking): 使用滑动窗口在文本上滑动,每次取窗口内的文本作为一个块。 可以保证块之间的上下文连续性,但可能存在信息冗余。
示例 (长文档问答):
原始长文档 (例如一篇长篇技术文档): 假设是一篇关于 “深度学习模型优化技巧” 的技术文档,内容分为多个章节,例如 “模型初始化”, “学习率调整”, “正则化方法”, “优化器选择” 等等,总 token 数量超过 20000。
文本分块: 将文档按照章节进行分割,每个章节作为一个 chunk。 例如:
Chunk 1: “模型初始化” 章节内容 (token 数量 < 4000)
Chunk 2: “学习率调整” 章节内容 (token 数量 < 4000)
Chunk 3: “正则化方法” 章节内容 (token 数量 < 4000)
Chunk 4: “优化器选择” 章节内容 (token 数量 < 4000)
…
处理方式:
基于块的问答: 当用户提问 “如何选择合适的优化器?”,可以先检索到 “优化器选择” 章节 (Chunk 4),然后只将 Chunk 4 输入到 LLM 中进行问答。
跨块信息整合: 如果问题需要跨多个章节的信息,可以分别对相关 chunk 进行处理,然后将多个 chunk 的输出结果进行整合,得到最终答案。
优点: 可以处理结构化长文本,保留更多细节信息,可以针对特定 chunk 进行处理。
缺点: 需要考虑如何分块,以及如何整合多个块的信息。 块之间的上下文信息可能丢失。
3. 信息检索 (Information Retrieval)
策略: 对于知识密集型任务 (例如问答系统), 不直接将整个长文档输入到 LLM 中,而是先从海量文档中检索出与问题最相关的文档片段 (或段落)**,然后 **只将检索到的相关片段与问题一起输入到 LLM 中 进行处理。 这可以大大减少输入文本的长度,并提高回答的准确性。
适用场景: 适用于知识库问答、搜索引擎、文档检索等场景,例如:
构建企业知识库问答系统: 用户提问时,先从企业知识库中检索相关文档,然后基于检索到的文档回答问题。
搜索引擎增强问答: 用户在搜索引擎中提问时,先检索相关网页,然后基于网页内容回答问题。
法律咨询、医学咨询等专业领域问答: 从法律法规库、医学文献库等专业知识库中检索相关信息,辅助回答问题。
信息检索技术: 可以使用传统的文本检索技术 (例如 TF-IDF, BM25),也可以使用基于向量相似度的语义检索技术 (例如使用 Sentence Embeddings, 向量数据库)。
示例 (知识库问答):
海量知识库文档: 假设有一个企业内部知识库,包含大量的文档 (例如产品手册、FAQ 文档、内部 Wiki 等),总 token 数量可能非常庞大,远远超出 Context Window 限制。
信息检索流程:
用户提问: 例如 “如何设置打印机的无线网络连接?”
知识库检索: 使用信息检索算法,在知识库文档中检索出与问题最相关的文档片段 (例如 “打印机无线网络连接设置指南” 文档中的相关段落)。
构建 Prompt: 将用户问题和检索到的相关文档片段一起构建成 Prompt,例如:
1
2
3
4
5
6
7请根据以下文档片段回答问题:
文档片段:
[检索到的 "打印机无线网络连接设置指南" 文档中的相关段落]
问题: 如何设置打印机的无线网络连接?
答案:
- LLM 回答: 将 Prompt 发送给 LLM,模型基于提供的文档片段生成答案。
优点: 可以处理海量知识库,只处理相关信息,提高效率和准确性。 可以有效缓解 Context Window 限制。
缺点: 检索算法的准确性会影响最终效果,需要维护知识库和检索系统。
4. 记忆机制 (Memory Mechanisms, 主要用于对话系统)
策略: 对于对话系统,可以使用 外部记忆模块 (例如向量数据库、键值存储) 来 存储和检索对话历史,突破 Context Window 的限制,实现更长程的对话记忆。
适用场景: 主要用于对话系统、聊天机器人等需要维护对话历史的场景。
记忆模块类型:
简单记忆 (Simple Memory): 只存储最近几轮对话的历史记录 (例如最近 5 轮对话),超出部分就丢弃。 简单易实现,但记忆能力有限。
总结记忆 (Summary Memory): 定期对对话历史进行摘要,将摘要信息存储起来。 可以压缩对话历史,但摘要质量会影响记忆效果。
向量记忆 (Vector Memory): 将对话历史 (例如每轮对话的 utterance) 编码成向量表示,存储到向量数据库中。 可以进行语义检索,找到与当前对话最相关的历史信息。 LangChain 等框架提供了多种向量记忆模块的实现。
示例 (对话系统):
对话历史 (多轮对话): 假设用户和聊天机器人进行了多轮对话,对话历史已经很长,超出了 Context Window 限制。
向量记忆机制:
对话轮次编码: 将每一轮对话 (用户 utterance 和机器人 response) 编码成向量表示。
向量存储: 将对话向量存储到向量数据库中。
检索相关历史: 当用户提出新的问题时,将当前问题也编码成向量,然后在向量数据库中检索与当前问题最相关的历史对话向量。
构建 Prompt (带记忆): 将当前问题和检索到的相关历史对话片段一起构建成 Prompt,输入到 LLM 中。
1
2
3
4
5相关对话历史:
[检索到的历史对话片段,例如最近几轮对话,或者语义上最相关的对话]
当前用户问题: [用户最新提出的问题]
聊天机器人回复:
- LLM 生成回复: LLM 基于 Prompt 中的当前问题和相关历史对话,生成回复。
优点: 可以突破 Context Window 的限制,实现更长程的对话记忆,提升对话连贯性和用户体验。
缺点: 需要维护外部记忆模块,记忆模块的质量和检索效果会影响对话系统性能。
5. 模型微调 (Fine-tuning) 或 Prompt 工程 (Prompt Engineering)
策略: 针对特定的长上下文任务,可以通过 模型微调 (Fine-tuning) 或 Prompt 工程 (Prompt Engineering) 的方法,来提高模型在有限 Context Window 下的处理能力。
模型微调: 可以使用长文本数据集,对 LLM 进行微调,让模型 更擅长处理长序列输入。 例如,可以使用更长的训练序列长度,或者采用一些针对长序列优化的训练技巧。
Prompt 工程: 设计更 精巧、高效的 Prompt,例如:
使用更简洁的指令: 在 Prompt 中使用更精炼的语言,减少冗余信息。
引导模型关注关键信息: 在 Prompt 中明确指示模型需要关注哪些关键信息,忽略哪些不重要的信息。
利用少样本学习 (Few-shot Learning): 在 Prompt 中提供一些长上下文任务的示例,引导模型学习处理长上下文的方法。
思维链提示 (Chain-of-Thought Prompting): 引导模型进行逐步推理,分解复杂任务,降低对长上下文的依赖。
适用场景: 适用于各种长上下文任务,可以与其他策略 (例如文本摘要、分块、检索) 结合使用,进一步提升效果。
优点: 可以更精细地控制模型行为,针对特定任务进行优化。
缺点: 模型微调需要更多的数据和计算资源,Prompt 工程需要一定的经验和技巧。
RAG 实现技术流程分解 (Detailed Technical Workflow)
RAG 的核心流程可以分为两个主要阶段: 离线索引构建阶段 (Offline Indexing) 和 **在线查询与生成阶段 (Online Query & Generation)**。
I. 离线索引构建阶段 (Offline Indexing/Knowledge Base Preparation):
这个阶段的目标是构建一个高效、可检索的向量数据库,作为 RAG 系统的知识库。 通常在系统部署前或定期进行。
数据获取与收集 (Data Acquisition & Collection):
确定数据源: 明确 RAG 系统需要利用的知识来源。 数据源可以是:
文档集合: PDF 文档, Word 文档, TXT 文档, HTML 网页, Markdown 文件, 电子书等。
数据库: 关系型数据库 (SQL), NoSQL 数据库 (MongoDB, Cassandra 等)。
知识图谱: 结构化的知识库,如 Wikidata, DBpedia, 自建知识图谱等。
API 数据: 从外部 API 获取的实时数据或结构化信息。
多媒体数据: 图像, 音频, 视频 (需要相应的处理和嵌入技术)。
数据采集工具: 根据数据源类型选择合适的采集工具:
网页爬虫 (Web Scrapers): Scrapy, Beautiful Soup, Puppeteer 等,用于抓取网页内容。
数据库连接器 (Database Connectors): JDBC, ODBC, 各种数据库的 Python 客户端 (PyMySQL, psycopg2, pymongo 等),用于连接和读取数据库数据。
API 客户端 (API Clients): Requests, aiohttp 等 HTTP 客户端,用于调用和获取 API 数据。
文件读取库 (File Reading Libraries): PyPDF2, python-docx, python-pptx, unstructured 等,用于读取不同格式的文件内容。
数据预处理与清洗 (Data Preprocessing & Cleaning):
格式转换与标准化 (Format Conversion & Normalization): 将不同格式的数据统一转换为便于处理的格式,例如统一编码 (UTF-8), 统一文档格式 (Markdown, TXT)。
文本清洗 (Text Cleaning): 去除噪声数据,提高文本质量:
去除 HTML 标签、XML 标签、Markdown 语法等标记语言的格式化符号。
去除特殊字符、乱码字符、URL、邮箱地址、电话号码等无关信息 (根据需求决定)。
去除重复内容 (文档去重、段落去重、句子去重)。
处理缩写、拼写错误、语法错误 (可选,根据需求和资源决定)。
结构化处理 (Structuring): 将非结构化文本转换为半结构化或结构化形式,方便后续分块和检索:
文档结构解析: 识别文档的标题、章节、段落、列表、表格等结构信息。 可以使用 NLP 工具 (SpaCy, NLTK) 或专门的文档解析库 (unstructured, Document AI)。
表格数据提取: 从文档中提取表格数据,转换为结构化表格 (例如 CSV, JSON)。
知识图谱构建 (可选): 从文档中抽取实体和关系,构建知识图谱 (如果需要支持基于知识图谱的检索)。
文本分块 (Text Chunking/Segmentation):
将文档分割成更小的文本块 (Chunks): 为了限制上下文长度,提高检索精度和生成效率,需要将长文档分割成更小的、语义相关的文本块。
分块策略选择: 根据文档类型、内容特点和 RAG 系统需求选择合适的分块策略:
固定大小分块 (Fixed-size Chunking): 按固定词语数量或字符数量分割,简单快速,但可能破坏语义完整性。
语义分块 (Semantic Chunking): 根据句子、段落、章节等语义单元分割,保持语义完整性,常用方法包括:
句子分割: 使用句子分割模型 (例如 SpaCy, NLTK 的句子分割器) 将文档分割成句子。
段落分割: 根据段落分隔符 (例如空行) 分割成段落。
章节分割: 根据章节标题分割成章节。
递归分块 (Recursive Chunking): 先按较大粒度 (如章节) 分割,再对每个大块递归地按较小粒度 (如段落、句子) 分割,保留文档层次结构。
重叠分块 (Overlapping Chunking): 相邻块之间存在一定的重叠部分,增加上下文连续性。
实体感知分块 (Entity-Aware Chunking): 围绕实体进行分块,确保实体及其相关上下文在同一块内。
根据文档类型定制分块策略: 例如代码文档按代码块分割,论文按章节或段落分割。
分块工具: 可以使用 Python NLP 库 (NLTK, SpaCy, Sentence Transformers), LangChain 等 RAG 框架提供的分块工具,或自定义分块脚本。
分块大小优化: 实验不同的分块大小,评估 RAG 系统性能,选择最佳分块大小。
嵌入生成 (Embedding Generation):
将文本块转换为向量表示 (Embeddings): 使用 Embedding 模型将每个文本块转换为高维向量,捕捉其语义信息。
选择合适的 Embedding 模型: 根据任务类型、数据特点和性能需求选择合适的 Embedding 模型:
Sentence Embeddings 模型 (Sentence-BERT, OpenAI Embeddings, Cohere Embeddings, Jina Embeddings 等): 现代 RAG 系统常用,擅长句子/段落级别语义表示。
词向量模型 (Word2Vec, GloVe, FastText): 轻量级,适用于资源受限场景,或作为基础组件。
领域特定 Embedding 模型: 针对特定领域数据微调或预训练的 Embedding 模型,提升领域任务精度。
多语言 Embedding 模型: 支持多语言的 Embedding 模型,用于多语言 RAG 系统。
Embedding 模型服务: 可以选择:
本地部署 Embedding 模型: 使用 Sentence-Transformers 库等在本地加载和运行开源模型。
云端 Embedding 服务 API: 使用 OpenAI Embeddings API, Cohere Embeddings API, Azure OpenAI Embeddings API 等云服务,方便快捷,性能通常更优,但需付费。
批量嵌入生成: 为了提高效率,通常采用批量处理的方式,一次性生成多个文本块的 Embedding 向量。
向量数据库索引构建与存储 (Vector Database Indexing & Storage):
选择向量数据库: 根据性能、规模、功能、成本、易用性等因素选择合适的向量数据库 (如 Pinecone, Weaviate, Milvus, Qdrant, Chroma 等)。 云端托管或自托管根据需求选择。
创建索引: 在向量数据库中创建索引,用于加速相似性搜索。 选择合适的索引类型 (HNSW, IVF, Flat 等) 和距离度量 (cosine, Euclidean, dot product) 。
存储向量和元数据: 将生成的文本块 Embedding 向量以及相关的元数据 (例如文档 ID, 块 ID, 原始文本内容等) 存储到向量数据库中。 元数据用于过滤和关联原始文本。
批量数据导入: 使用向量数据库提供的批量导入功能,高效地将大量向量数据导入到数据库中。
II. 在线查询与生成阶段 (Online Query & Generation/Inference Time):
这个阶段是当用户发起查询时,RAG 系统实时检索相关信息并生成答案的过程。
用户查询接收与处理 (User Query Reception & Processing):
接收用户查询: RAG 系统接收用户的自然语言查询 (例如通过 Web 界面, API 接口, 聊天机器人等)。
查询预处理 (Query Preprocessing): 对用户查询进行必要的预处理,例如:
文本清洗: 去除查询中的噪声字符、特殊符号等。
拼写检查和纠错 (可选): 纠正用户查询中的拼写错误。
查询改写 (Query Rewriting) (可选): 将用户查询改写为更适合检索系统的形式 (例如使用同义词、扩展关键词)。
查询向量化 (Query Vectorization/Embedding):
使用与离线索引阶段相同的 Embedding 模型: 将用户查询文本转换为向量表示,确保查询向量和文档向量在同一语义空间。
实时嵌入生成: 在线实时生成查询的 Embedding 向量。 通常需要低延迟的 Embedding 模型推理服务。
向量相似性搜索 (Vector Similarity Search/Retrieval):
在向量数据库中进行相似性搜索: 使用查询向量在向量数据库中执行相似性搜索,查找与查询向量最相似的 K 个文档块 (或向量)。 K 值 (检索结果数量) 通常需要根据应用场景和性能需求调整。
选择合适的相似性搜索算法: 向量数据库会根据索引类型选择高效的相似性搜索算法 (例如 HNSW 索引通常使用贪心搜索算法)。
元数据过滤 (Metadata Filtering) (可选): 在相似性搜索过程中,可以根据元数据进行过滤,例如只检索特定来源、特定时间范围或特定主题的文档块,提高检索精度。
上下文信息获取 (Context Information Retrieval):
从向量数据库获取检索到的文档块: 根据相似性搜索的结果,从向量数据库中获取检索到的最相关的文档块 (包括原始文本内容和元数据)。
上下文排序和选择 (Context Ranking & Selection) (可选): 对检索到的文档块进行排序和选择,例如根据相关性评分排序,或选择相关性评分最高的 Top N 个块。 也可以根据其他指标 (例如文档质量、信息密度) 进行排序和选择。
Prompt 构建 (Prompt Construction):
构建 Prompt 输入 LLM: 将用户查询和检索到的上下文信息组合成一个 Prompt,作为大型语言模型 (LLM) 的输入。 Prompt 的设计至关重要,直接影响 LLM 的生成效果。
Prompt 模板设计: 设计清晰、明确、有效的 Prompt 模板,引导 LLM 更好地利用上下文信息生成答案。 常见的 Prompt 结构包括:
1
"请根据以下上下文信息回答问题:\n\n上下文信息:\n[检索到的文档块 1]\n[检索到的文档块 2]\n...\n[检索到的文档块 K]\n\n问题:[用户查询]\n\n答案:"
content_copydownload
Use code with caution.
上下文窗口管理: 控制 Prompt 的总长度,避免超出 LLM 的上下文窗口限制。 可以采用截断、压缩、摘要等方法处理过长的上下文。
Prompt 工程技巧: 可以尝试 Few-shot Prompting (提供示例), Instruction Tuning (使用指令微调后的 LLM), Chain-of-Thought Prompting 等高级 Prompt 工程技巧,进一步优化生成效果。
LLM 推理与答案生成 (LLM Inference & Answer Generation):
调用 LLM API 进行推理: 将构建好的 Prompt 输入到预训练的 LLM (例如 OpenAI GPT-3.5 Turbo, GPT-4, Google PaLM 2, Meta Llama 2, Anthropic Claude 2 等) 的 API 接口,进行推理,生成答案文本。
LLM 参数配置: 根据需求配置 LLM 的生成参数,例如:
Temperature: 控制生成文本的随机性 (temperature 越高,随机性越高,temperature 越低,确定性越高)。
Top_p/Top_k: 控制采样策略,限制生成词语的范围。
Max Tokens: 限制生成答案的最大长度。
流式输出 (Streaming Output) (可选): 为了提高用户体验,可以使用 LLM 的流式输出功能,逐步返回生成结果,而不是等待整个答案生成完毕。
答案后处理与优化 (Answer Post-processing & Optimization):
答案抽取 (Answer Extraction) (可选): 从 LLM 生成的答案文本中抽取最核心、最相关的答案片段,去除冗余信息。
答案聚合 (Answer Aggregation) (可选): 如果从多个文档块中检索到相关信息,可以将 LLM 基于不同上下文生成的答案进行聚合,整合为一个更全面的答案。
答案润色与格式化 (Answer Refinement & Formatting) (可选): 对 LLM 生成的答案进行润色、语法纠错、格式化 (例如 Markdown 格式化, 列表格式化),提高答案的可读性和用户体验。
引用来源添加 (Citation/Source Linking) (可选): 在答案中添加对原始文档来源的引用链接或标注,提高答案的可信度和可追溯性。
事实性验证 (Fact Verification) (可选): 对 LLM 生成的答案进行事实性验证,检查答案是否与检索到的文档信息一致,避免幻觉问题。 可以使用事实性检测模型或知识图谱进行验证。
答案呈现与用户交互 (Answer Presentation & User Interaction):
将生成的答案呈现给用户: 将后处理后的答案文本呈现给用户 (例如在 Web 界面, 聊天机器人界面, API 返回结果中)。
用户反馈收集 (User Feedback Collection) (可选): 收集用户对答案的反馈 (例如点赞、踩、评价),用于后续 RAG 系统的迭代优化。
多轮对话管理 (Multi-turn Conversation Management) (可选): 如果 RAG 系统支持多轮对话,需要管理对话历史,维护对话状态,以便在后续对话中利用上下文信息。
向量嵌入
在向量数据库中,”嵌入 (Embeddings)” 是将各种类型的数据 (例如文本、图像、音频等) 转换成 高维向量 的过程。这些向量能够捕捉数据的语义信息或特征,使得计算机可以进行相似性比较和语义理解。 在 RAG (Retrieval-Augmented Generation) 系统中,嵌入技术至关重要,因为它允许我们将文档库中的文本内容转换为向量,并使用户的查询也转换为向量,然后在向量空间中进行相似性搜索,从而检索到最相关的上下文信息。
以下详细介绍几种常见的向量库嵌入类型,它们的不同之处以及各自的适用场景:
常见的向量库嵌入类型 (Embeddings for Vector Databases):
我们可以将向量库中常用的嵌入类型主要分为以下几类,并重点关注文本嵌入,因为在 RAG 应用中,文本数据是最常见的。
1. 文本嵌入 (Text Embeddings):
文本嵌入是将文本 (单词、句子、段落、文档) 转换为向量表示的技术,旨在捕捉文本的语义信息。
a) 基于词袋模型 (Bag-of-Words, BoW) 和 TF-IDF 的嵌入 (不太常用,但作为基础概念了解):
原理: BoW 模型统计词语在文档中出现的频率,忽略词序和语法。 TF-IDF (Term Frequency-Inverse Document Frequency) 在 BoW 的基础上,对词语频率进行加权,降低常见词语的权重,提高关键词的权重。
向量表示: 每个文档被表示为一个向量,向量的维度是词汇表的大小,每个维度的值是词语的频率或 TF-IDF 值。
优点: 简单易实现,计算速度快。
缺点: 丢失词序信息,无法捕捉语义关系,向量维度高且稀疏,效果有限,在现代 RAG 系统中已不常用。
适用场景: 早期的文本检索、文本分类任务,作为理解文本向量化概念的基础。
b) 基于词向量模型 (Word Embeddings) 的句子/文档嵌入 (Word2Vec, GloVe, FastText):
原理: Word2Vec (包括 CBOW 和 Skip-gram 模型)、GloVe (Global Vectors for Word Representation)、FastText 等模型通过神经网络训练,将每个词语映射到一个低维稠密向量空间,捕捉词语的语义信息和上下文关系。 要得到句子或文档嵌入,通常需要对词向量进行聚合 (例如平均池化、加权平均)。
向量表示:
词向量: 每个词语对应一个低维向量 (例如 100维、300维)。
句子/文档向量: 通过对句子/文档中的词向量进行平均池化或其他聚合操作得到。
优点: 捕捉词语语义信息,向量维度较低,计算效率较高。
缺点:
词向量模型本身是词级别的,句子/文档向量需要通过聚合得到,可能丢失句子/文档的整体语义信息。
Word2Vec 和 GloVe 无法很好地处理未登录词 (Out-of-Vocabulary, OOV) 问题。 FastText 通过词根信息部分缓解 OOV 问题。
对于复杂的句子或长文档,简单聚合词向量可能无法充分表达其语义。
适用场景: 早期的语义相似度计算、文本分类、信息检索任务,作为构建更复杂句子/文档嵌入模型的基础。 现在在 RAG 系统中,通常作为基础组件,或在资源受限的情况下使用 FastText 等轻量级模型。
c) 基于句子嵌入模型 (Sentence Embeddings) 的嵌入 (Sentence-BERT (SBERT), Universal Sentence Encoder (USE), OpenAI Embeddings, Cohere Embeddings, Jina Embeddings 等):
原理: Sentence Embeddings 模型专门设计用于生成句子或段落级别的语义向量表示。 Sentence-BERT (SBERT) 是基于 Transformer 架构微调得到的句子嵌入模型,通过 Siamese 或 triplet 网络结构和对比学习目标函数,优化句子向量的语义相似度表示能力。 Universal Sentence Encoder (USE) 是 Google 开源的句子嵌入模型,有基于 Transformer 和基于 DAN (Deep Averaging Network) 的版本。 OpenAI Embeddings (text-embedding-ada-002) 和 Cohere Embeddings 是商业公司提供的云端句子嵌入服务,通常基于强大的 Transformer 模型,并经过大规模数据训练和优化。 Jina Embeddings 是 Jina AI 提供的开源嵌入模型,也包含多种模型选择。
向量表示: 每个句子或段落直接被编码为一个低维稠密向量,向量维度通常在几百到几千维之间 (例如 SBERT 常用 768 维,OpenAI text-embedding-ada-002 为 1536 维)。
优点:
专门为句子/段落语义表示设计,能更好地捕捉句子/文档的整体语义信息。
通常基于 Transformer 等先进架构,性能强大。
Sentence-BERT 等开源模型易于使用和微调。 OpenAI Embeddings, Cohere Embeddings 等云服务易于集成和使用,且性能优秀。
缺点:
相比词向量模型,计算复杂度更高 (特别是基于 Transformer 的模型)。
对于非常长的文档,可能需要进行分块处理,再对块进行嵌入,或者使用专门处理长文本的模型 (如 Longformer, Transformer-XL 等)。
商业云服务 (OpenAI, Cohere) 需要付费,成本相对较高。
适用场景: 现代 RAG 系统中最常用的嵌入类型,适用于语义相似度搜索、文本聚类、文本分类、问答系统、信息检索等各种 NLP 任务。 Sentence-BERT 等开源模型适合本地部署和微调,OpenAI Embeddings, Cohere Embeddings 等云服务适合追求高性能和易用性的场景。
d) 领域特定嵌入 (Domain-Specific Embeddings):
原理: 在特定领域的数据集上训练或微调的嵌入模型,例如医学领域、法律领域、金融领域等。 可以使用 Sentence-BERT 等模型在领域数据上进行微调,或者使用领域预训练模型 (如果存在)。
向量表示: 与句子嵌入模型类似,但更侧重于领域数据的语义表示。
优点: 在特定领域任务上,语义表示能力更强,检索和 RAG 精度更高。
缺点: 通用性较差,只适用于特定领域。 需要领域数据集进行训练或微调,成本较高。
适用场景: 领域垂直的 RAG 系统,例如医学问答、法律咨询、金融信息检索等。 当通用嵌入模型在特定领域效果不佳时,可以考虑使用领域特定嵌入。
2. 图像嵌入 (Image Embeddings):
图像嵌入是将图像转换为向量表示的技术,捕捉图像的视觉特征和语义信息。 在多模态 RAG 系统中,可能需要对图像进行嵌入。
a) 基于卷积神经网络 (CNN) 的图像嵌入 (ResNet, EfficientNet, VGG, Inception 等):
原理: 使用预训练的 CNN 模型 (例如 ResNet, EfficientNet) 提取图像的特征图,然后通过全局平均池化 (Global Average Pooling, GAP) 或其他池化操作将特征图转换为固定长度的向量。
向量表示: 每个图像被表示为一个低维稠密向量,向量维度取决于 CNN 模型的输出维度 (例如 ResNet50 通常输出 2048 维向量)。
优点: 成熟的图像特征提取方法,性能良好,预训练模型丰富。
缺点: 主要捕捉图像的视觉特征,语义信息可能相对较弱 (相比多模态模型)。 对于语义理解要求高的任务,可能需要结合其他技术。
适用场景: 图像相似度搜索、图像分类、目标检测等计算机视觉任务。 在多模态 RAG 系统中,可以作为图像特征提取器,与其他模态的嵌入进行融合。
b) 基于视觉 Transformer (Vision Transformer, ViT) 的图像嵌入 (ViT, Swin Transformer 等):
原理: Vision Transformer (ViT) 将 Transformer 架构应用于图像处理,将图像分割成 Patch,作为序列输入 Transformer 进行处理,提取图像的全局和局部特征。 Swin Transformer 在 ViT 基础上引入滑动窗口注意力机制,进一步提升了图像任务的性能。
向量表示: 每个图像被表示为一个低维稠密向量,向量维度取决于 ViT 或 Swin Transformer 模型的配置。
优点: 在图像分类、目标检测、语义分割等任务上取得了优秀成果,能更好地捕捉图像的全局上下文信息。
缺点: 计算复杂度较高 (相比 CNN 模型)。 预训练模型相对 CNN 模型较少。
适用场景: 高性能图像识别、图像理解任务。 在多模态 RAG 系统中,可以作为图像特征提取器,尤其在需要捕捉图像全局语义信息的场景。
c) 基于多模态模型 (Multimodal Models) 的图像嵌入 (CLIP, ALIGN 等):
原理: CLIP (Contrastive Language-Image Pre-training) 和 ALIGN (Alignment Language-Image Network) 等多模态模型,通过对比学习方法,将图像和文本映射到同一个向量空间,使得语义相关的图像和文本的向量表示在向量空间中距离更近。
向量表示: 每个图像被表示为一个低维稠密向量,该向量与文本向量处于同一语义空间,可以直接进行图像-文本相似度计算。
优点: 同时捕捉图像的视觉特征和语义信息,并与文本语义空间对齐,非常适合跨模态检索和多模态 RAG 任务。 CLIP 模型尤其在零样本图像分类、图像-文本检索等任务上表现出色。
缺点: 模型结构相对复杂,训练数据和计算资源需求较高。
适用场景: 多模态 RAG 系统 (图像-文本 RAG),跨模态检索 (图像检索文本,文本检索图像),零样本图像分类等任务。 CLIP 模型是多模态 RAG 的常用选择。
3. 音频嵌入 (Audio Embeddings):
音频嵌入是将音频数据转换为向量表示的技术,捕捉音频的声学特征和语义信息。 在多模态 RAG 系统中,如果需要处理音频数据,则需要音频嵌入。
a) 基于声学特征的音频嵌入 (MFCC, Mel-spectrogram 等):
原理: 提取音频的声学特征,例如 MFCC (梅尔频率倒谱系数)、Mel-spectrogram (梅尔频谱图) 等,然后将这些特征转换为向量表示。
向量表示: 每个音频片段被表示为一个向量或向量序列,向量维度取决于声学特征的类型和参数设置。
优点: 传统的音频特征提取方法,计算效率较高,易于实现。
缺点: 主要捕捉音频的声学特征,语义信息可能相对较弱。 对于语义理解要求高的任务,可能需要结合更高级的模型。
适用场景: 音频分类、语音识别、音频相似度搜索等任务。 在多模态 RAG 系统中,可以作为音频特征提取器,与其他模态的嵌入进行融合。
b) 基于深度学习模型的音频嵌入 (VGGish, Wav2Vec2, HuBERT 等):
原理: 使用预训练的深度学习模型 (例如 VGGish, Wav2Vec2, HuBERT) 提取音频的特征表示。 Wav2Vec2 和 HuBERT 是基于 Transformer 架构的自监督学习模型,在语音识别等任务上取得了优秀成果。
向量表示: 每个音频片段被表示为一个低维稠密向量,向量维度取决于深度学习模型的输出维度。
优点: 能更好地捕捉音频的语义信息和上下文关系,尤其 Wav2Vec2 和 HuBERT 等自监督模型在语音识别等任务上性能强大。
缺点: 计算复杂度较高 (相比声学特征方法)。 预训练模型相对声学特征方法较少 (针对特定音频任务的模型较多)。
适用场景: 高性能语音识别、音频理解任务。 在多模态 RAG 系统中,可以作为音频特征提取器,尤其在需要捕捉音频语义信息的场景。
如何选择嵌入模型?
Sentence Embeddings 模型对比一览表
模型名称/类型 | 架构/方法 | 性能 (通用基准 MTEB)1 | 推理速度/延迟 | 向量维度 | 语言支持 | 训练数据/方法 | 易用性/部署 | 成本 (如适用) | 优点 | 缺点 | 适用场景/推荐 |
---|---|---|---|---|---|---|---|---|---|---|---|
Sentence-BERT (SBERT) 系列 | Transformer (BERT, RoBERTa, MPNet 等) 微调 | 高 (MTEB 排行榜前列) | 中等-较慢 | 768-1024 | 多语言 (部分模型) | 对预训练 Transformer 模型 (BERT, RoBERTa 等) 进行微调,使用 Siamese/Triplet 网络结构和对比学习目标函数,优化句子向量的语义相似度表示能力。 | Python 库 (Sentence-Transformers),易于使用,本地部署,支持微调 | 开源免费 | 高性能,句子语义表示能力强,模型选择丰富,开源免费,易于使用,支持微调,社区活跃 | 推理速度相对较慢 (Transformer),模型文件较大,部分模型多语言支持有限,需要一定的 Transformer 和 PyTorch 基础 | 现代 RAG 系统常用,语义相似度搜索,文本聚类,文本分类等各种 NLP 任务,需要高性能和开源可定制的场景,希望本地部署和微调 |
Universal Sentence Encoder (USE) | Transformer (USE-Transformer) / DAN (USE-DAN) | 中等-较高 | 中等 (Transformer), 较快 (DAN) | 512 (Transformer), 128 (DAN) | 多语言 | Google 开源,基于 Transformer (USE-Transformer) 和 Deep Averaging Network (USE-DAN) 两种架构,在大规模多语言文本数据上预训练,旨在提供通用的句子嵌入表示。 | Python 库 (TensorFlow Hub, Sentence-Transformers),易于使用,本地部署 (USE-DAN 轻量级易部署,USE-Transformer 部署相对复杂) | 开源免费 | 通用句子嵌入模型,多语言支持,USE-DAN 轻量级速度快,USE-Transformer 性能较好,TensorFlow Hub 和 Sentence-Transformers 库易于使用 | USE-Transformer 推理速度相对较慢,模型文件较大,USE-DAN 性能相对 USE-Transformer 稍逊,TensorFlow 生态系统相对 PyTorch 复杂,部分模型更新迭代相对较慢 | 通用场景 RAG,多语言 RAG,对速度有一定要求 (USE-DAN),希望使用 TensorFlow 生态系统的用户,作为通用句子嵌入基线模型 |
OpenAI Embeddings (text-embedding-ada-002) | 专有模型 (Transformer-based) | 顶尖 (MTEB 排行榜领先) | 极快 | 1536 | 多语言 | OpenAI 专有模型,基于强大的 Transformer 架构,在大规模高质量文本数据上训练,针对各种 NLP 任务进行优化,提供顶尖的句子嵌入性能。 | 云服务 API (OpenAI API),极其易于使用,通过简单的 API 调用即可获取嵌入 | 商业收费 (按 token 使用量) | 顶尖性能,极速推理速度,易于使用,云服务全托管,多语言支持,OpenAI 的品牌和技术背书,持续迭代更新 | 成本较高 (按 token 收费),依赖网络连接,数据隐私和安全需考虑,模型细节封闭,无法定制和微调,锁定 OpenAI 服务 | 高性能 RAG 系统首选,需要顶尖性能和易用性,对延迟极其敏感的应用,预算充足,可以接受云服务和数据传输,追求快速部署和零运维 |
Cohere Embeddings (cohere.embed) | 专有模型 (Transformer-based) | 高 (MTEB 排行榜前列) | 快 | 1024 | 多语言 | Cohere 专有模型,基于 Transformer 架构,在大规模文本数据上训练,提供高质量的句子嵌入表示,侧重于负责任的 AI 开发。 | 云服务 API (Cohere API),易于使用,提供多种模型尺寸选择 (small, medium, large) | 商业收费 (按 token 使用量) | 高性能,推理速度快,易于使用,云服务全托管,多语言支持,提供多种模型尺寸选择,Cohere 在数据隐私和安全方面有较好声誉 | 成本较高 (按 token 收费),依赖网络连接,数据隐私和安全需一定程度信任 Cohere,模型细节封闭,无法定制和微调,锁定 Cohere 服务,生态系统相对 OpenAI 稍小 | 高性能 RAG 系统,需要高性能和易用性,对延迟有一定要求,预算充足,对数据隐私和安全有一定关注,希望根据需求选择不同性能和成本模型 |
Jina Embeddings | 多种模型可选 (Transformer, 平均池化等) | 中等-较高 (取决于具体模型) | 较快-中等 (取决于具体模型) | 768 (例如 jina-embeddings-v2-base-en) | 多语言 (取决于具体模型) | Jina AI 提供,包含多种开源嵌入模型,基于 Transformer 和平均池化等架构,部分模型在特定任务上进行了优化,提供 Python 库和云服务 API 两种使用方式。 | Python 库 (Jina Embeddings),易于使用,本地部署,也提供云服务 API (JCloud AI Embeddings),选择灵活 | 开源免费 (Python 库),云服务 API 收费 (JCloud AI Embeddings) | 模型选择多样,开源 Python 库和云服务 API 可选,易于使用,社区支持,部分模型性能良好,针对多模态和跨模态检索有专门模型 | 云服务 API 稳定性可能不如 OpenAI/Cohere 成熟,开源模型的性能可能不如顶尖商业模型,生态系统和知名度相对 OpenAI/Cohere 稍小,模型性能和质量参差不齐,需要仔细选择模型 | 多用途 RAG 系统,需要多种模型选择,希望同时拥有开源和云服务选项,对成本敏感,或希望支持开源技术栈,可以根据具体模型选择适用于不同性能要求的场景,可以尝试多模态和跨模态 RAG 应用 |
E5 Embeddings (v2) | Transformer (Sentence-BERT 微调) | 高 (MTEB 排行榜前列) | 中等-较慢 | 768-1024 | 英文为主 (部分模型多语言) | 基于 Sentence-BERT 框架进行微调,针对检索任务进行了优化,使用了 Instruction Tuning 和 Query-Document 对比学习等技术,提升了检索任务的性能。 | Python 库 (Sentence-Transformers, FlagEmbedding),易于使用,本地部署,支持微调 | 开源免费 | 检索任务优化,高性能,句子语义表示能力强,开源免费,易于使用,支持微调,MTEB 检索任务 benchmark 表现突出,专门为 RAG 检索场景优化 | 推理速度相对较慢 (Transformer),模型文件较大,英文模型为主,多语言模型性能可能稍逊,需要一定的 Transformer 和 PyTorch 基础,模型系列较新,生态成熟度待观察 | 检索增强型 RAG 系统首选,高性能信息检索,问答系统,需要针对检索任务进行优化的场景,希望开源免费和本地部署,追求检索性能最大化 |
Instructor Embeddings | Transformer (Sentence-BERT 微调) | 高 (MTEB 排行榜前列) | 中等-较慢 | 768-1024 | 多语言 | 基于 Sentence-BERT 框架进行微调,使用了 Instruction Tuning 技术,通过指令 (instruction) 引导模型生成更符合任务需求的嵌入,提升了各种 NLP 任务的性能。 | Python 库 (Instructor-Embedding),易于使用,本地部署,支持指令定制 (instruction customization) | 开源免费 | 指令驱动嵌入,高性能,通用 NLP 任务性能优秀,开源免费,易于使用,支持指令定制,可以通过指令灵活控制模型行为,适用于各种 RAG 和 NLP 任务 | 推理速度相对较慢 (Transformer),模型文件较大,模型系列较新,生态成熟度待观察,需要理解 Instruction Tuning 的概念和使用方法 | 通用 RAG 和 NLP 任务,需要高性能和灵活控制模型行为,希望通过指令引导模型生成特定类型的嵌入,可以尝试指令定制功能,适用于各种复杂 NLP 任务,希望开源免费和本地部署 |
BGE Embeddings (BAAI General Embedding) | Transformer (BERT, RoBERTa 微调) | 高 (MTEB 排行榜前列) | 中等-较慢 | 768-1024 | 多语言 | 北京智源人工智能研究院 (BAAI) 发布,基于 Transformer 框架进行微调,使用了对比学习和多任务学习等技术,旨在提供通用的高质量嵌入模型,支持多种语言。 | Python 库 (FlagEmbedding),易于使用,本地部署,开源免费 | 开源免费 | 通用高性能,多语言支持,开源免费,易于使用,MTEB 排行榜表现优秀,北京智源出品,具有一定的技术背书,模型持续更新迭代 | 推理速度相对较慢 (Transformer),模型文件较大,模型系列相对较新,生态成熟度待观察,需要一定的 Transformer 和 PyTorch 基础,部分模型可能需要根据具体任务进行选择和调优 | 通用 RAG 和 NLP 任务,需要高性能和多语言支持,希望开源免费和本地部署,可以作为 Sentence-BERT, E5 Embeddings, Instructor Embeddings 等模型的替代方案,尝试不同模型的性能差异 |
另一种嵌入模型策略In-process (ONNX)
ONNX (Open Neural Network Exchange): ONNX 是一种开放标准,用于表示机器学习模型。 它的主要目的是 提高不同深度学习框架之间的互操作性。 您可以将使用 PyTorch、TensorFlow、 scikit-learn 等框架训练的模型导出为 ONNX 格式。 这样,您就可以使用 ONNX Runtime 这个高性能推理引擎来加载和运行这些 ONNX 模型,而无需依赖原始的训练框架。
In-process (进程内) 执行: “In-process” 指的是将 ONNX Runtime 引擎 集成到您的应用程序进程中,直接在应用程序的进程空间内加载和执行 ONNX 模型。 与 “Out-of-process” (进程外) 执行 (例如通过 gRPC 或 REST API 调用独立的模型服务进程) 相对。
如何理解 “In-process (ONNX)” 与 嵌入模型的关系?
ONNX 不是一种新的模型架构: ONNX 本身 不是一种新的嵌入模型架构,它只是一个 模型格式。 您可以将各种类型的嵌入模型 (例如 Sentence-BERT, E5 Embeddings, Instructor Embeddings 等) 导出为 ONNX 格式。
ONNX Runtime 是一个推理引擎: ONNX Runtime 是一个 跨平台的推理引擎,它可以 高效地执行 ONNX 格式的机器学习模型。 包括各种神经网络模型,当然也包括各种嵌入模型。
In-process (ONNX) 是一种部署选项: 使用 ONNX Runtime 进行 “In-process” 执行,是一种 将嵌入模型部署到您的应用程序中的方法。 这意味着:
性能提升: 进程内执行通常比进程外 API 调用 更快更高效,因为避免了进程间通信的开销。
简化部署: 将模型直接集成到应用程序中,简化了部署流程,无需单独部署模型服务。
资源控制: 您可以更 直接地控制资源分配和管理,因为模型运行在您的应用程序进程内。
离线能力: In-process 执行可以 支持离线推理 (如果您的应用程序需要离线运行)。
RAG 中常用的向量数据库 (Vector Databases for RAG):
RAG 中常用的向量数据库 (Vector Databases for RAG):
向量数据库专门设计用于存储和查询高维向量数据,并支持高效的相似性搜索,这正是 RAG 系统检索相关文档的关键能力。 以下是一些常用的向量数据库,可以根据部署方式和特点进行分类:
1. 云端托管向量数据库 (Cloud-Managed Vector Databases):
优点: 易于使用,无需管理基础设施,可扩展性好,通常提供完善的配套服务和支持。适合快速原型开发和生产环境。
缺点: 可能成本较高,受限于云服务商的功能和限制,数据安全性可能需要额外考虑 (取决于服务商的安全性)。
Pinecone: 非常流行的云端向量数据库,专注于高性能和低延迟的相似性搜索,易于集成,提供多种索引类型和过滤功能。适合需要快速响应和大规模数据的 RAG 应用。
Weaviate: 开源的云原生向量数据库,也提供托管服务。强调图数据库能力,可以构建知识图谱,支持复杂查询和语义搜索。适合需要更复杂数据结构和查询的 RAG 应用。
Milvus Cloud: 基于流行的开源 Milvus 向量数据库的云服务,提供高性能和高可扩展性,支持多种索引类型和距离度量。适合需要开源技术栈和高性能的 RAG 应用。
Azure Cognitive Search (with Vector Search): 微软 Azure 云提供的搜索服务,集成了向量搜索功能,可以方便地与其他 Azure 服务集成。适合已在使用 Azure 云平台的 RAG 应用。
AWS OpenSearch Service (with KNN): AWS 云提供的基于 Elasticsearch 的搜索服务,通过 KNN 插件支持向量搜索。适合已在使用 AWS 云平台的 RAG 应用。
Google Vertex AI Matching Engine: 谷歌云 Vertex AI 平台提供的向量相似性匹配服务,与谷歌云的其他 AI 服务集成良好。适合已在使用 Google Cloud 平台的 RAG 应用。
Zilliz Cloud (基于 Milvus): Zilliz 公司提供的 Milvus 云托管服务,专注于高性能和高可靠性,提供企业级支持。
2. 自托管向量数据库 (Self-Hosted Vector Databases):
优点: 完全控制数据和基础设施,可以根据自身需求定制和优化,长期来看可能更经济,适合对数据安全性和定制化要求高的场景。
缺点: 需要自行部署、维护和扩展,学习曲线较陡峭,需要一定的技术能力。
Faiss (Facebook AI Similarity Search): 由 Facebook AI 开发的开源库,专门用于高效的相似性搜索,性能强大,支持多种索引类型和距离度量。常用于构建自托管向量数据库的基础组件。
Milvus (开源): 开源的向量数据库,提供高性能、高可扩展性和易用性,支持多种索引类型和距离度量。社区活跃,文档完善。
Chroma: 开源的嵌入式向量数据库,轻量级,易于上手,适合小型项目和快速原型开发,也支持 Python 客户端。
Qdrant: 开源的向量搜索引擎,强调易用性和性能,提供 REST API 和客户端库,支持过滤和元数据操作。
ScaNN (Scalable Nearest Neighbor): 谷歌开源的向量相似性搜索库,专注于大规模数据集的高效搜索。
3. 其他选项 (Other Options):
- 基于传统数据库的向量扩展: 一些传统数据库 (如 PostgreSQL, MySQL) 通过扩展 (如 pgvector, vector-ai) 也开始提供向量存储和查询功能。 适合已在使用这些数据库,且向量搜索需求相对简单的场景。 但性能和扩展性可能不如专门的向量数据库。
如何选择向量数据库 (Choosing a Vector Database):
选择向量数据库需要根据 RAG 应用的具体需求和约束条件进行权衡:
性能和规模 (Performance and Scale):
数据规模: 预计需要存储多少向量数据? 数据库是否能支持未来的数据增长?
查询吞吐量和延迟: RAG 应用对查询响应时间有什么要求? 需要支持多少并发查询?
索引类型和算法: 数据库支持哪些索引类型 (如 HNSW, IVF)? 是否支持近似最近邻搜索 (ANN)? 不同的索引类型和算法在精度、速度和资源消耗之间有所权衡。
距离度量: 数据库支持哪些距离度量 (如 cosine, Euclidean, dot product)? 选择与你的 embedding 模型相匹配的距离度量。
功能和特性 (Features and Functionality):
过滤 (Filtering): 是否需要基于元数据进行过滤? 数据库是否提供灵活的过滤功能?
元数据管理 (Metadata Management): 数据库如何管理与向量关联的元数据? 是否方便进行元数据更新和查询?
更新和删除 (Updates and Deletions): 是否需要频繁更新或删除向量数据? 数据库的更新和删除性能如何?
多模态支持 (Multimodal Support): 如果 RAG 应用需要处理多模态数据 (如图像、音频),数据库是否支持多模态向量索引和查询?
集成和生态系统 (Integration and Ecosystem): 数据库是否提供方便的客户端库 (如 Python SDK)? 是否容易与其他 RAG 组件 (如 LLMs, embedding 模型) 集成?
部署和管理 (Deployment and Management):
云端托管 vs. 自托管: 选择云端托管可以简化部署和管理,但成本可能更高,控制权较少。 自托管需要更多技术投入,但更灵活和可控。
易用性 (Ease of Use): 数据库的文档是否完善? 是否易于学习和使用?
社区和支持 (Community and Support): 开源数据库的社区是否活跃? 商业数据库是否提供专业的技术支持?
成本 (Cost): 云端托管数据库通常按使用量收费,自托管数据库需要考虑硬件、运维等成本。
安全性 (Security):
数据加密: 数据库是否支持数据加密 (传输加密和静态加密)?
访问控制: 数据库是否提供完善的访问控制机制?
合规性: 如果 RAG 应用处理敏感数据,数据库是否满足相关的合规性要求 (如 GDPR, HIPAA)?
如何选择向量数据库?
存储库名称 | 类型 | 不同之处 | 优点 | 缺点 | 适用场景 | Storing Metadata (存储元数据) | Filtering by Metadata (基于元数据过滤) | Removing Embeddings (移除嵌入) |
---|---|---|---|---|---|---|---|---|
云端托管向量数据库 (Cloud-Managed Vector Databases) | ||||||||
Pinecone | 云端托管向量数据库 | 专注高性能,低延迟,云原生,全托管,多种索引,成熟 | 极致性能,极低延迟,高吞吐量,云原生易扩展,全托管,易用性极佳,成熟稳定,文档完善 | 成本较高,数据控制权部分依赖云服务商,定制化程度较低,锁定云服务商 | 高性能、低延迟、大规模 RAG 应用,企业级应用,实时推荐,在线广告检索,对性能和易用性有极高要求,预算充足,希望完全托管,无需运维 | 良好 - 核心功能,支持键值对元数据,与向量关联存储 | 优秀 - 高效灵活,支持基于元数据的精确和范围过滤,查询性能良好 | 良好 - 支持按 ID 或条件批量删除,操作相对简单高效 |
Weaviate Cloud | 云端托管向量数据库 (开源可选) | 开源可选,云托管方便,向量+图数据库,灵活数据模型,GraphQL | 开源可选,云托管方便,向量搜索+图数据库功能,GraphQL 查询灵活,数据模型灵活,可平衡性能和成本 | 云托管成本较高,性能相比 Pinecone 可能稍逊,学习曲线稍陡峭,大规模磁盘持久化模式下性能可能受限 | 需要结合知识图谱的复杂 RAG 应用,灵活数据模型和查询方式,希望同时具备开源和云托管选项,数据规模可大可小 | 优秀 - 核心功能,灵活的数据模型 (Schemas),元数据作为 Properties 与对象关联,支持丰富的数据类型 | 优秀 - GraphQL 查询语言强大,支持复杂的基于元数据的过滤和条件查询,图查询能力也支持元数据过滤 | 优秀 - 支持按 ID 或条件批量删除,GraphQL API 提供删除操作,支持数据生命周期管理 |
Milvus Cloud / Zilliz Cloud | 云端托管向量数据库 (基于 Milvus) | 基于开源 Milvus,高性能,高可扩展性,企业级支持 (Zilliz),多种索引,距离度量 | 高性能,高可扩展性,多种索引类型和距离度量,企业级支持 (Zilliz),基于成熟开源 Milvus,云托管降低运维成本,可控成本 (Milvus Cloud) | 云托管成本,数据安全性依赖云服务商,相比 Pinecone 生态系统可能稍弱,自托管 Milvus 运维复杂 | 需要高性能和高吞吐量的 RAG 应用,希望使用开源技术栈,有一定技术基础,追求性价比的用户,企业级大规模应用 (Zilliz Cloud) | 良好 - 支持字段 (Fields) 存储元数据,与向量数据一起管理 | 良好 - 支持基于字段的过滤,例如布尔表达式、范围查询等,查询性能较好 | 良好 - 支持按 ID 或条件批量删除,SDK 和 CLI 提供删除操作,数据删除效率较高 |
Azure Cognitive Search | 云端托管向量搜索服务 | Azure 云平台集成,向量+关键词混合搜索,成熟云服务,易管理 | 与 Azure 云平台深度集成,方便与其他 Azure 服务协同,成熟云服务,易于管理,向量+关键词混合搜索,Azure 云的企业级服务和安全保障 | 性能可能不如专门向量数据库,受限于 Azure 云平台,成本需评估,KNN 插件性能可能需调优,非纯向量数据库 | 已在使用 Azure 云平台,需要与 Azure 服务集成的 RAG 应用,需要向量+关键词混合搜索,希望利用 Azure 云平台成熟基础设施 | 良好 - 支持字段存储文档元数据,与向量索引一起管理,字段类型丰富 | 良好 - 支持基于字段的过滤,例如 facet 过滤、范围查询等,结合关键词搜索实现更精细的过滤 | 良好 - 支持按文档 ID 或条件批量删除,API 和 SDK 提供删除操作,数据删除与索引更新同步 |
AWS OpenSearch Service | 云端托管向量搜索服务 | AWS 云平台集成,向量+关键词混合搜索,成熟云服务,基于 Elasticsearch | 与 AWS 云平台深度集成,方便与其他 AWS 服务协同,成熟云服务,基于 Elasticsearch 强大搜索能力,向量+关键词混合搜索,AWS 云的广泛应用和生态系统 | 性能可能不如专门向量数据库,受限于 AWS 云平台,KNN 插件性能可能需评估,非纯向量数据库,Elasticsearch 资源消耗较高 | 已在使用 AWS 云平台,需要与 AWS 服务集成的 RAG 应用,需要向量+关键词混合搜索,希望利用 AWS 云平台成熟基础设施,熟悉 Elasticsearch | 良好 - Elasticsearch 强大的文档存储能力,支持丰富的字段类型和结构化元数据 | 优秀 - Elasticsearch 强大的查询 DSL,支持复杂的基于元数据的过滤和聚合,结合全文检索实现多维度过滤 | 良好 - 支持按文档 ID 或条件批量删除,REST API 提供删除操作,数据删除与索引更新异步 |
Vertex AI Matching Engine | 云端托管向量相似性匹配服务 | Google Cloud 平台集成,高性能匹配引擎,谷歌云基础设施强大 | 与 Google Cloud 平台深度集成,方便与 Google Cloud AI 服务协同,谷歌云基础设施强大,高性能相似性匹配,谷歌云的强大技术实力和生态系统 | 受限于 Google Cloud 平台,成本需评估,生态系统相对 Pinecone 可能稍弱,非纯向量数据库 | 已在使用 Google Cloud 平台,需要与 Google Cloud AI 服务集成的 RAG 应用,希望利用 Google Cloud 平台强大基础设施 | 良好 - 支持 attributes 存储元数据,与向量一起管理,元数据类型丰富 | 良好 - 支持基于 attributes 的过滤,例如布尔表达式、数值范围等,查询性能较好 | 良好 - 支持按 ID 或条件批量删除,API 提供删除操作,数据删除效率较高 |
自托管向量数据库 (Self-Hosted Vector Databases) | ||||||||
Milvus (开源) | 自托管向量数据库 | 开源免费,高性能,高可扩展性,多种索引,距离度量,灵活部署 | 开源免费,高性能,高可扩展性,多种索引类型和距离度量,社区活跃,文档完善,灵活的部署方式,可控成本 (硬件成本) | 需要自行部署和维护,运维成本和技术门槛较高,性能调优需要经验,大规模部署需要分布式架构知识 | 需要高性能和高吞吐量的 RAG 应用,希望使用开源技术栈,有技术团队进行运维,追求更高性价比,数据安全和控制权要求较高 | 良好 - 支持字段 (Fields) 存储元数据,与向量数据一起管理 | 良好 - 支持基于字段的过滤,例如布尔表达式、范围查询等,查询性能较好 | 良好 - 支持按 ID 或条件批量删除,SDK 和 CLI 提供删除操作,数据删除效率较高 |
Weaviate (开源) | 自托管向量数据库 (开源) | 开源免费,向量+图数据库,灵活数据模型,GraphQL,可配置持久化 | 开源免费,向量搜索+图数据库功能,GraphQL 查询灵活,数据模型灵活,可配置内存/磁盘混合存储,活跃社区,文档完善 | 性能相比 Milvus 或 Pinecone 可能稍逊,学习曲线稍陡峭,大规模磁盘持久化模式下性能可能受限,自托管运维成本 | 需要结合知识图谱的复杂 RAG 应用,灵活数据模型和查询方式,希望使用开源技术栈,有一定技术基础,希望平衡性能、功能和成本 | 优秀 - 核心功能,灵活的数据模型 (Schemas),元数据作为 Properties 与对象关联,支持丰富的数据类型 | 优秀 - GraphQL 查询语言强大,支持复杂的基于元数据的过滤和条件查询,图查询能力也支持元数据过滤 | 优秀 - 支持按 ID 或条件批量删除,GraphQL API 提供删除操作,支持数据生命周期管理 |
Qdrant | 自托管向量数据库 | 开源免费,易于使用,REST API,客户端库,元数据过滤 | 开源免费,易于使用,REST API 接口方便集成,客户端库友好,支持过滤和元数据操作,活跃社区,文档完善,快速上手 | 性能相比 Milvus 或 Pinecone 可能稍逊,扩展性可能不如云托管方案,大规模数据和高并发场景可能需集群部署,自托管运维成本 | 注重易用性和快速上手,需要 REST API 接口,希望快速构建原型或小型应用,数据规模适中,对性能有一定要求,希望快速验证 RAG 概念 | 良好 - 核心功能,支持 Payload 存储元数据,以 JSON 格式与向量关联 | 优秀 - 支持丰富的元数据过滤条件,例如精确匹配、范围查询、布尔表达式等,查询性能良好 | 良好 - 支持按 ID 或条件批量删除,REST API 和客户端库提供删除操作,数据删除效率较高 |
Chroma | 自托管嵌入式向量数据库 | 开源免费,嵌入式,轻量级,Python 友好,简单易用 | 开源免费,极其轻量级,嵌入式易于安装和使用,Python 客户端友好,简单易用,快速原型开发,本地部署方便 | 性能和扩展性有限,不适合大规模和高并发场景,功能相对简单,持久化依赖 SQLite,性能可能受限,不适合生产环境 | 小型 RAG 应用,个人项目,快速原型开发,数据量小,需要在本地快速搭建向量数据库,快速验证 RAG 流程,对性能和扩展性要求不高 | 良好 - 支持 metadata 参数存储元数据,以字典形式与向量关联 | 良好 - 支持基于 metadata 的过滤,例如精确匹配、范围查询,使用 Python 代码进行过滤条件定义 | 良好 - 支持按 ID 删除,Python API 提供删除操作,数据删除操作相对简单 |
Vald | 自托管分布式向量数据库 | 开源免费,分布式,高可扩展性,基于 NGT (Neighborhood Graph and Tree) 索引 | 开源免费,分布式架构,高可扩展性,基于 NGT 索引算法,高性能向量搜索,支持大规模数据集和高并发,可水平扩展 | 部署和运维相对复杂,NGT 索引构建时间较长,生态系统和社区规模相对较小,文档完善度可能不如 Milvus | 需要高性能、高可扩展性、分布式架构的 RAG 应用,大规模数据集,高并发查询,有技术团队进行运维,希望使用开源分布式向量数据库 | 良好 - 支持 object metadata 存储元数据,与向量数据一起管理 | 良好 - 支持基于 metadata 的过滤,例如精确匹配、范围查询,查询性能较好 | 良好 - 支持按 ID 或条件批量删除,gRPC API 提供删除操作,数据删除效率较高 |
Vespa | 自托管分布式搜索引擎 (向量+全文) | 开源免费,分布式搜索引擎,向量+全文混合搜索,功能强大,复杂查询 | 开源免费,分布式架构,高可扩展性,向量+全文混合搜索,功能强大,支持复杂查询和分析,成熟的搜索引擎技术,可构建复杂搜索应用 | 部署和运维极其复杂,学习曲线陡峭,资源消耗较高,配置和调优需要专业知识,不以纯向量搜索为核心优化目标 | 需要构建复杂搜索应用,向量+全文混合搜索,需要强大查询和分析能力,大规模数据,高并发查询,有专业运维团队和搜索引擎经验 | 优秀 - schema 定义灵活,支持结构化文档和丰富的字段类型,元数据管理能力强大 | 优秀 - 强大的查询语言 (YQL),支持极其复杂的基于元数据的过滤、排序、聚合和分析,结合全文检索实现多维度查询 | 优秀 - 支持按文档 ID 或条件批量删除,文档删除与索引更新异步高效,数据生命周期管理能力强大 |
向量扩展 (Vector Extensions for Databases) | ||||||||
pgvector (PostgreSQL) | 向量扩展 (PostgreSQL 插件) | PostgreSQL 扩展,易于集成,利用 PostgreSQL 功能,简单向量搜索 | 易于集成到 PostgreSQL 数据库,利用 PostgreSQL 成熟特性 (事务, 备份等),降低技术栈复杂度,快速集成 RAG 功能,成本较低 (利用现有 PostgreSQL 基础设施) | 性能和扩展性可能不如专门向量数据库,功能相对简单,受限于 PostgreSQL 性能瓶颈,不适合复杂 RAG 应用,大规模和高并发场景性能可能受限,非纯向量数据库 | 已在使用 PostgreSQL,向量搜索需求相对简单,希望快速集成 RAG 功能,数据量适中,利用现有 PostgreSQL 基础设施,降低技术栈复杂度 | 良好 - 利用 PostgreSQL 的表结构存储元数据,与向量列在同一张表中 | 良好 - 支持标准 SQL WHERE 子句进行元数据过滤,例如条件查询、范围查询等,利用 PostgreSQL 的索引优化查询性能 | 良好 - 支持标准 SQL DELETE 语句删除包含向量的行,数据删除与事务管理集成 |
vector-ai (MySQL) | 向量扩展 (MySQL 插件) | MySQL 插件,易于集成,利用 MySQL 功能,简单向量搜索 | 易于集成到 MySQL 数据库,利用 MySQL 广泛应用和成熟生态,快速集成 RAG 功能,成本较低 (利用现有 MySQL 基础设施) | 性能和扩展性可能不如专门向量数据库,功能相对简单,受限于 MySQL 性能瓶颈,不适合复杂 RAG 应用,大规模和高并发场景性能可能受限,非纯向量数据库 | 已在使用 MySQL,向量搜索需求相对简单,希望快速集成 RAG 功能,数据量适中,利用现有 MySQL 基础设施,降低技术栈复杂度 | 良好 - 利用 MySQL 表结构存储元数据,与向量列在同一张表中 | 良好 - 支持标准 SQL WHERE 子句进行元数据过滤,例如条件查询、范围查询等,利用 MySQL 的索引优化查询性能 | 良好 - 支持标准 SQL DELETE 语句删除包含向量的行,数据删除与事务管理集成 |
MongoDB Atlas Vector Search | 向量搜索 (MongoDB Atlas 云服务) | MongoDB Atlas 云服务,与 MongoDB 集成,向量搜索功能,NoSQL 数据库 | 与 MongoDB Atlas 深度集成,方便 MongoDB 用户使用,利用 MongoDB 的灵活性和可扩展性,云服务易于管理,NoSQL 数据库的灵活性 | 性能可能不如专门向量数据库,受限于 MongoDB Atlas 云平台,成本需评估,非纯向量数据库,向量搜索功能相对较新 | 已在使用 MongoDB Atlas,需要与 MongoDB 数据集成的 RAG 应用,希望利用 MongoDB Atlas 云服务,NoSQL 数据库用户 | 良好 - 利用 MongoDB 文档的灵活性存储元数据,键值对形式,schema-less | 良好 - 支持 MongoDB 查询语法进行元数据过滤,例如条件查询、嵌套文档查询等,利用 MongoDB 的索引优化查询性能 | 良好 - 支持 MongoDB 的文档删除操作删除包含向量的文档,数据删除与 MongoDB 的数据管理集成 |
内存存储 (In-Memory Solutions) | ||||||||
Redis (with Vector Modules) | 内存数据结构服务器 + 向量模块 | 见上表 | 见上表 | 见上表 | 见上表 | 基础 - 可以利用 Redis 的 Hash 数据结构存储元数据,与向量 Key 关联,但管理和查询相对简单 | 基础 - 可以基于 Hash 数据结构的字段进行简单过滤,例如 Get/Set 操作,但缺乏复杂的过滤查询能力 | 基础 - 支持按 Key 删除,Redis 的删除操作高效快速,但元数据和向量需要手动关联删除 |
内存数据结构 (In-Memory - e.g., Python dict, NumPy array) | 内存数据结构 | 见上表 | 见上表 | 见上表 | 见上表 | 非常基础 - 需要手动设计数据结构存储元数据,例如在 Python 字典中嵌套存储,管理和查询非常原始 | 非常基础 - 需要手动编写代码实现元数据过滤,例如遍历字典进行条件判断,效率极低,功能极其有限 | 非常基础 - 直接删除内存中的数据即可,操作简单,但数据丢失后无法恢复,无持久化 |
如何提升 RAG 精度 (Improving RAG Accuracy)
提高 RAG 精度是一个迭代优化的过程,涉及多个环节的改进:
数据准备和预处理 (Data Preparation and Preprocessing):
数据清洗: 去除噪声数据、重复数据、格式错误等,保证数据的质量。
数据增强: 对数据进行扩充或转换,增加数据的多样性,例如使用同义词替换、回译等方法。
文档结构化: 将非结构化文档转换为结构化或半结构化格式,例如将 PDF 文档转换为 Markdown 或 JSON 格式,方便后续处理和检索。
元数据添加: 为文档添加相关的元数据,例如文档来源、创建时间、关键词等,用于过滤和提升检索相关性。
文本分块策略优化 (Chunking Strategy Optimization):
固定大小分块: 简单易行,但可能破坏语义完整性。需要尝试不同的分块大小,找到最佳平衡点。
语义分块: 根据句子、段落或章节等语义单元进行分块,尽量保持语义完整性。可以使用 NLTK, SpaCy 等 NLP 工具进行句子分割或段落识别。
递归分块: 先将文档分成较大的块 (如章节),再将大块递归地分成更小的块 (如段落、句子),保留文档的层次结构。
重叠分块: 相邻块之间存在一定的重叠部分,增加上下文的连续性,减少信息丢失。
根据文档类型选择分块策略: 不同类型的文档 (如代码、论文、网页) 可能需要不同的分块策略。
Embedding 模型选择和优化 (Embedding Model Selection and Optimization):
选择合适的 Embedding 模型: 根据任务类型和数据特点选择合适的 Embedding 模型。 例如,sentence-transformers 库提供了多种预训练的 sentence embeddings 模型,可以根据不同的语言和任务进行选择。
微调 Embedding 模型: 如果预训练的 Embedding 模型在特定领域或数据集上效果不佳,可以考虑使用自己的数据微调 Embedding 模型,使其更适应特定任务。
使用领域特定的 Embedding 模型: 针对特定领域 (如医学、法律) 使用预训练或微调的领域特定 Embedding 模型,可以获得更好的语义表示效果。
检索策略优化 (Retrieval Strategy Optimization):
调整相似性搜索参数: 例如调整 k-NN 中的 k 值 (检索最近邻的数量),尝试不同的距离度量。
混合检索 (Hybrid Retrieval): 结合向量检索和关键词检索,利用关键词检索的精确性和向量检索的语义性,提高检索效果。例如,可以使用 Elasticsearch 或 OpenSearch 进行关键词检索,并结合向量数据库进行向量检索。
查询扩展 (Query Expansion): 对用户查询进行扩展,增加查询的覆盖面,例如使用同义词、相关词或知识图谱进行查询扩展。
多轮检索 (Multi-turn Retrieval): 在多轮对话场景中,考虑对话历史信息,进行上下文相关的检索。
排序和重排序 (Ranking and Re-ranking): 对检索结果进行排序或重排序,将更相关的文档排在前面。可以使用基于相关性评分、流行度、用户反馈等指标进行排序。 可以使用更复杂的模型 (如 Cross-Encoder) 对初始检索结果进行重排序,提升精度。
Prompt 工程 (Prompt Engineering):
设计清晰明确的 Prompt: Prompt 的质量直接影响 LLM 的生成效果。 设计清晰、具体、指令明确的 Prompt,引导 LLM 更好地利用检索到的上下文信息。
上下文窗口管理: 有效管理 LLM 的上下文窗口,避免上下文信息超出窗口限制。 可以采用截断、压缩、摘要等方法处理过长的上下文。
Few-shot Prompting: 在 Prompt 中提供少量示例,引导 LLM 学习如何根据上下文生成高质量的回答。
Instruction Tuning: 使用指令微调后的 LLM 通常在 RAG 任务中表现更好,因为它们更擅长理解和执行指令,并利用上下文信息生成答案。
后处理和结果优化 (Post-processing and Result Optimization):
答案抽取 (Answer Extraction): 从检索到的文档中抽取最相关的答案片段,而不是直接使用整个文档作为上下文。
答案聚合 (Answer Aggregation): 如果从多个文档中检索到相关信息,将这些信息聚合起来生成更全面的答案。
答案验证 (Answer Verification): 验证 LLM 生成的答案是否与检索到的文档一致,避免幻觉 (Hallucination) 问题。 可以使用事实性检测模型或知识图谱进行答案验证。
引用来源 (Citation): 在生成答案时,引用相关的文档来源,提高答案的可信度和可追溯性。
评估和迭代 (Evaluation and Iteration):
建立评估指标: 选择合适的评估指标来衡量 RAG 系统的精度,例如召回率 (Recall)、准确率 (Precision)、F1 值、NDCG (归一化折损累积增益) 等。
进行评估实验: 定期对 RAG 系统进行评估实验,分析系统的优点和不足,找出改进方向。
迭代优化: 根据评估结果,不断迭代优化 RAG 系统的各个环节,例如调整分块策略、优化 Embedding 模型、改进检索策略、优化 Prompt 等。
A/B 测试: 尝试不同的优化策略,进行 A/B 测试,比较不同策略的效果,选择最佳策略。
RAG 精度提升:
提升 RAG 精度是一个系统工程,需要从数据源头到最终结果的生成进行全链路优化。 我们可以将 RAG 流程分解为以下关键步骤,并针对每个步骤进行精度提升:
数据准备与预处理 (Data Preparation & Preprocessing): 高质量的知识库是 RAG 精度的基石。
文本分块策略优化 (Chunking Strategy Optimization): 合理的文本分块影响检索的上下文完整性和相关性。
Embedding 模型选择与优化 (Embedding Model Selection & Optimization): 强大的 Embedding 模型是语义检索的关键。
检索策略优化 (Retrieval Strategy Optimization): 高效的检索策略确保找到最相关的文档片段。
Prompt 工程优化 (Prompt Engineering Optimization): 精心设计的 Prompt 指导 LLM 更好地利用检索结果生成答案。
后处理与结果优化 (Post-processing & Result Optimization): 对 LLM 生成的答案进行优化和修正。
评估与迭代 (Evaluation & Iteration): 持续评估和迭代优化 RAG 系统。
以下详细展开每个环节的精度提升策略:
1. 数据准备与预处理 (Data Preparation & Preprocessing):
1.1 数据清洗 (Data Cleaning):
去除噪声数据: 识别并去除知识库中的噪声数据,例如:
无关信息: 与主题无关的文本、广告、导航栏等。
重复数据: 重复的段落、句子或文档。
格式错误: HTML 标签、乱码字符、不一致的格式等。
数据去重策略:
精确去重: 完全相同的文本块。
模糊去重: 使用文本相似度算法 (例如 SimHash, MinHash) 检测和去除相似度高的文本块。
工具: 可以使用正则表达式、专门的数据清洗工具库 (如 Beautiful Soup, Scrapy) 或自定义脚本进行数据清洗。
1.2 数据增强 (Data Augmentation):
扩充知识库多样性: 增加知识库中数据的多样性,提升模型的泛化能力。
数据增强方法:
同义词替换: 使用同义词词典或 WordNet 等工具替换文本中的词语。
回译 (Back Translation): 将文本翻译成另一种语言,再翻译回原始语言,生成语义相近但表达不同的文本。
随机插入/删除/替换词语: 在文本中随机插入、删除或替换词语,生成轻微扰动的文本。
上下文增强: 结合文档的上下文信息,例如文档标题、章节标题等,增强文档表示。
注意: 数据增强应适度,避免引入错误或改变原始语义。
1.3 文档结构化 (Document Structuring):
提升检索效率和相关性: 将非结构化文档转换为结构化或半结构化格式,方便后续处理和检索。
结构化方法:
Markdown 格式: 将文档转换为 Markdown 格式,保留标题、列表、代码块等结构信息。
JSON 格式: 将文档解析为 JSON 格式,例如将文档分解为章节、段落、句子等结构,并添加元数据。
表格化数据: 将表格数据提取并存储为结构化表格。
知识图谱构建: 从文档中抽取实体和关系,构建知识图谱,用于更复杂的语义检索。
工具: 可以使用 Pandoc, Mammoth 等工具进行文档格式转换,使用 NLP 工具 (如 SpaCy, NLTK) 进行结构化解析。
1.4 元数据添加 (Metadata Annotation):
辅助过滤和提升相关性: 为文档或文本块添加相关的元数据,用于过滤检索结果和提升相关性排序。
元数据类型:
文档来源: 例如网页 URL, 文档名称, 文件路径。
创建时间/更新时间: 文档的时间戳信息。
关键词/标签: 描述文档主题的关键词或标签。
作者/发布者: 文档的作者或发布者信息。
文档类型: 例如新闻报道, 技术文档, 博客文章。
领域/主题: 文档所属的领域或主题分类。
元数据获取方法: 可以从文档本身提取 (例如从 HTML 标签中提取元数据),也可以手动添加或使用外部知识库进行标注。
2. 文本分块策略优化 (Chunking Strategy Optimization):
2.1 分块大小选择 (Chunk Size Selection):
平衡上下文完整性和检索粒度: 分块大小直接影响检索的上下文完整性和检索粒度。
过大分块: 可能包含过多无关信息,降低检索精度,增加 LLM 处理上下文的负担。
过小分块: 可能丢失上下文信息,导致语义不完整,影响 LLM 理解。
最佳分块大小: 通常需要根据文档类型、任务类型和 Embedding 模型进行实验和调整。 常见的起始范围是 100-500 个词语。
实验方法: 尝试不同的分块大小 (例如 100, 200, 300, 400, 500 词语),评估 RAG 系统的精度,选择最佳分块大小。
2.2 分块策略类型 (Chunking Strategy Types):
固定大小分块 (Fixed-size Chunking):
简单易行: 将文档按固定词语数量或字符数量进行分块。
缺点: 可能破坏句子、段落或语义单元的完整性,导致上下文割裂。
语义分块 (Semantic Chunking):
保持语义完整性: 根据句子、段落或章节等语义单元进行分块。
句子分块: 使用句子分割工具 (例如 NLTK, SpaCy) 将文档分割成句子。
段落分块: 根据段落分隔符 (例如空行) 将文档分割成段落。
章节分块: 根据文档的章节标题将文档分割成章节。
优点: 更好地保持上下文语义完整性,提升检索相关性。
递归分块 (Recursive Chunking):
保留文档层次结构: 先将文档分成较大的块 (例如章节),再将大块递归地分成更小的块 (例如段落、句子)。
适用于结构化文档: 例如技术文档、书籍等,可以保留文档的章节、段落、句子等层次结构。
优点: 既能保持文档结构,又能提供不同粒度的上下文信息。
重叠分块 (Overlapping Chunking):
增加上下文连续性: 相邻块之间存在一定的重叠部分,例如重叠若干个句子或词语。
减少信息丢失: 避免因分块边界导致上下文信息丢失。
优点: 提升上下文的连贯性,尤其对于长文档或复杂语义的文档。
实体感知分块 (Entity-Aware Chunking):
围绕实体进行分块: 以实体为中心进行分块,确保实体及其相关上下文信息在同一个块中。
提升实体相关任务精度: 例如命名实体识别、关系抽取等任务。
方法: 可以使用 NER (命名实体识别) 模型识别文档中的实体,并根据实体位置进行分块。
根据文档类型选择分块策略: 不同类型的文档 (例如代码、论文、网页) 可能需要不同的分块策略。 代码文档可能更适合按代码块或函数进行分块,论文可能更适合按章节或段落进行分块。
2.3 分块工具选择 (Chunking Tool Selection):
Python NLP 库: NLTK, SpaCy, Sentence Transformers 等库提供句子分割、段落识别等功能。
专门的分块工具: 一些 RAG 框架或工具库 (如 LangChain) 提供了内置的分块工具,可以方便地实现不同的分块策略。
自定义分块脚本: 根据具体需求,可以编写自定义的分块脚本,实现更精细的分块控制。
3. Embedding 模型选择与优化 (Embedding Model Selection & Optimization):
3.1 Embedding 模型选择 (Embedding Model Selection):
Sentence Embedding 模型: 优先选择 Sentence Embedding 模型,例如 Sentence-BERT, OpenAI Embeddings, Cohere Embeddings 等。 这些模型专门用于生成句子或段落级别的语义向量表示。
模型类型:
通用 Embedding 模型: 在通用语料库上预训练的模型,适用于通用场景,例如 sentence-transformers/all-mpnet-base-v2。
领域特定 Embedding 模型: 在特定领域语料库上预训练或微调的模型,例如医学领域、法律领域等,适用于特定领域的 RAG 应用。 例如 sentence-transformers/allenai-specter (科学论文领域)。
多语言 Embedding 模型: 支持多种语言的 Embedding 模型,适用于多语言 RAG 应用。 例如 sentence-transformers/paraphrase-multilingual-mpnet-base-v2。
模型性能指标: 关注模型的语义表示能力、向量维度、推理速度、资源消耗等指标。 可以参考 Sentence Embedding 模型排行榜 (如 MTEB Leaderboard) 选择性能较好的模型。
模型服务: 可以选择本地部署的 Embedding 模型 (例如使用 Sentence-Transformers 库),也可以使用云端 Embedding 服务 (例如 OpenAI Embeddings API, Cohere Embeddings API)。
3.2 Embedding 模型微调 (Embedding Model Fine-tuning):
提升领域特定任务精度: 如果通用 Embedding 模型在特定领域或数据集上效果不佳,可以考虑使用自己的数据微调 Embedding 模型。
微调方法:
对比学习 (Contrastive Learning): 使用对比学习目标函数 (例如 InfoNCE Loss) 微调模型,使其更好地学习领域特定数据的语义表示。
监督学习 (Supervised Learning): 如果有领域特定的标注数据 (例如问答对、相关文档对),可以使用监督学习方法微调模型。
微调数据准备: 需要准备领域特定的数据集,例如领域相关的文档集、问答对、相似文档对等。
微调工具: 可以使用 Sentence-Transformers 库提供的微调工具,或者使用 PyTorch, TensorFlow 等深度学习框架自定义微调流程.
3.3 Embedding 模型参数优化 (Embedding Model Parameter Optimization):
向量维度选择: 向量维度影响模型的表示能力和计算效率。 高维度向量可以表达更丰富的语义信息,但计算和存储成本更高。 需要根据资源限制和性能需求选择合适的向量维度。
模型量化 (Model Quantization): 使用模型量化技术 (例如 int8 量化) 减小模型大小,加速推理速度,降低资源消耗。 可以使用 ONNX Runtime, TensorRT 等推理加速引擎进行模型量化。
3.4 多 Embedding 模型融合 (Multi-Embedding Model Fusion):
结合不同模型的优势: 可以使用多个 Embedding 模型,结合不同模型的优势,提升整体的语义表示能力。
融合方法:
向量拼接 (Vector Concatenation): 将不同模型的向量拼接在一起,形成一个更高维度的向量。
加权平均 (Weighted Averaging): 对不同模型的向量进行加权平均,根据模型性能或任务类型分配不同的权重。
模型集成 (Model Ensembling): 训练多个 Embedding 模型,并将它们的检索结果进行集成。
适用场景: 例如,可以使用通用 Embedding 模型和领域特定 Embedding 模型进行融合,提升通用性和领域特定任务的精度。
4. 检索策略优化 (Retrieval Strategy Optimization):
4.1 相似性搜索参数调整 (Similarity Search Parameter Tuning):
调整 k-NN 中的 k 值: k 值表示检索最近邻的数量。 较大的 k 值可以检索到更多相关的文档片段,但也会增加噪声,降低精度。 较小的 k 值可能检索结果太少,导致信息不完整。 需要根据任务类型和数据特点调整 k 值。
尝试不同的距离度量 (Distance Metric): 不同的距离度量 (例如 cosine similarity, Euclidean distance, dot product) 适用于不同的 Embedding 模型和数据分布。 需要根据 Embedding 模型和任务类型选择合适的距离度量。 Cosine similarity 常用于文本相似度计算。
实验方法: 尝试不同的 k 值和距离度量,评估 RAG 系统的精度,选择最佳参数组合。
4.2 混合检索 (Hybrid Retrieval):
结合向量检索和关键词检索: 利用关键词检索的精确性和向量检索的语义性,提高检索效果。
关键词检索: 使用传统的关键词索引和搜索技术 (例如 TF-IDF, BM25) 进行关键词检索。
向量检索: 使用向量数据库进行相似性搜索。
混合方法:
并行检索: 同时进行关键词检索和向量检索,并将结果合并。
级联检索: 先使用关键词检索进行粗略筛选,再使用向量检索对筛选结果进行精细排序。
加权融合: 根据关键词检索和向量检索的相关性评分,进行加权融合,生成最终的检索结果排序。
适用场景: 当用户查询既包含关键词信息,又包含语义信息时,混合检索可以更好地满足用户需求。
4.3 查询扩展 (Query Expansion):
增加查询的覆盖面: 对用户查询进行扩展,增加查询的覆盖面,检索更多相关的文档片段。
查询扩展方法:
同义词扩展: 使用同义词词典或 WordNet 等工具扩展查询中的词语。
相关词扩展: 使用词向量模型 (例如 Word2Vec, GloVe) 或语义网络扩展查询中的词语。
知识图谱扩展: 使用知识图谱扩展查询中的实体和关系。
查询改写: 使用查询改写模型 (例如基于 Transformer 的查询改写模型) 自动改写用户查询,使其更符合检索系统的输入要求。
注意: 查询扩展应适度,避免引入无关信息,降低检索精度。
4.4 多轮检索 (Multi-turn Retrieval):
考虑对话历史信息: 在多轮对话场景中,考虑对话历史信息,进行上下文相关的检索。
上下文融合方法:
拼接对话历史: 将当前用户查询和之前的对话历史拼接在一起,作为新的查询输入。
上下文向量表示: 使用对话历史编码器 (例如基于 RNN 或 Transformer 的对话历史编码器) 将对话历史编码成向量表示,并将其与当前查询的向量表示进行融合。
注意力机制: 使用注意力机制 (例如 Transformer 的自注意力机制) 建模当前查询和对话历史之间的关系,提升上下文相关的检索精度。
适用场景: 对话系统、聊天机器人等需要多轮对话交互的 RAG 应用。
4.5 排序和重排序 (Ranking and Re-ranking):
提升检索结果的排序质量: 对初始检索结果进行排序或重排序,将更相关的文档片段排在前面。
排序方法:
基于相关性评分排序: 根据向量数据库返回的相关性评分 (例如 cosine similarity) 进行排序。
基于流行度排序: 根据文档的流行度 (例如被引用次数、点击次数) 进行排序。
基于用户反馈排序: 根据用户对检索结果的反馈 (例如点击、点赞) 进行排序。
重排序模型 (Re-ranking Model): 使用更复杂的模型 (例如 Cross-Encoder 模型) 对初始检索结果进行重排序,提升精度。 Cross-Encoder 模型可以更精细地计算查询和文档片段之间的相关性,但计算成本较高。 可以使用 Sentence-Transformers 库提供的 Cross-Encoder 模型。
适用场景: 需要高精度检索结果排序的 RAG 应用,例如问答系统、搜索引擎等。
5. Prompt 工程优化 (Prompt Engineering Optimization):
5.1 设计清晰明确的 Prompt (Clear and Specific Prompt Design):
指令明确: Prompt 中明确指示 LLM 的任务和目标,例如 “请根据以下上下文回答问题”, “请总结以下文档”, “请从以下信息中提取关键信息”。
上下文引导: 在 Prompt 中明确告知 LLM 上下文信息的来源和格式,例如 “上下文信息如下:”, “请参考以下文档片段:”。
限制输出格式: 如果需要特定格式的输出 (例如 JSON 格式, 列表格式),在 Prompt 中明确指示输出格式。
避免歧义: Prompt 语言应简洁明了,避免歧义和模棱两可的表达。
示例 Prompt:
1
2
3
4请根据以下上下文信息回答问题:
上下文信息:[检索到的文档片段]
问题:[用户问题]
答案:content_copydownload
Use code with caution.
5.2 上下文窗口管理 (Context Window Management):
控制上下文长度: LLM 的上下文窗口长度有限制 (例如 GPT-3.5-turbo 的上下文窗口长度为 4096 tokens)。 需要控制 RAG 系统提供的上下文长度,避免超出 LLM 的上下文窗口限制。
上下文截断 (Context Truncation): 如果检索到的上下文信息过长,可以进行截断,只保留最相关的部分。 可以根据相关性评分或文档片段的重要性进行截断。
上下文压缩 (Context Compression): 使用上下文压缩技术 (例如摘要、信息抽取) 压缩上下文信息,减少上下文长度,同时尽量保留关键信息。
多文档检索与摘要 (Multi-document Retrieval and Summarization): 如果检索到多个相关文档,可以先对每个文档进行摘要,再将摘要信息作为上下文提供给 LLM。
分段式 Prompting (Segmented Prompting): 将长文档分成多个段落,分别生成 Prompt,分段输入 LLM,最后将结果整合。
5.3 Few-shot Prompting (Few-shot Prompting):
提供示例引导 LLM 学习: 在 Prompt 中提供少量示例 (输入-输出对),引导 LLM 学习如何根据上下文生成高质量的回答。
示例选择: 示例应与当前任务相关,并能有效展示期望的输出格式和内容。
示例数量: Few-shot Prompting 通常只需要少量示例 (例如 1-5 个示例)。
示例 Prompt:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15以下是一些问答示例:
示例 1:
上下文信息:[示例上下文1]
问题:[示例问题1]
答案:[示例答案1]
示例 2:
上下文信息:[示例上下文2]
问题:[示例问题2]
答案:[示例答案2]
现在请根据以下上下文信息回答问题:
上下文信息:[检索到的文档片段]
问题:[用户问题]
答案:content_copydownload
Use code with caution.
5.4 Instruction Tuning (Instruction Tuning):
使用指令微调后的 LLM: 使用在指令数据集上微调后的 LLM (例如 InstructGPT, ChatGPT) 通常在 RAG 任务中表现更好,因为它们更擅长理解和执行指令,并利用上下文信息生成答案。
Prompt 风格调整: 根据指令微调后的 LLM 的特点,调整 Prompt 的风格,例如更强调指令性、更简洁明了。
选择合适的 LLM: 根据任务类型和性能需求,选择合适的指令微调后的 LLM (例如 GPT-3.5-turbo-instruct, GPT-4)。
6. 后处理与结果优化 (Post-processing & Result Optimization):
6.1 答案抽取 (Answer Extraction):
从检索文档中抽取答案片段: 从检索到的文档中抽取最相关的答案片段,而不是直接使用整个文档作为上下文。
抽取方法:
关键词匹配: 在检索文档中查找与问题关键词相关的句子或段落。
阅读理解模型 (Reading Comprehension Model): 使用阅读理解模型 (例如 BERT-based QA 模型) 从检索文档中抽取答案片段。
启发式规则: 根据文档结构和语义信息,设计启发式规则抽取答案片段。
优点: 可以更精准地提取答案信息,减少 LLM 处理无关信息的负担,提高答案的准确性和简洁性。
6.2 答案聚合 (Answer Aggregation):
整合多个文档的信息: 如果从多个文档中检索到相关信息,将这些信息聚合起来生成更全面的答案。
聚合方法:
信息融合: 将多个文档的答案片段进行融合,去除冗余信息,整合相同或相似的信息。
排序和选择: 根据文档的相关性评分或答案片段的重要性,对答案片段进行排序和选择,只保留最重要和最相关的答案片段。
生成式摘要: 使用生成式摘要模型对多个文档的答案片段进行摘要,生成更简洁和流畅的答案。
适用场景: 需要综合多个信息源生成答案的 RAG 应用。
6.3 答案验证 (Answer Verification):
验证答案的事实性: 验证 LLM 生成的答案是否与检索到的文档一致,避免幻觉 (Hallucination) 问题。
验证方法:
事实性检测模型 (Factuality Detection Model): 使用事实性检测模型判断 LLM 生成的答案是否与上下文信息一致。
知识图谱验证: 使用知识图谱验证答案中涉及的实体和关系是否正确。
人工审核: 对 LLM 生成的答案进行人工审核,检查答案的事实性和准确性。
纠正策略: 如果答案验证失败,可以采取以下纠正策略:
重新检索: 调整检索策略,重新检索更相关的文档。
重新生成: 调整 Prompt 或 LLM 参数,重新生成答案。
拒绝回答: 如果无法生成可靠的答案,拒绝回答用户问题。
6.4 引用来源 (Citation):
提高答案可信度和可追溯性: 在生成答案时,引用相关的文档来源,让用户可以追溯答案的来源信息,提高答案的可信度和可追溯性。
引用格式: 可以使用脚注、尾注或内联引用的方式引用文档来源。
来源信息: 引用信息可以包括文档标题、URL, 文档 ID, 文档片段编号等。
7. 评估与迭代 (Evaluation & Iteration):
7.1 建立评估指标 (Evaluation Metric Establishment):
选择合适的评估指标: 根据 RAG 任务类型选择合适的评估指标,例如:
召回率 (Recall): 检索到的相关文档片段占所有相关文档片段的比例。
准确率 (Precision): 检索到的文档片段中相关文档片段的比例。
F1 值: 召回率和准确率的调和平均值。
NDCG (Normalized Discounted Cumulative Gain): 归一化折损累积增益,用于评估检索结果的排序质量。
答案相关性 (Answer Relevance): 评估 LLM 生成的答案与用户问题的相关程度。 可以使用人工评估或自动评估方法 (例如使用 ROUGE, BLEU 等指标)。
答案忠实度 (Answer Faithfulness/Factuality): 评估 LLM 生成的答案与检索到的文档信息的一致性。 可以使用事实性检测模型或人工评估。
答案完整性 (Answer Completeness): 评估 LLM 生成的答案是否充分回答了用户问题。
用户满意度 (User Satisfaction): 使用用户调查问卷或用户行为数据 (例如点击率、停留时间) 评估用户对 RAG 系统的满意度。
7.2 进行评估实验 (Evaluation Experimentation):
构建评估数据集: 准备包含用户问题、标准答案和相关文档片段的评估数据集。
自动化评估流程: 编写脚本或使用评估工具自动化 RAG 系统的评估流程。
对比实验: 对比不同 RAG 配置 (例如不同的分块策略、Embedding 模型、检索策略、Prompt 工程) 的性能,找出最佳配置。
消融实验: 分析不同优化策略对 RAG 精度提升的贡献度,例如分别评估数据清洗、分块策略优化、Embedding 模型优化等策略的效果。
错误分析: 分析 RAG 系统的错误案例,找出系统的不足之处,并针对性地进行改进。
7.3 迭代优化 (Iterative Optimization):
持续迭代优化 RAG 系统: RAG 精度提升是一个持续迭代优化的过程。 根据评估结果,不断调整和优化 RAG 系统的各个环节。
A/B 测试 (A/B Testing): 尝试不同的优化策略,进行 A/B 测试,比较不同策略的效果,选择最佳策略。
监控系统性能: 定期监控 RAG 系统的性能指标 (例如检索时间、答案生成时间、精度指标),及时发现和解决性能问题。
用户反馈收集: 收集用户对 RAG 系统的反馈意见,了解用户需求和痛点,并根据用户反馈进行改进。
- 本文作者: reiner
- 本文链接: https://reiner.host/posts/3943ac5e.html
- 版权声明: 转载请注明出处,并附上原文链接