formula_img2latex/CHANGELOG.md
dschlueter 6373db73a4 feat: Formeln im Fließtext (pdf2md --formulas), etwa dreimal schneller
- 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>
2026-10-10 03:31:57 +02:00

136 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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-*.json` vermerkt. "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`, `\textbf` als
Fettdruck, `\cfrac` = `\frac` (pix2text schreibt `\dfrac`), wörtliches `\n` aus 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.
- **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
`pdftext` bleibt aus.
- pix2texts eigene Sicherheit: Fehler auch bei 1,0.
- Qwen3-VL-8B: nicht schneller als das MoE-30B-Modell (3B aktiv), etwas schlechter.
- **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`/`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.