mod-trace 0.3.1__tar.gz → 0.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mod_trace-0.3.1 → mod_trace-0.3.2}/Cargo.lock +1 -1
- {mod_trace-0.3.1 → mod_trace-0.3.2}/Cargo.toml +1 -1
- {mod_trace-0.3.1 → mod_trace-0.3.2}/PKG-INFO +1 -1
- {mod_trace-0.3.1 → mod_trace-0.3.2}/pyproject.toml +1 -1
- {mod_trace-0.3.1 → mod_trace-0.3.2}/src/main.rs +113 -4
- {mod_trace-0.3.1 → mod_trace-0.3.2}/.github/workflows/release.yml +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/.gitignore +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/LICENSE +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/README.md +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/benchmarks/tiny_pytorch.py +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/docs/ARCHITECTURE.md +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/docs/REAL_MODELS.md +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/docs/tensor-lab.md +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/examples/broken_shape.json +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/examples/lightgbm/README.md +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/examples/lightgbm/clf_v1.txt +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/examples/lightgbm/clf_v2.txt +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/examples/lightgbm/generate_demo_models.py +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/examples/make_sample_catboost.py +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/examples/mlp.json +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/examples/onnx/README.md +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/examples/onnx/generate_demo_models.py +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/examples/onnx/mlp_retrain_a.onnx +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/examples/onnx/mlp_retrain_b.onnx +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/examples/onnx/mlp_v1.onnx +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/examples/onnx/mlp_v2.onnx +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/examples/tiny_attention.json +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/examples/tiny_attention_plan.json +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/src/catboost_deep_diff.py +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/src/catboost_explain.py +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/src/cbm.rs +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/src/demo.rs +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/src/explain.rs +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/src/lgbm.rs +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/src/model.rs +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/src/onnx.rs +0 -0
- {mod_trace-0.3.1 → mod_trace-0.3.2}/src/tensor.rs +0 -0
|
@@ -1027,6 +1027,12 @@ fn opt_num(value: Option<usize>) -> String {
|
|
|
1027
1027
|
.unwrap_or_else(|| "unknown".to_string())
|
|
1028
1028
|
}
|
|
1029
1029
|
|
|
1030
|
+
fn opt_float(value: Option<f64>) -> String {
|
|
1031
|
+
value
|
|
1032
|
+
.map(|value| format!("{value}"))
|
|
1033
|
+
.unwrap_or_else(|| "unknown".to_string())
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1030
1036
|
fn format_count_human(count: usize) -> String {
|
|
1031
1037
|
let value = count as f64;
|
|
1032
1038
|
if value >= 1e9 {
|
|
@@ -1161,10 +1167,29 @@ fn explain_diff_onnx(old_path: &str, new_path: &str) -> Result<(), String> {
|
|
|
1161
1167
|
Ok(())
|
|
1162
1168
|
}
|
|
1163
1169
|
|
|
1170
|
+
fn same_or_changed(equal: bool) -> &'static str {
|
|
1171
|
+
if equal { "same" } else { "changed" }
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1164
1174
|
fn explain_diff_lgbm(old_path: &str, new_path: &str) -> Result<(), String> {
|
|
1165
1175
|
let old = lgbm::inspect(old_path)?;
|
|
1166
1176
|
let new = lgbm::inspect(new_path)?;
|
|
1167
1177
|
|
|
1178
|
+
// Feature-name set comparison (not just the count).
|
|
1179
|
+
let old_features = old.feature_names.iter().collect::<BTreeSet<_>>();
|
|
1180
|
+
let new_features = new.feature_names.iter().collect::<BTreeSet<_>>();
|
|
1181
|
+
let added = new_features
|
|
1182
|
+
.difference(&old_features)
|
|
1183
|
+
.map(|name| name.as_str())
|
|
1184
|
+
.collect::<Vec<_>>();
|
|
1185
|
+
let removed = old_features
|
|
1186
|
+
.difference(&new_features)
|
|
1187
|
+
.map(|name| name.as_str())
|
|
1188
|
+
.collect::<Vec<_>>();
|
|
1189
|
+
let names_known = !old.feature_names.is_empty() || !new.feature_names.is_empty();
|
|
1190
|
+
|
|
1191
|
+
let config_same = lgbm_training_config_same(&old, &new);
|
|
1192
|
+
|
|
1168
1193
|
println!("Model Change Explanation");
|
|
1169
1194
|
println!("------------------------");
|
|
1170
1195
|
println!("Type: LightGBM");
|
|
@@ -1183,17 +1208,60 @@ fn explain_diff_lgbm(old_path: &str, new_path: &str) -> Result<(), String> {
|
|
|
1183
1208
|
opt_num(old.num_leaves.map(|value| value as usize)),
|
|
1184
1209
|
opt_num(new.num_leaves.map(|value| value as usize))
|
|
1185
1210
|
);
|
|
1211
|
+
let feature_note = if !names_known {
|
|
1212
|
+
"names not in header".to_string()
|
|
1213
|
+
} else if added.is_empty() && removed.is_empty() {
|
|
1214
|
+
"same set".to_string()
|
|
1215
|
+
} else {
|
|
1216
|
+
format!("+{} added, -{} removed", added.len(), removed.len())
|
|
1217
|
+
};
|
|
1186
1218
|
println!(
|
|
1187
|
-
" Features: {} -> {}",
|
|
1219
|
+
" Features: {} -> {} ({})",
|
|
1188
1220
|
opt_num(old.num_features.map(|value| value as usize)),
|
|
1189
|
-
opt_num(new.num_features.map(|value| value as usize))
|
|
1221
|
+
opt_num(new.num_features.map(|value| value as usize)),
|
|
1222
|
+
feature_note
|
|
1190
1223
|
);
|
|
1224
|
+
print_lgbm_feature_list(" added: ", &added, 8);
|
|
1225
|
+
print_lgbm_feature_list(" removed:", &removed, 8);
|
|
1226
|
+
println!();
|
|
1227
|
+
println!("Training config:");
|
|
1191
1228
|
println!(
|
|
1192
|
-
" Objective: {} -> {}",
|
|
1229
|
+
" Objective: {} -> {} ({})",
|
|
1193
1230
|
old.objective.as_deref().unwrap_or("unknown"),
|
|
1194
|
-
new.objective.as_deref().unwrap_or("unknown")
|
|
1231
|
+
new.objective.as_deref().unwrap_or("unknown"),
|
|
1232
|
+
same_or_changed(old.objective == new.objective)
|
|
1233
|
+
);
|
|
1234
|
+
println!(
|
|
1235
|
+
" Boosting: {} -> {} ({})",
|
|
1236
|
+
old.boosting.as_deref().unwrap_or("unknown"),
|
|
1237
|
+
new.boosting.as_deref().unwrap_or("unknown"),
|
|
1238
|
+
same_or_changed(old.boosting == new.boosting)
|
|
1239
|
+
);
|
|
1240
|
+
println!(
|
|
1241
|
+
" Metric: {} -> {} ({})",
|
|
1242
|
+
old.metric.as_deref().unwrap_or("unknown"),
|
|
1243
|
+
new.metric.as_deref().unwrap_or("unknown"),
|
|
1244
|
+
same_or_changed(old.metric == new.metric)
|
|
1245
|
+
);
|
|
1246
|
+
println!(
|
|
1247
|
+
" Learning rate: {} -> {} ({})",
|
|
1248
|
+
opt_float(old.learning_rate),
|
|
1249
|
+
opt_float(new.learning_rate),
|
|
1250
|
+
same_or_changed(old.learning_rate == new.learning_rate)
|
|
1251
|
+
);
|
|
1252
|
+
println!(
|
|
1253
|
+
" Max depth: {} -> {} ({})",
|
|
1254
|
+
old.max_depth.map(lgbm_depth_label).as_deref().unwrap_or("unknown"),
|
|
1255
|
+
new.max_depth.map(lgbm_depth_label).as_deref().unwrap_or("unknown"),
|
|
1256
|
+
same_or_changed(old.max_depth == new.max_depth)
|
|
1195
1257
|
);
|
|
1196
1258
|
println!();
|
|
1259
|
+
println!(
|
|
1260
|
+
"File size: {} -> {} ({})",
|
|
1261
|
+
format_bytes(old.bytes),
|
|
1262
|
+
format_bytes(new.bytes),
|
|
1263
|
+
growth_label(old.bytes, new.bytes)
|
|
1264
|
+
);
|
|
1197
1265
|
match (old.estimated_leaf_values(), new.estimated_leaf_values()) {
|
|
1198
1266
|
(Some(o), Some(n)) => println!(
|
|
1199
1267
|
"Estimated leaf-slot growth: {}",
|
|
@@ -1208,11 +1276,52 @@ fn explain_diff_lgbm(old_path: &str, new_path: &str) -> Result<(), String> {
|
|
|
1208
1276
|
println!("Learned state: unchanged (identical leaf values)");
|
|
1209
1277
|
}
|
|
1210
1278
|
println!();
|
|
1279
|
+
println!("Summary:");
|
|
1280
|
+
let structure_same = old.num_trees == new.num_trees && old.num_leaves == new.num_leaves;
|
|
1281
|
+
let features_same = added.is_empty() && removed.is_empty();
|
|
1282
|
+
let descriptor = if !features_same {
|
|
1283
|
+
"feature set changed"
|
|
1284
|
+
} else if !config_same {
|
|
1285
|
+
"training config changed"
|
|
1286
|
+
} else if !structure_same {
|
|
1287
|
+
"same spec, retrained with more/fewer trees"
|
|
1288
|
+
} else {
|
|
1289
|
+
"same spec and features, retrained"
|
|
1290
|
+
};
|
|
1291
|
+
println!(
|
|
1292
|
+
" {descriptor}; trees {}, features {}.",
|
|
1293
|
+
growth_label(old.num_trees as usize, new.num_trees as usize),
|
|
1294
|
+
if !names_known {
|
|
1295
|
+
"unknown".to_string()
|
|
1296
|
+
} else if features_same {
|
|
1297
|
+
"unchanged".to_string()
|
|
1298
|
+
} else {
|
|
1299
|
+
format!("+{}/-{}", added.len(), removed.len())
|
|
1300
|
+
}
|
|
1301
|
+
);
|
|
1302
|
+
println!();
|
|
1211
1303
|
println!("Note: parsed natively from the LightGBM text model.");
|
|
1212
1304
|
|
|
1213
1305
|
Ok(())
|
|
1214
1306
|
}
|
|
1215
1307
|
|
|
1308
|
+
fn print_lgbm_feature_list(label: &str, names: &[&str], limit: usize) {
|
|
1309
|
+
if names.is_empty() {
|
|
1310
|
+
return;
|
|
1311
|
+
}
|
|
1312
|
+
let shown = names
|
|
1313
|
+
.iter()
|
|
1314
|
+
.take(limit)
|
|
1315
|
+
.copied()
|
|
1316
|
+
.collect::<Vec<_>>()
|
|
1317
|
+
.join(", ");
|
|
1318
|
+
if names.len() > limit {
|
|
1319
|
+
println!("{label} {shown}, ... {} more", names.len() - limit);
|
|
1320
|
+
} else {
|
|
1321
|
+
println!("{label} {shown}");
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1216
1325
|
fn explain_diff_catboost(old_path: &str, new_path: &str) -> Result<(), String> {
|
|
1217
1326
|
let old = cbm::inspect(old_path)?;
|
|
1218
1327
|
let new = cbm::inspect(new_path)?;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|