feat(ml-alpha): PerceptionTrainer::forward_only + from_checkpoint (X11)
X11 inference interface for the deployability backtester. Two new
public methods on PerceptionTrainer:
forward_only(snapshots) -> Vec<f32>
Forward-only pass over a K-snapshot window. Wraps evaluate() with
dummy zero-valued labels and discards the loss. Returns the same
[K, B, N_HORIZONS]-shaped probability output as evaluate_batched.
from_checkpoint(dev, cfg, path) -> Result<Self>
Build a PerceptionTrainer ready for inference: constructs a fresh
trainer (with random init) to wire up kernel handles + grad
buffers + scratches, then overwrites the trunk's weights from the
Checkpoint file via CfcTrunk::load_checkpoint. The optimizer +
grad buffers stay allocated — unused at inference, but allocating
them keeps the struct invariant uniform. A leaner inference-only
struct can be added later if memory matters.
Architectural note: the trunk is the source of truth for weights (X1-X9
established that). PerceptionTrainer is the kernel-launch adapter that
drives forward + backward over those weights. Inference doesn't need a
separate forward path on the trunk — the trainer's evaluate_batched
already does the full chain correctly. fxt-backtest can now construct a
PerceptionTrainer in inference role via from_checkpoint + call
forward_only per decision.
Verification: ml-alpha + ml-backtesting + fxt-backtest build clean.
ml-alpha lib tests: 33 pass.
This commit is contained in:
@@ -2316,6 +2316,56 @@ impl PerceptionTrainer {
|
||||
self.trunk.save_checkpoint(path).context("trunk save_checkpoint")
|
||||
}
|
||||
|
||||
/// X11 inference entry point: forward-only pass over `snapshots`
|
||||
/// (length `cfg.n_batch * cfg.seq_len` per the trainer's batching).
|
||||
/// Returns per-horizon probabilities flattened as `[K, B, N_HORIZONS]`
|
||||
/// in row-major layout — same shape as `evaluate_batched`'s second
|
||||
/// return value but with no loss computed and no labels required.
|
||||
///
|
||||
/// The backtester calls this per decision: load `PerceptionTrainer`
|
||||
/// from a Checkpoint via `from_checkpoint`, maintain a sliding K-window
|
||||
/// of recent snapshots, take the last K position's probs as the
|
||||
/// decision signal.
|
||||
pub fn forward_only(&mut self, snapshots: &[Mbp10RawInput]) -> Result<Vec<f32>> {
|
||||
// Mamba2 + the full perception chain process the K snapshots
|
||||
// together; BCE consumes the labels. For inference we pass
|
||||
// zero-valued dummy labels and discard the resulting loss.
|
||||
let dummy_labels: Vec<[f32; N_HORIZONS]> =
|
||||
vec![[0.0_f32; N_HORIZONS]; snapshots.len()];
|
||||
let (_loss, probs) = self.evaluate(snapshots, &dummy_labels)?;
|
||||
Ok(probs)
|
||||
}
|
||||
|
||||
/// X11 checkpoint-loaded constructor: instantiates a PerceptionTrainer
|
||||
/// from a Checkpoint file, ready for `forward_only` inference. The
|
||||
/// optimizer state + gradient buffers ARE allocated (training-only
|
||||
/// state); they're unused at inference but allocating them keeps
|
||||
/// the struct invariant simple. For pure-inference deployments where
|
||||
/// the memory matters, a leaner "InferenceOnly" variant can be added
|
||||
/// later.
|
||||
pub fn from_checkpoint(
|
||||
dev: &MlDevice,
|
||||
cfg: &PerceptionTrainerConfig,
|
||||
path: &std::path::Path,
|
||||
) -> Result<Self> {
|
||||
// Construct a fresh trainer (with random init) to wire up all
|
||||
// grad buffers + kernel handles + scratches, then overwrite the
|
||||
// trunk's weights from the checkpoint via load_checkpoint.
|
||||
let mut trainer = Self::new(dev, cfg)?;
|
||||
let trunk_cfg = crate::cfc::trunk::CfcConfig {
|
||||
n_in: FEATURE_DIM,
|
||||
n_hid: HIDDEN_DIM,
|
||||
cfc_n_in: HIDDEN_DIM,
|
||||
mamba2_state_dim: cfg.mamba2_state_dim,
|
||||
n_batch: cfg.n_batch,
|
||||
seq_len: cfg.seq_len,
|
||||
};
|
||||
let new_trunk = crate::cfc::trunk::CfcTrunk::load_checkpoint(dev, &trunk_cfg, path)
|
||||
.context("PerceptionTrainer::from_checkpoint: trunk load")?;
|
||||
trainer.trunk = new_trunk;
|
||||
Ok(trainer)
|
||||
}
|
||||
|
||||
pub fn evaluate(
|
||||
&mut self,
|
||||
snapshots: &[Mbp10RawInput],
|
||||
|
||||
Reference in New Issue
Block a user