# IteraGPU Lab v1

Ressources originales, version du 24 septembre 2026, pour préparer une expérience GPU reproductible. Le notebook de mémoire et son compagnon exécutent un petit réseau synthétique `Linear → GELU → Linear`. Ils ne téléchargent aucun modèle ni jeu de données. Ce réseau n'est ni un LLM, ni un entraînement, ni un benchmark représentatif des GPU proposés à la location.

## Contenu

- `mesure-memoire.ipynb` : notebook autonome, code inclus, cellules sans sorties enregistrées.
- `mesure_memoire.py` : même arithmétique et même protocole de mesure, utilisables en ligne de commande.
- `protocole-qualite.md` : protocole métier à compléter avant de comparer temps et coût.
- `resultats-bruts.csv` : grille vierge, une ligne à remplir par passage réel.
- `calcul_forfaits.py` : calcul du forfait complet, sans dépendance externe.
- `tarifs-forfaits.csv` : 45 tarifs IteraGPU, 15 modèles × 3 durées, instantané du 24 septembre 2026.
- `LICENSE.txt` : licence MIT du code, du notebook et des documents originaux.
- `MANIFEST.json` : liste exhaustive des neuf membres de l'archive, tailles et SHA-256 des huit fichiers de contenu. Le manifeste se déclare lui-même sans empreinte afin d'éviter une empreinte autoréférente.

L'archive `iteragpu-lab-v1.zip` contient ces neuf fichiers sous un dossier unique. Elle ne contient ni résultat GPU, ni environnement Python, ni pilote, ni identifiant. Extraire les fichiers dans un répertoire neuf. Le notebook peut aussi être téléchargé seul : il n'importe pas le script compagnon.

## Prérequis et limites

Les calculs arithmétiques et de forfait utilisent seulement Python 3.10 ou ultérieur et sa bibliothèque standard. Le notebook nécessite un outil sachant ouvrir un notebook Python ; aucun serveur Jupyter n'est fourni. La mesure nécessite en plus une installation existante de PyTorch compatible avec le GPU, le pilote et son runtime CUDA ou ROCm. Aucune commande du dossier n'installe ces composants.

Choisir un device explicite, par exemple `cuda:0`. Le backend ROCm de PyTorch réutilise aussi ce nom d'interface ; cela ne prouve pas la compatibilité d'une installation AMD particulière. Sans PyTorch chargeable ou sans GPU accessible, `measure` termine avec le code 2 et un message clair. Il n'écrit aucune fausse mesure et ne bascule pas sur le CPU. `environment` est un diagnostic : une sortie valide peut annoncer un GPU indisponible.

## 1. Estimer les poids, sans GPU

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

Ce calcul prend un nombre de paramètres et une largeur de stockage. Il arrondit les bits au nombre entier d'octets supérieur, puis convertit en Gio (`2**30` octets). Un Go décimal représente `10**9` octets. Les 4 Gio sont une hypothèse choisie dans cet exemple, pas une réserve mesurée. Le résultat n'inclut pas automatiquement activations, cache KV, métadonnées de quantification, gradients, états d'optimiseur ou bibliothèques. Il ne prédit pas si un modèle réel tient sur une carte.

## 2. Vérifier l'environnement existant

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

Conserver Python, version PyTorch, version de build CUDA/HIP, GPU réellement visible et mémoire annoncée par le runtime. Le pilote doit être relevé séparément avec l'outil du fournisseur. Le script ne collecte ni variables d'environnement, ni données personnelles. La version du runtime intégré à PyTorch n'est pas la version du pilote.

## 3. Effectuer une mesure explicitement bornée

Commencer petit, dans un processus neuf :

```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
```

Pour explorer ensuite les dimensions du MLP, un exemple de commande plus grand est :

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

Augmenter une dimension à la fois et surveiller la mémoire disponible. La seconde commande est une configuration proposée, pas une capacité garantie ni un résultat publié. `context` désigne ici le nombre de positions de l'entrée `[batch, context, width]`, sans mécanisme d'attention ou cache KV. Les poids et entrées partagent le dtype demandé ; pas d'autocast, de gradients, d'optimiseur, de quantification ou de répartition entre GPU. `float16` et `bfloat16` dépendent de l'installation effective et ne sont pas validés par le seul essai float32.

Le JSON contient `environment`, `configuration`, `synthetic_model` et `phases`. Le fichier doit avoir un nom nouveau ; le script refuse d'écraser un résultat existant.

| Phase | Périmètre |
| --- | --- |
| `model_load` | Construction et initialisation CPU du modèle, transfert vers le GPU choisi. Le temps inclut cette préparation CPU ; les compteurs mémoire portent seulement sur le GPU. |
| `inputs` | Création des entrées synthétiques sur ce GPU. |
| `cold_forward` | Premier passage du modèle après initialisation du device, du générateur et des entrées. Ce n'est pas un démarrage à froid de la machine ou du pilote. |
| `warmup` | Ensemble des passages d'échauffement ; ce temps n'est pas mélangé aux répétitions suivantes. |
| `warm_forward` | Une ligne par répétition après échauffement. |

Chaque phase synchronise le device avant et après l'opération, relève les baselines puis réinitialise les pics. Les sorties sont encore présentes au relevé de fin ; elles sont libérées avant le passage suivant. Les poids et entrées persistent entre passages. Le cache de l'allocateur est conservé. Les temps incluent le coût Python et la synchronisation : ce ne sont pas des temps noyau isolés.

`allocated` fait partie de `reserved`, donc on ne les additionne pas. `peak_allocated_bytes` et `peak_reserved_bytes` sont deux maxima distincts : on ne les soustrait pas pour calculer un cache. Comparer séparément les baselines, fins et pics absolus. Les compteurs ne couvrent que l'allocateur PyTorch de ce processus sur le GPU choisi, pas toute la mémoire du GPU, du pilote ou d'autres processus. Un éventuel autre GPU n'est pas mesuré. Les valeurs dépendent aussi de l'allocateur et du logiciel : conserver l'environnement avec les résultats.

## 4. Relier qualité et coût

Lire `protocole-qualite.md`, fixer le travail utile et le seuil avant l'essai, puis remplir `resultats-bruts.csv` avec les observations réelles. Ce dossier ne fournit aucun corpus de classification ni mesure qualité.

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

Le prix d'un lot B200 comprend déjà deux GPU. Deux lots donnent quatre GPU, mais le prix du lot est multiplié uniquement par deux. Les tarifs sont ceux du catalogue IteraGPU au jour de cet instantané : unités entières en centimes USD, durées de 3, 7 ou 30 jours, sans conversion ni prorata horaire. Le CSV ne prouve ni disponibilité actuelle ni reservation. Vérifier l'offre affichée avant toute décision d'achat.

L'option `--accepted-results` est volontairement sans valeur par défaut. L'ajouter seulement avec le nombre entier positif d'unités utiles distinctes réellement acceptées. Le coût unitaire utilise le prix du forfait entier. Les répétitions du même benchmark ne sont pas de nouveaux corpus utiles. Sans dénominateur renseigné, le coût unitaire reste `null` ; zéro est refusé.

## Validation de cette version

L'arithmétique, les tarifs et l'absence de sorties préremplies sont vérifiés avec Python 3.12.14 et sa bibliothèque standard. Cet environnement ne contient pas PyTorch : la garde d'absence est donc testée réellement. Aucune installation n'a été effectuée.

Un essai fonctionnel borné a aussi été exécuté le 24 septembre 2026 sur une **GeForce RTX 5070 locale**, pilote 610.62, Python 3.14.6, PyTorch 2.11.0+cu128, CUDA 12.8 : batch 1, contexte 16, largeur 64, float32, un échauffement et deux répétitions. Il valide l'exécution des six lignes de phase du script sur ce seul cas. Il ne valide ni les performances des GPU du catalogue, ni une machine louée, ni un LLM, ni ROCm, ni les autres précisions. Les mesures de cet essai ne sont pas préremplies dans les fichiers distribués. Le notebook conserve toutes ses sorties vides.

## Sources techniques primaires

Documentation consultée le 24 septembre 2026. Ces références expliquent les API ; la version PyTorch réellement exécutée est indiquée ci-dessus, distincte de celle des pages documentaires.

- [PyTorch : gestion de mémoire CUDA](https://docs.pytorch.org/docs/2.14/notes/cuda.html#memory-management)
- [PyTorch : sémantique HIP/ROCm](https://docs.pytorch.org/docs/2.14/notes/hip.html)
- [PyTorch : synchronisation du device](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.synchronize.html)
- [PyTorch : remise à zéro des pics](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.reset_peak_memory_stats.html)
- [PyTorch : mémoire allouée](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.memory_allocated.html) et [mémoire réservée](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.memory_reserved.html)
- [PyTorch : maximum alloué](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.max_memory_allocated.html) et [maximum réservé](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.max_memory_reserved.html)
- [Python : arithmétique décimale](https://docs.python.org/3/library/decimal.html) et [fichiers CSV](https://docs.python.org/3/library/csv.html)

## Licence

Les créations originales du dossier sont distribuées sous licence MIT, reproduite dans `LICENSE.txt`. Conserver la notice lors d'une redistribution. Python, PyTorch et les autres outils cités ne sont pas distribués avec l'archive et conservent leurs licences respectives.
