13.6.2025 - Stable-Diffusion

Vielleicht haben die vorherigen Kapitel Sie ja neugierig auf weitere KI-Experimente gemacht. Ein ganz heisser Kandidat für nähere Beschäftigung wird vermutlich Bilderstellung mit KI sein - zumindest, sobald sie einmal hineingeschnuppert haben. Das Hineinschnuppern ist allerdings nicht ganz einfach, denn die Platzhirsche ChatGPT 4o, Midjourney, Firefly und wie sie alle heissen, sind für simples Ausprobieren zu teuer. Sie erlauben zwar kostenlose Nutzung, aber dann ist die Erstellung der Bilder sehr langsam oder kompliziert oder auf wenige Bilder begrenzt.

Vielleicht erst mal eine Idee, was man zum Beispiel machen kann: Eine Möglichkeit von Bildgeneratoren ist, aus einer Textbeschreibung ein Bild zu machen. Zum Beispiel:

a van gogh painting of a tired doctor sitting in front of a computer

Van Gogh am Computer

Oder:

a picasso painting of a tired doctor sitting in front of a computer

Picasso

Sie sehen das Prinzip. Es spielt keine Rolle, dass Van Gogh oder Picasso vermutlich eher keinen Laptop besassen. Nebst Kopien von Malern kann man auch fotorealistische oder Cartoon-ähnliche oder Anime-ähnliche Bilder einfach nur aus Textbeschreibungen erstellen.

Dies wäre nicht das Amateur-Blog, wenn es hier nicht um eine Möglichkeit ginge, KI-Bilder auf der eigenen Hardware zu erstellen. Ich stelle hier die OpenSource-Lösung Stable-Diffusion vor. Und die gute Nachricht ist: Wenn Sie den letzten Artikeln gefolgt sind, dann haben Sie schon alles, was Sie brauchen. Um Stable-Diffusion lokal laufen zu lassen, benötigen Sie:

  • Einen halbwegs modernen Computer mit mindestens 16GB RAM (Mehr ist besser)
  • Eine Grafikkarte mit mindestens 8GB RAM (16GB oder mehr ist deutlich besser). Idealerweise mit NVidia RTX-Chip,
  • Ein Betriebssystem. auf dem die Programmiersprache Python laufen kann (gilt z.B. für Linux, Mac, Windows)
  • Die Grafik-Treiber von NVidia (geht bei Windows und Mac automatisch, bei Linux braucht es manchmal bei ganz neuen Karten ein wenig Frickelei)
  • Das CUDA von NVidia, dass zu Grafikkarte und Treiber passt.

Ich schlage vor, das stable-diffusion-webui von AUTOMATIC1111 zu verwenden. Die Installation ist auf der Github-Seite sehr gut erklärt, scrollen Sie einfach zu “Installation and Running” hinunter.

Wenn alles geklappt hat, öffnet sich nach der (Durchaus einige Zeit dauernden) Installation ein Browser-Fenster, das so ähnlich wie dieses aussieht (Wenn nicht, schauen Sie weiter unten unter “Probleme bei der Installation):

WebUI

Sie erkennen hier eine Menge etwas verwirrende Felder und Einstellmöglichkeiten. Zunächst sehen Sie ganz oben, dass der Browser offenbar die Adresse http://localhost:7860 geöffnet hat. Das ist darum interessant, weil es bedeutet, dass Sie Stable-Diffusion nicht nur an dem Computer nutzen können, auf dem das Programm läuft, sondern an jedem, der diesen Computer erreichen kann. Allerdings sollten Sie dann das webui mit ./webui --listen starten.

Okay, seit ich diesen Artikel angefangen habe, habe ich mich ein wenig mit Bildgenerierung befasst und eingesehen: Das sprengt den Rahmen eines solchen Beitrags bei weitem. Die Möglichkeiten sind unendlich. Ich schlage vor, sich zum Beispiel mit dieser Seite zu befassen: Stable Diffusion beginners guide

1.6.2025 - Sprachmodelle finden

Ich habe in den letzten Folgen die eigentlichen Sprachmodelle nur gestreift, resp, irgendwelche kryptischen Namen wie Phi3:14b oder gemma3:12b oder auch gemma3-27b-abliterated-dpo.i1-IQ3_XS.gguf fallen lassen. Aber was soll das alles? Welches Sprachmodell soll man dann nehmen?

Die korrekte Antwort ist: Es kommt drauf an. Fangen wir vielleicht zuerst mit einem kleinen Exkurs an: Im Grunde schreibe ich in diesem und den letzten paar Artikeln gar nicht von LLMs, sondern von SLMs. LLMs (Large Language Models) laufen nur auf Hardware, die sich unsereins nicht leisten kann und will. Allein die Grafikkarten eines typischen LLM-Servers kommen gemäss Angaben von DeepSeek auf rund 80000 Euro. Dazu kommen Multiprozessorsysteme und viel Speicher. So ein LLM hat dann zum Beispiel 100 Milliarden “Neurone” (Parameter) und benötigt 200GB Arbeitsspeicher, um nur schon eingelesen zu werden.

Man kann solche Modelle aber, wenn sie mal fertig trainiert sind, “eindampfen” (Quantisieren): Man reduziert die Leistung bzw. Genauigkeit der einzelnen Parameter und braucht dadurch wesentlich weniger Speicherplatz. Dann entfernt man die, die nach dem Training offenbar nicht so wichtig waren, und hat am Ende vielleicht noch 1,2,3,6 oder 12 Milliarden Neurone mit reduzierter Genauigkeit, die sich in geläufige Hardware packen lassen. Man nennt diese Extrakte dann SLM - Small Language Models, auch wenn “small” nicht ganz richtig ist, die Dinger brauche immer noch Gigabytes von Speicher.

Nun ist klar, dass man unterschiedliche Techniken zum “Eindampfen” verwenden kann. Häufig geben die Autoren der Modelle dann nebst dem Ursprungs-LLM auch die Reduktionstiefe im Namen an. Dadurch entstehen diese etwas schwer verständlichen Namen.

Wobei man gemma3:12b ja noch leicht verstehen kann: Aus der Basis Gemma3 (Ein OpenSource LLM von Google) hat man ein Extrakt mit 12 Milliarden (billions) Parametern gezogen. Bei gemma3-27b-abliterated-dpo.i1-IQ3_XS ist es schon schwieriger. Offenbar war es dasselbe Basismodell, aber mit 27 Milliarden Parametern, dann aber auf bestimmte Art quantisiert, so dass diese 27 Milliarden Neurone am Ende erheblich weniger Speicher brauchen - auf Kosten der Genauigkeit. Häufig findet man im Hugging-Face-Repository vom selben Autor viele unterschiedliche Quantisierungen desselben Basismodells, oft auch mit Kommentaren über deren Eigenheiten.

Es gibt allerdings auch SLMs, die von vornherein neu entwickelt und trainiert wurden, also nicht voin einem grossen Basismodell “abstammen”. Hier ist dann die Qualität des Trainings ganz entscheidend, und häufig werden sie auch auf bestimmte Fachgebiete trainiert (z.B. als Chatbots von Online Shops oder Versicherungskonzernen etc.), haben also kein universelles “Wissen”, wie LLMs.

Kurz: Das Ganze ist sehr unübersichtlich. Bei einer derart neuen, in stürmischer Entwicklung befindlichen Technologie ist das auch nicht verwunderlich. Woran kann man sich festhalten?

  • Speicherbedarf: Idealerweise sollte das gewählte Modell in den Speicher Ihrer Grafikkarte passen. Hierbei ist allerdings nicht der Name entscheidend: Ein geeignet quantisiertes :27b - Modell kann durchaus in eine 16GB Grafikkarte passen. Es hilft nichts: Sie müssen die Dokumentation des Modells lesen, oder es einfach ausprobieren.
  • Ausgangsmodell: Man kann nach “Sympathie” oder erwarteter Qualität auswählen.
    • Phi ist eine SLM Serie von Microsoft. Vor allem die Phi-3.5 und Phi-4 Modelle sind interessant, beide gibt es in verschiedenen Grössen, die man je nach Hardware auswählen kann.
    • Qwen ist eine Familie von Modellen des chinesischen AliBaba-Konzerns, die sich vor allem durch ihre Sprachkenntnisse (können in 29 Sprachen kommunizieren) auszeichnen. (Ebensowenig wie die anderen Modelle sendet Qwen Daten aus dem lokalen System nach aussen. Datenschutzbedenken sind also nicht nötig).
    • LLama sind Abkömmlinge des Originals von Meta (Facebook). Auch hier gibt es Modelle in verschiedenen Grössen
    • Gemma 2 und 3 sind Googles Modelle
    • SmolLM2 wurden von Hugging Face entwickelt und publiziert.
  • “Instruct” oder “Chat”: Instruct-Modelle sind darauf optimiert, jeweils eine Frage zu beantworten. Sie können sich idR. danach weder an die Frage noch an die Antwort “erinnern”. Chat-Modelle sind dagegen zum “plaudern” optimiert. Sie geben nicht so ausführliche Antworten, merken sich dafür, worüber gesprochen wurde, und können sich später auf etwas beziehen, was vorher gesagt wurde. Allerdings ist auch hier das “Gedächtnis” idR gelöscht, sobald man den Chat beendet. Sie können also morgen nicht mehr darauf zurückkommen und sagen “Aber das habe ich dir doch gestern schon erklärt!” (Wenn Sie trotzdem in der Benutzeroberfläche einen früheren Chat anwählen und dort scheinbar nahtlos weitermachen können, dann liegt das daran, dass das System den bisherigen Chatverlauf für Sie unsichtbar wieder einspeist, bevor es das Eingabefenster bedient).

Damit haben Sie mal etwas, womit Sie anfangen können. Im Zweifelsfall wählen Sie immer zuerst ein eher kleines Modell aus der gewählten Familie, und erst wenn das zwar gut läuft, aber zu “flache” oder falsche Antworten gibt, versuchen Sie ein grösseres.

29.5.2025 - Intelligente Texterkennung und benötigte Hardware

Nachdem ich im letzten Teil gezeigt habe, wie das LLM einen langen Bericht, typischerweise in PDF-Form, zusammenfassen kann, sei hier noch kurz auf eine andere Möglichkeit eingegangen: Die KI kann das Problem des “PDF-Friedhofs” elektronische KG zu lösen helfen, indem es PDFs auch semantisch analysieren kann.

ollama run gemma3:12b

>Bitte finde die Diagnosen in diesem Text: (PDF-Datei)

Basierend auf dem Text sind die Diagnosen (oder zumindest die Hauptprobleme) wie folgt:

  • Chronischer Knieschmerz rechts: Dies ist das Hauptanliegen des Patienten.
  • DD Überlagerung durch lumbosakrale Schmerzsyndrom: Eine Differentialdiagnose, die andeutet, dass Rückenschmerzen und ein lumbosakrales Schmerzsyndrom die Kniebeschwerden beeinflussen könnten.
  • Status nach aufrichtender Überbrückungsspondylodese Th11-L1: Dies bezieht sich auf eine frühere Operation des Rückens (Wirbelsäulenversteifung).
  • Mögliche Anschlussdegeneration der Wirbelsäule: Dies ist eine Vermutung bzgl. möglicher Problemen im Bereich der Wirbelsäule.
  • Chondropathie Grad 4 (medialer Femurkondylus): Eine Knorpelschädigung im Knie.
  • Teilresezierten Innenmeniskus: Beschädigung des Innenmeniskus.
  • Auffaserung Aussenmeniskus: Veränderung des Außenmeniskus.
  • Hyperkyphose des thoracolumbalen Übergangs: Eine Verkrümmung der Wirbelsäule.

Er ist sogar so freundlich, alles in laiengerechte Sprache zu übersetzen.

Weiteres Beispiel der semantischen Analyse:

>Bitte finde die Austrittsmedikation in folgendem Text: (PDF-Inhalt)

Hier ist die Liste der Medikamente, die dem Patienten bei Austritt verschrieben wurden, basierend auf dem Text:

  • Xarelto (Filmtabl. 20 mg) - Rivaroxaban Filmtabl. 20mg (1 Stk p.o.)
  • Bilol (Filmtabl. 5 mg) - Bisoprolol Filmtabl. 5mg (1 Stk p.o.)
  • Amiodarone Zentiva (Tabl. 200 mg) - Für 2 Wochen 200mg 1-0-1, danach 200mg 1x täglich für 3 Monate.
  • Exforge HCT (Filmtabl.) - Amlodipin, Valsartan, Hydrochlorothiazid Filmtabl. 10mg, 160mg, 25mg (1 Stk p.o.)
  • Pantozol (Filmtabl. 40 mg) - Pantoprazol Filmtabl. 40mg (1 Stk p.o.)
  • Xanax (Tabl. 0.5 mg) - Alprazolam Tabl. 0.5mg (bei Bedarf 1 Stk p.o.)

Wohlbemerkt: Das ist ein vier Seiten umfassendes PDF. Mit relativ wenig Zusatzaufwand könnte man das direkt in die KG übernehmen.

Datenschutzbedenken

Selbstverständlich dürften Sie einen solchen Auftrag niemals einer frei zugänglichen KI (ChatGPT, Gemini, Claude, DeepSeek usw) übergeben, da Sie dafür ja das PDF mit sensiblen Patienendaten hochladen würden. Aber bei einer KI, die nur lokal in Ihrem System läuft, ist das kein Problem (Testen Sie es: ziehen Sie den Netzwerk-Stecker. Es wird immer noch gleich funktionieren).

Die Kehrseite ist: Während die “grossen” KIs alles, was sie erhalten, auch benutzen, um sich weiterzuentwickeln (zum Besseren oder zum Schlechteren), bleibt unsere lokale KI statisch auf dem Stand, in dem wir sie heruntergeladen haben. Sie kann also nicht “degradieren”, aber sich auch nicht anpassen oder verbessern. Sie können sie aber jederzeit durch ein neueres oder ganz anderes Modell austauschen. Sie hat übrigens auch kein Gedächtnis: Wenn Sie in zehn Minuten fragen “Was war schon wieder die Hauptdiagnose?”, dann werden Sie irgendeine wirre Antwort bekommen, die nichts mit dem eben analysierten Text zu tun hat.

Wie ich aber hier hoffentlich gezeigt habe, kann man auf dem heutigen Stand schon recht viel machen.

Wie bekommt man es zum Laufen?

Ein kurzes Wort zur benötigen Hardware:

LLMs laufen bevorzugt auf Grafikkarten, da diese viele Operationen parallel ausführen können (Genau wie sie beim Bildaufbau alle Pixel möglichst gleichzeitig neu berechnen müssen). LLMs arbeiten auch mit vielen gleichzeitig ablaufenden Operationen. Am besten funktionieren sie darum, wenn möglichst viele “Neurone” in den Speicher der Grafikkarte passen.

Es ist empfehlenswert, eine Grafikkarte mit mindestens 16GB RAM zu kaufen. Am wenigsten Probleme hat man immer noch mit Grafikkarten mit NVidia-Chipsatz, da die meisten LLM Transformer damit zurechtkommen. Es muss keine High-End Karte sein, aber Mittelklasse wäre schon empfehlenswert. Bei mir laufen die hier vorgestellten Modelle auf einer NVidia 5060 Ti (nicht verwechseln mit 5060 ohne Ti) einigermassen gut. Die kosten derzeit (Mitte 2025) zwischen CHF 400.- und 500.- (Achten Sie wie gesagt darauf, dass Sie mindestens 16GB Speicher bekommen; es sind unterschiedliche Grössen im Handel). Natürlich wären stärkere Karten mit mehr Speicher noch besser, aber ein Modell mit doppelt so viel Speicher kostet derzeit locker den fünffachen Preis… Um etwas Geld zu sparen man auch mehrere “kleinere” Grafikkarten statt einer grösseren einbauen, wenn der Computer ein ausreichend starkes Netzteil und genügend PCIe-Slots hat. Man kann die Software dann anweisen, die Rechenaufgaben auf beide Grafikkarten zu verteilen. Eine versorgt dann nebenher die Bildschirme, die andere kann sich ganz dem LLM widmen.

Auch am Arbeitsspeicher des Rechners sollte man nicht knausern. Mindestens 48GB sind empfehlenswert, 64GB besser. Der Prozessor ist dagegen nicht so wichtig, wobei es auch hier eher auf die Zahl der Kerne als auf deren Einzelgeschwindigkeit ankommt.

Damit die Grafikkarte für KI verwendet werden kann, ist ausserdem das CUDA-Toolkit erforderlich, das man relativ einfach direkt von NVidia herunterladen und installieren kann.

Was nimmt man überhaupt?

Wenn Sie sich mit KI beschäftigen, begegnen Sie häufig diesen südamerikanischen Nutztieren: LLama, Ollama, Alpaca und so weiter. Der Name leitet sich ursprünglich von LLM (also large language Model) ab, wurde aber von Meta rückakronymisiert (Large Language Model Meta AI). Meta (also der Facebook-Konzern, ja, ausgerechnet!) hat die KI gewissermasen demokratisiert, indem es ihr LLM als OpenSouce publiziert hat. Seither ist ein riesiges Ökosystem entstanden. Wenn Sie sich einen Überblick verschaffen wollen, besuchen Sie die Hugging Face Website und lassen Sie sich von den Unmengen an Information und Modellen dort erschlagen.

Wenn Sie es sich etwas einfacher machen wollen, laden Sie z.B. Ollama herunter. Ollama baut eine Oberfläche und ein API um LLM-Modelle und erlaubt Ihnen auch die Auswahl solcher Modelle. Nach der Installation können Sie einfach mit z.B. ollama run gemma3:4b das gewünschte Modell herunterladen und starten. Wenn Ihnen der dann präsentierte Text-Prompt nicht gefällt, gibt es auch eine Reihe von GUIs,probieren Sie z.B. Hollama.

Wählen Sie zuerst mal ein kleines Modell (Eines mit :3b oder :4b im Namen), und wenn alles läuft können Sie grössere Modelle ausprobieren, bis Sie an die Grenzen Ihres PC stossen.

(Etwas mehr zur Auswahl eines geeigneten Modells finden Sie in einem späteren Artikel).

29.5.2025 - LLM im echten Leben

Nach den ersten Spielereien möchte ich testen, ob mein lokales LLM nützlich für den beruflichen Alltag sein kann. Ein zunehmender Zeitfresser sind die steigenden Zahlen von (Dank EDV immer länger werdenden) Berichten, die jeden Tag eintreffen.

Ich möchte, dass die KI mir Zusammenfassungen erstellt und direkt in der KG ablegt.

Ich füttere also einen Bericht zuerst mal an Phi3:14b:

> Bitte fasse den folgenden Text zusammen: (Es folgt der Inhalt des PDF)

Der Bericht von Dr. … enthält eine Detaillierung der MRT-Untersuchung des Patienten, die am 2. Dezember 2024 durchgeführt wurde. Es wird festgestellt, dass es sich bei allen beschriebenen Zysten im Bereich der Nieren um Bosniak 1 Zysten handelt und keine Anzeichen für ein Malignom im Oberbauch vorliegen. Die größte Zyste befindet sich mit einer Größe von 9,7 cm am linken oberen Pol. Es wird vorgeschlagen, die verdächtige Zyste am linken Nierenoberpol weiter zu untersuchen.


Nicht schlecht, nicht wahr? Und dieses Modell ist noch nicht mal speziell auf medizinische Texte trainiert. Jetzt mal sehen, was gemma3:12b daraus macht:

> Bitte fasse den folgenden Text zusammen: (Es folgt der Inhalt des PDF)

Hier ist eine Zusammenfassung des Textes:

Zusammenfassung:

Dr. … hat Herrn Dr. … (Nephrologie und Innere Medizin) einen Patienten (geb. xx.xx.xxxx) zur weiteren Abklärung von Nierenzysten überwiesen. Eine MRT der Nieren wurde am 02.12.2024 durchgeführt.

Wichtigste Ergebnisse:

  • Linke Niere: Eine große Zyste (9,7 cm) am Oberpol, die zunächst als Bosniak 2F verdächtig war, wurde nun MRT-morphologisch als Bosniak 1 klassifiziert. Zwei weitere kleinere Zysten wurden ebenfalls festgestellt.
  • Rechte Niere: Mehrere kleinere Zysten, ebenfalls als Bosniak 1 klassifiziert.
  • Allgemein: Die übrigen Organe im Oberbauch sind unauffällig. Es gibt keinen Hinweis auf ein Malignom.

Nächste Schritte: Die Ergebnisse der MRT werden Herrn Dr. … zur Kenntnis gebracht. Die Bilder sind für registrierte Zuweiser online verfügbar.


Auch dieses LLM ist nicht speziell auf medizinische Texte trainiert, hat aber den Inhalt des Befundes sehr genau erfasst und strukturiert zusammengefasst (Die Anonymisierungen stammen von mir, das LLM hat die Namen aller Beteiligten korrekt erfasst).

Nun gut, das war ja nur ein einfacher Text. Jetzt mal etwas Kompliziertes: Einen Spital-Austrittsbericht. Spitalberichte werden immer schwerer lesbar, da sie teilautomatisiert aus früheren Diagnosen und Berichten, sowie aktuellen Einträgen erstellt werden und darum oft sehr lang sind, und den aktuell relevanten Inhalt in den Tiefen des Textes ein wenig verbergen. Hier lohnt sich Automatisierung besonders, wenn sie denn vernünfige Resultate liefert. Also dann (wieder gemma3:12b):

> Bitte fasse den folgenden Text zusammen: (Es folgt das PDF)

Hier ist eine Zusammenfassung des Textes:

Hintergrund: Es handelt sich um einen Bericht des Kantonsspitals xy (Klinik für Innere Medizin) an den Hausarzt Dr. xxxx bezüglich des Patienten yyy (geb. xx.xx.xxxx). Der Bericht wurde digital visiert und stammt vom 20. November 2020.

Anlass der Einweisung: Der Patient wurde aufgrund einer wiederkehrenden, progredienten Dyspnoe, Gewichtszunahme und eines Ausschlags in die Klinik eingeliefert. Er wurde von einem Dermatologen (PD Dr. xx) überwiesen.

Wichtigste medizinische Befunde und Diagnosen:

  • Herz-Kreislauf-Erkrankungen: Schwere Herzinsuffizienz (NYHA IV) mit valvulären, rhythmogenen und koronaren Problemen. Er hat einen Schrittmacher und war unter Antikoagulation (Xarelto).
  • Lungenprobleme: Asthma-COPD-Overlap-Syndrom mit Atemwegsobstruktion und Diffusionsminderung, sowie ein Pleuraerguss rechts. Er wurde wegen eines Ausschlags von Dr. xx überwiesen und hat sich auch schon in der Vergangenheit Steroide gegeben.
  • Urogenitalmykose: War vorhanden, wurde aber behandelt.
  • Hauterkrankung: Bullöser Pemphigoid, wird aktuell von Dr. xx behandelt.
  • Niereninsuffizienz: Chronische Niereninsuffizienz Stadium G3a-b.</b>
  • Diabetes: Diabetes mellitus Typ 2, mit Komplikationen (diabetische Nephropathie).
  • Weitere Probleme: Ulcus duodeni, Anämie, Hypokaliämie, Mild cognitive impairment, Prostata-Syndrom, sowie eine Synkope, die möglicherweise rhythmogen war.</b>

Klinischer Verlauf und Therapie:

  • Der Patient wurde zunächst isoliert, um eine SARS-CoV-2-Infektion auszuschließen.
  • Ein Pleuraerguss wurde punktiert.
  • Die Herzinsuffizienztherapie wurde angepasst, und der Patient erhielt diuretische Medikamente und Atemübungen.
  • Er wurde mit einer Spitexunterstützung nach Hause entlassen.
  • Die Medikation und weitere Beobachtungen wurden geplant.

Empfehlungen:

  • Tägliche Gewichtskontrollen
  • Anpassung der Diuretika je nach Gewichtsschwankungen
  • Evaluation des Eisenmangels
  • Dermatologische Betreuung durch Dr. xx
  • Atorvastatin Evalutation

Auch hier stammen die Anonymisierungen wieder von mir. Das LLM hat alle Namen korrekt wiedergegeben und den fünf Seiten langen Text sinnerhaltend kondensiert. Im Prinzip könnte man das direkt als Verlaufseintrag in die KG übernehmen, wenn es eine entsprechende Schnittstelle gäbe.

Praktische Anwendung

Eine Beispielanwendung zum Erstellen einer Zusammenfassung aus pdf, docx, odt und anderen Dateitypen sieht zum Beispiel so aus (basierend auf node-llama-cpp):

// src/index.ts
import { fileURLToPath } from "url";
import path from "path";
import chalk from "chalk";
import { getLlama, LlamaChatSession, resolveModelFile } from "node-llama-cpp";
import { extractTextFromFile } from "./extract"

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const modelsDirectory = path.join(__dirname, "..", "models");

const llama = await getLlama();

console.log(chalk.yellow("Resolving model file..."));
const modelPath = await resolveModelFile(
    "hf:mradermacher/DeepSeek-R1-Distill-Qwen-14B-GGUF:Q6_K",
    modelsDirectory
);

console.log(chalk.yellow("Loading model..."));
const model = await llama.loadModel({ modelPath });

console.log(chalk.yellow("Creating context..."));
const context = await model.createContext({
    contextSize: { max: 16384 } // omit this for a longer context size, but increased memory usage
});

const session = new LlamaChatSession({
    contextSequence: context.getSequence()
});
console.log();

const filename = process.argv[2];
if (filename) {
      const text = await extractTextFromFile(filename);
    const q1 = "Bitte fasse den folgenden Text zusammen: " + text;
    const a1 = await session.prompt(q1, {
        onTextChunk(chunk) {
            process.stdout.write(chunk);
        }
    });
    process.stdout.write("\n");
    console.log();
} else {
    console.log(chalk.red("No file provided. Please provide a file path as an argument."));
    console.log(chalk.red("Usage: node index.js <path-to-file>"));
}
// src/extract.ts
import fs from "fs/promises";

const tika = "http://localhost:9998/tika"; // Apache Tika server URL
const tikaExtensions = [".pdf", ".html", ".xml", ".docx", ".xlsx", ".pptx", ".odt", ".rtf"];

/**
 * Extract text contents from a number of file formats using apache Tika 
 * If no suitable file type was found, try to interpret file contents as Plaintext
*/
export async function extractTextFromFile(filename: string): Promise<string> {

    let text = "";
    const contents = await fs.readFile(filename);
    if (tikaExtensions.some(ext => filename.endsWith(ext))) {
        console.log("Extracting text from " + filename + " using Apache Tika...");
        const response = await fetch(tika, {
            method: "PUT",
            body: contents
        });
        if (response.status !== 200) {
            throw new Error("Error extracting text from PDF: " + response.statusText);
        } else {
            text = await response.text();
        }
    } else {
        console.log("Reading text from file...");
        text = contents.toString();
    }
    return text;
}

Aufruf zum Beispiel mit bun src/index.ts dateiname.pdf, oder Einbinden in irgendeinen Import-Workflow