# Protocole : un corpus accepté avant de comparer le coût

Version 1 — 24 septembre 2026. Cette fiche propose un protocole à remplir ; elle ne contient aucun résultat mesuré ni jeu de données. Le notebook associé utilise un petit MLP synthétique pour apprendre à relever la mémoire. Il n'exécute pas le protocole métier ci-dessous.

## 1. Définir le travail utile avant les essais

Exemple de travail : classifier un corpus de **1 000 textes**. Constituez vous-même un jeu autorisé, représentatif de votre usage, avec un identifiant unique et une référence vérifiée par texte. Fixez la révision du corpus, du modèle, du tokenizer, du code et la graine. Conservez séparément la liste des IDs attendus et les sorties individuelles pour permettre l'audit.

Définissez avant toute mesure : les classes, le format de sortie, la métrique principale (par exemple macro-F1), son seuil d'acceptation et la dégradation maximale autorisée face à une référence. Choisissez une tolérance pertinente pour votre application ; aucune valeur universelle n'est fournie ici. Les données d'entraînement, de réglage et d'évaluation doivent rester séparées.

Un corpus est accepté seulement si les 1 000 IDs attendus sont présents exactement une fois, aucune réponse supplémentaire ne figure dans les sorties, le format est valide et la règle de qualité préétablie est satisfaite. Deux fichiers contenant chacun 1 000 lignes ne prouvent pas à eux seuls l'égalité des IDs. Archivez le contrôle des ensembles et des doublons.

## 2. Ne changer que la variante annoncée

Pour étudier le batch, préparez par exemple des variantes 1, 4 et 8. Gardez le même corpus, ordre des entrées, modèle, tokenizer, précision et limite de contexte. Si vous étudiez ensuite la précision, créez une expérience distincte et refaites le contrôle qualité. Décrivez la troncature : raccourcir les textes change le travail accompli.

Relevez le GPU réel, le nombre de GPU effectivement utilisés, le device, le pilote, Python, PyTorch et le runtime CUDA ou ROCm. Inscrivez aussi la version de votre code, les options de génération éventuelles et toute concurrence sur la machine dans `notes`. Un lot commercial de deux GPU n'implique pas que le programme les utilise tous deux.

## 3. Mesurer des passages comparables

Annoncez ce que le chronomètre englobe : traitement seul ou chaîne complète avec lecture, tokenisation et écriture. Séparez chargement, premier passage et passages échauffés. Le script mémoire ne mesure que son MLP et ne chronomètre pas une chaîne de classification complète.

Effectuez l'échauffement annoncé, puis cinq passages mesurés par variante dans un ordre alterné ou tiré à l'avance. Gardez chaque durée brute. Rapporter la médiane et l'étendue min–max permet de voir la dispersion ; cinq observations ne justifient pas une estimation robuste du p95. N'écartez pas silencieusement une erreur ou un passage lent : conservez sa ligne et expliquez l'incident. Relancez dans un processus neuf si vous souhaitez comparer les premiers passages dans des conditions similaires.

Pour les mesures GPU PyTorch, synchronisez le device choisi avant le relevé initial et après l'opération. Relevez les baselines `allocated` et `reserved`, réinitialisez les statistiques de pic, puis conservez les pics absolus de la phase. `allocated` est inclus dans `reserved` : les additionner compterait deux fois une partie de la mémoire. Les deux maxima peuvent être atteints à des instants différents : leur différence n'est pas une mesure du cache à un instant donné. Les allocations d'autres processus et celles extérieures à l'allocateur PyTorch ne sont pas couvertes.

## 4. Remplir resultats-bruts.csv

Le CSV distribué contient uniquement les en-têtes. Écrivez une ligne par passage, avec un point décimal et des secondes pour les temps, des octets pour la mémoire et des centimes USD pour le forfait. Une cellule vide signifie « non relevé » ; zéro signifie réellement zéro. Les virgules présentes dans une note doivent être protégées par les règles CSV habituelles.

| Champs | Sens et saisie |
| --- | --- |
| `experiment_id`, `variant_id` | Identifiants stables de l'expérience et de la variante. |
| `corpus_revision`, `model_revision`, `tokenizer_revision`, `seed` | Versions immuables ou empreintes, et graine annoncée. |
| `gpu_model`, `gpu_count`, `device`, `driver_version`, `python_version`, `torch_version`, `runtime_version` | Matériel réellement utilisé et environnement observé ; ne pas recopier une promesse d'offre. |
| `precision`, `batch`, `context` | Configuration réellement appliquée. |
| `phase`, `run_index`, `warmup_iterations` | Phase séparée (`cold` ou `warm`, par exemple), numéro du passage, nombre d'échauffements. Ne mélangez pas les durées. |
| `expected_ids`, `observed_ids` | Nombres d'IDs attendus et observés ; les listes détaillées sont conservées avec les sorties. |
| `ids_match`, `format_valid` | `true`/`false` après vérification réelle, y compris doublons et réponses supplémentaires. |
| `quality_metric`, `quality_threshold`, `quality_tolerance`, `quality_value` | Nom, seuil et tolérance préétablis, puis valeur mesurée. Préciser le sens de la tolérance et la référence dans `notes`. |
| `corpus_accepted` | `true` seulement si toutes les conditions de validation sont satisfaites ; sinon `false`. |
| `elapsed_seconds` | Durée brute du périmètre annoncé, jamais une valeur attendue. |
| `baseline_allocated_bytes`, `baseline_reserved_bytes`, `peak_allocated_bytes`, `peak_reserved_bytes` | Relevés distincts pour le seul device mesuré. Laisser vides si non mesurés. |
| `duration_days`, `lots`, `package_total_usd_minor` | Forfait complet choisi, lots facturés et prix total en centimes USD ; une seule dépense ne doit pas être additionnée cinq fois. |
| `accepted_unique_corpora` | Nombre de corpus utiles distincts acceptés pour l'analyse économique ; ce champ n'est pas à sommer entre répétitions. |
| `notes` | Périmètre, incidents, décisions qualité, révision du code et références des pièces conservées. |

## 5. Calculer sans inventer de production

Le prix à comparer est le forfait entier de 3, 7 ou 30 jours multiplié par les lots. Pour B200, un lot contient deux GPU et le tarif couvre déjà ce lot. `calcul_forfaits.py` applique cette règle aux tarifs fournis.

Si le travail utile choisi est un corpus complet accepté, `--accepted-results` doit recevoir le nombre de corpus distincts effectivement validés sur la période. Les cinq répétitions du même corpus servent à mesurer la variabilité : elles ne créent pas cinq livrables utiles. Fixez l'unité avant la comparaison et gardez-la pour toutes les variantes. Sans quantité mesurée et acceptée, laissez ce paramètre absent : seul le coût du forfait sera calculé. Ne projetez pas automatiquement une cadence sur 3, 7 ou 30 jours.

Conservez ensemble le protocole rempli, les sorties individuelles, les contrôles qualité, le CSV brut et le calcul économique. Une configuration plus rapide mais non acceptée ne remplit pas le même objectif. Une configuration qui dépasse la mémoire reste une observation d'échec, pas un temps à remplacer par zéro.
