Files
foxhunt/crates/ml-alpha/Cargo.toml
jgrusewski 3fa215ad2e feat(ml-alpha): CfcTrunk save/load checkpoint + --checkpoint CLI (C14)
CfcTrunk::save_checkpoint(path) reads each device weight tensor back
via memcpy_dtoh and bincode-serialises into a CheckpointV1 envelope:
  { version, n_in, n_hid,
    w_in, w_rec, b, tau,
    heads_w, heads_b,
    proj_w, proj_b, proj_g, proj_n }
Total ~22k-25k f32 = ~90 KB per trunk. Tiny.

CfcTrunk::load_checkpoint(dev, cfg, path) deserialises + validates
(version == 1, n_in/n_hid match the supplied CfcConfig — a model
trained for one arch can't silently load against another). Constructs
a fresh trunk via new_random (for kernel bindings + scratch buffers)
then overwrites every weight tensor via memcpy_htod. The random init
values are thrown away — marginally wasteful, but keeps the
construction code paths unified.

Roundtrip test (--ignored, CUDA-required): save trunk_A → load → read
back every device tensor and assert bit-equality between trunk_A and
the loaded trunk_B. Passed locally. Dim-mismatch rejection test runs
without CUDA (verifies bincode envelope serialise/deserialise).

bin/fxt-backtest --checkpoint <path>: when set, overrides --seed and
loads from disk. When absent, warns loudly that the trunk is
random-initialised and backtest results are noise. This makes the
binary genuinely useful as a deployment tool — point it at a trained
checkpoint and run real backtests.

Adds bincode workspace dep to ml-alpha (was already in workspace
dependencies, just not in ml-alpha's [dependencies] block). serde
features bumped to ["derive"] (was using workspace default which
omits derive macros).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 09:31:50 +02:00

51 lines
1.8 KiB
TOML

[package]
name = "ml-alpha"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
description = "CfC perception + multi-horizon alpha heads (Phase A foundation for CfC+PPO greenfield)"
publish = false
# Phase A scope: snapshot-level CfC trunk + 5 multi-horizon BCE heads,
# pre-compiled CUDA cubins, GPU-resident weights. The hard validation gate
# (CfC vs Mamba2 AUC at every horizon) sits at the end of Phase A. Phase B
# (PPO) extends this crate; live integration lives in trading_agent_service.
[features]
default = ["cuda"]
cuda = []
[dependencies]
ml-core = { workspace = true }
# NOTE: cannot depend on `ml` (would cycle — ml depends on ml-alpha for the
# mamba2_block gate reference). MappedF32Buffer is duplicated locally in
# `src/pinned_mem.rs`; eventually we should move mapped-pinned to ml-core.
ml-features = { workspace = true }
data = { workspace = true }
cudarc = { version = "0.19", default-features = false, features = ["driver", "cublas", "dynamic-linking", "std", "cuda-version-from-build-system", "f16"] }
# Standard async + error + logging plumbing
tokio = { workspace = true, features = ["rt-multi-thread", "macros", "fs", "io-util"] }
anyhow.workspace = true
tracing.workspace = true
tracing-subscriber.workspace = true
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
bincode.workspace = true
thiserror.workspace = true
clap = { workspace = true, features = ["derive"] }
# Arrow IPC for fxcache reading (gate reference path).
arrow = { workspace = true, features = ["ipc"] }
# Deterministic RNG for weight init, shuffling.
rand = { workspace = true }
rand_chacha = "0.3"
# Phase A data path: mmap predecoded MBP-10 sidecars.
memmap2 = { workspace = true }
[dev-dependencies]
tempfile = { workspace = true }
approx = { workspace = true }