Recette : Mettre en place un pipeline d’adversarial testing avec Workflow v6
Découvrez comment construire, automatiser et monitorer un pipeline d’évaluation de robustesse adversariale pour vos modèles IA à l’aide de Workflow v6, de la génération d’attaques à la production de rapports détaillés.
Contexte et objectifs
Les modèles d’apprentissage profond sont de plus en plus déployés en production, mais leur vulnérabilité aux perturbations adversariales (ex. images légèrement modifiées, texte reformulé) reste un risque majeur. Un pipeline d’adversarial testing permet de détecter ces faiblesses de façon systématique, d‑enrichir les jeux de données d’entraînement et d‑informer les équipes produit. Workflow v6 offre les primitives nécessaires : orchestration de tâches, gestion des artefacts, et intégration native aux systèmes CI/CD.
L’objectif de cette recette :
- Générer automatiquement des exemples adversariaux à partir d’un modèle entraîné.
- Évaluer la perte de performance (accuracy, F1, etc.) sur ces exemples.
- Produire un rapport exploitable (HTML/JSON) et le publier comme artefact de build.
- Enclencher une étape de « re‑training » conditionnelle si la dégradation dépasse un seuil défini.
Définir le pipeline d’adversarial testing dans Workflow v6
1. Déclaration du workflow
name: adversarial-testing
on:
push:
branches: [main]
schedule:
- cron: "0 2 * * MON" # chaque lundi à 02:00
jobs:
generate_attacks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install torch torchvision foolbox==3.3.0
- name: Pull trained model
uses: workflow-v6/artifact@v1
with:
name: model.pt
path: artifacts/model.pt
- name: Generate adversarial samples
id: attacks
run: |
python scripts/generate_attacks.py \
--model artifacts/model.pt \
--output attacks.npy
- name: Upload attacks
uses: workflow-v6/artifact@v1
with:
name: attacks
path: attacks.npy
evaluate:
needs: generate_attacks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install evaluation deps
run: |
pip install torch torchvision foolbox==3.3.0 pandas
- name: Download artifacts
uses: workflow-v6/artifact@v1
with:
name: model.pt
path: model.pt
- name: Download attacks
uses: workflow-v6/artifact@v1
with:
name: attacks
path: attacks.npy
- name: Run evaluation
id: eval
run: |
python scripts/evaluate_attacks.py \
--model model.pt \
--attacks attacks.npy \
--report report.json
- name: Publish report
uses: workflow-v6/artifact@v1
with:
name: adversarial-report
path: report.json
Ce fichier décrit deux jobs : generate_attacks crée les exemples adversariaux à l’aide de Foolbox, puis les stocke comme artefact; evaluate charge le modèle et les attaques, calcule les métriques de robustesse et génère un rapport JSON.
2. Script de génération d’attaques (generate_attacks.py)
import argparse
import numpy as np
import torch
import foolbox as fb
from torchvision import models, transforms
parser = argparse.ArgumentParser()
parser.add_argument('--model', required=True)
parser.add_argument('--output', required=True)
args = parser.parse_args()
# Chargement du modèle PyTorch
model = torch.load(args.model)
model.eval()
# Wrapper Foolbox
fmodel = fb.PyTorchModel(model, bounds=(0, 1))
# Exemple de jeu de données (CIFAR‑10) – ici on charge juste 100 images aléatoires
transform = transforms.Compose([transforms.ToTensor()])
images = torch.randn(100, 3, 32, 32) # placeholder, remplacer par un vrai DataLoader
labels = torch.randint(0, 10, (100,))
# Attaque FGSM (Fast Gradient Sign Method)
adversarial = []
for img, lbl in zip(images, labels):
raw, clipped, is_adv = fb.attacks.FGSM()(fmodel, img.unsqueeze(0), lbl)
adversarial.append(clipped.squeeze(0).numpy())
np.save(args.output, np.stack(adversarial))
Le script reste générique : il suffit de remplacer le jeu de données factice par un DataLoader réel. D’autres attaques (PGD, DeepFool) peuvent être sélectionnées en changeant la classe fb.attacks.XYZ.
3. Script d’évaluation (evaluate_attacks.py)
import argparse, json, numpy as np, torch
from torch.utils.data import TensorDataset, DataLoader
import foolbox as fb
parser = argparse.ArgumentParser()
parser.add_argument('--model', required=True)
parser.add_argument('--attacks', required=True)
parser.add_argument('--report', required=True)
args = parser.parse_args()
model = torch.load(args.model)
model.eval()
fmodel = fb.PyTorchModel(model, bounds=(0, 1))
adv_images = np.load(args.attacks)
# Supposons que les labels originaux soient connus et stockés séparément
# Ici on génère des labels aléatoires comme placeholder
labels = torch.randint(0, 10, (adv_images.shape[0],))
dataset = TensorDataset(torch.tensor(adv_images, dtype=torch.float32), labels)
loader = DataLoader(dataset, batch_size=32)
correct = 0
total = 0
for imgs, lbls in loader:
preds = model(imgs).argmax(dim=1)
correct += (preds == lbls).sum().item()
total += lbls.size(0)
accuracy_adv = correct / total
report = {
"adversarial_accuracy": accuracy_adv,
"total_samples": total,
"threshold": 0.70 # valeur de référence, configurable
}
with open(args.report, 'w') as f:
json.dump(report, f, indent=2)
Le rapport JSON contient la accuracy sur les exemples adversariaux ainsi qu’un seuil de tolérance configurable.
Intégration au CI/CD et automatisation des rapports
- Publication du rapport – Workflow v6 expose les artefacts via son UI ; on peut également pousser le JSON vers un tableau de bord interne (Grafana, Kibana) à l’aide d’un webhook.
- Gate de qualité – Ajoutez une étape conditionnelle qui arrête le pipeline si
adversarial_accuracy<threshold:
- name: Check robustness
if: steps.eval.outputs.adversarial_accuracy < 0.70
run: |
echo "Robustness below threshold – aborting deploy"
exit 1
- Re‑training automatisé – Si le test échoue, déclenchez un job
retrainqui ré‑entraîne le modèle avec les exemples adversariaux ajoutés au jeu d’entraînement. - Alerting – Configurez un alert dans votre système de monitoring (ex. PagerDuty) en s’appuyant sur l’événement
workflow-v6:artifact:adversarial-report.
Bonnes pratiques et points de vigilance
- Sélection du jeu d’échantillons : testez sur un sous‑ensemble représentatif (au moins 5 % du jeu de validation) pour limiter le temps d’exécution.
- Diversité des attaques : ne vous limitez pas à FGSM. Combinez méthodes gradient‑based et optimisation‑based pour couvrir différents vecteurs d’attaque.
- Gestion des ressources : les attaques PGD sont coûteuses en GPU. Utilisez les options
--batch-sizeet--max-stepspour éviter la saturation du runner. - Versionnage des modèles : chaque exécution doit référencer une version de modèle immuable (hash Git ou tag Docker) afin de garantir la traçabilité.
- Sécurité des artefacts : les exemples adversariaux peuvent contenir des informations sensibles (images réelles). Appliquez le chiffrement fourni par Workflow v6 avant le stockage.
En suivant cette recette, les équipes produit gagnent en visibilité sur la robustesse de leurs modèles, intègrent la détection de vulnérabilités dès le commit, et automatisent la réponse (re‑training, notification). Workflow v6 assure la cohérence du processus tout en restant agnostique quant aux bibliothèques d’attaque utilisées.
Envie d’aller plus loin avec WORKFLOW v6 ?
Découvrir WORKFLOW v6