feat: 0.3.0 – pix2text zuerst, Qwen bestätigt, Gemma nur bei Uneinigkeit
Neue Standardregel p2t (GLM/Cloud wird nicht mehr benutzt):
- pix2text liest zuerst; übernommen wird immer seine Lesart, wenn Qwen sie
bestätigt oder – nur bei Uneinigkeit gefragt – Gemma. Qwen = Gemma gegen
pix2text geht an einen Menschen. Schlusspunkt muss bestätigt sein; Bild-Veto
und Pandoc auf pix2texts Lesart. Alte Regel als consensus_rule=vlm3 wählbar.
- pix2text auf der GPU (onnxruntime-gpu, FORMULA_P2T_DEVICE=auto/cpu/cuda:N)
- Ausgabe bereinigt: post_process aus pix2tex, Fettschreibweisen \boldmath/\bf
-> \boldsymbol/\mathbf; an 400 Lesarten gleiches gesetztes Bild
- Normalform: \mathop, \begin{array}[t]
- calibrate: --engines, Regel-Tabelle, --reuse; wahre Formeln aus dem alt-Text
bereinigt (aligned, \mathop{}\!, upgreek)
- tools/zeittest.py, tools/regeltest.py (--reuse, --exclude)
Messung: Göllmann Band 1 (2 x 150) 86 % / 85 % automatisch, 0 falsch
(bisher 78 % / 70 %); Band 2, zwei Stichproben zu 50: 78 % und 86 %, 0 falsch.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
41bfe9fc26
commit
4638a12571
1 changed files with 941 additions and 98 deletions
72
README.md
72
README.md
|
|
@ -3,7 +3,8 @@
|
|||
Nachbearbeitungs-Werkzeug für die Markdown-Ausgaben von
|
||||
[epub2md](https://kitux.de/forgejo/dschlueter/epub2md) und
|
||||
[pdf2md](https://kitux.de/forgejo/dschlueter/pdf2md): Formeln, die nur als Bild vorliegen, werden durch
|
||||
LaTeX ersetzt – **aber nur, wenn drei unabhängige Bildmodelle dieselbe Formel lesen** und ein grober
|
||||
LaTeX ersetzt – **aber nur, wenn zwei unabhängige Erkenner dieselbe Formel lesen** (zuerst das Formel-OCR
|
||||
pix2text, bestätigt vom Bildmodell Qwen; bei Uneinigkeit darf Gemma pix2text bestätigen) und ein grober
|
||||
Bildabgleich nicht widerspricht. Alles andere geht in eine Review-Galerie oder bleibt Bild.
|
||||
|
||||
Schritt-für-Schritt-Anleitung: [BEDIENUNGSANLEITUNG.md](BEDIENUNGSANLEITUNG.md). Änderungen je Version:
|
||||
|
|
@ -14,13 +15,22 @@ Schritt-für-Schritt-Anleitung: [BEDIENUNGSANLEITUNG.md](BEDIENUNGSANLEITUNG.md)
|
|||
> Jedes Zeichen muss stimmen und an der richtigen Stelle relativ zu den anderen stehen. Abstände,
|
||||
> Pfeil- und Bruchstrichlängen, Schriftgröße, kursiv/aufrecht und Fettdruck dürfen abweichen.
|
||||
|
||||
Eine Formel wird automatisch ersetzt, wenn
|
||||
Eine Formel wird automatisch ersetzt (Regel `p2t`, Standard), wenn
|
||||
|
||||
1. **Qwen3-VL-30B-A3B** (lokal, llama.cpp) und **Gemma-4-26B-A4B** (lokal) dieselbe Formel lesen,
|
||||
2. **GLM-4.6V** (Cloud über OpenRouter, andere Modellfamilie) das bestätigt – ein fehlender Schlusspunkt
|
||||
zählt dabei nicht,
|
||||
3. Pandoc sie nach MathML umsetzen kann (sonst bliebe sie im EPUB/PDF roher TeX-Text) und
|
||||
4. das gerenderte LaTeX dem Original grob ähnelt (Bild-Veto, elastischer Vergleich, Ähnlichkeit ≥ 0,65).
|
||||
1. **pix2text** (Formel-OCR MFR 1.5, lokal, GPU) sie zuerst liest und **Qwen3-VL-30B-A3B** (Bildmodell,
|
||||
lokal, llama.cpp) dieselbe Formel liest **oder**, wenn die beiden uneinig sind, **Gemma-4-26B-A4B**
|
||||
(lokal) die Lesart von pix2text bestätigt. Übernommen wird immer **pix2texts Lesart** – sie trifft den
|
||||
Fettdruck am besten. Ihre überflüssigen Leerzeichen entfernt vorher `post_process` aus pix2tex (LaTeX-OCR):
|
||||
`\frac{\alpha} {3 6 0}` → `\frac{\alpha}{360}`; am gesetzten Bild ändert das nichts, geprüft an
|
||||
400 Lesarten. Auch der Schlusspunkt muss bestätigt sein,
|
||||
2. Pandoc sie nach MathML umsetzen kann (sonst bliebe sie im EPUB/PDF roher TeX-Text) und
|
||||
3. das gerenderte LaTeX dem Original grob ähnelt (Bild-Veto, elastischer Vergleich, Ähnlichkeit ≥ 0,65).
|
||||
|
||||
Sind Qwen und Gemma gemeinsam gegen pix2text einig, entscheidet ein Mensch: Genau das sind die Fehler,
|
||||
die beide Bildmodelle teilen (`\mathcal{E}_r` statt `\varepsilon_r`, erfundenes `\tilde{z}`).
|
||||
|
||||
Die frühere Regel `vlm3` (Qwen = Gemma, bestätigt von **GLM-4.6V** über OpenRouter) bleibt wählbar:
|
||||
`"consensus_rule": "vlm3"` unter `settings` in `workspace.json` des Arbeitsordners.
|
||||
|
||||
„Dieselbe Formel“ prüft `consensus.py`: gleiche Normalform (Abstände, `\left`/`\right`, überflüssige
|
||||
Klammern, `\vec`/`\overrightarrow`, `\frac`/`\dfrac`, `\iff`/`\Leftrightarrow`, `pmatrix`/`\left(\begin{matrix}`,
|
||||
|
|
@ -32,6 +42,25 @@ Sind sich die Modelle uneinig oder widerspricht das Veto, entscheidet ein Mensch
|
|||
|
||||
## Messung
|
||||
|
||||
### Regel `p2t` (Standard)
|
||||
|
||||
Göllmann Band 1, 150 echte Bilder und 150 Nachbildungen im Gehrke-Stil, Lesarten aller Modelle:
|
||||
|
||||
| Regel | echt: automatisch / falsch | Gehrke-Stil: automatisch / falsch |
|
||||
| --- | --- | --- |
|
||||
| pix2text = Qwen | 81 % / 0 | 76 % / 0 |
|
||||
| + Stichwahl: Gemma bestätigt pix2text, Qwens Lesart (erste Fassung) | 85 % / 0 | 80 % / 0 |
|
||||
| **pix2text zuerst und übernommen, bereinigt, Stichwahl Gemma** (Standard) | **86 % / 0** | **85 % / 0** |
|
||||
| + Stichwahl auch Qwen = Gemma gegen pix2text | 92 % / 1 | 91 % / 2 |
|
||||
| Qwen = Gemma = GLM (Regel `vlm3`) | 78 % / 0 | 70 % / 0 |
|
||||
|
||||
Allein richtig: pix2text 90 % / 85 %, Qwen 86 % / 84 %, Gemma 86 % / 80 %, GLM 86 % / 83 %.
|
||||
Zeit je Formel (seriell, 15 Formeln): pix2text 0,10 s (GPU) bzw. 0,51 s (CPU), Qwen 0,72 s, GLM 1,19 s,
|
||||
Gemma 1,77 s. Gegenprobe an 50 frischen Formeln aus Göllmann Band 2 (`tools/regeltest.py`):
|
||||
37 automatisch (74 %), **0 falsch**, 13 Review; Gemma wurde für 16 Formeln gefragt.
|
||||
|
||||
### Regel `vlm3` (Standard bis 0.2.0)
|
||||
|
||||
An Formelbildern mit bekanntem TeX (Göllmann, Springer: TeX im alt-Text), je 150 echte Bilder und 150
|
||||
Nachbildungen im Stil von Gehrke (LaTeX + dvipng mit Bitmap-Schriften, ~102 dpi, JPEG):
|
||||
|
||||
|
|
@ -63,12 +92,12 @@ Gehrke, Brückenkurs Mathematik (EPUB, 1505 Formelbilder): siehe [Stand](#stand)
|
|||
|
||||
```text
|
||||
scan Bildverweise in chapters/*.md (bzw. pdf2md-Markdown) finden, Formel/Abbildung vorklassifizieren
|
||||
run in Paketen zu 50: Qwen + Gemma lesen (parallel), prüfen, GLM nur für Einige, prüfen;
|
||||
nach jedem Paket eine Statuszeile
|
||||
run in Paketen zu 50: pix2text, dann Qwen lesen, prüfen, Gemma nur für Uneinige, prüfen;
|
||||
nach jedem Paket eine Statuszeile (Regel vlm3: Qwen + Gemma, GLM nur für Einige)
|
||||
review Zweifelsfälle im Browser: Original / Render / Overlay / Diff, LaTeX korrigieren und neu prüfen
|
||||
apply angenommene Formeln ins Markdown schreiben (aus einer Sicherung, idempotent)
|
||||
revert Markdown-Dateien auf den Stand vor apply zurücksetzen
|
||||
recognize einzelne Engine (local, local2, cloud) laufen lassen
|
||||
recognize einzelne Engine (local, local2, cloud, p2t) laufen lassen
|
||||
verify prüfen und entscheiden (ohne neue Modellabfragen)
|
||||
status Zählung je Status
|
||||
calibrate Messung an Formelbildern mit bekanntem TeX (--consensus: Konsensregel)
|
||||
|
|
@ -90,14 +119,19 @@ Status je Formel: `auto_accepted`, `needs_review`, `rejected_keep_image`, `rende
|
|||
| --- | --- | --- |
|
||||
| `local` | llama.cpp `http://127.0.0.1:8011/v1` (Qwen3-VL-30B-A3B-Instruct Q4_K_M + mmproj) | `FORMULA_LOCAL_URL`, `FORMULA_LOCAL_MODEL` |
|
||||
| `local2` | llama.cpp `http://127.0.0.1:8012/v1` (Gemma-4-26B-A4B-it Q4_0 + mmproj) | `FORMULA_LOCAL2_URL`, `FORMULA_LOCAL2_MODEL` |
|
||||
| `cloud` | OpenRouter, `z-ai/glm-4.6v` | `OPENROUTER_API_KEY`, `FORMULA_CLOUD_MODEL` |
|
||||
| `cloud` | OpenRouter, `z-ai/glm-4.6v` (nur Regel `vlm3`) | `OPENROUTER_API_KEY`, `FORMULA_CLOUD_MODEL` |
|
||||
| `p2t` | pix2text MFR 1.5 (ONNX) im Prozess, erste sichtbare GPU, sonst CPU | `FORMULA_P2T_DEVICE` (`auto`, `cpu`, `cuda:N`), `FORMULA_P2T_MODEL` |
|
||||
|
||||
pix2text auf der GPU braucht `onnxruntime-gpu` statt `onnxruntime` (cuDNN kommt aus den nvidia-Paketen
|
||||
von torch). Für `post_process` wird `pix2tex` ohne seine Abhängigkeiten installiert
|
||||
(`pip install --no-deps pix2tex munch`), weil es sonst `timm==0.5.4` erzwingen würde. `cuda:N` zählt innerhalb von `CUDA_VISIBLE_DEVICES`.
|
||||
|
||||
`FORMULA_<ENGINE>_THINKING=1` schaltet das Nachdenken wieder ein. Antworten sind auf 800 Tokens begrenzt
|
||||
(lange mehrzeilige Formeln brauchen ~400; einzelne Antworten von Gemma liefen sonst in
|
||||
Wiederholungsschleifen bis 165 s). Jede Lesart wird mit Modell, Prompt-Version und Nachdenk-Einstellung
|
||||
gespeichert; dieselbe Frage wird nie zweimal gestellt, ein abgebrochener Lauf setzt dort fort.
|
||||
|
||||
Kosten der Cloud-Stufe: GLM liest nur Formeln, bei denen Qwen und Gemma einig sind. Gehrke: 967
|
||||
Kosten der Cloud-Stufe (nur Regel `vlm3`): GLM liest nur Formeln, bei denen Qwen und Gemma einig sind. Gehrke: 967
|
||||
Anfragen, Ø 2,6 s, zusammen rund 0,15–0,20 $.
|
||||
|
||||
## Bildvergleich (Veto)
|
||||
|
|
@ -105,9 +139,9 @@ Anfragen, Ø 2,6 s, zusammen rund 0,15–0,20 $.
|
|||
`compare.py` rendert die Lesart mit pdflatex (Schrift je Buch automatisch: `cm`, `times`, `txfonts`,
|
||||
`palatino`, `stix`, `euler`), richtet sie auf das Original aus und verzerrt sie **elastisch**
|
||||
(dynamische Zeitverzerrung über Spalten und Zeilen; Dehnen kostet proportional zur Tinte), damit
|
||||
Abstände und Längen keine Rolle spielen. Die Ähnlichkeit danach ist das Veto. Geprüft wird nur die
|
||||
Lesart, die übernommen würde (die von Qwen; im Konsens ist sie gleichwertig zu den anderen) – eine
|
||||
später eintreffende dritte Lesart löst keine neue Prüfung aus. Die Prüfergebnisse tragen eine
|
||||
Abstände und Längen keine Rolle spielen. Die Ähnlichkeit danach ist das Veto. Geprüft wird nur
|
||||
die Lesart, die übernommen werden kann: die von pix2text (Regel `vlm3`: die von Qwen). Bestätigende
|
||||
Lesarten werden nie übernommen und brauchen keine Prüfung. Die Prüfergebnisse tragen eine
|
||||
Versionsnummer des Verfahrens und werden nach Änderungen neu berechnet. Der alte Pixel-Entscheider mit
|
||||
Verwechslungsvarianten und Kontrasttest bleibt als Modus `decide=pixel` erhalten.
|
||||
|
||||
|
|
@ -145,6 +179,11 @@ sind nicht Teil dieser Version.
|
|||
- `tools/vergleich.py AUSGABE` – feste Stichprobe (50 Formeln), verarbeitet wie `run`, schreibt
|
||||
`vergleich/<name>/index.html` mit Original, gerenderten Lesarten, Entscheidung und Veto-Overlay.
|
||||
- `tools/konsens_bericht.py BERICHT.json EPUB` – Übersichtsseite zu `calibrate --consensus --report`.
|
||||
- `tools/zeittest.py EPUB` – Zeit und Trefferquote je Tool, seriell an 15 Formeln mit bekanntem TeX.
|
||||
- `tools/regeltest.py EPUB [--n 50] [--reuse ergebnis.json]` – die Standardregel an Formeln mit bekanntem
|
||||
TeX, wie `run`; Seite mit Original, wahrer Formel, allen Lesarten und Entscheidung.
|
||||
- `calibrate --consensus --engines local,local2,cloud,p2t --report X.json` misst alle Regeln;
|
||||
`--reuse X.json` rechnet sie ohne Modellabfragen neu.
|
||||
- `vergleich/` ist nicht versioniert (Ausschnitte aus Büchern).
|
||||
|
||||
## Stand
|
||||
|
|
@ -209,7 +248,8 @@ formula_img2latex/
|
|||
├── pipeline.py scan, recognize, verify, Entscheidung (Konsens/Pixel), run in Paketen, apply/revert
|
||||
├── consensus.py Normalform, Render-Gleichheit: sagen zwei Lesarten dasselbe?
|
||||
├── decide.py Annahmeregeln und Schwellen (Konsens- und Pixel-Modus)
|
||||
├── engines/ Vision-Modelle über die OpenAI-API (llama.cpp, OpenRouter), Logprobs, Prompt-Version
|
||||
├── engines/ Vision-Modelle über die OpenAI-API (llama.cpp, OpenRouter), Logprobs, Prompt-Version;
|
||||
│ p2t.py: pix2text-Formel-OCR (ONNX, CPU/GPU)
|
||||
├── compare.py Ausrichtung, elastische Verzerrung, Kennzahlen, Kontrasttest, Diff-Bilder
|
||||
├── confusables.py Verwechslungsvarianten (Pixel-Modus)
|
||||
├── verify.py Bildprüfung einer Lesart (Veto bzw. Pixel-Entscheider)
|
||||
|
|
|
|||
Loading…
Reference in a new issue