update-golden-values

Par nvidia · skills

Rafraîchit les valeurs golden à partir d'une exécution de workflow GitHub Actions (uniquement les jobs en échec ou tous les jobs), évalue le changement avec la divergence KL, et produit un résumé prêt pour une PR. À utiliser quand l'utilisateur demande à mettre à jour les goldens pour une exécution CI, à rafraîchir les valeurs golden à partir d'un ID de workflow, ou à générer un résumé de diff de valeurs golden pour une description de PR.

npx skills add https://github.com/nvidia/skills --skill update-golden-values

Mise à jour des valeurs golden + résumé KL

Workflow end-to-end pour actualiser les valeurs golden à partir d'une exécution GitHub Actions, valider la mise à jour avec la divergence KL et rédiger un résumé prêt pour PR.

La skill orchestre deux scripts qui résident déjà dans le repo :

  • tests/test_utils/python_scripts/download_golden_values.py — récupère les artefacts d'une exécution et remplace tests/functional_tests/test_cases/**/golden_values_*.json.
  • tests/test_utils/python_scripts/compare_golden_values_kl.py — compare les goldens de l'arborescence de travail par rapport à git HEAD et rapporte la KL par métrique.

Entrées à recueillir auprès de l'utilisateur

  1. ID d'exécution GitHub Actions workflow (p. ex. 25341543542). C'est l'ID numérique dans l'URL de l'exécution.

  2. Source : doit être github pour ce workflow. (gitlab est supporté par le script de téléchargement mais utilise un chemin env différent.)

  3. Scope — accepter l'une des options suivantes :

    • only-failing → exécuter avec --only-failing (télécharger depuis les jobs qui ont échoué/ont été annulés uniquement). À utiliser pour les workflows « corriger les tests cassés ».
    • all → exécuter sans --only-failing (télécharger depuis chaque job qui a produit des valeurs golden). À utiliser quand l'utilisateur veut un rafraîchissement complet.

    Si l'utilisateur ne spécifie pas, demander. Ne pas définir silencieusement une valeur par défaut.

Workflow

- [ ] Étape 1 : Configurer l'environnement (token + venv avec deps)
- [ ] Étape 2 : Réinitialiser les modifications antérieures des valeurs golden
- [ ] Étape 3 : Télécharger les goldens (scope = only-failing | all)
- [ ] Étape 4 : Exécuter la comparaison KL + capturer le CSV
- [ ] Étape 5 : Produire le texte du résumé

Étape 1 — Environnement

Le script de téléchargement a besoin de GITHUB_TOKEN. Si l'utilisateur a la CLI gh authentifiée, la dériver ; NE PAS exporter le token dans un shell de longue durée ou le commiter.

# token (usage unique, limité à la commande)
export GITHUB_TOKEN="$(gh auth token)"

# dépendances python (le script importe click, gitlab, requests)
python3 -m venv /tmp/gv_venv
/tmp/gv_venv/bin/pip install --quiet click python-gitlab requests

Réutiliser /tmp/gv_venv s'il existe déjà. Le script KL ne dépend que de click (aussi dans le venv).

Étape 2 — Réinitialiser les modifications antérieures (seulement si l'utilisateur réexécute)

Si l'arborescence de travail a déjà des modifications antérieures des valeurs golden que vous voulez abandonner avant de retélécharger :

git checkout -- tests/functional_tests/test_cases/
git ls-files --others --exclude-standard tests/functional_tests/test_cases/ \
  | while IFS= read -r f; do rm -f "$f"; done

Ignorer cette étape quand l'utilisateur veut explicitement superposer un nouveau téléchargement sur une branche en cours.

Étape 3 — Télécharger

Construire la commande à partir du scope fourni par l'utilisateur :

# scope = only-failing (par défaut pour « corriger les tests cassés »)
/tmp/gv_venv/bin/python tests/test_utils/python_scripts/download_golden_values.py \
  --source github --pipeline-id <WORKFLOW_RUN_ID> --only-failing

# scope = all (rafraîchissement complet ; omettre le drapeau)
/tmp/gv_venv/bin/python tests/test_utils/python_scripts/download_golden_values.py \
  --source github --pipeline-id <WORKFLOW_RUN_ID>

Quand --only-failing est défini, le chemin GitHub filtre dans _fetch_and_filter_artifacts sur matched_job["conclusion"] == "success", donc seuls les jobs qui ont échoué/ont été annulés contribuent des artefacts. Sans le drapeau, tous les artefacts de valeurs golden de chaque job sont récupérés.

Capturer les deux dernières lignes de log pour le résumé ; elles ressemblent à :

INFO:__main__:Total tests with golden values: <N>
INFO:__main__:Total golden values found: <M>

Étape 4 — Comparaison KL

/tmp/gv_venv/bin/python tests/test_utils/python_scripts/compare_golden_values_kl.py \
  --top 20 --csv /tmp/kl_summary.csv

Le CSV contient une ligne par (file, metric) avec colonnes : file, metric, n_steps, KL(old||new), KL(new||old), sym_KL, max|d|, mean|d|, mean rel|d|.

Ensuite, dériver les agrégats du CSV (faire cela en Python ; ne pas coller le CSV brut dans le résumé) :

import csv, collections
rows = list(csv.DictReader(open('/tmp/kl_summary.csv')))
for r in rows:
    for k in ('KL(old||new)','KL(new||old)','sym_KL','max|d|','mean|d|','mean rel|d|'):
        r[k] = float(r[k])

by_metric = collections.defaultdict(list)
for r in rows:
    by_metric[r['metric']].append(r['sym_KL'])

# numéros de titre par métrique
for m, syms in sorted(by_metric.items()):
    syms.sort()
    print(m, len(syms), 'median', syms[len(syms)//2], 'max', syms[-1])

# décomptes de buckets sur toutes les lignes
buckets = [('==0',lambda x:x==0), ('(0,1e-9)',lambda x:0<x<1e-9),
           ('[1e-9,1e-6)',lambda x:1e-9<=x<1e-6), ('[1e-6,1e-3)',lambda x:1e-6<=x<1e-3),
           ('[1e-3,1e-2)',lambda x:1e-3<=x<1e-2), ('[1e-2,1e-1)',lambda x:1e-2<=x<1e-1),
           ('>=1e-1',lambda x:x>=1e-1)]
syms_all = [r['sym_KL'] for r in rows]
for label, pred in buckets:
    print(label, sum(1 for s in syms_all if pred(s)))

Étape 5 — Texte du résumé

Utiliser ce modèle verbatim, remplir <…> depuis les étapes 3–4. Supprimer les sections qui ne s'appliquent pas à l'exécution.

Choisir le libellé de la première ligne selon le scope utilisé :

  • only-failing → « Rafraîchissement des valeurs golden pour les tests fonctionnels qui ont échoué à partir de l'exécution GitHub workflow … »
  • all → « Rafraîchissement complet des valeurs golden à partir de l'exécution GitHub workflow … »

Correspondre la commande download_golden_values.py dans la liste à puces au scope utilisé (avec ou sans --only-failing).

### Summary

<phrase adaptée au scope> à partir de l'exécution GitHub workflow `<WORKFLOW_RUN_ID>`.

**Mises à jour des valeurs golden**

- Réexécuté `tests/test_utils/python_scripts/download_golden_values.py --source github --pipeline-id <WORKFLOW_RUN_ID> <--only-failing si scope=only-failing>`.
- Mis à jour **<N> fichiers de valeurs golden** sous `tests/functional_tests/test_cases/`.

### Résumé de la divergence KL

La comparaison couvre <FILES_WITH_BASELINE> fichiers × <NUM_METRICS> métriques = **<TOTAL_ROWS> paires `(file, metric)`**.

**Numéros de titre par métrique**

| métrique                  |   n | median sym_KL | max sym_KL |
| ------------------------- | --: | ------------: | ---------: |
| `lm loss`                 | <…> |         <…>   |       <…>  |
| `num-zeros`               | <…> |         <…>   |       <…>  |
| `iteration-time`          | <…> |         <…>   |       <…>  |
| `mem-allocated-bytes`     | <…> |         <…>   |       <…>  |
| `mem-max-allocated-bytes` | <…> |         <…>   |       <…>  |

**Distribution de la KL symétrique sur l'ensemble des <TOTAL_ROWS> lignes**

| bucket sym_KL  | compte |
| -------------- | ----: |
| `== 0`         |  <…>  |
| `(0, 1e-9)`    |  <…>  |
| `[1e-9, 1e-6)` |  <…>  |
| `[1e-6, 1e-3)` |  <…>  |
| `[1e-3, 1e-2)` |  <…>  |
| `[1e-2, 1e-1)` |  <…>  |
| `>= 1e-1`      |  <…>  |

**Interprétation** (appliquer seulement les points qui correspondent aux données)

- `lm loss` max sym_KL <X> / median <Y> — les trajectoires de perte correspondent aux goldens anciens au bruit numérique près.
- Les métriques `mem-*` sont plates en KL même quand `max|d|` en octets bruts est grand (décalage constant).
- Les divergences `iteration-time` sont du bruit de warmup/scheduler, pas un signal de correction.
- Les décalages `num-zeros` cluster sur `<liste des motifs de test>`; à l'intérieur de la variance historique d'exécution à exécution.

Lecture des colonnes KL

colonne sens
n_steps indices d'étape partagés après suppression des NaN/inf
KL(old\|\|new) / KL(new\|\|old) divergence KL en nats, les deux directions (asymétrique)
sym_KL KL(old\|\|new) + KL(new\|\|old) ; colonne de classement primaire
max\|d\|, mean\|d\| diffs absolus étape par étape en unités de métrique brutes
mean rel\|d\| moyenne de \|old − new\| / max(\|old\|, ε) ; sans échelle

Règles pratiques de triage :

  • Les lignes lm loss / num-zeros avec sym_KL ≲ 1e-6 sont du bruit d'exécution à exécution.
  • Les divergences iteration-time sont généralement du bruit de warmup/scheduler, pas une correction.
  • Attirer l'attention du relecteur sur les lignes lm loss et num-zeros avec sym_KL ≥ ~1e-3, et vérifier mean rel|d| pour une magnitude intuitive.

Notes & pièges

  • _fetch_and_filter_artifacts du script de téléchargement n'honore --only-failing que sur le chemin GitHub. Le chemin Gitlab l'applique par job dans download_from_gitlab.
  • Un fichier golden tout neuf (pas de baseline git HEAD) est silencieusement ignoré par le script KL avec un avertissement. Soustraire ces derniers du décompte de fichiers quand on rapporte « fichiers avec baseline ».
  • Certains artefacts ont une chaîne littérale "nan" à l'étape 1 de iteration-time ; le script KL les filtre, donc les divergences pour cette métrique viennent quand même. Ne pas signaler iteration-time comme un problème de correction sauf si quelque chose d'autre a aussi changé.
  • Ne jamais commiter GITHUB_TOKEN, RO_API_TOKEN, ou toute valeur dérivée de gh auth token. Si l'utilisateur veut que vous committiez, ne mettre en scène que les fichiers de valeurs golden et le CSV optionnel — pas l'env ou le venv.

Skills similaires