diff --git a/docs/experiment_round34_cert_batch_check.json b/docs/experiment_round34_cert_batch_check.json new file mode 100644 index 0000000..c895f28 --- /dev/null +++ b/docs/experiment_round34_cert_batch_check.json @@ -0,0 +1,71 @@ +{ + "config": { + "ckpt": "ml/runs/base_dag2_dag1/best.pt", + "samples": "ml/data/samples", + "tasks": null, + "split": "val", + "n": 256, + "K": 8, + "commit": 2, + "fb": 2.2, + "ki": 0.0, + "fb_scale": 0.0, + "fb_near": 0.2, + "fb_fallback": 0.0, + "kdecay": 0.9, + "kimax": 0.5, + "fb_every": 1, + "safety_try": 0, + "sel_w": 0.1, + "dls_safety": 1, + "fb_clear": 0.0, + "fb_cmin": 0.3, + "sub_refresh": 0, + "fb_block_gain": 0.5, + "dump": null, + "out": "docs/experiment_round34_cert_batch_check.json", + "trace": null, + "select": "endpoint", + "replan": "empty", + "safety": 1, + "partial": 1, + "inc_cap": 0, + "gap_margin": 0.0, + "cert_batch": 1, + "max_sec": null, + "seed": 0, + "dls": "analytic", + "device": "cuda" + }, + "batch_size": 256, + "batch_seed_rule": "same seed per batch", + "checkpoint_sha256": "f7f686fd8ee92fb6948fbcc4ee954636065ad87bb54f661c4f8f575bc16c2ce1", + "tasks_sha256": "249bd93457825cda98c59e64d9a096d3473c69aeb3553de1dea6d9e56be71772", + "kin_fp": "2ebcbf17", + "act_scale": 1.0, + "metrics": { + "n": 256, + "n_ref": 256, + "success": 0.57421875, + "collision_free_success": 0.57421875, + "time_ok_1p3": 0.390625, + "collision_rate": 0.0, + "collision_steps_mean": 0.0, + "travel_ratio_median": 2.4449527263641357, + "time_mean_s": 2.3076188564300537, + "brakes_mean": 19.25, + "start_fail": 0.0, + "goal_ratio_2s": 0.20997506380081177, + "err_fail_med": 229.68746948242188, + "err_success_med": 0.18899640440940857, + "dls_share": 0.625, + "time_budget": "teacher×2(≥3 s)", + "speed_ratio_p50": 1.6600004434585571, + "speed_ratio_p95": 1.6600035429000854, + "speed_ratio_max": 1.660003662109375, + "over_vmax_rate": 1.0, + "accel_ratio_p95": 1.5835107564926147, + "accel_ratio_max": 1.6600004434585571 + }, + "simulation_wall_s": 306.9490996999957 +} diff --git a/docs/experiment_round34_fused_cycle.json b/docs/experiment_round34_fused_cycle.json new file mode 100644 index 0000000..63b0caa --- /dev/null +++ b/docs/experiment_round34_fused_cycle.json @@ -0,0 +1,629 @@ +{ + "device": "NVIDIA GeForce RTX 3090", + "B": 1, + "K": 8, + "steps": 1, + "reps": 90, + "design": "\u540c\u4e00\u6279 4 \u4e2a\u53d8\u4f53\u9010\u8f6e\u4ea4\u66ff\uff08\u5947\u6570\u8f6e\u53cd\u5e8f\uff09\uff0c\u6d88\u9664 GPU \u65f6\u949f\u6f02\u79fb\uff1b\u539f\u59cb\u8017\u65f6\u5168\u90e8\u843d\u76d8", + "equivalence": { + "features_reuse_bitwise_equal": true, + "gm_groups_vs_full_table_max_abs_mm": 0.0, + "cert_matrix_bitwise_equal_at_same_cap": true, + "shared_xf_cert_bitwise_equal_at_cap1": true, + "max_abs_shared_diff_mm": 0.0, + "max_abs_cert_diff_mm": 0.0, + "decision_equal_by_threshold": { + "thr_0.0": true, + "thr_0.5": true, + "thr_1.0": true + }, + "per_point_min_cur_mm": [ + 8.833421, + 8.849185, + 8.859405, + 8.83829 + ], + "per_point_min_fused_mm": [ + 8.833421, + 8.849185, + 8.859405, + 8.83829 + ] + }, + "results": { + "current_discrete": { + "p50": 32.932, + "p95": 42.589, + "p99": 55.568, + "max": 55.568, + "hz_p50": 30.4, + "raw_ms": [ + 30.458, + 30.624, + 30.789, + 31.17, + 31.229, + 31.283, + 31.371, + 31.394, + 31.454, + 31.473, + 31.564, + 31.58, + 31.719, + 31.772, + 31.78, + 31.785, + 31.859, + 31.875, + 31.906, + 31.973, + 31.979, + 32.002, + 32.017, + 32.063, + 32.099, + 32.113, + 32.123, + 32.127, + 32.13, + 32.137, + 32.191, + 32.286, + 32.308, + 32.324, + 32.33, + 32.388, + 32.48, + 32.508, + 32.564, + 32.63, + 32.64, + 32.702, + 32.78, + 32.822, + 32.834, + 32.932, + 32.964, + 32.975, + 32.996, + 33.071, + 33.163, + 33.191, + 33.192, + 33.402, + 33.477, + 33.509, + 33.583, + 33.956, + 34.014, + 34.04, + 34.047, + 34.047, + 34.154, + 34.302, + 34.595, + 34.658, + 34.943, + 35.296, + 35.522, + 35.67, + 35.757, + 35.828, + 35.859, + 36.459, + 36.503, + 36.562, + 36.956, + 37.047, + 37.067, + 37.142, + 37.442, + 38.632, + 39.285, + 41.269, + 41.932, + 42.589, + 43.199, + 43.329, + 54.407, + 55.568 + ] + }, + "fused_discrete": { + "p50": 24.515, + "p95": 30.02, + "p99": 42.085, + "max": 42.085, + "hz_p50": 40.8, + "raw_ms": [ + 22.146, + 22.266, + 22.409, + 22.653, + 22.66, + 22.695, + 22.76, + 22.827, + 22.848, + 23.001, + 23.033, + 23.087, + 23.249, + 23.36, + 23.488, + 23.573, + 23.607, + 23.625, + 23.649, + 23.651, + 23.652, + 23.652, + 23.656, + 23.676, + 23.716, + 23.737, + 23.745, + 23.795, + 23.871, + 23.883, + 23.92, + 23.922, + 23.945, + 23.959, + 24.046, + 24.13, + 24.184, + 24.282, + 24.291, + 24.313, + 24.318, + 24.319, + 24.32, + 24.34, + 24.399, + 24.515, + 24.532, + 24.541, + 24.552, + 24.592, + 24.618, + 24.731, + 24.741, + 24.745, + 24.766, + 24.807, + 24.813, + 24.898, + 25.066, + 25.088, + 25.137, + 25.18, + 25.223, + 25.376, + 25.474, + 25.603, + 25.68, + 25.744, + 25.82, + 25.936, + 25.95, + 25.953, + 26.002, + 26.174, + 26.312, + 26.88, + 27.036, + 27.209, + 27.329, + 27.424, + 27.715, + 28.796, + 28.824, + 29.427, + 29.662, + 30.02, + 31.515, + 31.839, + 36.18, + 42.085 + ] + }, + "shared_xf_discrete": { + "p50": 26.864, + "p95": 34.544, + "p99": 67.243, + "max": 67.243, + "hz_p50": 37.2, + "raw_ms": [ + 24.433, + 24.441, + 24.585, + 24.777, + 24.862, + 24.935, + 25.054, + 25.08, + 25.105, + 25.193, + 25.313, + 25.44, + 25.466, + 25.483, + 25.516, + 25.554, + 25.577, + 25.689, + 25.702, + 25.708, + 25.854, + 25.896, + 25.898, + 26.011, + 26.097, + 26.175, + 26.255, + 26.289, + 26.297, + 26.306, + 26.328, + 26.336, + 26.346, + 26.375, + 26.397, + 26.456, + 26.502, + 26.523, + 26.563, + 26.613, + 26.634, + 26.658, + 26.708, + 26.752, + 26.798, + 26.864, + 26.869, + 26.874, + 27.315, + 27.341, + 27.668, + 27.67, + 27.732, + 27.774, + 27.812, + 27.84, + 27.882, + 27.921, + 28.24, + 28.302, + 28.421, + 28.694, + 28.722, + 28.739, + 28.817, + 28.914, + 28.944, + 28.998, + 29.12, + 29.122, + 29.259, + 29.292, + 29.334, + 29.658, + 29.847, + 30.181, + 30.206, + 30.292, + 30.492, + 30.782, + 31.168, + 31.222, + 31.607, + 31.614, + 32.187, + 34.544, + 35.274, + 35.565, + 35.915, + 67.243 + ] + }, + "current_cert_n8": { + "p50": 42.624, + "p95": 49.434, + "p99": 57.771, + "max": 57.771, + "hz_p50": 23.5, + "raw_ms": [ + 38.546, + 38.666, + 39.152, + 39.265, + 39.344, + 39.441, + 39.584, + 39.626, + 39.738, + 39.841, + 40.228, + 40.306, + 40.514, + 40.805, + 40.838, + 40.875, + 40.884, + 40.907, + 40.952, + 40.971, + 41.185, + 41.193, + 41.193, + 41.277, + 41.279, + 41.422, + 41.448, + 41.463, + 41.465, + 41.473, + 41.504, + 41.551, + 41.684, + 41.733, + 41.841, + 41.947, + 41.967, + 42.011, + 42.077, + 42.241, + 42.249, + 42.269, + 42.301, + 42.314, + 42.388, + 42.624, + 42.661, + 42.767, + 42.773, + 42.837, + 42.865, + 42.87, + 42.913, + 43.343, + 43.35, + 43.356, + 43.376, + 43.501, + 43.695, + 43.708, + 43.842, + 43.923, + 43.972, + 44.243, + 44.476, + 44.536, + 44.648, + 44.745, + 44.894, + 45.034, + 45.144, + 45.236, + 45.697, + 45.859, + 45.944, + 46.039, + 46.126, + 46.467, + 46.575, + 46.887, + 46.983, + 47.234, + 47.621, + 47.685, + 48.547, + 49.434, + 49.683, + 50.646, + 54.754, + 57.771 + ] + }, + "fused_cert_n8": { + "p50": 24.826, + "p95": 31.721, + "p99": 49.398, + "max": 49.398, + "hz_p50": 40.3, + "raw_ms": [ + 22.127, + 22.553, + 22.598, + 22.624, + 22.789, + 22.798, + 22.878, + 22.983, + 23.002, + 23.134, + 23.192, + 23.273, + 23.323, + 23.345, + 23.377, + 23.445, + 23.466, + 23.549, + 23.611, + 23.613, + 23.861, + 23.868, + 23.885, + 23.885, + 23.906, + 23.918, + 23.919, + 23.933, + 23.947, + 24.052, + 24.064, + 24.067, + 24.08, + 24.103, + 24.13, + 24.164, + 24.249, + 24.301, + 24.429, + 24.515, + 24.603, + 24.609, + 24.7, + 24.748, + 24.812, + 24.826, + 24.855, + 24.858, + 24.954, + 24.99, + 25.052, + 25.097, + 25.195, + 25.209, + 25.241, + 25.252, + 25.264, + 25.298, + 25.63, + 25.659, + 25.767, + 25.804, + 25.928, + 25.976, + 26.494, + 26.871, + 26.886, + 26.988, + 26.995, + 27.004, + 27.307, + 27.322, + 27.352, + 27.937, + 28.144, + 28.165, + 28.216, + 28.288, + 28.331, + 29.37, + 29.611, + 30.6, + 30.704, + 31.026, + 31.552, + 31.721, + 32.875, + 34.001, + 40.223, + 49.398 + ] + }, + "shared_xf_cert_n8": { + "p50": 36.185, + "p95": 41.136, + "p99": 64.287, + "max": 64.287, + "hz_p50": 27.6, + "raw_ms": [ + 33.051, + 33.153, + 33.201, + 33.406, + 33.819, + 33.845, + 33.94, + 34.083, + 34.145, + 34.235, + 34.3, + 34.372, + 34.605, + 34.697, + 34.714, + 34.755, + 34.817, + 34.855, + 34.925, + 34.957, + 34.963, + 34.967, + 34.986, + 35.167, + 35.239, + 35.314, + 35.325, + 35.402, + 35.444, + 35.518, + 35.544, + 35.582, + 35.594, + 35.662, + 35.675, + 35.724, + 35.775, + 35.874, + 35.908, + 35.929, + 35.965, + 36.019, + 36.04, + 36.126, + 36.164, + 36.185, + 36.2, + 36.259, + 36.263, + 36.266, + 36.301, + 36.324, + 36.383, + 36.393, + 36.609, + 36.667, + 36.696, + 36.779, + 36.799, + 36.836, + 36.881, + 36.978, + 37.001, + 37.033, + 37.043, + 37.078, + 37.183, + 37.206, + 37.278, + 37.3, + 37.411, + 37.485, + 37.722, + 37.923, + 37.965, + 38.197, + 38.588, + 38.871, + 39.082, + 39.099, + 39.135, + 39.351, + 39.505, + 40.204, + 40.892, + 41.136, + 41.449, + 42.611, + 44.687, + 64.287 + ] + } + } +} \ No newline at end of file diff --git a/docs/experiment_round34_geom_opt.json b/docs/experiment_round34_geom_opt.json new file mode 100644 index 0000000..12d238e --- /dev/null +++ b/docs/experiment_round34_geom_opt.json @@ -0,0 +1,630 @@ +{ + "device": "NVIDIA GeForce RTX 3090", + "B": 1, + "K": 8, + "commit_n": 2, + "reps": 80, + "design": "5 \u4e2a\u53d8\u4f53\u9010\u8f6e\u4ea4\u66ff\uff08\u5947\u6570\u8f6e\u53cd\u5e8f\uff09\uff1b\u53ea\u6d4b\u53ef\u5b9e\u73b0\u7684\u53e3\u5f84\uff1a\u7279\u5f81/\u63a8\u7406/\u8ba4\u8bc1\u6309\u771f\u5b9e\u987a\u5e8f", + "equivalence": { + "batch_cert_matrix_equal_to_loop": true, + "features_xf_reuse_bitwise_equal": true + }, + "results": { + "A_today": { + "p50": 33.494, + "p95": 46.143, + "p99": 64.693, + "max": 64.693, + "raw_ms": [ + 28.984, + 29.251, + 29.361, + 29.549, + 29.899, + 29.944, + 30.181, + 30.605, + 30.624, + 30.744, + 30.815, + 30.838, + 30.862, + 30.9, + 31.024, + 31.092, + 31.115, + 31.262, + 31.433, + 31.463, + 31.52, + 31.572, + 31.642, + 31.741, + 31.871, + 31.902, + 31.924, + 31.933, + 31.976, + 32.001, + 32.03, + 32.06, + 32.285, + 32.384, + 32.624, + 32.825, + 32.919, + 33.063, + 33.168, + 33.197, + 33.494, + 33.589, + 33.624, + 33.632, + 33.666, + 33.708, + 33.727, + 33.735, + 33.754, + 33.773, + 33.869, + 33.907, + 34.116, + 34.219, + 34.314, + 34.337, + 34.897, + 34.957, + 35.436, + 35.469, + 35.999, + 36.106, + 36.523, + 36.559, + 36.846, + 36.866, + 36.922, + 37.354, + 37.375, + 37.581, + 37.933, + 38.026, + 40.541, + 40.882, + 44.161, + 44.233, + 46.143, + 54.047, + 58.36, + 64.693 + ] + }, + "B_xf_reuse": { + "p50": 30.122, + "p95": 42.349, + "p99": 66.368, + "max": 66.368, + "raw_ms": [ + 26.698, + 26.958, + 26.984, + 27.007, + 27.018, + 27.158, + 27.308, + 27.369, + 27.987, + 28.066, + 28.219, + 28.288, + 28.362, + 28.517, + 28.537, + 28.539, + 28.593, + 28.611, + 28.638, + 28.735, + 28.828, + 28.871, + 28.922, + 28.945, + 28.978, + 29.088, + 29.202, + 29.226, + 29.226, + 29.31, + 29.497, + 29.506, + 29.531, + 29.549, + 29.649, + 29.875, + 29.978, + 29.992, + 30.025, + 30.102, + 30.122, + 30.243, + 30.245, + 30.263, + 30.407, + 30.578, + 30.665, + 30.717, + 30.863, + 30.884, + 30.889, + 30.95, + 31.023, + 31.314, + 31.525, + 31.537, + 31.543, + 31.549, + 31.62, + 32.011, + 32.098, + 32.168, + 32.188, + 32.22, + 32.578, + 32.818, + 32.851, + 32.929, + 32.991, + 33.76, + 33.805, + 33.831, + 33.94, + 34.124, + 34.891, + 39.001, + 42.349, + 43.636, + 62.045, + 66.368 + ] + }, + "C_batch_cert": { + "p50": 38.048, + "p95": 50.171, + "p99": 59.86, + "max": 59.86, + "raw_ms": [ + 33.625, + 33.736, + 33.848, + 34.235, + 34.49, + 34.917, + 34.918, + 35.108, + 35.407, + 35.919, + 36.023, + 36.035, + 36.087, + 36.263, + 36.318, + 36.531, + 36.627, + 36.638, + 36.722, + 36.778, + 36.791, + 36.801, + 36.816, + 36.859, + 36.97, + 36.998, + 37.029, + 37.055, + 37.057, + 37.093, + 37.208, + 37.318, + 37.408, + 37.438, + 37.463, + 37.501, + 37.503, + 37.605, + 37.63, + 37.984, + 38.048, + 38.283, + 38.347, + 38.524, + 38.547, + 38.667, + 38.816, + 38.995, + 39.028, + 39.34, + 39.617, + 39.679, + 39.845, + 39.852, + 39.871, + 39.894, + 39.923, + 40.195, + 40.514, + 41.421, + 41.684, + 41.804, + 41.879, + 41.933, + 42.011, + 42.127, + 42.483, + 42.551, + 42.656, + 43.038, + 43.248, + 43.269, + 45.68, + 46.514, + 46.755, + 48.909, + 50.171, + 50.906, + 55.33, + 59.86 + ] + }, + "D_both": { + "p50": 34.87, + "p95": 39.811, + "p99": 48.258, + "max": 48.258, + "raw_ms": [ + 30.044, + 30.934, + 31.005, + 31.007, + 31.064, + 31.492, + 31.675, + 31.758, + 32.114, + 32.153, + 32.338, + 32.374, + 32.442, + 32.494, + 32.681, + 32.882, + 32.942, + 32.991, + 33.167, + 33.18, + 33.302, + 33.305, + 33.342, + 33.449, + 33.58, + 33.694, + 33.739, + 33.784, + 33.832, + 33.835, + 33.866, + 33.961, + 34.037, + 34.135, + 34.315, + 34.395, + 34.465, + 34.556, + 34.656, + 34.819, + 34.87, + 34.98, + 35.047, + 35.176, + 35.19, + 35.37, + 35.461, + 35.528, + 35.557, + 35.59, + 35.643, + 35.716, + 35.742, + 35.804, + 35.991, + 36.018, + 36.063, + 36.105, + 36.293, + 36.312, + 36.326, + 36.537, + 36.541, + 36.602, + 36.717, + 36.934, + 36.945, + 37.088, + 37.141, + 37.46, + 37.561, + 37.608, + 37.765, + 37.904, + 37.974, + 39.253, + 39.811, + 40.076, + 46.504, + 48.258 + ] + }, + "E_both_cont_n8": { + "p50": 43.725, + "p95": 51.084, + "p99": 65.681, + "max": 65.681, + "raw_ms": [ + 37.733, + 39.087, + 39.154, + 39.238, + 39.36, + 39.454, + 39.514, + 40.167, + 40.44, + 40.837, + 40.86, + 40.868, + 41.237, + 41.276, + 41.346, + 41.408, + 41.551, + 41.815, + 41.824, + 41.912, + 41.932, + 41.973, + 42.074, + 42.296, + 42.341, + 42.365, + 42.435, + 42.505, + 42.592, + 42.598, + 42.637, + 42.85, + 43.045, + 43.048, + 43.18, + 43.209, + 43.359, + 43.361, + 43.373, + 43.411, + 43.725, + 43.728, + 43.787, + 43.833, + 43.985, + 44.133, + 44.185, + 44.401, + 44.458, + 44.585, + 44.689, + 44.819, + 44.841, + 44.86, + 45.081, + 45.087, + 45.55, + 45.701, + 45.939, + 46.06, + 46.128, + 46.264, + 46.368, + 46.43, + 46.957, + 47.145, + 47.231, + 47.256, + 47.463, + 47.637, + 47.819, + 47.863, + 48.382, + 48.87, + 49.676, + 50.884, + 51.084, + 51.17, + 53.859, + 65.681 + ] + }, + "F_worst_loop8": { + "p50": 80.224, + "p95": 88.436, + "p99": 89.553, + "max": 89.553, + "raw_ms": [ + 67.204, + 70.008, + 70.436, + 71.432, + 72.454, + 72.503, + 73.006, + 73.12, + 73.492, + 73.971, + 74.203, + 74.358, + 74.756, + 74.816, + 74.893, + 75.536, + 75.98, + 76.049, + 76.164, + 76.25, + 76.547, + 76.669, + 76.843, + 77.268, + 77.534, + 77.658, + 77.872, + 78.149, + 78.343, + 78.377, + 78.445, + 78.483, + 78.86, + 78.863, + 78.905, + 79.048, + 79.315, + 79.857, + 80.035, + 80.041, + 80.224, + 80.602, + 80.644, + 80.677, + 80.848, + 81.061, + 81.094, + 81.155, + 81.243, + 81.384, + 81.628, + 81.679, + 81.75, + 82.117, + 82.148, + 82.363, + 82.444, + 82.511, + 82.651, + 82.828, + 82.921, + 83.371, + 83.592, + 83.894, + 83.926, + 84.386, + 84.519, + 84.608, + 85.06, + 85.078, + 85.094, + 85.26, + 87.212, + 87.744, + 87.847, + 88.098, + 88.436, + 88.461, + 88.919, + 89.553 + ] + }, + "G_worst_batch": { + "p50": 37.139, + "p95": 46.06, + "p99": 52.215, + "max": 52.215, + "raw_ms": [ + 32.718, + 33.447, + 33.569, + 33.692, + 33.81, + 34.236, + 34.28, + 34.475, + 34.496, + 34.746, + 35.19, + 35.392, + 35.435, + 35.564, + 35.569, + 35.669, + 35.693, + 35.734, + 35.741, + 35.812, + 35.828, + 35.934, + 36.015, + 36.036, + 36.097, + 36.144, + 36.197, + 36.205, + 36.487, + 36.637, + 36.71, + 36.775, + 36.79, + 36.83, + 36.831, + 36.885, + 36.894, + 36.903, + 36.947, + 37.122, + 37.139, + 37.154, + 37.198, + 37.225, + 37.249, + 37.478, + 37.615, + 37.617, + 38.114, + 38.164, + 38.288, + 38.637, + 38.651, + 38.724, + 38.813, + 39.108, + 39.15, + 39.848, + 39.866, + 39.946, + 39.969, + 39.992, + 40.04, + 40.28, + 40.35, + 40.697, + 40.727, + 40.893, + 40.972, + 41.029, + 41.138, + 41.479, + 41.51, + 41.711, + 45.036, + 45.784, + 46.06, + 48.597, + 50.186, + 52.215 + ] + } + } +} \ No newline at end of file diff --git a/docs/experiment_round34_xf_reuse_check.json b/docs/experiment_round34_xf_reuse_check.json new file mode 100644 index 0000000..ade9ed2 --- /dev/null +++ b/docs/experiment_round34_xf_reuse_check.json @@ -0,0 +1,70 @@ +{ + "config": { + "ckpt": "ml/runs/base_dag2_dag1/best.pt", + "samples": "ml/data/samples", + "tasks": null, + "split": "val", + "n": 256, + "K": 8, + "commit": 2, + "fb": 2.2, + "ki": 0.0, + "fb_scale": 0.0, + "fb_near": 0.2, + "fb_fallback": 0.0, + "kdecay": 0.9, + "kimax": 0.5, + "fb_every": 1, + "safety_try": 0, + "sel_w": 0.1, + "dls_safety": 1, + "fb_clear": 0.0, + "fb_cmin": 0.3, + "sub_refresh": 0, + "fb_block_gain": 0.5, + "dump": null, + "out": "docs/experiment_round34_xf_reuse_check.json", + "trace": null, + "select": "endpoint", + "replan": "empty", + "safety": 1, + "partial": 1, + "inc_cap": 0, + "gap_margin": 0.0, + "max_sec": null, + "seed": 0, + "dls": "analytic", + "device": "cuda" + }, + "batch_size": 256, + "batch_seed_rule": "same seed per batch", + "checkpoint_sha256": "f7f686fd8ee92fb6948fbcc4ee954636065ad87bb54f661c4f8f575bc16c2ce1", + "tasks_sha256": "249bd93457825cda98c59e64d9a096d3473c69aeb3553de1dea6d9e56be71772", + "kin_fp": "2ebcbf17", + "act_scale": 1.0, + "metrics": { + "n": 256, + "n_ref": 256, + "success": 0.57421875, + "collision_free_success": 0.57421875, + "time_ok_1p3": 0.390625, + "collision_rate": 0.0, + "collision_steps_mean": 0.0, + "travel_ratio_median": 2.4449527263641357, + "time_mean_s": 2.3076188564300537, + "brakes_mean": 19.25, + "start_fail": 0.0, + "goal_ratio_2s": 0.20997506380081177, + "err_fail_med": 229.68746948242188, + "err_success_med": 0.18899640440940857, + "dls_share": 0.625, + "time_budget": "teacher×2(≥3 s)", + "speed_ratio_p50": 1.6600004434585571, + "speed_ratio_p95": 1.6600035429000854, + "speed_ratio_max": 1.660003662109375, + "over_vmax_rate": 1.0, + "accel_ratio_p95": 1.5835107564926147, + "accel_ratio_max": 1.6600004434585571 + }, + "simulation_wall_s": 317.96790459999465 +} diff --git a/docs/探索日志.md b/docs/探索日志.md index f38458b..21002ba 100644 --- a/docs/探索日志.md +++ b/docs/探索日志.md @@ -694,6 +694,33 @@ - **50 Hz 结论(当前状态)**:真实配方一个规划周期 **36.7 ms(P99 49.2)≈ 27 Hz**,仍不满足"P99<20 ms";且必须记住这是在**不限幅**(可超速 1.66×)的策略分布下测的——限幅后的到达率代价见上表,两者不能混着谈。 - f32 与 f64 的间隙在 3 个点上完全相同(最大偏差 0.0 mm、无符号翻转),但 **3 个点不足以支持"认证可以改用 float32"**,需按真实轨迹批量对比才能下结论。 +## 轮次 34:GPU 周期的可实现优化——复用 FK 与压认证最坏情况(exp: `exp/dagger-deploy`) + +- **起因与一次自我撤回**:轮次 33 记下"合并几何查询看能不能进 20 ms"后,先按 `docs/experiment_round34_fused_cycle.json` 测出"整周期 41.9→24.5 ms"。这个数**作废**,两个独立原因: + 1. 第一版的"合并"把 `xf=` 传给了包含 5 行的 `gaps` 调用,而 `gaps` 的 `xf` 是按行对应的 → 只有第 0 行走完宽相位,认证点 4 行全部退回截顶值 40.0 mm,即**少干了活**(表现为认证矩阵差 31.17 mm)。修好后同一 cap 下矩阵逐位一致(差 0.0 mm)。 + 2. 更根本:真实管线顺序是 特征 → 推理 → 候选 → 认证,**认证点依赖网络输出**,所以"特征用的 q 间隙与认证点间隙合成同一次调用"在实现上做不到。该文件保留作记录,但不能当作可实现收益。 +- **只测可实现的口径**(`docs/experiment_round34_geom_opt.json`;B=1、K=8、commit 2;7 个变体逐轮交替、奇数轮反序,80 轮;等价性两项都 `True`:批量认证矩阵与逐条循环逐位一致、features 复用 xf 前后逐位一致): + + | 变体 | 含义 | P50 | P95 | P99 | + |---|---|---|---|---| + | A_today | 现口径 | 33.49 | 46.14 | 64.69 | + | B_xf_reuse | `gm_groups` 复用 features 已算的 `cum_xf` | **30.12** | 42.35 | 66.37 | + | C_batch_cert | K 条候选的认证点并成 1 次 gaps | 38.05 | 50.17 | 59.86 | + | D_both | B + C | 34.87 | 39.81 | 48.26 | + | E_both_cont_n8 | B + C + 连续认证 n=8 | 43.73 | 51.08 | 65.68 | + | F_worst_loop8 | **最坏情况**:所有候选被拒(今天逐条串行 K 次调用) | 80.22 | 88.44 | 89.55 | + | G_worst_batch | 同一最坏情况但并成 1 次调用 | **37.14** | 46.06 | 52.22 | + + - **复用 FK 是无条件收益**:省一次 `cum_xf`(约 3.4–3.7 ms),特征输出逐位一致,已直接实现进 `ml/common/kin_torch.py` 的 `gm_groups(..., xf=)` 与 `ml/common/features.py`(默认行为不变,新参数仅在调用方已算过 xf 时传)。 + - **批量认证是"典型换尾部"**:常见路径(第一条候选就通过)贵 4.6 ms;但今天一旦前面的候选被拒就要串行调用,实测最坏 **80.2 ms(12.5 Hz)→ 37.1 ms**,P99 64.7→48.3 ms(D vs A)。硬实时看的是最坏情况,所以这条值得做,但要按"典型略变慢、尾部大幅变稳"来汇报,不能只报 P50。 + - **仍未到 20 ms**:即便 D 档 P50 34.9 ms、P99 48.3 ms。连续认证挂在 D 上是 43.7 ms(E)。所以 GPU 侧下一步只能是更结构性的:认证降 float32(需先批量量化 f32/f64 判据差异,不能凭 3 个点下结论)、把宽相位做成可增量复用的核、或 `torch.compile`/CUDA Graph 把碎 kernel 合批。 +- **等价性闸门(纯效率改动不许改变任何结果)**: + - 复用 FK:同一 256 题、同 seed、同配方重跑(`docs/experiment_round34_xf_reuse_check.json`),**22 个指标逐项与轮次 33 base 完全相同**(含 success 0.57421875、time_ok 0.390625、brakes 19.25、speed_ratio_max 1.660003662 等)。整批墙钟 296.3 → 318.0 s,是两次独立运行的差,**不能当作开销结论**:省下的那次 `cum_xf` 只在 B=1 交错实测里量到 −3.4 ms,批量评估里一次调用已覆盖 256 行,摊薄后不足以抵消运行间波动。 + - 批量认证(`--cert_batch 1`,默认 0 不变):同一 256 题重跑 **22 项指标与 base 逐项相同**(`docs/experiment_round34_cert_batch_check.json`,success 0.57421875、time_ok 0.390625、speed_ratio_max 1.660003662 等全部一致),整批墙钟 296.3 → 306.9 s(批量口径把 8 次串行调用换成 1 次 K×256 点的大调用,均值略涨符合预期,与 B=1 交错实测方向一致)。合成夹具里也断言两条路径选到同一条候选、同一前缀长度、逐位相同的轨迹与证书。 +- **测试 32→34 项**:`CertBatchEquivalenceTest` 两条(候选 0 前缀不完整 → 选候选 1;所有候选第 2 步都不安全 → 两条路径都停在第 1 步)。写夹具时踩到一个自己的坑:桩里掩码写成 `q[:, :1]` 再 `[:, None]` 变成 3 维,广播出 (4,4,49) 才报"size 16",是**测试桩错**不是库错——先证形状再改代码。 + +## 分支清理(2026-10-20) + ## 分支清理(2026-10-20) - `feat/fb-mix`(8e5431c):反馈混合方案的中间分支,**已验证是 `exp/dagger-deploy` 的祖先**(所有提交都在后者历史里),本地/远端分支删除,内容保留在 exp/dagger-deploy。 diff --git a/ml/common/features.py b/ml/common/features.py index 25e58d8..051e0bd 100644 --- a/ml/common/features.py +++ b/ml/common/features.py @@ -52,7 +52,7 @@ def features(kin, q, q_prev, T, R, prefix, prefix_len, sub, sub_flag, gm=None, x out.append(sd) out.append(sub_flag[:, None].to(dt)) if gm is None: - out.append(kin.gm_groups(q, GP, GAP_CAP) / GAP_CAP) # 2026-10-20:只算特征用到的 8 组 + out.append(kin.gm_groups(q, GP, GAP_CAP, xf=xf) / GAP_CAP) # 2026-10-20:只算特征用到的 8 组;xf 复用不重复算 FK gm = None if gm is not None: out.append(torch.stack([gm[:, a * 7 + b].clamp(max=GAP_CAP) / GAP_CAP for a, b in GP], -1)) diff --git a/ml/common/kin_torch.py b/ml/common/kin_torch.py index 205a6a9..da8f414 100644 --- a/ml/common/kin_torch.py +++ b/ml/common/kin_torch.py @@ -235,9 +235,10 @@ class Kin: if not pairs: return {'gm': gm.view(B, 49)} return {'gm': gm.view(B, 49), 'b': rep_b, 'i': pi, 'j': pj, 'gap': gap} - def gm_groups(self, q, gp, cap=40.0): + def gm_groups(self, q, gp, cap=40.0, xf=None): """只算指定组对 gp=[(a,b),...] 的最小间隙 [B,len(gp)](特征用,避免 49 组全量)。 - 数值与 gaps(q,cap)['gm'][:, a*7+b] 一致;组对在碰撞粗对里不存在时返回 cap。""" + 数值与 gaps(q,cap)['gm'][:, a*7+b] 一致;组对在碰撞粗对里不存在时返回 cap。 + xf 可传入调用者已算好的 cum_xf(q),避免同一姿态重复算 FK(特征路径每周期省一次)。""" key = tuple(gp) if getattr(self, '_gp_key', None) != key: m = torch.full((49,), -1, dtype=torch.long, device=q.device) @@ -247,7 +248,7 @@ class Kin: sel = torch.isin(cg, torch.tensor([min(a, b) * 7 + max(a, b) for a, b in gp], device=q.device)) self._gp = (m, sel, sel.nonzero(as_tuple=True)[0]); self._gp_key = key self._gp49, sel, idx = self._gp - xf = self.cum_xf(q); Rs, Ts = xf; B = q.shape[0] + xf = xf if xf is not None else self.cum_xf(q); Rs, Ts = xf; B = q.shape[0] with torch.no_grad(): cc = torch.einsum('bkij,kj->bki', Rs[:, self.cl_g], self.cl_c.to(q.dtype)) + Ts[:, self.cl_g] d2 = (cc[:, self.cp_a[idx]] - cc[:, self.cp_b[idx]]).pow(2).sum(-1) diff --git a/ml/eval/eval_cl.py b/ml/eval/eval_cl.py index d944610..0815845 100644 --- a/ml/eval/eval_cl.py +++ b/ml/eval/eval_cl.py @@ -92,6 +92,7 @@ def main(): ap.add_argument('--partial', type=int, default=1) ap.add_argument('--inc_cap', type=int, default=0, help='1=反馈叠加后再按每轴 VMAX·DT 限幅') ap.add_argument('--gap_margin', type=float, default=0.0, help='安全层要求的间隙余量 mm(>0 时宽相位 cap 自动抬到 margin+0.5)') + ap.add_argument('--cert_batch', type=int, default=0, help='1=一次 gaps 调用覆盖全部候选(压最坏情况,典型路径略贵)') ap.add_argument('--max_sec', type=float, default=None) ap.add_argument('--seed', type=int, default=0) ap.add_argument('--dls', default='analytic', choices=['analytic', 'fd']) @@ -118,7 +119,7 @@ def main(): safety_partial=(a.commit if (a.safety and a.partial) else 0), commit_n=a.commit, select=a.select, replan=a.replan, fb_gain=a.fb, fb_scale=a.fb_scale, fb_near=a.fb_near, fb_fallback=a.fb_fallback, fb_ki=a.ki, fb_decay=a.kdecay, fb_imax=a.kimax, fb_every=a.fb_every, safety_try=a.safety_try, sel_w=a.sel_w, dls_safety=a.dls_safety, fb_clear=a.fb_clear, fb_cmin=a.fb_cmin, sub_refresh=a.sub_refresh, fb_block_gain=a.fb_block_gain, - inc_cap=a.inc_cap, gap_margin=a.gap_margin, return_traj=bool(a.trace)) + inc_cap=a.inc_cap, gap_margin=a.gap_margin, cert_batch=a.cert_batch, return_traj=bool(a.trace)) wall = time.perf_counter() - t0 result = {**meta, 'metrics': r, 'simulation_wall_s': wall} print(json.dumps(json_finite(result), ensure_ascii=False, allow_nan=False), flush=True) diff --git a/ml/sim/closed_loop.py b/ml/sim/closed_loop.py index 62ae7ed..1d09af4 100644 --- a/ml/sim/closed_loop.py +++ b/ml/sim/closed_loop.py @@ -163,7 +163,7 @@ def rollout(model, kin, tasks, device, K=8, safety=False, seed=0, max_sec=None, qp0=None, steps=1, z_scale=1.0, select='consist', oracle=None, replan='r3', sub_rule='cross', fb_gain=0.0, fb_scale=0.0, fb_near=0.2, fb_fallback=0.0, safety_partial=0, commit_n=3, collect=None, fb_exec=0.0, exec_safety=0, fb_ki=0.0, fb_decay=0.9, fb_imax=0.5, fb_every=1, safety_try=0, sel_w=0.1, dls_safety=0, fb_clear=0.0, fb_cmin=0.3, sub_refresh=0, fb_block_gain=1.0, - inc_cap=0, gap_margin=0.0, progress=None): + inc_cap=0, gap_margin=0.0, cert_batch=0, progress=None): """use_sub=False:不用子目标(sf=0);sub_override=(subs [B,M,6] 绝对关节角, n [B] 个数 或 need [B] bool):冷启动时用给定途经点代替子目标头; qp0 [B,6]:起点的上一帧(默认 = q0,即静止起步)。steps:MeanFlow 采样段数;z_scale:噪声缩放; select:consist(部署口径:冷启动价值前瞻、之后与上一条已提交计划的一致性)/ value(每次都价值前瞻)/ first(不选,取第 0 条)。 @@ -329,22 +329,37 @@ def rollout(model, kin, tasks, device, K=8, safety=False, seed=0, max_sec=None, maxlen = torch.zeros(B, dtype=torch.long, device=device) chosen = torch.zeros(B, commit_n, 6, device=device); chosen_k = pick.clone() ntry = min(K_eff, safety_try) if safety_try > 0 else K_eff - for kk in range(ntry): - ck = inc[ar, order[:, kk], r:r + commit_n] - pts, mids = execution_points(kin, qe, ck) - allq = torch.cat([pts, mids], 1).reshape(-1, 6) - gaps6 = kin.gaps(allq, gcap)['gm'].min(-1).values.view(B, 2 * commit_n) - ok6 = gaps6 > gap_margin - okstep = ok6[:, :commit_n] & ok6[:, commit_n:] - plen = torch.cumprod(okstep.long(), 1).sum(1) - take = plen > maxlen - chosen = torch.where(take[:, None, None], ck, chosen); chosen_k = torch.where(take, order[:, kk], chosen_k) + if cert_batch: # 一次 gaps 覆盖全部候选:典型路径略贵,但把「前面候选被拒→串行调用 K 次」的最坏情况封成 1 次 + cks = inc[ar[:, None], order[:, :ntry], r:r + commit_n].reshape(B * ntry, commit_n, 6) + pts, mids = execution_points(kin, qe.repeat_interleave(ntry, 0), cks) + gaps6 = kin.gaps(torch.cat([pts, mids], 1).reshape(-1, 6), gcap)['gm'].min(-1).values.view(B, ntry, 2 * commit_n) + plen = torch.cumprod(((gaps6 > gap_margin)[:, :, :commit_n] & + (gaps6 > gap_margin)[:, :, commit_n:]).long(), -1).sum(-1) + maxlen = plen.max(-1).values + best = plen.argmax(-1) # 与串行同口径:严格更大者胜 ⇒ 首个最大值 + chosen = cks.view(B, ntry, commit_n, 6)[ar, best] + chosen_k = order[ar, best] if return_traj: - cert_pts = torch.where(take[:, None, None], pts, cert_pts) - cert_mids = torch.where(take[:, None, None], mids, cert_mids) - cert_gaps = torch.where(take[:, None], gaps6, cert_gaps) - maxlen = torch.maximum(maxlen, plen) - if B == 1 and int(maxlen[0]) >= commit_n: break # 实时单题:首个全安全候选即停(安全层 16 点→2-4 点) + cert_pts = pts.view(B, ntry, commit_n, 6)[ar, best] + cert_mids = mids.view(B, ntry, commit_n, 6)[ar, best] + cert_gaps = gaps6[ar, best] + else: + for kk in range(ntry): + ck = inc[ar, order[:, kk], r:r + commit_n] + pts, mids = execution_points(kin, qe, ck) + allq = torch.cat([pts, mids], 1).reshape(-1, 6) + gaps6 = kin.gaps(allq, gcap)['gm'].min(-1).values.view(B, 2 * commit_n) + ok6 = gaps6 > gap_margin + okstep = ok6[:, :commit_n] & ok6[:, commit_n:] + plen = torch.cumprod(okstep.long(), 1).sum(1) + take = plen > maxlen + chosen = torch.where(take[:, None, None], ck, chosen); chosen_k = torch.where(take, order[:, kk], chosen_k) + if return_traj: + cert_pts = torch.where(take[:, None, None], pts, cert_pts) + cert_mids = torch.where(take[:, None, None], mids, cert_mids) + cert_gaps = torch.where(take[:, None], gaps6, cert_gaps) + maxlen = torch.maximum(maxlen, plen) + if B == 1 and int(maxlen[0]) >= commit_n: break # 实时单题:首个全安全候选即停(安全层 16 点→2-4 点) msk = (torch.arange(commit_n, device=device)[None] < maxlen[:, None]) commit = torch.where(msk[..., None], chosen, torch.zeros_like(chosen)) if return_traj: certified = msk.clone() diff --git a/tests/test_eval_cl.py b/tests/test_eval_cl.py index 0469170..2ac5c8c 100644 --- a/tests/test_eval_cl.py +++ b/tests/test_eval_cl.py @@ -620,5 +620,85 @@ class SpeedAndMarginTest(unittest.TestCase): self.assertTrue((per['plans']['gaps'] > 0.5).all().item()) +class FeatureGeometryReuseTest(unittest.TestCase): + """#16 第①条:gm_groups 复用调用者已算好的 cum_xf,省一次 FK,但结果必须与原口径逐位一致。""" + def test_gm_groups_with_supplied_xf_is_bitwise_identical(self): + from ml.common.features import features, GP, GAP_CAP + kin = Kin() + q = torch.tensor([[-129.9, 46.68, 43.49, -97.46, -85.1, -139.7], + [10.0, -20.0, 30.0, -40.0, 50.0, -60.0]]) + xf = kin.cum_xf(q) + torch.testing.assert_close(kin.gm_groups(q, GP, GAP_CAP, xf=xf), kin.gm_groups(q, GP, GAP_CAP), + rtol=0, atol=0) + idx = [a * 7 + b for a, b in GP] + table = kin.gaps(q, GAP_CAP, xf)['gm'][:, idx] + torch.testing.assert_close(kin.gm_groups(q, GP, GAP_CAP), table, rtol=0, atol=0) + z = torch.zeros(len(q), 6) + f = features(kin, q, z, q[:, :3], torch.zeros(len(q), 9), z[:, None, :].expand(len(q), 3, 6), + torch.zeros(len(q)), z, torch.zeros(len(q))) + cols = 12 + 3 + 6 + 3 + 6 + 3 + 6 + 3 + 3 + 2 + 18 + 3 + 6 + 1 # 间隙块之前的特征数 = 75 + self.assertEqual(cols + 8, 83) + torch.testing.assert_close(f[:, cols:cols + 8], table / GAP_CAP, rtol=0, atol=0) + + +class CertBatchEquivalenceTest(unittest.TestCase): + """#16 第②条:把 K 条候选的认证并成一次 gaps 调用,选择结果必须与串行循环逐位一致。""" + class StubModel: + act_scale = 1.0 + + def __init__(self, act): + self.act = act + + def sample_k(self, feat, K, z, steps=1): + B = feat.shape[0] + return (self.act.expand(B, K, 16, 6).clone(), torch.zeros(B, device=feat.device), + torch.zeros(B, 13, device=feat.device)) + + def run_both(self, acts, reject_first): + class StepKin: + def clamp_box(self, q): + return q + + def gaps(self, q, cap): + bad = (q[:, 0] > 0.5) if reject_first else torch.zeros(len(q), dtype=torch.bool, device=q.device) + return {'gm': torch.where(bad[:, None], -torch.ones(len(q), 49, device=q.device), + torch.full((len(q), 49), 1.0, device=q.device))} + + acts = torch.tensor(acts, dtype=torch.float32) # [K,16,6] 动作(±1 归一化) + model = self.StubModel(acts) + tasks = [{'q0': [0] * 6, 'T': [10, 0, 0]}] * 2 # B=2:批量索引形状必须在多行下也成立 + out = [] + for batched in (0, 1): + with patch('ml.sim.closed_loop.features', return_value=torch.zeros(len(tasks), 83)), \ + patch('ml.sim.closed_loop.goal_err', + side_effect=lambda kin, q, T, R: (torch.full((q.shape[0],), 10.0), torch.zeros(q.shape[0]))): + _, per = rollout(model, StepKin(), tasks, 'cpu', K=acts.shape[0], safety=True, max_sec=0.04, + return_traj=True, use_sub=False, select='first', replan='empty', commit_n=2, + safety_partial=1, cert_batch=batched) + out.append(per) + return out + + def test_batched_certification_selects_the_same_candidate(self): + # 候选 0 第 2 步撞上 q0>0.5 的障碍 ⇒ 只有前缀 1 步;候选 1 全程安全 ⇒ 应被选中 + acts = [[[0.2, 0, 0, 0, 0, 0], [0.5, 0, 0, 0, 0, 0]] + [[0, 0, 0, 0, 0, 0]] * 14, + [[0.1, 0, 0, 0, 0, 0], [0.1, 0, 0, 0, 0, 0]] + [[0, 0, 0, 0, 0, 0]] * 14] + seq, batched = self.run_both(acts, reject_first=True) + torch.testing.assert_close(batched['traj'], seq['traj'], rtol=0, atol=0) + torch.testing.assert_close(batched['plans']['commit'], seq['plans']['commit'], rtol=0, atol=0) + torch.testing.assert_close(batched['plans']['certified'], seq['plans']['certified'], rtol=0, atol=0) + self.assertEqual(batched['brakes'].tolist(), seq['brakes'].tolist()) + self.assertAlmostEqual(seq['traj'][0, -1, 0].item(), 0.24, places=5) # 候选 1 的两步 0.1×STEP=0.12° + + def test_batched_certification_keeps_partial_prefix_choice(self): + # 所有候选都只走得了第 1 步 ⇒ 两条路径都取第 1 条候选、前缀长度 1 + acts = [[[0.2, 0, 0, 0, 0, 0], [0.5, 0, 0, 0, 0, 0]] + [[0, 0, 0, 0, 0, 0]] * 14, + [[0.3, 0, 0, 0, 0, 0], [0.6, 0, 0, 0, 0, 0]] + [[0, 0, 0, 0, 0, 0]] * 14] + seq, batched = self.run_both(acts, reject_first=True) + torch.testing.assert_close(batched['traj'], seq['traj'], rtol=0, atol=0) + torch.testing.assert_close(batched['plans']['commit'], seq['plans']['commit'], rtol=0, atol=0) + self.assertAlmostEqual(seq['traj'][0, 1, 0].item(), 0.24, places=5) + self.assertAlmostEqual(seq['traj'][0, 2, 0].item(), 0.24, places=5) # 第 2 步被拒后停在原地 + + if __name__ == '__main__': unittest.main()