feat(crt-train): add --smoothness-base-lambda CLI flag + telemetry

This commit is contained in:
jgrusewski
2026-05-20 23:51:20 +02:00
parent c9aa0c2a98
commit 60d0b62b8d
2 changed files with 28 additions and 1 deletions

View File

@@ -153,6 +153,14 @@ struct Cli {
#[arg(long, default_value_t = 0)]
cv_train_window: usize,
/// CRT.train intervention A — output-smoothness regularizer.
///
/// λ[h] = base × (HORIZONS[h] / HORIZONS[0]). Default 0.0 disables
/// the regularizer (kernel still launches, produces zero gradient).
/// Recommended sweep: 0.001 / 0.01 / 0.1. See
/// `docs/superpowers/specs/2026-05-20-crt-train-output-smoothness-design.md`.
#[arg(long, default_value_t = 0.0)]
smoothness_base_lambda: f32,
}
#[derive(Serialize, serde::Deserialize, Default)]
@@ -196,6 +204,11 @@ struct AlphaTrainSummary {
/// Written by the X14 wiring inside the `auc_h6000_improved` block.
#[serde(default, skip_serializing_if = "Option::is_none")]
best_h6000_ckpt_path: Option<String>,
/// Per-horizon raw mean-squared adjacent-prob diff at the final epoch
/// (CRT.train intervention A telemetry). All zeros when
/// `--smoothness-base-lambda` is unset (default).
#[serde(default)]
final_smooth_loss_per_horizon: [f32; N_HORIZONS],
}
/// Linear warmup then cosine decay to `lr_min`. `step_idx` is the
@@ -261,7 +274,7 @@ fn main() -> Result<()> {
seed: cli.seed,
horizon_weights,
n_batch: cli.batch_size,
smoothness_base_lambda: 0.0,
smoothness_base_lambda: cli.smoothness_base_lambda,
};
let mut trainer = PerceptionTrainer::new(&dev, &trainer_cfg).context("trainer init")?;
@@ -655,6 +668,7 @@ fn main() -> Result<()> {
best_auc_h6000_per_horizon,
early_stopped,
best_h6000_ckpt_path,
final_smooth_loss_per_horizon: trainer.last_smoothness_loss_per_horizon(),
};
let summary_path = cli.out.join("alpha_train_summary.json");
std::fs::write(&summary_path, serde_json::to_vec_pretty(&summary).context("serialize summary")?)

View File

@@ -3928,6 +3928,19 @@ impl PerceptionTrainer {
download(&self.stream, &self.probs_per_k_d)
}
/// Last-step per-horizon raw mean-squared-diff (pre-λ). Reads from
/// the mapped-pinned host shadow populated by `step_batched`. Returns
/// all zeros when the smoothness regularizer is disabled
/// (`cfg.smoothness_base_lambda == 0.0`).
pub fn last_smoothness_loss_per_horizon(&self) -> [f32; N_HORIZONS] {
let raw = self.smoothness_loss_per_horizon_host_d.read_all();
let mut out = [0.0f32; N_HORIZONS];
for (i, v) in raw.into_iter().take(N_HORIZONS).enumerate() {
out[i] = v;
}
out
}
/// Convenience for callers that only need the LAST position's probs
/// (legacy API — final-position AUC scoring).
pub fn last_probs(&self) -> Result<[f32; N_HORIZONS]> {