Sostituire GPT con un modello open-source auto-ospitato: ritorno d'esperienza con l'estrazione documentale
In breve: migrazione reale di una stack di estrazione documentale daAzure (Document Intelligence + GPT-4o) a un SLM open-source auto-ospitato su una singola GPU. Risultato : qualità equivalente al cloud, elaborazione più rapida, e fino a 20× meno costoso su scala - senza che alcun dato sensibile lasci l'infrastruttura. Rilevante già da quelques milliers de pages/mois, con vincoli di sovranità o di rate limits.
L'estrazione documentale fa parte dei compiti dell'IA generativa che si possono facilmente trattare con i modelli proprietari in API come GPT, Claude e Gemini. Questi modelli sono veloci da integrare, performanti e semplici da operare. Ma il loro utilizzo si scontra rapidamente con la congiunzione di diversi vincoli : la sovranità dei dati, il costo fatturato al token che aumenta con il volume, les rate limits che limitano il flusso, la moderazione che a volte blocca richieste legittime, e la dipendenza da un fornitore.
Tuttavia le prestazioni dei SLM open-source (small language models) raggiungono oggi il livello dei grandi modelli proprietari sui compiti classici (OCR, segmentazione, estrazione strutturata). Presso Galadrim, agenzia tech & IA francese, abbiamo condotto questa migrazione per un cliente soggetto a forti vincoli di sovranità. Questo articolo ne descrive il feedback passo dopo passo : scelta del modello e della GPU, messa in produzione, salvaguardie, e metodo di valutazione per validare che non si perde nulla in qualità.
Il contesto : perché un'API proprietaria non reggeva più
Il progetto è un'applicazione aziendale costruita su misura per un ufficio di perizie mediche i cui clienti sono assicuratori sanitari in Svizzera. Un utente vi deposita un dossier PDF composito, spesso 50 à 500 pages, che raccoglie documenti eterogenei : rapporti, moduli, corrispondenza, prescrizioni, fatture. L'applicazione suddivide questo PDF in sotto-documenti distinti, ne estrae la data e il titolo, produce un riassunto, e seleziona i documenti utili all'elaborazione.
Internamente, questa pipeline concatena 7 fasi :
rendering delle pagine in immagini,
OCR,
segmentazione (definire i confini tra sottodocumenti),
fusione dei blocchi,
estrazione delle date,
estrazione del contenuto (titolo + riassunto + selezione),
e deduplicazione.
La la segmentazione è la fase pivot. Se si taglia male, tutto il resto è distorto: un rapporto suddiviso in più parti fa esplodere le date estratte e falsa la selezione. È quindi la fase su cui abbiamo concentrato i nostri test per primi.
La protezione dei dati privati è stata al centro dei vincoli di sviluppo del progetto a causa dei dati sensibili trattati e regolati dalla LPD svizzera(Legge federale sulla protezione dei dati), equivalente alla regolamentazione europea. Diversi clienti della soluzione desideravano andare oltre le garanzie contrattuali fornite da Azure in Svizzera in termini di sovranità del dato.
A questo vincolo normativo, si aggiungevano già un costo fatturato al token che cresce con il volume, e una dipendenza a fornitori fuori dal nostro controllo. Il cliente ha quindi richiesto, a monte, un'infrastruttura 100 % svizzera, senza terzi extra-europei nel ciclo. Questo è il fattore scatenante della migrazione.
Scegliere il tuo SLM : multimodalità e budget VRAM
Migrare verso un GPU auto-ospitato comporta un costo di infrastruttura e una complessità operativa e solleva principalmente le seguenti domande: quale infrastruttura scegliere per l'inferenza, in particolare la memoria RAM del GPU (VRAM) e quale modello scegliere per ogni compito (numero di parametri, quantificazione ecc.) ?
Il LLM per i compiti di estrazione e sintesi
L'input della fase di segmentazione è composto daimmagini di pagine. È quindi necessario un modello multimodale, con finestra di contesto ampia, che stia su un singolo GPU.
Modello
Parametri attivi
VRAM Q5
Multimodale
Scelta
Llama 3.1 70B
70B
~50 GB
✗
✗nessuna visione
Mistral Large 2 123B
123B
> 80 GB
✗
✗irrealizzabile single-GPU
Qwen2.5-VL 32B
32B
~22 GB
✓
▲corretto ma lento
Qwen3.6-35B-A3B (MoE)
3B attivi / 35B
~28 GB
✓
✓selezionato
Pixtral 12B
12B
~10 GB
✓
✗differenza di qualità
Tabella 1 - Scelta del modello multimodale (splitter): Un singolo GPU 48 Go, visione richiesta per leggere le pagine.
Abbiamo scelto un Mixture-of-Experts (Qwen3.6-35B-A3B): attiva solo 3 miliardi di parametri per token generato pur disponendo della conoscenza di un modello da 35 miliardi di parametri. Otteniamo quindi il throughput di un modello piccolo con la qualità di uno grande. Nel nostro compito, è al livello di GPT-4o nella segmentazione e nell'estrazione di date.
L'OCR
GLM-OCR è specializzato OCR (non generalista) e legge bene le scritture manoscritte. È un punto critico sui moduli dove l'informazione utile è spesso una menzione manoscritta.
Modello
Qualità testo piccolo
Velocità
Scelta
Azure Document Intelligence
riferimento
1-2 s/p
✗cloud
Tesseract / PaddleOCR
degradata su timbri/scrittura
< 1 s/p
✗insufficiente
Qwen2.5-VL OCR-mode
buona
8-10 s/p
▲lento
GLM-OCR (THUDM)
≈ Azure DI
1-2 s/p
✓selezionato
Tabella 2 - Scelta del motore OCR : Qualità vicina ad Azure, senza il cloud.
Quantization : è prima di tutto una questione di budget VRAM
Far coesistere due modelli su 48 GB è soprattutto un problema diingombro di memoria. Abbiamo confrontato diversi livelli di quantization e abbiamo scelto, per il nostro caso e la nostra VRAM, del Q5_K_M per il LLM e del Q8_0 per l'OCR : è il punto in cui la qualità rimane indistinguibile dal FP16 sui nostri compiti lasciando comunque abbastanza margine per far girare diverse richieste LLM concorrenti. Il livello giusto dipende dal modello, dal compito e dalla GPU. Il Q4 degradava l'estrazione strutturata e l'OCR delle piccole cifre ; il FP16 semplicemente non rientrava.
Figura 1 - I due modelli coesistono su una singola GPU da 48 GB : ~38 GB allocati, ~10 GB mantenuti come margine per assorbire i picchi di contesto.
Due insegnamenti tratti dalla messa in produzione degli SLM
Tagliare la « modalità di pensiero » : strutturare il compito invece di lasciare che il modello pensi
Per impostazione predefinita, il modello emette diverse migliaia di token di ragionamento (…) prima di produrre il suo JSON. Su un compito a output strutturato, questo ragionamento è tempo perso : su un batch di 10 pagine, si passa da ~20 s a ~3 s disattivandolo, un guadagno × 5 a × 10.
Oltre il flag : sui compiti strutturati, la qualità deriva meno dal ragionamento libero che dal definire e strutturare bene il compito nel prompt di sistema. E quando la qualità dell'output è critica, si sostituisce il ragionamento implicito con un dispositivo esplicito e controllato, tipicamente diverse passate in una rete avversariale di LLM-as-a-judge per rafforzare e validare il sistema di prompt. Si mantiene il ragionamento solo dove aiuta realmente (qui, la deduplicazione).
Testa sempre i tuoi guardrail : i modelli open-source allucinano
Un SLM auto-ospitato non ha la rete di sicurezza di un fornitore. Bisogna costruire i propri guardrail, e testarli in condizioni reali per trovare le giuste soluzioni.
Guardrail
Attivazione
Effetto
Rilevamento di ciclo OCR
Output anormalmente lungo o ripetizione a livello di frase
Salvataggio del prefisso valido, retry, fallback
Fallback per pagina
Il parsing di un batch OCR fallisce
Re-OCR pagina per pagina
Fallback LLM su loop OCR
Loop OCR + retry fallito
Passa al LLM vision per questa pagina
Retry esponenziale
Errore HTTP / timeout
Recupera i transienti di rete o saturazione
Boundary resolver
Lo splitter esita tra 2 confini
Reinietta il contesto limitrofo per decidere
Tabella 3 - Misure di protezione della pipeline auto-ospitata: senza rete del fornitore, tutto è gestito lato pipeline.
In pratica, queste misure di protezione recuperano quasi tutti gli incidenti: sui nostri lotti, circa l'1% delle pagine entra in un loop di allucinazione, e il 100% viene recuperato tramite il salvataggio del prefisso valido + fallback. L'obiettivo è di rilevare e di avere un piano B sistematico.
Misurare per decidere: come abbiamo validato di non perdere nulla
Il rischio numero uno di una migrazione come questa, è di degradare silenziosamente la qualità. Abbiamo quindi costruito un harness di valutazione che confronta ogni output del modello locale con una riferimento, su un set di dossier rappresentativi annotati (diverse centinaia di sotto-documenti).
Quale riferimento? L'obiettivo è l'estrazione fatta a monte da GPT-4o (lo stack di produzione storico), consolidata tramite annotazione. Punto importante: questo riferimento non è una verità assoluta. Ci sono ancora delle incertezze di business e a volte il LLM-as-a-judge ritiene che il sezionamento o l'estrazione del modello locale siano migliori del riferimento. In altre parole, una parte degli «scostamenti» misurati non sono regressioni ma disaccordi legittimi, il che limita meccanicamente i punteggi grezzi verso il basso.
Separare il meccanico dal semantico. Tutto ciò che è paragonabile meccanicamente (confini, date, selezione, allucinazioni) è calcolato in Python puro, allineamento per overlap di pagine, F1, il che li rende KPIsriproducibili bit-per-bit tra due run. Ma alcuni criteri non si riducono a un exact-match : « Rapporto medico Dr Martin » e « Rapporto iniziale - Jean MARTIN » designano lo stesso documento. Per questi casi, un LLM-as-a-judge emette un verdetto strutturato ok | partial | ko + una breve motivazione. Solo questo strato dipende da un LLM, quindi rimane auditabile indipendentemente.
KPI
Definizione
Obiettivo
Cut F1 (tol ±1)
Precisione/richiamo dei confini di sezionamento
≥ 90 %
Date exact rate
% di date previste esatte
≥ 80 %
is_selected F1
Selezione delle parti utili
≥ 90 %
Hallucination rate
% di documenti previsti senza corrispondenza
≤ 2 %
Title verdict
Qualità del titolo, giudicata da LLM
≥ 95% ok
Tabella 4 - KPI e obiettivi di business: separare il meccanico dal semantico.
Suggerimento: il LLM-as-a-judge come annotatore quando non si ha un golden set. Costruire una ground truth a mano costa caro. Con i modelli attuali (si usa oggi Claude Code con Opus 4.8, o Codex con GPT-5.5), un LLM-as-a-judge fa un annotatore di partenza sorprendentemente affidabile: pre-annota, si rilegge, e si itera. È un ottimo modo per avviare un set di valutazione a costi ridotti.
⚠️ Su dati sensibili, anonimizza prima. Appena si inviano contenuti a un LLM-as-a-judge o a un modello di annotazione - a fortiori tramite un'API esterna - è necessario anonimizzare a monte (caviardatura delle identità, identificatori). Altrimenti, si reintroduce dalla porta di servizio esattamente la fuga di dati che si cercava di eliminare migrando on-premise. Da qui l'importanza di un set di base anonimizzato.
(Nota trasversale) Per iterare velocemente, è un agente di codice che pilota la catena di valutazione : lancia le pipeline, avvia le fasi di giudizio, aggrega i bilanci e rigenera un confronto cross-runs - senza intervento manuale. Un buon esempio di utilizzo di agenti di codice per accelerare un ciclo di R&D.
Risultati : qualità, velocità, costo
La qualità all'altezza
KPI
Score (locale)
Verdict
Cut F1 (tol ±1)
89,8 %
✓al livello obiettivo
Date exact rate
81,3 %
✓
is_selected F1
85,1 %
✓
Hallucination rate
0,4 %
✓quasi nulla
Title verdict ok
68 % ok / 25 % parziale / 6 % ko
✓
Tabella 5 - Risultati dello SLM locale vs obiettivi: tutti gli indicatori al livello atteso.
Figura 2 - Lo SLM locale raggiunge o si avvicina agli obiettivi di business su tutti i KPIs, con un tasso di allucinazione quasi nullo (0,4 %).
Su un caso rappresentativo, la segmentazione raggiunge un Cut F1 del 98 % : i confini predetti coincidono quasi tutti con i confini di riferimento, con solo due sovra-segmentazioni minori su 48.
Figura 3 - Confini di riferimento e predetti su un caso di 79 pagine. 46 dei 48 confini predetti sono esatti; i due sovra-tagli evidenziati sono gli unici scostamenti.
La velocità: più veloce del cloud
Misurazione diretta su lo stesso caso di 530 pagine :
Azure (DI + GPT-4o)
Locale (GPU L40S)
Ratio
Tempo wall-clock
45 min
30 min
× 1,5 più veloce
Costo del run
$8.70
~$0.45 (stimato sul costo orario)
× ~20 meno caro
Tabella 6 - Azure vs locale sullo stesso caso di 530 pagine.
Il costo locale non è nullo: si stima rapportando il tempo macchina al costo orario della GPU (~$0.90/h). Un run di 30 min equivale quindi a ~$0.45 di compute, contro $8.70 fatturati dal cloud sullo stesso caso.
Figura 4 - DATES e SPLIT concentrano il 92 % del tempo di elaborazione: sono le due voci da parallelizzare in priorità.
Da notare, un limite: una sola GPU non gestisce un'enorme carico parallelo: si plafona intorno a ~15 pagine/min a carico massimo. È perfetto per l'elaborazione asincrona a volume moderato, meno adatto a un picco in tempo reale massivo.
Il costo: il vero argomento su larga scala
È sul costo che il guadagno è più netto. La GPU costa un importo fisso (~$0.90/h, ovvero ~$650/mese in 24/24), indipendente dal volume. Il cloud, invece, fattura ogni pagina.
Metrica
Azure
Locale (GPU 24/24)
Costo marginale / fascicolo (530 p)
$8.70
~$0.45 (in on-demand)
Costo fisso / mese
0 (pay-as-you-go)
~$650
Soglia di redditività
-
da ~75 grandi fascicoli / mese
Tabella 7 - Costo - Azure vs GPU locale 24/24.
In modalità 24/24, il costo marginale di un fascicolo aggiuntivo tende a zero (la macchina funziona comunque). Oltre la soglia, qualsiasi volume aggiuntivo viene elaborato a costo marginale quasi nullo lato infrastruttura AI, e il divario si allarga linearmente.
Figura 5 - Il costo cloud cresce con il volume; la GPU on-premise rimane fissa. Oltre ~75 grandi fascicoli/mese, il divario si allarga a favore dell'on-premise.
Quando passare a un SLM on-premise
Questa migrazione non è un dogma. Ecco il quadro decisionale che ne deriva.
Passa a un SLM auto-ospitato quando :
hai una vincolo di sovranità / conformità forte (dati sensibili, settore regolamentato) ;
il tuo volume supera la soglia di redditività (tipicamente da decine a centinaia di fascicoli/mese) ;
ti imbatti regolarmente nei rate limits delle API : auto-ospitare significa riprendere il controllo del tuo throughput invece di subire le quote del fornitore ;
il tuo caso d'uso è « classico » (OCR, segmentation, estrazione strutturata, classificazione), laddove gli SLM hanno raggiunto i modelli grandi ;
il tuo carico è asincrono e tollera una latenza dell'ordine del minuto.
Ciò che abbiamo imparato lungo il percorso
La quantization è un compromesso locale, non una ricetta : il giusto livello dipende dal modello, dal compito e dalla tua VRAM.
MoE = qualità di un modello grande alla velocità di un piccolo : un profilo eccellente per l'auto-ospitato.
Struttura il compito piuttosto che lasciare il modello ragionare liberamente : prompt di sistema curato, e passaggi avversariali di LLM-as-a-judge quando la qualità è critica.
Testa i tuoi guard-rail in condizioni reali : i modelli open-source allucinano, la sfida è rilevare e recuperare, non mirare allo zero difetti illusorio.
Separa la valutazione meccanica (riproducibile) dal giudizio semantico (LLM) per KPIs auditabili - e anonimizza prima di qualsiasi passaggio tramite un giudice esterno.
Conclusione
Su questo trattamento documentale, un SLM open-source in architettura MoE associato a un OCR specializzato, su una singola GPU a ~$650/mese, raggiunge la qualità del cloud, è più veloce, costa fino a 20 volte meno su larga scala, e mantiene i dati sensibili all'interno del perimetro. L'open-source non sostituisce tutto : si tratta di scegliere il modello giusto per l'uso giusto. Per i compiti classici, a volume, sotto vincolo di sovranità o di rate limits, gli SLM sono pronti.
Di Maceo Duriez, AI Engineer presso Galadrim. Feedback di esperienza da un progetto cliente reale.
FAQ
Un SLM open-source può eguagliare GPT-4o sull'estrazione documentale ?
Sì, sui compiti classici (OCR, segmentation, estrazione strutturata). Su questo progetto, il modello MoE locale raggiunge il livello di GPT-4o nella segmentation ed estrazione di date. Le API proprietarie mantengono il vantaggio sul ragionamento avanzato e i compiti agentici complessi.
A partire da quale volume l'auto-ospitato diventa redditizio ?
Tipicamente da decine a centinaia di fascicoli/mese. La GPU costa un importo fisso (~650 $/mese in 24/24) ; oltre la soglia di redditività (~3000 pagine/mese qui), ogni fascicolo aggiuntivo viene elaborato a costo marginale quasi nullo, laddove il cloud fattura ogni pagina.
Quanto costa l'elaborazione di un fascicolo in locale vs cloud ?
Su un identico fascicolo di 530 pagine : ~0,45 $ di compute in locale (30 min a ~0,90 $/h di GPU) contro 8,70 $ (circa 16cts/pagina) fatturati dal cloud.
Quando rimanere su un'API proprietaria piuttosto che un SLM on-premise ?
Quando il volume è basso, che hai bisogno del ragionamento più avanzato, che devi gestire picchi di carico massicci senza provvedere all'infrastruttura, o che il dato non ha alcun vincolo di localizzazione.
Desideri essere accompagnato per lanciare il tuo progetto digitale ?