立即下载 DOCA,开启高性能AI 网络之旅,实现“一站式” 编程
对话式人工智能

使用 NVIDIA AI 端点和 Ragas 对医疗 RAG 的评估分析

在快速发展的医学领域,尖端技术的集成对于增强患者护理和推进研究至关重要。其中一项创新是 检索增强生成(RAG),它正在改变医疗信息的处理和使用方式。

RAG 将 大语言模型 (LLMs) 的功能与外部知识检索相结合,解决了信息过时和生成不准确数据(称为“幻觉”)等关键限制。通过从结构化数据库、科学文献和患者记录中检索最新的相关信息,RAG 为医疗应用提供了更准确、更符合情境感知的基础。这种混合方法提高了生成输出的准确性和可靠性,并增强了可解释性,使其成为药物研发和临床试验筛选等领域的重要工具。

随着我们继续探索 RAG 在医学领域 的潜力,必须严格评估其性能,同时考虑检索和生成组件,以确保在医疗应用中实现更高的准确性和相关性标准。医疗 RAG 系统具有独特的需求和要求,这凸显了对全面评估框架的需求,这些框架可以有力地解决这些问题。

在本文中,我将向您展示如何使用 LangChain NVIDIA AI 端点和 Ragas 应对医疗评估挑战。您将使用 MACCROBAT 数据集 ,这是一个来自 PubMed Central 的详细患者医疗报告数据集,其中包含精心注释的信息。

医疗 RAG 的挑战 

可扩展性是一项主要挑战。随着 medical data grows at a CAGR of >35%,RAG 系统必须在不影响速度或准确性的情况下高效处理和检索相关信息。这在实时应用中至关重要,因为及时访问信息会直接影响患者护理。

医疗应用程序所需的特定语言和知识可能与其他领域(例如法律或金融领域)大不相同,这限制了系统的通用性,并需要对特定领域进行调整。

另一个关键挑战是缺乏医疗 RAG 基准,以及该领域通用的评估指标不足。缺乏基准需要根据医疗文本和健康记录生成合成测试和真实数据。

BLEU 或 ROUGE 等传统指标专注于文本相似性,无法充分捕捉 RAG 系统的细微性能。这些指标通常无法反映生成内容的事实准确性和上下文相关性,而事实准确性和上下文相关性在医疗应用中至关重要。

最后,评估 RAG 系统还需要独立地评估检索和生成组件,以及整体评估。检索组件必须评估其从庞大且动态的知识库中获取相关和最新信息的能力。这包括测量精度、召回率和相关性,同时还考虑信息的时间方面。

生成组件由大语言模型提供支持,必须评估其生成内容的真实性和准确性,确保其与检索到的数据和原始查询保持一致。

总体而言,这些挑战凸显了对全面评估框架的需求,这些框架可以满足医疗 RAG 系统的独特需求,确保这些系统提供准确、可靠且适合上下文的信息。

什么是 Ragas?

Ragas (检索增强型生成评估) 是一种热门的开源自动评估框架,旨在评估 RAG 工作流。

Ragas 框架提供了用于评估这些流程性能的 工具和指标 ,重点关注上下文相关性、上下文召回、忠实性和答案相关性等方面。它采用 LLM-as-a-judge 进行无参考评估,从而最大限度地减少对人工标注数据的需求,并提供类似人工标注的反馈,从而提高评估流程的效率和成本效益。

RAG 评估策略 

RAG 稳健评估的典型策略如下所示:

  1. 根据向量存储中的文档生成一组合成生成的三元组(问题-答案-上下文)。
  2. 通过在 RAG 中运行每个样本问题,并将响应和上下文与基准真值进行比较,为每个样本问题运行评估精度/召回指标。
  3. 过滤掉低质量的合成样本。
  4. 在实际 RAG 上运行示例查询,并使用合成上下文和响应作为真值的指标进行评估。
Diagram shows a question, such as ‘What are typical BP measurements in the case of congestive heart failure?” The system asks whether the retrieved context is relevant to the question and then whether the retrieved context contains information relevant to the question. The response might start with something like, “While normal blood pressure is generally considered below 120/80 mmHg, heart failure patients often require careful management within a target range….” The system then asks if the response is accurate and relevant to the question.
图 1. RAG 和搜索系统的评估组件流

要充分利用本教程,您需要了解 LLM 推理管道的基本知识。

设置 

首先,使用 NVIDIA API Catalog 创建一个免费帐户,并按照以下步骤操作:

  1. 选择任意型号。
  2. 选择 Python, 获取 API 密钥
  3. 将生成的密钥另存为 NVIDIA_API_KEY

从那里,您应该可以访问端点。

现在,安装 LangChain、NVIDIA AI 端点和 Ragas:

pip install langchain
pip install langchain_nvidia_ai_endpoints
pip install ragas

下载医疗数据集 

接下来,下载 Kaggle MACCROBAT 数据集 。您可以直接从 Kaggle 下载数据集(需要 Kaggle API 令牌),也可以使用 Hugging Face /MACCROBAT_biomedical_ner 版本

在这篇博文中,您使用医疗报告的完整文本,而忽略 NER 注释:

from langchain_community.document_loaders import HuggingFaceDatasetLoader
from datasets import load_dataset

dataset_name = "singh-aditya/MACCROBAT_biomedical_ner"
page_content_column = "full_text"

loader = HuggingFaceDatasetLoader(dataset_name, page_content_column)
dataset = loader.load()

生成合成数据 

RAG 评估的主要挑战之一是生成合成数据。这是进行稳健评估所必需的,因为您想在与向量数据库中的数据相关的问题上测试 RAG 系统。

此方法的一个主要优势是,它支持广泛测试,同时不需要昂贵的人工标注数据。一组 LLMs(generatorcriticembedding)用于根据相关数据生成代表性合成数据。Ragas 默认使用 OpenAI,因此您可以覆盖此选项,转而使用 NVIDIA AI 端点。

from ragas.testset.generator import TestsetGenerator
from ragas.testset.evolutions import simple
from langchain_nvidia_ai_endpoints import ChatNVIDIA, NVIDIAEmbeddings

critic_llm = ChatNVIDIA(model="meta/llama3.1-8b-instruct")
generator_llm = ChatNVIDIA(model="mistralai/mixtral-8x7b-instruct-v0.1")
embeddings = NVIDIAEmbeddings(model="nv-embedqa-e5-v5", truncate="END")

generator = TestsetGenerator.from_langchain(
     generator_llm,
     critic_llm,
     embeddings,
     chunk_size=512
)

# generate testset
testset = generator.generate_with_langchain_docs(dataset,  test_size=10, is_async=False, raise_exceptions=False, distributions={simple: 1.0})
Diagram showing an evaluation pipeline for medical RAG, consisting of input from the EHR database; synthetic questions, answers, and contexts; and output and metrics.
图 2 医疗 RAG 评估系统流程图

根据 MACCROBAT 数据集 中的医疗报告,在向量存储上部署代码。这将根据向量存储中的实际文档生成样本问题列表。

[“What are typical BP measurements in the case of congestive heart failure?”,
“What can scans reveal in patients with severe acute pain in the periumbilical region?”
“Is surgical intervention required for the treatment of a metachronous solitary liver metastasis?”  
“What are the most effective procedures for detecting gastric cancer?”]

此外,每个问题都与检索到的上下文和生成的真值答案相关联,您稍后可以使用这些答案独立评估和分级医疗 RAG 的检索和生成组件。

评估输入数据

现在,您可以将合成数据用作评估的输入数据。使用生成的问题(question)和回答(ground_truth),以及从医疗 RAG 系统检索到的实际上下文(contexts)及其相应回答(answer),填充输入数据。

在此代码示例中,您将评估特定于生成的指标(answer_relevancyfaithfulness)。

   # answer relevance and faithfulness metrics ignore ground truth, so just fill it with empty values
    ground_truth = ['']*len(queries)
    answers = []
    contexts = []

    # Run queries in search endpoint and collect context and results 
    for query in queries:
        json_data = query_rag(query)

        response =json_data['results'][0]['answer']
        answers.append(response)
  
        seq_str = []
        seq_str.append(json_data['results'][0]['retrieved _document_context'])
        contexts.append(seq_str)

    # Store all data in HF dataset for RAGAS
    data = {
        "question": queries,
        "answer": answers,
        "contexts": contexts,
        "ground_truth": ground_truth
    }
    dataset= DatasetDict()
    dataset['eval']=Dataset.from_dict(data)

    # Override OpenAI LLM and embedding with NVIDIA AI endpoints
    nvidia_llm = ChatNVIDIA(model="meta/llama-3.1-8b-instruct")    
nvidia_embeddings = NVIDIAEmbeddings(model="nvidia/nv-embedqa-e5-v5", truncate="END")

   result = evaluate(
            dataset["eval"],
            metrics=[answer_relevancy, 
                faithfulness
                ],
            llm=nvidia_llm,
            embeddings=nvidia_embeddings,
            raise_exceptions=False,
            is_async=False,
        )

您可以进一步修改系统,根据关键字 (而非问答对) 评估语义搜索。在这种情况下,您可以从 Ragas 中提取关键词,而忽略已生成的测试集的问答数据。这在尚未部署完整 Ragas 工作流的医疗系统中通常很有用。

testset = generator.generate_with_langchain_docs([doc], test_size=10, is_async=False, raise_exceptions=False, distributions={simple: 1.0})
        queries = []
        for node in generator.docstore.nodes:
            queries += node.keyphrases
        return queries

现在,您可以将查询(而非问题)输入任何医学语义搜索系统进行评估:

[“lesion”, “intraperitoneal fluid”, “RF treatment”, “palpitations”, “thoracoscopic lung biopsy”, “preoperative chemoradiotherapy”, “haemoglobin level”, “needle biopsy specimen”, “hypotension”, “tachycardia”,  “abdominal radiograph”, “pneumatic dilatation balloon”, “computed tomographic (CT) scan”, “tumor cells“, “radiologic examinations“, “S-100 protein“, “ultrastructural analysis”, “Birbeck granules”, “diastolic congestive heart failure (CHF)”, “Brachial blood pressure”, “ventricular endomyocardial biopsy”, “myocarditis”, “infiltrative cardiomyopathies”, “stenosis”, “diastolic dysfunction”,  “autoimmune hepatitis”]

如前所述,默认评估指标并不总是足以满足医疗系统的需求,因此通常必须进行定制以支持特定领域的挑战。

为此,您可以在 Ragas 中创建自定义指标。这需要创建自定义提示。在本例中,您创建自定义提示来衡量语义搜索查询的检索精度:

RETRIEVAL_PRECISION = Prompt(
    name="retrieval_precision",
    instruction="""if a user put this query into a search engine, is this result relevant enough that it could be in the first page of results? Answers should STRICTLY be either '1' or '0'. Answer '0' if the provided summary does not contain enough information to answer the question and answer '1' if the provided summary can answer the question.""",
    input_keys=["question", "context"],
    output_key="answer",
    output_type="json",
)

接下来,构建一个继承自 MetricWithLLM 的新类,并覆盖 _ascore 函数,根据提示响应计算分数:

@dataclass
class RetrievalPrecision(MetricWithLLM):

    name: str = "retrieval_precision"  # type: ignore
    evaluation_mode: EvaluationMode = EvaluationMode.qc  # type: ignore
    context_relevancy_prompt: Prompt = field(default_factory=lambda: RETRIEVAL_PRECISION)

    async def _ascore(self, row: t.Dict, callbacks: Callbacks, is_async: bool) -> float:
        score=response[0] # first token is the result [0,1]
        if score.isnumeric():
            return int(score)
        else:
            return 0

    retrieval_precision = RetrievalPrecision()

现在,新的自定义指标定义为 retrieval_precision,您可以在标准 Ragas 评估管道中使用它:

nvidia_llm = ChatNVIDIA(model="meta/llama-3.1-8b-instruct")
nvidia_embeddings = NVIDIAEmbeddings(model="nvidia/nv-embedqa-e5-v5", truncate="END")

score = evaluate(dataset["eval"], metrics=[retrieval_precision], llm=nvidia_llm, embeddings=nvidia_embeddings, raise_exceptions=False, is_async=False)

使用结构化输出进行优化 

RAG 和 LLM 评估框架采用 LLM 即判断技术,通常需要长而复杂的提示。正如您在之前的自定义指标提示示例中所看到的,这还需要对 LLM 响应进行解析和后处理。

您可以使用 LangChain NVIDIA AI 端点 结构化输出 功能来改进此过程,使其更加稳健。修改之前的提示会生成一个简化的管道:

import enum

class Choices(enum.Enum):
    Y = "Y"
    N = "N"

structured_llm = nvidia_llm.with_structured_output(Choices)

structured_llm.invoke("if a user put this query into a search engine, is this result relevant enough that it could be in the first page of results? Answer 'N' if the provided summary does not contain enough information to answer the question and answer 'Y' if the provided summary can answer the question.")

结束语 

RAG 已成为一种强大的方法,它将大型语言模型和密集向量表示的优势相结合。通过使用密集向量表示,RAG 模型可以高效扩展,非常适合大型企业应用,例如多语种客户服务聊天机器人和代码生成代理。

随着大型语言模型(LLMs)的不断发展,RAG 将在推动创新和提供高质量、智能的医疗系统方面发挥越来越重要的作用。

在评估医疗 RAG 系统时,必须考虑几个关键因素:

  • The system should provide accurate, relevant, and up-to-date information while remaining faithful to the retrieved context.
  • 它必须在处理专门的医学术语和概念以及嘈杂或不完善的输入方面表现出稳健性。
  • 正确的评估包括对检索和生成组件使用适当的度量指标,与专门的医疗数据集进行基准测试,并考虑成本效益。
  • 整合医疗健康专业人员的反馈并进行持续评估对于确保该系统在临床环境中的实用性和相关性至关重要。

本文中描述的管道解决了所有这些问题,并且可以进一步完善以包括其他指标和特征。

有关使用 Ragas 的参考评估工具的更多信息,请参阅 NVIDIA/GenerativeAIExamples GitHub 仓库上的 评估示例

 

标签