Files
vllm-omni/benchmarks/edge_harness/test_bench_harness.py
T
tzhouamandClaude Opus 5 b36a3431bd Package this fork as vllm-embedding: README, docs, roadmap, harness
Turns a branch of accumulated edge/CPU work into something someone else can
read, reproduce and continue.

README.md states what the fork is for (multimodal models on edge CPUs rather
than servers), the headline memory and speed results with their costs, and why
the numbers are worth reading -- five retracted conclusions, all measurement
errors rather than coding errors. Upstream's README is preserved at
docs/README.vllm-omni.md and NOTICE records the Apache-2.0 derivation and the
files this fork changes.

docs/edge/:
  methodology.md  the measurement discipline, which is the most transferable
                  thing here: what each of the five retractions was, and the
                  rule it left behind. Includes the two traps specific to this
                  stack -- vLLM's AOT compile cache keying on config so two
                  arms sharing an artifact load the wrong graph, and allocated
                  not being resident until mincore(2) says so.
  results.md      every measured figure with its spread and baseline, and an
                  explicit note that the four memory levers overlap and must
                  not be added.
  cpu-4bit.md     the two 4-bit paths, the packed layout as measured rather
                  than assumed, why the path choice is a config field, and the
                  GPTQ output-head trap that invalidated a whole round of W4A8
                  numbers.
  harness.md      how to run a comparison, and the two arguments that matter
                  more than they look (--context-len, --prompt-len), each of
                  which has produced a wrong conclusion by being left at its
                  default.

ROADMAP.md orders by whether the verification method is correct rather than by
expected size, lists what is done with results, what is next with expected
gains and how each would be verified, and -- at equal length -- what was
considered and rejected, including the CPU megakernel with the measurements
that rule it out for now.

benchmarks/edge_harness/ brings the tooling into the repo so the numbers are
reproducible: the grid runner, the single-run benchmarks, the memory ledger,
the fidelity metric, the Android agent suite, the quantizers, and the tests
that pin the harness's judgement. 82 tests pass from the new location.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L1ax5wYLA6XbqEL1i8L9gZ
2026-09-14 13:25:32 +08:00

309 lines
12 KiB
Python

"""Tests for the benchmark harness's judgement, not its plumbing.
The summariser is where a shared machine turns into a wrong claim, so that is
what is pinned here: spread reported, noisy arms flagged, single passes
refused as results, contended passes labelled.
"""
import json
import os
import pytest
from bench_harness import (
Arm,
HostLock,
check_expectations,
indistinguishable,
Observation,
core_utilization,
format_summary,
metric_is_lower_better,
parse_cores,
preflight,
provenance,
run_grid,
summarize,
)
def _obs(tag, p, value, load=1.0, ok=True):
return Observation(tag, p, {"tg_tps": value} if ok else {}, load, load, 1.0, ok)
def test_reports_best_median_and_spread():
s = summarize([_obs("a", 1, 80), _obs("a", 2, 100), _obs("a", 3, 90)], "tg_tps")[0]
assert s.best == 100 and s.median == 90
assert s.spread_pct == pytest.approx(20.0)
assert s.n == 3
def test_flags_an_arm_whose_passes_disagree():
"""A 30% swing between identical runs is the failure mode that produced
three wrong conclusions in this study."""
noisy = summarize([_obs("a", 1, 60), _obs("a", 2, 90)], "tg_tps")[0]
assert noisy.noisy
clean = summarize([_obs("b", 1, 88), _obs("b", 2, 90)], "tg_tps", noise_threshold=8.0)[0]
assert not clean.noisy
def test_single_pass_is_not_presented_as_a_result():
text = format_summary(summarize([_obs("a", 1, 80)], "tg_tps"))
assert "single pass" in text
def test_contended_passes_are_counted_not_hidden():
rows = [_obs("a", 1, 80, load=1.0), _obs("a", 2, 40, load=40.0)]
s = summarize(rows, "tg_tps")[0]
assert s.n_busy == 1
assert "under load" in format_summary([s])
def test_failed_runs_do_not_enter_the_summary():
rows = [_obs("a", 1, 80), _obs("a", 2, 0, ok=False)]
s = summarize(rows, "tg_tps")[0]
assert s.n == 1
def test_arm_order_rotates_between_passes(monkeypatch):
"""Interleaving alone leaves arm 0 permanently first, so whatever the host
is doing at the start of a pass always lands on the same arm. This test
previously asserted the un-rotated order, which is how that survived."""
order = []
def fake_run(arm, pass_no, timeout, keys):
order.append((pass_no, arm.tag))
return _obs(arm.tag, pass_no, 50.0)
monkeypatch.setattr("bench_harness.run_once", fake_run)
arms = [Arm("a", ["true"]), Arm("b", ["true"]), Arm("c", ["true"])]
run_grid(arms, passes=3, metric="tg_tps", timeout=1, keys=["tg_tps"])
assert order == [(1, "a"), (1, "b"), (1, "c"),
(2, "b"), (2, "c"), (2, "a"),
(3, "c"), (3, "a"), (3, "b")]
# every arm still runs once per pass
for p in (1, 2, 3):
assert sorted(t for q, t in order if q == p) == ["a", "b", "c"]
def test_best_is_the_minimum_for_a_memory_metric():
"""Taking the maximum for every metric published the worst memory pass as
the headline figure."""
rows = [Observation("a", 1, {"rss_anon_mb": 2802.0}, 1.0, 1.0, 1.0, True),
Observation("a", 2, {"rss_anon_mb": 2814.0}, 1.0, 1.0, 1.0, True)]
s = summarize(rows, "rss_anon_mb")[0]
assert s.lower_is_better is True
assert s.best == 2802.0
def test_best_arm_sorts_first_in_both_directions():
mem = [Observation("small", 1, {"rss_anon_mb": 2802.0}, 1.0, 1.0, 1.0, True),
Observation("big", 1, {"rss_anon_mb": 3542.0}, 1.0, 1.0, 1.0, True)]
assert [s.tag for s in summarize(mem, "rss_anon_mb")] == ["small", "big"]
assert [s.tag for s in summarize([_obs("slow", 1, 40.0), _obs("fast", 1, 86.6)],
"tg_tps")] == ["fast", "slow"]
@pytest.mark.parametrize("metric,lower", [
("tg_tps", False), ("pp_tps", False),
("rss_anon_mb", True), ("peak_rss_anon_mb", True),
("init_s", True), ("ready_s", True), ("step_ms", True),
])
def test_metric_direction_is_read_from_the_name(metric, lower):
assert metric_is_lower_better(metric) is lower
def test_a_custom_noise_threshold_does_not_leak_into_the_next_call():
"""The threshold used to be written into a module global after the rows
were built, so one call's setting silently changed the next one's."""
loose = summarize([_obs("a", 1, 60), _obs("a", 2, 90)], "tg_tps",
noise_threshold=50.0)[0]
assert not loose.noisy
strict = summarize([_obs("a", 1, 60), _obs("a", 2, 90)], "tg_tps")[0]
assert strict.noisy
def test_provenance_records_what_makes_a_number_retractable():
p = provenance({"model": "spark2_5-int4-g128"})
assert p["model"] == "spark2_5-int4-g128"
assert set(p) >= {"recorded_at", "host", "commits", "env", "n_affinity"}
assert set(p["commits"]) == {"embedding_infer", "vllm_omni", "vllm"}
def test_scrapes_the_last_json_object_a_run_printed():
from bench_harness import _scrape
stdout = 'INFO noise {"not": "it"}\nmore logs\n{"tg_tps": 86.6, "pp_tps": 3347}\n'
assert _scrape(stdout, ["tg_tps", "pp_tps"]) == {"tg_tps": 86.6, "pp_tps": 3347.0}
def test_end_to_end_against_a_real_subprocess(tmp_path):
"""The arm really is a subprocess, so a trivial one must round-trip."""
script = tmp_path / "emit.py"
script.write_text('print("noise"); print(\'{"tg_tps": 42.0}\')')
arm = Arm("trivial", ["python3", str(script)])
obs = run_grid([arm], passes=2, metric="tg_tps", timeout=60,
keys=["tg_tps"], settle_s=0)
assert all(o.ok for o in obs)
s = summarize(obs, "tg_tps")[0]
assert s.best == 42.0 and s.n == 2 and s.spread_pct == 0.0
def test_a_failing_arm_is_recorded_with_its_error(tmp_path):
arm = Arm("broken", ["python3", "-c", "import sys; sys.exit(3)"])
obs = run_grid([arm], passes=1, metric="tg_tps", timeout=60,
keys=["tg_tps"], settle_s=0)
assert obs[0].ok is False
assert summarize(obs, "tg_tps") == []
# ------------------------------------------------------- contention guard
def test_parse_cores_handles_ranges_and_singletons():
assert parse_cores("0-3,8") == [0, 1, 2, 3, 8]
assert parse_cores("5") == [5]
assert parse_cores("2-1") == [] # empty range, not an error
assert parse_cores("") == []
def test_core_utilization_reports_the_requested_cores():
"""Load average is a whole-host number and this host has 224 cores, so it
says nothing about the 24 a run is pinned to."""
usage = core_utilization([0, 1], window_s=0.05)
assert set(usage) <= {0, 1}
assert all(0.0 <= v <= 100.0 for v in usage.values())
def test_preflight_refuses_a_sustained_straggler(monkeypatch):
"""One heavily loaded core gates every OpenMP barrier, so it costs far more
than its 1/24 share of capacity."""
monkeypatch.setattr("bench_harness.core_utilization",
lambda cores, window_s=0.75: {0: 3.0, 1: 91.0})
check = preflight([0, 1])
assert check["clear"] is False
assert check["busy_cores"] == {1: 91.0}
def test_preflight_passes_on_idle_cores(monkeypatch):
monkeypatch.setattr("bench_harness.core_utilization",
lambda cores, window_s=0.75: {0: 1.0, 1: 2.0})
assert preflight([0, 1])["clear"] is True
def test_preflight_ignores_a_transient_spike(monkeypatch):
"""A flat per-core threshold over one window refused three consecutive
launches on cores that were idle seconds earlier. Load is the minimum of
two windows, so a blip in one of them is not load."""
windows = iter([{0: 1.0, 1: 30.0}, {0: 1.0, 1: 1.0}])
monkeypatch.setattr("bench_harness.core_utilization",
lambda cores, window_s=0.75: next(windows))
check = preflight([0, 1])
assert check["clear"] is True
assert check["utilization"][1] == 1.0
def test_preflight_refuses_when_aggregate_capacity_is_stolen(monkeypatch):
"""No single straggler, but a third of every core is someone else's."""
monkeypatch.setattr("bench_harness.core_utilization",
lambda cores, window_s=0.75: {c: 33.0 for c in cores})
check = preflight(list(range(24)))
assert check["clear"] is False
assert check["stolen_pct"] == 33.0
assert check["busy_cores"] == {} # none individually over 50%
def test_one_blipping_core_out_of_many_does_not_block_a_run(monkeypatch):
"""1 core of 24 at 30% is ~1.25% of capacity; refusing on that makes the
guard useless rather than strict."""
monkeypatch.setattr("bench_harness.core_utilization",
lambda cores, window_s=0.75: {c: (30.0 if c == 11 else 1.0)
for c in cores})
assert preflight(list(range(24)))["clear"] is True
def test_host_lock_excludes_a_second_benchmark(tmp_path):
"""Two sessions benchmarking the same cores wrecked several measurements."""
path = str(tmp_path / "bench.lock")
with HostLock(path, note="first"):
with pytest.raises(SystemExit) as excinfo:
with HostLock(path, note="second"):
pass
assert "another benchmark holds" in str(excinfo.value)
# released again afterwards
with HostLock(path, note="third"):
pass
def test_host_lock_records_who_holds_it(tmp_path):
path = str(tmp_path / "bench.lock")
with HostLock(path, note="peak_rss_anon_mb"):
held = open(path).read()
assert "peak_rss_anon_mb" in held and str(os.getpid()) in held
# ------------------------------------------------------- regression gates
def _summary(tag, metric, median, lower):
from bench_harness import ArmSummary
return ArmSummary(tag=tag, metric=metric, best=median, median=median,
spread_pct=0.0, n=3, n_busy=0, lower_is_better=lower)
EXPECT = {"arms": {"w4a16": {"rss_anon_mb": 3541.8, "tg_tps": 80.0}},
"bands_pct": {"rss_anon_mb": 1.5}}
def test_memory_regression_outside_the_band_fails():
rows = check_expectations([_summary("w4a16", "rss_anon_mb", 3900.0, True)], EXPECT)
assert rows[0]["status"] == "REGRESSION"
assert rows[0]["drift_pct"] > 1.5
def test_memory_inside_the_band_passes():
rows = check_expectations([_summary("w4a16", "rss_anon_mb", 3560.0, True)], EXPECT)
assert rows[0]["status"] == "ok"
def test_a_large_improvement_is_not_reported_as_a_regression():
rows = check_expectations([_summary("w4a16", "rss_anon_mb", 2800.0, True)], EXPECT)
assert rows[0]["status"] == "improved"
def test_throughput_is_not_gated_because_this_host_cannot_resolve_it():
"""tg_tps swings ~30% run to run here, so any band wide enough not to fire
constantly is too wide to catch a real regression."""
rows = check_expectations([_summary("w4a16", "tg_tps", 55.0, False)], EXPECT)
assert rows[0]["status"] == "ungateable"
def test_an_unlisted_arm_is_reported_not_silently_passed():
rows = check_expectations([_summary("brand-new", "rss_anon_mb", 100.0, True)], EXPECT)
assert rows[0]["status"] == "unlisted"
# ---------------------------------------- refusing to rank inside the noise
def test_a_difference_inside_the_noise_is_not_presented_as_a_ranking():
"""An 8% tg_tps gap on a host that swings 30% is not a result; publishing
one is how the W4A8/W4A16 ordering flipped between grids."""
rows = [_obs("a", 1, 86.0), _obs("a", 2, 80.0),
_obs("b", 1, 84.0), _obs("b", 2, 78.0)]
text = format_summary(summarize(rows, "tg_tps"))
assert "NOT A RANKING" in text
assert "profile_cpu_step.py" in text
def test_a_real_difference_is_still_reported_as_one():
rows = [_obs("fast", 1, 86.0), _obs("fast", 2, 86.2),
_obs("slow", 1, 41.0), _obs("slow", 2, 41.1)]
text = format_summary(summarize(rows, "tg_tps"))
assert "NOT A RANKING" not in text
def test_memory_arms_that_really_differ_are_ranked():
rows = [Observation("small", p, {"rss_anon_mb": v}, 1.0, 1.0, 1.0, True)
for p, v in ((1, 2802.0), (2, 2814.0))]
rows += [Observation("big", p, {"rss_anon_mb": v}, 1.0, 1.0, 1.0, True)
for p, v in ((1, 3541.0), (2, 3542.0))]
assert indistinguishable(summarize(rows, "rss_anon_mb")) is None