diff --git a/README.md b/README.md index 8b3b78757b..460f17708b 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,13 @@ `category` 请从以下类别中选择 +- `RAG` - 语言模型(`LLM`) - 提示技术(`Prompt`) - 微调技术(`Finetune`) - 评估方法(`Eval`) - 数据集(`Dataset`) +- 推理方法(`Reasoning`) - `Token` 在 [src/zh/posts/${category}](https://github.com/HUSTAI/HUSTAI.github.io/tree/main/src/zh/posts/) 目录下增加一个新的 `md` 文件,参考[配置](https://theme-hope.vuejs.press/zh/config/frontmatter/info.html)来设置 `Frontmatter` diff --git a/src/.vuepress/sidebar/zh.ts b/src/.vuepress/sidebar/zh.ts index 34d669af3b..431c1f9890 100644 --- a/src/.vuepress/sidebar/zh.ts +++ b/src/.vuepress/sidebar/zh.ts @@ -8,11 +8,13 @@ export const zhSidebar = sidebar({ icon: "lightbulb", prefix: "posts/", children: [ + "rag/", "llm/", "prompt/", "finetune/", "eval/", "dataset/", + "reasoning/", "token/" ] // activeMatch: "^/zh/posts/", diff --git a/src/zh/README.md b/src/zh/README.md index 95262804ef..19634549ee 100644 --- a/src/zh/README.md +++ b/src/zh/README.md @@ -11,6 +11,10 @@ tagline: 分享知识-分享快乐 article: false projects: + - icon: circle-question + name: RAG + link: /zh/category/rag/ + - icon: circle-question name: 语言模型 link: /zh/category/语言模型/ @@ -31,6 +35,10 @@ projects: name: 数据集 link: /zh/category/数据集/ + - icon: puzzle-piece + name: 推理方法 + link: /zh/category/推理方法/ + - icon: puzzle-piece name: Token link: /zh/category/token/ diff --git a/src/zh/posts/README.md b/src/zh/posts/README.md index ab064a9788..9f4d10faec 100644 --- a/src/zh/posts/README.md +++ b/src/zh/posts/README.md @@ -9,9 +9,11 @@ article: false 本页面包含一些论文分享的分类: +- [RAG](./rag/) - [语言模型](./llm/) - [提示技术](./prompt/) - [微调技术](./finetune/) - [评估方法](./eval/) - [数据集](./dataset/) +- [推理方法](./reasoning/) - [Token](./token/) \ No newline at end of file diff --git a/src/zh/posts/dataset/README.md b/src/zh/posts/dataset/README.md index 4bbbe72a41..e9e344658a 100644 --- a/src/zh/posts/dataset/README.md +++ b/src/zh/posts/dataset/README.md @@ -8,5 +8,5 @@ category: tag: - Dataset dir: - order: 5 + order: 6 --- \ No newline at end of file diff --git a/src/zh/posts/eval/README.md b/src/zh/posts/eval/README.md index 493d5f7c6b..e024a09cf8 100644 --- a/src/zh/posts/eval/README.md +++ b/src/zh/posts/eval/README.md @@ -8,5 +8,5 @@ category: tag: - Eval dir: - order: 4 + order: 5 --- \ No newline at end of file diff --git a/src/zh/posts/finetune/README.md b/src/zh/posts/finetune/README.md index b9fccdca09..575a84ecc6 100644 --- a/src/zh/posts/finetune/README.md +++ b/src/zh/posts/finetune/README.md @@ -8,5 +8,5 @@ category: tag: - Finetune dir: - order: 3 + order: 4 --- \ No newline at end of file diff --git a/src/zh/posts/llm/README.md b/src/zh/posts/llm/README.md index a13b3d3896..2645094ef0 100644 --- a/src/zh/posts/llm/README.md +++ b/src/zh/posts/llm/README.md @@ -8,5 +8,5 @@ category: tag: - LLM dir: - order: 1 + order: 2 --- \ No newline at end of file diff --git a/src/zh/posts/prompt/README.md b/src/zh/posts/prompt/README.md index 905239e9cb..0f90bb1fb3 100644 --- a/src/zh/posts/prompt/README.md +++ b/src/zh/posts/prompt/README.md @@ -8,5 +8,5 @@ category: tag: - Prompt dir: - order: 2 + order: 3 --- \ No newline at end of file diff --git a/src/zh/posts/llm/Chunking-Strategies.md b/src/zh/posts/rag/Chunking-Strategies.md similarity index 98% rename from src/zh/posts/llm/Chunking-Strategies.md rename to src/zh/posts/rag/Chunking-Strategies.md index 1900f60994..cbb348b53f 100644 --- a/src/zh/posts/llm/Chunking-Strategies.md +++ b/src/zh/posts/rag/Chunking-Strategies.md @@ -1,158 +1,159 @@ ---- -author: 研究生鱼皮-yjf -icon: pen-to-square -date: 2023-09-04 -category: - - 语言模型 -tag: - - 检索 -# sticky: 10 ---- - -# 大语言模型应用中的文本分块策略 - -这篇博文讨论了在构建与大语言模型(LLM)相关的应用中使用的文本分块策略。分块是将大段文本分解为较小段的过程,它对于优化向量数据库返回内容相关性至关重要。 - - - -文章来源:https://www.pinecone.io/learn/chunking-strategies/ - -## 1 介绍 - -在构建与LLM相关的应用时,**分块(chunking)** 是将大段文本分解为较小段的过程。当我们使用LLM嵌入内容时,chunking是一项帮助优化向量数据库返回内容相关性的基本技术。在这篇博文中,我们将探讨它是否以及如何帮助提高LLM相关应用的效率和准确性。 - -往向量数据库中索引的任何内容都需要首先向量化(称为嵌入,embedding)。分块的主要原因是确保我们向量化的内容的噪音尽可能少,并且具有语义相关性。 - -例如,在语义搜索(semantic search)中,我们索引文档语料库。每个文档都包含有关特定主题的有价值的信息。通过应用有效的分块策略,可以确保搜索结果准确捕获用户查询的本质。区块太小或太大,可能会导致搜索结果不精确或错失显示相关内容的机会。**根据经验,如果文本块在没有周围上下文的情况下对人类有意义,那么它对语言模型也有意义。** 因此,为语料库中的文档找到最佳区块大小对于确保搜索结果准确且相关至关重要。 - -另一个例子是会话代理(conversational agents)。我们使用向量化的块来构建基于知识库的会话代理的**上下文**,该知识库使代理基于**受信任**的信息。在这种情况下,对分块策略做出正确的选择很重要,原因有两个:首先,它将确定上下文是否真正与我们的提示(prompt)相关。其次,它将确定是否能够在将检索到的文本发送到外部模型提供者(例如OpenAI)之前将其放入上下文中,因为我们可以为每个请求发送的token数量受到限制。在某些情况下,例如将 GPT-4 与 32k 上下文窗口一起使用时,拟合区块可能不是问题。尽管如此,使用非常大的块可能会对从向量数据库返回的结果的相关性产生不利影响。 - -我们将探讨几种分块方法,并讨论在选择分块大小和方法时应考虑的权衡。最后,我们将提供一些建议,以确定适合您的应用的最佳区块大小和方法。 - -## 2 嵌入短内容和长内容 - -当我们嵌入内容时,我们可以根据内容是短(如句子)还是长(如段落或整个文档)来预测不同的行为。 - -当嵌入**句子**时,生成的向量侧重于句子的特定含义。与其他句子嵌入相比,比较自然会在该级别上进行。这也意味着嵌入可能会错过段落或文档中更广泛的上下文信息。 - -嵌入**整个段落或文档**时,嵌入过程会考虑整体上下文以及文本中句子和短语之间的关系。这可以产生更全面的矢量表示,从而捕获文本的更广泛含义和主题。另一方面,较大的输入文本大小可能会引入干扰或稀释单个句子或短语的重要性,从而在查询索引时更难找到精确匹配项。 - -查询的长度也会影响嵌入之间的相互关系。较短的查询(例如单个句子或短语)将专注于细节,并且可能更适合与句子级嵌入进行匹配。跨越多个句子或段落的较长查询可能更符合段落或文档级别的嵌入,因为它可能正在寻找更广泛的上下文或主题。 - -索引也可能是非同类的,并且包含不同大小的块的嵌入。这可能会在查询结果相关性方面带来挑战,但也可能会产生一些积极的后果。一方面,由于长内容和短内容的语义表示之间存在差异,查询结果的相关性可能会波动。另一方面,非同构索引可能会捕获更广泛的上下文和信息,因为不同的块大小表示文本中的不同粒度级别。这可以更灵活地适应不同类型的查询。 - -## 3 chunking注意事项 - -几个变量在确定最佳分块策略方面发挥作用,这些变量因用例而异。以下是需要牢记的一些关键方面: - -1. **被索引的内容的性质是什么?** 您是处理较长的文档(如文章或书籍)还是较短的内容(如推文或即时消息)?答案将决定哪种模型更适合您的目标,从而决定应用哪种分块策略。 - -2. **您使用的是哪种嵌入模型,它在哪些块大小上表现最佳?** 例如,[sentence-transformer](https://huggingface.co/sentence-transformers)模型在单个句子上效果很好,但像[text-embedding-ada-002](https://openai.com/blog/new-and-improved-embedding-model)这样的模型在包含 256 或 512 个token的块上表现更好。 - -3. **您对用户查询的长度和复杂性有何期望?** 它们是简短而具体的还是冗长而复杂的?这也可能会告知您选择对内容进行分块的方式,以便嵌入式查询和嵌入式区块之间有更紧密的相关性。 - -4. **检索到的结果将如何在您的特定应用程序中使用?** 例如,它们是否用于语义搜索、问答、摘要或其他目的?例如,如果你的结果需要被输入到另一个具有令牌限制的LLM,你必须考虑到这一点,并根据你想要适应LLM请求的块数来限制块的大小。 - -回答这些问题将允许您开发平衡性能和准确性的分块策略,这反过来又将确保查询结果更具相关性。 - -## 4 分块方法 -有不同的分块方法,每种方法可能适用于不同的情况。通过检查每种方法的优点和缺点,我们的目标是确定应用它们的正确方案。 - -### 4.1 固定大小的分块 -这是最常见和最直接的分块方法:我们只需决定块中的代币数量,以及它们之间是否应该有任何重叠。通常,我们希望在块之间保持一些重叠,以确保语义上下文不会在块之间丢失。在大多数常见情况下,固定大小的分块将是最佳路径。与其他形式的分块相比,固定大小的分块在计算上便宜且易于使用,因为它不需要使用任何 NLP 库。 - -下面是使用 [LangChain](https://api.python.langchain.com/en/latest/api_reference.html) 执行固定大小的分块的示例: - -```Python -text = "..." # your text -from langchain.text_splitter import CharacterTextSplitter -text_splitter = CharacterTextSplitter( - separator = "\n\n", - chunk_size = 256, - chunk_overlap = 20 -) -docs = text_splitter.create_documents([text]) -``` - -### 4.2 “内容感知”(Content-aware)分块 -这些是一组方法,用于利用我们正在分块的内容的性质并对其应用更复杂的分块。以下是一些示例: - -#### 4.2.1 句子切分 -正如我们之前提到的,许多模型都针对嵌入句子级内容进行了优化。当然,我们会使用句子分块,并且有几种方法和工具可用于执行此操作,包括: - -- **朴素切分**:最简单的方法是按句点(“.”)和换行符切分句子。虽然这可能既快速又简单,但这种方法不会考虑所有可能的边缘情况。下面是一个非常简单的示例: - -```Python -text = "..." # your text -docs = text.split(".") -``` - -- **[NLTK](https://www.nltk.org/)**:自然语言工具包(NLTK)是一个流行的Python库,用于处理人类语言数据。它提供了一个句子分词器,可以将文本切分为句子,帮助创建更有意义的块。例如,要将NLTK与LangChain一起使用,您可以执行以下操作: -```Python -text = "..." # your text -from langchain.text_splitter import NLTKTextSplitter -text_splitter = NLTKTextSplitter() -docs = text_splitter.split_text(text) -``` - -- **[spaCy](https://spacy.io/)**:spaCy是另一个强大的Python库,用于NLP任务。它提供了复杂的分句功能,可以有效地将文本划分为单独的句子,从而在生成的块中更好地保留上下文。例如,要将spaCy与LangChain一起使用,您可以执行以下操作: -```Python -text = "..." # your text -from langchain.text_splitter import SpacyTextSplitter -text_splitter = SpaCyTextSplitter() -docs = text_splitter.split_text(text) -``` - -#### 4.2.2 递归分块 -递归分块使用一组分隔符以分层和迭代方式将输入文本划分为较小的块。如果拆分文本的初始尝试未生成所需大小或结构的块,则该方法会使用不同的分隔符或条件递归调用生成的块,直到达到所需的块大小或结构。这意味着,虽然块的大小不会完全相同,但它们仍然追求具有相似的大小。 - -下面是如何在 LangChain 中使用递归分块的示例: -```Python -text = "..." # your text -from langchain.text_splitter import RecursiveCharacterTextSplitter -text_splitter = RecursiveCharacterTextSplitter( - # Set a really small chunk size, just to show. - chunk_size = 256, - chunk_overlap = 20 -) - -docs = text_splitter.create_documents([text]) -``` - -#### 4.2.3 专用分块 - -Markdown和LaTeX是您可能会遇到的结构化和格式化内容的两个例子。在这些情况下,您可以使用专门的分块方法在分块过程中保留内容的原始结构。 - -- **[Markdown](https://www.markdownguide.org/)**:Markdown 是一种轻量级标记语言,通常用于格式化文本。通过识别 Markdown 语法(例如,标题、列表和代码块),您可以根据内容的结构和层次结构智能地划分内容,从而产生语义上更一致的块。例如: -```Python -from langchain.text_splitter import MarkdownTextSplitter -markdown_text = "..." - -markdown_splitter = MarkdownTextSplitter(chunk_size=100, chunk_overlap=0) -docs = markdown_splitter.create_documents([markdown_text]) - -``` - -- **[LaTex](https://www.latex-project.org/)**:LaTeX是一种文档准备系统和标记语言,通常用于学术论文和技术文档。通过解析 LaTeX 命令和环境,您可以创建尊重内容逻辑组织(例如,部分、子部分和公式)的块,从而获得更准确和上下文相关的结果。例如: - -```Python -from langchain.text_splitter import LatexTextSplitter -latex_text = "..." -latex_splitter = LatexTextSplitter(chunk_size=100, chunk_overlap=0) -docs = latex_splitter.create_documents([latex_text]) -``` - -## 5 确定应用的最佳块大小 -以下是一些指导意见,可帮助您在常见的分块方法(如固定分块)不容易应用于您的应用场景时提出最佳块大小。 - -- **预处理数据** - 在确定应用的最佳区块大小之前,需要先预处理数据以确保质量。例如,如果您的数据是从网络上抓取的,则可能需要移除具有干扰作用的 HTML标记或特定元素。 - -- **选择一组区块大小** - 预处理数据后,下一步是选择要测试的潜在区块大小范围。如前所述,选择应考虑内容的性质(例如,短消息或长文档)、您将使用的embedding模型及其功能(例如,token限制)。目标是在保留上下文和保持准确性之间找到平衡。首先探索各种块大小,包括用于捕获更精细语义信息的较小块(例如,128或256个token)和用于保留更多上下文的较大块(例如,512或1024个token)。 - -- **评估每个区块大小的性能** - 为了测试各种区块大小,您可以使用多个索引或具有多个[命名空间](https://docs.pinecone.io/docs/namespaces)的单个索引。使用代表性数据集,为要测试的区块大小创建嵌入向量,并将其保存在索引(或多个索引)中。然后,可以运行一系列查询,以便评估质量,并比较各种区块大小的性能。这很可能是一个迭代过程,您可以在其中针对不同的查询测试不同的区块大小,直到您可以确定内容和预期查询的最佳性能区块大小。 - -## 6 总结 -在大多数情况下,对内容进行分块非常简单。但是当您开始徘徊在人迹罕至的地方时,它可能会带来一些挑战。文本分块没有一刀切的解决方案,因此适用于一个场景的方法可能不适用于另一个场景。希望这篇文章能帮助你更好地了解如何为您的应用进行文本分块。 - - - +--- +author: 研究生鱼皮-yjf +icon: pen-to-square +date: 2023-09-04 +category: + - rag +tag: + - 检索 + - rag +# sticky: 10 +--- + +# 大语言模型应用中的文本分块策略 + +这篇博文讨论了在构建与大语言模型(LLM)相关的应用中使用的文本分块策略。分块是将大段文本分解为较小段的过程,它对于优化向量数据库返回内容相关性至关重要。 + + + +文章来源:https://www.pinecone.io/learn/chunking-strategies/ + +## 1 介绍 + +在构建与LLM相关的应用时,**分块(chunking)** 是将大段文本分解为较小段的过程。当我们使用LLM嵌入内容时,chunking是一项帮助优化向量数据库返回内容相关性的基本技术。在这篇博文中,我们将探讨它是否以及如何帮助提高LLM相关应用的效率和准确性。 + +往向量数据库中索引的任何内容都需要首先向量化(称为嵌入,embedding)。分块的主要原因是确保我们向量化的内容的噪音尽可能少,并且具有语义相关性。 + +例如,在语义搜索(semantic search)中,我们索引文档语料库。每个文档都包含有关特定主题的有价值的信息。通过应用有效的分块策略,可以确保搜索结果准确捕获用户查询的本质。区块太小或太大,可能会导致搜索结果不精确或错失显示相关内容的机会。**根据经验,如果文本块在没有周围上下文的情况下对人类有意义,那么它对语言模型也有意义。** 因此,为语料库中的文档找到最佳区块大小对于确保搜索结果准确且相关至关重要。 + +另一个例子是会话代理(conversational agents)。我们使用向量化的块来构建基于知识库的会话代理的**上下文**,该知识库使代理基于**受信任**的信息。在这种情况下,对分块策略做出正确的选择很重要,原因有两个:首先,它将确定上下文是否真正与我们的提示(prompt)相关。其次,它将确定是否能够在将检索到的文本发送到外部模型提供者(例如OpenAI)之前将其放入上下文中,因为我们可以为每个请求发送的token数量受到限制。在某些情况下,例如将 GPT-4 与 32k 上下文窗口一起使用时,拟合区块可能不是问题。尽管如此,使用非常大的块可能会对从向量数据库返回的结果的相关性产生不利影响。 + +我们将探讨几种分块方法,并讨论在选择分块大小和方法时应考虑的权衡。最后,我们将提供一些建议,以确定适合您的应用的最佳区块大小和方法。 + +## 2 嵌入短内容和长内容 + +当我们嵌入内容时,我们可以根据内容是短(如句子)还是长(如段落或整个文档)来预测不同的行为。 + +当嵌入**句子**时,生成的向量侧重于句子的特定含义。与其他句子嵌入相比,比较自然会在该级别上进行。这也意味着嵌入可能会错过段落或文档中更广泛的上下文信息。 + +嵌入**整个段落或文档**时,嵌入过程会考虑整体上下文以及文本中句子和短语之间的关系。这可以产生更全面的矢量表示,从而捕获文本的更广泛含义和主题。另一方面,较大的输入文本大小可能会引入干扰或稀释单个句子或短语的重要性,从而在查询索引时更难找到精确匹配项。 + +查询的长度也会影响嵌入之间的相互关系。较短的查询(例如单个句子或短语)将专注于细节,并且可能更适合与句子级嵌入进行匹配。跨越多个句子或段落的较长查询可能更符合段落或文档级别的嵌入,因为它可能正在寻找更广泛的上下文或主题。 + +索引也可能是非同类的,并且包含不同大小的块的嵌入。这可能会在查询结果相关性方面带来挑战,但也可能会产生一些积极的后果。一方面,由于长内容和短内容的语义表示之间存在差异,查询结果的相关性可能会波动。另一方面,非同构索引可能会捕获更广泛的上下文和信息,因为不同的块大小表示文本中的不同粒度级别。这可以更灵活地适应不同类型的查询。 + +## 3 chunking注意事项 + +几个变量在确定最佳分块策略方面发挥作用,这些变量因用例而异。以下是需要牢记的一些关键方面: + +1. **被索引的内容的性质是什么?** 您是处理较长的文档(如文章或书籍)还是较短的内容(如推文或即时消息)?答案将决定哪种模型更适合您的目标,从而决定应用哪种分块策略。 + +2. **您使用的是哪种嵌入模型,它在哪些块大小上表现最佳?** 例如,[sentence-transformer](https://huggingface.co/sentence-transformers)模型在单个句子上效果很好,但像[text-embedding-ada-002](https://openai.com/blog/new-and-improved-embedding-model)这样的模型在包含 256 或 512 个token的块上表现更好。 + +3. **您对用户查询的长度和复杂性有何期望?** 它们是简短而具体的还是冗长而复杂的?这也可能会告知您选择对内容进行分块的方式,以便嵌入式查询和嵌入式区块之间有更紧密的相关性。 + +4. **检索到的结果将如何在您的特定应用程序中使用?** 例如,它们是否用于语义搜索、问答、摘要或其他目的?例如,如果你的结果需要被输入到另一个具有令牌限制的LLM,你必须考虑到这一点,并根据你想要适应LLM请求的块数来限制块的大小。 + +回答这些问题将允许您开发平衡性能和准确性的分块策略,这反过来又将确保查询结果更具相关性。 + +## 4 分块方法 +有不同的分块方法,每种方法可能适用于不同的情况。通过检查每种方法的优点和缺点,我们的目标是确定应用它们的正确方案。 + +### 4.1 固定大小的分块 +这是最常见和最直接的分块方法:我们只需决定块中的代币数量,以及它们之间是否应该有任何重叠。通常,我们希望在块之间保持一些重叠,以确保语义上下文不会在块之间丢失。在大多数常见情况下,固定大小的分块将是最佳路径。与其他形式的分块相比,固定大小的分块在计算上便宜且易于使用,因为它不需要使用任何 NLP 库。 + +下面是使用 [LangChain](https://api.python.langchain.com/en/latest/api_reference.html) 执行固定大小的分块的示例: + +```Python +text = "..." # your text +from langchain.text_splitter import CharacterTextSplitter +text_splitter = CharacterTextSplitter( + separator = "\n\n", + chunk_size = 256, + chunk_overlap = 20 +) +docs = text_splitter.create_documents([text]) +``` + +### 4.2 “内容感知”(Content-aware)分块 +这些是一组方法,用于利用我们正在分块的内容的性质并对其应用更复杂的分块。以下是一些示例: + +#### 4.2.1 句子切分 +正如我们之前提到的,许多模型都针对嵌入句子级内容进行了优化。当然,我们会使用句子分块,并且有几种方法和工具可用于执行此操作,包括: + +- **朴素切分**:最简单的方法是按句点(“.”)和换行符切分句子。虽然这可能既快速又简单,但这种方法不会考虑所有可能的边缘情况。下面是一个非常简单的示例: + +```Python +text = "..." # your text +docs = text.split(".") +``` + +- **[NLTK](https://www.nltk.org/)**:自然语言工具包(NLTK)是一个流行的Python库,用于处理人类语言数据。它提供了一个句子分词器,可以将文本切分为句子,帮助创建更有意义的块。例如,要将NLTK与LangChain一起使用,您可以执行以下操作: +```Python +text = "..." # your text +from langchain.text_splitter import NLTKTextSplitter +text_splitter = NLTKTextSplitter() +docs = text_splitter.split_text(text) +``` + +- **[spaCy](https://spacy.io/)**:spaCy是另一个强大的Python库,用于NLP任务。它提供了复杂的分句功能,可以有效地将文本划分为单独的句子,从而在生成的块中更好地保留上下文。例如,要将spaCy与LangChain一起使用,您可以执行以下操作: +```Python +text = "..." # your text +from langchain.text_splitter import SpacyTextSplitter +text_splitter = SpaCyTextSplitter() +docs = text_splitter.split_text(text) +``` + +#### 4.2.2 递归分块 +递归分块使用一组分隔符以分层和迭代方式将输入文本划分为较小的块。如果拆分文本的初始尝试未生成所需大小或结构的块,则该方法会使用不同的分隔符或条件递归调用生成的块,直到达到所需的块大小或结构。这意味着,虽然块的大小不会完全相同,但它们仍然追求具有相似的大小。 + +下面是如何在 LangChain 中使用递归分块的示例: +```Python +text = "..." # your text +from langchain.text_splitter import RecursiveCharacterTextSplitter +text_splitter = RecursiveCharacterTextSplitter( + # Set a really small chunk size, just to show. + chunk_size = 256, + chunk_overlap = 20 +) + +docs = text_splitter.create_documents([text]) +``` + +#### 4.2.3 专用分块 + +Markdown和LaTeX是您可能会遇到的结构化和格式化内容的两个例子。在这些情况下,您可以使用专门的分块方法在分块过程中保留内容的原始结构。 + +- **[Markdown](https://www.markdownguide.org/)**:Markdown 是一种轻量级标记语言,通常用于格式化文本。通过识别 Markdown 语法(例如,标题、列表和代码块),您可以根据内容的结构和层次结构智能地划分内容,从而产生语义上更一致的块。例如: +```Python +from langchain.text_splitter import MarkdownTextSplitter +markdown_text = "..." + +markdown_splitter = MarkdownTextSplitter(chunk_size=100, chunk_overlap=0) +docs = markdown_splitter.create_documents([markdown_text]) + +``` + +- **[LaTex](https://www.latex-project.org/)**:LaTeX是一种文档准备系统和标记语言,通常用于学术论文和技术文档。通过解析 LaTeX 命令和环境,您可以创建尊重内容逻辑组织(例如,部分、子部分和公式)的块,从而获得更准确和上下文相关的结果。例如: + +```Python +from langchain.text_splitter import LatexTextSplitter +latex_text = "..." +latex_splitter = LatexTextSplitter(chunk_size=100, chunk_overlap=0) +docs = latex_splitter.create_documents([latex_text]) +``` + +## 5 确定应用的最佳块大小 +以下是一些指导意见,可帮助您在常见的分块方法(如固定分块)不容易应用于您的应用场景时提出最佳块大小。 + +- **预处理数据** - 在确定应用的最佳区块大小之前,需要先预处理数据以确保质量。例如,如果您的数据是从网络上抓取的,则可能需要移除具有干扰作用的 HTML标记或特定元素。 + +- **选择一组区块大小** - 预处理数据后,下一步是选择要测试的潜在区块大小范围。如前所述,选择应考虑内容的性质(例如,短消息或长文档)、您将使用的embedding模型及其功能(例如,token限制)。目标是在保留上下文和保持准确性之间找到平衡。首先探索各种块大小,包括用于捕获更精细语义信息的较小块(例如,128或256个token)和用于保留更多上下文的较大块(例如,512或1024个token)。 + +- **评估每个区块大小的性能** - 为了测试各种区块大小,您可以使用多个索引或具有多个[命名空间](https://docs.pinecone.io/docs/namespaces)的单个索引。使用代表性数据集,为要测试的区块大小创建嵌入向量,并将其保存在索引(或多个索引)中。然后,可以运行一系列查询,以便评估质量,并比较各种区块大小的性能。这很可能是一个迭代过程,您可以在其中针对不同的查询测试不同的区块大小,直到您可以确定内容和预期查询的最佳性能区块大小。 + +## 6 总结 +在大多数情况下,对内容进行分块非常简单。但是当您开始徘徊在人迹罕至的地方时,它可能会带来一些挑战。文本分块没有一刀切的解决方案,因此适用于一个场景的方法可能不适用于另一个场景。希望这篇文章能帮助你更好地了解如何为您的应用进行文本分块。 + + + diff --git a/src/zh/posts/token/LLMretrieval.md b/src/zh/posts/rag/LLMretrieval.md similarity index 99% rename from src/zh/posts/token/LLMretrieval.md rename to src/zh/posts/rag/LLMretrieval.md index d659f8ed80..0c54d1af3f 100644 --- a/src/zh/posts/token/LLMretrieval.md +++ b/src/zh/posts/rag/LLMretrieval.md @@ -4,10 +4,11 @@ icon: clipboard-list date: 2023-09-07 shortTitle: "大模型外挂知识库优化" category: - - Token + - rag tag: - LLM - 检索 + - rag --- # 如何通过大模型实现外挂知识库优化 diff --git a/src/zh/posts/llm/LSR.md b/src/zh/posts/rag/LSR.md similarity index 99% rename from src/zh/posts/llm/LSR.md rename to src/zh/posts/rag/LSR.md index 88727efe88..9ad7b22816 100644 --- a/src/zh/posts/llm/LSR.md +++ b/src/zh/posts/rag/LSR.md @@ -1,112 +1,113 @@ ---- -author: 研究生鱼皮-yjf -icon: pen-to-square -date: 2023-08-23 -category: - - 语言模型 -tag: - - 检索 -# sticky: 10 ---- - -# 学习稀疏检索的统一框架 - -学习稀疏检索是一种结合机器学习和信息检索的方法,旨在优化文本检索效果。通过学习模型,将查询和文档映射到稀疏表示空间,实现高效的检索。在训练阶段,利用已标记的查询-文档对和相关性标签,通过优化模型参数,学习如何选择、加权和组合特征,使相关文档在稀疏表示中更接近查询。学习稀疏检索方法可应用于大规模信息检索任务,如搜索引擎和推荐系统,以提高检索效率和准确性。 - - - -## 1 背景和目的 - -自然语言查询的文本检索是信息检索(IR)系统的核心任务。之前的研究采用了两阶段的流程来解决这个问题,首先通过快速的检索器从文档集合中检索出一组初始文档,然后由更复杂的模型进一步重新排名。对于第一阶段的检索,神经网络的密集表示在语义匹配方面具有很大的潜力,在许多自然语言处理任务中超越了稀疏方法,但在强调长文档检索和精确匹配的情况下不一定成立。此外,对于极大规模(例如100亿)的候选文档集合,密集方法不得不在效率与准确性之间权衡。传统的基于术语的稀疏表示,也称为词袋(BoW),如TF-IDF和BM25,可以有效地进行字面匹配,因此在工业级IR系统中扮演着核心角色。然而,传统的基于术语的方法通常被认为表示能力不足,不适用于语义级匹配。 - -学习稀疏检索最早由Zamani等人在论文《From Neural Re-Ranking to Neural Ranking: Learning a Sparse Representation for Inverted Indexing》中提出。SNRM(Standalone Neural Ranking Model)是一种独立的神经排序模型,旨在解决神经排序模型在效率方面的问题。它通过引入稀疏属性,为每个查询和文档学习潜在的稀疏表示。其中“潜在”Token在反向索引过程中扮演传统术语的角色。关于SNRM的一个挑战是它失去了原始术语的可解释性,这对于工业系统至关重要。 - -该论文研究了学习稀疏检索(LSR)方法,这是一类用于生成查询和文档稀疏词汇表示的首阶段检索方法,用于倒排索引。虽然有许多LSR方法已被引入,其中Splade模型在MSMarco数据集上取得了最先进的性能,但不同的实验设置和配置难以进行有效的比较和洞察。在这项工作中,作者分析了现有的LSR方法,识别出关键组成部分,并建立了一个统一的LSR框架,将所有LSR方法放置在一个统一的视角下。然后,作者重新实现了所有重要的方法,并在相同环境中重新训练,以便量化不同框架组成部分如何影响效果和效率。研究发现:(1)文档词项加权对方法的效果最具影响,(2)查询加权略有正面影响,(3)文档扩展和查询扩展效果相互抵消。因此,作者提出了如何从最先进的模型中移除查询扩展,以显著降低延迟,同时在MSMarco和TripClick数据集上保持性能。该工作旨在提供一种统一的LSR框架,深入分析了不同组成部分对效果和效率的影响,并为LSR方法的进一步优化提供了指导。 - -## 2 统一框架的建立 - -学习稀疏检索 (LSR) 使用查询编码器 $f_Q$和$f_D$文档编码器 将查询和文档投影到词汇大小的稀疏向量: $w_q=f_Q(q)=w_q^1,w_q^2,\dots ,w_q^{|V|}$和$w_d=f_D(d)=w_d^1,w_d^2,\dots ,w_d^{|V|}$。 查询与文档之间的分数是其对应向量之间的点积:$sim(q,d) = \sum _{i=1}^{|V|}w_q^iw_d^i$。 该公式与 BM25 等传统稀疏检索方法密切相关; 事实上,BM25 可以表述为: - -$$\begin{aligned} \text {BM25}(q,d)&= \sum _{i=1}^{|q|} \text {IDF}(q_i) \times \frac{tf(q_i, d) \times (k_1 + 1)}{tf(q_i, d) + k_1 \cdot \left( 1 - b + b \cdot \frac{|d|}{\text {avgdl}}\right) } \\&= \sum _{j=1}^{|V|} \underbrace{ \mathbb {1}_{q(v_j)} \text {IDF}(v_j)}_{\text {query encoder}} \times \underbrace{\mathbb {1}_{d(v_j)} \frac{tf(v_j, d) \times (k_1 + 1)}{tf(v_j, d) + k_1 \cdot \left( 1 - b + b \cdot \frac{|d|}{\text {avgdl}}\right) }}_{\text {doc encoder}} \\&= \sum _{j=1}^{|V|} f_Q(q)_j \times f_D(d)_j \\ \end{aligned}$$ - -使用 BM25,IDF 和 TF 分量可以被视为查询/文档术语权重。 LSR 的不同之处在于使用神经模型(通常是 Transformer)来预测术语权重。 LSR 与稀疏检索的许多技术兼容,例如倒排索引和附带的查询处理算法。 然而,LSR 权重的差异可能意味着现有的查询处理优化变得不太有用,从而激发新的优化。 - -在本节中,我们介绍一个由三个组件(稀疏编码器、稀疏正则化器、监督)组成的概念框架,它捕获了我们观察到的现有学习稀疏检索方法之间的关键差异。 随后,我们描述了文献中的 LSR 方法如何适应这个框架。 - -稀疏(词法)编码器是学习稀疏检索方法的主要组成部分,用于将查询和段落编码为相同维度的权重向量。与密集编码器相比,稀疏编码器具有三个主要特征。首先,稀疏编码器生成稀疏向量,其中大多数权重为零,这由稀疏正则化器控制。其次,稀疏权重向量的维度通常与词汇表中的术语数量相对应,而密集编码器生成较小的压缩向量,没有明确的术语与维度对应关系。第三,稀疏编码器只产生非负权重,因为稀疏检索方法依赖于传统词汇搜索的堆栈,其中权重始终是非负的术语频率。 - -这些差异可能导致学习稀疏检索(LSR)方法和密集检索方法在行为上有系统性的不同。一些研究表明,LSR模型和一些密集模型在基准测试上表现更好,例如在BEIR基准上,LSR模型和类似ColBERT的令牌级密集模型通常具有更好的泛化能力。近期也有工作提出了混合检索系统,将稀疏表示和密集表示相结合,以获得域内和域外的有效性优势。 - -1.稀疏编码器: 稀疏编码器是对查询和段落进行编码的组件,构建在Transformer主干上。不同的稀疏编码器架构包括: - - a.BINARY: 标记输入中的术语,并考虑术语的存在。 - - b.MLP: 使用多层感知器生成每个输入项的分数,重点关注术语权重。 - - c.expMLP: 在MLP编码器之前进行术语扩展。 - - d.MLM: 根据BERT的屏蔽语言模型生成术语权重。 - - e.clsMLM: 简化版的MLM编码器,仅输出序列中位置0的[CLS]标记的logits。 - -2.稀疏正则化器: 控制权重向量的稀疏性,以提高查询处理效率。包括: - - a.FLOPs: 估计点积运算的浮点运算次数,通过平滑函数计算权重向量之间的点积。 - - b.Lp 范数: 应用于输出向量的规范化,减轻过度拟合。 - - c.Top-K: 保留top-k最高的权重,将其余置零。 - -3.监督: 为了区分LSR方法并考虑效果,引入监督组件,包括负样本和标签。 - - a.负样本: 用于训练的负样本影响性能,可以从语料库中选择难度适中的负样本。 - - b.标签: 标签分为类型(人工、教师、自我)和级别(术语级、段落级)。 大多数方法使用段落级标签。 - -!["图2.1 现有 LSR 方法的定义"](/assets/images/llm/lsr_1.png "图2.1 现有 LSR 方法的定义") - - -在表中,总结了适合概念框架的学习稀疏检索(LSR)方法。这些方法可以根据概念相似性分为四个组: - -A. 无扩展方法: 包括 DeepCT 和 uniCOIL。它们使用MLP编码器对查询和文档中的术语进行加权,Equ2稍作修改。 DeepCT在监督方面使用术语召回进行监督,而uniCOIL使用段落级别标签。 - -B. 无查询扩展方法: 包括 uniCOIL $_{dT5q}$、uniCOIL $_{tilde}$ 和EPIC。它们使用具有文档扩展功能的expMLP或MLM编码器替代A组中的MLP文档编码器。其中,uniCOIL $_{dT5q}$ 和uniCOIL $_{tilde}$ 使用第三方模型进行术语扩展,而EPIC使用训练有素的MLM架构进行端到端的文档扩展和术语评分。 - -C. 无查询扩展或加权方法: 包括DeepImpact、Sparta、TILDE和TILDEv2。它们简化了B组中的方法,通过删除查询编码器来减少查询编码时间,没有查询扩展和加权功能。 - -D. 充分展开和加权方法: 包括Splade-max和distilSplade-max。它们使用共享的MLM架构在查询和文档端进行加权和扩展。这些方法没有选择前k个项,而是使用FLOPs正则化器来稀疏表示。Splade-max和distilSplade-max之间的差异在于监督方法,其中Splade-max使用多个批次的BM25负样本进行训练,而distilSplade-max使用蒸馏技术和硬负样本进行训练。 - -总的来说,这些LSR方法在概念框架下的适用性根据是否进行扩展、加权以及监督方法的不同而有所不同。不同方法之间微小的差异可能涉及非线性选择、术语质量或段落质量函数等方面。 - - -## 3 实验 - -作者对已有的LSR方法进行复现,以下是复现结果,效果采用MRR指标进行评估。 - -!["图3.1 复现结果"](/assets/images/llm/lsr_2.png "图3.1 复现结果") - -## 4 结论 - -### 4.1 研究问题一(RQ1):LSR论文的结果是否可重现? - -在复现过程中,我们采用了原始论文和代码中所述的实验设置来训练LSR方法,并将结果与原始工作进行比较。大部分方法的得分要么略高于原始工作,要么与其相当。其中,DeepCT、uniCOIL、EPIC、TILDE $_{v2}$ 和 distilSplade $_{max}$ 的MRR稍高,而DeepImpact 和 uniCOIL $_{dT5q}$ 的复现得分稍低。Sparta方法在原始论文中没有进行MSMarco评估,因此无法与其他方法进行比较。 - -复现的结果显示,DeepCT 和 uniCOIL(没有 docT5query 扩展)方法通常效率较低,而 distilSplade $_{max}$ 方法实现了最高的 MRR。值得注意的是,具有相同架构但不同训练方法的方法之间得分差异显著。例如,将 DeepCT 的监督信号从令牌级权重改为段落级相关性,使得 uniCOIL 方法的 MRR 从 24.6 跃升 28% 至 31.6。这表明监督对性能至关重要,段落级别标签有助于更好地学习术语权重以实现段落级相关性。同样,使用硬负样本挖掘和蒸馏技术将 Splade 模型的 MRR 从 34.0 提高到 37.9。这种监督方法的改变使得 distilSplade $_{max}$ 成为考虑中最有效的 LSR 方法。如果没有这种高级训练,Splade $_{max}$ 的性能与 uniCOIL $_{dT5q}$ 和 uniCOIL $_{tilde}$ 相当。在组 (B) 中,EPIC 方法似乎已经达到其性能极限,其 MRR 显著低于两个 uniCOIL 变体。这可能是因为 EPIC 最初是在 40000 个三元组上进行训练的,而其他方法是在多达数百万个样本上进行训练的。 - -### 4.2 研究问题二(RQ2):LSR方法如何在最新的高级训练技术下表现? - - -Splade模型在MSMarco上展现出令人印象深刻的排名得分。尽管这些改进可能是因为架构选择(如查询扩展)等原因,但Splade还通过高级训练过程中挖掘的难负样本和交叉编码器蒸馏等技术受益。实验结果显示,与Splade相同的训练方式使得许多旧方法的效果显著提升。其中,旧的EPIC模型的MRR@10分数增加了36%,变得与Splade相当。 - -由于不同环境可能引起公平比较的困难,作者在一致的环境中进行了所有方法的训练,证明这是有效的。在最有效的监督设置下,即使用蒸馏和硬负片进行训练的 distilSplade $_{max}$ ,作者发现最低效的方法(如DeepCT)和最高效的方法(如distilSplade $_{max}$ )保持在相同位置。而介于这两个端点之间的方法根据其效果而变化。实验结果显示,多数方法在这种设置下取得了提升,其中EPIC和Sparta的改进最为显著,分别相对于MSMarco提升了8.0和4.2个MRR点。EPIC在训练时间更长和改进的监督下,有效性提升使其在相对排名中跃升为第二位,并与MSMarco上的distilSplade $_{max}$ 相竞争。而在TREC DL 2019和TREC DL 2020上,EPIC和distilSplade $_{max}$ 之间的NDCG@10差距更大。 - -作者还注意到在使用不同架构类型方面,使用MLM架构(无论是在文档端还是查询端)的方法通常在三个数据集上表现更好,然而MLM也会导致显著增加索引大小和延迟。最后,通过引入独立的编码器以减少文档和查询之间的术语激活概率相似性,成功解决了Splade中的延迟问题,进一步支持了这一解决方法的重要性。 - -### 4.3 研究问题三(RQ3):编码器架构和正则化的选择如何影响结果? - - -通过在共同训练环境中进行实验,作者量化了不同架构决策(如扩展、加权和正则化)对系统效果和效率的影响。他们发现文档加权对系统的有效性影响最大,而查询加权的影响较为适中,尽管查询加权通过减少无用术语改善了检索延迟。查询和文档扩展之间存在抵消效应,因为一侧扩展时,另一侧的扩展对系统效果的提升会受到影响,表明查询扩展对于LSR系统表现良好并不是必需的。 - -作者的实验结果还表明,不同的正则化方法对有效性和效率影响不大。总体而言,这些发现揭示了在优化LSR方法时,文档加权、查询加权、查询扩展和文档扩展之间的权衡,同时对正则化方法的选择在某些情况下可能不太重要。 - -作者展示了仅在查询端或文档端进行扩展的系统结果。这些结果进一步支持了之前的发现,即查询扩展和文档扩展之间存在抵消效应。他们还指出,将MLM查询编码器替换为MLP查询编码器(distilSplade $_{qMLP}$ )可以在不显著影响排名指标的情况下降低检索延迟,从而提高效率。这种变化可以被视为更有效的替代方式,进一步强调了提高LSR方法效率的可能性。 +--- +author: 研究生鱼皮-yjf +icon: pen-to-square +date: 2023-08-23 +category: + - rag +tag: + - 检索 + - rag +# sticky: 10 +--- + +# 学习稀疏检索的统一框架 + +学习稀疏检索是一种结合机器学习和信息检索的方法,旨在优化文本检索效果。通过学习模型,将查询和文档映射到稀疏表示空间,实现高效的检索。在训练阶段,利用已标记的查询-文档对和相关性标签,通过优化模型参数,学习如何选择、加权和组合特征,使相关文档在稀疏表示中更接近查询。学习稀疏检索方法可应用于大规模信息检索任务,如搜索引擎和推荐系统,以提高检索效率和准确性。 + + + +## 1 背景和目的 + +自然语言查询的文本检索是信息检索(IR)系统的核心任务。之前的研究采用了两阶段的流程来解决这个问题,首先通过快速的检索器从文档集合中检索出一组初始文档,然后由更复杂的模型进一步重新排名。对于第一阶段的检索,神经网络的密集表示在语义匹配方面具有很大的潜力,在许多自然语言处理任务中超越了稀疏方法,但在强调长文档检索和精确匹配的情况下不一定成立。此外,对于极大规模(例如100亿)的候选文档集合,密集方法不得不在效率与准确性之间权衡。传统的基于术语的稀疏表示,也称为词袋(BoW),如TF-IDF和BM25,可以有效地进行字面匹配,因此在工业级IR系统中扮演着核心角色。然而,传统的基于术语的方法通常被认为表示能力不足,不适用于语义级匹配。 + +学习稀疏检索最早由Zamani等人在论文《From Neural Re-Ranking to Neural Ranking: Learning a Sparse Representation for Inverted Indexing》中提出。SNRM(Standalone Neural Ranking Model)是一种独立的神经排序模型,旨在解决神经排序模型在效率方面的问题。它通过引入稀疏属性,为每个查询和文档学习潜在的稀疏表示。其中“潜在”Token在反向索引过程中扮演传统术语的角色。关于SNRM的一个挑战是它失去了原始术语的可解释性,这对于工业系统至关重要。 + +该论文研究了学习稀疏检索(LSR)方法,这是一类用于生成查询和文档稀疏词汇表示的首阶段检索方法,用于倒排索引。虽然有许多LSR方法已被引入,其中Splade模型在MSMarco数据集上取得了最先进的性能,但不同的实验设置和配置难以进行有效的比较和洞察。在这项工作中,作者分析了现有的LSR方法,识别出关键组成部分,并建立了一个统一的LSR框架,将所有LSR方法放置在一个统一的视角下。然后,作者重新实现了所有重要的方法,并在相同环境中重新训练,以便量化不同框架组成部分如何影响效果和效率。研究发现:(1)文档词项加权对方法的效果最具影响,(2)查询加权略有正面影响,(3)文档扩展和查询扩展效果相互抵消。因此,作者提出了如何从最先进的模型中移除查询扩展,以显著降低延迟,同时在MSMarco和TripClick数据集上保持性能。该工作旨在提供一种统一的LSR框架,深入分析了不同组成部分对效果和效率的影响,并为LSR方法的进一步优化提供了指导。 + +## 2 统一框架的建立 + +学习稀疏检索 (LSR) 使用查询编码器 $f_Q$和$f_D$文档编码器 将查询和文档投影到词汇大小的稀疏向量: $w_q=f_Q(q)=w_q^1,w_q^2,\dots ,w_q^{|V|}$和$w_d=f_D(d)=w_d^1,w_d^2,\dots ,w_d^{|V|}$。 查询与文档之间的分数是其对应向量之间的点积:$sim(q,d) = \sum _{i=1}^{|V|}w_q^iw_d^i$。 该公式与 BM25 等传统稀疏检索方法密切相关; 事实上,BM25 可以表述为: + +$$\begin{aligned} \text {BM25}(q,d)&= \sum _{i=1}^{|q|} \text {IDF}(q_i) \times \frac{tf(q_i, d) \times (k_1 + 1)}{tf(q_i, d) + k_1 \cdot \left( 1 - b + b \cdot \frac{|d|}{\text {avgdl}}\right) } \\&= \sum _{j=1}^{|V|} \underbrace{ \mathbb {1}_{q(v_j)} \text {IDF}(v_j)}_{\text {query encoder}} \times \underbrace{\mathbb {1}_{d(v_j)} \frac{tf(v_j, d) \times (k_1 + 1)}{tf(v_j, d) + k_1 \cdot \left( 1 - b + b \cdot \frac{|d|}{\text {avgdl}}\right) }}_{\text {doc encoder}} \\&= \sum _{j=1}^{|V|} f_Q(q)_j \times f_D(d)_j \\ \end{aligned}$$ + +使用 BM25,IDF 和 TF 分量可以被视为查询/文档术语权重。 LSR 的不同之处在于使用神经模型(通常是 Transformer)来预测术语权重。 LSR 与稀疏检索的许多技术兼容,例如倒排索引和附带的查询处理算法。 然而,LSR 权重的差异可能意味着现有的查询处理优化变得不太有用,从而激发新的优化。 + +在本节中,我们介绍一个由三个组件(稀疏编码器、稀疏正则化器、监督)组成的概念框架,它捕获了我们观察到的现有学习稀疏检索方法之间的关键差异。 随后,我们描述了文献中的 LSR 方法如何适应这个框架。 + +稀疏(词法)编码器是学习稀疏检索方法的主要组成部分,用于将查询和段落编码为相同维度的权重向量。与密集编码器相比,稀疏编码器具有三个主要特征。首先,稀疏编码器生成稀疏向量,其中大多数权重为零,这由稀疏正则化器控制。其次,稀疏权重向量的维度通常与词汇表中的术语数量相对应,而密集编码器生成较小的压缩向量,没有明确的术语与维度对应关系。第三,稀疏编码器只产生非负权重,因为稀疏检索方法依赖于传统词汇搜索的堆栈,其中权重始终是非负的术语频率。 + +这些差异可能导致学习稀疏检索(LSR)方法和密集检索方法在行为上有系统性的不同。一些研究表明,LSR模型和一些密集模型在基准测试上表现更好,例如在BEIR基准上,LSR模型和类似ColBERT的令牌级密集模型通常具有更好的泛化能力。近期也有工作提出了混合检索系统,将稀疏表示和密集表示相结合,以获得域内和域外的有效性优势。 + +1.稀疏编码器: 稀疏编码器是对查询和段落进行编码的组件,构建在Transformer主干上。不同的稀疏编码器架构包括: + + a.BINARY: 标记输入中的术语,并考虑术语的存在。 + + b.MLP: 使用多层感知器生成每个输入项的分数,重点关注术语权重。 + + c.expMLP: 在MLP编码器之前进行术语扩展。 + + d.MLM: 根据BERT的屏蔽语言模型生成术语权重。 + + e.clsMLM: 简化版的MLM编码器,仅输出序列中位置0的[CLS]标记的logits。 + +2.稀疏正则化器: 控制权重向量的稀疏性,以提高查询处理效率。包括: + + a.FLOPs: 估计点积运算的浮点运算次数,通过平滑函数计算权重向量之间的点积。 + + b.Lp 范数: 应用于输出向量的规范化,减轻过度拟合。 + + c.Top-K: 保留top-k最高的权重,将其余置零。 + +3.监督: 为了区分LSR方法并考虑效果,引入监督组件,包括负样本和标签。 + + a.负样本: 用于训练的负样本影响性能,可以从语料库中选择难度适中的负样本。 + + b.标签: 标签分为类型(人工、教师、自我)和级别(术语级、段落级)。 大多数方法使用段落级标签。 + +!["图2.1 现有 LSR 方法的定义"](/assets/images/llm/lsr_1.png "图2.1 现有 LSR 方法的定义") + + +在表中,总结了适合概念框架的学习稀疏检索(LSR)方法。这些方法可以根据概念相似性分为四个组: + +A. 无扩展方法: 包括 DeepCT 和 uniCOIL。它们使用MLP编码器对查询和文档中的术语进行加权,Equ2稍作修改。 DeepCT在监督方面使用术语召回进行监督,而uniCOIL使用段落级别标签。 + +B. 无查询扩展方法: 包括 uniCOIL $_{dT5q}$、uniCOIL $_{tilde}$ 和EPIC。它们使用具有文档扩展功能的expMLP或MLM编码器替代A组中的MLP文档编码器。其中,uniCOIL $_{dT5q}$ 和uniCOIL $_{tilde}$ 使用第三方模型进行术语扩展,而EPIC使用训练有素的MLM架构进行端到端的文档扩展和术语评分。 + +C. 无查询扩展或加权方法: 包括DeepImpact、Sparta、TILDE和TILDEv2。它们简化了B组中的方法,通过删除查询编码器来减少查询编码时间,没有查询扩展和加权功能。 + +D. 充分展开和加权方法: 包括Splade-max和distilSplade-max。它们使用共享的MLM架构在查询和文档端进行加权和扩展。这些方法没有选择前k个项,而是使用FLOPs正则化器来稀疏表示。Splade-max和distilSplade-max之间的差异在于监督方法,其中Splade-max使用多个批次的BM25负样本进行训练,而distilSplade-max使用蒸馏技术和硬负样本进行训练。 + +总的来说,这些LSR方法在概念框架下的适用性根据是否进行扩展、加权以及监督方法的不同而有所不同。不同方法之间微小的差异可能涉及非线性选择、术语质量或段落质量函数等方面。 + + +## 3 实验 + +作者对已有的LSR方法进行复现,以下是复现结果,效果采用MRR指标进行评估。 + +!["图3.1 复现结果"](/assets/images/llm/lsr_2.png "图3.1 复现结果") + +## 4 结论 + +### 4.1 研究问题一(RQ1):LSR论文的结果是否可重现? + +在复现过程中,我们采用了原始论文和代码中所述的实验设置来训练LSR方法,并将结果与原始工作进行比较。大部分方法的得分要么略高于原始工作,要么与其相当。其中,DeepCT、uniCOIL、EPIC、TILDE $_{v2}$ 和 distilSplade $_{max}$ 的MRR稍高,而DeepImpact 和 uniCOIL $_{dT5q}$ 的复现得分稍低。Sparta方法在原始论文中没有进行MSMarco评估,因此无法与其他方法进行比较。 + +复现的结果显示,DeepCT 和 uniCOIL(没有 docT5query 扩展)方法通常效率较低,而 distilSplade $_{max}$ 方法实现了最高的 MRR。值得注意的是,具有相同架构但不同训练方法的方法之间得分差异显著。例如,将 DeepCT 的监督信号从令牌级权重改为段落级相关性,使得 uniCOIL 方法的 MRR 从 24.6 跃升 28% 至 31.6。这表明监督对性能至关重要,段落级别标签有助于更好地学习术语权重以实现段落级相关性。同样,使用硬负样本挖掘和蒸馏技术将 Splade 模型的 MRR 从 34.0 提高到 37.9。这种监督方法的改变使得 distilSplade $_{max}$ 成为考虑中最有效的 LSR 方法。如果没有这种高级训练,Splade $_{max}$ 的性能与 uniCOIL $_{dT5q}$ 和 uniCOIL $_{tilde}$ 相当。在组 (B) 中,EPIC 方法似乎已经达到其性能极限,其 MRR 显著低于两个 uniCOIL 变体。这可能是因为 EPIC 最初是在 40000 个三元组上进行训练的,而其他方法是在多达数百万个样本上进行训练的。 + +### 4.2 研究问题二(RQ2):LSR方法如何在最新的高级训练技术下表现? + + +Splade模型在MSMarco上展现出令人印象深刻的排名得分。尽管这些改进可能是因为架构选择(如查询扩展)等原因,但Splade还通过高级训练过程中挖掘的难负样本和交叉编码器蒸馏等技术受益。实验结果显示,与Splade相同的训练方式使得许多旧方法的效果显著提升。其中,旧的EPIC模型的MRR@10分数增加了36%,变得与Splade相当。 + +由于不同环境可能引起公平比较的困难,作者在一致的环境中进行了所有方法的训练,证明这是有效的。在最有效的监督设置下,即使用蒸馏和硬负片进行训练的 distilSplade $_{max}$ ,作者发现最低效的方法(如DeepCT)和最高效的方法(如distilSplade $_{max}$ )保持在相同位置。而介于这两个端点之间的方法根据其效果而变化。实验结果显示,多数方法在这种设置下取得了提升,其中EPIC和Sparta的改进最为显著,分别相对于MSMarco提升了8.0和4.2个MRR点。EPIC在训练时间更长和改进的监督下,有效性提升使其在相对排名中跃升为第二位,并与MSMarco上的distilSplade $_{max}$ 相竞争。而在TREC DL 2019和TREC DL 2020上,EPIC和distilSplade $_{max}$ 之间的NDCG@10差距更大。 + +作者还注意到在使用不同架构类型方面,使用MLM架构(无论是在文档端还是查询端)的方法通常在三个数据集上表现更好,然而MLM也会导致显著增加索引大小和延迟。最后,通过引入独立的编码器以减少文档和查询之间的术语激活概率相似性,成功解决了Splade中的延迟问题,进一步支持了这一解决方法的重要性。 + +### 4.3 研究问题三(RQ3):编码器架构和正则化的选择如何影响结果? + + +通过在共同训练环境中进行实验,作者量化了不同架构决策(如扩展、加权和正则化)对系统效果和效率的影响。他们发现文档加权对系统的有效性影响最大,而查询加权的影响较为适中,尽管查询加权通过减少无用术语改善了检索延迟。查询和文档扩展之间存在抵消效应,因为一侧扩展时,另一侧的扩展对系统效果的提升会受到影响,表明查询扩展对于LSR系统表现良好并不是必需的。 + +作者的实验结果还表明,不同的正则化方法对有效性和效率影响不大。总体而言,这些发现揭示了在优化LSR方法时,文档加权、查询加权、查询扩展和文档扩展之间的权衡,同时对正则化方法的选择在某些情况下可能不太重要。 + +作者展示了仅在查询端或文档端进行扩展的系统结果。这些结果进一步支持了之前的发现,即查询扩展和文档扩展之间存在抵消效应。他们还指出,将MLM查询编码器替换为MLP查询编码器(distilSplade $_{qMLP}$ )可以在不显著影响排名指标的情况下降低检索延迟,从而提高效率。这种变化可以被视为更有效的替代方式,进一步强调了提高LSR方法效率的可能性。 diff --git a/src/zh/posts/rag/README.md b/src/zh/posts/rag/README.md new file mode 100644 index 0000000000..b90719e2ae --- /dev/null +++ b/src/zh/posts/rag/README.md @@ -0,0 +1,12 @@ +--- +title: RAG +icon: puzzle-piece +index: false +article: false +category: + - rag +tag: + - rag +dir: + order: 1 +--- \ No newline at end of file diff --git a/src/zh/posts/llm/RetrieveTextGeneration.md b/src/zh/posts/rag/RetrieveTextGeneration.md similarity index 99% rename from src/zh/posts/llm/RetrieveTextGeneration.md rename to src/zh/posts/rag/RetrieveTextGeneration.md index 4a9a365fb6..68d4a4ff4a 100644 --- a/src/zh/posts/llm/RetrieveTextGeneration.md +++ b/src/zh/posts/rag/RetrieveTextGeneration.md @@ -3,10 +3,11 @@ author: 最后的开神-wkyc icon: pen-to-square date: 2023-09-21 category: - - 语言模型 + - rag tag: - 检索 - 文本生成 + - rag # sticky: 10 --- diff --git a/src/zh/posts/llm/GPT4Reason.md b/src/zh/posts/reasoning/GPT4Reason.md similarity index 99% rename from src/zh/posts/llm/GPT4Reason.md rename to src/zh/posts/reasoning/GPT4Reason.md index 0cc6ef7cff..b1b9df64ed 100644 --- a/src/zh/posts/llm/GPT4Reason.md +++ b/src/zh/posts/reasoning/GPT4Reason.md @@ -5,7 +5,7 @@ date: 2023-08-13 shortTitle: 探究GPT4的推理能力 title: 探究GPT-4到底有没有推理能力? category: - - 语言模型 + - 推理方法 tag: - GPT-4 - Reasoning diff --git a/src/zh/posts/reasoning/README.md b/src/zh/posts/reasoning/README.md new file mode 100644 index 0000000000..7ee3002fcc --- /dev/null +++ b/src/zh/posts/reasoning/README.md @@ -0,0 +1,12 @@ +--- +title: 推理方法 +icon: gem +index: false +article: false +category: + - 推理方法 +tag: + - Reasoning +dir: + order: 7 +--- \ No newline at end of file diff --git a/src/zh/posts/prompt/llmReasonSurvey.md b/src/zh/posts/reasoning/llmReasonSurvey.md similarity index 99% rename from src/zh/posts/prompt/llmReasonSurvey.md rename to src/zh/posts/reasoning/llmReasonSurvey.md index 375a597a27..e57ae04f5d 100644 --- a/src/zh/posts/prompt/llmReasonSurvey.md +++ b/src/zh/posts/reasoning/llmReasonSurvey.md @@ -5,7 +5,7 @@ date: 2023-07-14 shortTitle: LLM推理综述 title: 论文分享:基于提示学习的大型语言模型推理综述 category: - - 提示技术 + - 推理方法 tag: - Survey - LLM diff --git a/src/zh/posts/token/README.md b/src/zh/posts/token/README.md index 4aa84861fe..0474cb9505 100644 --- a/src/zh/posts/token/README.md +++ b/src/zh/posts/token/README.md @@ -8,5 +8,5 @@ category: tag: - token dir: - order: 6 + order: 8 --- \ No newline at end of file diff --git a/src/zh/posts/llm/Token-Crisis.md b/src/zh/posts/token/Token-Crisis.md similarity index 99% rename from src/zh/posts/llm/Token-Crisis.md rename to src/zh/posts/token/Token-Crisis.md index 9070ddbfea..6d24c924a3 100644 --- a/src/zh/posts/llm/Token-Crisis.md +++ b/src/zh/posts/token/Token-Crisis.md @@ -4,7 +4,7 @@ icon: pen-to-square date: 2023-05-31 shortTitle: Token危机 category: - - 语言模型 + - Token tag: - 模型 - 深度学习