diff --git a/docs/img/wvs/wvs_steer_honesty_qwen3_14b.md b/docs/img/wvs/wvs_steer_honesty_qwen3_14b.md index 64127f0..cb9424f 100644 --- a/docs/img/wvs/wvs_steer_honesty_qwen3_14b.md +++ b/docs/img/wvs/wvs_steer_honesty_qwen3_14b.md @@ -60,3 +60,64 @@ Filled path points satisfy pooled `pmass(dose) / pmass(vanilla) >= 0.96`. The fi | -0.5C | 0.134 | 15 | | +0.5C | 0.128 | 16 | | +1C | 0.215 | 9 | + +## Per-seed answer-mass evidence + +The figure follows the specified pooled condition. This audit table retains each saved seed so a pooled pass cannot hide disagreement. + +| method | seed | dose | pmass/base | per-seed result | +|:----------|-------:|:-------|-------------:|:------------------| +| vjp_delta | 0 | -2C | 0.999 | pass | +| vjp_delta | 0 | -1C | 0.959 | fail | +| vjp_delta | 0 | -0.5C | 0.655 | fail | +| vjp_delta | 0 | +0.5C | 1.007 | pass | +| vjp_delta | 0 | +1C | 1.007 | pass | +| vjp_delta | 0 | +2C | 1.001 | pass | +| vjp_delta | 1 | -2C | 0.996 | pass | +| vjp_delta | 1 | -1C | 0.956 | fail | +| vjp_delta | 1 | -0.5C | 0.622 | fail | +| vjp_delta | 1 | +0.5C | 1.005 | pass | +| vjp_delta | 1 | +1C | 1.005 | pass | +| vjp_delta | 1 | +2C | 1 | pass | +| vjp_delta | 2 | -2C | 1.01 | pass | +| vjp_delta | 2 | -1C | 0.973 | pass | +| vjp_delta | 2 | -0.5C | 0.632 | fail | +| vjp_delta | 2 | +0.5C | 1.017 | pass | +| vjp_delta | 2 | +1C | 1.017 | pass | +| vjp_delta | 2 | +2C | 1.012 | pass | +| mean_diff | 0 | -2C | 0.864 | fail | +| mean_diff | 0 | -1C | 0.988 | pass | +| mean_diff | 0 | -0.5C | 1.006 | pass | +| mean_diff | 0 | +0.5C | 0.991 | pass | +| mean_diff | 0 | +1C | 1 | pass | +| mean_diff | 0 | +2C | 0.977 | pass | +| mean_diff | 1 | -2C | 0.813 | fail | +| mean_diff | 1 | -1C | 0.974 | pass | +| mean_diff | 1 | -0.5C | 0.995 | pass | +| mean_diff | 1 | +0.5C | 0.99 | pass | +| mean_diff | 1 | +1C | 0.984 | pass | +| mean_diff | 1 | +2C | 0.972 | pass | +| mean_diff | 2 | -2C | 0.856 | fail | +| mean_diff | 2 | -1C | 1 | pass | +| mean_diff | 2 | -0.5C | 1.008 | pass | +| mean_diff | 2 | +0.5C | 1.011 | pass | +| mean_diff | 2 | +1C | 1.005 | pass | +| mean_diff | 2 | +2C | 0.984 | pass | +| pca | 0 | -2C | 0.814 | fail | +| pca | 0 | -1C | 0.984 | pass | +| pca | 0 | -0.5C | 0.986 | pass | +| pca | 0 | +0.5C | 1.009 | pass | +| pca | 0 | +1C | 1.01 | pass | +| pca | 0 | +2C | 0.943 | fail | +| pca | 1 | -2C | 0.795 | fail | +| pca | 1 | -1C | 0.969 | pass | +| pca | 1 | -0.5C | 0.969 | pass | +| pca | 1 | +0.5C | 1.003 | pass | +| pca | 1 | +1C | 0.999 | pass | +| pca | 1 | +2C | 0.932 | fail | +| pca | 2 | -2C | 0.819 | fail | +| pca | 2 | -1C | 0.98 | pass | +| pca | 2 | -0.5C | 0.97 | pass | +| pca | 2 | +0.5C | 1.016 | pass | +| pca | 2 | +1C | 1.011 | pass | +| pca | 2 | +2C | 0.947 | fail | diff --git a/docs/img/wvs/wvs_steer_honesty_qwen3_14b.png b/docs/img/wvs/wvs_steer_honesty_qwen3_14b.png index 63a9df2..46682d9 100644 Binary files a/docs/img/wvs/wvs_steer_honesty_qwen3_14b.png and b/docs/img/wvs/wvs_steer_honesty_qwen3_14b.png differ diff --git a/docs/img/wvs/wvs_steer_honesty_qwen3_14b.svg b/docs/img/wvs/wvs_steer_honesty_qwen3_14b.svg index e300f1d..6e25f31 100644 --- a/docs/img/wvs/wvs_steer_honesty_qwen3_14b.svg +++ b/docs/img/wvs/wvs_steer_honesty_qwen3_14b.svg @@ -6,7 +6,7 @@ - 2026-09-19T14:17:45.799525 + 2026-09-19T14:39:21.067957 image/svg+xml @@ -31,532 +31,402 @@ z +L 710.64 363.49884 +" clip-path="url(#pcb9a789b3b)" style="fill: none; stroke: #c9c4b4; stroke-linecap: square"/> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - +" clip-path="url(#pcb9a789b3b)" style="fill: none; opacity: 0.9; stroke: #4e79a7; stroke-width: 1.8; stroke-linejoin: miter"/> - +" clip-path="url(#pcb9a789b3b)" style="fill: none; opacity: 0.9; stroke: #9c755f; stroke-width: 1.8; stroke-linejoin: miter"/> - +" clip-path="url(#pcb9a789b3b)" style="fill: none; opacity: 0.9; stroke: #e15759; stroke-width: 1.8; stroke-linejoin: miter"/> - +" clip-path="url(#pcb9a789b3b)" style="fill: none; opacity: 0.9; stroke: #f28e2b; stroke-width: 1.8; stroke-linejoin: miter"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - + - + - + - - + + - + @@ -1137,7 +1007,7 @@ L 112.619251 189.437014 - + - + @@ -1164,463 +1034,284 @@ z - + - - + + - - + + - - + + - - + - - - +" clip-path="url(#pcb9a789b3b)" style="fill: #111111; opacity: 0.7; stroke-dasharray: 5.18,2.24; stroke-dashoffset: 0; stroke: #111111; stroke-width: 1.4; stroke-linecap: round"/> - - - - - - - - - - - - - - - - - - - - - - - - - +" clip-path="url(#pcb9a789b3b)" style="fill: none; stroke: #111111; stroke-opacity: 0.45; stroke-width: 1.2"/> - +" clip-path="url(#pcb9a789b3b)" style="fill: none; stroke: #111111; stroke-opacity: 0.45; stroke-width: 1.2"/> - - - + + +" clip-path="url(#pcb9a789b3b)" style="fill: #00838f; opacity: 0.7; stroke-dasharray: 5.18,2.24; stroke-dashoffset: 0; stroke: #00838f; stroke-width: 1.4; stroke-linecap: round"/> - - - + + +" clip-path="url(#pcb9a789b3b)" style="fill: #1e8449; opacity: 0.7; stroke-dasharray: 5.18,2.24; stroke-dashoffset: 0; stroke: #1e8449; stroke-width: 1.4; stroke-linecap: round"/> - - - + + +" clip-path="url(#pcb9a789b3b)" style="fill: #1e8449; opacity: 0.7; stroke-dasharray: 5.18,2.24; stroke-dashoffset: 0; stroke: #1e8449; stroke-width: 1.4; stroke-linecap: round"/> - - - + + +" clip-path="url(#pcb9a789b3b)" style="fill: #111111; opacity: 0.95; stroke: #111111; stroke-width: 2.2; stroke-linecap: round"/> - - - + + +" clip-path="url(#pcb9a789b3b)" style="fill: #111111; opacity: 0.95; stroke: #111111; stroke-width: 2.2; stroke-linecap: round"/> + + + + - +" clip-path="url(#pcb9a789b3b)" style="fill: none; stroke: #111111; stroke-opacity: 0.48; stroke-width: 1.4"/> - - - + + +" clip-path="url(#pcb9a789b3b)" style="fill: #00838f; opacity: 0.95; stroke: #00838f; stroke-width: 2.2; stroke-linecap: round"/> - - - + + +" clip-path="url(#pcb9a789b3b)" style="fill: #00838f; opacity: 0.95; stroke: #00838f; stroke-width: 2.2; stroke-linecap: round"/> + + + + + + + + + + + + - +" clip-path="url(#pcb9a789b3b)" style="fill: none; stroke: #00838f; stroke-opacity: 0.48; stroke-width: 1.4"/> - - - + + +" clip-path="url(#pcb9a789b3b)" style="fill: #1e8449; opacity: 0.95; stroke: #1e8449; stroke-width: 2.2; stroke-linecap: round"/> - - - + + +" clip-path="url(#pcb9a789b3b)" style="fill: #1e8449; opacity: 0.95; stroke: #1e8449; stroke-width: 2.2; stroke-linecap: round"/> - +" clip-path="url(#pcb9a789b3b)" style="fill: none; stroke: #1e8449; stroke-opacity: 0.48; stroke-width: 1.4"/> + + + + + + + + + + + - +" style="fill: #ffffff; opacity: 0.88; stroke: #cccccc; stroke-linejoin: miter"/> - - + + + + - - + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + - + - + @@ -1829,46 +1861,16 @@ L 554.3384 68.629453 - - + - + - + - - - + - + - + @@ -2015,15 +2017,15 @@ L 554.3384 89.630547 - - + - + - + @@ -2068,15 +2070,15 @@ L 554.3384 100.131094 - - + - + - + @@ -2125,9 +2127,9 @@ L 554.3384 110.631641 - + - - - - - - - - - - - - - - - - + + - - + + + + + - - + + - - - - - + + + + + + + - + + + + + + + + - - - - - - - - - - - - + + - - + + - - + + - - + + + + + + + + + + + + - - - + + - + - - - - - - - - - - - - - + + - - + + - - + + + + + + + + + + + + - - - + + - - + - - - + - - - + - - - + - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - + - - - - - + - - - + + + + + + + + - + - + + diff --git a/docs/img/wvs/wvs_steer_honesty_qwen3_14b_vjp.png b/docs/img/wvs/wvs_steer_honesty_qwen3_14b_vjp.png index 65e3235..7d88a27 100644 Binary files a/docs/img/wvs/wvs_steer_honesty_qwen3_14b_vjp.png and b/docs/img/wvs/wvs_steer_honesty_qwen3_14b_vjp.png differ diff --git a/docs/img/wvs/wvs_steer_honesty_qwen3_14b_vjp.svg b/docs/img/wvs/wvs_steer_honesty_qwen3_14b_vjp.svg index a024f78..bdaef0f 100644 --- a/docs/img/wvs/wvs_steer_honesty_qwen3_14b_vjp.svg +++ b/docs/img/wvs/wvs_steer_honesty_qwen3_14b_vjp.svg @@ -6,7 +6,7 @@ - 2026-09-19T14:17:52.967479 + 2026-09-19T14:39:24.071597 image/svg+xml @@ -40,12 +40,72 @@ z +" clip-path="url(#pf59c1c854b)" style="fill: none; stroke: #c9c4b4; stroke-linecap: square"/> +" clip-path="url(#pf59c1c854b)" style="fill: none; stroke: #c9c4b4; stroke-linecap: square"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +" clip-path="url(#pf59c1c854b)" style="fill: none; opacity: 0.9; stroke: #4e79a7; stroke-width: 1.8; stroke-linejoin: miter"/> +" clip-path="url(#pf59c1c854b)" style="fill: none; opacity: 0.9; stroke: #9c755f; stroke-width: 1.8; stroke-linejoin: miter"/> +" clip-path="url(#pf59c1c854b)" style="fill: none; opacity: 0.9; stroke: #e15759; stroke-width: 1.8; stroke-linejoin: miter"/> +" clip-path="url(#pf59c1c854b)" style="fill: none; opacity: 0.9; stroke: #f28e2b; stroke-width: 1.8; stroke-linejoin: miter"/> - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +" clip-path="url(#pf59c1c854b)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/> - + - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + @@ -1122,10 +984,10 @@ z - + +" clip-path="url(#pf59c1c854b)" style="fill: none; stroke-dasharray: 4.44,1.92; stroke-dashoffset: 0; stroke: #a13a3a; stroke-opacity: 0.35; stroke-width: 1.2"/> @@ -1174,64 +1036,42 @@ z + + + - - + + - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -1698,10 +1295,52 @@ z Q 462.323157 336.610459 448.246763 342.632388 " style="fill: none; stroke: #555555; stroke-linecap: round"/> - + + + + @@ -1763,6 +1428,32 @@ Q 550 2706 781 3412 Q 1013 4119 1484 4856 L 1984 4856 z +" transform="scale(0.015625)"/> + - + +" clip-path="url(#pf59c1c854b)" style="fill: #a13a3a; opacity: 0.7; stroke-dasharray: 5.18,2.24; stroke-dashoffset: 0; stroke: #a13a3a; stroke-width: 1.4; stroke-linecap: round"/> - + +" clip-path="url(#pf59c1c854b)" style="fill: none; stroke: #a13a3a; stroke-opacity: 0.45; stroke-width: 1.2"/> - + +" clip-path="url(#pf59c1c854b)" style="fill: none; stroke: #a13a3a; stroke-opacity: 0.45; stroke-width: 1.2"/> - + +" clip-path="url(#pf59c1c854b)" style="fill: #147d64; opacity: 0.95; stroke: #147d64; stroke-width: 2.2; stroke-linecap: round"/> - + +" clip-path="url(#pf59c1c854b)" style="fill: #147d64; opacity: 0.95; stroke: #147d64; stroke-width: 2.2; stroke-linecap: round"/> - + +" clip-path="url(#pf59c1c854b)" style="fill: #147d64; opacity: 0.95; stroke: #147d64; stroke-width: 2.2; stroke-linecap: round"/> - + +" clip-path="url(#pf59c1c854b)" style="fill: none; stroke: #a13a3a; stroke-opacity: 0.48; stroke-width: 1.4"/> - +" style="fill: #ffffff; opacity: 0.88; stroke: #cccccc; stroke-linejoin: miter"/> - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + - + @@ -2001,9 +1824,9 @@ L 717.9512 71.509453 - + - - - + + - + - - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - + - - - + + @@ -9953,53 +9776,53 @@ z +" clip-path="url(#p84d08d95c3)" style="fill: none; stroke: #147d64; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#p84d08d95c3)" style="fill: #147d64; stroke: #147d64; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#p84d08d95c3)" style="fill: none; stroke: #147d64; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#p84d08d95c3)" style="fill: #147d64; stroke: #147d64; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#p84d08d95c3)" style="fill: none; stroke: #147d64; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#p84d08d95c3)" style="fill: #147d64; stroke: #147d64; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#p84d08d95c3)" style="fill: none; opacity: 0.45; stroke-dasharray: 3.7,1.6; stroke-dashoffset: 0; stroke: #a13a3a; stroke-linecap: round"/> +" clip-path="url(#p84d08d95c3)" style="fill: #a13a3a; opacity: 0.45; stroke-dasharray: 3.7,1.6; stroke-dashoffset: 0; stroke: #a13a3a; stroke-linecap: round"/> - + - - + @@ -10022,9 +9845,9 @@ z - + - + @@ -10038,9 +9861,9 @@ z - + - + @@ -10054,9 +9877,9 @@ z - + - + @@ -10070,9 +9893,9 @@ z - + - + @@ -10085,9 +9908,9 @@ z - + - + @@ -10100,9 +9923,9 @@ z - + - + @@ -10115,9 +9938,9 @@ z - + - + @@ -10130,9 +9953,9 @@ z - + - + @@ -10167,14 +9990,14 @@ z - + - - + @@ -10219,9 +10042,9 @@ z - + - + @@ -10246,9 +10069,9 @@ z - + - + @@ -10302,14 +10125,46 @@ z - + - + + + + @@ -10317,9 +10172,9 @@ z - + - + @@ -10335,36 +10190,6 @@ z - - + + +" clip-path="url(#p84d08d95c3)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #a13a3a; stroke-opacity: 0.35; stroke-width: 1.5"/> - - + + +" clip-path="url(#p84d08d95c3)" style="fill: none; stroke-dasharray: 3.7,1.6; stroke-dashoffset: 0; stroke: #aa3333"/> - + - - - - - - - - - - - - - + + - - + + + + + + + + + + + + - - - + + - + +" clip-path="url(#p84d08d95c3)" style="fill: none; stroke: #a13a3a; stroke-opacity: 0.55"/> - + +" clip-path="url(#p84d08d95c3)" style="fill: none; stroke: #a13a3a; stroke-opacity: 0.55"/> - + +" clip-path="url(#p84d08d95c3)" style="fill: none; stroke: #a13a3a; stroke-opacity: 0.55"/> - + - + - + +" clip-path="url(#pa62efafaae)" style="fill: none; stroke: #4c78a8; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#pa62efafaae)" style="fill: #4c78a8; stroke: #4c78a8; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#pa62efafaae)" style="fill: none; stroke: #4c78a8; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#pa62efafaae)" style="fill: #4c78a8; stroke: #4c78a8; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#pa62efafaae)" style="fill: none; stroke: #4c78a8; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#pa62efafaae)" style="fill: #4c78a8; stroke: #4c78a8; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#pa62efafaae)" style="fill: none; opacity: 0.45; stroke-dasharray: 3.7,1.6; stroke-dashoffset: 0; stroke: #4c78a8; stroke-linecap: round"/> +" clip-path="url(#pa62efafaae)" style="fill: #4c78a8; opacity: 0.45; stroke-dasharray: 3.7,1.6; stroke-dashoffset: 0; stroke: #4c78a8; stroke-linecap: round"/> - + - + @@ -10773,9 +10598,9 @@ z - + - + @@ -10789,9 +10614,9 @@ z - + - + @@ -10805,9 +10630,9 @@ z - + - + @@ -10821,9 +10646,9 @@ z - + - + @@ -10836,9 +10661,9 @@ z - + - + @@ -10851,9 +10676,9 @@ z - + - + @@ -10866,9 +10691,9 @@ z - + - + @@ -10881,9 +10706,9 @@ z - + - + @@ -10918,9 +10743,9 @@ z - + - + @@ -10933,9 +10758,9 @@ z - + - + @@ -10948,9 +10773,9 @@ z - + - + @@ -10984,9 +10809,9 @@ z - + - + @@ -10999,9 +10824,9 @@ z - + - + @@ -11014,9 +10839,9 @@ z - + - + @@ -11067,13 +10892,13 @@ z - - + + +" clip-path="url(#pa62efafaae)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #4c78a8; stroke-opacity: 0.35; stroke-width: 1.5"/> - + - + - - - - - - - - - - - - - + + - - + + - - + + + + + + + + + + + + +" clip-path="url(#pa62efafaae)" style="fill: none; stroke: #4c78a8; stroke-opacity: 0.55"/> - + +" clip-path="url(#pa62efafaae)" style="fill: none; stroke: #4c78a8; stroke-opacity: 0.55"/> - + +" clip-path="url(#pa62efafaae)" style="fill: none; stroke: #4c78a8; stroke-opacity: 0.55"/> - +" clip-path="url(#pafc84e2cea)" style="fill: none; stroke: #e45756; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#pafc84e2cea)" style="fill: #e45756; stroke: #e45756; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#pafc84e2cea)" style="fill: none; stroke: #e45756; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#pafc84e2cea)" style="fill: #e45756; stroke: #e45756; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#pafc84e2cea)" style="fill: none; stroke: #e45756; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#pafc84e2cea)" style="fill: #e45756; stroke: #e45756; stroke-width: 1.7; stroke-linecap: round"/> +" clip-path="url(#pafc84e2cea)" style="fill: none; opacity: 0.45; stroke-dasharray: 3.7,1.6; stroke-dashoffset: 0; stroke: #e45756; stroke-linecap: round"/> +" clip-path="url(#pafc84e2cea)" style="fill: #e45756; opacity: 0.45; stroke-dasharray: 3.7,1.6; stroke-dashoffset: 0; stroke: #e45756; stroke-linecap: round"/> - + - - + @@ -11344,9 +11160,9 @@ L 3.5 0 - + - + @@ -11359,9 +11175,9 @@ L 3.5 0 - + - + @@ -11374,9 +11190,9 @@ L 3.5 0 - + - + @@ -11389,9 +11205,9 @@ L 3.5 0 - + - + @@ -11404,9 +11220,9 @@ L 3.5 0 - + - + @@ -11455,13 +11271,13 @@ L 3.5 0 - - + + +" clip-path="url(#pafc84e2cea)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #e45756; stroke-opacity: 0.35; stroke-width: 1.5"/> - + - + - - - - - - - - - - - - - + + - - + + - - + + + + + + + + + + + + +" clip-path="url(#pafc84e2cea)" style="fill: none; stroke: #e45756; stroke-opacity: 0.55"/> - + +" clip-path="url(#pafc84e2cea)" style="fill: none; stroke: #e45756; stroke-opacity: 0.55"/> - + +" clip-path="url(#pafc84e2cea)" style="fill: none; stroke: #e45756; stroke-opacity: 0.55"/> - + - + - + - + diff --git a/logs_wvs_steer_plot_14b.log b/logs_wvs_steer_plot_14b.log index a7f4963..5267159 100644 --- a/logs_wvs_steer_plot_14b.log +++ b/logs_wvs_steer_plot_14b.log @@ -1,18 +1,2 @@ -# Saved Qwen3-14B WVS replot - -Command: - -```sh -UV_OFFLINE=1 uv run --offline python -u scripts/plot_wvs_steer.py --runs outputs --out docs/img/wvs/wvs_steer_honesty_qwen3_14b.png -``` - -Observed output: - -```text -2026-09-19 14:17:53 | wrote docs/img/wvs/wvs_steer_honesty_qwen3_14b.png, docs/img/wvs/wvs_steer_honesty_qwen3_14b.svg, docs/img/wvs/wvs_steer_honesty_qwen3_14b.md -2026-09-19 14:17:53 | wrote docs/img/wvs/wvs_steer_honesty_qwen3_14b_vjp.png -``` - -The plot reads saved `outputs/wvs_steer_*.json` artifacts only. Filled points use pooled `pmass(dose) / pmass(vanilla) >= 0.96`. The VJP negative `-0.5C` point is the first failure. Later negative observations remain disconnected. - --- PI[gpt-5.6-terra] +2026-09-19 14:39:24.250 | INFO | __main__:main:438 - wrote docs/img/wvs/wvs_steer_honesty_qwen3_14b.png, docs/img/wvs/wvs_steer_honesty_qwen3_14b.svg, docs/img/wvs/wvs_steer_honesty_qwen3_14b.md +2026-09-19 14:39:24.250 | INFO | __main__:main:439 - wrote docs/img/wvs/wvs_steer_honesty_qwen3_14b_vjp.png diff --git a/scripts/plot_wvs_steer.py b/scripts/plot_wvs_steer.py index 4d4b697..6130f53 100644 --- a/scripts/plot_wvs_steer.py +++ b/scripts/plot_wvs_steer.py @@ -164,7 +164,7 @@ def add_path(ax, path: list[dict], sign: int, color: str, scale_x: float, scale_ ax.add_patch(FancyArrowPatch( (start["x"] * scale_x, start["y"] * scale_y), (end["x"] * scale_x, end["y"] * scale_y), - arrowstyle="-|>", mutation_scale=10, linewidth=1.1, linestyle="--", color=color, alpha=0.45, zorder=4, + arrowstyle="-|>", mutation_scale=18, linewidth=1.4, linestyle="--", color=color, alpha=0.70, zorder=4, )) continue if state != "connected": @@ -173,7 +173,7 @@ def add_path(ax, path: list[dict], sign: int, color: str, scale_x: float, scale_ arrow = FancyArrowPatch( (start["x"] * scale_x, start["y"] * scale_y), (end["x"] * scale_x, end["y"] * scale_y), - arrowstyle="-|>", mutation_scale=11, linewidth=2, color=color, alpha=0.82, zorder=5, + arrowstyle="-|>", mutation_scale=18, linewidth=2.2, color=color, alpha=0.95, zorder=5, ) ax.add_patch(arrow) for dose, state in zip(path, states): @@ -184,12 +184,6 @@ def add_path(ax, path: list[dict], sign: int, color: str, scale_x: float, scale_ ax.scatter(x, y, s=34, facecolors="none", edgecolors=color, linewidths=1.4, alpha=0.48, zorder=5) else: ax.scatter(x, y, s=28, marker="s", facecolors="none", edgecolors=color, linewidths=1.2, alpha=0.45, zorder=4) - if show_uncertainty and dose["mult"] != 0.0: - _, _, dx_se, dy_se = paired_coordinate_ci(path[0], dose, resolved) - ax.errorbar( - x, y, xerr=1.96 * dx_se * abs(scale_x), yerr=1.96 * dy_se * abs(scale_y), - fmt="none", ecolor=color, elinewidth=0.8, capsize=1.8, alpha=0.38, zorder=2, - ) if dose_labels: text = "vanilla" if dose["mult"] == 0.0 else f"{dose['mult']:+g}C" ax.annotate(text, (x, y), xytext=label_offset, textcoords="offset points", fontsize=6.3, color=color) @@ -256,9 +250,40 @@ def render_table(pooled: dict[str, list[dict]], groups: dict[str, list[dict]], r for mult, (p95, n) in sorted(null.items()): random_rows.append([f"{mult:+g}C", f"{p95:.3f}", n]) sections.extend(["", "## Dose-matched random controls", "", tabulate(random_rows, headers=["dose", "movement p95", "coherent n"], tablefmt="pipe")]) + per_seed_rows = [] + for method in MAIN_METHODS: + for run in groups[method]: + base = next(dose for dose in run["doses"] if dose["mult"] == 0.0) + for dose in sorted((dose for dose in run["doses"] if dose["mult"] != 0.0), key=lambda dose: dose["mult"]): + ratio = dose["mean_pmass"] / base["mean_pmass"] + per_seed_rows.append([method, run["seed"], f"{dose['mult']:+g}C", f"{ratio:.3f}", "pass" if ratio >= PMASS_RATIO_FLOOR else "fail"]) + sections.extend([ + "", "## Per-seed answer-mass evidence", "", + "The figure follows the specified pooled condition. This audit table retains each saved seed so a pooled pass cannot hide disagreement.", "", + tabulate(per_seed_rows, headers=["method", "seed", "dose", "pmass/base", "per-seed result"], tablefmt="pipe"), + ]) return "\n".join(sections) + "\n" +def random_passing_points(groups: dict[str, list[dict]]) -> tuple[np.ndarray, np.ndarray]: + """Return saved random observations that individually pass their own 0.96 mass condition.""" + xs, ys = [], [] + for run in groups["random"]: + base = next(dose for dose in run["doses"] if dose["mult"] == 0.0) + for dose in run["doses"]: + if dose["mult"] and dose["mean_pmass"] / base["mean_pmass"] >= PMASS_RATIO_FLOOR: + xs.append(dose["x"]) + ys.append(dose["y"]) + return np.asarray(xs), np.asarray(ys) + + +def add_random_zone(ax, groups: dict[str, list[dict]], scale_x: float, scale_y: float) -> None: + """Show the saved random reference observations without implying a matched-dose null.""" + xs, ys = random_passing_points(groups) + ax.scatter(xs * scale_x, ys * scale_y, s=15, color="#777777", alpha=0.12, marker="s", zorder=1, + label="saved random directions, individual pmass-passing doses") + + def map_axes(runs: list[dict], pooled: dict[str, list[dict]], *, title: str, note: str): """Create the culture map and include all saved plotted observations in its limits.""" resolved = resolve_items(load_wvs_all()) @@ -293,13 +318,14 @@ def save_figure(figure, out: Path) -> None: svg.write_text("\n".join(line.rstrip() for line in svg.read_text().splitlines()) + "\n") -def render_main(runs: list[dict], pooled: dict[str, list[dict]], out: Path) -> None: +def render_main(runs: list[dict], pooled: dict[str, list[dict]], groups: dict[str, list[dict]], out: Path) -> None: """Render all saved real methods with separately traversed signed paths.""" figure, ax, resolved, scale_x, scale_y = map_axes( runs, pooled, title="Saved WVS steering paths, Qwen3-14B", note="", ) offsets = {"vjp_delta": (3, 4), "mean_diff": (3, -8), "pca": (3, 10)} + add_random_zone(ax, groups, scale_x, scale_y) for method in MAIN_METHODS: if method not in pooled: continue @@ -307,9 +333,9 @@ def render_main(runs: list[dict], pooled: dict[str, list[dict]], out: Path) -> N label = f"{method}: {name} ({'+' if sign == 1 else '-'})" add_path(ax, side_path(pooled[method], sign), sign, COLORS[method], scale_x, scale_y, label=label, dose_labels=method == "vjp_delta", resolved=resolved, - show_uncertainty=method == "vjp_delta", label_offset=offsets[method]) - ax.set_position([0.06, 0.10, 0.64, 0.82]) - ax.legend(loc="upper left", bbox_to_anchor=(1.01, 1.0), fontsize=7, framealpha=0.9) + show_uncertainty=False, label_offset=offsets[method]) + ax.set_position([0.06, 0.10, 0.88, 0.82]) + ax.legend(loc="upper right", bbox_to_anchor=(0.99, 0.99), fontsize=6.3, framealpha=0.88) out.parent.mkdir(parents=True, exist_ok=True) save_figure(figure, out) plt.close(figure) @@ -342,7 +368,7 @@ def metric_path(ax, path: list[dict], sign: int, value: str, color: str, *, labe ax.plot([], [], color=color, label=label) -def render_vjp(runs: list[dict], pooled: dict[str, list[dict]], out: Path) -> None: +def render_vjp(runs: list[dict], pooled: dict[str, list[dict]], groups: dict[str, list[dict]], out: Path) -> None: """Render a readable VJP-only map plus answer-mass and saturation diagnostics.""" figure, ax, resolved, scale_x, scale_y = map_axes( runs, pooled, title="VJP delta, saved Qwen3-14B WVS observations", note="", @@ -351,17 +377,17 @@ def render_vjp(runs: list[dict], pooled: dict[str, list[dict]], out: Path) -> No ax.set_position([0.04, 0.12, 0.56, 0.79]) positive = side_path(pooled["vjp_delta"], 1) negative = side_path(pooled["vjp_delta"], -1) + add_random_zone(ax, groups, scale_x, scale_y) positive_color, negative_color = "#147d64", "#a13a3a" add_path(ax, positive, 1, positive_color, scale_x, scale_y, label="intended honest-persona direction (+)", - dose_labels=True, resolved=resolved, show_uncertainty=True) + dose_labels=True, resolved=resolved, show_uncertainty=False) add_path(ax, negative, -1, negative_color, scale_x, scale_y, label="intended dishonest-persona direction (-)", - dose_labels=True, resolved=resolved, show_uncertainty=True, label_offset=(4, -9)) - ax.text(0.02, 0.95, "Faint crossbars: paired 95% coordinate intervals", transform=ax.transAxes, fontsize=6.5) + dose_labels=True, resolved=resolved, show_uncertainty=False, label_offset=(4, -9)) ax.annotate("first negative failure: -0.5C", xy=(negative[1]["x"] * scale_x, negative[1]["y"] * scale_y), xytext=(18, -20), textcoords="offset points", fontsize=7, arrowprops={"arrowstyle": "-", "color": "#555555"}) ax.annotate("later recovery observations\n(disconnected)", xy=(negative[-1]["x"] * scale_x, negative[-1]["y"] * scale_y), xytext=(8, 18), textcoords="offset points", fontsize=7, arrowprops={"arrowstyle": "-", "color": "#555555"}) - ax.legend(loc="upper left", bbox_to_anchor=(1.01, 1.0), fontsize=7) + ax.legend(loc="lower left", bbox_to_anchor=(0.01, 0.01), fontsize=6.2, framealpha=0.88) pmass_ax = figure.add_axes([0.68, 0.58, 0.28, 0.28]) metric_path(pmass_ax, positive, 1, "pmass_ratio", positive_color, label="intended honest (+)") @@ -407,8 +433,8 @@ def main() -> None: resolved = resolve_items(load_wvs_all()) table_path.parent.mkdir(parents=True, exist_ok=True) table_path.write_text(render_table(pooled, groups, resolved)) - render_main(runs, pooled, args.out) - render_vjp(runs, pooled, args.out.with_name(args.out.stem + "_vjp.png")) + render_main(runs, pooled, groups, args.out) + render_vjp(runs, pooled, groups, args.out.with_name(args.out.stem + "_vjp.png")) logger.info(f"wrote {args.out}, {args.out.with_suffix('.svg')}, {table_path}") logger.info(f"wrote {args.out.with_name(args.out.stem + '_vjp.png')}")