Files
Multi_Swarm_Coevolutive/docs/decisions/2026-05-11-phase1-5-nemotron-run.md
T
Adriano 1a171acfb2 docs: decision memo Phase 1.5 nemotron run (NO-GO)
Run phase1.5-nemotron-001 completato in 2h26min, costo $0.1244.
Max fitness 0.0215 stagnante (15x peggio del baseline qwen 0.3347),
DSR=0 universale, Sharpe -1.08/-1.15. Loop non converge.

Adversarial Phase 1.5 attivo: 98 finding totali, 35 fees_eat_alpha
HIGH + 15 flat_too_long + 8 time_in_market — i 3 nuovi check killano
correttamente, ma popolazione non ha materiale sano da cui evolvere.

Tre direzioni candidate per Phase 2: A) rollback qwen-2.5-72b,
B) prompt re-tuning nemotron, C) promuovere deepseek-v4-flash.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 14:46:35 +02:00

8.5 KiB
Raw Blame History

Phase 1.5 — Run nemotron tier C — Decision Memo

Data: 11 maggio 2026 Run di riferimento: phase1.5-nemotron-001 (id 434c417e2b6f42bb8cf32514e5d0db1d) Tier LLM: C → nvidia/nemotron-3-super-120b-a12b:free Durata wallclock: 2 h 26 min (08:15 → 10:11 UTC, gen 0 → gen 9) Spesa totale: $0.1244 (price-table tier C; il modello effettivo è :free su OpenRouter, ma il cost tracker applica la pricing nominale del tier) Status: Completato, ma esito strategico NO-GO sulla configurazione corrente


1. Premessa

Il run phase1.5-nemotron-001 è la prima esecuzione end-to-end del loop GA con:

  • l'Adversarial layer aggiornato in Phase 1.5 (commits 56a631f + d3662f6), con tre nuovi check HIGH (flat_too_long, fees_eat_alpha, time_in_market_too_high) più i due esistenti rinforzati;
  • il tier C ribindato a nvidia/nemotron-3-super-120b-a12b:free, modello scelto in benchmark contro sette alternative per stabilità JSON e costo nullo;
  • il fix EmptyCompletionError su llm/client.py (commit 9d0deb3) introdotto durante la stessa sessione per gestire le risposte vuote che alcuni provider :free ritornano sporadicamente.

L'obiettivo dichiarato del run era verificare se il nuovo budget di vincoli adversarial — più stretto del v5 — fosse compatibile con la capacità generativa di nemotron, e se la popolazione riuscisse a esplorare una zona di fitness positiva non degenere.


2. Hard gate Phase 1 — ripercorrenza

I 5 hard gate originali (definiti nello spec strategico di Phase 1) sono stati rivalutati su questo run come sanity check, non come passaggio formale di gate.

# Gate Soglia Misura Esito
1 Loop converge mediana cresce ≥3 gen consecutive Gen 0→8: median oscilla tra 0.0 e 0.0073 senza crescita strutturale FAIL
2 Parse success ≥80% proposte LLM parse-OK 81/89 = 91.0% PASS
3 Top-5 ratio top-5 fitness ≥10× mediana top-5 = 0.01620.0215; mediana ≈ 0 → ratio indefinito ⚠️ N/A
4 Entropy ≥0.5 a fine run 0.845 alla gen 9 PASS
5 Budget costo ≤ cap $0.1244 vs cap $700 (0.02%) PASS

Il gate critico è il numero 1. La popolazione non converge: il max_fitness resta inchiodato a 0.0215 dalla generazione 0 fino alla 9, segnale che l'elite preservation cattura un singolo genoma poco peggiore degli altri ma altrettanto inadatto, mentre il resto della popolazione non riesce a superarlo. La mediana è zero in 9 generazioni su 10 (singolo picco a 0.0073 in gen 8).


3. Lettura dei top genomi

I cinque genomi a fitness più alta hanno tutti caratteristiche economicamente disastrose:

Genome ID Fitness DSR Sharpe Total return n_trades
0e1f9d7af25cfd6a 0.0215 0.000 1.083 115.9% 385
85a8116ab2cd2735 0.0215 0.000 1.083 115.9% 385
92aae563277b6f21 0.0193 0.000 1.129 131.0% 597
01d0ca99bbdd7320 0.0180 0.000 1.112 131.7% 602
194b096f7edab53c 0.0162 0.000 1.154 150.7% 369

Il fatto che DSR sia zero per tutti i top-5 indica che nessuna strategia passa il deflation test di Bailey & López 2014: il loop non sta generando proposte con edge statistico anche solo apparente. Il valore di fitness positivo che li seleziona deriva interamente dal termine tanh(sharpe) × penalty(dd) della fitness v1, che resta debolmente non nullo anche per Sharpe negativi grazie alla penalty di drawdown e a saturazioni numeriche. I primi due genomi hanno fitness identico a 0.0215 e total return identico — verosimilmente lo stesso elite riproposto a generazioni adiacenti.


4. Adversarial findings — il sistema fa il suo lavoro

Il layer Adversarial Phase 1.5 ha emesso 98 finding sul run:

Severità Check Conteggio
HIGH fees_eat_alpha (nuovo P1.5) 35
MEDIUM overtrading 19
HIGH no_trades 16
HIGH flat_too_long (nuovo P1.5) 15
HIGH time_in_market_too_high (nuovo P1.5) 8
HIGH undertrading 4
HIGH degenerate 1

Il dato saliente è che i tre check introdotti in Phase 1.5 — fees_eat_alpha, flat_too_long, time_in_market_too_high — sono effettivamente attivi e killano strategie. In particolare fees_eat_alpha è la categoria più popolata: 35 occorrenze HIGH. Esempi tipici dai detail dei finding:

  • Fees $17073.82 = 2032.6% of gross $840.00;
  • Fees $70646.03 = 12671.9% of gross $557.50;
  • Signal flat for 98.8% of bars (>95% threshold).

Il messaggio è netto: il pool di strategie generato da nemotron, ai prompt e ai gradi di libertà attuali, oscilla tra due estremi degeneri — strategie inattive (flat 98%+) e strategie iperattive (overtrading + fee che divorano l'alpha lordo). Phase 1.5 cattura entrambi gli estremi, ma il loop GA non ha materiale di partenza sano da cui evolvere.


5. Decisione

Esito: NO-GO sulla combinazione tier C = nemotron + Phase 1.5 adversarial come configurazione di Phase 2.

Le ragioni a supporto della decisione sono tre.

Primo, la convergenza è assente per nove generazioni consecutive, non un plateau di selezione raggiunto dopo una fase di salita. Non si tratta cioè di un loop che ha già trovato il suo ottimo e lo conserva, ma di un loop che non ne ha trovato uno.

Secondo, la distanza dal baseline Phase 1 v5 è di un ordine di grandezza: max fitness 0.0215 qui contro 0.3347 nel run di gate Phase 1, mediana che oscilla sullo zero contro una mediana attorno a 0.0050.09. Nemotron, in questa configurazione, sta producendo proposte qualitativamente più povere di qwen-2.5-72b nello stesso schema operativo.

Terzo, i finding adversarial non puntano a un bug del sistema ma a una mancanza di edge nelle proposte. Il loop sta sanzionando correttamente — il problema è a monte, nella generazione.


6. Tre direzioni per Phase 2

Tre opzioni si configurano per il passo successivo. Vanno valutate prima di una nuova esecuzione, non in parallelo a essa.

Direzione A — Riportare tier C a qwen/qwen-2.5-72b-instruct (configurazione di gate Phase 1). Il run di riferimento phase1-real-005 è già un baseline noto: max fitness 0.3347, top genome problematico (flat 99.8%) ma generato sotto Phase 1 adversarial. Rilanciare lo stesso pool con Phase 1.5 adversarial isolerebbe l'effetto del solo hardening sul medesimo motore generativo, senza confondere variabili. Questo è il percorso più informativo nel breve.

Direzione B — Mantenere nemotron ma rilassare i prompt di Hypothesis. L'ipotesi alternativa è che il prompting attuale, calibrato su qwen, sia troppo terso o troppo vincolato per la modalità di ragionamento di nemotron. Iterare due o tre versioni del prompt — più esempi few-shot, vincoli espliciti su n_trades minimo e time_in_market target — può cambiare radicalmente la qualità dell'output senza cambiare il modello.

Direzione C — Sostituire il tier C con un modello a pagamento di fascia comparabile. Tra i benchmark precedenti, deepseek/deepseek-v4-flash è già usato come tier A/B nel file .env; promuoverlo a tier C significa accettare una spesa marginale (stima $13 per run di 10 gen × 20 pop) in cambio di una qualità generativa nota.

La preferenza dell'operatore per modelli cost-conscious orienta verso A o B. La direzione C resta utile come benchmark di controllo se A e B fallissero a loro volta.


7. Operazioni di pulizia eseguite contestualmente

  • Il run zombie phase1-real-008 (id 6ebcff9f7f6544c18ced50313cf72ca9, marcato running da 07:11 UTC senza processo associato) è stato chiuso a status='failed' direttamente in runs.db, per evitare contaminazione delle query di dashboard.
  • Il commit 9d0deb3 (fix(llm): handle empty completions + missing usage) è già su main. Il client.py ora tratta resp.choices == [] e resp.usage is None come errori retryable invece che assertion failure: precondizione necessaria per qualsiasi run successivo su provider :free.

8. Note per chi legge

Questo memo è un documento di decisione, non un rapporto tecnico completo. Il rapporto tecnico esteso del run può essere ricostruito da runs.db interrogando le tabelle runs, generations, evaluations, adversarial_findings, cost_records con run_id='434c417e2b6f42bb8cf32514e5d0db1d'. Il design Phase 1.5 e le motivazioni delle soglie adversarial restano definiti nel commit 56a631f e nei suoi file di test.