# IteraGPU Lab v1

Risorse originali, versione del 24 settembre 2026, per preparare un esperimento GPU riproducibile. Il notebook sulla memoria e il suo compagno eseguono una piccola rete sintetica `Linear → GELU → Linear`. Non scaricano alcun modello né dataset. Questa rete non è un LLM, né un addestramento, né un benchmark rappresentativo delle GPU proposte a noleggio.

## Contenuto

- `mesure-memoire.ipynb`: notebook autonomo, codice incluso, celle senza output salvati.
- `mesure_memoire.py`: stessa aritmetica e stesso protocollo di misurazione, utilizzabili da riga di comando.
- `protocole-qualite.md`: protocollo operativo da completare prima di confrontare tempi e costi.
- `resultats-bruts.csv`: griglia vuota, una riga da compilare per ogni esecuzione reale.
- `calcul_forfaits.py`: calcolo del forfait completo, senza dipendenze esterne.
- `tarifs-forfaits.csv`: 45 tariffe IteraGPU, 15 modelli × 3 durate, istantanea del 24 settembre 2026.
- `LICENSE.txt`: licenza MIT del codice, del notebook e dei documenti originali.
- `MANIFEST.json`: elenco esaustivo dei nove membri dell'archivio, dimensioni e SHA-256 degli otto file di contenuto. Il manifest si dichiara esso stesso privo di impronta per evitare un'impronta autoreferenziale.

L'archivio `iteragpu-lab-v1.zip` contiene questi nove file sotto un'unica cartella. Non contiene né risultati GPU, né ambiente Python, né driver, né credenziali. Estrarre i file in una directory nuova. Il notebook può anche essere scaricato da solo: non importa lo script compagno.

## Prerequisiti e limiti

I calcoli aritmetici e di forfait utilizzano solo Python 3.10 o successivo e la sua libreria standard. Il notebook richiede uno strumento in grado di aprire un notebook Python; nessun server Jupyter è fornito. La misurazione richiede inoltre un'installazione esistente di PyTorch compatibile con la GPU, il driver e il suo runtime CUDA o ROCm. Nessun comando della cartella installa questi componenti.

Scegliere un device esplicito, ad esempio `cuda:0`. Anche il backend ROCm di PyTorch riutilizza questo nome di interfaccia; ciò non prova la compatibilità di una particolare installazione AMD. Senza PyTorch caricabile o senza GPU accessibile, `measure` termina con il codice 2 e un messaggio chiaro. Non scrive alcuna misura falsa e non passa alla CPU. `environment` è una diagnostica: un output valido può annunciare una GPU non disponibile.

## 1. Stimare i pesi, senza GPU

```console
python mesure_memoire.py estimate --parameters 7000000000 --bits 16 --reserve-gib 4
```

Questo calcolo prende un numero di parametri e una larghezza di memorizzazione. Arrotonda i bit al numero intero di byte superiore, poi converte in GiB (`2**30` byte). Un GB decimale rappresenta `10**9` byte. I 4 GiB sono un'ipotesi scelta in questo esempio, non una riserva misurata. Il risultato non include automaticamente attivazioni, cache KV, metadati di quantizzazione, gradienti, stati dell'optimizer o librerie. Non prevede se un modello reale entra su una scheda.

## 2. Verificare l'ambiente esistente

```console
python mesure_memoire.py environment --device cuda:0
```

Conservare Python, versione di PyTorch, versione di build CUDA/HIP, GPU effettivamente visibile e memoria annunciata dal runtime. Il driver deve essere rilevato separatamente con lo strumento del fornitore. Lo script non raccoglie né variabili d'ambiente, né dati personali. La versione del runtime integrato in PyTorch non è la versione del driver.

## 3. Effettuare una misurazione esplicitamente limitata

Iniziare in piccolo, in un processo nuovo:

```console
python mesure_memoire.py measure --device cuda:0 --batch 1 --context 16 --width 64 --dtype float32 --warmup 1 --repeats 2 --output mesures-petit-essai.json
```

Per esplorare poi le dimensioni del MLP, un esempio di comando più grande è:

```console
python mesure_memoire.py measure --device cuda:0 --batch 2 --context 128 --width 1024 --dtype float32 --warmup 3 --repeats 5 --output mesures.json
```

Aumenta una dimensione alla volta e monitora la memoria disponibile. Il secondo comando è una configurazione proposta, non una capacità garantita né un risultato pubblicato. Qui `context` indica il numero di posizioni dell'input `[batch, context, width]`, senza meccanismo di attenzione o cache KV. I pesi e gli input condividono il dtype richiesto; nessun autocast, gradienti, ottimizzatore, quantizzazione o ripartizione tra GPU. `float16` e `bfloat16` dipendono dall'installazione effettiva e non sono validati dalla sola prova in float32.

Il JSON contiene `environment`, `configuration`, `synthetic_model` e `phases`. Il file deve avere un nome nuovo; lo script rifiuta di sovrascrivere un risultato esistente.

| Fase | Perimetro |
| --- | --- |
| `model_load` | Costruzione e inizializzazione CPU del modello, trasferimento sulla GPU scelta. Il tempo include questa preparazione CPU; i contatori di memoria riguardano solo la GPU. |
| `inputs` | Creazione degli input sintetici su questa GPU. |
| `cold_forward` | Primo passaggio del modello dopo l'inizializzazione del device, del generatore e degli input. Non è un avvio a freddo della macchina o del driver. |
| `warmup` | Insieme dei passaggi di riscaldamento; questo tempo non viene mescolato con le ripetizioni successive. |
| `warm_forward` | Una riga per ripetizione dopo il riscaldamento. |

Ogni fase sincronizza il device prima e dopo l'operazione, rileva le baseline e poi azzera i picchi. Gli output sono ancora presenti al rilevamento finale; vengono liberati prima del passaggio successivo. I pesi e gli input persistono tra i passaggi. La cache dell'allocatore viene conservata. I tempi includono il costo Python e la sincronizzazione: non sono tempi kernel isolati.

`allocated` fa parte di `reserved`, quindi non si sommano. `peak_allocated_bytes` e `peak_reserved_bytes` sono due massimi distinti: non si sottraggono per calcolare una cache. Confronta separatamente baseline, fini e picchi assoluti. I contatori coprono solo l'allocatore PyTorch di questo processo sulla GPU scelta, non tutta la memoria della GPU, del driver o di altri processi. Un eventuale altra GPU non viene misurata. I valori dipendono anche dall'allocatore e dal software: conserva l'ambiente insieme ai risultati.

## 4. Collegare qualità e costo

Leggi `protocole-qualite.md`, fissa il lavoro utile e la soglia prima della prova, poi compila `resultats-bruts.csv` con le osservazioni reali. Questa cartella non fornisce alcun corpus di classificazione né misura di qualità.

```console
python calcul_forfaits.py --gpu b200 --days 7 --lots 2
```

Il prezzo di un lotto B200 comprende già due GPU. Due lotti danno quattro GPU, ma il prezzo del lotto viene moltiplicato solo per due. Le tariffe sono quelle del catalogo IteraGPU al giorno di questo snapshot: unità intere in centesimi USD, durate di 3, 7 o 30 giorni, senza conversione né prorata oraria. Il CSV non prova né la disponibilità attuale né la reservation. Verifica l'offerta mostrata prima di qualsiasi decisione di acquisto.

L'opzione `--accepted-results` è volutamente senza valore predefinito. Aggiungila solo con il numero intero positivo di unità utili distinte realmente accettate. Il costo unitario usa il prezzo del forfait intero. Le ripetizioni dello stesso benchmark non sono nuovi corpus utili. Senza denominatore compilato, il costo unitario resta `null`; zero viene rifiutato.

## Validazione di questa versione

L'aritmetica, le tariffe e l'assenza di output precompilati sono verificati con Python 3.12.14 e la sua libreria standard. Questo ambiente non contiene PyTorch: la guardia di assenza viene quindi testata realmente. Nessuna installazione è stata effettuata.

Una prova funzionale limitata è stata eseguita anche il 24 settembre 2026 su una **GeForce RTX 5070 locale**, driver 610.62, Python 3.14.6, PyTorch 2.11.0+cu128, CUDA 12.8: batch 1, contesto 16, larghezza 64, float32, un riscaldamento e due ripetizioni. Convalida l'esecuzione delle sei righe di fase dello script su questo unico caso. Non convalida né le prestazioni delle GPU del catalogo, né una macchina a noleggio, né un LLM, né ROCm, né le altre precisioni. Le misure di questa prova non sono precompilate nei file distribuiti. Il notebook conserva tutti i suoi output vuoti.

## Fonti tecniche primarie

Documentazione consultata il 24 settembre 2026. Questi riferimenti spiegano le API; la versione PyTorch realmente eseguita è indicata sopra, distinta da quella delle pagine documentali.

- [PyTorch: gestione della memoria CUDA](https://docs.pytorch.org/docs/2.14/notes/cuda.html#memory-management)
- [PyTorch: semantica HIP/ROCm](https://docs.pytorch.org/docs/2.14/notes/hip.html)
- [PyTorch: sincronizzazione del device](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.synchronize.html)
- [PyTorch: azzeramento dei picchi](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.reset_peak_memory_stats.html)
- [PyTorch: memoria allocata](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.memory_allocated.html) e [memoria riservata](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.memory_reserved.html)
- [PyTorch: massimo allocato](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.max_memory_allocated.html) e [massimo riservato](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.max_memory_reserved.html)
- [Python: aritmetica decimale](https://docs.python.org/3/library/decimal.html) e [file CSV](https://docs.python.org/3/library/csv.html)

## Licenza

Le creazioni originali della cartella sono distribuite sotto licenza MIT, riprodotta in `LICENSE.txt`. Conservare la nota in caso di ridistribuzione. Python, PyTorch e gli altri strumenti citati non sono distribuiti con l'archivio e mantengono le rispettive licenze.
