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 remplacetests/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 HEADet rapporte la KL par métrique.
Entrées à recueillir auprès de l'utilisateur
-
ID d'exécution GitHub Actions workflow (p. ex.
25341543542). C'est l'ID numérique dans l'URL de l'exécution. -
Source : doit être
githubpour ce workflow. (gitlabest supporté par le script de téléchargement mais utilise un chemin env différent.) -
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-zerosavecsym_KL≲ 1e-6 sont du bruit d'exécution à exécution. - Les divergences
iteration-timesont généralement du bruit de warmup/scheduler, pas une correction. - Attirer l'attention du relecteur sur les lignes
lm lossetnum-zerosavecsym_KL≥ ~1e-3, et vérifiermean rel|d|pour une magnitude intuitive.
Notes & pièges
_fetch_and_filter_artifactsdu script de téléchargement n'honore--only-failingque sur le chemin GitHub. Le chemin Gitlab l'applique par job dansdownload_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 deiteration-time; le script KL les filtre, donc les divergences pour cette métrique viennent quand même. Ne pas signaleriteration-timecomme 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 degh 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.