In diesem Blogpost habe ich aktuelle bürokratische Herausforderungen in der Gesundheitsversorgung angesprochen. Der Einsatz von KI in der Medizin begegnet oft nicht nur Skepsis, sondern auch Limitierungen wie einem Mangel an Kompetenz und Budgets für die Entwicklung, den Betrieb und die Forschung von KI-Themen. Bei Zusammenarbeit mit vielen großen Krankenhäusern in Deutschland ist mir aufgefallen: Die Skepsis lässt nach und die Bereitschaft für KI wächst, auch weil immer mehr Kollegen die Potenziale bei der Automatisierung sehen. Gleichzeitig sehen sich immer mehr Kollegen mit der Realität konfrontiert, mangels Infrastruktur nicht das volle Potenzial von KI entfalten zu können.
Ich habe im o.g. Blogpost eine Fusion von Retrieval-Techniken mit Schwerpunkt auf OPS-Rohdaten mit kontext-basierter Text-Generation mit Large Language Models (LLMs) behandelt. Eine solche Technologie hat zwar viele Vorteile, wie verbesserte Genauigkeit und Geschwindigkeit, aber es bedarf an Infrastruktur, die eine KI-Plattform solcher Art stemmen kann.
Alternativ zu diesem Ansatz besteht auch die Möglichkeit, ein medizinisches Modell zu trainieren, welches diese Klassifizierung machen kann. In diesem Artikel behandeln wir das Finetuning von einem KI-Modell basierend auf BERT-Basismodell für OPS-Kodierung in der Klinik.
BERT als Rettung
BERT ist ein omnipotentes Basismodell von Google, welches sich wunderbar für nachgelagerte Klassifizierung eignet. Ein Vorteil liegt darin, dass die Modelle oft sehr klein und einfacher zu verwenden sind. Die Klassifizierung mit einem BERT-Modell kann daher auch ohne GPU mit respektablem Ressourcenaufwand betrieben werden.
Auf der anderen Seite erlaubt die kompakte Größe auch Finetuning an ressourcenarmen Systemen. Die Basisinfrastruktur für dieses Projekt war ein Nvidia Jetson Nano Super mit 8GB VRAM. Solche Modelle lassen sich daher auch auf Grafikkarten für Normalverbraucher finetunen.
BERT-Architektur
Die Architektur von BERT-Modellen ist ziemlich einfach. Die auch als "Encoder Only" Transformer-Architektur beinhaltet einen Tokenizer, Embedder, Encoder und Task Head.
[Image: Daniel Voigt Godoy, Wikimedia]
Ein Tokenizer-Modul ist der erste Schritt in der Input-Pipeline beim BERT und erzeugt aus dem Input-Text die sog. Tokens. Tokens sind kleinere Einheiten vom Text und repräsentieren den Schwerpunkt der Aussage im Text. BERT-Architektur verwendet sog. "WordPiece" Tokenizer, welcher von Google nicht open-sourced wurde und wir daher nicht wissen, wie genau er funktioniert. Dieses Thema hat Huggingface ausführlich hier behandelt.
Ein Embedder wandelt die im Schritt 1 erstellten Tokens in Einbettungen (oder Embeddings), die den Token numerisch als Vektoren repräsentieren. Der endgültige Vektor in BERT ist eine Mischung aus Vektoren vom Token-, Segment- und Positions-Einbettungen.
Der Encoder ist die zentrale Komponente von BERT und besteht aus mehreren Schichten von Transformern. Jede Schicht hat eigene Art, die Eingabe zu interpretieren (self-attention) und erzeugt daraus kontext-umfassende Ausgabe.
Der Task Head (Aufgabenmodul) verarbeitet die Ausgabe vom Encoder für spezifische Aufgaben. Für unser Text-Klassifikationsmodell werden sogenannte [CLS]
Tokens verarbeitet, die mit zwei Köpfen Start- und Endpunkt der Antwort im Text vorhersagen.
Text-Klassifikation mit BERT
BERT lässt sich mit adäquaten Beschriftungen (Labels) und Texten (Sequences) in ein Text-Klassifikationsmodell umwandeln. Der häufigste Use-Case hierfür ist Sentiment Analysis, wobei ein Text auf verschiedene Labels wie "glücklich", "traurig", "sauer", "neutral" klassifiziert wird und z.B. in Kundensupport eine Nachrichtenpriorität vorgeben kann.
In unserem Beispiel werden wir OPS-Codes als Label und eine Eingabe aus Operationsprotokollen als Sequence nutzen. Daher würden wir im besten Fall die Sätze aus OP-Bericht nutzen, um gültige OP-Prozeduren zu erkennen und so den Kodierungsprozess vereinfachen.
Finetuning vom BERT
Basis für das Finetuning ist das Modell bert-base-german-cased
[Modelcard]
Mit den unten beschriebenen Konzepten haben wir das Modell bereits veröffentlicht und in der Modellkarte auf Huggingface findet ihr eine Anleitung zur Verwendung mit der transformers
-Bibliothek.
Datenaugmentation
Ich habe hier ein synthetisches Dataset veröffentlicht, welches mit Qwen2.5 7B erzeugt wurde.
Unser Datensatz beinhaltet die Spalten ops_code
und full_text
die für das Training von entscheidender Bedeutung sind. Die erste Spalte ist das Label-Spalte und die zweite die Sequence-Spalte.
Es empfiehlt sich, die Daten genauer anzuschauen. In unserem Fall haben wir ca. 241k Zeilen.
Folgende Schritte haben wir vor dem Training unternommen:
- Wir analysieren nur Textzeilen, die nicht leer sind.
- Wir betrachten Klassenverteilung und erzeugen Klassengewichtungen, die im Training-Loss mitberücksichtigt werden.
- Die Abkürzungen wurden ausgeschrieben (best-effort)
- Klassen ohne Wiederholung werden verworfen.
Die Klassengewichtung ist wichtig, da im Klinikalltag nicht alle Prozeduren mit gleicher Prävalenz durchgeführt werden. Da allerdings unser Datensatz synthetisch ist, ist die Wirkung im konkreten Fall dadurch eingeschränkt.
Wir haben ein sog. 80-10-10 Splitting vorgenommen, wobei 80% des Datensatzes für Training, 10% für Validation und 10% für Test verwendet wurden.
Training
Wir trainieren das Modell auf Full Precision (32 bit). Es ist wichtig zu beachten, dass man eine angemessene Learning Rate und Batch Sizes auswählt. Da in unserem Gerät nur 8GB unified VRAM zur Verfügung stehen, haben wir einen Adam-Optimizer mit einer Learning Rate von 2 x 10 ^-5 ausgewählt. Als Batch Size haben wir 16 gewählt. Mit den oben berechneten Klassengewichtungen wurde eine Entropie ins System eingeschleust und damit Loss überwacht.
Nach ca. 20 Epochen hat das Modell sich in eine Phase gebracht, bei der unser Training Loss pro Epoche nur minimal verringert wurde (Plateau-Phase). Um ein Overfitting zu vermeiden, haben wir das Training beendet. Am Ende sahen die Parameter so aus:
- Accuracy: 0.8083
- Precision: 0.8323
- Recall: 0.8083
- F1-Score: 0.8042
Evaluation
Für Tests habe ich mir ein Test-Fragenset mit ca. 20 fächerübergreifenden OPS-Vorgängen überlegt. Von Kardiologie bis hin zur Opthalmologie soll somit das Modell auf ein breites Spektrum an Vorgängen untersucht werden.
Bei 20 Operationen hat das Modell 18 Einträge richtig kodiert. Somit lag bei dieser gewählten Batch-Größe die Genauigkeit bei ca. 90%.
Limitierungen
Die Datenqualität ist wohl der Elefant im Raum. Im veröffentlichten Datensatz sieht man bereits, dass die Daten in vielen Zeilen bei weitem nicht dem entsprechen, was medizinisches Personal durch Dokumentation erzeugen würde. Das ist der größte Bottleneck.
Die Klassenverteilung beeinflusst die Klassifizierung maßgeblich. Diese ist generell schwer mit synthetischen Datensätzen zu erreichen.
Wegen des Sequence-Length-Limits (512 bei unserem Modell) bedarf es an Vorverarbeitung der Texte, bevor diese an das Modell fließen. Das verkompliziert viele Workflows.
Implikationen für Zukunft
Die Modellgröße beträgt nach dem Finetuning ca. 511MB. Das erlaubt ein Einsatz des Modells in Edge-Geräten wie Smartphones bis hin zu Cloud. Auch ohne GPU liegt eine Klassifizierung von Texten im Bereich von wenigen Sekunden (200ms in Testmaschine mit Intel Xeon E3). Solche Expertenmodelle eröffnen neue Dimensionen an Möglichkeiten, um das ärztliche Personal vor dem Bürokratiestress zu retten.
Zusammenfassung
Obwohl die Daten synthetisch waren und der Betrieb solcher Modelle gewiss nicht wenig Aufwand mit sich bringt, zeigte sich unser Finetuned-Modell in Benchmarks standhaft.
Mit den neuesten Entwicklungen im KI-Umfeld blicke ich optimistisch in die Zukunft und bin mir sicher, dass mit solchen lokalen Modellen viele Engpässe des ärztlichen Personals, zumal mit der Automatisierung der organisatorischen Workflows, datenschutzgerecht und kostengünstig für die Krankenhäuser zu lösen sein werden.
Bei Fragen oder Anregungen freue ich mich über eine Email an bijay@regmi.dev
Ein medizinisches Modell mit synthetischen Daten