J'ai laissé un agent mener 700 expériences sur mon LLM
L'annonce Sakana en mars 2026 m'avait bluffé : un agent IA qui mène 700 expériences en 48h pour optimiser un modèle de langage, avec une amélioration nette de 11% sur le temps d'entraînement. J'ai voulu savoir si un bricoleur avec un A100 loué à 2,50 $ de l'heure pouvait reproduire ça sur son propre modèle. Verdict après 9 jours, 683 runs et 412 $ de facture cloud : oui, avec des résultats plus modestes mais étonnamment solides. Voici le setup exact, les diffs que l'agent a produits, et les 4 choses qui ne marchent pas comme dans le papier.
Le setup : Llama 8B, A100 loué, boucle d'optimisation
Soutenez mon travail sur Patreon
Accès anticipé aux articles, contenu exclusif, et la satisfaction de soutenir un auteur indépendant.
Rejoindre — à partir de 3€/moisLe modèle cible : Llama 3.1 8B Instruct, quantifié en NF4 via bitsandbytes, fine-tuné sur mon dataset perso de 2 400 exemples (dialogues auteur-lecteur sur mes livres). Le baseline avant optimisation : 4h12 de fine-tuning pour 3 époques, loss finale de 0,847, rouge-L de 0,62 sur un test set de 240 exemples.
L'agent d'optimisation : un Claude Sonnet 4.5 qui reçoit le script d'entraînement, les métriques du baseline, et la consigne « trouve des modifications qui accélèrent l'entraînement ou améliorent la loss, teste-les, garde ce qui marche ». Chaque expérience = modifier le script, relancer 1 époque sur un sous-set de 400 exemples, mesurer, commit dans un git local.
# optimizer_loop.py
import subprocess
from anthropic import Anthropic
client = Anthropic()
baseline = {"loss": 0.847, "time_sec": 4320, "rouge_l": 0.62}
def run_experiment(idx: int):
prompt = f"""Experiment #{idx}. Current best: {current_best}.
Read training_script.py. Propose one change. Apply it. Run 1 epoch on data_small.jsonl.
Measure: loss, time_sec, rouge_l. Commit if improvement >1%."""
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=4096,
messages=[{"role": "user", "content": prompt}],
)
# L'agent exécute les outils : edit_file, run_bash, read_metrics
return parse_tool_results(response)
for i in range(1000):
run_experiment(i)Les 683 runs en 9 jours
J'ai laissé tourner du 10 au 19 mars. L'agent a fait 683 expériences (plus que prévu parce que certaines étaient triviales). Voici la distribution des types d'optimisation qu'il a essayés :
| Type d'optimisation | Nombre de runs | Gains réels |
|---|---|---|
| Hyperparameters (lr, batch, warmup) | 234 | -14% temps |
| Optimizer / scheduler | 89 | -6% temps |
| Gradient accumulation | 67 | +2% loss |
| LoRA rank / alpha | 58 | -3% temps, +1% rouge-L |
| Data ordering / curriculum | 52 | +4% rouge-L |
| Precision (BF16/FP16/NF4) | 47 | -8% temps |
| Attention implementation | 41 | -22% temps |
| Packing / padding | 38 | -11% temps |
| Memory optimizations | 32 | -4% temps |
| Autres (failed) | 25 | 0 |
Gain cumulé sur le baseline : temps d'entraînement passé de 4h12 à 2h58 (-29%), loss finale à 0,812 (-4,1%), rouge-L à 0,648 (+4,5%). Moins spectaculaire que les 11% de Sakana côté temps, mais remember que le benchmark de Sakana était sur un LLM plus gros avec plus de marge.
Les diffs que l'agent a vraiment trouvés
Diff 1 : Flash Attention activée silencieusement
La plus grosse découverte (-22% temps) est venue du run 47. L'agent a testé attn_implementation="flash_attention_2" dans le AutoModelForCausalLM.from_pretrained. J'avais oublié de l'activer dans mon script original. Le gain était immédiat, massif, et gratuit.
Bizarre : j'écris des articles sur Flash Attention et je ne l'avais pas activée. C'est exactement le genre d'erreur qu'un agent automatique trouve en 10 secondes.
Diff 2 : Packing au lieu de padding
Run 152. L'agent a remplacé le padding classique par du packing (concatener plusieurs exemples courts dans une seule séquence de 4096 tokens). Gain : -11% temps, zéro impact sur la loss. Je connaissais cette technique, je trouvais ça « trop compliqué à maintenir ». L'agent l'a juste fait.
# Avant (padding)
dataset = dataset.map(lambda x: tokenizer(x["text"], padding="max_length", max_length=4096))
# Après (packing)
from trl import SFTTrainer
trainer = SFTTrainer(
model=model,
args=training_args,
train_dataset=dataset,
packing=True,
max_seq_length=4096,
)Diff 3 : Cosine schedule avec 3% warmup
Run 203. L'agent a testé 12 combinaisons de schedulers et landed sur cosine avec warmup_ratio=0.03 au lieu de mes linear + 10% de warmup par défaut. Gain : -6% temps, +0,005 sur rouge-L. Minime individuellement mais cumulatif.
Diff 4 : LoRA rank 16 au lieu de 64
Run 301. L'agent a baissé le LoRA rank de 64 à 16. Gain temps : négligeable. Gain mémoire : 3,4 Go de VRAM libérés, ce qui a permis d'augmenter le batch size de 8 à 16 et d'accélérer à l'étape suivante.
Ce genre de changements en cascade (un diff qui en débloque un autre) est exactement ce qu'un humain rate en mode « je change un truc à la fois ».
Les 4 choses qui ne marchent pas comme dans le papier Sakana
Chose 1 : le coût n'est pas linéaire
Sakana annonce un coût de ~500 $ pour 700 expériences. Moi, j'ai payé 412 $ pour 683 runs, soit ~0,60 $ par expérience. Sauf que 35% de ce coût est allé dans les retries — l'agent qui relance la même expérience parce qu'une dépendance Python avait crashé, ou parce qu'un OOM était passé. Sans les retries, j'aurais pu descendre à ~270 $.
Chose 2 : l'agent boucle sur les plateaux
Après ~300 runs, les gains ralentissent drastiquement. L'agent continue à proposer des modifications, mais 80% d'entre elles sont des variations microscopiques sur des trucs déjà testés. J'ai dû manuellement injecter dans le prompt : « ne propose pas de variations sur les 5 dernières optimisations, essaie une direction radicalement différente ».
Chose 3 : les régressions cachées
L'agent optimise une métrique (loss) à la fois. Il a dégradé silencieusement la longueur moyenne des réponses (de 240 tokens à 180) parce qu'un de ses diffs avait réduit le max_new_tokens en évaluation. Sans surveillance humaine, j'aurais validé une régression qualitative pour un gain quantitatif marginal.
Chose 4 : il ne lit pas bien les papiers
J'ai donné à l'agent accès au papier Sakana en contexte pour qu'il s'en inspire. Il a essayé 3 des techniques citées (compile, Liger kernels, fused AdamW) — aucune des 3 n'a marché sur mon setup parce que j'étais sur une A100 et non une H100, et les implémentations divergent. Il n'a jamais compris la subtilité et a retenté chaque technique 3-4 fois avant d'abandonner.
Ce qui vaut vraiment le coup
Après 9 jours, voici mon verdict :
| Type de travail | Agent automatique utile ? |
|---|---|
| Grid search hyperparams | ✅ ✅ ✅ |
| Activation d'optimisations évidentes oubliées | ✅ ✅ ✅ |
| Recherche de diffs en cascade | ✅ ✅ |
| Curriculum learning / data ordering | ✅ |
| Choix d'architecture | ❌ |
| Adaptation au hardware spécifique | ❌ |
| Debug des bugs d'entraînement | ❌ |
L'agent est remarquablement fort pour explorer un espace d'hyperparamètres et découvrir des optimisations évidentes que tu as oubliées. Il est nul pour tout ce qui demande de la connaissance contextuelle fine (hardware, data spécifique, architecture).
Ce qu'il faut retenir
- 1.Reproduire l'expérience Sakana avec 30% du budget est possible — et donne 29% de gain en temps d'entraînement sur un setup grand public.
- 2.Les diffs les plus précieux sont ceux qui corrigent des oublis humains évidents (Flash Attention, packing, LoRA rank).
- 3.L'agent plateau rapidement — après 300 runs, l'exploration stagne sans intervention.
- 4.Toujours surveiller une métrique secondaire pour détecter les régressions cachées.
Pour le détail des architectures d'agents autonomes capables de mener ce genre d'expériences, j'ai écrit un guide complet sur la construction d'agents LLM en Python :
Soutenez mon travail sur Patreon
Accès anticipé aux articles, contenu exclusif, et la satisfaction de soutenir un auteur indépendant.
Rejoindre — à partir de 3€/mois