mod-trace 0.3.0__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.0 → mod_trace-0.3.2}/Cargo.lock +1 -1
- {mod_trace-0.3.0 → mod_trace-0.3.2}/Cargo.toml +1 -1
- {mod_trace-0.3.0 → mod_trace-0.3.2}/PKG-INFO +1 -1
- {mod_trace-0.3.0 → mod_trace-0.3.2}/pyproject.toml +1 -1
- {mod_trace-0.3.0 → mod_trace-0.3.2}/src/main.rs +119 -6
- {mod_trace-0.3.0 → mod_trace-0.3.2}/.github/workflows/release.yml +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/.gitignore +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/LICENSE +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/README.md +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/benchmarks/tiny_pytorch.py +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/docs/ARCHITECTURE.md +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/docs/REAL_MODELS.md +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/docs/tensor-lab.md +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/examples/broken_shape.json +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/examples/lightgbm/README.md +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/examples/lightgbm/clf_v1.txt +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/examples/lightgbm/clf_v2.txt +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/examples/lightgbm/generate_demo_models.py +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/examples/make_sample_catboost.py +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/examples/mlp.json +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/examples/onnx/README.md +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/examples/onnx/generate_demo_models.py +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/examples/onnx/mlp_retrain_a.onnx +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/examples/onnx/mlp_retrain_b.onnx +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/examples/onnx/mlp_v1.onnx +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/examples/onnx/mlp_v2.onnx +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/examples/tiny_attention.json +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/examples/tiny_attention_plan.json +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/src/catboost_deep_diff.py +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/src/catboost_explain.py +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/src/cbm.rs +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/src/demo.rs +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/src/explain.rs +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/src/lgbm.rs +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/src/model.rs +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/src/onnx.rs +0 -0
- {mod_trace-0.3.0 → mod_trace-0.3.2}/src/tensor.rs +0 -0
|
@@ -192,11 +192,15 @@ fn print_doctor_report(report: &DoctorReport) {
|
|
|
192
192
|
println!();
|
|
193
193
|
println!("Available commands:");
|
|
194
194
|
println!(
|
|
195
|
-
" inspect .cbm/.onnx/.json: {}",
|
|
195
|
+
" inspect .cbm/.lgb/.onnx/.json: {}",
|
|
196
196
|
available_unavailable(report.commands.inspect_artifacts)
|
|
197
197
|
);
|
|
198
198
|
println!(
|
|
199
|
-
" diff .cbm/.onnx: {}",
|
|
199
|
+
" diff .cbm/.lgb/.onnx: {}",
|
|
200
|
+
available_unavailable(report.commands.diff_artifacts)
|
|
201
|
+
);
|
|
202
|
+
println!(
|
|
203
|
+
" explain-diff .cbm/.lgb/.onnx: {}",
|
|
200
204
|
available_unavailable(report.commands.diff_artifacts)
|
|
201
205
|
);
|
|
202
206
|
println!(
|
|
@@ -1023,6 +1027,12 @@ fn opt_num(value: Option<usize>) -> String {
|
|
|
1023
1027
|
.unwrap_or_else(|| "unknown".to_string())
|
|
1024
1028
|
}
|
|
1025
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
|
+
|
|
1026
1036
|
fn format_count_human(count: usize) -> String {
|
|
1027
1037
|
let value = count as f64;
|
|
1028
1038
|
if value >= 1e9 {
|
|
@@ -1157,10 +1167,29 @@ fn explain_diff_onnx(old_path: &str, new_path: &str) -> Result<(), String> {
|
|
|
1157
1167
|
Ok(())
|
|
1158
1168
|
}
|
|
1159
1169
|
|
|
1170
|
+
fn same_or_changed(equal: bool) -> &'static str {
|
|
1171
|
+
if equal { "same" } else { "changed" }
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1160
1174
|
fn explain_diff_lgbm(old_path: &str, new_path: &str) -> Result<(), String> {
|
|
1161
1175
|
let old = lgbm::inspect(old_path)?;
|
|
1162
1176
|
let new = lgbm::inspect(new_path)?;
|
|
1163
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
|
+
|
|
1164
1193
|
println!("Model Change Explanation");
|
|
1165
1194
|
println!("------------------------");
|
|
1166
1195
|
println!("Type: LightGBM");
|
|
@@ -1179,17 +1208,60 @@ fn explain_diff_lgbm(old_path: &str, new_path: &str) -> Result<(), String> {
|
|
|
1179
1208
|
opt_num(old.num_leaves.map(|value| value as usize)),
|
|
1180
1209
|
opt_num(new.num_leaves.map(|value| value as usize))
|
|
1181
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
|
+
};
|
|
1182
1218
|
println!(
|
|
1183
|
-
" Features: {} -> {}",
|
|
1219
|
+
" Features: {} -> {} ({})",
|
|
1184
1220
|
opt_num(old.num_features.map(|value| value as usize)),
|
|
1185
|
-
opt_num(new.num_features.map(|value| value as usize))
|
|
1221
|
+
opt_num(new.num_features.map(|value| value as usize)),
|
|
1222
|
+
feature_note
|
|
1186
1223
|
);
|
|
1224
|
+
print_lgbm_feature_list(" added: ", &added, 8);
|
|
1225
|
+
print_lgbm_feature_list(" removed:", &removed, 8);
|
|
1226
|
+
println!();
|
|
1227
|
+
println!("Training config:");
|
|
1187
1228
|
println!(
|
|
1188
|
-
" Objective: {} -> {}",
|
|
1229
|
+
" Objective: {} -> {} ({})",
|
|
1189
1230
|
old.objective.as_deref().unwrap_or("unknown"),
|
|
1190
|
-
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)
|
|
1191
1257
|
);
|
|
1192
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
|
+
);
|
|
1193
1265
|
match (old.estimated_leaf_values(), new.estimated_leaf_values()) {
|
|
1194
1266
|
(Some(o), Some(n)) => println!(
|
|
1195
1267
|
"Estimated leaf-slot growth: {}",
|
|
@@ -1204,11 +1276,52 @@ fn explain_diff_lgbm(old_path: &str, new_path: &str) -> Result<(), String> {
|
|
|
1204
1276
|
println!("Learned state: unchanged (identical leaf values)");
|
|
1205
1277
|
}
|
|
1206
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!();
|
|
1207
1303
|
println!("Note: parsed natively from the LightGBM text model.");
|
|
1208
1304
|
|
|
1209
1305
|
Ok(())
|
|
1210
1306
|
}
|
|
1211
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
|
+
|
|
1212
1325
|
fn explain_diff_catboost(old_path: &str, new_path: &str) -> Result<(), String> {
|
|
1213
1326
|
let old = cbm::inspect(old_path)?;
|
|
1214
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
|