从 LlamaHub 下载 LlamaDataset¶
您可以通过 llamahub.ai 浏览我们可用的基准数据集。本 notebook 指南介绍了如何下载数据集及其源文本文档。特别是,download_llama_dataset
将下载评估数据集(即 LabelledRagDataset
)以及用于构建原始评估数据集的源文本文件的 Document
。
最后,在本 notebook 中,我们还演示了下载评估数据集、使用您自己的 RAG 管线(查询引擎)对其进行预测,然后评估这些预测的端到端工作流。
%pip install llama-index-llms-openai
from llama_index.core.llama_dataset import download_llama_dataset
# download and install dependencies
rag_dataset, documents = download_llama_dataset(
"PaulGrahamEssayDataset", "./paul_graham"
)
github url: https://raw.githubusercontent.com/nerdai/llama-hub/datasets/llama_hub/llama_datasets/library.json github url: https://media.githubusercontent.com/media/run-llama/llama_datasets/main/llama_datasets/paul_graham_essay/rag_dataset.json github url: https://media.githubusercontent.com/media/run-llama/llama_datasets/main/llama_datasets/paul_graham_essay/source.txt
rag_dataset.to_pandas()[:5]
查询 | 参考上下文 | 参考答案 | 参考答案来源 | 查询来源 | |
---|---|---|---|---|---|
0 | 在文章中,作者提到了他早期的经历... | [我在做什么 2021 年 2 月 在做...之前] |
作者用于编程的第一台计算机... | ai (gpt-4) | ai (gpt-4) |
1 | 作者将其专业从哲学转为... | [我在做什么 2021 年 2 月 在做...之前] |
导致作者的两个具体影响是... | ai (gpt-4) | ai (gpt-4) |
2 | 在文章中,作者讨论了他最初的... | [我当时无法用言语表达...的时候] | 最初吸引作者的两个主要影响是... | ai (gpt-4) | ai (gpt-4) |
3 | 作者提到他将兴趣转向了... | [我当时无法用言语表达...的时候] | 作者将兴趣转向 Lisp 和... | ai (gpt-4) | ai (gpt-4) |
4 | 在文章中,作者提到了他对...的兴趣 | [所以我四处看看我能挽救什么...] | 文章中的作者是 Paul Graham,他当时... | ai (gpt-4) | ai (gpt-4) |
有了 documents
,您可以构建自己的 RAG 管线,然后进行预测并执行评估,以与 llamahub.ai 上与数据集关联的 DatasetCard
中列出的基准进行比较。
预测¶
注意:notebook 的其余部分说明了如何手动执行预测和后续评估,仅用于演示目的。或者,您可以使用 RagEvaluatorPack
,它将负责使用您提供的 RAG 系统进行预测和评估。
from llama_index.core import VectorStoreIndex
# a basic RAG pipeline, uses defaults
index = VectorStoreIndex.from_documents(documents=documents)
query_engine = index.as_query_engine()
您现在可以手动创建预测并执行评估,或者下载 PredictAndEvaluatePack
,只需一行代码即可为您完成此操作。
import nest_asyncio
nest_asyncio.apply()
# manually
prediction_dataset = await rag_dataset.amake_predictions_with(
query_engine=query_engine, show_progress=True
)
100%|███████████████████████████████████████████████████████| 44/44 [00:08<00:00, 4.90it/s]
prediction_dataset.to_pandas()[:5]
响应 | 上下文 | |
---|---|---|
0 | 作者提到他使用的第一台计算机... | [我在做什么 2021 年 2 月 在做...之前] |
1 | 作者将其专业从哲学转为... | [我当时无法用言语表达...的时候] |
2 | 作者提到最初影响他的两个主要因素是... | [我当时无法用言语表达...的时候] |
3 | 作者提到他将兴趣转向了... | [所以我四处看看我能挽救什么...] |
4 | 作者提到他对计算机和...都有兴趣 | [我在做什么 2021 年 2 月 在做...之前] |
评估¶
现在我们有了预测结果,我们可以从两个维度进行评估
- 生成的响应:预测的响应与参考答案的匹配程度。
- 检索到的上下文:预测的检索到的上下文与参考上下文的匹配程度。
注意:对于检索到的上下文,我们无法使用标准的检索指标,例如 命中率 (hit rate)
和 平均倒数排名 (mean reciproccal rank)
,因为这需要我们拥有与生成地面真实数据所使用的索引相同的索引。然而,LabelledRagDataset
甚至不必由索引创建。因此,我们将使用预测的上下文和参考上下文之间的 语义相似度 (semantic similarity)
作为衡量优劣的标准。
import tqdm
为了评估响应,我们将使用 LLM-As-A-Judge 模式。具体来说,我们将使用 CorrectnessEvaluator
、FaithfulnessEvaluator
和 RelevancyEvaluator
。
为了评估检索到的上下文的优劣,我们将使用 SemanticSimilarityEvaluator
。
# instantiate the gpt-4 judge
from llama_index.llms.openai import OpenAI
from llama_index.core.evaluation import (
CorrectnessEvaluator,
FaithfulnessEvaluator,
RelevancyEvaluator,
SemanticSimilarityEvaluator,
)
judges = {}
judges["correctness"] = CorrectnessEvaluator(
llm=OpenAI(temperature=0, model="gpt-4"),
)
judges["relevancy"] = RelevancyEvaluator(
llm=OpenAI(temperature=0, model="gpt-4"),
)
judges["faithfulness"] = FaithfulnessEvaluator(
llm=OpenAI(temperature=0, model="gpt-4"),
)
judges["semantic_similarity"] = SemanticSimilarityEvaluator()
遍历 (labelled_example
, prediction
) 对,并对它们中的每一个单独执行评估。
evals = {
"correctness": [],
"relevancy": [],
"faithfulness": [],
"context_similarity": [],
}
for example, prediction in tqdm.tqdm(
zip(rag_dataset.examples, prediction_dataset.predictions)
):
correctness_result = judges["correctness"].evaluate(
query=example.query,
response=prediction.response,
reference=example.reference_answer,
)
relevancy_result = judges["relevancy"].evaluate(
query=example.query,
response=prediction.response,
contexts=prediction.contexts,
)
faithfulness_result = judges["faithfulness"].evaluate(
query=example.query,
response=prediction.response,
contexts=prediction.contexts,
)
semantic_similarity_result = judges["semantic_similarity"].evaluate(
query=example.query,
response="\n".join(prediction.contexts),
reference="\n".join(example.reference_contexts),
)
evals["correctness"].append(correctness_result)
evals["relevancy"].append(relevancy_result)
evals["faithfulness"].append(faithfulness_result)
evals["context_similarity"].append(semantic_similarity_result)
44it [07:15, 9.90s/it]
import json
# saving evaluations
evaluations_objects = {
"context_similarity": [e.dict() for e in evals["context_similarity"]],
"correctness": [e.dict() for e in evals["correctness"]],
"faithfulness": [e.dict() for e in evals["faithfulness"]],
"relevancy": [e.dict() for e in evals["relevancy"]],
}
with open("evaluations.json", "w") as json_file:
json.dump(evaluations_objects, json_file)
现在,我们可以使用 notebook 的实用函数来查看这些评估结果。
import pandas as pd
from llama_index.core.evaluation.notebook_utils import get_eval_results_df
deep_eval_df, mean_correctness_df = get_eval_results_df(
["base_rag"] * len(evals["correctness"]),
evals["correctness"],
metric="correctness",
)
deep_eval_df, mean_relevancy_df = get_eval_results_df(
["base_rag"] * len(evals["relevancy"]),
evals["relevancy"],
metric="relevancy",
)
_, mean_faithfulness_df = get_eval_results_df(
["base_rag"] * len(evals["faithfulness"]),
evals["faithfulness"],
metric="faithfulness",
)
_, mean_context_similarity_df = get_eval_results_df(
["base_rag"] * len(evals["context_similarity"]),
evals["context_similarity"],
metric="context_similarity",
)
mean_scores_df = pd.concat(
[
mean_correctness_df.reset_index(),
mean_relevancy_df.reset_index(),
mean_faithfulness_df.reset_index(),
mean_context_similarity_df.reset_index(),
],
axis=0,
ignore_index=True,
)
mean_scores_df = mean_scores_df.set_index("index")
mean_scores_df.index = mean_scores_df.index.set_names(["metrics"])
mean_scores_df
RAG | base_rag |
---|---|
指标 | |
平均正确性得分 | 4.238636 |
平均相关性得分 | 0.977273 |
平均忠实度得分 | 0.977273 |
平均上下文相似度得分 | 0.933568 |
在这个玩具示例中,我们看到基本 RAG 管线在评估基准 (rag_dataset
) 下表现相当不错!为了完整性,若要改用 RagEvaluatorPack
执行上述步骤,请使用下面提供的代码
from llama_index.core.llama_pack import download_llama_pack
RagEvaluatorPack = download_llama_pack("RagEvaluatorPack", "./pack")
rag_evaluator = RagEvaluatorPack(
query_engine=query_engine, rag_dataset=rag_dataset, show_progress=True
)
############################################################################
# NOTE: If have a lower tier subscription for OpenAI API like Usage Tier 1 #
# then you'll need to use different batch_size and sleep_time_in_seconds. #
# For Usage Tier 1, settings that seemed to work well were batch_size=5, #
# and sleep_time_in_seconds=15 (as of December 2023.) #
############################################################################
benchmark_df = await rag_evaluator_pack.arun(
batch_size=20, # batches the number of openai api calls to make
sleep_time_in_seconds=1, # seconds to sleep before making an api call
)