diff --git a/BEDIENUNGSANLEITUNG.md b/BEDIENUNGSANLEITUNG.md index 88ad847..0090291 100644 --- a/BEDIENUNGSANLEITUNG.md +++ b/BEDIENUNGSANLEITUNG.md @@ -32,7 +32,7 @@ Zwei Vision-Sprachmodelle lesen jede Formel, je eines pro Grafikkarte (je ~18– M=~/endeavour_home/lm_studio/models/lmstudio-community/Qwen3-VL-30B-A3B-Instruct-GGUF CUDA_VISIBLE_DEVICES=1 ~/.local/bin/llama-server \ -m $M/Qwen3-VL-30B-A3B-Instruct-Q4_K_M.gguf --mmproj $M/mmproj-Qwen3-VL-30B-A3B-Instruct-F16.gguf \ - --host 127.0.0.1 --port 8011 -ngl 99 -c 16384 --parallel 4 + --host 127.0.0.1 --port 8011 -ngl 99 -c 32768 --parallel 8 # Modell B: Gemma 4 auf GPU 2, Port 8012 M=~/nvme2n1p7_home/huggingface/models/gemma4 @@ -41,7 +41,8 @@ CUDA_VISIBLE_DEVICES=2 ~/.local/bin/llama-server \ --host 127.0.0.1 --port 8012 -ngl 99 -c 16384 --parallel 4 ``` -Gemma braucht auf GPU 2 rund 17,5 GB. Laufen dort Chatterbox-TTS und der STT-Server, reicht der Speicher +Qwen läuft mit 8 Plätzen zu je 4096 Tokens (zusammen 32768) und belegt rund 22,6 GB; `run` stellt bis zu +8 Anfragen gleichzeitig. Gemma braucht auf GPU 2 rund 17,5 GB. Laufen dort Chatterbox-TTS und der STT-Server, reicht der Speicher nicht (Gemma bricht beim ersten Bild mit „out of memory“ ab); dann vorher stoppen und danach wieder starten: ```bash @@ -63,7 +64,8 @@ pip install --no-deps pix2tex munch # nur für post_p pip uninstall -y onnxruntime && pip install onnxruntime-gpu # für die GPU ``` -Das Modell (~300 MB) wird beim ersten Lauf nach `~/.pix2text` geladen. Gerät wählen mit +Das Modell (~300 MB) wird beim ersten Lauf nach `~/.pix2text` geladen. Ohne Angabe nimmt pix2text die +Grafikkarte mit dem meisten freien Speicher und liest die Formeln gebündelt. Gerät festlegen mit `FORMULA_P2T_DEVICE=cpu` oder `cuda:N` (`N` zählt innerhalb von `CUDA_VISIBLE_DEVICES`). Gemma (Port 8012) wird nur für Formeln gefragt, bei denen pix2text und Qwen uneinig sind. Läuft Gemma @@ -86,7 +88,16 @@ cd ~/Python_Programs/epub2md python3 epub2md.py buch.epub output/buch ``` -Bei PDFs mit pdf2md immer `--images` (oder `--epub`) angeben, sonst gibt es keine Formelbilder. +Bei PDFs mit pdf2md immer `--images` (oder `--epub`) angeben, sonst gibt es keine Formelbilder. Für +Mathebücher **`--formulas`** verwenden: Dann findet pdf2md jede Formel auf der Seite, auch im Fließtext und +in Merkkästen, und schneidet sie als Bild aus (braucht pix2text, siehe oben): + +```bash +cd ~/Python_Programs/pdf2md +python3 pdf2md.py --formulas --epub buch.pdf Output/buch/buch.md +``` + +Das dauert bei 350 Seiten gut 10 Minuten (Corral: 9239 Formeln). ### Schritt 2: Formeln erkennen und prüfen @@ -101,10 +112,11 @@ Bei pdf2md zusätzlich die Original-PDF angeben. Dann schneidet das Programm jed python3 formula_img2latex.py run Output/buch.md --pdf buch.pdf ``` -Das Programm arbeitet in Paketen zu 50 Formeln und meldet nach jedem Paket den Stand: +Das Programm arbeitet in Paketen zu 50 Formeln und meldet nach jedem Paket den Stand und die Zeiten je +Stufe (die Stufen laufen teils gleichzeitig, daher ist die Summe größer als die Paketzeit): ```text - 100/1505 verarbeitet: automatisch ersetzt 68 (68%), Review 28, bleibt Bild/keine Formel 4 + 100/940 verarbeitet: automatisch ersetzt 78 (78%), Review 20, bleibt Bild/keine Formel 2 [Paket 35 s; pix2text 3 s, Qwen 30 s, Prüfung 14 s, Gemma 21 s] ``` Am Ende steht eine Übersicht je Status, beim Gehrke-Brückenkurs zum Beispiel: @@ -116,10 +128,10 @@ Am Ende steht eine Übersicht je Status, beim Gehrke-Brückenkurs zum Beispiel: pending 539 ← Abbildungen/Symbole, nicht geprüft ``` -Dauer: Mit der früheren Regel (Version 0.2.0, mit GLM) etwa 5 Minuten je 50 Formeln, ein Buch mit 1500 -Formelbildern also rund 2,5 Stunden. Mit der jetzigen Regel liest pix2text eine Formel in ~0,15 s und Qwen -in ~0,8 s, Gemma nur bei Uneinigkeit; an 2 × 50 Testformeln dauerte das Lesen im Mittel 1,5–2,3 s je -Formel (ohne Bildprüfung). Ein ganzes Buch ist damit noch nicht gemessen. +Dauer: etwa 0,8 s je Formel, also 35–50 Sekunden je Paket (Corral mit `--formulas`: 940 Formeln in +13 Minuten, das ganze Buch mit 9239 Formeln rund 2 Stunden). Am längsten braucht die Bestätigung durch Qwen. +Der Scan liest beim ersten Mal alle Bilder ein (Corral: 6 Minuten); beim Fortsetzen entfällt er, solange +sich das Markdown nicht geändert hat. Abbrechen (Strg+C) und erneut starten ist kein Problem: Bereits gelesene Formeln werden nicht noch einmal gefragt, der Lauf setzt fort. `--chunk 100` ändert die Paketgröße, `--limit 200` verarbeitet nur die ersten 200 Bilder. @@ -163,7 +175,14 @@ python3 formula_img2latex.py apply ~/Python_Programs/epub2md/output/buch ``` Aus `![…](../media/images/0042-…jpg)` wird `$L = \{-\sqrt{2};\sqrt{2}\}$` im Text bzw. `$$…$$` als eigener -Absatz. Die Bilddateien bleiben liegen. +Absatz. Die Bilddateien bleiben liegen. Hat die Formelerkennung bei einer Formel im Text ein Satzzeichen +mit ausgeschnitten, steht es danach als normaler Text hinter der Formel (`$a^{x}$,`). + +Bei pdf2md-Büchern baut `pdf2md.py --from-md` das EPUB neu, mit allen Formeln als MathML: + +```bash +cd ~/Python_Programs/pdf2md && python3 pdf2md.py --from-md Output/buch/buch.md +``` **Danach die Gesamtdatei neu bauen**, sie enthält sonst noch die Bilder: diff --git a/README.md b/README.md index 77f1310..92ca467 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,9 @@ LaTeX ersetzt – **aber nur, wenn zwei unabhängige Erkenner dieselbe Formel le 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. +Für PDF-Bücher findet `pdf2md --formulas` jede Formel auf der Seite, auch im Fließtext und in Merkkästen, +und schneidet sie als Bild aus; formula_img2latex übersetzt sie dann ebenso (siehe [Quellen](#quellen)). + Schritt-für-Schritt-Anleitung: [BEDIENUNGSANLEITUNG.md](BEDIENUNGSANLEITUNG.md). Änderungen je Version: [CHANGELOG.md](CHANGELOG.md). Hintergrund und ursprüngliche Planung: `Idee/`. @@ -131,7 +134,8 @@ 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: 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) + nach jedem Paket eine Statuszeile mit Zeiten je Stufe (Regel vlm3: Qwen + Gemma, GLM nur + für Einige). Die GPUs lesen schon das nächste Paket, während die CPU das vorige prüft. 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 @@ -148,6 +152,17 @@ python3 formula_img2latex.py apply output/buch python3 epub2md_merge.py output/buch --force # Gesamtdatei danach neu bauen ``` +PDF-Buch mit allen Formeln, auch im Fließtext: + +```bash +cd ~/Python_Programs/pdf2md +python3 pdf2md.py --formulas --epub buch.pdf Output/buch/buch.md # Formeln als Bilder + Liste +cd ~/Python_Programs/formula_img2latex +python3 formula_img2latex.py run ~/Python_Programs/pdf2md/Output/buch/buch.md --pdf buch.pdf +python3 formula_img2latex.py apply ~/Python_Programs/pdf2md/Output/buch/buch.md +cd ~/Python_Programs/pdf2md && python3 pdf2md.py --from-md Output/buch/buch.md # EPUB mit MathML +``` + Status je Formel: `auto_accepted`, `needs_review`, `rejected_keep_image`, `render_failed`, `no_candidate`, `not_formula`, nach Review `accepted_by_human`, `corrected_by_human`, `kept_by_human`. @@ -155,10 +170,10 @@ Status je Formel: `auto_accepted`, `needs_review`, `rejected_keep_image`, `rende | Engine | Standard | Konfiguration | | --- | --- | --- | -| `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` | +| `local` | llama.cpp `http://127.0.0.1:8011/v1` (Qwen3-VL-30B-A3B-Instruct Q4_K_M + mmproj), 8 parallele Anfragen | `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` (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` | +| `p2t` | pix2text MFR 1.5 (ONNX) im Prozess, die sichtbare GPU mit dem meisten freien Speicher, sonst CPU; gebündelt nach Pixelbudget | `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 @@ -169,6 +184,11 @@ von torch). Für `post_process` wird `pix2tex` ohne seine Abhängigkeiten instal 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. +Qwen-Server mit `--parallel 8 -c 32768` (je Platz 4096 Tokens) starten; `run` stellt bis zu 8 Anfragen +gleichzeitig (BEDIENUNGSANLEITUNG). Gemessen und verworfen: Qwen3-VL-8B statt 30B-A3B ist nicht schneller +(das MoE-Modell rechnet je Token nur ~3B Parameter) und liest etwas schlechter (Göllmann 42/44 statt 44/45 +automatisch). + 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 $. @@ -193,7 +213,9 @@ Sicherheit: Kandidaten kommen von Modellen und gelten als unsicher. Vor pdflatex .formulas/ # neben der Ausgabe, weil epub2md --force die Ausgabe ersetzt ├── workspace.json # Quelle, Schrift, Einstellungen, apply-Zustand ├── formulas/f--.json # je Bild und Darstellung: Lesarten, Prüfung, Entscheidung +├── crops/.png # Original je Formel, einmal ausgeschnitten (PDF-Quellen) ├── review/-{orig,render,rigid,diff}.png +├── bericht/ # Ergebnisseite (tools/buch_bericht.py) └── backup/ # Markdown-Dateien vor dem ersten apply ``` @@ -201,7 +223,8 @@ Die Datensätze hängen am SHA-256 des Bildes: Ein erneuter epub2md-Lauf verlier Einstellungen in `workspace.json` → `settings.consensus_thresholds`: `require_third` (1), `bold_relevant` (0), `structural` (0), `arbiter` (0), `arbiter_margin` (5), `veto_ncc` (0,65), -`veto_scale_dev` (0 = aus), `min_p_mean`/`min_p_min` (0). +`veto_scale_dev` (0 = aus), `min_p_mean`/`min_p_min` (0), `pdftext` (0: die PDF-Textebene bestätigt nie; +gemessen: in 12 von 319 Fällen fehlten dort Punkte, Striche oder Indizes, die Qwen sah). ## Quellen @@ -209,9 +232,13 @@ Einstellungen in `workspace.json` → `settings.consensus_thresholds`: `require_ | --- | --- | --- | | epub2md-Ordner | `conversion-report.json`; Warnungen `formula-image` markieren sichere Formeln | `--math auto`: `$…$`/`$$…$$`, `--math tex`: `\(…\)`/`\[…\]`; deutsche Bücher: `3{,}6` | | pdf2md (`.md` + `_images/` oder `--split`-Ordner) | Bildname `--`; mit `--pdf` per Template-Matching auf der Seite gefunden und mit 600 dpi aus dem Vektor-PDF neu ausgeschnitten | `$…$`/`$$…$$` | +| pdf2md `--formulas` | Bildname `--f.png` (300 dpi), Liste `_images/formulas-*.json` mit Seite, Rechteck, Art (im Text/abgesetzt) und PDF-Text; das Bild wird direkt verwendet | `$…$`/`$$…$$` | -Codeblöcke werden nie verändert. Inline-Formeln, die pdf2md als Glyphensalat im Fließtext ausgibt, -sind nicht Teil dieser Version. +Mit `pdf2md --formulas` findet die Formelerkennung von pix2text (MFD) jede Formel auf der Seite, auch im +Fließtext und in Merkkästen; pdf2md schneidet sie zeichengenau aus dem Text (statt Glyphensalat wie `x4n`). +Ein Satzzeichen am Ende einer eingebetteten Formel wird vor dem Vergleich abgetrennt und als Text hinter +die Formel gesetzt (`$a^{x}$,`). Codeblöcke werden nie verändert. Formeln in Tabellen erfasst die +Erkennung noch nicht. ## Werkzeuge zum Einstellen @@ -234,6 +261,13 @@ sind nicht Teil dieser Version. ## Stand +**Formeln im Fließtext** (unveröffentlicht, nach 0.4.0): Corral mit `pdf2md --formulas`: 9239 Formelbilder +(davon ~88 % eingebettet). Stichprobe 10 % (940): **747 automatisch (79 %)**, im Text 83 %, abgesetzte +Box-Bilder (Herleitungen, Kästen) nur ~29 %; 174 Review, 19 keine Formel; 13 Minuten, hochgerechnet ~2 h +für das ganze Buch. Beschleunigung am Pilot (869 Formeln): 70 → ~24 Minuten, Entscheidungen zu 863/876 +gleich (die Abweichungen kommen von den Modellen selbst). Qualität ist hier ohne bekannte Lösung – +vor dem Einsatz eine Stichprobe der übernommenen Formeln von Hand prüfen. + Version 0.4.0 (Regel `p2t`, mehrzeilige Normalform) ist an Göllmann Band 1 und 2 gemessen (siehe [Messung](#messung)), aber noch **nicht am ganzen Gehrke** gelaufen. @@ -274,8 +308,11 @@ Grenzen und offene Punkte: - Fettdruck wird nicht geprüft (Vorgabe). - Die Messung umfasst 2 × 150 Formeln eines Buches ohne Textausschnitt; „0 Fehler“ bedeutet eine Fehlerquote sehr wahrscheinlich unter ~2 %. -- pdf2md-Bücher: der Ablauf ist umgesetzt (600-dpi-Neuausschnitt, Euler-Schrift für Hefferon), aber im - Konsens-Modus noch nicht an einem ganzen Buch getestet. +- pdf2md-Bücher: am ganzen Corral getestet (ohne `--formulas` 0.4.0, mit `--formulas` 10 %); Formeln in + Tabellen fehlen noch. +- Einzelne Riesenausschnitte (Grafiken, dreizeilige Herleitungen mit völlig anderer Lesart) werden ohne + Bildvergleich abgelehnt: über 2,5 MP oder mehr als 2,5-fach falsche Proportionen; breite Originale werden + für den Vergleich auf 1600 px verkleinert. ## Installation @@ -312,6 +349,7 @@ formula_img2latex/ ├── render.py pdflatex-Batch, Schrift-Presets, Rasterung ├── imageio.py Originale laden (PNG/GIF/JPG/SVG, Transparenz, Tönung) ├── sources/ epub2md.py, pdf2md.py, base.py (Markdown-Scan, Begrenzer, Dezimalkomma) +├── structure.py Strukturvergleich mit sympy (optional, aus) ├── pdfcrop.py Formelbild auf der PDF-Seite finden, 600-dpi-Neuausschnitt ├── classify.py Formel / unklar / Abbildung ├── checks.py Pandoc/MathML-Prüfung