一、RAG痛点介绍
迩来我一直在关注和优化RAG(Retrieval-Augmented Generation)干系的内容,总结了一下RAG的痛点和最佳实践,然后重点会介绍怎样评估RAG。
二、RAG痛点优化
认识了RAG的痛点,就知道怎样举行优化了,下面是RAG最佳实践的总结。
首先,总结一下日常对RAG(Retrieval-Augmented Generation)的最佳实践中,通常会涉及以下关键问题和优化计谋:
1. 数据怎样处理的?
- 清洗和预处理:在使用数据之前,确保数据是干净和结构化的。这可能包罗去除噪音、处理缺失值、标准化格式等。
- 分段和标注:将长文档分成较小的段落(chunks),并为每个段落添加干系标签或元数据,以便更好地举行检索和天生。
- import pandas as pd
- # 读取数据
- data = pd.read_csv('data.csv')
- # 数据清洗
- data.dropna(inplace=True) # 去除缺失值
- data['text'] = data['text'].str.lower() # 转换为小写data['text'] =
- data['text'].str.replace(r'\d+', '', regex=True) # 去除数字
- # 数据分段和标注
- def chunk_text(text, chunk_size=200):
- words = text.split()
- chunks = [' '.join(words[i:i + chunk_size]) for i in range(0, len(words), chunk_size)]
- return chunksdata['chunks'] =
-
- data['text'].apply(chunk_text)
复制代码 2. chunk-size怎样设置的?
- 优化长度:chunk-size的设置需要均衡信息量和检索效率。一般来说,较短的chunk可以进步检索的正确性,但可能会丢失上下文信息;较长的chunk可以保留更多的上下文,但可能会增加冗余信息。常见的chunk大小在100到300个词之间,根据详细应用场景举行调整。
- # 设置chunk大小
- chunk_size = 150 # 例如设置为150个词
- # 分段函数
- def chunk_text(text, chunk_size):
- words = text.split()
- chunks = [' '.join(words[i:i + chunk_size]) for i in range(0, len(words), chunk_size)]
- return chunks
-
- data['chunks'] = data['text'].apply(lambda x: chunk_text(x, chunk_size))
复制代码 3. Embedding模型使用的什么?
- 选择合适的模型:常用的embedding模型包罗BERT、RoBERTa、Sentence-BERT等。选择时需要考虑模型的性能、练习数据和盘算资源。
- 自定义练习:对于特定范畴的应用,可以考虑对预练习模型举行微调,以进步嵌入的干系性和正确性。
- from transformers import BertTokenizer, BertModel
- import torch
- # 加载预训练模型和
- tokenizertokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
- model = BertModel.from_pretrained('bert-base-uncased')
- # 微调模型
- # 假设我们有一个自定义数据集custom_dataset
- # for batch in custom_dataset:
- # inputs = tokenizer(batch['text'], return_tensors='pt', padding=True, truncation=True)
- # outputs = model(**inputs)
- # # 在这里添加微调逻辑
- # 对数据进行embedding
- inputs = tokenizer(data['chunks'].sum(), return_tensors='pt', padding=True, truncation=True)
- with torch.no_grad():
- outputs = model(**inputs)
- embeddings = outputs.last_hidden_state.mean(dim=1)
复制代码 4. Prompt怎样设计?
- Prompt设计:设计有效的prompt以引导天生模型产生所需的回答。Prompt应只管清楚、详细,避免含糊或开放性太强。
5. 检索的topN怎样设置?
- 检索的topN设置:topN设置决定了在天生过程中使用多少个最干系的文档段落。常见的topN值在3到10之间,根据检索结果和天生质量举行调整。
6. LLM模型选择的什么?
- 选择合适的天生模型:常用的大语言模型(LLM)包罗GPT-3.5、GPT-4、4o等。选择时需要考虑模型的天生能力、推理速度和盘算资源。
- 混合使用模型:在一些场景下,可以同时使用多个模型来进步天见结果,例如结合检索模型和天生模型的优势。
7. RAG检索天见结果优化计谋
- 选择更大的模型:如果现有模型的天见结果不理想,可以尝试使用更大的预练习模型,这通常会带来更好的天生质量和上下文理解能力。
- 使用不同的embedding模型:根据实际应用场景和数据特点,尝试使用不同的embedding模型,以找到最恰当的模型来进步检索精度。
- 调整chunk-size:重新评估和调整chunk的大小,以找到信息量和检索效率之间的最佳均衡点。
通过不断地实验和优化,可以找到最恰当特定应用场景的RAG配置,从而实现更好的检索和天见结果。
颠末各种优化之后,对RAG来说,最紧张的就是怎样评估其结果。
三、为什么需要对RAG体系评估?
评估是AI开发流程中的一个非常关键步骤,它被用于查抄当前计谋相对于其他计谋的有效性,或在当你对流程举行更改时举行评估。因此在举行LLM项目的开发和改进时,必须要有衡量其表现的方法。
LlamaIndex中RAG处理过程(图片来源:https://docs.llamaindex.ai/en/stable/getting_started/concepts/ ):
为了评估RAG体系,我们通常使用两种类型的评估:
与传统的呆板学习技能不同,传统技能有明白定量的度量指标(如Gini系数、R平方、AIC、BIC、混淆矩阵等),评估RAG体系更加复杂。这种复杂性的原因在于RAG体系天生的相应是非结构化文本,需要结合定性和定量指标来正确评估其性能。
为了有效评估RAG体系,我们通常遵照TRIAD框架。该框架由三个主要组成部分组成:
- 上下文干系性:这个组件评估RAG体系的检索部分。它评估从大型数据集中正确检索到的文档。这里使用的度量指标包罗正确度、召回率、MRR和MAP。
- 老实度(基于检索):这个组件属于相应评估。它查抄天生的相应是否正确无误,并且基于检索到的文档。通过人工评估、自动事实查抄工具和同等性查抄等方法来评估老实度。
- 答案干系性:这也是相应评估的一部分。它衡量天生的相应对用户的查询提供了多少有效的信息。使用的度量指标包罗BLEU、ROUGE、METEOR和基于嵌入的评估。
检索评估适用于RAG体系的检索器组件,该组件通常使用向量数据库。这些评估衡量检索器在相应用户查询时辨认和排名干系文档的结果。检索评估的主要目标是评估上下文干系性,即检索到的文档与用户查询的匹配程度。它确保提供给天生组件的上下文是干系和正确的。
正确度
正确度衡量了检索到的文档的正确性。它是检索到的干系文档数目与检索到的文档总数之比。定义如下:
这意味着正确度评估了体系检索到的文档中有多少实际与用户查询干系。例如,如果检索器检索到了10个文档,其中7个是干系的,那么正确度将是0.7或70%。
- def calculate_precision(retrieved_docs, relevant_docs):
- """
- 计算精确度
-
- 参数:
- retrieved_docs (list): 检索到的文档列表
- relevant_docs (list): 相关文档列表
-
- 返回:
- float: 精确度
- """
- # 计算检索到的相关文档数量
- relevant_retrieved_docs = [doc for doc in retrieved_docs if doc in relevant_docs]
-
- # 计算精确度
- precision = len(relevant_retrieved_docs) / len(retrieved_docs) if retrieved_docs else 0
- return precision
-
- # 示例数据
- retrieved_docs = ['doc1', 'doc2', 'doc3', 'doc4', 'doc5']
- relevant_docs = ['doc2', 'doc4', 'doc6']
- # 计算精确度
- precision = calculate_precision(retrieved_docs, relevant_docs)
- print(f"精确度: {precision:.2f}")
复制代码 正确度评估的是“体系检索到的所有文档中,有多少实际上是干系的?”
在可能导致负面结果的情况下,正确度尤为紧张。例如,在医学信息检索体系中,高正确度至关紧张,因为提供不干系的医学文档可能导致错误信息和潜在的有害结果。
召回率
召回率衡量了检索到的文档的全面性。它是检索到的干系文档数目与数据库中干系文档的总数之比。定义如下:
这意味着召回率评估了数据库中存在的干系文档有多少被体系乐成检索到。
- def calculate_recall(retrieved_docs, relevant_docs):
- """
- 计算召回率
-
- 参数:
- retrieved_docs (list): 检索到的文档列表
- relevant_docs (list): 相关文档列表
-
- 返回:
- float: 召回率
- """
- # 计算检索到的相关文档数量
- relevant_retrieved_docs = [doc for doc in retrieved_docs if doc in relevant_docs]
-
- # 计算召回率
- recall = len(relevant_retrieved_docs) / len(relevant_docs) if relevant_docs else 0
- return recall
-
- # 示例数据
- retrieved_docs = ['doc1', 'doc2', 'doc3', 'doc4', 'doc5']
- relevant_docs = ['doc2', 'doc4', 'doc6', 'doc7']
- # 计算召回率
- recall = calculate_recall(retrieved_docs, relevant_docs)
- print(f"召回率: {recall:.2f}")
复制代码 召回率评估的是“数据库中存在的所有干系文档中,体系乐成检索到了多少个?”
在可能错过干系信息会产天生本的情况下,召回率至关紧张。例如,在法律信息检索体系中,高召回率至关紧张,因为未能检索到干系的法律文件可能导致不完备的案例研究,并可能影响法律诉讼的结果。
正确度和召回率的均衡
通常需要均衡正确度和召回率,因为改善其中一个指标有时会低落另一个指标。目标是找到恰当特定应用需求的最佳均衡。这种均衡有时可以用F1分数来量化,F1分数是正确度和召回率的调平静均值:
平均倒数排名(MRR)
平均倒数排名(MRR)是一种评估检索体系结果的度量指标,它考虑了第一个干系文档的排名位置。当只有第一个干系文档是主要关注的情况下,MRR特殊有效。倒数排名是第一个干系文档被找到的排名的倒数。MRR是多个查询的这些倒数排名的平均值。MRR的公式如下:
其中Q是查询的数目,是第q个查询的第一个干系文档的排名。
MRR评估的是“平均来说,体系多快能够在相应用户查询时检索到第一个干系文档?”
例如,在基于RAG的问答体系中,MRR至关紧张,因为它反映了体系能够多快地向用户出现正确答案。如果正确答案更频仍地出如今列表的顶部,MRR值将更高,表现检索体系更有效。
平均正确率(MAP)
平均正确率(MAP)是一种评估多个查询的检索正确度的度量指标。它同时考虑了检索的正确度和检索文档的次序。MAP定义为一组查询的平均正确率得分的平均值。为了盘算单个查询的平均正确率,需要在检索到的文档的排序列表中的每个位置盘算正确度,只考虑前K个检索到的文档,其中每个正确度都根据文档是否干系举行加权。多个查询的MAP公式如下:
其中Q是查询的数目,是查询q的平均正确率。
MAP评估的是“平均来说,体系在多个查询中排名靠前的文档的正确度怎样?”
例如,在基于RAG的搜索引擎中,MAP至关紧张,因为它考虑了检索的正确度和不同排名的检索结果,确保干系文档在搜索结果中更高地显示,从而通过首先出现最干系的信息来进步用户体验。
相应评估
相应评估适用于体系的天生组件。这些评估衡量体系根据检索到的文档提供的上下文有效地天生相应的能力。我们将相应评估分为两种类型:
老实度(基于检索)
老实度评估天生的相应是否正确,并且基于检索到的文档。它确保相应不包罗幻觉或错误信息。这个度量指标至关紧张,因为它将天生的相应追溯到其来源,确保信息基于可验证的真实情况。老实度有助于防止幻觉,即体系天生听起来公道但事实上不正确的相应。
为了衡量老实度,通常使用以下方法:
- 人工评估:专家手动评估天生的相应是否事实正确,并且是否正确引用了检索到的文档。这个过程涉及查抄每个相应与源文档,以确保所有主张都有证据支持。
- 自动事实查抄工具:这些工具将天生的相应与已验证事实的数据库举行比较,以辨认不正确之处。它们提供了一种无需人工干预即可查抄信息有效性的自动方式。
- 同等性查抄:这些评估模型是否在不同查询中始终提供雷同的事实信息。这确保模型可靠,不会产生抵牾的信息。
答案干系性
答案干系性衡量天生的相应对用户的查询有多好,并提供有效的信息。
四、使用LangSmith举行评估
了解了这些评估指标,该怎样举行评估,可以先通过使用LangSmith举行评估,LangSmith 是一个开发者平台,允许您调试、测试、评估和监控大语言模型 (LLM) 应用步伐,并且能够与 LangChain 无缝集成, 助您从开发原型顺利过渡到实际生产应用。
在LLM使命中,丈量正确性的一个挑战来自非结构化文本的影响。问答体系可能天生冗长的相应,使得传统的指标如 BLEU 或 ROUGE 变得不可靠。在这种情况下,使用标注良好的数据集和大语言模型 (LLM) 辅助评估器可以帮助您评估体系的相应质量。
针对一个RAG体系举行评估,主要步骤如下:
- 创建一个测试用的数据集。
- 定义您的问答体系。
- 使用 LangSmith 运行评估。
- 迭代改进体系。
\1. 在LangChain代码中参加使用LangSmith
第一步:获取一个LangChain的API Key,登录LangSmith:https://smith.langchain.com/,参考下图创建API key:
第二步:设置以下参数后,LangSmith会自动举行跟踪管理。
\2. 准备测试数据
这里整理了三种准备测试数据的方式:数据导入,代码创建和使用LangSmith辅助创建。
第一种方法:CSV文件导入
第二种方法:代码创建
下面的代码实验后,也可以在LangSmith中新建一个 Retrieval QA Questions xxxxx 的测试集。
- # 问题与答案
- examples = [
- (
- "What is LangChain?",
- "LangChain is an open-source framework for building applications using large language models. It is also the name of the company building LangSmith.",
- ),
- (
- "Can I trace my Llama V2 llm?",
- "So long as you are using one of LangChain's LLM implementations, all your calls can be traced",
- ),
- ]
- # 数据库创建部分
- from langsmith import Client
- client = Client()
- import uuid
- dataset_name = f"Retrieval QA Questions {str(uuid.uuid4())}"
- dataset = client.create_dataset(dataset_name=dataset_name)
- for q, a in examples:
- client.create_example(
- inputs={"question": q}, outputs={"answer": a}, dataset_id=dataset.id
- )
复制代码 第三种方法:使用LangSmith辅助创建
创建的步骤如下:
- 创建RAG体系
- 准备问题并实验
你可以准备一系列问题,然后实验查询,如: rag_chain.invoke(“Ollama支持哪些模型?”)
- LangSmith后台根据处理的结果,对测试数据举行管理,添加,修改等。
\3. 使用LangSmith举行评估
测试数据准备好之后,就可以开始对体系举行评估了。LangSmith的后台可以天生评估的代码。



RAG QA问答的正确性评估器(Evaluator)包罗三个版本:“qa”、“context_qa”、“cot_qa”。
“qa”评估器,指示大语言模型 (LLM) 根据参考答案直接将相应评为“正确”或“错误”。
“context_qa”评估器指示 LLM 使用参考“上下文”来确定相应的正确性。用于只有上下文息争答,没有答案的情况。
“cot_qa”评估器与“context_qa”评估器雷同,但它指示 LLMChain 在得出最终结论前使用头脑链“推理”。
这通常会导致相应更好地与人工标签匹配,但会稍微增加 Token 和运行成本。
更多评估器,可以参考下面的文档:
https://docs.smith.langchain.com/old/evaluation/faq/evaluator-implementations
\4. 完备代码
- import langsmith
- from langchain import chat_models, prompts, smith
- from langchain.schema import output_parser
- from langchain_community.llms import Ollama
- from langchain_community.embeddings import OllamaEmbeddings
- import bs4
- from langchain import hub
- from langchain.text_splitter import RecursiveCharacterTextSplitter
- from langchain_community.document_loaders import WebBaseLoader
- from langchain_community.vectorstores import Chroma
- from langchain_core.output_parsers import StrOutputParser
- from langchain_core.runnables import RunnablePassthrough
- from langchain_community.document_loaders import UnstructuredHTML
- Loaderloader = UnstructuredHTMLLoader("./240327-ollama-20question.html")
- docs = loader.load()
- text_splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=50)
- splits = text_splitter.split_documents(docs)
- vectorstore = Chroma.from_documents(documents=splits, embedding=OllamaEmbeddings(model="mofanke/acge_text_embedding"))
- retriever = vectorstore.as_retriever()
- from langchain.prompts import ChatPromptTempla
- tetemplate = """你是一个回答问题的助手。请使用以下检索到的背景信息来回答问题。如果你不知道答案,直接说你不知道。请用最多三句话来保持回答的简洁性。
- 问题:{question}
- 背景:{context}
- 答案:
- """
- prompt = ChatPromptTemplate.from_template(template)
- #llm = chat_models.ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
- llm = Ollama(model="qwen:72b", temperature=0)
- # Post-processing
- def format_docs(docs):
- return "\n\n".join(doc.page_content for doc in docs)
- # Chain
- rag_chain = (
- {"context": retriever | format_docs, "question": RunnablePassthrough()}
- | prompt
- | llm
- | StrOutputParser()
- )
- # 执行查询
- rag_chain.invoke("Ollama支持哪些模型?")
- # 定义评估设置(评估器,评估用的LLM等)
- eval_config = smith.RunEvalConfig(
- evaluators=[
- "cot_qa"
- ],
- custom_evaluators=[],
- eval_llm=Ollama(model="qwen:72b", temperature=0)
- )
- client = langsmith.Client()
- chain_results = client.run_on_dataset(
- dataset_name="Self-RAG-Ollama-20QA",
- llm_or_chain_factory=rag_chain,
- evaluation=eval_config,
- project_name="test-crazy-rag-qw72b-qw72b",
- concurrency_level=5,
- verbose=True,
- )
复制代码 开发RAG体系自己并不困难,但评估RAG体系对于性能、实现持续改进、与业务目标保持同等、均衡成本、确保可靠性和顺应新方法至关紧张。这个全面的评估过程有助于构建强盛、高效和以用户为中央的RAG体系。
后续筹划继续写3-5篇,继续介绍RAG的评估框架和方法,点赞评论关注我,持续学习更精彩。
参考资料:
1.https://baoyu.io/translations/rag/12-rag-pain-points-and-proposed-solutions
\2. https://myscale.com/blog/zh/ultimate-guide-to-evaluate-rag-system/
\3. https://github.com/langchain-ai/langsmith-cookbook/blob/main/testing-examples/qa-correctness/qa-correctness.ipynb
怎样学习AI大模型?
作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将紧张的AI大模型资料包罗AI大模型入门学习头脑导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
这份完备版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】
一、全套AGI大模型学习路线
AI大模型时代的学习之旅:从底子到前沿,把握人工智能的核心技能!
二、640套AI大模型报告合集
这套包罗640份报告的合集,涵盖了AI大模型的理论研究、技能实现、行业应用等多个方面。无论您是科研人员、工程师,照旧对AI大模型感爱好的爱好者,这套报告合集都将为您提供宝贵的信息和启示。
三、AI大模型经典PDF籍
随着人工智能技能的飞速发展,AI大模型已经成为了当今科技范畴的一大热点。这些大型预练习模型,如GPT-3、BERT、XLNet等,以其强盛的语言理解和天生能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。
四、AI大模型商业化落地方案
作为普通人,入局大模型时代需要持续学习和实践,不断进步自己的技能和认知程度,同时也需要有责任感和伦理意识,为人工智能的康健发展贡献气力。
本文转自 https://blog.csdn.net/zhishi0000/article/details/140964285?spm=1001.2014.3001.5501,如有侵权,请联系删除。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |