对 RAG 概念验证阶段的性能评估实践

240 阅读3分钟

RAG 在概念验证阶段(POC)应该做一个性能评估,确定生成的回答是否能满足用户最基本需求。

在数据源确定的情况下和客户创建一个数据集,包括:

  • 问题
  • 问题对应数据源的数据块
  • 答案

然后通过数据集测试 RAG 原型评估是否可行。

如果可行,再进行后续开发。而不是完成开发主要阶段后,再调试或者重新开发 RAG 核心部分。

本文后续将:

  • 通过 LlamaIndex 实现一个简易的 RAG 系统
  • 给出一个示意性的测试数据集
  • 通过 Ragas 实现对检索和生成回答的评估

完整的代码见Jupyterlab 笔记 jupyterlab-demos /ragas-rag-poc-eval.ipynb (JupyterLab 环境搭建可参考 在 4GB 显存下运行 LLM 基础开发环境)

评估效果:

Kapture 2024-08-08 at 11.44.32.gif

创建简易的 RAG

这是一个针对北京旅游景点的 RAG,数据来源于百度百科,这里只加载一个条目,北海公园

item="北海公园"

documents = TrafilaturaWebReader().load_data(
    [ f"https://baike.baidu.com/item/{item}" ]
)

RAG 使用本地 LLM qwen2:7b,嵌入模型 bge-large-zh-v1.5,并且设置了分块参数:

Settings.llm=OpenAILike(
    model="qwen2", 
    ..
)

Settings.embed_model = OllamaEmbedding(
    model_name="quentinz/bge-large-zh-v1.5",
    ..
)

Settings.chunk_size = 128
Settings.chunk_overlap = 10

这里 LLM 加载使用了 Ollama 和 one-api,环境搭建同样参见 在 4GB 显存下运行 LLM 基础开发环境

创建索引没有用到向量数据库,使用 LlamaIndex 默认的内存实现:

vector_index = VectorStoreIndex.from_documents(documents)
query_engine = vector_index.as_query_engine(streaming=True)

测试下运行效果:

Kapture 2024-08-08 at 12.46.55.gif

创建数据集

创建有真实答案的数据集,用于对 RAG 检索和回答的测试评估。

data_samples = {
    'question': ['北海公园在哪里?', ],
    'contexts' : ['北海公园(Beihai Park),位于北京市西城区文津街1号,东邻景山公园,南濒中南海,北连什刹海,全园占地68.2万平方米(其中水域面积38.9万平方米,陆地面积29.3万平方米),1925年开放为公园。'],
    'ground_truth': ['北海公园位于北京市西城区文津街1号,东邻景山公园,南濒中南海,北连什刹海。'],
    
}

显示在表格里:

image.png

使用 Ragas

设置评估用 LLM,应该选择尽量好的模型,比如 gpt-4-turbo,这里做演示,就使用 gpt-3.5-turbo 了:

%%time

evaluator_llm = OpenAILike(
    model="gpt-3.5-turbo", 
    ..
)

使用 Ragas 做评估:

metrics = [
    faithfulness,
    answer_relevancy,
    context_precision,
    context_recall,
    harmfulness,
]

result = evaluate(
    query_engine=vector_index.as_query_engine(),
    metrics=metrics,
    dataset=data_samples,
    llm=evaluator_llm,
    embeddings=Settings.embed_model,
)

Ragas 评估主要分2方面4个指标:

  • 针对 LLM 生成内容
    • faithfulness,回答忠实性,生成答案的事实准确性
    • answer relevancy,答案相关性,生成的答案与问题的相关程度
  • 针对检索上下文内容
    • context precision,检索到的上下文精度
    • context recall,是否检索到回答问题所需的所有相关信息

可以从pandas的列表查看每个测试的评分,这里只有一个测试:

image.png

最重要的是总的评分, 是对所有测试的汇总:

image.png

可以看到各项都很好,唯独 answer_relevancy 只有 0.55,这是因为真实答案更长:

北海公园位于北京市西城区文津街1号,东邻景山公园,南濒中南海,北连什刹海。

如果有大量的测试,比如至少要大于 30 个,一般会到一百以上,这个汇总处理的平均值可能并不低。

总结

  • RAG 核心部分代码应该先实现,然后做性能评估
  • 性能评估符合预期,再进行后续周边的开发
  • 这里介绍了 Ragas 做 POC 阶段的性能评估
  • Ragas 还可以在其他阶段运用,甚至在生产运行时