day0-release

Par nvidia · model-optimizer

Pilote déterministe de bout en bout pour les releases de checkpoints quantifiés à J-0 — enchaîne PTQ → évaluation → comparaison avec des gates imposées entre les étapes (l'étape d'évaluation déploie le checkpoint lui-même), et retourne une décision de publication (ACCEPT / REGRESSION / ANOMALOUS / INFEASIBLE). À utiliser quand l'utilisateur demande à « releaser un modèle à J-0 », « quantifier et valider que le modèle X est dans les N% de la baseline et indiquer si il est publiable », ou « lancer le workflow complet J-0 ». NE PAS utiliser pour les requêtes à étape unique — quantification seule (utiliser ptq), serving seul (utiliser deployment), évaluation seule (utiliser evaluation), ou comparaison de deux runs existants (utiliser compare-results).

npx skills add https://github.com/nvidia/model-optimizer --skill day0-release

Publication Release Jour-0

Conduire un modèle depuis un checkpoint pré-entraîné jusqu'à une décision de publication pour un checkpoint quantifié, dans une séquence fixe avec une gate après chaque étape. Cette skill est un conductor : elle ordonnance les domain skills existantes et applique les gates — elle ne réimplémente pas la quantification, le serving, l'évaluation ou la comparaison.

Objectif (le critère jour-0 par défaut) : un checkpoint quantifié plus petit que la source, avec une baisse de précision inférieure au seuil (défaut <1%) sur l'ensemble de benchmarks standard par rapport à la baseline correspondante, plus une recommandation de publication.

Quand utiliser

À utiliser uniquement pour la publication complète guidée par objectif. Pour une seule étape, router directement vers la domain skill : quantify → ptq, serve → deployment, evaluate → evaluation, compare deux runs existants → compare-results.

Entrées

Résoudre ces points avant de commencer (demander à l'utilisateur tout élément manquant) :

  • Model — identifiant HF ou chemin du checkpoint.
  • Recipe / qformat — ex. nvfp4, fp8, ou chemin d'une recipe. Un candidat pour v1.
  • Cluster / launcher — issu de clusters.yaml (voir skills/common/environment-setup.md).
  • Eval set — par défaut la suite AA (evaluation/recipes/tasks/aa/).
  • Threshold — baisse de précision max ; défaut 0.01 (1%).

La chaîne

setup ─▶ PTQ ─▶ baseline-eval ─▶ quantized-eval ─▶ compare ─▶ closeout
          │          │                │               │
       gate_ptq   gate_run         gate_run       gate_compare

La skill evaluation déploie le modèle qu'elle évalue (elle lève son propre endpoint par run), il n'y a donc pas d'étape de deploy séparée — un échec de serving remonte par la gate de l'étape d'eval (DEPLOYMENT_HEALTH_FAILED) et triage vers la skill deployment pour déboguer le serving isolément (voir Étape 4).

Exécuter chaque étape en invoquant la domain skill, puis exécuter sa gate avant de progresser. Ne pas avancer au-delà d'une gate échouée. Copier cette checklist et suivre la progression :

- [ ] Étape 0 : Résoudre les entrées ; confirmer le seuil et l'ensemble d'eval
- [ ] Étape 1 : Setup gate — credentials présentes, cluster joignable
- [ ] Étape 2 : PTQ (skill ptq) → gate_ptq.py
- [ ] Étape 3 : Baseline eval (skill evaluation, déploie la source) → gate_run.py   [skip si en cache, voir ci-dessous]
- [ ] Étape 4 : Quantized eval (skill evaluation, déploie le candidat) → gate_run.py
- [ ] Étape 5 : Compare (skill compare-results) → gate_compare.py → décision
- [ ] Étape 6 : Closeout — rapport + recommandation de publication

Étape 1 — Setup gate

Confirmer les credentials (skills/common/credentials.md) et la joignabilité du cluster (skills/common/remote-execution.md). Si l'une échoue, arrêter avec SYSTEMIC — ne pas démarrer le PTQ.

Étape 2 — PTQ

Invoquer la skill ptq pour produire le checkpoint quantifié. Puis gate :

# La validation post-PTQ de la skill ptq produit un JSON validation-summary (ratio
# de taille + décomptes de précision par couche + diffs de métadonnées ; voir
# ptq/references/checkpoint-validation.md). v1 gate sur ce résumé :
python .agents/skills/day0-release/scripts/gate_ptq.py --summary <validation-summary.json>
#   ajouter `--recipe <qformat>` pour surcharger la recipe enregistrée dans le résumé

gate_ptq.py retourne JSON {pass, failure_class, detail}. Si pass: false, brancher sur failure_class (voir Triage ci-dessous). Ne pas évaluer un checkpoint non validé.

Étape 3 — Baseline eval

La baseline est le modèle source (pré-quantification) sur le même ensemble de tâches et paramètres d'échantillonnage. La chercher d'abord — si un run de baseline correspondant existe déjà dans MLflow (même modèle, même ensemble de tâches, mêmes paramètres d'échantillonnage), le réutiliser et sauter cette étape. Sinon, l'exécuter via la skill evaluation (qui déploie elle-même le modèle source). Gate avec gate_run.py.

Étape 4 — Quantized eval

Invoquer la skill evaluation sur le checkpoint quantifié, en utilisant l'ensemble de tâches et les paramètres d'échantillonnage de la baseline. La skill evaluation lève elle-même l'endpoint de serving (elle construit deployment.command, ex. une vllm serve …), donc un échec de serving remonte ici comme une gate_run.py échouée avec DEPLOYMENT_HEALTH_FAILED. Quand cela arrive, descendre à la skill deployment pour reproduire et déboguer le serving isolément (servir le checkpoint standalone, confirmer /health + une génération, itérer sur les flags / TP / image / vars d'env) plutôt que de brûler des cycles d'eval complets sur un endpoint cassé — puis porter la commande fonctionnelle dans deployment.command de NEL et reprendre l'eval. Si le checkpoint ne peut vraiment pas être servi, POINT_INFEASIBLE. Gate :

python .agents/skills/day0-release/scripts/gate_run.py --run <run-summary.json>

Un pass: false ici signifie que le run est incomplet ou invalide (erreur judge/parse, échantillons perdus) — ne pas comparer les scores à partir de lui.

Étape 5 — Compare

Invoquer la skill compare-results pour produire les deltas par tâche, puis gate :

python .agents/skills/day0-release/scripts/gate_compare.py \
    --baseline <baseline_scores.json> --candidate <candidate_scores.json> \
    --threshold 0.01

Le seuil est une fraction de l'échelle de score de chaque tâche. La plupart des tâches AA rapportent 0-100, mais certaines (ex. tau2_bench_telecom Result) rapportent 0-1 ; la gate en déduit l'échelle de chaque tâche (0-1 si les deux scores sont dans [0, 1], sinon 0-100) et normalise la baisse en conséquence, donc --threshold 0.01 signifie "≤1 pt sur une tâche 0-100 / ≤0.01 sur une tâche 0-1" uniformément. Passer --scales '{"task": max}' pour surcharger la déduction si les scores d'une tâche tombent dans une plage ambiguë.

Décision de gate_compare.py :

  • ACCEPT — toutes les tâches dans le seuil → aller à l'Étape 6.
  • REGRESSION — une ou plusieurs tâches dépassent le seuil. v1 s'arrête ici et rapporte quelles tâches ont régressé et de combien. (Choisir la prochaine recipe et réexécuter est déféré — voir Scope.)
  • ANOMALOUS — scores présents mais implausibles (ex. baseline inférieure au candidat d'une marge importante, ou un score de tâche en dehors de sa plage valide) → le surfacer à l'utilisateur.

Étape 6 — Closeout

Rapporter la décision avec : taille source vs output + ratio, baseline / candidat / delta / dans-seuil par tâche, IDs de run MLflow, et une recommandation de publication (publish / do-not-publish / needs-human). Archiver les artefacts vers le workspace.

Triage (gate échouée → décision)

Mapper la failure_class d'une gate à l'action suivante :

failure_class Action
INFRA_TRANSIENT Réessayer l'étape une fois ; si elle récidive, SYSTEMIC.
MODEL_UNSUPPORTED PATCH : corriger le pattern de recipe / ajouter le support du modèle (la skill ptq possède la boucle de patch), puis réessayer. Si non patchable, POINT_INFEASIBLE.
QUANT_COVERAGE_FAILURE PATCH : corriger le wildcard de la recipe pour que les couches visées soient couvertes ; re-exécuter le PTQ.
DEPLOYMENT_HEALTH_FAILED Descendre à la skill deployment : reproduire le serving standalone (/health + une génération), déboguer les flags / image / TP / env, puis porter la commande fonctionnelle dans deployment.command de NEL et réessayer l'eval. Si ça ne peut pas servir, POINT_INFEASIBLE.
EVAL_JUDGE_FAILED Généralement transient (auth / rate limit) — attendre et réessayer.
SAMPLE_ACCOUNTING_FAILED Investiguer les échantillons perdus/échoués avant de faire confiance aux scores.
USER_CONFIG_ERROR Arrêter et demander à l'utilisateur.
UNKNOWN Arrêter et le surfacer à l'utilisateur (NEEDS_HUMAN).

SYSTEMIC (cluster down, dataset indisponible) avorte le run entier. POINT_INFEASIBLE signifie que ce (modèle, recipe) ne peut pas fonctionner tel que configuré.

Sortie

Retourner une décision, pas un artefact brut :

  • ACCEPT + rapport + recommandation de publication
  • REGRESSION + quelles tâches ont échoué le seuil et de combien
  • ANOMALOUS / INFEASIBLE / NEEDS_HUMAN + raison
  • Toujours : chemin du workspace + IDs de run MLflow pour la traçabilité

Scope (v1)

En v1 : la chaîne linéaire + gates + rapport. Sur REGRESSION, v1 rapporte et arrête. Déféré à un suivi : la boucle recipe evaluator-optimizer (compare → choisir la prochaine recipe → re-exécuter PTQ), qui nécessite l'intégration bigpareto et un schéma config/result partagé.

Skills similaires