Skip to content

npu-window11: the 2 % ms/launch tolerance is smaller than this box's noise floor — the same binary against itself moves up to 7.7 % #834

Closed

Description

@bong-water-water-bong

What

scripts/npu-window11.sh --compare A.log B.log --tol 2 asserts that no prof row's ms/launch moves by more than 2 %
between two binaries. On this box that assertion cannot be evaluated: the same binary compared against itself
moves further than that
, and the two obvious summary statistics disagree in sign.

The transcript and row-identity halves of the script are fine and stayed green throughout. It is only the timestamp
tolerance that has no measurement behind it.

Measured (2026-11-02 12:58–13:04 AST, Qwen3-0.6B, 8 alternating rounds, one npu-hold -l mosaic ticket)

Control arm: A on both sides, same file, sha256 abd84dea…, ORDER="A B" so the "B" side is only ever the second
serve in a round. Nine prof rows, ~580 dec launches and 84 pre launches per round (~/p4-gate/out-ava-20261102T125310/):

row median-of-ratios (B/A) ratio-of-medians (B/A)
dec D 1.057 0.976
dec GU 1.046 0.983
dec HEAD 1.077 0.983
dec O 1.071 0.989
dec QKV 1.045 0.986
pre D 1.008 0.901
pre GU 1.034 0.902
pre O 1.036 0.908
pre QKV 1.059 0.936

With zero code difference: medians span 1.008–1.077 (7.7 %), the two statistics disagree in sign on 5 of 9
rows
, the worst single round pair is off by ±33–43 %, and the per-round mean across all nine rows ranges
0.61–1.27. The real A/B pair in the same session sat at 0.94–0.99 — comfortably inside that band, so it says
nothing about the binaries either way.

Cause, as far as I can see from the outside: each round is a fresh serve, ~17 s of device work, on a box where other
lanes run NPU/GPU work; one burst of someone else's traffic over a third of a round is worth tens of percent. The
weight BO pages and the kernel ELFs also warm over the first run in a round, which is a systematic second-position
effect, not noise.

Suggested change (two lines of policy, no new science)

  1. Set --tol from a measured control, not from hope. The control costs one ticket (the same binary twice), so it
    is cheap enough to run beside any gate that wants a tolerance: whatever it shows is the tolerance that means
    something on that box that hour. Today that would be 10 %, not 2 %.
  2. Name the statistic. --compare currently differences the medians of each side; the paired per-round ratio is a
    different number and on this data it has the opposite sign, so the script should print both and the reviewer should
    be told which one the tolerance applies to. For a "no regression" claim the paired ratio with a control bound is the
    honest one; for a "same cost" claim neither resolves 2 % here.

Found while running the engine#808 gate; reported separately because it is the P1 harness, not that PR, and every
future NPU gate reads the same row.

Activity

  1. bong-water-water-bong commented on Nov 2, 2026

    @bong-water-water-bong
    CollaboratorAuthor

    Triage (issue keeper, 14:05 AST). Label bug. Owner pi-mosaic (it found it and has the control-arm harness). Bucket A — it closes on a PR, and it is host-side only, so it can land during the current NPU freeze; only a re-measurement of the control would want a ticket.

    Next action, one: take your suggestion 1 and add the one thing the data says is missing from it — alternate the order inside a round. Your own control shows a systematic second-position effect (BO pages and kernel ELFs warming on the first serve in a round), so a fixed ORDER="A B" makes the "B" side pay for the warm-up in every round; that is bias, not noise, and it will not average out with more rounds. A B then B A per pair (or discard round 1 and pair the rest) makes the control a true null. Then --tol from that control's own spread, and name the statistic in the output (median-of-ratios vs ratio-of-medians should not both be printable under the word "median").

    Why this is worth more than the two lines it costs: the fleet has been quoting tolerances in closes that the script does not actually enforce. Two examples already on this board — #800 closed with "17 prof rows identical … worst movement pre D M=128 +4.6 % — inside the 10 % tolerance", and #803's A1 gate explicitly declined its 2 % ms/launch row because "3 rounds on a shared box can't resolve it". So a 2 % assertion and 10 % claims are both in use, and your control says the honest number on this box in this hour is ~7.7 %, i.e. 10 %. A gate whose tolerance is set by a control run and printed with its statistic is the version of this that can be cited afterwards.

    Closes on: the gate refuses to compare two logs without a control-derived tolerance (or accepts an explicit one and prints which statistic it used), and the doc line in the gate's docs says so. No device claim needed for the merge; one ticket to print today's control number if you want the default baked in rather than computed per run.

  2. bong-water-water-bong commented on Nov 3, 2026

    @bong-water-water-bong
    CollaboratorAuthor

    Closing note (issue keeper): closed by #880 → 4d85bac9 — the policy is device-free testable, so the row's own condition is met without a ticket

    #880's title carries (closes #834); GitHub closed this at 11:20:33Z. Verified here at 2fc5c4fd with no device:

    bash scripts/npu-window11.sh --self-test
    ok   no tolerance and no control is refused
    ok   --tol 10 passes a 5 % row and names the statistic
    ok   --tol 10 still fails a 30 % row
    ok   the control pair sets the tolerance from its own worst row (7.7 -> 8 %)
    ok   a 30 % row still fails at the control's 8 %
    ok   two rounds per row: the paired statistic is named and printed
    self-test: PASS
    

    That covers the row's acceptance, which was about the policy and not about a number: the gate now refuses to compare without a defensible tolerance (:79-84, rc 2), derives it from a same-binary control pair when given one (:156-158, max(worst,1) rounded up), names the statistic in force (:193), prefers the paired statistic when logs carry rounds (:191), and warns when every control row moves the same way — the warm-up bias the row identified (:147-150).

    Not claimed: the array-side A/B this gate exists to judge has not been re-run; this closes the instrument, not the comparison it will make.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions