diff --git a/docs/experiment_round34_f32_cert.json b/docs/experiment_round34_f32_cert.json new file mode 100644 index 0000000..ba13b9a --- /dev/null +++ b/docs/experiment_round34_f32_cert.json @@ -0,0 +1,41 @@ +{ + "kin_fp": "2ebcbf17", + "segments": 48, + "n_subsegments": 8, + "wide_cap_mm": 2.0, + "gap_abs_err_mm": { + "p50": 0.0, + "p99": 3.661949063912929e-05, + "p999": 7.4360332600075e-05, + "max": 0.00013247109886016517 + }, + "signed_err_mm": { + "min": -0.00010937313134817828, + "max": 0.00013247109886016517, + "overestimate_count": 1, + "overestimate_gt_1e-3": 0 + }, + "sign_flips": 0, + "accepted_f64": 24, + "accepted_f32": 24, + "unsafe_direction_f32_only": 0, + "conservative_f64_only": 0, + "per_group_pair_err_p99": [ + 0.0, + 7.6e-05, + 0.0001, + 7e-05, + 7.1e-05, + 0.0, + 0.0, + 0.0, + 0.000132, + 6.7e-05, + 5.1e-05, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "note": "wide_cap 2.0 mm\uff1a\u8ba4\u8bc1\u5b9e\u9645\u7528 bound+2eps \u7684\u81ea\u9002\u5e94 cap\uff0c\u8fd9\u91cc\u53d6\u56fa\u5b9a 2 mm \u4ee5\u8986\u76d6\u88ab\u68c0\u9a8c\u7684\u6bb5\uff1b\u82e5 max \u8bef\u5dee\u8fdc\u5c0f\u4e8e 1e-4 \u7684 eps\uff0c\u5224\u636e\u5728 f32 \u4e0b\u4ecd\u6210\u7acb\u9700\u518d\u786e\u8ba4 f32 \u7684\u95f4\u9699\u672c\u8eab\u8bef\u5dee\u7b26\u53f7\u65b9\u5411\u3002" +} \ No newline at end of file diff --git a/docs/experiment_round34_precision_ab.json b/docs/experiment_round34_precision_ab.json new file mode 100644 index 0000000..89480cc --- /dev/null +++ b/docs/experiment_round34_precision_ab.json @@ -0,0 +1,58 @@ +{ + "device": "NVIDIA GeForce RTX 3090", + "torch": "2.10.0+cu130", + "K": 8, + "steps": 1, + "B": 1, + "act_scale": 1.0, + "inference": { + "fp32": { + "p50": 7.681, + "p95": 9.426, + "p99": 10.631, + "max": 15.837 + }, + "fp16": { + "p50": 8.309, + "p95": 10.791, + "p99": 12.031, + "max": 12.322 + }, + "bf16": { + "p50": 8.577, + "p95": 11.057, + "p99": 14.174, + "max": 17.1 + } + }, + "cycle": { + "fp32": { + "p50": 36.507, + "p95": 43.688, + "p99": 46.568, + "max": 50.598 + }, + "fp16": { + "p50": 36.162, + "p95": 50.43, + "p99": 55.598, + "max": 57.043 + } + }, + "output_deviation": { + "fp16": { + "act_max_abs": 0.002096, + "act_p99_abs": 0.001059, + "deg_max_abs": 0.005, + "deg_p99_abs": 0.00219, + "would_change_execution_order": false + }, + "bf16": { + "act_max_abs": 0.017171, + "act_p99_abs": 0.012661, + "deg_max_abs": 0.03766, + "deg_p99_abs": 0.03008, + "would_change_execution_order": true + } + } +} \ No newline at end of file diff --git a/docs/experiment_round35_pipeline_gaps.json b/docs/experiment_round35_pipeline_gaps.json new file mode 100644 index 0000000..50641fa --- /dev/null +++ b/docs/experiment_round35_pipeline_gaps.json @@ -0,0 +1,23 @@ +{ + "device": "NVIDIA GeForce RTX 3090", + "K": 8, + "commit_n": 2, + "design": "\u4e24\u6b21\u89c4\u5212\u4e3a\u4e00\u4e2a\u5355\u5143\uff0c\u5947\u6570\u8f6e\u53cd\u5e8f\uff1b\u6d41\u6c34\u7ebf\u90a3\u6b21\u7684\u8ba4\u8bc1\u8c03\u7528\u88ab\u8feb\u7528 cap=GAP_CAP(\u7279\u5f81\u9700\u8981)\uff0c\u8fd9\u662f\u590d\u7528\u7684\u771f\u5b9e\u4ee3\u4ef7\uff0c\u4e0d\u662f\u514d\u8d39", + "equivalence": { + "cached_gap_row_bitwise_equal": false, + "features_bitwise_equal": false, + "max_row_diff_mm": 6.29425048828125e-05 + }, + "fresh": { + "p50_per_plan": 34.779, + "p95": 39.271, + "p99": 40.98, + "reps": 60 + }, + "pipelined": { + "p50_per_plan": 31.655, + "p95": 34.483, + "p99": 38.208, + "reps": 60 + } +} \ No newline at end of file diff --git a/docs/探索日志.md b/docs/探索日志.md index 21002ba..96d9c07 100644 --- a/docs/探索日志.md +++ b/docs/探索日志.md @@ -719,7 +719,20 @@ - 批量认证(`--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) +## 轮次 35:半精度、流水线复用与 float32 认证的实测(exp: `exp/dagger-deploy`,三条路两条被自己否掉) + +- **按用户指定的方向先量显卡精度档**(FP32 / FP16 / BF16,`docs/experiment_round34_precision_ab.json`;B=1、K=8、steps=1,25 次预热 + 120 次计时): + + | 精度 | 推理 P50 | 推理 P99 | 整周期 P50 | 整周期 P99 | 动作最大偏差 | + |---|---|---|---|---|---| + | FP32 | 7.68 ms | 10.63 | 36.51 | 46.57 | — | + | FP16 | 8.31 ms(慢 8%) | 12.03 | 36.16 | **55.60(更差)** | 2.1e−3 归一化 = **0.0050°** | + | BF16 | 8.58 ms(慢 12%) | 14.17 | — | — | 1.7e−2 = **0.0377°** | + + 结论:**这个网络在这个批量下不是算力受限**,半精度换不来时间,还要付动作偏差与更差的尾部 ⇒ 推理保持 FP32。(未测更大 batch,那里的结论不下。) +- **float32 能不能做认证**(`docs/experiment_round34_f32_cert.json`,48 段 × 9 网格点 × 15 组对,宽相位 cap 2 mm):f32 与 f64 间隙差 p50 **0**、p99 3.66e−5、p999 7.44e−5、**max 1.32e−4 mm**;有符号误差 max +1.32e−4(确有 1 例高估)、min −1.09e−4。同一判据下 f64/f32 都接受 24/48 段,"仅 f32 判安全"= 0、符号翻转 = 0。⇒ f32 不是不能用,但**现用 eps=1e−4 已被实测越界**,要用就得把 eps 抬到 ≥2e−4 mm;且这只量了间隙值误差,没覆盖 f32 下 FK/界自身的误差,因此暂不放宽 dtype 守卫。 +- **流水线复用特征间隙——否掉**(`docs/experiment_round35_pipeline_gaps.json`):想法是"下一次规划的 q 正好是本次认证已算过的末点"。第一版给出 42.1→31.8 ms,但**等价性检查不通过**(缓存行与新算差 3.19 mm)——是我取行索引用错(`full[CN-1]` 取到第 2 条候选的第 1 步,而非第 1 条候选走完 commit 步)。修好后收益只剩 **34.8→31.7 ms(−3.1 ms)**:复用要求认证调用改用 cap=40 的宽相位(特征所需),省下的被吃回大半;且缓存行与新算**不是逐位相同**(差 6.3e−5 mm,源于不同 batch 下矩阵乘的结合序),会扰动特征输入。⇒ 不为这 3 ms 改口径,放弃。 +- **剩下的量级判断**:一个周期 ≈ 推理 7.2 + 特征 13.1(宽相位 8.2 + FK 4.0)+ 末态打分 4.3 + DLS 6.5 + 认证 7.4 ≈ 33 ms,其中 **4–5 次调用各自重做同一个宽相位筛选**(67,256 个簇对)。下一步是把一次筛选的半径按位移界(`cert_lever`)扩到整个 commit 地平线,供同周期所有点共用——这才是有量级的候选,而不是再抠精度。 ## 分支清理(2026-10-20)