RadFact ist ein Framework für die Auswertung modellgenerierter Radiologieberichte anhand eines Ground-Truth-Berichts, mit oder ohne Grounding . RadFact nutzt die logischen Inferenzfähigkeiten großer Sprachmodelle und ist keine einzelne Zahl, sondern eine Reihe von Metriken, die Aspekte der Präzision und des Abrufs auf reiner Textebene und auf Text- und Erdungsebene erfassen.
RadFact wurde in MAIRA-2: Grounded Radiology Report Generation eingeführt. Hier stellen wir eine Open-Source-Implementierung der Metrik zur Verfügung, um ihre Verwendung und Entwicklung zu erleichtern.
LLMEngine
für ParallelverarbeitungUm RadFact auszuführen, müssen Sie lediglich dieses Repository klonen und den folgenden Befehl ausführen:
pip install .
Dadurch werden das radfact
-Paket und alle seine Abhängigkeiten installiert.
Alternativ stellen wir ein Makefile
zur Verfügung, um eine Conda-Umgebung mit allen Abhängigkeiten einzurichten. Sie können die Umgebung erstellen mit:
make miniconda
make mamba
make env
conda activate radfact
Im ersten Schritt wird Miniconda installiert, im zweiten Schritt wird Mamba für eine schnelle Abhängigkeitsauflösung installiert und im dritten Schritt wird eine Conda-Umgebung namens radfact
mit allen Abhängigkeiten erstellt. Dadurch wird auch das Radfact-Paket standardmäßig im bearbeitbaren Modus über das Rezept setup_packages_with_deps
installiert (siehe Makefile). Aktivieren Sie abschließend die Umgebung zum Ausführen von RadFact. Dies wird dringend empfohlen, wenn Sie einen Beitrag zum Projekt leisten möchten.
Um RadFact nutzen zu können, benötigen Sie Zugriff auf ein großes Sprachmodell. Sie müssen zunächst die Endpunkte mit Authentifizierung einrichten und dann mithilfe unseres Testskripts bestätigen, dass sie sich wie erwartet verhalten.
Das LLM sollte als API-Endpunkt verfügbar sein und von langchain
(Version 0.1.4) unterstützt werden. Wir unterstützen zwei Arten von Modellen: AzureChatOpenAI- und ChatOpenAI-Modelle. Ersteres eignet sich für GPT-Modelle, die in Azure verfügbar sind, während Letzteres für benutzerdefinierte bereitgestellte Modelle wie Llama-3 in Azure geeignet ist.
Wir unterstützen die folgenden Authentifizierungsmethoden:
API_KEY
auf den API-Schlüssel des Endpunkts fest. Wir verwenden API_KEY
als Standardnamen für die Umgebungsvariable. Wenn Sie einen anderen Namen verwenden, können Sie diesen in der Endpunktkonfiguration über api_key_env_var_name
angeben. Dies ist besonders nützlich, wenn mehrere Endpunkte mit unterschiedlichen API-Schlüsseln verwendet werden.config.json
im Stammverzeichnis des Projekts. Diese Konfiguration sollte die Schlüssel subscription_id
, resource_group
und workspace_name
haben. Es kann über das Portal aus dem AzureML-Arbeitsbereich heruntergeladen werden. Diese Datei wird zum .gitignore
hinzugefügt, um versehentliche Commits zu vermeiden. Stellen Sie sicher, dass Sie die Datei im Stammverzeichnis des Projekts unter dem Namen config.json
speichern, wie von der Endpunktklasse erwartet.key_vault_secret_name
in der Endpunktkonfiguration.azure_ad_token_provider
eines AzureChatOpenAI
-Modells festgelegt, das eine automatische Tokenaktualisierung ermöglicht. Dies wird nur für AzureChatOpenAI
-Modelle unterstützt. Um mehr darüber zu erfahren, wie wir die Enpoints in RadFact integrieren, lesen Sie bitte die LLMAPIArguments
-Klasse in arguments.py, die ein Endpunktobjekt der Endpoint
-Klasse in endpoint.py nutzt.
Wir verwenden Hydra für die Konfigurationsverwaltung. Die Endpunktkonfigurationen befinden sich im Pfad: configs/endpoints
.
Dies ist ein Beispiel für eine Konfigurationsdatei:
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"
und type: "AZURE_CHAT_OPENAI"
abhängig vom verwendeten Modellendpunkt. Für in Azure verfügbare GPT-Modelle verwenden Sie type: "AZURE_CHAT_OPENAI"
. Für benutzerdefinierte bereitgestellte Modelle wie Llama-3 in Azure verwenden Sie type: "CHAT_OPENAI"
.url
und „Vermutlicher deployment_name
mit den entsprechenden Werten aktualisieren.keyvault_secret_name
ist optional und nicht erforderlich, wenn Sie die API über eine Umgebungsvariable festlegen. Aktualisieren Sie api_key_env_var_name
, wenn Sie einen anderen Umgebungsvariablennamen für den API-Schlüssel als den Standardnamen "API_KEY"
verwenden. Wenn Sie mehrere Endpunkte verwenden, geben Sie für jeden Endpunkt einen anderen api_key_env_var_name
an.speed_factor
wird verwendet, wenn mehr als ein Endpunkt verfügbar ist. Auf diese Weise können Sie die relative Geschwindigkeit des Endpunkts im Vergleich zu den anderen angeben, mit der die Daten proportional auf die Endpunkte verteilt werden.num_parallel_processes
wird verwendet, um die Anzahl der parallelen Prozesse anzugeben, die bei der Abfrage eines bestimmten Endpunkts verwendet werden sollen. Alle Anfragen werden nacheinander verarbeitet, es sei denn, num_parallel_processes
ist auf einen Wert größer als 1 eingestellt, was eine parallele Verarbeitung ermöglicht. Wenn RadFact wie oben für die Auswertung nicht begründeter , z. B. narrativer Berichte verwendet wird, wandelt RadFact die Berichte zunächst in eine Liste von Phrasen um. Für diesen Schritt verwenden wir ein LLM, es muss jedoch nicht dasselbe LLM sein, das für die Entailment-Verifizierung verwendet wird. Sie können in den folgenden Konfigurationen unter „Endpunkte override endpoints:
:
configs/report_to_phrases.yaml
– Konvertierung des Berichts in eine Phrasenliste. In MAIRA-2 haben wir hierfür GPT-4 verwendet, das als AzureChatOpenAI-Modell abgefragt werden kann.configs/radfact.yaml
– Entailment-Überprüfung. In MAIRA-2 haben wir hierfür LLama-3-70B-Instruct
verwendet, das als ChatOpenAI-Modell abgefragt werden kann. Verschiedene Back-End-LLMs können sich unterschiedlich verhalten und unterschiedliche Metrikergebnisse liefern. Insbesondere sollte für RadFact kein Modell verwendet werden, das bei der Entailment-Verifizierung schlecht abschneidet. Um zu bestätigen, dass sich die Entailment-Überprüfung wie erwartet verhält, führen Sie python src/radfact/cli/run_radfact_test_examples.py
aus und stellen Sie sicher, dass die Ergebnisse den erwarteten ähneln. Die erwarteten Ergebnisse wurden mit dem LLama-3-70b-Instruct
Modell erzielt.
Beachten Sie, dass hierdurch nicht das Verhalten des Berichts-zu-Phrasen-Schritts getestet wird.
Die LLMEngine
-Klasse ermöglicht die parallele Verarbeitung über mehrere Endpunkte hinweg. Wenn Sie Zugriff auf mehrere Endpunkte mit unterschiedlichem Durchsatz haben, kann die Engine die Daten proportional zu ihrer Geschwindigkeit auf die Endpunkte verteilen. Die Engine ermöglicht auch die parallele Verarbeitung von Anfragen an einen einzelnen Endpunkt. Dies wird standardmäßig unabhängig von der Anzahl der Endpunkte verwendet. Informationen zu den Optionen speed_factor
und num_parallel_processes
finden Sie in der Endpunktkonfigurationsdatei. Darüber hinaus übernimmt die Engine die Stapelverarbeitung und Zwischenspeicherung der Ergebnisse. Alle Zwischenergebnisse werden im Verzeichnis outputs/radfact
unter einem Lauf-ID-Ordner gespeichert, der mit dem Startzeitstempel versehen ist, z. B. outputs/radfact/run_20240814_075225
. Die Ordnerstruktur ist wie folgt:
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
enthält die Endergebnisse für alle Datenpunkte. progress.csv
enthält den Fortschritt der Verarbeitung für jeden Endpunkt. batch_outputs
enthält die Zwischenergebnisse pro Batchgröße. skipped
enthält die Datenpunkte, die aufgrund von Fehlern übersprungen wurden.
Im Getting_started-Notizbuch erfahren Sie, wie Sie RadFact mit Ihren eigenen Daten ausführen. Wir empfehlen dringend, zuerst das Notebook zu lesen, um den RadFact-Workflow und seine Verwendung zu verstehen. Wir stellen auch ein Skript zur Verfügung, um RadFact auf Ihren Daten auszuführen. Stellen Sie sicher, dass Sie die Endpunkte wie oben beschrieben eingerichtet haben, bevor Sie das Skript ausführen. Der Befehl run_radfact
führt python src/radfact/cli/run_radfact.py
unter der Haube aus. Sie können das Standardverhalten über die unten erläuterten Befehlszeilenargumente überschreiben, indem Sie run_radfact --help
ausführen. Um das Skript ausführen zu können, muss das Paket lokal installiert sein.
$ 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 >
Das erwartete Format der Eingabedateien finden Sie in den Beispieleingabedateien im examples
. Die Eingabedateien sollten das Format einer CSV-Datei für nicht fundierte Berichte haben: „founding_generation_examples.csv“ und eine JSON-Datei für fundierte Berichte „grounded_reporting_examples.json“.
Das Skript berechnet Konfidenzintervalle für die Metriken mithilfe von Bootstrapping. Die Anzahl der Bootstrap-Beispiele kann mit dem Argument --bootstrap_samples
gesteuert werden. Der Standardwert ist 500. Um Bootstrapping zu deaktivieren, legen Sie --bootstrap_samples 0
fest.
num_llm_failures
. Das Skript gibt am Ende des Laufs die Anzahl der übersprungenen Abfragen aus und speichert diese im skipped
Verzeichnis unter dem Lauf-ID-Ordner. Außerdem wird in den Protokollen für jede fehlgeschlagene Abfrage eine Warnmeldung angezeigt. WARNING: No response for example {query_id}. Setting as NOT ENTAILED
.
Wir bieten auch ein Skript zum Konvertieren von Berichten in Phrasen an. Dies ist nützlich, wenn Sie einen narrativen Bericht haben und ihn für die RadFact-Bewertung in eine Liste von Phrasen umwandeln möchten. Sie können diesen Schritt offline ausführen und die Ausgabedatei dann als Eingabe für RadFact verwenden. Stellen Sie sicher, dass Sie die Endpunkte wie oben beschrieben eingerichtet haben, bevor Sie das Skript ausführen. Der Befehl run_report_to_phrases
führt python src/radfact/cli/run_report_to_phrases.py
unter der Haube aus.
run_report_to_phrases dataset.csv_path= < your_path_to_cxr_reports >
Dieses Skript kann mithilfe der Konfigurationsdatei report_to_phrases.yaml
konfiguriert werden. Sie können die Eingabedatei, die Ausgabedatei und den Endpunkt angeben, die für die Konvertierung verwendet werden sollen.
Bei Bedarf zerlegt RadFact die Berichte zunächst in einzelne Sätze, die höchstens einen Befund beschreiben. Anschließend werden die logischen Inferenzfähigkeiten eines großen Sprachmodells verwendet, um zu bestimmen, ob diese Sätze angesichts des Referenzberichts logisch unterstützt („enthalten“) werden. Wir berechnen dies in zwei Richtungen: Zuerst verwenden wir den Ground-Truth-Bericht (Originalbericht) als Referenz und umgekehrt, indem wir den modellgenerierten Bericht als Referenz verwenden. Dies ermöglicht die Quantifizierung sowohl der Richtigkeit als auch der Vollständigkeit.
Insgesamt bietet RadFact sechs Maßstäbe für die (fundierte) Berichtsqualität:
Metrisch | Definition | Was sagt es uns? | Erdung? |
---|---|---|---|
Logische Präzision | Der Anteil der generierten Sätze, die im Ground-Truth-Bericht enthalten sind. | Wie wahrheitsgetreu die Modellgenerationen sind: Falsche Generationen werden bestraft. | ❌ |
Logischer Rückruf | Der Anteil der Grundwahrheitssätze, die im generierten Bericht enthalten sind. | Wie vollständig der erstellte Bericht ist: Auslassungen werden bestraft. | ❌ |
Erdungspräzision | Der Anteil der logisch bedingten begründet generierten Sätze, die auch räumlich bedingt sind. | Wie oft sind richtig generierte Erkenntnisse auch richtig begründet? | ✔️ |
Rückruf wegen Erdung | Der Anteil der logisch bedingten Ground-Truth-Sätze, die auch räumlich bedingt sind. | Wie oft sind richtig erfasste Erkenntnisse auch richtig begründet? | ✔️ |
Räumliche Präzision | Der Anteil aller begründet generierten Sätze, die sowohl logisch als auch räumlich involviert sind. | Eine niedrige Punktzahl bedeutet, dass das Modell unnötige Kästchen oder Kästchen für falsche Sätze generiert hat. | ✔️ |
Räumliche Erinnerung | Der Anteil aller fundierten Grundwahrheitssätze, die sowohl logisch als auch räumlich impliziert sind. | Eine niedrige Punktzahl bedeutet, dass das Modell keine Kästchen für Ergebnisse in der Referenz generieren konnte, möglicherweise weil das Ergebnis falsch oder überhaupt nicht beschrieben wurde. | ✔️ |
Räumliche {Präzision, Erinnerung} sind weniger unmittelbar interpretierbar als die anderen Metriken, aber wir schließen sie ein, um den in der Begründung {Präzision, Erinnerung} impliziten Nenner zu kontrollieren: Wenn wir nur die Qualität von Kästchen mit logisch bedingten Sätzen bewerten, gemessen durch die Begründung {Präzision, Rückruf}, wir erfassen keine Begründungsfehler, die durch irrelevante Kästchen im Zusammenhang mit falschen Sätzen (z. B. vollständig erfundene Befunde) oder fehlende Kästchen im Zusammenhang mit übersehenen Befunden entstehen.
RadFact nutzt LLMs in zwei Schritten. In beiden Fällen verwenden wir etwa 10 Beispiele für wenige Aufnahmen.
Die unidirektionale Entailment-Überprüfung (Teil von Schritt 2) funktioniert wie folgt:
Dies ermöglicht es uns, jeden Satz als logisch (oder nicht) und räumlich (oder nicht) zu kennzeichnen und somit die oben aufgeführten RadFact-Metriken zu berechnen. Beachten Sie, dass die räumliche Folgerung nur für Sätze mit Kästchen definiert ist.
Für die Umwandlung von Berichten in einzelne Sätze haben wir mithilfe des Abschnitts FINDINGS
synthetische Beispiele im Stil von MIMIC-CXR-Berichten generiert. Die ursprünglichen MIMIC-Berichte sind durch eine Datennutzungsvereinbarung geschützt, die eine Weiterverbreitung verbietet. Wir teilen die Erzählberichte manuell in einzelne Sätze auf. Die Beispiele und die Systemmeldung sind unter llm_utils.report_to_phrases.prompts
zu sehen.
Zur Entailment-Verifizierung stammen die Fence-Shot-Beispiele aus einem privaten Datensatz („USMix“). Jedes Beispiel enthält Sätze aus zwei Berichten, die wir mithilfe der TF-IDF-Statistik als ähnlich, aber nicht identisch ausgewählt haben. In Zusammenarbeit mit einem beratenden Radiologen haben wir sie dann manuell mit dem Enthaltungsstatus und den Beweisen versehen. Obwohl es sich um eine logische Inferenzaufgabe handelt, gibt es bei der Konsequenzverifizierung ein gewisses Maß an Subjektivität, die sich daraus ergibt, wie streng bestimmte Konzepte interpretiert werden. Daher könnten einige dieser Beispiele angefochten werden. Beispiele und Systemmeldungen sind unter llm_utils.nli.prompts
verfügbar.
Um RadFact zu zitieren, können Sie Folgendes verwenden:
@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 wird nur für Forschungszwecke bereitgestellt. RadFact ist nicht für den Einsatz bei der Diagnose, Vorbeugung, Linderung oder Behandlung einer Krankheit oder eines medizinischen Zustands konzipiert, vorgesehen oder wird zur Verfügung gestellt und dient auch nicht dazu, eine medizinische Funktion zu erfüllen, und die Leistungsfähigkeit von RadFact für solche Zwecke wurde nicht nachgewiesen. Sie tragen die alleinige Verantwortung für jegliche Verwendung von RadFact, einschließlich der Einarbeitung in ein Produkt, das für medizinische Zwecke bestimmt ist.
Dieses Projekt freut sich über Beiträge und Vorschläge. Für die meisten Beiträge müssen Sie einem Contributor License Agreement (CLA) zustimmen, in dem Sie erklären, dass Sie das Recht haben, uns die Rechte zur Nutzung Ihres Beitrags zu gewähren, und dies auch tatsächlich tun. Weitere Informationen finden Sie unter https://cla.opensource.microsoft.com.
Wenn Sie eine Pull-Anfrage einreichen, ermittelt ein CLA-Bot automatisch, ob Sie eine CLA bereitstellen müssen, und schmückt die PR entsprechend (z. B. Statusprüfung, Kommentar). Folgen Sie einfach den Anweisungen des Bots. Sie müssen dies nur einmal für alle Repos tun, die unsere CLA verwenden.
Dieses Projekt hat den Microsoft Open Source Verhaltenskodex übernommen. Weitere Informationen finden Sie in den häufig gestellten Fragen zum Verhaltenskodex oder wenden Sie sich bei weiteren Fragen oder Kommentaren an [email protected].
Dieses Projekt kann Marken oder Logos für Projekte, Produkte oder Dienstleistungen enthalten. Die autorisierte Nutzung von Microsoft-Marken oder -Logos unterliegt den Marken- und Markenrichtlinien von Microsoft und muss diesen entsprechen. Die Verwendung von Microsoft-Marken oder -Logos in geänderten Versionen dieses Projekts darf keine Verwirrung stiften oder eine Sponsorschaft durch Microsoft implizieren. Jegliche Nutzung von Marken oder Logos Dritter unterliegt den Richtlinien dieser Drittanbieter.