OCR Verbesserung mit lokalem LLM

Hintergrund

Ich habe mittlerweile fast 2000 Dokumente in meiner PaperlessNGX Instanz und war mit der OCR-Qualität nicht wirklich zufrieden. Tools wie paperless-AI waren nur bedingt in der Lage wirklich gute Titel, Korrespondenten und tags zu finden weil der gespeicherte Text als input nicht wirklich gut war.
Ich habe paperless-GPT mit ollama zum Laufen gebraucht aber es hat sich beständig geweigert Dokumente mit auto-OCR tag zu prozessieren und eine Aktualisierung des Textinhalts in PaperlessNGX war nur bei manuellem Prozessieren möglich.

Lösung: Python Skript

Hier ist eine Übersicht der derzeit implementierten Funktionen:

  • Automatisierte Pagination: Das Skript erkennt automatisch, wenn mehr als 50 Dokumente vorhanden sind, und arbeitet sich selbstständig durch alle (z. B. 2000+) Dokumente, indem es die API-Seiten nacheinander abruft.

  • Echtzeit-Statusbericht: Nach jedem verarbeiteten Dokument wird eine übersichtliche Tabelle ausgegeben, die den aktuellen Fortschritt in Prozent sowie die Anzahl der erfolgreichen und fehlgeschlagenen Aufgaben anzeigt.

  • Intelligentes Tag-Filtering: Durch die Integration eines Tag nach erfolgreicher Prozessierung (ocr-done) überspringt das Skript bereits bearbeitete Dokumente zuverlässig und verhindert Endlosschleifen. (Tag-Name und ID sind konfigurierbar)

  • Multithreading (Producer-Consumer-Modell): Während die KI (Ollama) noch ein Dokument analysiert, lädt das Skript im Hintergrund bereits die nächsten Dateien herunter, um die Hardware optimal auszulasten.

  • Lokales Caching: Bilder und Metadaten werden zwischengespeichert. Sollte das Skript abstürzen, muss es die bereits heruntergeladenen Seiten nicht erneut konvertieren.

  • Seitenbegrenzung: Um Ressourcen zu sparen, ist das OCR standardmäßig auf die ersten 3 Seiten pro Dokument limitiert (konfigurierbar), fügt aber einen Hinweis auf die Gesamtzahl der Seiten in Paperless hinzu.

  • Automatischer PDF-Ersatz: Das Skript erstellt ein neues, durchsuchbares PDF aus den OCR-Texten und ersetzt die Originaldatei in Paperless-ngx über die /replace_document/ Schnittstelle.

  • Detailliertes Logging: Durch die „Flush“-Funktion wird jede Aktion (Download, Konvertierung, API-Antwort) sofort im Terminal angezeigt, sodass du den Fortschritt live verfolgen kannst.

  • Trennung von Konfiguration und Code mittels .env Datei

  • Trennung von Code und LLM Anweisungen: Der Verwendete Prompt wurde für das verwendete minicpm-v Modell und deutsche Dokumente “optimiert”. Da gibt es je nach Dokumententypen sicher Potenzial zur Verbesserung.

Das Script läuft bei mir auf einem MacMini M4 (Basismodell) stabil im Hintergrund, ohne die Maschine zu überlasten.

Haftungsausschluss

  • Vibe coded!
  • Benutzung des Skriptes auf eigene Verantwortung!
  • macht vor der Benutzung unbedingt ein Backup Eurer PaperlessNGX Instanz mit dem document_exporter

Projekt auf Github: GitHub - helmerj/paperless-ai-ocr: AI-OCR for PaperlessNGX with pagination and status reporting using Ollama

LG Jürgen

Lieber @juergenhelmers !

Wow, tolles Skript!

Ich hab’s noch nicht ausprobieren können, da ich eine andere Konfiguration habe als Du und arbeite mit einem spark (llm) und synology (paperless-ngx) Server.
Deswegen bin ich noch bei der Analyse Deines Skripts und da ist bei mir eine Frage aufgetaucht, die ich mir selbst nicht beantworten kann:

Durch den Befehl: PDFProcessor.from_text() wird ein reines Text-PDF ohne Scan-Bild erzeugt. Das würde bedeuten, dass das Original-Scanbild verloren geht – nur der erkannte Text bleibt als Seite. Das neue PDF müsste daher nur Text in Helvetica auf weißem Hintergrund enthalten und das original Dokumenten-Layout würde verloren gehen.

Da Du in Deiner Beschreibung etwas ähnliches schreibst (automatischer PDF-Ersatz über die replacement_document Schnittstelle), wie muss ich mir dieses Replacement dann tatsächlich vorstellen (mit Scanbild und neuem OCR text im Hintergrund oder nur neuer Text) und befindet sich noch irgendwo das Original?

Grüße, Alexander

Hey Alexander,

Das Skript ersetzt die Text Layer in Deinem PDF Dokument und aktualisiert das content Feld in paperlessNGX. Du kannst das Skript ja mit einem Dokument oder einer Tag Gruppe testen :slight_smile:

Bei mir lauft das seit vorgestern im Hintergrund (7 OCR Prozesse parallel) und macht bis auf wenige time outs eine guten Job.

LG Jürgen

Hallo Jürgen,

hab ein Update vom Workflow eingestellt:

Falls noch Interesse besteht PN an mich.

Gruß Heiko