Trackio documentation
Exécuter des expériences ML avec des agents
Exécuter des expériences ML avec des agents
Trackio est conçu dès le départ pour prendre en charge l’expérimentation ML autonome pilotée par des agents LLM. Ce guide explique comment structurer votre code d’entraînement, configurer les alertes et mettre en place la boucle de rétroaction afin qu’un agent puisse lancer des expériences, les surveiller, réagir aux problèmes et itérer sur les hyperparamètres — le tout sans intervention humaine.
Pourquoi Trackio pour les agents ?
La plupart des outils de suivi d’expériences supposent qu’un humain surveille un tableau de bord. Trackio offre aux agents un accès programmatique de premier ordre via plusieurs canaux :
- CLI avec sortie JSON — chaque commande
trackioprend en charge--json, ce qui facilite son analyse dans n’importe quel langage - API Python —
trackio.Api()fournit un accès direct aux exécutions, aux métriques et aux alertes - API HTTP / MCP — le tableau de bord Trackio expose des points de terminaison d'API Gradio et peut fonctionner en tant que serveur MCP, permettant aux LLM d'appeler directement des outils
- Alertes avec des webhooks — les agents peuvent insérer des appels
trackio.alert()comme des instructions d’affichage et les interroger ultérieurement sincefiltering — interrogation efficace des nouvelles alertes sans relire l'historique complet
La boucle de rétroaction de l'agent
Une boucle d'expérimentation autonome typique ressemble à ceci :
┌─────────────────────────────────────┐
│ 1. Agent writes training script │
│ with trackio.init(), log(), │
│ and alert() calls │
├─────────────────────────────────────┤
│ 2. Agent launches the script │
├─────────────────────────────────────┤
│ 3. Agent polls for alerts and │
│ metrics while training runs │
├─────────────────────────────────────┤
│ 4. Agent reads results, decides │
│ next hyperparameters │
├─────────────────────────────────────┤
│ 5. Agent writes a new script │
│ and repeats from step 1 │
└─────────────────────────────────────┘Le reste de ce guide détaille chaque étape avec du code concret.
Étape 1 : Structurer le code d’entraînement pour les agents
L’idée clé est qu’un agent peut insérer des appels trackio.alert() de la même manière qu’il insérerait des instructions print() pour le débogage. Les alertes sont plus structurées que les instructions print : elles disposent d’un titre, d’une description facultative, d’un niveau de gravité, et sont automatiquement persistées et interrogeables.
Voici un script d’entraînement rédigé comme le ferait un agent, avec des alertes à chaque point de décision :
import trackio
import torch
trackio.init(
project="cifar10-hparam-search",
name="run-lr0.001-bs64",
config={
"learning_rate": 0.001,
"batch_size": 64,
"optimizer": "adamw",
"epochs": 50,
"weight_decay": 1e-4,
},
)
model = build_model()
optimizer = torch.optim.AdamW(
model.parameters(), lr=0.001, weight_decay=1e-4
)
best_val_loss = float("inf")
patience_counter = 0
patience_limit = 5
for epoch in range(50):
train_loss = train_one_epoch(model, train_loader, optimizer)
val_loss, val_acc = evaluate(model, val_loader)
trackio.log({
"train_loss": train_loss,
"val_loss": val_loss,
"val_accuracy": val_acc,
"learning_rate": optimizer.param_groups[0]["lr"],
})
# Alert on loss divergence
if train_loss > 10.0:
trackio.alert(
title="Training diverged",
text=f"train_loss={train_loss:.4f} at epoch {epoch}. "
"Learning rate is likely too high.",
level=trackio.AlertLevel.ERROR,
)
break
# Alert when validation stops improving
if val_loss < best_val_loss:
best_val_loss = val_loss
patience_counter = 0
torch.save(model.state_dict(), "best_model.pt")
else:
patience_counter += 1
if patience_counter >= patience_limit:
trackio.alert(
title="Early stopping triggered",
text=f"No improvement for {patience_limit} epochs. "
f"Best val_loss={best_val_loss:.4f} at epoch "
f"{epoch - patience_limit}.",
level=trackio.AlertLevel.WARN,
)
break
# Alert on overfitting
if epoch > 10 and (train_loss < 0.1 and val_loss > 1.5):
trackio.alert(
title="Overfitting detected",
text=f"train_loss={train_loss:.4f} vs val_loss={val_loss:.4f}. "
"Consider adding regularization or reducing model capacity.",
level=trackio.AlertLevel.WARN,
)
# Alert on good results
if val_acc > 0.93:
trackio.alert(
title="High accuracy reached",
text=f"val_accuracy={val_acc:.4f} at epoch {epoch}.",
level=trackio.AlertLevel.INFO,
)
trackio.alert(
title="Training complete",
text=f"Final val_loss={val_loss:.4f}, val_accuracy={val_acc:.4f}. "
f"Best val_loss={best_val_loss:.4f}.",
level=trackio.AlertLevel.INFO,
)
trackio.finish()Les alertes ici ne s'adressent pas uniquement aux humains — ce sont des signaux structurés que l'agent lira plus tard pour décider de la suite à donner.
Lignes directrices pour des alertes adaptées aux agents
- Utilisez
ERRORpour les conditions qui doivent arrêter l'exécution (divergence, perte NaN, mémoire insuffisante). - Utilisez
WARNpour les conditions suggérant que les hyperparamètres doivent être modifiés (surapprentissage, arrêt anticipé, convergence lente). - Utilisez
INFOpour les jalons (entraînement terminé, précision élevée atteinte, point de contrôle enregistré). - Inclure des valeurs numériques dans
textafin que l'agent puisse les analyser et en tirer des conclusions. - Inclure des suggestions actionnables dans
text(par exemple, « Le taux d’apprentissage est probablement trop élevé ») pour aider l’agent à décider quoi modifier.
Étape 2 : Lancement du script
L'agent peut lancer le script dans un sous-processus ou un processus en arrière-plan. Dans la plupart des frameworks d'agents, cela revient simplement à exécuter une commande shell :
python train.py
Si l’agent utilise un LLM connecté à MCP, il peut également lancer des scripts via un outil shell.
Étape 3 : Surveillance pendant l’entraînement
Pendant l’exécution de l’entraînement, l’agent interroge les alertes et les métriques. L’indicateur --since rend cette opération efficace : seules les nouvelles alertes depuis la dernière vérification sont renvoyées.
Interrogation via CLI
# First poll — get all alerts
trackio get alerts --project "cifar10-hparam-search" --run "run-lr0.001-bs64" --json
# Subsequent polls — only new alerts
trackio get alerts --project "cifar10-hparam-search" --since "2025-06-15T14:30:00" --jsonInterrogation via l'API Python
import trackio
from datetime import datetime, timezone
api = trackio.Api()
last_check = None
while training_is_running():
alerts = api.alerts(
"cifar10-hparam-search",
run="run-lr0.001-bs64",
since=last_check,
)
if alerts:
last_check = alerts[0]["timestamp"] # alerts are sorted newest-first
for a in alerts:
print(f"[{a['level'].upper()}] {a['title']}: {a['text']}")
if a["level"] == "error":
# Stop the run and re-plan
handle_error(a)
time.sleep(30)Interrogation via MCP
Si le tableau de bord Trackio fonctionne en tant que serveur MCP, l’agent peut appeler directement l’outil get_alerts via le protocole MCP. Consultez Trackio en tant qu’API et serveur MCP pour les instructions de configuration.
Étape 4 : Lecture des résultats et décision des prochaines étapes
Une fois l’exécution terminée, l’agent lit les résultats complets :
# Get run summary (metrics, config, step count)
trackio get run --project "cifar10-hparam-search" --run "run-lr0.001-bs64" --json
# Get the loss curve
trackio get metric --project "cifar10-hparam-search" --run "run-lr0.001-bs64" --metric "val_loss" --json
# Get all alerts (the most useful signal for decision-making)
trackio get alerts --project "cifar10-hparam-search" --run "run-lr0.001-bs64" --jsonLes alertes fournissent un résumé concis de ce qui s’est produit pendant l’entraînement. Au lieu d’analyser des milliers de valeurs de métriques, l’agent peut lire quelques alertes pour comprendre :
- La formation a-t-elle divergé ? → Baissez le taux d'apprentissage
- A-t-il sur-apprendu ? → Ajoutez de la régularisation ou réduisez la capacité
- A-t-il effectué un arrêt anticipé ? → Les hyperparamètres sont dans la bonne fourchette mais pourraient nécessiter un réglage
- A-t-il atteint une haute précision ? → Cette configuration fonctionne bien
Étape 5 : Itération sur les hyperparamètres
L'agent utilise les alertes de l'exécution précédente pour choisir de nouveaux hyperparamètres. Voici un exemple concret de la logique de décision qu'un agent pourrait suivre :
import json
import subprocess
import trackio
api = trackio.Api()
# Read alerts from the last run
alerts = api.alerts("cifar10-hparam-search", run="run-lr0.001-bs64")
# Read the config from the last run
runs = api.runs("cifar10-hparam-search")
last_run = [r for r in runs if r.name == "run-lr0.001-bs64"][0]
config = last_run.config
# Decision logic based on alerts
new_config = dict(config)
for alert in alerts:
if "diverged" in alert["title"].lower():
new_config["learning_rate"] = config["learning_rate"] * 0.1
elif "overfitting" in alert["title"].lower():
new_config["weight_decay"] = config.get("weight_decay", 1e-4) * 10
elif "early stopping" in alert["title"].lower():
new_config["learning_rate"] = config["learning_rate"] * 0.5
elif "high accuracy" in alert["title"].lower():
# This config is good — try fine-tuning
new_config["learning_rate"] = config["learning_rate"] * 0.5
new_config["epochs"] = config["epochs"] + 20L'agent génère ensuite un nouveau script d'entraînement avec la configuration mise à jour et le lance, en répétant la boucle.
Comparaison des exécutions
Après plusieurs itérations, l’agent peut comparer toutes les exécutions du projet :
# List all runs
trackio list runs --project "cifar10-hparam-search" --json
# Get a summary of each run
trackio get run --project "cifar10-hparam-search" --run "run-lr0.001-bs64" --json
trackio get run --project "cifar10-hparam-search" --run "run-lr0.0001-bs64" --jsonEn Python :
api = trackio.Api()
runs = api.runs("cifar10-hparam-search")
for run in runs:
alerts = run.alerts()
errors = [a for a in alerts if a["level"] == "error"]
warns = [a for a in alerts if a["level"] == "warn"]
infos = [a for a in alerts if a["level"] == "info"]
print(f"{run.name}: {len(errors)} errors, {len(warns)} warnings, {len(infos)} info")Envoi d'alertes à l'agent via des Webhooks
Si votre framework d’agent dispose d’un point de terminaison HTTP ou peut recevoir des messages de Slack/Discord, vous pouvez utiliser des webhooks pour envoyer des alertes à l’agent en temps réel au lieu de faire du polling :
trackio.init(
project="cifar10-hparam-search",
webhook_url="https://hooks.slack.com/services/T.../B.../xxx",
)De cette manière, les alertes sont acheminées vers un canal Slack surveillé par l’agent, fermant ainsi la boucle sans aucun mécanisme de sonde. Consultez le guide des alertes pour des instructions détaillées de configuration pour Slack et Discord.
Exemple complet : Recherche autonome d’hyperparamètres
Voici un exemple complet et autonome qui rassemble l’ensemble. Ce script exécute une simple recherche de grille d’hyperparamètres avec des décisions automatisées basées sur des alertes :
import trackio
import random
import time
def run_experiment(config):
"""Simulate a training run. Replace with real training code."""
run = trackio.init(
project="auto-hparam-search",
config=config,
)
lr = config["learning_rate"]
best_val_loss = float("inf")
patience = 0
for epoch in range(config["epochs"]):
# Simulated metrics — replace with real training
noise = random.gauss(0, lr * 10)
train_loss = max(0.01, 1.0 / (epoch + 1) + noise)
val_loss = train_loss + random.uniform(0, 0.3)
val_acc = max(0, min(1, 1.0 - val_loss + random.uniform(-0.05, 0.05)))
trackio.log({
"train_loss": train_loss,
"val_loss": val_loss,
"val_accuracy": val_acc,
})
if train_loss > 5.0:
trackio.alert(
title="Training diverged",
text=f"train_loss={train_loss:.4f}, lr={lr}",
level=trackio.AlertLevel.ERROR,
)
break
if val_loss < best_val_loss:
best_val_loss = val_loss
patience = 0
else:
patience += 1
if patience >= 5:
trackio.alert(
title="Early stopping",
text=f"Best val_loss={best_val_loss:.4f}",
level=trackio.AlertLevel.WARN,
)
break
time.sleep(0.05)
trackio.alert(
title="Run complete",
text=f"Final val_loss={val_loss:.4f}, val_acc={val_acc:.4f}, "
f"best_val_loss={best_val_loss:.4f}",
level=trackio.AlertLevel.INFO,
)
trackio.finish()
return run.name
def analyze_and_decide(api, project, run_name, config):
"""Read alerts from a run and suggest new hyperparameters."""
alerts = api.alerts(project, run=run_name)
new_config = dict(config)
for alert in alerts:
title = alert["title"].lower()
if "diverged" in title:
new_config["learning_rate"] *= 0.1
elif "early stopping" in title:
new_config["learning_rate"] *= 0.5
elif "run complete" in title and "val_acc" in (alert.get("text") or ""):
# Slight refinement
new_config["learning_rate"] *= 0.8
new_config["epochs"] += 10
return new_config
api = trackio.Api()
project = "auto-hparam-search"
config = {
"learning_rate": 0.01,
"batch_size": 64,
"epochs": 30,
}
for iteration in range(5):
print(f"\n--- Iteration {iteration + 1} ---")
print(f"Config: {config}")
run_name = run_experiment(config)
config = analyze_and_decide(api, project, run_name, config)Cet exemple est autonome et utilise des métriques simulées. Remplacez le corps de la fonction run_experiment par votre code d’entraînement réel et le schéma reste le même.
Utiliser les alertes avec Transformers et TRL
Lors de l’utilisation de report_to="trackio" avec le Trainer de Hugging Face, le TrackioCallback intégré gère automatiquement trackio.init(), trackio.log() et trackio.finish(). Étant donné que trackio.init() est appelé avant le début de l’entraînement, l’exécution en cours est définie et trackio.alert() fonctionne depuis n’importe quel autre callback du même processus.
Pour ajouter des alertes, écrivez un petit TrainerCallback et passez-le au Trainer via callbacks= :
Transformers
import trackio
from transformers import Trainer, TrainerCallback, TrainingArguments
class AlertCallback(TrainerCallback):
def on_log(self, args, state, control, logs=None, **kwargs):
if "trackio" not in args.report_to or logs is None:
return
loss = logs.get("loss")
if loss is not None and loss > 5.0:
trackio.alert(
title="Training loss spike",
text=f"loss={loss:.4f} at step {state.global_step}. "
"Consider lowering the learning rate.",
level=trackio.AlertLevel.ERROR,
)
def on_evaluate(self, args, state, control, metrics=None, **kwargs):
if "trackio" not in args.report_to or metrics is None:
return
eval_loss = metrics.get("eval_loss")
if eval_loss is not None and eval_loss > 2.0:
trackio.alert(
title="High eval loss",
text=f"eval_loss={eval_loss:.4f} at step {state.global_step}.",
level=trackio.AlertLevel.WARN,
)
trainer = Trainer(
model=model,
args=TrainingArguments(
report_to="trackio",
project="my-project",
output_dir="./output",
num_train_epochs=3,
eval_strategy="steps",
eval_steps=100,
),
train_dataset=train_dataset,
eval_dataset=eval_dataset,
callbacks=[AlertCallback()],
)
trainer.train()Un agent générant ce code n'a besoin que de définir la classe AlertCallback avec les bonnes conditions, puis de l'ajouter à la liste callbacks. Le schéma est le même quel que soit le modèle ou le jeu de données.
TRL
La même approche fonctionne avec les formateurs TRL tels que GRPOTrainer ou SFTTrainer. Voici un exemple pour l'apprentissage par renforcement avec des alertes sur l'effondrement de la récompense et la divergence KL :
import trackio
from transformers import TrainerCallback
class RLAlertCallback(TrainerCallback):
def on_log(self, args, state, control, logs=None, **kwargs):
if "trackio" not in args.report_to or logs is None:
return
reward = logs.get("train/reward")
if reward is not None and reward < -1.0:
trackio.alert(
title="Reward collapse",
text=f"reward={reward:.4f} at step {state.global_step}. "
"Consider lowering the learning rate or checking the "
"reward model.",
level=trackio.AlertLevel.ERROR,
)
kl = logs.get("train/kl")
if kl is not None and kl > 10.0:
trackio.alert(
title="KL divergence too high",
text=f"kl={kl:.4f} at step {state.global_step}. "
"The policy is drifting too far from the reference model.",
level=trackio.AlertLevel.WARN,
)
completion_length = logs.get("train/completion_length")
if completion_length is not None and completion_length < 5.0:
trackio.alert(
title="Completions too short",
text=f"Mean completion length={completion_length:.1f} tokens. "
"The model may be collapsing to short outputs.",
level=trackio.AlertLevel.WARN,
)Passez-le ensuite à n'importe quel formateur TRL :
from trl import GRPOTrainer, GRPOConfig
trainer = GRPOTrainer(
model=model,
config=GRPOConfig(
report_to="trackio",
project="rl-experiment",
output_dir="./output",
),
train_dataset=dataset,
callbacks=[RLAlertCallback()],
)
trainer.train()Conseils pour les agents rédigeant des callbacks d'alerte
- Gardez les conditions simples. Chaque bloc
ifdoit vérifier une seule métrique par rapport à un seul seuil. Cela permet à un agent d’ajouter, de supprimer ou d’ajuster facilement des conditions entre les exécutions. - Incluez la valeur de la métrique et l'étape dans
text. Cela fournit à l'agent des chiffres concrets sur lesquels raisonner lors du choix des hyperparamètres suivants. - Incluez des suggestions actionnables. Des formulations comme « Pensez à réduire le taux d’apprentissage » aident l’agent à décider de la modification à apporter ensuite.
- Utilisez
on_evaluatepour les métriques d'évaluation. Les métriques d'évaluation ne sont disponibles que danson_evaluate, et non danson_log. Les métriques d'entraînement commelossapparaissent danson_log.
Résumé des bonnes pratiques
Utilisez les alertes comme des signaux structurés, et non comme de simples notifications. Incluez des valeurs numériques et des suggestions actionnables dans
textafin que l’agent puisse les analyser et y réagir.Utilisez les niveaux de gravité de manière cohérente.
ERROR= arrêtez-vous et changez d'approche.WARN= ajustez les paramètres.INFO= jalon atteint.Effectuez des requêtes avec
sincepour plus d’efficacité. Enregistrez l’horodatage de la dernière alerte traitée et transmettez-le en tant quesincelors de la requête suivante afin d’éviter de relire les anciennes alertes.Conservez toutes les exécutions dans le même projet. Cela permet à l'agent de comparer les exécutions côte à côte et de consulter l'historique complet de ce qui a été essayé.
Journaliser la configuration à chaque exécution. Passez toujours
config=àtrackio.init()afin que l’agent puisse relire quels hyperparamètres ont produit quels résultats.Utilisez l’interface en ligne de commande avec
--jsonpour les scripts d’agents. La sortie JSON est fiable à analyser et ne sera pas altérée si le format lisible par l’humain change.Envisagez MCP pour une intégration étroite. Si votre framework d’agents prend en charge MCP, l’exécution de
trackio show --mcp-serverpermet à l’agent d’appeler directement les outils Trackio sans générer de sous-processus.