
Ravi Theja • 2023-12-15
LlamaIndex:RAG 评估对决:GPT-4 vs. 开源 Prometheus 模型
引言
评估是增强检索增强生成(RAG)流程的关键组成部分,传统上依赖于 GPT-4。然而,开源的 Prometheus 模型 最近已成为此类评估任务的重要替代方案。
在这篇博文中,我们将通过与 GPT-4 评估进行比较,演示如何有效地使用 Prometheus 模型进行评估,并将其与 LlamaIndex 框架顺利集成。我们的主要重点将是使用我们的标准指标评估 RAG:正确性(Correctness)、忠实性(Faithfulness)和上下文相关性(Context Relevancy)。为了提供更清晰的理解,以下是每个指标的含义
- 正确性(Correctness):评估生成的答案在给定查询的情况下是否与参考答案一致(这需要标注数据)。
- 忠实性(Faithfulness):衡量答案是否忠实于检索到的上下文,本质上是检查是否存在幻觉。
- 上下文相关性(Context Relevancy):评估检索到的上下文和答案与查询的相关性。
如需深入探索,我们的文档可在此处查阅:here。
对于首次探索 Prometheus 模型的人来说,Andrei 撰写的论文摘要是深入了解的极佳资源。

使用 Prometheus 模型时需要记住的一个关键点是,它在 prompt 中依赖于评分标准分数来进行有效评估。在 正确性评估(Correctness Evaluation)
上下文中,此类评分标准分数的一个示例如下:
###评分标准:分数 1:如果生成的答案与用户查询和参考答案都不相关。分数 2:如果生成的答案与参考答案一致但不与用户查询相关。分数 3:如果生成的答案与用户查询和参考答案相关但包含错误。分数 4:如果生成的答案与用户查询相关并且与参考答案具有完全相同的指标,但不够简洁。分数 5:如果生成的答案与用户查询相关并且完全正确,符合参考答案。
您将在本教程的 prompts 部分找到详细信息。
要详细了解代码,请随时查阅本博客文章附带的 Google Colab Notebook。在该笔记本中,我们对 Paul Graham 论文文本
和 Llama2 论文
进行了评估。然而,对于本博客文章,我们将只关注 Llama2 论文,因为它揭示了一些特别有趣的见解。
大纲
- 设置评估流程。
- 下载数据集。
- 定义评估所需的 LLMs(Prometheus、GPT-4)。
- 定义正确性、忠实性和相关性 prompt 模板。
- 定义 Prometheus、GPT-4 评估器和批量评估运行器。
- 对 Llama2 数据集运行正确性、忠实性和相关性评估。
2. 结果
- Correctness 评估分数在 Prometheus 和 GPT-4 之间的分布。
- Prometheus 和 GPT-4 在正确性评估方面的反馈比较。
- Prometheus 和 GPT-4 的忠实性(Faithfulness)和相关性(Relevancy)评估分数。
- Prometheus 和 GPT-4 之间的汉明距离比较。
- Prometheus 和 GPT-4 在忠实性(Faithfulness)和相关性(Relevancy)方面的反馈比较。
3. 总结与成本分析。
设置评估流程
请注意,此处提及的某些功能在博客文章中未详细定义。我们仅展示了流程的关键部分,以提供其设置概览。如需全面的代码演练,我们建议访问我们的 Google Colab Notebook。
下载数据集
我们将使用 Llama Datasets 中的 Llama2 论文数据集,其中包含 100 个问题及其参考答案。
from llama_index.llama_dataset import download_llama_dataset
llama2_rag_dataset, llama2_documents = download_llama_dataset(
"Llama2PaperDataset", "./data/llama2"
)
定义托管在 HuggingFace 上的 Prometheus LLM 和用于创建索引(RAG)流程的 OpenAI
我们需要在 HF 推理端点上使用 Nvidia A100 GPU,80GB 内存托管模型。
from llama_index.llms import HuggingFaceInferenceAPI
import os
HF_TOKEN = "YOUR HF TOKEN"
HF_ENDPOINT_URL = "HF END POINT URL"
prometheus_llm = HuggingFaceInferenceAPI(
model_name=HF_ENDPOINT_URL,
token=HF_TOKEN,
temperature=0.1,
do_sample=True,
top_p=0.95,
top_k=40,
repetition_penalty=1.1,
)
os.environ["OPENAI_API_KEY"] = "YOUR OPENAI API KEY"
from llama_index.llms import OpenAI
gpt4_llm = OpenAI("gpt-4")
Prompt 模板。
我们将对 Prometheus 模型和 GPT-4 使用相同的 prompts,以进行一致的性能比较。
正确性评估 Prompt
prometheus_correctness_eval_prompt_template = """###Task Description: An instruction (might include an Input inside it), a query, a response to evaluate, a reference answer that gets a score of 5, and a score rubric representing a evaluation criteria are given.
1. Write a detailed feedback that assesses the quality of the response strictly based on the given score rubric, not evaluating in general.
2. After writing a feedback, write a score that is either 1 or 2 or 3 or 4 or 5. You should refer to the score rubric.
3. The output format should look as follows: 'Feedback: (write a feedback for criteria) [RESULT] (1 or 2 or 3 or 4 or 5)'
4. Please do not generate any other opening, closing, and explanations.
5. Only evaluate on common things between generated answer and reference answer. Don't evaluate on things which are present in reference answer but not in generated answer.
###The instruction to evaluate: Your task is to evaluate the generated answer and reference answer for the query: {query}
###Generate answer to evaluate: {generated_answer}
###Reference Answer (Score 5): {reference_answer}
###Score Rubrics:
Score 1: If the generated answer is not relevant to the user query and reference answer.
Score 2: If the generated answer is according to reference answer but not relevant to user query.
Score 3: If the generated answer is relevant to the user query and reference answer but contains mistakes.
Score 4: If the generated answer is relevant to the user query and has the exact same metrics as the reference answer, but it is not as concise.
Score 5: If the generated answer is relevant to the user query and fully correct according to the reference answer.
###Feedback:"""
忠实性评估 Prompt
prometheus_faithfulness_eval_prompt_template= """###Task Description: An instruction (might include an Input inside it), an information, a context, and a score rubric representing evaluation criteria are given.
1. You are provided with evaluation task with the help of information, context information to give result based on score rubrics.
2. Write a detailed feedback based on evaluation task and the given score rubric, not evaluating in general.
3. After writing a feedback, write a score that is YES or NO. You should refer to the score rubric.
4. The output format should look as follows: "Feedback: (write a feedback for criteria) [RESULT] (YES or NO)”
5. Please do not generate any other opening, closing, and explanations.
###The instruction to evaluate: Your task is to evaluate if the given piece of information is supported by context.
###Information: {query_str}
###Context: {context_str}
###Score Rubrics:
Score YES: If the given piece of information is supported by context.
Score NO: If the given piece of information is not supported by context
###Feedback: """
prometheus_faithfulness_refine_prompt_template= """###Task Description: An instruction (might include an Input inside it), a information, a context information, an existing answer, and a score rubric representing a evaluation criteria are given.
1. You are provided with evaluation task with the help of information, context information and an existing answer.
2. Write a detailed feedback based on evaluation task and the given score rubric, not evaluating in general.
3. After writing a feedback, write a score that is YES or NO. You should refer to the score rubric.
4. The output format should look as follows: "Feedback: (write a feedback for criteria) [RESULT] (YES or NO)"
5. Please do not generate any other opening, closing, and explanations.
###The instruction to evaluate: If the information is present in the context and also provided with an existing answer.
###Existing answer: {existing_answer}
###Information: {query_str}
###Context: {context_msg}
###Score Rubrics:
Score YES: If the existing answer is already YES or If the Information is present in the context.
Score NO: If the existing answer is NO and If the Information is not present in the context.
###Feedback: """
相关性评估 Prompt
prometheus_relevancy_eval_prompt_template = """###Task Description: An instruction (might include an Input inside it), a query with response, context, and a score rubric representing evaluation criteria are given.
1. You are provided with evaluation task with the help of a query with response and context.
2. Write a detailed feedback based on evaluation task and the given score rubric, not evaluating in general.
3. After writing a feedback, write a score that is YES or NO. You should refer to the score rubric.
4. The output format should look as follows: "Feedback: (write a feedback for criteria) [RESULT] (YES or NO)”
5. Please do not generate any other opening, closing, and explanations.
###The instruction to evaluate: Your task is to evaluate if the response for the query is in line with the context information provided.
###Query and Response: {query_str}
###Context: {context_str}
###Score Rubrics:
Score YES: If the response for the query is in line with the context information provided.
Score NO: If the response for the query is not in line with the context information provided.
###Feedback: """
prometheus_relevancy_refine_prompt_template = """###Task Description: An instruction (might include an Input inside it), a query with response, context, an existing answer, and a score rubric representing a evaluation criteria are given.
1. You are provided with evaluation task with the help of a query with response and context and an existing answer.
2. Write a detailed feedback based on evaluation task and the given score rubric, not evaluating in general.
3. After writing a feedback, write a score that is YES or NO. You should refer to the score rubric.
4. The output format should look as follows: "Feedback: (write a feedback for criteria) [RESULT] (YES or NO)"
5. Please do not generate any other opening, closing, and explanations.
###The instruction to evaluate: Your task is to evaluate if the response for the query is in line with the context information provided.
###Query and Response: {query_str}
###Context: {context_str}
###Score Rubrics:
Score YES: If the existing answer is already YES or If the response for the query is in line with the context information provided.
Score NO: If the existing answer is NO and If the response for the query is in line with the context information provided.
###Feedback: """
定义正确性、忠实性、相关性评估器
from llama_index import ServiceContext
from llama_index.evaluation import (
CorrectnessEvaluator,
FaithfulnessEvaluator,
RelevancyEvaluator,
)
from llama_index.callbacks import CallbackManager, TokenCountingHandler
import tiktoken
# Provide Prometheus model in service_context
prometheus_service_context = ServiceContext.from_defaults(llm=prometheus_llm)
# CorrectnessEvaluator with Prometheus model
prometheus_correctness_evaluator = CorrectnessEvaluator(
service_context=prometheus_service_context,
parser_function=parser_function,
eval_template=prometheus_correctness_eval_prompt_template,
)
# FaithfulnessEvaluator with Prometheus model
prometheus_faithfulness_evaluator = FaithfulnessEvaluator(
service_context=prometheus_service_context,
eval_template=prometheus_faithfulness_eval_prompt_template,
refine_template=prometheus_faithfulness_refine_prompt_template,
)
# RelevancyEvaluator with Prometheus model
prometheus_relevancy_evaluator = RelevancyEvaluator(
service_context=prometheus_service_context,
eval_template=prometheus_relevancy_eval_prompt_template,
refine_template=prometheus_relevancy_refine_prompt_template,
)
# Set the encoding model to `gpt-4` for token counting.
token_counter = TokenCountingHandler(
tokenizer=tiktoken.encoding_for_model("gpt-4").encode
)
callback_manager = CallbackManager([token_counter])
# Provide GPT-4 model in service_context
gpt4_service_context = ServiceContext.from_defaults(
llm=gpt4_llm, callback_manager=callback_manager
)
# CorrectnessEvaluator with GPT-4 model
gpt4_correctness_evaluator = CorrectnessEvaluator(
service_context=gpt4_service_context,
# parser_function=parser_function,
)
# FaithfulnessEvaluator with GPT-4 model
gpt4_faithfulness_evaluator = FaithfulnessEvaluator(
service_context=gpt4_service_context,
eval_template=prometheus_faithfulness_eval_prompt_template,
refine_template=prometheus_faithfulness_refine_prompt_template,
)
# RelevancyEvaluator with GPT-4 model
gpt4_relevancy_evaluator = RelevancyEvaluator(
service_context=gpt4_service_context,
eval_template=prometheus_relevancy_eval_prompt_template,
refine_template=prometheus_relevancy_refine_prompt_template,
)
# create a dictionary of evaluators
prometheus_evaluators = {
"correctness": prometheus_correctness_evaluator,
"faithfulness": prometheus_faithfulness_evaluator,
"relevancy": prometheus_relevancy_evaluator,
}
gpt4_evaluators = {
"correctness": gpt4_correctness_evaluator,
"faithfulness": gpt4_faithfulness_evaluator,
"relevancy": gpt4_relevancy_evaluator,
}
在定义的评估器上运行批量评估的函数
from llama_index.evaluation import BatchEvalRunner
async def batch_eval_runner(
evaluators, query_engine, questions, reference=None, num_workers=8
):
batch_runner = BatchEvalRunner(
evaluators, workers=num_workers, show_progress=True
)
eval_results = await batch_runner.aevaluate_queries(
query_engine, queries=questions, reference=reference
)
return eval_results
获取查询引擎、问题和参考答案。
query_engine, rag_dataset = create_query_engine_rag_dataset("./data/llama2")
questions = [example.query for example in rag_dataset.examples]
reference = [[example.reference_answer] for example in rag_dataset.examples]
计算正确性、忠实性和相关性评估结果。
prometheus_eval_results = await batch_eval_runner(
prometheus_evaluators, query_engine, questions, reference
)
gpt4_eval_results = await batch_eval_runner(
gpt4_evaluators, query_engine, questions, reference
)
结果
正确性评估分数分布。
使用 Prometheus 模型
3.0: 56.0, 1.0: 26.0, 5.0: 9.0, 4.0: 8.0, 2.0: 1.0
使用 GPT-4 模型
4.5: 57.99, 1.0: 6.0, 4.0: 12.0, 5.0: 10.0, 2.0: 5.0, 3.5: 5.0, 2.5: 3.0, 3.0: 1.0
观察
与给出 4.5
的 GPT-4 相比,Prometheus 评估器给出更多的 3.0
分数。让我们借助反馈来调查原因。
Prometheus 和 GPT-4 在正确性方面的反馈比较。
查询: 根据《Llama 2:开放基础和微调聊天模型》的摘要,这项工作实现了哪两个主要目标?以及所开发的大型语言模型的参数范围是多少?
生成的答案: 这项工作实现的两个主要目标是开发和发布 Llama 2,这是一个预训练和微调大型语言模型(LLMs)的集合,以及为对话用例优化这些模型。所开发的大型语言模型的参数范围是 70 亿到 700 亿。
参考答案: 《Llama 2:开放基础和微调聊天模型》摘要中描述的工作实现的两个主要目标是:1. 开发和发布一个专门为对话用例优化的预训练和微调大型语言模型(LLMs)集合。2. 证明这些被称为 Llama 2-Chat 的微调 LLMs 在我们测试的大多数基准测试中优于开源聊天模型,并且可能是闭源模型的合适替代品,尤其是在基于人类评估的有用性和安全性方面。这项工作开发的大型语言模型的参数范围是 70 亿到 700 亿参数。
Prometheus 反馈: 生成的响应与用户查询相关,并正确识别了《Llama 2:开放基础和微调聊天模型》摘要中描述工作的两个主要目标。然而,它没有提及微调 LLMs 在我们测试的大多数基准测试中优于开源聊天模型的证明,这是参考响应中的一个关键点。所开发的大型语言模型的参数范围正确识别,但响应没有提及被称为 Llama 2-Chat 的特定模型。因此总体得分为 3 分。
Prometheus 得分: 3.0
GPT-4 反馈: 生成的答案相关且几乎完全正确。它正确地识别了两个主要目标和大型语言模型的参数范围。然而,它遗漏了关于 Llama 2-Chat 在大多数基准测试中优于其他模型并可能是闭源模型的合适替代品的细节。
GPT-4 得分: 4.5
观察
与 GPT-4 相比,Prometheus 的反馈稍显精确,它会进行更严格的惩罚并给出 3.0
分,而 GPT-4 给出 4.5
分。即使生成的答案中遗漏了参考答案中的一些文本,Prometheus 的惩罚也更重。
忠实性(Faithfulness)和相关性(Relevancy)评估分数。
使用 Prometheus 模型
忠实性得分:0.39 相关性得分:0.57
使用 GPT-4 模型
忠实性得分:0.93 相关性得分:0.98
观察
我们看到 GPT-4 的忠实性和相关性得分高于 Prometheus 模型。让我们通过反馈来调查原因。
Prometheus 和 GPT-4 之间的汉明距离比较
忠实性汉明距离:58 相关性汉明距离:41
观察
比较结果显示,在 忠实性(Faithfulness)
方面,Prometheus 和 GPT-4 评估的分数大约有 42%
是相同的;在 相关性(Relevancy)
方面,大约有 59%
是相同的。这表明 Prometheus 和 GPT-4 模型在忠实性和相关性评分方面存在相当程度的相关性。
Prometheus 和 GPT-4 在忠实性(Faithfulness)和相关性(Relevancy)方面的反馈比较。
查询: 根据《Llama 2:开放基础和微调聊天模型》的摘要,这项工作实现了哪两个主要目标?以及所开发的大型语言模型的参数范围是多少?生成的答案:这项工作实现的两个主要目标是开发和发布 Llama 2,这是一个预训练和微调大型语言模型(LLMs)的集合,以及为对话用例优化这些模型。所开发的大型语言模型的参数范围是 70 亿到 700 亿。
上下文 1: Llama 2:开放基础和微调聊天模型 Hugo Touvron∗Louis Martin†Kevin Stone† Peter Albert Amjad Almahairi Yasmine Babaei Nikolay Bashlykov Soumya Batra Prajjwal Bhargava Shruti Bhosale Dan Bikel Lukas Blecher Cristian Canton Ferrer Moya Chen Guillem Cucurull David Esiobu Jude Fernandes Jeremy Fu Wenyin Fu Brian Fuller Cynthia Gao Vedanuj Goswami Naman Goyal Anthony Hartshorn Saghar Hosseini Rui Hou Hakan Inan Marcin Kardas Viktor Kerkez Madian Khabsa Isabel Kloumann Artem Korenev Punit Singh Koura Marie-Anne Lachaux Thibaut Lavril Jenya Lee Diana Liskovich Yinghai Lu Yuning Mao Xavier Martinet Todor Mihaylov Pushkar Mishra Igor Molybog Yixin Nie Andrew Poulton Jeremy Reizenstein Rashi Rungta Kalyan Saladi Alan Schelten Ruan Silva Eric Michael Smith Ranjan Subramanian Xiaoqing Ellen Tan Binh Tang Ross Taylor Adina Williams Jian Xiang Kuan Puxin Xu Zheng Yan Iliyan Zarov Yuchen Zhang Angela Fan Melanie Kambadur Sharan Narang Aurelien Rodriguez Robert Stojnic Sergey Edunov Thomas Scialom∗ GenAI, Meta 摘要 在这项工作中,我们开发并发布了 Llama 2,这是一个预训练和微调大型语言模型(LLMs)的集合,规模从 70 亿到 700 亿参数不等。我们的微调 LLMs,称为 Llama 2-Chat,针对对话用例进行了优化。我们的模型在我们测试的大多数基准测试中优于开源聊天模型,并且基于我们对有用性和安全性的主观评估,可能是闭源模型的合适替代品。我们详细描述了我们对 Llama 2-Chat 进行微调和安全改进的方法,以便社区可以在我们的工作基础上进行构建,并为 LLMs 的负责任开发做出贡献。 ∗同等贡献,通讯作者:{tscialom, htouvron}@meta.com †第二作者 所有作者的贡献可以在 A.1 节中找到。arXiv:2307.09288v2 [cs.CL] 2023 年 7 月 19 日
上下文 2: (2021) 也阐明了与面向聊天机器人的 LLMs 相关的困难,关注点从隐私到误导性专业知识声明不等。Deng 等人 (2023) 提出了一个分类框架来解决这些问题,Bergman 等人 (2022) 深入探讨了发布对话模型可能带来的积极和消极影响之间的平衡。红队演习的调查揭示了微调 LLMs 中的特定挑战,Ganguli 等人 (2022) 和 Zhuo 等人 (2023) 的研究展示了各种成功的攻击类型及其对有害内容生成的影响。国家安全机构和各种研究人员,例如 (Mialon 等人, 2023),也对先进的涌现模型行为、网络威胁以及在生物战等领域的潜在误用发出了警告。最后,更广泛的社会问题,如由于加速的 AI 研究导致的失业以及对 LLMs 的过度依赖导致训练数据退化,也是相关的考虑因素 (Acemoglu 和 Restrepo, 2018; Autor 和 Salomons, 2018; Webb, 2019; Shumailov 等人, 2023)。我们致力于继续与更广泛的政策、学术和行业社区就这些问题进行合作。7 结论 在这项研究中,我们介绍了 Llama 2,这是一个新的预训练和微调模型家族,规模从 70 亿到 700 亿参数不等。这些模型在我们检查的评估集上表现出了与现有开源聊天模型的竞争力,以及与某些专有模型相当的能力,尽管它们仍然落后于 GPT-4 等其他模型。我们详细阐述了实现我们的模型所应用的方法和技术,重点强调它们与有用性和安全原则的契合。为了更显著地贡献社会并促进研究进展,我们负责任地开放了对 Llama 2 和 Llama 2-Chat 的访问。作为我们持续致力于透明度和安全性的一部分,我们计划在未来的工作中对 Llama 2-Chat 进行进一步改进。36
Prometheus 忠实性反馈: 上下文中提供的信息不受给定信息的支持。上下文是关于 Llama 2 的开发和发布,这是一个预训练和微调大型语言模型(LLMs)的集合,以及为对话用例优化这些模型。然而,上下文中提供的信息与给定的信息不符。上下文没有提及所开发的大型语言模型的参数范围,而这是信息中提到的主要目标。上下文只讨论了 Llama 2 的开发和发布以及其对话用例的优化,但没有提供关于所开发的大型语言模型参数范围的任何信息。因此总体得分是 NO。[结果] NO
Prometheus 忠实性得分 0.0
Prometheus 相关性反馈: 响应与提供的上下文信息不一致。查询要求获得该工作实现的两个主要目标以及所开发的大型语言模型的参数范围。然而,响应提供了论文摘要并提及了作者,这与查询无关。响应也没有提及该工作实现的两个主要目标或所开发的大型语言模型的参数范围。因此总体得分为 NO。[结果] NO
Prometheus 相关性得分 0.0
GPT-4 忠实性反馈: 给定的信息得到了上下文的充分支持。上下文明确指出,Llama 2,一个预训练和微调大型语言模型(LLMs)的集合,已被开发和发布。它还提及这些模型的规模从 70 亿到 700 亿参数不等。此外,上下文证实这些模型针对对话用例进行了优化。因此,提供的信息是准确的,并得到了上下文的证实。[结果] YES
GPT-4 忠实性得分 1.0
GPT-4 相关性反馈: 响应准确反映了提供的上下文。响应正确地识别了该工作的两个主要目标,即开发和发布 Llama 2,一个预训练和微调大型语言模型(LLMs)的集合,以及为对话用例优化这些模型。这与上下文中摘要提供的信息一致。响应还正确地说明了所开发的大型语言模型的参数范围为 70 亿到 700 亿,这也得到了上下文的证实。因此,响应与提供的上下文信息一致。[结果] YES
GPT-4 相关性得分 1.0
观察
- Prometheus:如果您比较反馈和上下文,上下文中和响应中都提到了参数范围,但反馈却说模型找不到此类信息。
- GPT-4:与 Prometheus 模型不同,它评估正确。
总结
- 评估成本(约):Prometheus 模型
$1.5
,GPT4$15
。 - Prometheus 模型虽然提供了比 GPT-4 更详细的反馈,但偶尔也会提供不正确的反馈,因此需要谨慎使用。
- 如果生成的答案缺少参考答案中存在的某些事实,Prometheus 模型对得分的惩罚比 GPT-4 更严格。
- 与 GPT-4 相比,Prometheus 的忠实性和相关性反馈中表现出更多的幻觉/错误解释。
注意
- 您可以在 Google Colab Notebook 上查看包含代码的详细分析。
- HF 上的端点部署在 AWS Nvidia A100G · 1x GPU · 80 GB 上,费用为 $6.5/小时。(我们感谢 Hugging Face 团队在我们遇到问题时提供的帮助。)
- 我们在此分析中使用了 Prometheus 模型。我们也使用 Prometheus 模型 的 GPTQ 量化版本 进行了类似分析,并观察到与原始非量化模型相比,反馈中存在更多幻觉。感谢论文作者开源该模型,以及 Tom Jobbins 提供了该模型的量化版本。