llm_aided_ocr: Tesseract-Ausgabe mit LLM-Korrektur nachbearbeiten
Enhances Tesseract OCR output using LLMs (local or API) for error correction, smart chunking, and markdown formatting of scanned PDFs
Auf einen Blick
- Was ist das?
- Das Projekt von Dicklesworthstone hängt eine zweistufige LLM-Nachbearbeitung hinter die Tesseract-OCR und gibt Markdown aus. Die Dokumentation deckt Pipeline, Konfiguration und Grenzen ab, lässt aber Fehlerraten und Lizenzfragen offen.
- Für wen ist es gedacht?
- Sinnvoll ist llm_aided_ocr für alle, die bereits Tesseract einsetzen und die Fehlerkorrektur an ein lokales GGUF-Modell oder eine API auslagern wollen; wer ausschließlich saubere digitale PDFs verarbeitet, braucht das Projekt nicht.
- Darf ich es kommerziell nutzen?
- Erst prüfen. Die Lizenz dieses Repositorys ordnen wir nicht automatisch ein; lesen Sie vor jeder kommerziellen Nutzung die LICENSE-Datei.
- Wird es noch gepflegt?
- Ja. Die letzten Commits kamen vor 44 Tagen.
- In welcher Sprache ist es geschrieben?
- Hauptsächlich Python, laut der Sprachstatistik von GitHub.
Die Antworten beruhen auf den GitHub-Daten des Projekts (zuletzt abgeglichen am 15. September 2026) und auf unserer Analyse. Sie sind keine Rechtsberatung.
TIEFGEHENDE OPEN-SOURCE-ANALYSE
Welches Problem die Nachbearbeitung überhaupt löst
Tesseract liefert bei gescannten Vorlagen bekanntermaßen Zeichenfehler: verwechselte Ziffern, zerfallene Ligaturen, falsch erkannte Satzzeichen. Wer solche Texte weiterverarbeitet, korrigiert sie bisher von Hand oder mit regelbasierten Ersetzungstabellen, die bei jeder neuen Schriftart neu gepflegt werden müssen. llm_aided_ocr setzt an dieser Stelle an und schiebt ein Sprachmodell zwischen Rohtext und Enddokument. Zielgruppe sind laut README Anwender, die gescannte PDFs in lesbares Markdown überführen wollen, also etwa Archivare, Redaktionen oder Entwickler, die Altbestände digitalisieren. Der Anspruch ist ausdrücklich nicht, OCR zu ersetzen. Tesseract bleibt die Texterkennung, das LLM arbeitet auf deren Ergebnis.
Vom PDF zum korrigierten Markdown: die Verarbeitungskette
Die Kette beginnt mit convert_pdf_to_images(), das über pdf2image Seiten in Bilder umwandelt. Über max_pages und skip_first_n_pages lässt sich nur ein Ausschnitt verarbeiten, was bei langen Scans praktisch ist, wenn man erst die Qualität prüfen will. Anschließend nimmt ocr_image() den Text mit pytesseract ab; vorher läuft preprocess_image() über das Bild und macht drei Dinge: Graustufen, binäre Schwellenwertbildung nach Otsu, Dilation zur Kontrastverstärkung. Danach übernimmt process_document(), zerlegt den Gesamttext an Satzgrenzen in Chunks und lässt benachbarte Chunks überlappen, damit der Kontext an den Nahtstellen nicht abreißt. Die eigentliche Arbeit macht process_chunk() in zwei Stufen: erst OCR-Korrektur unter Beibehaltung von Struktur und Inhalt, dann optional die Markdown-Formatierung mit Überschriften, Listen und Hervorhebungen. In diesem zweiten Schritt sitzt auch die Duplikaterkennung, die exakt oder nahezu identische Absätze entfernt. Wer Kopf- und Fußzeilen oder Seitenzahlen loswerden will, kann das über eine Option steuern, die diese Elemente entfernt oder gesondert formatiert.
Lokales Modell oder API: zwei Betriebsarten mit unterschiedlichem Verhalten
Das Projekt kennt zwei Wege zur Textgenerierung. Lokal läuft generate_completion_from_local_llm() über llama_cpp und erwartet ein GGUF-Modell; laut README werden eigene Grammatiken für strukturierte Ausgaben unterstützt. Für API-Betrieb stehen generate_completion_from_claude() und generate_completion_from_openai() bereit, jeweils mit Fehlerbehandlung und Wiederholungslogik. Der Unterschied reicht über die reine Herkunft der Antwort hinaus. Bei API-Anbietern verarbeitet das Projekt Chunks per asyncio nebenläufig und stellt die Reihenfolge danach wieder her, damit die Ausgabe zusammenhängend bleibt. Lokal ist das laut Beschreibung nicht der Fall, dort läuft die Inferenz sequenziell auf der eigenen GPU. Ein zweiter Punkt ist die Token-Steuerung: estimate_tokens() nutzt modellspezifische Tokenizer, wo vorhanden, und fällt sonst auf approximate_tokens() zurück. Darauf setzt eine dynamische Anpassung von max_tokens auf, die TOKEN_BUFFER und TOKEN_CUSHION einrechnet, um die Grenzen des jeweiligen Modells nicht zu reißen.
Installation und die Konfigurationsschlüssel in der .env
Die README beschreibt den Weg über pyenv und Python 3.12: pyenv install 3.12, dann im geklonten Verzeichnis pyenv local 3.12, ein venv anlegen, aktivieren und pip install -r requirements.txt. Tesseract kommt als Systempaket dazu, unter Ubuntu per sudo apt-get install tesseract-ocr, unter macOS per brew install tesseract, unter Windows über den Installer von UB-Mannheim. Konfiguriert wird über eine .env-Datei. Die README nennt vier Schlüssel im Beispiel: USE_LOCAL_LLM, API_PROVIDER, OPENAI_API_KEY und ANTHROPIC_API_KEY. Weitere Einstellungen existieren laut Text für Modellauswahl je Provider, Token-Grenzen und Puffergrößen sowie die Markdown-Optionen, sie werden aber nicht namentlich aufgeführt. Das ist eine konkrete Lücke: Wer USE_LOCAL_LLM=True setzen will, erfährt aus dem gezeigten Ausschnitt nicht, welcher Schlüssel auf das GGUF-Modell zeigt. Die Ausgabedateien folgen einem festen Muster: {base_name}__raw_ocr_output.txt für den Rohtext und {base_name}_llm_corrected.md oder .txt für das Ergebnis.
Qualitätsbewertung durch das Modell, das auch korrigiert
assess_output_quality() vergleicht den ursprünglichen OCR-Text mit der bearbeiteten Fassung und lässt ein LLM einen Qualitätswert samt Begründung liefern. Das ist als Fortschrittsanzeige brauchbar, methodisch aber angreifbar: Bewertet wird mit demselben Werkzeugtyp, der die Korrektur vorgenommen hat. Ein Modell, das eine Passage falsch geglättet hat, wird diese Glättung in der Bewertung kaum als Fehler markieren. Die README beschreibt nicht, ob ein anderes Modell oder ein separater Prompt für die Bewertung verwendet wird. Wer die Ausgabe fachlich prüfen muss, etwa bei juristischen oder medizinischen Texten, sollte diesen Score nicht als Freigabe verstehen. Er zeigt Trends über mehrere Läufe, ersetzt aber keine Stichprobe am Original.
Wo das Verfahren an Grenzen stößt
Der wichtigste Einwand betrifft die Art der Korrektur. Ein Sprachmodell, das fehlerhaften Text glätten soll, kann Inhalte verändern, ohne dass dies im Ergebnis sichtbar wird: Zahlen, Eigennamen und Negationen sind typische Kandidaten. Die README verspricht, die Korrektur bewahre Struktur und Inhalt, liefert aber keine Angabe dazu, wie oft das misslingt. Es gibt keine Fehlerrate, keinen Vergleich gegen ein manuell korrigiertes Referenzdokument, keine Aussage zur Reproduzierbarkeit bei temperaturabhängiger Generierung. Für Dokumente, bei denen jedes Zeichen zählt, ist das Projekt deshalb das falsche Werkzeug. Ein zweiter Fall: saubere, digital erzeugte PDFs. Dort hat Tesseract nichts zu tun, und eine LLM-Nachbearbeitung fügt nur eine Fehlerquelle hinzu. Drittens bleibt die Frage der Datenweitergabe. Im API-Betrieb verlässt der gesamte Dokumenttext die eigene Infrastruktur, was bei vertraulichen Scans ein Ausschlusskriterium sein kann. Der lokale Pfad vermeidet das, verlangt aber ein GGUF-Modell und eine GPU, deren Speicherbedarf die README nicht beziffert.
Was andere Werkzeuge anders machen
Der nächstliegende Vergleich ist OCRmyPDF. Dieses Werkzeug kombiniert Vorverarbeitung, Tesseract und das Einbetten einer durchsuchbaren Textebene direkt in das PDF; die Korrektur geschieht dort über Bildoptimierung und Tesseract-Parameter, nicht über ein Sprachmodell. Der Unterschied im Ansatz ist grundsätzlich: OCRmyPDF verbessert die Erkennung, llm_aided_ocr verbessert den bereits erkannten Text. Daraus folgen unterschiedliche Ausgaben. OCRmyPDF liefert ein durchsuchbares PDF, llm_aided_ocr liefert Markdown oder reinen Text und verliert das Seitenlayout. Für Ablage und Archivierung ist das ein Nachteil, für die Weiterverarbeitung in einem Redaktionssystem ein Vorteil. Wer beides braucht, müsste die Pipelines kombinieren, wozu die README nichts sagt. Eine zweite Alternative sind spezialisierte Document-AI-Dienste, die Layout und Text in einem Modell verarbeiten; sie sind nicht Open Source und arbeiten ebenfalls in der Cloud.
Wartung, Abhängigkeiten und die Lizenzfrage
Das Repository wird laut Metadaten weiter gepflegt, der letzte Push liegt bei August 2026, und es ist nicht archiviert. Veröffentlichte Releases gibt es allerdings keine, das Projekt wird also über den main-Branch bezogen. Für den Betrieb heißt das: Updates kommen als Commits, nicht als versionierte Pakete, und ein git pull kann Verhalten ändern, ohne dass eine Changelog-Datei darauf hinweist. Die Abhängigkeitsliste ist ungewöhnlich breit, weil sie pdf2image, pytesseract, llama_cpp sowie die SDKs von OpenAI und Anthropic nebeneinander führt, obwohl die README alle drei LLM-Pfade als optional bezeichnet. Wer nur einen Provider nutzt, installiert dennoch alles. Dazu kommen externe Voraussetzungen: Tesseract als Systempaket und bei lokalem Betrieb ein GGUF-Modell. Zur Lizenz lässt sich aus dem Material nichts Belastbares sagen. Die Metadaten nennen NOASSERTION, das heißt, es wurde keine standardisierte Kennung erkannt. Wer das Projekt kommerziell einsetzen will, muss die Lizenzdatei im Repository selbst prüfen und gegebenenfalls klären lassen; aus der README geht dazu nichts hervor. Das ist keine Rechtsberatung, sondern der Hinweis auf eine offene Angabe.
Redaktionelles Fazit
Sinnvoll ist llm_aided_ocr für alle, die bereits Tesseract einsetzen und die Fehlerkorrektur an ein lokales GGUF-Modell oder eine API auslagern wollen; wer ausschließlich saubere digitale PDFs verarbeitet, braucht das Projekt nicht. Vor dem ersten Lauf sollte man prüfen, ob requirements.txt und die .env-Datei tatsächlich die gewünschten Provider-Schlüssel enthalten, denn die README bricht mitten im Abschnitt Usage ab und zeigt weder einen vollständigen Aufruf des Skripts noch eine Beispielkonfiguration für USE_LOCAL_LLM=True.
Community-Notizen