TAO Generate Anomalies
Installation autonome ? Si cette session n'a pas été initialisée par le plugin de skill bank TAO, exécutez d'abord le skill
tao-setup(vérification de préflight de l'hôte, identifiants, découverte inter-skills).
Pipeline multi-phase (0–7) ; le flag mode sélectionne les phases qui s'exécutent.
| Phase | Ce qui s'exécute | Mode(s) |
|---|---|---|
| 0 | Vérifier / télécharger les checkpoints pré-entraînés | all |
| 1 | Fine-tune sur dataset_dir |
full, finetune_only |
| 2 | Préparer l'inférence JSONL (routage AMP) | full, inference_only |
| 3 | SDG — générer des images d'anomalies synthétiques → original/ |
full, inference_only |
| 4 | Eval original/ — émettre per_sample.csv + eval.log, fusionner nn_score dans SDG_result.csv |
full, inference_only |
| 5 | Rounds de recherche (guidance, crop_ratio) par échantillon → rounds/round_NN/ (chaque round exécute SDG + eval) |
full, inference_only |
| 6 | Assembler le meilleur des rounds dans searched/ (stitching uniquement), plus rounds/search_summary.csv |
full, inference_only |
| 7 | Filtrer searched/ par nn_threshold (par défaut 0.4), régénérer les échantillons supprimés, puis eval canonique du bucket → searched/{per_sample.csv, eval.log} |
full, inference_only |
Exécutez chaque phase jusqu'à son terme sans pauses en cours d'exécution. Collectez tous les paramètres requis à l'avance et exécutez chaque commande depuis la racine du dépôt.
Configuration shell. Toutes les références ${ANOMALYGEN_SCRIPTS} pointent vers le répertoire des scripts helper fournis. Dans le conteneur, c'est prédéfini (ENV ANOMALYGEN_SCRIPTS=<dir>/scripts/utilities) ; sur l'hôte, exportez-le une fois par shell :
export ANOMALYGEN_SCRIPTS="$(git rev-parse --show-toplevel)/scripts/utilities"
Les invocations python3 -m scripts.utilities.<name> fonctionnent depuis n'importe quel répertoire dans le conteneur (PYTHONPATH est prédéfini) et depuis la racine du dépôt sur l'hôte. Quand vous êtes dans un conteneur produit (ANOMALYGEN_PRODUCT_MODE=1), invoquez anomalygen-guard avant tout travail GPU ; s'il signale BLOCKED, corrigez les problèmes listés avant de continuer.
Démarrage rapide
Le pipeline s'exécute dans le conteneur metropolis_sdg.paidf_anomalygen (déclaré dans versions.yaml) ou sur tout hôte avec l'environnement conda cosmos-predict2 actif. Toutes les commandes de phase supposent cet environnement, à la racine du dépôt, avec ANOMALYGEN_SCRIPTS exporté.
Exécution minimale end-to-end (mode=full) :
# 1. Définissez les variables partagées (voir « Variables partagées » pour l'ensemble complet).
export ANOMALYGEN_SCRIPTS="$(git rev-parse --show-toplevel)/scripts/utilities"
MODE=full
NAME=my_exp
DATASET_DIR=/data/uc1
DEFECT_DESC=assets/defect_spec_template.jsonl
NUM_SDG=20
MODEL_SIZE=2b
# 2. Phase 0 — vérifier / télécharger les checkpoints (~40 GB pour le défaut 2B ; nécessite HF_TOKEN).
${ANOMALYGEN_SCRIPTS}/check.sh --model-sizes ${MODEL_SIZE^^} \
|| ${ANOMALYGEN_SCRIPTS}/download_checkpoints.sh --model-sizes ${MODEL_SIZE^^}
# 3. Parcourez les phases 1→7 dans l'ordre (voir chaque section Phase).
Pour mode=inference_only (réutiliser un checkpoint), définissez aussi CKPT/STEP et ignorez la Phase 1. Pour mode=finetune_only, exécutez uniquement les phases 0–1.
Exécution dans Docker — lancement de conteneur, montages et permissions
L'image paidf-anomalygen s'exécute en tant qu'utilisateur non-root intégré (USER anomalygen, uid=10000), indépendamment de votre uid d'hôte. Docker ne rémappe pas les uids sur les montages bind, donc un répertoire d'hôte appartenant à votre uid n'est pas inscriptible par uid 10000 et le conteneur échoue dès qu'il essaie de créer un fichier. Exécutez avec l'identité d'hôte complète : --user "$(id -u):$(id -g)", correspondant à USER/LOGNAME, HOME=/tmp, et montages read-only /etc/passwd+/etc/group, plus les redirections de cache. Exécutez le preflight d'écriture fail-fast avant la Phase 0. Voir references/docker.md pour la commande docker run complète, le tableau des flags indispensables, l'extrait preflight et le fallback chown/chmod uid-10000.
Fichiers de référence — à lire avant d'exécuter les phases
Lisez references/finetune.md avant les phases 0/1 et references/inference.md avant les phases 2–7 ; pour mode=full, lisez les deux avant de commencer. Les références restantes ci-dessous sont à la demande — à lire lors du dépannage ou si vous avez besoin de tous les détails pour une phase spécifique.
| Fichier | À lire quand |
|---|---|
references/finetune.md |
Avant les phases 0/1 : vérification env, téléchargement checkpoint, validation dataset, génération config, commandes training, sélection meilleur-checkpoint |
references/finetune-commands.md |
Commandes exactes des étapes 1–4 de la Phase 1 et dérivation de CKPT/STEP |
references/inference-commands.md |
Commandes exactes run_round.sh Phase 5 et filter_with_regen Phase 7 |
references/inference.md |
Avant les phases 2–7 : routage AMP, validation JSONL, flags SDG, interprétation eval, boucle de recherche, filtrage |
references/setup.md |
Échec du téléchargement de checkpoint ; setup initial ; problèmes HF_TOKEN / disque |
references/datasets.md |
L'utilisateur doit préparer ou obtenir un dataset UC1 / UC2 / UC3 ; dataset_dir n'existe pas encore |
references/prep-testcase.md |
AMP échoue ; besoin du tableau complet des param, descriptions des scripts helper, invariant d'allocation |
references/sdg-inference.md |
Blocage NCCL ; erreur de validation de checkpoint ; question VRAM multi-GPU ; liste d'étapes complète |
references/eval.md |
Scores inattendus ; confusion d'ordre des colonnes FID ; référence de format de sortie eval |
references/sdg-refine.md |
Alignement draws.json ; heuristiques re-AMP ; layout de sortie de recherche |
references/guard-and-custom-counts.md |
Commande preflight guard complète ; exemple --per-defect-counts |
references/docker.md |
Commande de lancement du conteneur, flags de permission-montage, preflight d'écriture, fallback uid-10000 |
references/output-layout.md |
Arborescence complète du répertoire results/<name>/ avec annotations par fichier ; checklist de vérification post-run |
references/error-handling.md |
Modes de défaillance au niveau du pipeline : répertoires mask manquants, AMP court/vide, reprise mid-round, step hors-limite |
Paramètres requis
L'allocation de num_SDG dépend de prep_testcase.sh --mode : inference (par défaut, Phase 2) est uniforme sur les types de défaut, override par-défaut via --per-defect-counts ; validation (JSONL de validation de la Phase 1) est proportionnelle aux nombres de masques d'entraînement (arrondi plus grand reste) et applique ≥1 par défaut. Voir references/prep-testcase.md pour le tableau complet des modes.
| Paramètre | Description |
|---|---|
mode |
full (Phase 0→7), inference_only (ignorer Phase 1), ou finetune_only (Phase 0→1 uniquement). |
name |
Label d'expérience. |
dataset_dir |
Racine du dataset de training/référence. Pilote l'allocation des nombres de masques, les templates de submask AMP, et contient semantic_segmentation_labels.json pour les défauts cad. |
defect_spec |
JSONL taguant chaque spatial_dependency de défaut comme free/text/cad. Les entrées text ont besoin de roi_prompt_defect_location. Template : assets/defect_spec_template.jsonl. |
num_SDG |
Nombre total d'échantillons de sortie par bucket. (Ignoré quand mode=finetune_only.) |
Conditionnellement requis
| Paramètre | Requis quand | Description |
|---|---|---|
checkpoint_dir / step |
mode=inference_only |
Modèle fine-tuné pré-existant. En mode=full, ces paramètres sont auto-dérivés après la Phase 1 ; les passer est une erreur. En mode=finetune_only, silencieusement ignorés — Phase 1 s'entraîne toujours from scratch (pas de support resume-from-checkpoint). Les deux doivent être présents ensemble — fournir un seul est une erreur. |
Paramètres optionnels
| Paramètre | Défaut | Description |
|---|---|---|
clean_dir |
dataset_dir |
Images propres. Définissez uniquement si elles vivent en dehors du dataset de training. Transmis en --clean-dir à prep-testcase et --clean-image-path à finetune. |
validation_jsonl |
auto-généré | JSONL de validation pré-construit pour la Phase 1. Quand fourni, le preflight vérifie que chaque type de defect_spec apparaît et que les chemins existent. |
num_search_run |
3 |
Budget de recherche par-échantillon pour la Phase 5. 0 ignore la recherche (uniquement original/). (Ignoré quand mode=finetune_only.) |
nn_threshold |
0.4 |
Cutoff nn_score pour la Phase 7 (correspondance de contenu DINOv2 aux défauts réels — KPI clé). Les échantillons en dessous sont régénérés ; le final searched/ a toujours num_SDG. 0 désactive le filtrage. |
max_iter |
75000 |
Phase 1 uniquement. Total d'itérations fine-tune. |
save_iter |
5000 |
Phase 1 uniquement. Intervalle de sauvegarde de checkpoint. |
validation_iter |
5000 |
Phase 1 uniquement. Intervalle de logging de validation (nn_score). |
num_gpus |
1 |
Transmis à la Phase 1 (finetune) et Phase 3 (SDG). Eval et rounds de recherche restent single-GPU. |
model_size |
2b |
2b ou 14b. Utilisé par finetune et SDG. Le chemin de checkpoint sur disque encode en majuscules (2b→2B, 14b→14B). |
lr |
0.02 |
Phase 1 uniquement. Learning rate. |
batch_size |
2 |
Phase 1 uniquement. Taille de batch par-GPU. |
image_size |
512 |
Phase 1 uniquement. Résolution de training (carré). |
guidance_range |
1.5 10.0 |
Plage de draw de recherche Phase 5 pour guidance. |
crop_ratio_range |
1.5 10.0 |
Plage de draw de recherche Phase 5 pour crop_ratio. |
Validation du mode (fail fast avant toute phase)
modenon défini → halte : "modeest requis (full|inference_only|finetune_only)."mode=inference_onlymanquantcheckpoint_diroustep→ halte : "inference_only nécessite les deuxcheckpoint_diretstep."mode=fullaveccheckpoint_diroustepfourni → halte : "full mode exécute finetune ; utilisezmode=inference_onlypour réutiliser un checkpoint existant."
Variables partagées
Définissez une fois avant la Phase 0 :
MODE=<full|inference_only|finetune_only>
NAME=<exp>
DATASET_DIR=<dataset_dir>
CLEAN_DIR=${clean_dir:-${DATASET_DIR}}
CKPT=<checkpoint_dir> # requis ssi MODE=inference_only ; auto-dérivé après Phase 1 quand MODE=full
STEP=<iter> # requis ssi MODE=inference_only ; auto-dérivé après Phase 1 quand MODE=full
NUM_SDG=<N>
DEFECT_DESC=<defect_spec.jsonl>
DEFECTS=(T+A T+B) # noms TEXTURE+TYPE. Pour mode=inference_only, dérivez de ${CKPT}/ag_config.yaml → dataloader_train.dataset.anomaly_types (aussi imprimé par validate_checkpoint.py en Phase 0). Pour mode=full, prenez les entrées DEFECT_DESC. Voir references/inference.md §Phase 0.
NUM_SEARCH_RUN=${num_search_run:-3}
NN_THRESHOLD=${nn_threshold:-0.4}
MODEL_SIZE=<2b|14b>
NUM_GPUS=${num_gpus:-1}
MAX_ITER=${max_iter:-75000}
SAVE_ITER=${save_iter:-5000}
VALIDATION_ITER=${validation_iter:-5000}
LR=${lr:-0.02}
BATCH_SIZE=${batch_size:-2}
IMAGE_SIZE=${image_size:-512}
VALIDATION_JSONL=${validation_jsonl:-} # optionnel ; défini par Phase 1 Step 2 si non fourni par utilisateur
BASE=results/${NAME}
JSONL=ag_inference/${NAME}/testcase.jsonl
ORIGINAL=${BASE}/original
SEARCHED=${BASE}/searched
ROUNDS=${BASE}/rounds
REGENS=${BASE}/regens
Preflight guard (mode produit uniquement)
Quand ANOMALYGEN_PRODUCT_MODE=1, exécutez .agents/skills/anomalygen-guard/scripts/preflight.py avant tout travail GPU et corrigez les problèmes BLOCKED. --validation-jsonl est transmis uniquement quand l'utilisateur en a fourni un ; pour MODE=finetune_only, omettez --num-sdg si non fourni. Voir references/guard-and-custom-counts.md pour la commande preflight complète avec tous les flags transmis et les vérifications JSONL de validation / allocate_samples.py à 0 entrée.
Phase 0 — checkpoints
Lisez references/finetune.md §Phase 0 pour les exigences HF_TOKEN et ce qui est téléchargé. Les deux scripts ciblent par défaut la base 2B + t5-large (~40 GB) ; passez --model-sizes ${MODEL_SIZE^^} pour que la chaîne vérifie et récupère la taille de base que cette exécution utilise réellement (2b→2B, 14b→14B) — autrement une exécution 14b passe silencieusement la vérification 2B-only et ne télécharge jamais son checkpoint. Vérifiez d'abord ; téléchargez uniquement ce qui manque.
${ANOMALYGEN_SCRIPTS}/check.sh --model-sizes ${MODEL_SIZE^^} \
|| ${ANOMALYGEN_SCRIPTS}/download_checkpoints.sh --model-sizes ${MODEL_SIZE^^}
Phase 1 — fine-tune (ignorer quand MODE=inference_only)
Lisez references/finetune.md §Phase 1 pour la structure du dataset, les détails du template config et la sélection du meilleur checkpoint. Quatre étapes : (1) valider le dataset / dériver les types d'anomalie, (2) générer le JSONL de validation (ignorer si l'utilisateur a fourni VALIDATION_JSONL), (3) générer la config d'entraînement — montrer-la à l'utilisateur et confirmer avant d'écrire — (4) lancer l'entraînement en arrière-plan. Puis dérivez CKPT (le chemin encode MODEL_SIZE en majuscules) et STEP (step nn_score le plus élevé des logs de validation). Si MODE=finetune_only, arrêtez après l'entraînement. Voir references/finetune-commands.md pour les commandes exactes des étapes 1–4 et l'extrait de dérivation de CKPT/STEP.
Phase 2 — prep-testcase (ignorer quand MODE=finetune_only)
Lisez references/inference.md §Phase 2 pour le détail du routage AMP et le dimensionnement n_seeds. Ne passez PAS --seeds — il est auto-calculé et n'est pas un flag reconnu. prep_testcase.sh cible par défaut --mode inference (allocation uniforme sur les types de défaut, pas de plancher KPI), que la Phase 2 utilise toujours.
${ANOMALYGEN_SCRIPTS}/prep_testcase.sh \
--name ${NAME} --num-sdg ${NUM_SDG} \
--dataset-dir ${DATASET_DIR} \
--clean-dir ${CLEAN_DIR} \
--defect-spec ${DEFECT_DESC} \
--amp-output-dir ag_inference/${NAME}/amp \
--output-jsonl ${JSONL}
Nombres par-défaut custom : quand l'utilisateur spécifie les nombres par type de défaut, traduisez en --num-sdg plus un dict JSON --per-defect-counts (les types absents du dict obtiennent 0 ; la somme doit égaler --num-sdg, sinon le script avertit sur stderr et utilise la somme override). Confirmez l'allocation quand l'intention est ambiguë. Voir references/guard-and-custom-counts.md pour l'exemple de commande --per-defect-counts complet et le détail de gestion d'ambiguïté.
Phase 3 — SDG → original/
Lisez references/inference.md §Phase 3 pour la validation JSONL contre le checkpoint, les précautions multi-GPU et la vérification de sortie.
python3 -m scripts.utilities.validate_checkpoint ${CKPT} --step ${STEP}
python3 -m scripts.utilities.validate_jsonl ${CKPT} ${JSONL}
${ANOMALYGEN_SCRIPTS}/run_sdg.sh \
--checkpoint_dir ${CKPT} --step ${STEP} \
--input_jsonl ${JSONL} --output_dir ${ORIGINAL} \
--model_size ${MODEL_SIZE} --num_gpus ${NUM_GPUS}
${ANOMALYGEN_SCRIPTS}/verify_output.sh ${JSONL} ${ORIGINAL}
Phase 4 — eval original/
Lisez references/inference.md §Eval pour l'interprétation des scores et l'explication du comptage de features. run_eval.sh écrit per_sample.csv et eval.log à l'intérieur de original/ et fusionne nn_score dans SDG_result.csv.
${ANOMALYGEN_SCRIPTS}/run_eval.sh \
--real-path ${DATASET_DIR} --generated-path ${ORIGINAL} \
--anomaly-types ${DEFECTS[@]}
Phase 5 — rounds de recherche par-échantillon
Lisez references/inference.md §Phase 5 pour la stratégie de draw, les plages et les guidance re-AMP. Pour r dans 1..NUM_SEARCH_RUN :
- Lisez le
per_sample.csvdu round précédent (ou${ORIGINAL}/per_sample.csvpourr=1). - Écrivez
${ROUNDS}/round_${r}/draws.jsonavec(guidance, crop_ratio)sélectionné par échantillon. - Exécutez le round via
${ANOMALYGEN_SCRIPTS}/run_round.sh(SDG + eval ; le répertoire du round obtient son propresdg/{SDG_result.csv, per_sample.csv, eval.log}). Voirreferences/inference-commands.md §Phase 5pour la commande complète et les flags.
NUM_SEARCH_RUN=0 est valide — ignorez entièrement cette phase et laissez la Phase 6 cloner original/ dans searched/.
Phase 6 — assembler searched/ (stitching uniquement)
Exécutez toujours l'assemblage (fonctionne avec 0 round — searched/ clone original/, donc en aval lit toujours searched/ indépendamment de num_search_run). Stitching uniquement : copie les images gagnantes par indice d'échantillon dans searched/ et porte le nn_score / mnn_score par-échantillon de chaque pick depuis le per_sample.csv de son round-source. Pas d'eval — la Phase 7 émet le eval.log canonique.
mkdir -p ${ROUNDS}
python3 -m scripts.utilities.assemble_searched \
--original-dir ${ORIGINAL} --original-csv ${ORIGINAL}/per_sample.csv \
--rounds-dir ${ROUNDS} --searched-dir ${SEARCHED}
Phase 7 — filtrer + régénérer + eval (par défaut nn_threshold=0.4)
la Phase 7 s'exécute par défaut (nn_threshold=0.4) sur chaque invocation mode=full et mode=inference_only ; passez nn_threshold=0 pour l'ignorer. Elle filtre searched/ par nn_threshold, régénère les échantillons supprimés via re-AMP (nouvel appairage (clean, submask) dans le même type de défaut) pour jusqu'à 5 tentatives, puis bascule aux meilleurs-scoring regens non-passants et finalement aux originals supprimés, pour que le bucket final égale toujours num_SDG.
Exécutez python3 -m scripts.utilities.filter_with_regen. Passez --allocation ag_inference/${NAME}/allocation.json pour que la régénération cible les nombres par-défaut intentionnels — sans cela, un bucket laissé court (p.ex. par un SDG interrompu) ne peut pas être complété jusqu'à num_SDG. Il exécute le final run_eval.sh en interne — le seul eval contre searched/. Lisez references/inference.md §Phase 7 pour la mécanique de regen, le traçage des colonnes-source et le schéma de regens/regen_summary.csv ; voir references/inference-commands.md §Phase 7 pour la commande complète et les flags.
Layout de sortie
Chaque bucket qui obtient une eval porte la même triade de fichiers : SDG_result.csv (params de génération + nn_score + guardrail_pass), per_sample.csv (nn + mnn par-échantillon) et eval.log (FID agrégé / moyenne par-défaut). Les buckets vivent sous results/<name>/ en tant que original/ (Phase 3+4), searched/ (Phase 6 stitch + Phase 7 filter+regen+eval), rounds/round_NN/ (Phase 5, plus search_summary.csv), et regens/regen_NN/ (Phase 7, plus regen_summary.csv).
Guardrail de contenu d'image. Une vérification de sécurité de contenu SigLIP s'exécute sur chaque image générée et enregistre son verdict dans SDG_result.csv.guardrail_pass (1 safe / 0 bloqué). Une image bloquée est remplacée par une image entièrement noire qui occupe toujours son slot sur disque, pour que compter les fichiers ne puisse pas la détecter — ne passez jamais un échantillon guardrail_pass=0 en aval. Les échantillons noircis score près de zéro nn_score, donc la Phase 7 les régénère comme tout autre échantillon sous-threshold. Désactiver avec ANOMALYGEN_IMAGE_GUARDRAIL=0.
Voir references/output-layout.md pour l'arborescence complète du répertoire avec annotations par-fichier, la sémantique du guardrail et la Vérification post-run checklist (nombres d'images par bucket, vérifications de lignes search_summary.csv / regen_summary.csv, les champs nn_score / mnn_score / fid par-type dans chaque eval.log, et le balayage guardrail_pass).
Gestion d'erreur
Les modes de défaillance communs du pipeline (répertoires mask manquants, sortie AMP court/vide et l'halte 0 entries written, reprise SDG mid-round, step hors-limite, sortie non-zéro de validate_dataset.py sur tout problème d'appairage, le défaut 2B-only de check.sh et les images noires bloquées par guardrail) sont couverts dans references/error-handling.md ; voir aussi references/finetune.md et references/inference.md pour la gestion d'erreur spécifique à la phase.