RadFact 是一个框架,用于评估模型生成的放射学报告(给定真实报告,无论是否有依据) 。利用大型语言模型的逻辑推理能力,RadFact 不是一个单一的数字,而是一套指标,捕获纯文本和文本和基础级别的精确度和召回率方面。
RadFact 在 MAIRA-2:基础放射学报告生成中引入。在这里,我们提供了该指标的开源实现,以方便其使用和开发。
LLMEngine
为了运行 RadFact,您只需克隆此存储库并运行以下命令:
pip install .
这将安装radfact
包及其所有依赖项。
或者,我们提供一个Makefile
来设置包含所有依赖项的 conda 环境。您可以使用以下方式创建环境:
make miniconda
make mamba
make env
conda activate radfact
第一步安装 miniconda,第二步安装 mamba 以快速解决依赖关系,第三步创建一个名为radfact
的 conda 环境,其中包含所有依赖项。默认情况下,这还将通过setup_packages_with_deps
配方以可编辑模式安装 radfact 包(请参阅 Makefile)。最后,激活RadFact的运行环境。如果您打算为该项目做出贡献,强烈建议您这样做。
要使用 RadFact,您需要访问大型语言模型。您需要首先通过身份验证设置端点,然后使用我们的测试脚本确认它们的行为符合预期。
LLM 应作为 API 端点提供,并受到langchain
(版本 0.1.4)的支持。我们支持两种类型的模型:AzureChatOpenAI 和 ChatOpenAI 模型。前者适用于 Azure 上提供的 GPT 模型,而后者适用于 Azure 中的 Llama-3 等自定义部署模型。
我们支持以下认证方式:
API_KEY
环境变量设置为端点的 API 密钥。我们使用API_KEY
作为默认环境变量名称。如果您使用不同的名称,您可以通过api_key_env_var_name
在端点配置中指定它。当使用具有不同 API 密钥的多个端点时,这尤其有用。config.json
。此配置应具有键subscription_id
、 resource_group
和workspace_name
。可以通过门户从 AzureML 工作区下载它。该文件被添加到.gitignore
以避免意外提交。确保按照端点类的预期将文件保存在项目的根目录中,名称为config.json
。key_vault_secret_name
。AzureChatOpenAI
模型的azure_ad_token_provider
参数。仅AzureChatOpenAI
模型支持此功能。要了解有关如何在 RadFact 中集成 enpoint 的更多信息,请参阅arguments.py 中的LLMAPIArguments
类,该类使用 endpoint.py 中Endpoint
类的端点对象。
我们使用 Hydra 进行配置管理。端点配置位于路径: configs/endpoints
中。
这是配置文件的示例:
ENDPOINT_EXAMPLE : type : " CHAT_OPENAI " url : "" deployment_name : " llama3-70b " api_key_env_var_name : "" keyvault_secret_name : "" speed_factor : 1.0 num_parallel_processes : 10
type: "CHAT_OPENAI"
和type: "AZURE_CHAT_OPENAI"
具体取决于所使用的模型端点。对于 Azure 上可用的 GPT 模型,请使用type: "AZURE_CHAT_OPENAI"
。对于 Azure 上的 Llama-3 等自定义部署模型,请使用type: "CHAT_OPENAI"
。url
和可能的deployment_name
字段。keyvault_secret_name
是可选的,如果您通过环境变量设置 api,则不需要。如果您对 API 密钥使用的环境变量名称与默认的"API_KEY"
不同,请更新api_key_env_var_name
。使用多个端点时,为每个端点指定不同的api_key_env_var_name
。speed_factor
选项。这允许您指定端点与其他端点相比的相对速度,用于按比例跨端点分片数据。num_parallel_processes
用于指定查询特定端点时要使用的并行进程数。所有请求均按顺序处理,除非num_parallel_processes
设置为大于 1 的值(允许并行处理)。如上所述,当使用 RadFact 评估无根据的报告(例如叙述性报告)时,RadFact 首先将报告转换为短语列表。我们在此步骤中使用 LLM,但它不需要与用于蕴涵验证的 LLM 相同。您可以在override endpoints:
:
configs/report_to_phrases.yaml
-- 将报告转换为短语列表。在 MAIRA-2 中,我们为此使用了 GPT-4,它可以作为 AzureChatOpenAI 模型进行查询。configs/radfact.yaml
蕴含验证。在 MAIRA-2 中,我们使用LLama-3-70B-Instruct
来实现此目的,它可以作为 ChatOpenAI 模型进行查询。 不同的后端法学硕士可能表现不同并产生不同的指标结果。特别是,在蕴含验证方面表现不佳的模型不应该用于 RadFact。要确认蕴涵验证的行为符合预期,请运行python src/radfact/cli/run_radfact_test_examples.py
并确认结果与预期类似。使用LLama-3-70b-Instruct
模型获得了预期结果。
请注意,这不会测试报告到短语步骤的行为。
LLMEngine
类支持跨多个端点的并行处理。如果您可以访问具有不同吞吐量的多个端点,引擎可以根据端点的速度按比例将数据分片。该引擎还允许并行处理到单个端点的请求。无论端点数量多少,默认情况下都会使用此选项。有关speed_factor
和num_parallel_processes
选项,请参阅端点配置文件。此外,该引擎还负责结果的批处理和中间缓存。所有中间结果都存储在标有起始时间戳的 run id 文件夹下的outputs/radfact
目录中,例如outputs/radfact/run_20240814_075225
。文件夹结构如下:
outputs/radfact/run_20240814_075225
├── batch_outputs
│ ├── outputs_0_100.json
| ├── .
| ├── .
| ├── .
│ └── outputs_1000_1100.json
├── progress
│ ├── subset_0_240.csv
| ├── .
| ├── .
| ├── .
│ └── subset_800_1100.csv
├── skipped
│ ├── subset_0_240.csv
| ├── .
| ├── .
| ├── .
│ └── subset_800_1100.csv
├── outputs.json
├── progress.csv
└── skipped.csv
outputs.json
包含所有数据点的最终结果。 progress.csv
包含每个端点的处理进度。 batch_outputs
包含每个批次大小的中间结果。 skipped
包含由于错误而被跳过的数据点。
您可以参考 getting_started 笔记本来了解如何在您自己的数据上运行 RadFact。我们强烈建议您首先阅读笔记本以了解 RadFact 工作流程以及如何使用它。我们还提供了一个脚本来对您的数据运行 RadFact。确保在运行脚本之前已按上述方式设置端点。 run_radfact
命令在后台运行python src/radfact/cli/run_radfact.py
脚本。您可以通过运行run_radfact --help
通过下面解释的命令行参数覆盖默认行为。您需要在本地安装该软件包才能运行该脚本。
$ run_radfact --help
usage: run_radfact [-h] [--radfact_config_name RADFACT_CONFIG_NAME] [--phrases_config_name PHRASES_CONFIG_NAME] --input_path INPUT_PATH [--is_narrative_text] [--output_dir OUTPUT_DIR] [--bootstrap_samples BOOTSTRAP_SAMPLES]
Compute RadFact metric for a set of samples and saves the results to a json file.
options:
-h, --help show this help message and exit
--input_path INPUT_PATH
The path to the csv or json file containing the samples to compute RadFact for. For finding generation samples, the csv file should have columns ' example_id ' ,
' prediction ' , and ' target ' similar to the example in ` examples/findings_generation_examples.csv ` . For grounded reporting samples, provide a json file in the
same format as ` examples/grounded_reporting_examples.json ` .
--is_narrative_text Whether the input samples are narrative text or not. If true, the input samples are expected to be narrative text, otherwise they are expected to be grounded
phrases.
--radfact_config_name RADFACT_CONFIG_NAME
The name of the config file for RadFact processing. We use the default config file but you can provide a custom config. Make sure the config follows the same
structure as ` configs/radfact.yaml ` and is saved in the ` configs ` directory. This is necessary for hydra initialization from the ` configs ` directory.
--phrases_config_name PHRASES_CONFIG_NAME
The name of the config file for reports to phrases conversion. We use the default config file but you can provide a custom config. Make sure the config follows
the same structure as ` configs/report_to_phrases.yaml ` and is saved in the ` configs ` directory. This is necessary for hydra initialization from the ` configs `
directory.
--output_dir OUTPUT_DIR
Path to the directory where the results will be saved as a json file.
--bootstrap_samples BOOTSTRAP_SAMPLES
Number of bootstrap samples to use for computing the confidence intervals. Set to 0 to disable bootstrapping.
run_radfact --input_path < path_to_input_file.csv > --is_narrative_text
run_radfact --input_path < path_to_input_file.json >
有关输入文件的预期格式,请参阅examples
目录中的示例输入文件。输入文件的格式应为 CSV 文件(对于非接地报告findings_ Generation_examples.csv)和 JSON 文件(对于接地报告 grounded_reporting_examples.json)。
该脚本使用引导计算指标的置信区间。可以使用--bootstrap_samples
参数控制引导样本的数量。默认值为 500。要禁用引导,请设置--bootstrap_samples 0
。
num_llm_failures
下此类跳过的查询的数量。该脚本将在运行结束时打印跳过的查询数,并将它们存储在运行 id 文件夹下的skipped
目录中。您还将在日志中看到每个失败查询的警告消息。 WARNING: No response for example {query_id}. Setting as NOT ENTAILED
。
我们还提供了一个将报告转换为短语的脚本。当您有叙述性报告并希望将其转换为短语列表以进行 RadFact 评估时,这非常有用。您可以离线运行此步骤,然后使用输出文件作为 RadFact 的输入。确保在运行脚本之前已按上述方式设置端点。 run_report_to_phrases
命令在后台运行python src/radfact/cli/run_report_to_phrases.py
脚本。
run_report_to_phrases dataset.csv_path= < your_path_to_cxr_reports >
该脚本可使用report_to_phrases.yaml
配置文件进行配置。您可以指定用于转换的输入文件、输出文件和端点。
如有必要,RadFact 首先将报告分解为最多描述一个发现的单个句子。然后,它使用大型语言模型的逻辑推理功能来确定给定参考报告的这些句子是否在逻辑上得到支持(“包含”)。我们从两个方向进行计算,首先使用真实(原始)报告作为参考,反之亦然,使用模型生成的报告作为参考。这允许对正确性和完整性进行量化。
总体而言,RadFact 提供了六种(基础)报告质量衡量标准:
公制 | 定义 | 它告诉我们什么? | 接地? |
---|---|---|---|
逻辑精确 | 真实报告所包含的生成句子的比例。 | 模型生成的真实程度如何:它会惩罚不正确的生成。 | ❌ |
逻辑回忆 | 生成的报告所包含的真实句子的比例。 | 生成的报告的完整性如何:它会惩罚遗漏。 | ❌ |
接地精度 | 逻辑蕴涵的接地生成句子中也具有空间蕴含的部分。 | 正确生成的发现也有正确依据的频率有多少? | ✔️ |
接地召回 | 逻辑上蕴含的、空间上蕴涵的事实句子的比例。 | 正确捕获的发现也有正确依据的频率有多少? | ✔️ |
空间精度 | 所有接地生成的句子中逻辑和空间蕴涵的部分。 | 低分意味着模型生成了不必要的框或错误句子的框。 | ✔️ |
空间回忆 | 所有接地事实句子中在逻辑上和空间上都蕴涵的部分。 | 低分意味着模型无法为参考文献中的发现生成框,可能是因为错误地描述了发现或根本没有描述发现。 | ✔️ |
空间{精确度,召回率}不如其他指标直接解释,但我们将它们包括在内以控制基础{精度,召回}中隐含的分母:如果我们仅评估通过基础测量的逻辑蕴含句子框的质量{精确度,召回率},我们不会捕获与错误句子相关的无关框(例如完全捏造的发现)或与遗漏发现相关的缺失框而引起的接地故障。
RadFact 分两步使用法学硕士。在这两种情况下,我们都使用大约 10 个小样本示例。
单向蕴涵验证(步骤 2 的一部分)的工作原理如下:
这使我们能够将每个句子标记为逻辑蕴涵(或非)和空间蕴涵(或非),从而计算上面列出的 RadFact 指标。请注意,空间蕴含仅针对带有框的句子定义。
为了将报告转换为单独的句子,我们使用FINDINGS
部分生成了 MIMIC-CXR 报告风格的综合示例。原始 MIMIC 报告受到禁止重新分发的数据使用协议的保护。我们手动将叙述性报告分成单独的句子。示例和系统消息可以在llm_utils.report_to_phrases.prompts
下查看。
对于蕴涵验证,少数样本示例来自私人数据集(“USMix”)。每个示例都包含来自两个报告的句子,我们使用 tf-idf 统计数据选择相似但不相同的句子。然后,我们与放射科顾问合作,手动为它们贴上隐含状态和证据的标签。尽管是一项逻辑推理任务,但蕴涵验证存在一定程度的主观性,这是由于对某些概念的解释有多严格而产生的。因此,其中一些例子可能存在争议。示例和系统消息可在llm_utils.nli.prompts
下找到。
要引用 RadFact,您可以使用:
@article { Bannur2024MAIRA2GR ,
title = { MAIRA-2: Grounded Radiology Report Generation } ,
author = { Shruthi Bannur and Kenza Bouzid and Daniel C. Castro and Anton Schwaighofer and Sam Bond-Taylor and Maximilian Ilse and Fernando P'erez-Garc'ia and Valentina Salvatelli and Harshita Sharma and Felix Meissen and Mercy Prasanna Ranjit and Shaury Srivastav and Julia Gong and Fabian Falck and Ozan Oktay and Anja Thieme and Matthew P. Lungren and Maria T. A. Wetscherek and Javier Alvarez-Valle and Stephanie L. Hyland } ,
journal = { arXiv } ,
year = { 2024 } ,
volume = { abs/2406.04449 } ,
url = { https://arxiv.org/abs/2406.04449 }
}
RadFact 仅供研究使用。 RadFact 并非设计、旨在或用于诊断、预防、缓解或治疗疾病或医疗状况,也不是为了执行任何医疗功能,并且 RadFact 对于此类目的的性能尚未确定。您对 RadFact 的任何使用承担全部责任,包括纳入任何用于医疗目的的产品。
该项目欢迎贡献和建议。大多数贡献都要求您同意贡献者许可协议 (CLA),声明您有权并且实际上授予我们使用您的贡献的权利。有关详细信息,请访问 https://cla.opensource.microsoft.com。
当您提交拉取请求时,CLA 机器人将自动确定您是否需要提供 CLA 并适当地修饰 PR(例如,状态检查、评论)。只需按照机器人提供的说明进行操作即可。您只需使用我们的 CLA 在所有存储库中执行一次此操作。
该项目采用了微软开源行为准则。有关详细信息,请参阅行为准则常见问题解答或联系 [email protected] 提出任何其他问题或意见。
该项目可能包含项目、产品或服务的商标或徽标。 Microsoft 商标或徽标的授权使用须遵守且必须遵循 Microsoft 的商标和品牌指南。在此项目的修改版本中使用 Microsoft 商标或徽标不得引起混淆或暗示 Microsoft 赞助。对第三方商标或徽标的任何使用均须遵守这些第三方的政策。