formula_img2latex/CHANGELOG.md
dschlueter 2478bc5cb9 feat: 0.4.0 – mehrzeilige Normalform, erstes ganzes PDF-Buch
Normalform (Göllmann, 400 Formeln: +17 automatisch, weiterhin 0 falsch):
- mehrzeilige Formeln gleich bei gleichen Zeilen, egal in welchem Rahmen
  (aligned/&/\\, cases = \left\{array\right. = \left\{aligned\right.),
  leere letzte Zeile zählt nicht; Matrizen behalten & als Spaltentrenner
- Argumente nach Argumentzahl des Befehls (t^{2}\,{\sqrt{2}} = t^2\sqrt{2})
- \cdot\cdot\cdot = \dots, \root3\of{x} = \sqrt[3]{x}, \left./\right. entfallen,
  \cfrac = \frac; wörtliche \n aus Modellantworten werden zu Leerraum

Gemessen und abgeschaltet bzw. verworfen:
- Strukturvergleich mit sympy (structure.py, optional, FORMULA_STRUCTURAL=1):
  nach der neuen Normalform kein Gewinn mehr
- Bild-Schiedsrichter (verify.image_arbiter, arbiter=0): der gemeinsame
  Fehler \mathcal{E}_r bekam Beleg 7,2 – Abstand zu knapp
- Prompt-Stilvorgabe: kein Gewinn, Prompt-Version bleibt 2

Ganzes PDF-Buch (Corral, Elementary Calculus): 429 von 1123 automatisch.
- Bilder für die Modelle höchstens 1600 Pixel (Qwen lehnte große ab),
  Bildvergleich nur bis 4 MP (ganzseitige Abbildung brachte ihn zum Absturz)
- fehlgeschlagene Modellanfragen werden wiederholt
- pix2text: \cfrac -> \dfrac (Pandoc kennt \cfrac nicht)

Werkzeuge: tools/buch_bericht.py (Ergebnisseite eines Buchs),
tools/vergleich_bericht.py (Vorher/Nachher), regeltest --refresh/--arbiter,
calibrate misst Schiedsrichter und strukturelle Treffer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:30:15 +02:00

7.9 KiB
Raw Blame History

Changelog

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/split mit & 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\cdot und ... = \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=1 schaltet 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}_r bekam Beleg 7,2 – zu knapp. Einstellungen arbiter, 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 --reuse neu fragen) und --arbiter; calibrate misst 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 \cfrac nicht 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, \neq bleiben.
    • 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.

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 mit onnxruntime-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" in workspace.json wählbar.
  • pix2text-Ausgabe bereinigt: Leerzeichen mit post_process aus 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, --reuse rechnet aus einem früheren Bericht ohne Modellabfragen; wahre Formeln aus dem alt-Text werden bereinigt (einzeiliges aligned, \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 in vergleich/ (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.