Files
foxhunt/docs
jgrusewski f86353840e fix(dqn): unstick IQN trunk gradient — drop iqn_readiness multiplier from SAXPY scale
`apply_iqn_trunk_gradient` and the parallel VSN-range SAXPY both scaled their
contribution by `iqn_lambda × iqn_readiness × iqn_budget`. The readiness
scalar initialises to 0.0 and only ramps up when `iqn_loss_ema` drops below
`iqn_loss_initial` — but that improvement requires the trunk to learn IQN's
gradient, which the readiness gate just blocked. Bootstrap deadlock:
trunk_iqn=0.0000 across every observed L40S epoch, downstream strangling
direction-Q discrimination → eval strict-argmax glues to one direction →
22-34 trades per 858k-bar window vs healthy 1257-trade burst at the one
epoch where the gate momentarily lifted.

iqn_budget already throttles the IQN contribution via the per-component
budget controller (60% IQN, ISV-driven), so readiness was an additive
band-aid that became load-bearing. New scale: `iqn_lambda × iqn_budget`.

The `iqn_readiness` field stays on `self` because the C51 loss kernel
launch site reuses `iqn_readiness_dev_ptr` as a CVaR-alpha pointer
(gpu_dqn_trainer.rs:~16227) — that semantic overload is broken in a
different way (CVaR α=0 is degenerate) and is tracked for follow-up.

Verified on cluster trace `train-multi-seed-vg2r9` (epochs 0–13):
trunk_iqn=0.0000 every epoch, q_gap_comp=0.00 every epoch, val
trade_count locked at 22–34 except epoch 2 (1257 trades) where the
gate accidentally cleared.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 18:04:36 +02:00
..