# Protocollo: un corpus accettato prima di confrontare il costo

Versione 1 — 24 settembre 2026. Questa scheda propone un protocollo da compilare; non contiene alcun risultato misurato né set di dati. Il notebook associato utilizza un piccolo MLP sintetico per imparare a rilevare la memoria. Non esegue il protocollo operativo riportato di seguito.

## 1. Definire il lavoro utile prima delle prove

Esempio di lavoro: classificare un corpus di **1 000 testi**. Costituisci tu stesso un set autorizzato, rappresentativo del tuo utilizzo, con un identificatore univoco e un riferimento verificato per ogni testo. Fissa la revisione del corpus, del modello, del tokenizer, del codice e il seed. Conserva separatamente la lista degli ID attesi e le uscite individuali per consentire l'audit.

Definisci prima di qualsiasi misurazione: le classi, il formato di output, la metrica principale (ad esempio macro-F1), la sua soglia di accettazione e la degradazione massima consentita rispetto a un riferimento. Scegli una tolleranza pertinente per la tua applicazione; qui non viene fornito alcun valore universale. I dati di addestramento, di regolazione e di valutazione devono rimanere separati.

Un corpus è accettato solo se i 1 000 ID attesi sono presenti esattamente una volta, nessuna risposta supplementare figura nelle uscite, il formato è valido e la regola di qualità prestabilita è soddisfatta. Due file contenenti ciascuno 1 000 righe non provano da soli l'uguaglianza degli ID. Archivia il controllo degli insiemi e dei duplicati.

## 2. Cambiare solo la variante annunciata

Per studiare il batch, prepara ad esempio le varianti 1, 4 e 8. Mantieni lo stesso corpus, l'ordine degli input, il modello, il tokenizer, la precisione e il limite di contesto. Se studi successivamente la precisione, crea un esperimento distinto e rifai il controllo qualità. Descrivi il troncamento: accorciare i testi cambia il lavoro svolto.

Rileva la GPU reale, il numero di GPU effettivamente utilizzate, il device, il driver, Python, PyTorch e il runtime CUDA o ROCm. Inscrivi anche la versione del tuo codice, le eventuali opzioni di generazione e qualsiasi concorrenza sulla macchina in `notes`. Un lotto commerciale di due GPU non implica che il programma le utilizzi entrambe.

## 3. Misurare passaggi confrontabili

Annuncia ciò che il cronometro comprende: solo l'elaborazione o l'intera catena con lettura, tokenizzazione e scrittura. Separa caricamento, primo passaggio e passaggi riscaldati. Lo script della memoria misura solo il suo MLP e non cronometra una catena di classificazione completa.

Esegui il riscaldamento annunciato, poi cinque passaggi misurati per variante in un ordine alternato o estratto in anticipo. Conserva ogni durata grezza. Riportare la mediana e l'intervallo min–max permette di vedere la dispersione; cinque osservazioni non giustificano una stima robusta del p95. Non scartare silenziosamente un errore o un passaggio lento: conserva la sua riga e spiega l'incidente. Riavvia in un processo nuovo se desideri confrontare i primi passaggi in condizioni simili.

Per le misurazioni GPU PyTorch, sincronizza il device scelto prima del rilevamento iniziale e dopo l'operazione. Rileva le baseline `allocated` e `reserved`, reimposta le statistiche di picco, poi conserva i picchi assoluti della fase. `allocated` è incluso in `reserved`: sommarli conterebbe due volte una parte della memoria. I due massimi possono essere raggiunti in istanti diversi: la loro differenza non è una misura della cache in un dato istante. Le allocazioni di altri processi e quelle esterne all'allocatore PyTorch non sono coperte.

## 4. Compilare resultats-bruts.csv

Il CSV distribuito contiene unicamente le intestazioni. Scrivi una riga per passaggio, con un punto decimale e secondi per i tempi, byte per la memoria e centesimi USD per il forfait. Una cella vuota significa «non rilevato»; zero significa realmente zero. Le virgole presenti in una nota devono essere protette dalle regole CSV abituali.

| Campi | Significato e inserimento |
| --- | --- |
| `experiment_id`, `variant_id` | Identificatori stabili dell'esperimento e della variante. |
| `corpus_revision`, `model_revision`, `tokenizer_revision`, `seed` | Versioni immutabili o impronte, e seed dichiarato. |
| `gpu_model`, `gpu_count`, `device`, `driver_version`, `python_version`, `torch_version`, `runtime_version` | Hardware effettivamente utilizzato e ambiente osservato; non copiare una promessa dell'offerta. |
| `precision`, `batch`, `context` | Configurazione effettivamente applicata. |
| `phase`, `run_index`, `warmup_iterations` | Fase separata (`cold` o `warm`, ad esempio), numero del passaggio, numero di riscaldamenti. Non mescolare le durate. |
| `expected_ids`, `observed_ids` | Numeri di ID attesi e osservati; gli elenchi dettagliati sono conservati con gli output. |
| `ids_match`, `format_valid` | `true`/`false` dopo verifica reale, inclusi duplicati e risposte aggiuntive. |
| `quality_metric`, `quality_threshold`, `quality_tolerance`, `quality_value` | Nome, soglia e tolleranza prestabiliti, poi valore misurato. Specificare il senso della tolleranza e il riferimento in `notes`. |
| `corpus_accepted` | `true` solo se tutte le condizioni di validazione sono soddisfatte; altrimenti `false`. |
| `elapsed_seconds` | Durata grezza del perimetro dichiarato, mai un valore atteso. |
| `baseline_allocated_bytes`, `baseline_reserved_bytes`, `peak_allocated_bytes`, `peak_reserved_bytes` | Rilevazioni distinte per il solo device misurato. Lasciare vuoti se non misurati. |
| `duration_days`, `lots`, `package_total_usd_minor` | Pacchetto completo scelto, lotti fatturati e prezzo totale in centesimi USD; una sola spesa non deve essere sommata cinque volte. |
| `accepted_unique_corpora` | Numero di corpus utili distinti accettati per l'analisi economica; questo campo non va sommato tra le ripetizioni. |
| `notes` | Perimetro, incidenti, decisioni di qualità, revisione del codice e riferimenti dei documenti conservati. |

## 5. Calcolare senza inventare produzione

Il prezzo da confrontare è il pacchetto intero di 3, 7 o 30 giorni moltiplicato per i lotti. Per B200, un lotto contiene due GPU e la tariffa copre già questo lotto. `calcul_forfaits.py` applica questa regola alle tariffe fornite.

Se il lavoro utile scelto è un corpus completo accettato, `--accepted-results` deve ricevere il numero di corpus distinti effettivamente validati nel periodo. Le cinque ripetizioni dello stesso corpus servono a misurare la variabilità: non creano cinque deliverable utili. Fissa l'unità prima del confronto e mantienila per tutte le varianti. Senza quantità misurata e accettata, lascia questo parametro assente: sarà calcolato solo il costo del pacchetto. Non proiettare automaticamente una cadenza su 3, 7 o 30 giorni.

Conserva insieme il protocollo compilato, gli output individuali, i controlli di qualità, il CSV grezzo e il calcolo economico. Una configurazione più veloce ma non accettata non soddisfa lo stesso obiettivo. Una configurazione che supera la memoria resta un'osservazione di errore, non un tempo da sostituire con zero.
