概述

Chunking

  1. Documents 经过解析后,通过 Chunking 将信息内容划分为适当大小的 Chunks - 能够高效处理精准检索
  2. Chunk 的本质在于依据一定的逻辑语义原则,将长文本拆解为更小的单元
  3. Chunking 有多种策略,各有侧重,选择适合特定场景的 Chunking 策略,有助于提升 RAG 召回率

Embedding

  1. Embedding Model 负责将文本数据映射到高维向量空间,将输入的文档片段转换为对应的嵌入向量
  2. 嵌入向量捕捉了文本的语义信息,并存储到向量库中,以便于后续检索
  3. Query 同样通过 Embedding Model 的处理生成 Query 的嵌入向量,在向量库中通过向量检索匹配最相似的文档片段
  4. 根据不同的场景,评估并选择最优的 Embedding Model,以确保 RAG 的检索性能符合要求

image-20240902232040001

Chunking

影响

  1. Documents 包含丰富的上下文信息复杂的语义结构
    • 通过 Chunking,模型可以更有效地提取关键信息,并减少不相关内容的干扰
  2. Chunking 的目标
    • 确保每个片段在保留核心语义的同时,具备相对独立的语义完整性
    • 使得模型在处理时不必依赖广泛的上下文信息,增强检索召回准确性
  3. Chunking 直接影响 RAG 系统的生成质量
    • 能够确保检索到片段与 Query 高度匹配,避免信息冗余或者丢失
    • 有助于提升生成内容的连贯性,精心设计的独立语义片段可以降低模型对上下文的依赖
    • 影响系统的响应速度效率

尺寸

  1. Chunking 最大的挑战是确定 Chunk 大小
  2. Chunk 过大 - 可能导致向量无法精确捕捉内容的特定细节并且增加计算成本
  3. Chunk 过小 - 可能丢失上下文,导致句子碎片化语义不连贯
  4. 适合的场景
    • 小 Chunk - 需要细粒度分析的任务 - 情感分析
    • 大 Chunk - 需要保留更广泛上下文的场景 - 文档摘要 or 主题检测
  5. 取舍
    • Chunk 大小的确定必须在计算效率上下文之间取得平衡

策略

  1. 最佳的 Chunking 策略取决于具体的应用场景 - 业界无统一标准
  2. 选择最合适目标场景的 Chunking 策略,确保 RAG 系统中 LLM 能够更精确地处理和检索数据

Chunking 策略的组成

Part Desc
大小 每个 Chunk 所允许的最大字符数
重叠 在相邻 Chunk 之间,重叠字符的数量
拆分 通过段落边界分隔符标记语义边界来确定 Chunk 边界的位置

63b052c1b1639bfa66c23342cf28d9ef.jpg

https://chunkviz.up.railway.app/

Fixed Size

固定大小分块

概述

  1. 将文档按固定大小进行分块,作为 Chunking 策略的基准线

image-20240903001840753

场景

  1. 作为 Chunking 策略的基准线
  2. 大型数据集进行初步分析
  3. 实现简单 + 可预测性高,Chunk 便于管理
  4. 适用于格式大小相似的同质数据集 - 新闻 or 博客

问题

  1. 不考虑内容上下文,可能在句子或者段落中断内容,导致无意义的 Chunk
  2. 缺乏灵活性,无法适应文本自然结构

Overlap

重叠分块

概述

  1. 通过滑动窗口技术切分 Chunk,使新 Chunk 与前一个 Chunk 的内容部分重叠
  2. 保留 Chunk 边界处的重要上下文信息,增强系统的语义相关性
  3. 增加了存储需求和冗余信息,有效避免了 Chunk 之间丢失关键语义句法结构

image-20240903003257672

场景

  1. 需要深入理解语义保持完整上下文的文档 - 法律文档 / 技术手册 / 科研论文
  2. 提升 Chunk 的内容连贯性,以提高分析质量

问题

  1. 增加计算复杂度,降低处理效率
  2. 需要存储和管理冗余信息

Recursive

递归分块

概述

  1. 通过预定义的文本分隔符迭代地将文本分解为更小的 Chunk - 段大小的均匀性 + 语义的完整性
  2. 过程 - 按较大的逻辑单元分割,然后逐步递归较小的逻辑单元
  3. 确保在 Chunk 大小内,保留最强的语义片段

image-20240903005751718

场景

  1. 需要逐层分析的文档,或者需要分解成长片段、长段落的长文档 - 研究报告 / 法律文档

问题

  1. 可能在 Chunk 边界模糊语义,容易将完整的语义单元切分

Document Specific

文档特定分块

概述

  1. 根据文档格式(Markdown、Code 等)进行定制化分割
  2. 确保 Chunk 能够准确反映文档的特点 - 优化保留了完整语义的单元,提升后续处理和分析的效果

image-20240903010758462

场景

  1. 根据特定的文档结构,进行准确的语义内容切分

问题

  1. 依赖性强,不同格式之间的 Chunking 策略不通用
  2. 无法处理格式不规范混合多种格式的情况

Semantic

语义分块

概述

  1. 基于文本的自然语言边界(句子、段落等)进行分段
  2. 需要使用 NLP 技术根据语义分词分句,旨在确保每个 Chunk 都包含语义连贯的信息单元
  3. 保留了较高的上下文信息,并确保每个 Chunk 都包含连贯的信息,但需要更多的计算资源
  4. 常用 NLP 库
    • spaCy - 需要高效精准语义切分的大规模文本处理
    • NLTK - 适合教学研究和需要灵活自定义的语义切分任务

95687f417dyy2f92ab7c9ca374619acf.png

场景

  1. 确保每个 Chunk 的信息完整语义连贯
  2. 提高检索结果相关性准确性
  3. 适用于复杂文档上下文敏感精细化分析

问题

  1. 需要额外的高计算资源 - 动态或者大型的文档数据
  2. 降低处理效率

Mix

混合分块

概述

  1. 综合利用不同 Chunking 技术的优势,提高 Chunking 的精确性处理效率
  2. 初始阶段使用固定长度分块快速处理大量文档,在后续阶段使用语义分块进行更精细的分类和主题提取

场景

  1. 多层次精细化 Chunking 场景
  2. 数据集动态变化,包含多种格式和结构
  3. 平衡处理速度准确性的场景

问题

  1. 实现复杂度
  2. 调优难度高
  3. 增加资源消耗

实践

LangChain

langchain_text_splitters

Chunking LangChain Text Splitter
Fixed Size CharacterTextSplitter
Overlap CharacterTextSplitter
Recursive RecursiveCharacterTextSplitter
Document Specific MarkdownTextSplitter
PythonCodeTextSplitter
LatexTextSplitter
Semantic SpacyTextSplitter
NLTKTextSplitter

image-20240903014314872

Dependency

1
2
3
$ pip install spacy nltk
$ python -m spacy download zh_core_web_sm
$ python -m spacy download en_core_web_sm

TextSplitter

SpacyTextSplitter

1
2
3
4
5
6
7
8
9
# 配置SpacyTextSplitter分割文本块库
text_splitter = SpacyTextSplitter(
chunk_size=512, chunk_overlap=128, pipeline="zh_core_web_sm"
)

# 配置RecursiveCharacterTextSplitter分割文本块
# 可以更换为CharacterTextSplitter、MarkdownTextSplitter、PythonCodeTextSplitter、LatexTextSplitter、NLTKTextSplitter等
# text_splitter = RecursiveCharacterTextSplitter(
# chunk_size=512, chunk_overlap=128)

Embedding

概述

  1. 文本图像音频视频等形式的信息映射到高维空间中的密集向量表示
  2. 嵌入向量语义空间中起到坐标的作用,用于捕捉对象之间的语义关系隐含意义
  3. 通过在向量空间中进行计算(如余弦相似度),可以量化和衡量对象之间的语义相似性
  4. 嵌入向量每个维度通常对应文本的某种特征,通过多维度的数值表示,计算机能够理解解析文本的复杂语义结构
  5. 向量是一组在高维空间中定义点的数值数组,而嵌入是将信息转化为某种向量表示的过程
    • 嵌入向量能够捕捉数据的语义及其它重要特征
    • 使得语义相近的对象在向量空间中相距较近,而语义相异的对象则相距较远
  6. 向量检索
    • 通过计算 Query 向量Chunk 向量相似度来识别最相关的文本数据
    • 非常高效,能够在大规模数据集快速准确地找到与 Query 最相关的内容 - 向量蕴含丰富语义

image-20240903084318722

模型

  1. 早期 word2vecGloVefastText 等嵌入模型通过分析大量文本数据,学习得出单词的嵌入向量
  2. Transformer 后,Embedding 发展非常快
    • BERTRoBERTaELECTRA 等模型将 Embedding 推进到上下文敏感的阶段
    • 同一个单词不同语境下的嵌入向量不同的,提升了模型理解复杂语言结构的能力

RAG

  1. Embedding ModelChunksQuery 转换为 Vectors
  2. Vectors 捕捉了文本的语义信息,可以在向量空间中与其它嵌入向量进行比较

image-20240903085807853

评估

  1. 评估维度 - 特定领域、检索精度、支持语言、文本块长度、模型大小、检索效率
  2. 评估标准 - 涵盖分类聚类语义文本相似性重排序检索等多个数据集的评测
    • MTEB - Massive Text Embedding Benchmark
    • C-MTEB - Chinese Massive Text Embedding Benchmark
  3. 根据不同任务的需求,评估并选择最优的 Embedding Model,以获得在特定场景中的最佳性能

image-20240903091131548

https://huggingface.co/spaces/mteb/leaderboard
RAG 是检索任务,按照 Retrieval Average 倒排 - 需实际实验各种高得分的模型

image-20240903091617395

Metrics Desc
Retrieval Average 检索平均值
Model Size 模型大小(GB
模型越大,检索性能越好,但延迟也越大
Max Tokens 最大 Token 数,可压缩单个 Chunk 中的最大 Token 数,经验值 512
Embedding Dimensions 嵌入向量的维度
更少的嵌入维度提供更快的推理速度更高的存储效率
更多的维度可以捕获数据中的细微特征

实践

  1. SentenceTransformer 模块可以用于训练和推理 Embedding Model,可以在 RAG 系统中计算嵌入向量
  2. 支持的模型列表 - https://www.sbert.net/docs/sentence_transformer/pretrained_models.html
  3. 中文领域,BAAIBGE(BAAI General Embedding) 系列模型是比较知名的,在 C-MTEB 上表现出色

image-20240903095158210

加载 Embedding Model

1
2
3
4
5
# 绝对路径:SentenceTransformer读取绝对路径下的bge-small-zh-v1.5模型,如需使用其他模型,下载其他模型,并且更换绝对路径即可
embedding_model = SentenceTransformer(os.path.abspath('data/model/embedding/bge-large-zh-v1.5'))

# 自动下载:SentenceTransformer库自动下载BAAI/bge-large-zh-v1.5模型,如需下载其他模型,输入其他模型名称即可
# embedding_model = SentenceTransformer('BAAI/bge-large-zh-v1.5')

将 Chunks 转化为 Embeddings

1
2
3
4
5
# 文本块转化为嵌入向量列表,normalize_embeddings表示对嵌入向量进行归一化,用于准确计算相似度
embeddings = []
for chunk in all_chunks:
embedding = embedding_model.encode(chunk, normalize_embeddings=True)
embeddings.append(embedding)