- pdf2md-Formelliste lesen: jede Formel mit Seite/Rechteck/PDF-Text, 300-dpi-Bild - eingebettete Formeln: Satzzeichen am Ende abgetrennt, als Text dahinter (final_suffix) - Normalform: \underset-Grenzwerte, Gleichungsnummer als \tag, \textbf, \cfrac, wörtliches \n - Tempo: Verweis- und Ausschnitt-Cache, pix2text gebündelt nach Pixelbudget, Lesen und Prüfen überlappend (forkserver), Qwen 8 Plätze, Render-Vorfilter, kein neuer Scan, je Paket nur dessen Datensätze, Zeiten je Stufe - Bildprüfung: max. 1600 px Breite, 2,5 MP, Proportionen-Abbruch - gemessen und abgeschaltet: PDF-Textebene als Bestätigung (pdftext=0) - Corral 10 %: 79 % automatisch, Pilot 869 Formeln 70 → ~24 min Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
9.9 KiB
9.9 KiB
Changelog
Unveröffentlicht
Alle Formeln eines PDF-Buchs, auch im Fließtext, und etwa dreimal schneller.
- pdf2md --formulas (Nachbarprojekt): Die Formelerkennung von pix2text (MFD) findet jede Formel auf der
Seite, eingebettet oder abgesetzt, auch in Merkkästen. Sie wird zeichengenau aus dem Text geschnitten
(300 dpi) und mit Seite, Rechteck und PDF-Text in
formulas-*.jsonvermerkt. "Formel"-Boxen mit Text werden zu Text, solche mit Kurven zu Grafiken. formula_img2latex liest die Liste (sources/pdf2md.listed). Corral, 10 % der 9239 Formeln: 79 % automatisch (im Text 83 %). - Eingebettete Formeln: Ein Satzzeichen am Ende wird vor dem Vergleich abgetrennt und als Text hinter
die Formel gesetzt (
final_suffix). - Normalform:
\underset{…}{\lim}=\lim_{…}, Gleichungsnummer am Ende =\tag,\textbfals Fettdruck,\cfrac=\frac(pix2text schreibt\dfrac), wörtliches\naus Modellantworten entfällt. - Tempo (Pilot 869 Formeln: 70 → ~24 min):
- Markdown-Verweise und Ausschnitte nur einmal lesen (
crops/); - pix2text gebündelt nach Pixelbudget, auf der freiesten GPU, einmal geladen;
- Lesen und Prüfen überlappen, die Prüfprozesse starten per
forkserver; - Qwen mit 8 parallelen Anfragen (
llama-server --parallel 8 -c 32768); - pdflatex beim Entscheiden nur, wenn gleiche Bilder möglich sind;
- kein neuer Scan beim Fortsetzen;
- je Paket nur dessen Datensätze laden;
- Zeiten je Stufe in der Statuszeile.
- Markdown-Verweise und Ausschnitte nur einmal lesen (
- Bildprüfung: Originale höchstens 1600 px breit, über 2,5 MP nicht, Lesarten mit mehr als 2,5-fach falschen Proportionen sofort abgelehnt. Vorher hielten einzelne Formeln den Lauf über 10 Minuten auf.
- Gemessen und verworfen:
- PDF-Textebene als Bestätigung: 12 von 319 widersprachen Qwen, fehlende Punkte und Indizes; Schalter
pdftextbleibt aus. - pix2texts eigene Sicherheit: Fehler auch bei 1,0.
- Qwen3-VL-8B: nicht schneller als das MoE-30B-Modell (3B aktiv), etwas schlechter.
- PDF-Textebene als Bestätigung: 12 von 319 widersprachen Qwen, fehlende Punkte und Indizes; Schalter
- Offen: Formeln in Tabellen.
0.4.0 – 2026-10-09
Bessere Normalform: Lesarten, die sich nur in der Schreibweise unterscheiden, gelten als gleich. Göllmann (400 Formeln mit bekannter Lösung, gleiche Lesarten): +17 automatisch, weiterhin 0 falsch.
- Mehrzeilige Formeln: gleich bei gleichen Zeilen mit gleichen Zeichen, egal in welchem Rahmen
(
aligned/gathered/splitmit&oder nur\\;cases=\left\{array\right.=\left\{aligned\right.); eine leere letzte Zeile zählt nicht. In Matrizen trennt&weiter Spalten. - Argumente nach Argumentzahl: Eine Gruppe ist nur Argument, wenn der Befehl noch eines erwartet
(
t^{2}\,{\sqrt{2}}=t^2\sqrt{2},\Delta{x_{n}}=\Delta x_n). - Weitere Gleichsetzungen:
\cdot\cdot\cdotund...=\dots,\root3\of{x}=\sqrt[3]{x},\left./\right.entfallen. - Messung genauer: Der Wahrheitsvergleich nutzt dieselbe Normalform; richtige mehrzeilige Lesarten zählten bisher als falsch (pix2text allein richtig: Band 2 jetzt 45/50 und 47/50).
- Ergebnis: Band 1 89 % / 88 % automatisch (bisher 86 % / 85 %), Band 2 44 und 45 von 50 (bisher 39 und 43), 0 falsch.
- Strukturvergleich mit sympy (
structure.py, neu, optional, aus): gleicher unausgewerteter Ausdrucksbaum, nichts umgerechnet; Relationen nie an sympy, Zeichen durch Platzhalter geschützt. Brachte vor der neuen Normalform +1 Formel, danach nichts –structural= 1 bzw.FORMULA_STRUCTURAL=1schaltet ihn ein (pip install sympy lark). - Bild-Schiedsrichter (
verify.image_arbiter, gemessen, aus): bei „Qwen = Gemma gegen pix2text“ entscheidet der Bildbeleg. +11 Formeln ab Schwelle 8, aber der gemeinsame Fehler\mathcal{E}_rbekam Beleg 7,2 – zu knapp. Einstellungenarbiter,arbiter_margin. - Prompt-Stilvorgabe getestet und verworfen (Band 2: 44/44 statt 44/45; die Modelle schrieben nach
\\ein wörtliches\n). Prompt-Version bleibt 2, gespeicherte Lesarten bleiben gültig. - Werkzeuge:
tools/vergleich_bericht.py(Vorher/Nachher-Seite zweier Läufe),regeltest.py --refresh(Engines trotz--reuseneu fragen) und--arbiter;calibratemisst den Schiedsrichter (Werte je Fall, Schwellen) und listet nur strukturell gefundene Übereinstimmungen;tools/buch_bericht.py(Ergebnisseite eines ganzen Buchs: jede Formel mit Original, gesetztem LaTeX, Status, Begründung und allen Lesarten, filterbar). - Erstes ganzes PDF-Buch (Corral, Elementary Calculus, 346 Seiten, pdf2md): 1150 Ausschnitte,
429 automatisch ersetzt (37 %), 633 Review, 61 keine Formel. Gefundene und behobene Probleme:
- pix2text schreibt hier Brüche als
\cfrac: in der Normalform =\frac, beim Bereinigen zu\dfrac(Pandoc kennt\cfracnicht und ließ die Formel als TeX-Text stehen). - Qwen und Gemma schreiben Zeilenumbrüche als wörtliches
\n(\begin{aligned}\n…): wird zu Leerraum (tex.fix_literal_newlines), echte Befehle wie\nu,\neqbleiben. - 600-dpi-Ausschnitte bis 3800 × 2700 Pixel: Qwen lehnte sie ab („400 Bad Request“, Kontext voll), eine ganzseitige Abbildung (33 MP) brachte den Bildvergleich zum Absturz. Jetzt: Bilder für die Modelle höchstens 1600 Pixel lang, Bildvergleich nur bis 4 MP (größte übernommene Formel: 1,7 MP).
- Fehlgeschlagene Modellanfragen werden beim nächsten Lauf wiederholt (zählten als „schon gefragt“).
- Göllmann danach unverändert: 0 falsch.
- Grenze: pdf2md schneidet in diesem Buch auch Merkkästen mit Text, Tabellen und ganze Herleitungsblöcke als „Formel“ aus; sie bilden den Großteil des Reviews.
- pix2text schreibt hier Brüche als
0.3.0 – 2026-10-09
Neue Standardregel p2t: pix2text liest zuerst, Qwen bestätigt, Gemma nur bei Uneinigkeit; GLM (Cloud)
wird nicht mehr benutzt.
- pix2text (Formel-OCR MFR 1.5, ONNX) als Engine
p2t, im Prozess, auf der GPU mitonnxruntime-gpu(FORMULA_P2T_DEVICE:auto,cpu,cuda:N). Allein am häufigsten richtig (Göllmann Band 1: 90 % / 85 %) und am schnellsten (0,1 s/Formel auf der GPU, Qwen 0,7 s, Gemma 1,8 s). - Regel: übernommen wird immer pix2texts Lesart (trifft den Fettdruck am besten), wenn Qwen sie
bestätigt oder – nur bei Uneinigkeit gefragt – Gemma. Qwen und Gemma gemeinsam gegen pix2text gehen
an einen Menschen (so kamen an Band 1 die gemeinsamen Fehler der beiden Bildmodelle durch). Der
Schlusspunkt muss bestätigt sein. Bild-Veto und Pandoc wie bisher, geprüft auf pix2texts Lesart.
Die alte Regel bleibt als
"consensus_rule": "vlm3"inworkspace.jsonwählbar. - pix2text-Ausgabe bereinigt: Leerzeichen mit
post_processaus pix2tex (installiert mit--no-deps), Fettschreibweisen\mathrm{\boldmath~ x ~}/\mathrm{\bf~ r o t}→\boldsymbol{x}/\mathbf{rot}. An 400 Lesarten geprüft: gleiches gesetztes Bild. - Normalform:
\operatorname{l i m}=\lim,\ddot{u}in Text = ü,^{\prime}=', abschließendes\\vor\end,\begin{array}[t],\mathop{…}. - calibrate: beliebig viele Engines (
--engines), Regel-Tabelle,--reuserechnet aus einem früheren Bericht ohne Modellabfragen; wahre Formeln aus dem alt-Text werden bereinigt (einzeiligesaligned,\mathop{}\!\mathrm{d}, upgreek). - Werkzeuge:
tools/zeittest.py(Zeit und Trefferquote je Tool),tools/regeltest.py(Standardregel an Formeln mit bekanntem TeX, Seite zum Mitbeurteilen;--reuse,--exclude). - Messung: Göllmann Band 1 (2 × 150) 86 % / 85 % automatisch, 0 falsch (bisher 78 % / 70 %); Band 2, zwei frische Stichproben zu 50: 78 % und 86 % automatisch, 0 falsch.
0.2.0 – 2026-10-07
Entscheider ist jetzt der Konsens dreier Bildmodelle statt eines Pixelvergleichs.
- Annahmeregel: jedes Zeichen richtig und an der richtigen Stelle; Abstände, Längen, Schriftgröße, kursiv/aufrecht und Fettdruck egal.
- Konsens: Qwen3-VL-30B-A3B (lokal) = Gemma-4-26B-A4B (lokal) = GLM-4.6V (OpenRouter, andere Modellfamilie); Pandoc muss die Formel umsetzen; grobes Bild-Veto (elastischer Vergleich, Ähnlichkeit ≥ 0,65). Bei 2:1 entscheidet ein Mensch.
consensus.py: Normalform auf Baumbasis (Abstände,\left/\right, freistehende Klammern,\vec/\overrightarrow,\frac/\dfrac,\iff/\Leftrightarrow, Matrix-Umgebungen, TeX-Umlaute,\atop/\substack, kursiv/aufrecht, fett/normal) und Render-Gleichheit als Rückfallebene.- Engines: zweite lokale Engine
local2; Token-Wahrscheinlichkeiten aus Logprobs; Nachdenken abgeschaltet (Gemma ~10× schneller, GLM besser und ~25× billiger); Antworten auf 800 Tokens begrenzt; Prompt fragt ausdrücklich nach Fettdruck; Prompt-Version und Nachdenk-Einstellung im Cache-Schlüssel. run: in Paketen zu 50 mit Statuszeile; beide lokalen Modelle parallel; GLM nur für Einige; geprüft wird nur die übernommene Lesart; Prüfergebnisse mit Verfahrensversion.- Bildvergleich: elastische Ausrichtung (DTW über Spalten und Zeilen, Dehnen kostet proportional zur
Tinte); layouttreue Prüfvarianten und rauschnormierter Kontrast im Pixel-Modus (
decide=pixel). - apply: deutsches Dezimalkomma
3{,}6. - Behoben: Gleichungsnummern wurden aus alten, verworfenen Lesarten übernommen (erfundene „(3.7)“); sie kommen jetzt nur aus der übernommenen Lesart. Gleichzeitige Speicherungen zweier Engines sind abgesichert. Verify stürzte bei Formeln ohne aktuelle Lesart ab.
- Werkzeuge:
calibrate --consensus,tools/vergleich.py(50er-Stichprobe mit Bildern),tools/konsens_bericht.py; Ausgaben invergleich/(nicht versioniert). - Messung (2 × 150 Formeln mit bekanntem TeX): 63–68 % automatisch, 0 falsch. Gehrke-Brückenkurs: 942 von 1505 automatisch (63 %), 62 von 62 geprüften korrekt.
0.1.0 – 2026-10-07
Erste Fassung: scan, recognize (ein Vision-Modell), verify mit Pixelvergleich und Kontrasttest gegen Verwechslungsvarianten, Review-Galerie, apply/revert, calibrate. Sicher (0 Falsch-Annahmen), aber an echten Büchern nur 1–2 % automatisch.