fn create_embedding_layer(d_model: usize) -> LayerTrace {
LayerTrace {
name: "embedding".to_string(),
index: None,
hidden_dim: (d_model > 0).then_some(d_model),
input_stats: None,
output_stats: None,
weight_stats: None,
anomalies: vec![],
}
}
fn create_transformer_layers(n_layers: usize) -> Vec<LayerTrace> {
(0..n_layers)
.map(|i| LayerTrace {
name: format!("transformer_block_{i}"),
index: Some(i),
hidden_dim: None,
input_stats: None,
output_stats: None,
weight_stats: None,
anomalies: vec![],
})
.collect()
}
fn create_final_layer_norm() -> LayerTrace {
LayerTrace {
name: "final_layer_norm".to_string(),
index: None,
hidden_dim: None,
input_stats: None,
output_stats: None,
weight_stats: None,
anomalies: vec![],
}
}
fn create_default_layer() -> LayerTrace {
LayerTrace {
name: "(layer trace metadata not available)".to_string(),
index: None,
hidden_dim: None,
input_stats: None,
output_stats: None,
weight_stats: None,
anomalies: vec!["No layer information in metadata".to_string()],
}
}
fn apply_layer_filter(
layers: Vec<LayerTrace>,
filter: Option<&str>,
) -> (Vec<LayerTrace>, Vec<String>) {
let Some(pattern) = filter else {
return (layers, Vec::new());
};
let total = layers.len();
let kept: Vec<LayerTrace> = layers
.into_iter()
.filter(|l| l.name.contains(pattern))
.collect();
if kept.is_empty() {
let note = format!("layer filter {pattern:?} matched 0 of {total} layers");
return (kept, vec![note]);
}
(kept, Vec::new())
}
fn extract_layers_from_hyperparameters(
hp: &serde_json::Map<String, serde_json::Value>,
) -> Vec<LayerTrace> {
let n_layers = extract_layer_count(hp);
let d_model = extract_model_dimension(hp);
let mut layers = vec![create_embedding_layer(d_model)];
layers.extend(create_transformer_layers(n_layers));
layers.push(create_final_layer_norm());
layers
}
#[allow(clippy::disallowed_methods)] fn trace_layers(metadata_bytes: &[u8], verbose: bool) -> Vec<LayerTrace> {
if verbose {
eprintln!("Warning: --verbose is not yet implemented for layer tracing. Flag ignored.");
}
let metadata: BTreeMap<String, serde_json::Value> =
rmp_serde::from_slice(metadata_bytes).unwrap_or_default();
let layers: Vec<LayerTrace> = metadata
.get("hyperparameters")
.and_then(|hp| hp.as_object())
.map(extract_layers_from_hyperparameters)
.unwrap_or_default();
if layers.is_empty() {
vec![create_default_layer()]
} else {
layers
}
}
const REFERENCE_UNIMPLEMENTED: &str =
"`apr trace --reference` is not implemented: no layer-by-layer comparison is performed. \
Re-run without --reference to get the trace of a single model.";
fn compare_with_reference(ref_path: &Path) -> Result<(), CliError> {
validate_path(ref_path)?;
Err(CliError::NotImplemented(
REFERENCE_UNIMPLEMENTED.to_string(),
))
}
fn build_trace_result(
path: &Path,
format: &str,
layers: &[LayerTrace],
summary: &TraceSummary,
notes: &[String],
) -> TraceResult {
let mut all_notes = vec![METADATA_ONLY_NOTE.to_string()];
all_notes.extend(notes.iter().cloned());
TraceResult {
file: path.display().to_string(),
format: format.to_string(),
stats_source: STATS_SOURCE_METADATA_ONLY,
notes: all_notes,
layers: layers.to_vec(),
summary: TraceSummary {
total_layers: summary.total_layers,
total_parameters: summary.total_parameters,
anomaly_count: summary.anomaly_count,
anomalies: summary.anomalies.clone(),
},
}
}
fn output_json(
path: &Path,
format: &str,
layers: &[LayerTrace],
summary: &TraceSummary,
notes: &[String],
) {
let result = build_trace_result(path, format, layers, summary, notes);
if let Ok(json) = serde_json::to_string_pretty(&result) {
println!("{json}");
}
}
fn output_text(
path: &Path,
format: &str,
layers: &[LayerTrace],
summary: &TraceSummary,
notes: &[String],
verbose: bool,
) {
output::header(&format!("Layer Trace: {}", path.display()));
println!(
"{}",
output::kv_table(&[
("Format", format.to_string()),
("Layers", summary.total_layers.to_string()),
("Parameters", output::count_fmt(summary.total_parameters)),
("Stats", STATS_SOURCE_METADATA_ONLY.to_string()),
])
);
println!();
println!(" {}", METADATA_ONLY_NOTE.yellow());
for note in notes {
println!(" {}", note.yellow());
}
if !summary.anomalies.is_empty() {
println!();
println!(
" {} {} anomalies detected:",
output::badge_warn("ANOMALY"),
summary.anomaly_count
);
for anomaly in &summary.anomalies {
println!(" - {}", anomaly.red());
}
}
println!();
output::subheader("Layer Breakdown");
let mut rows: Vec<Vec<String>> = Vec::new();
for layer in layers {
let idx_str = layer.index.map_or(String::new(), |i| format!("{i}"));
let anomaly_str = if layer.anomalies.is_empty() {
String::new()
} else {
layer.anomalies.join("; ")
};
if verbose {
let weight_info = layer.weight_stats.as_ref().map_or(String::from("-"), |s| {
format!("{} params, mean={:.4}, std={:.4}", s.count, s.mean, s.std)
});
let output_info = layer.output_stats.as_ref().map_or(String::from("-"), |s| {
format!(
"mean={:.4}, std={:.4}, [{:.4}, {:.4}]",
s.mean, s.std, s.min, s.max
)
});
rows.push(vec![
idx_str,
layer.name.clone(),
weight_info,
output_info,
anomaly_str,
]);
} else {
rows.push(vec![idx_str, layer.name.clone(), anomaly_str]);
}
}
if verbose {
println!(
"{}",
output::table(&["#", "Layer", "Weights", "Output", "Anomalies"], &rows,)
);
} else {
println!("{}", output::table(&["#", "Layer", "Anomalies"], &rows));
}
}