OCR di Grothendieck, parte II: un ground truth condiviso, un gap di prezzo di 15x, e una sorpresa dal modello piccolo
Seguito di Trascrivere la scrittura di Grothendieck con l’AI. Come una sezione di riferimento vera, corretta da un archivista, ha messo in luce un problema di prompt che i modelli stavano nascondendo, e perché questo importa per chiunque stia confrontando LLM di frontiera su task di testo strutturato.
Dove eravamo rimasti
A gennaio ho scritto di un esperimento di un fine settimana: i modelli vision-language moderni riescono a leggere una pagina dell’archivio manoscritto di Grothendieck? La risposta breve era sì, con una gerarchia. Gemini 3 Pro gestiva prosa densa di teoria delle categorie in modo impressionante, Claude Opus 4.5 produceva output più pulito ma meno ambizioso, ChatGPT 5.2 faceva fatica. Ho chiuso il post con l’avvertenza onesta che ogni trascrizione richiede verifica, perché il pattern matching che permette il riconoscimento permette anche la confabulazione sicura di sé.
Poi la storia è passata da esperimento del fine settimana a progetto vero. Questo post è il resoconto dopo quattro mesi, concentrato su una specifica scoperta, perché mi ha sorpreso abbastanza da valere la pena di scriverla con attenzione. Tutto è riproducibile da github.com/ivan-gentile/la-longue-marche.
Una cronologia, perché l’ordine conta
Fine gennaio. Il post esce. Entro una settimana ricevo un’email da Mateo Carmona, l’archivista del Centre for Grothendieckian Studies, che sta trascrivendo manualmente la Parte I di La Longue Marche à travers la théorie de Galois. Si offre di collaborare sulla Parte II, le 976 pagine manoscritte ancora non lette, e, crucialmente, di condividere il LaTeX della Parte I che ha già. Olivia Caramello, direttrice dell’Istituto Grothendieck, accetta di ospitare l’output. Ora abbiamo ground truth.
Febbraio. Design della pipeline. Benchmark pilota: 17 configurazioni su 4 pagine. Gemini 3.1 Pro, medium thinking, con la pagina precedente allegata come contesto visivo, vince.
6 marzo. Primo run di produzione: 398 delle 976 pagine trascritte. Circa 3 euro di costi API. Email a Mateo con numeri e dashboard.
9 marzo. Corpus completo di 976 pagine consegnato come due file .tex compilati. Costo totale del progetto finora: sotto i 10 euro.
20 marzo. Aggiornamento per gli stakeholder: normalizzazione della notazione spedita, rollout parziale dei diagrammi commutativi in 140-3 (84 pagine su 119 convertite da placeholder a veri tikzcd), diagrammi di 140-4 ancora in sospeso.
21 marzo. Mateo risponde. Ha fatto la cosa migliore che un archivista possa fare per un benchmark: ha mandato due versioni della stessa sottosezione della Sezione 49. La prima è 49.1old.tex, l’output prodotto dalla nostra pipeline. La seconda è 49.1new.tex, la versione corretta nella forma in cui si aspetta di pubblicarla. Richiede anche un resoconto dettagliato della nostra strategia di prompting, e suggerisce un secondo benchmark su un manoscritto Grothendieck tipografato dagli archivi Bourbaki, un setting controllato dove la scrittura a mano è rimossa dalle variabili.
17 aprile. Il giorno in cui questo post è scritto. Il ground truth appaiato 49.1 è stato il punto di svolta. Quello che segue è cosa ha rivelato quella coppia.
Il diagnostico
Ho scritto un piccolo tool che categorizza ogni differenza tra 49.1old.tex e 49.1new.tex. Le categorie vengono dal fissare entrambi i file fianco a fianco e notare quali tipi di divergenza ricorrono. Cinque categorie:
- Residuo grezzo della pipeline. Placeholder che il modello ha lasciato dentro (
[unclear: ...],[MARGIN: ...],[DIAGRAM: ...]). - Deriva di notazione. Il nostro output usa
\widehat{\mathfrak{G}}_{0,3}^+, quello di Mateo usa\mathfrak{S}^{+\wedge}_{0,3}. Il nostro usa\text{int}e\text{Norm}, il suo\operatorname{int}e\operatorname{Norm}. Il nostro\mathbb{Z}, il suo\mathbf{Z}.gminuscolo per un sottogruppo chiuso contro il suo\mathcal{G}. - Struttura pubblicabile. Il suo file ha
\chapter*,\addcontentsline{toc}{section}{...},\label{sec:49}, equazioni numerate con\leqno{(N)}a destra,\footnote{...}per le note autoriali,\begin{tikzpicture}per uno schema. Il nostro file non aveva niente di tutto ciò. - Letture impegnate. 26 marcatori
[unclear]non risolti nel nostro, zero nel suo. Si era semplicemente impegnato sulla migliore lettura matematica nel contesto. “Unclear” era solitamente decidibile. - Espansione delle abbreviazioni. Scrive per esteso
sous-groupe, noi avevamo lasciatoss-groupe;homomorphismevshom..
Trasformato in un punteggio di qualità composito in [0, 1] (1 significa corrispondenza esatta alle convenzioni di Mateo), l’output spedito ha segnato 0.113.
Quel numero non sembrava giusto. La pipeline leggeva Grothendieck bene: i singoli simboli erano di solito corretti, la prosa era per lo più fedele, il contenuto matematico sopravviveva. Ma l’output non era LaTeX pubblicabile. Erano appunti, non un capitolo.
Aggiornamento del prompt
Ho riscritto il prompt. Tre aggiunte:
- Un blocco di convenzioni notazionali che elenca i simboli canonici verbatim: “usa
\mathfrak{S}, non\widehat{\mathfrak{G}}; usa\operatorname{Norm}, non\text{Norm}; usa\mathbf{Z}, non\mathbb{Z}.” - Una regola per la gestione dei margini: un
(N)marginale accanto a un’equazione diventa\leqno{(N)}; una nota autoriale al margine diventa\footnote{...}; altre annotazioni rimangono come\marginpar{...}. Il vecchio prompt lasciava decidere il modello; il nuovo glielo dice. - Un pool di few-shot a tre estratti tratti dalle Sezioni 19, 25bis e 31 della Parte I di Mateo. Uno prose-dense, uno con un’equazione numerata con
\leqno, uno con un footnote. Nessuna spiegazione estesa; il modello vede lo stile reale.
Ho chiamato questa variante di prompt mateo-canonical. È circa 6.000 caratteri di system prompt. Non piccolo, ma niente di esotico.
Opus 4.7 vs Gemini 3.1 Pro, round 1 (prima dell’aggiornamento del prompt)
Questa è la parte che vale la pena scrivere con attenzione, perché mi ha sorpreso.
Prima che il prompt mateo-canonical esistesse, ho eseguito entrambi i modelli di frontiera su dodici pagine della Parte II (cinque della Sezione 49 dove abbiamo ground truth, sette campioni ciechi attraverso il corpus), sotto lo stesso prompt spedito, stesso contesto di pagina precedente, stessi PDF di input.
| Modello | Costo per 12 pagine | Latenza media | Deriva notazione / 1000 char | Residuo pipeline / 1000 char |
|---|---|---|---|---|
| Gemini 3.1 Pro | $0.13 | (batch) | 7.10 | 3.33 |
| Claude Opus 4.7 | $2.06 | 24.5 s | 4.05 | 3.43 |
Lettura ovvia: Opus è 15x più costoso ma fa significativamente meglio sulla notazione. Questo giustificherebbe una politica “usa Opus per le pagine difficili”.
Due caveat, però. Uno: Opus ha prodotto il 40% di testo in più per pagina, e una parte di quel testo non era sulla pagina corrente. Opus a volte includeva il contenuto della pagina precedente nel suo output, perché interpretava “shown above for context” come “anche includere nella trascrizione”. È una vera failure mode, ed è successa su diverse delle cinque pagine di ground truth. Due: sotto un prompt ambiguo su cosa significhi “trascrivere in LaTeX”, quello che stavamo effettivamente misurando era “quale modello indovina meglio le preferenze dell’archivista quando sotto-specificato”, una domanda sui prior, non sulla qualità di trascrizione.
Opus 4.7 vs Gemini 3.1 Pro, round 2 (dopo l’aggiornamento del prompt)
Ho rifatto le cinque pagine di ground truth con mateo-canonical su entrambi i modelli.
| Variante | Costo per 5 pagine | Residuo / kch | Deriva notazione / kch | Copertura strutturale | Qualità composita |
|---|---|---|---|---|---|
| Output della pipeline spedita | (già pagato) | 4.71 | 5.42 | 7 % | 0.113 |
Claude Opus 4.7 + mateo-canonical | $1.173 | 0.71 | 1.42 | 71 % | 0.661 |
Gemini 3.1 Pro + mateo-canonical | $0.074 | 0.80 | 0.90 | 71 % | 0.742 |
Gemini 3.1 Pro + mateo-canonical, whole-document (10 pagine in una chiamata) | $0.088 | 0.62 | 0.75 | 50 % | 0.714 |
Tre cose succedono contemporaneamente:
-
Il punteggio composito salta 6.6x, da 0.113 a 0.742 sulle stesse cinque pagine. La maggior parte di quello che sembrava un soffitto di qualità era un pavimento di prompt. I modelli erano capaci di produrre LaTeX pubblicabile; nessuno glielo aveva chiesto.
-
Il ranking Opus-contro-Gemini si inverte. Sotto il vecchio prompt, la deriva di notazione di Opus era del 43% inferiore a quella di Gemini (4.05 vs 7.10). Sotto
mateo-canonical, quella di Gemini è del 37% inferiore a quella di Opus (0.90 vs 1.42). Gemini batte Opus anche sul composito (0.742 vs 0.661). E Gemini è 16x più economico per pagina. -
La modalità whole-document è competitiva. Gemini 3.1 Pro su dieci pagine in una singola chiamata raggiunge 0.714, leggermente sotto al per-page ma con il 40% in meno di costo per pagina e 5x meno tempo di wall-clock. Per testo tipografato o prosa manoscritta leggera questo è ora il percorso raccomandato; per scrittura densa con riferimenti tra pagine il contesto visivo per-page continua ad aiutare.
Quello che sembrava un gap di qualità del modello era un gap di ambiguità del prompt. Opus non era “migliore sulla notazione matematica”; era “migliore a indovinare lo stile corretto quando il prompt era sotto-specificato”. Una volta che diciamo a entrambi i modelli lo stile esplicitamente, la convergenza è immediata, e il confronto rimanente è su costo e velocità, dove Gemini vince pulitamente.
Questa è, per me, la scoperta più importante del progetto finora. Perché significa che la maggior parte dei benchmark pubblici degli LLM di frontiera su task sotto-specificati non sta misurando quello che sembra misurare.
Round 3: entra in scena Flash-Lite
L’API Gemini tier Pro ha un tetto rigido di 250 richieste per modello al giorno sulla quota che stavo usando, cosa che ho scoperto nel modo peggiore dopo aver lanciato un re-run dell’intero corpus con mateo-canonical. Il re-run avrebbe richiesto quattro giorni di calendario a quel ritmo. Fastidioso.
Mentre aspettavo il reset della quota, ho provato qualcosa di leggermente perverso: le stesse cinque pagine di ground truth attraverso Gemini 3.1 Flash-Lite, il modello Gemini più economico, più piccolo e più veloce, sotto lo stesso prompt mateo-canonical.
| Variante | Costo per 5 pagine | Latenza media | Residuo grezzo / kch | Deriva notazione / kch | Copertura strutturale | Qualità composita |
|---|---|---|---|---|---|---|
Claude Opus 4.7 + mateo-canonical | $1.173 | 28.6 s | 0.71 | 1.42 | 71 % | 0.661 |
Gemini 3.1 Pro + mateo-canonical | $0.074 | 67.8 s | 0.80 | 0.90 | 71 % | 0.742 |
Gemini 3.1 Flash-Lite + mateo-canonical | $0.008 | 7.4 s | 0.12 | 0.85 | 50 % | 0.777 |
Flash-Lite ha battuto sia Pro sia Opus sulla qualità composita, a un costo 10× inferiore a Pro e 150× inferiore a Opus, con uno speedup di 9× su Pro e 4× su Opus. Ha perso un po’ di copertura strutturale (50 % vs 71 %) ma ha guadagnato una densità di residuo grezzo molto più bassa.
Il campione di output si legge così, esattamente come lo vorresti:
49. Homomorphismes de $M_{0,3}$, les groupes $M_{g,0}$ généralisés
I) Considérons un sous-groupe $G$ de $M_{0,3}$, contenant
$\mathfrak{S}^{+\wedge}_{0,3}$, d'image inverse d'un sous-groupe fermé
de $\mathfrak{T}_{0,3}$. [...]
$$G \cap \mathfrak{S}^{+\wedge}_{0,3} \subset M_{0,3}, \quad
u \in G \implies \mu(u) \equiv 1 \pmod 3 \leqno{(1)}$$
Simbolo canonico \mathfrak{S}^{+\wedge}_{0,3}, \operatorname{int}, \leqno{(1)}, \defeq, \marginpar — tutto presente. I token sono giusti. Il modello è piccolo ma il prompt sta portando la specifica.
Stessa ipotesi testata sul controllo di testo tipografato (Bourbaki schemi, 5 pagine, whole-document):
| Variante | Costo | Latenza |
|---|---|---|
| Claude Opus 4.7, pagina-per-pagina | $0.632 | ~100 s |
| Gemini 3.1 Pro, whole-document | $0.057 | 65 s |
| Gemini 3.1 Flash-Lite, whole-document | $0.007 | 13 s |
La qualità dell’output è essenzialmente indistinguibile da Pro — ideali \mathfrak{p}, definizioni \emph{}, diagrammi commutativi tikzcd, tutti presenti. Flash-Lite ha saltato le marginalia archivistiche che Pro ha catturato, ma tutto ciò che un matematico vorrebbe c’è.
Proiezione costo re-run corpus intero: ~€3 (da €10), wall-clock ~3-4 ore (da 10-16 ore con Pro, o una settimana con la quota giornaliera Pro). Quel re-run è in corso al momento della pubblicazione; il corpus sarà un output Flash-Lite-con-mateo-canonical quando leggerai questo.
Di nuovo il pattern: con un prompt esplicito, la dimensione e il costo del modello importano molto meno di quanto suggeriscano molti benchmark recenti. Un modello 15× più economico può eguagliare o battere uno più costoso su un task specifica-pesante, perché la maggior parte del gap di capacità apparente veniva speso a compensare la sotto-specificazione del prompt.
Il controllo su testo tipografato
Il secondo suggerimento di Mateo, per fattorizzare la variabile della scrittura, era di eseguire la pipeline su un primo manoscritto Grothendieck tipografato sulla teoria degli schemi. Cinque pagine, due modi:
- Claude Opus 4.7, pagina-per-pagina: $0.632.
- Gemini 3.1 Pro, whole-document (tutte e cinque le pagine in una chiamata): $0.057, 11x più economico.
Entrambi producono LaTeX pubblicabile: \mathfrak{p} per gli ideali primi, \emph{} per le definizioni introdotte, un vero tikzcd per il diagramma commutativo a pagina 2. Gemini inoltre cattura le marginalia archivistiche (“Archives Grothendieck sept. 59”, “n° 326 bis”) che Claude ha silenziosamente scartato.
%% ===== Pagina 1 =====
[Archives Grothendieck sept. 59]
\begin{flushright}
n$^\circ$ 326 bis
\end{flushright}
\begin{center} CHAPITRE 0 \\ PRÉLIMINAIRES. \end{center}
\begin{center} §1. \emph{Algèbre commutative.} \end{center}
Nous rappelons ... Un \emph{idéal premier} $\mathfrak{p}$ d'un anneau $A$
est un idéal tel que $A/\mathfrak{p}$ soit intègre ...
Su input tipografato la pipeline produce essenzialmente LaTeX di forma finale, confermando che il gap rimanente sulla Parte II è un problema di prompt e post-processing, non un problema di OCR.
La valutazione a tre livelli
Nessuna singola metrica di qualità è sopravvissuta al contatto con questo progetto. Similarità di stringhe, LLM-as-judge e diff strutturale contro un file gold corretto sono tutti in disaccordo in modi specifici, e ognuno cattura qualcosa che gli altri mancano.
- Similarità di stringhe (SequenceMatcher contro un riferimento tipografato) va bene per classificare le configurazioni l’una contro l’altra, fuorviante come punteggio assoluto. Allineamento pagine, varianza LaTeX e differenze tipografiche spingono la similarità nel range 12 a 18% indipendentemente dalla qualità reale.
- LLM-as-judge (Gemini Flash-Lite che valuta cinque dimensioni per pagina) è abbastanza economico per l’intero corpus e correla ragionevolmente con i revisori umani, ma premia output dall’aspetto sicuro, esattamente la failure mode segnalata nel post di gennaio.
- Diff strutturato categorizzato (l’approccio
diagnose_49_1.py) è di gran lunga il segnale più onesto, ma richiede una versione gold corretta, che costa ore di esperto. - Preferenza umana A/B su coppie cieche è il complemento: economico per il revisore, mirato, trattabile una volta che hai circa 50 coppie.
Quando due qualsiasi sono in disaccordo guardiamo le pagine specifiche. Ha catturato diverse cose che altrimenti sarebbero state spedite.
Cosa avevo sbagliato a gennaio
- “La scelta del modello importa enormemente.” Importa, ma meno del design del prompt. Il salto da 0.113 a 0.742 è venuto dalla riscrittura del prompt, non dal cambio di modello.
- “Gemini 3 Pro gestisce questo in modo impressionante.” Lo fa, ma senza istruzioni strutturali esplicite produce silenziosamente LaTeX non pubblicabile: numeri di equazione
(1)inline invece di\leqno{(1)}, placeholder[MARGIN: ...]invece di footnote,a)/b)inline invece di\begin{enumerate}. Il contenuto è per lo più giusto; il LaTeX no. - “Il collo di bottiglia non è l’AI, è la verifica.” Credo ancora nella parte di verifica, ma ho sottopesato quanto prima della verifica sia un problema di prompt engineering. I modelli non fanno fatica a leggere Grothendieck; fanno fatica a sapere cosa “trascrivere in LaTeX” dovrebbe significare quando la risposta ha un formato di pubblicazione particolare.
Cosa rimane aperto
- Re-run dell’intero corpus con
mateo-canonical. In corso. La quota API giornaliera è il vincolo di pacing attuale; circa una settimana per finire. - Figure disegnate a mano. Una manciata di pagine contiene disegni veri e propri, non diagrammi commutativi. Nessuno dei due prompt li gestisce bene; servirà aiuto umano.
- Calibrazione del giudice contro valutazioni di esperti. Il visualizzatore di benchmark
benchmark_opus_vs_gemini.htmlraccoglie preferenze A/B cieche su sette pagine; i voti di Mateo calibreranno direttamente i punteggi LLM-as-judge.
Crediti
La collaborazione è con Mateo Carmona (CSG) e Olivia Caramello (Istituto Grothendieck). Ogni scoperta utile in questo progetto è a valle del fatto che Mateo ha condiviso la sua trascrizione della Parte I e ha scritto 49.1new.tex. Il benchmark su testo tipografato è una sua idea.
Repository: github.com/ivan-gentile/la-longue-marche. Documentazione della pipeline rivolta specificamente a Mateo: PIPELINE.md. Entrambi i file tex_output/*.tex sono committati.
Se lavori su OCR manoscritto, trascrizione di manoscritti matematici, o valutazione di modelli di frontiera su task di testo strutturato, mi piacerebbe sentirti, soprattutto sulle failure mode che i quattro livelli di valutazione sopra ancora mancano. Scrivimi su LinkedIn.
Co-scritto con Claude Opus 4.7, che, in un piccolo tocco di ironia, è anche uno dei due modelli che stavo benchmarkando.