Repository navigation
fix(vision-suite): summarize_reps reports the context-ladder rung; retire summarize_lowtemp - #197
Conversation
A remote agent could not reach :11436 while the server was up and answering locally. Cause: OLLAMA_HOST was hardcoded to 127.0.0.1, inherited from the original /tmp restart script, so the listener was loopback-only — `TCP 127.0.0.1:11436`, not `TCP *:11436`. The failure is silent from the host, where curl succeeds and nothing looks wrong. BIND now defaults to 0.0.0.0, with OLLAMA_BIND to narrow it. Requested explicitly; the script states what it means rather than leaving it implicit: ollama has no authentication, so every interface this binds reaches /api/generate, /api/pull, /api/delete and the whole model store with no credential. OLLAMA_BIND=127.0.0.1 restores loopback-only, and that is the right setting on any host whose network you do not control. Verified: listener is now TCP *:11436, and the version endpoint answers on both 127.0.0.1 and the LAN address 10.1.1.84. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…tire summarize_lowtemp TWO ADRs I HAD NOT READ ALREADY SETTLED THIS. ADR 0029 makes THINK_TEMPERATURE default 0 and records the 0.01 variant as measured and rejected, and SPEC H4a makes the context-ladder rung a result rather than plumbing — the runner now refuses (exit 2) a CTX_MAX that leaves no rung above the think-on start, which is exactly the pin I had armed on the deferred bf16 cell an hour earlier. What was actually missing: summarize_reps.py never rendered the rung, though ADR 0029 requires think-on tables to report it, SPEC H4a calls it a throughput fact about the model, and ADR 0012 rule 8 says the reported num_ctx is the final successful rung and a first-class result. Its own test fixtures carry num_ctx and nothing read it. Adds **num_ctx rung** and **num_predict** as the first two rows, before the metrics, because they condition everything under them: two arms measured at different rungs are not comparable on tok/s or req/h at all — KV size drives decode speed — so a table without the rung invites the one comparison it cannot support. Distinct values within an arm render as "a/b ⚠" rather than collapsing to the first, because repeats of one arm are supposed to sit at one rung and more than one means it escalated between repeats. Retires summarize_lowtemp.py. Its arm is dead under ADR 0029, and the three things it did that summarize_reps did not — capped-cell exclusion, num_ctx columns, a no-result count — are unnecessary once the ladder always runs: a cell either finishes at some rung, which is the result, or exhausts the ladder, which the runner reports as NOT CONVERGED. Four references repointed. The negative-result document it rendered stays; it is the evidence ADR 0029 rests on. Verified: test_summarizers.py 9/9, and the rung row renders 65536/57344 for qwen3.6-nvfp4 think-on against 32768/24576 for nemotron3-bf16. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Reviewing as consolidator; I wrote H4a and used The rung going first is correct, and the reason given is the right reason.
That is exactly what H4a was for, and the gap you found is real: I wrote the rule that the rung is a result,
Retiring
|
The negative-result document's status amendment said ADR 0029 "adopts
temperature 0.01 for think-on deliberately". It does not. Both the ADR's own
status line and the code disagree:
ADR 0029 THINK_TEMPERATURE default is 0; the 0.01 variant was
measured and rejected
sampling.py:92 THINK_TEMPERATURE = float(os.environ.get("THINK_TEMPERATURE", "0"))
Left as written it tells a reader the fork measures think-on at 0.01 when it
measures at 0 — and this document is the cost sheet ADR 0029 cites, so it is
exactly where someone would go to check.
Also states the direction of the error, which matters for reading the table
below: 0 is STRICTER than the 0.01 measured here, so these numbers are a floor
on the cost of the policy, not a ceiling. The two models that lose six of eight
cells at 0.01 do not lose fewer at 0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
#197's rung row scans every section of every run, so the finetext block sets it off on its own. vision_suite.py:1136 gives finetext `NUM_CTX or 32768` where every other section takes `NUM_CTX or 16384`, so with NUM_CTX unset the two differ in every run ever measured — and the qwen3.8 ROCm arms, whose vision tests all sat at 16384, rendered "16384/32768 ⚠". A warning that fires on every arm carries no information. The docstring's own justification is escalation *between repeats*, which is a different axis from sections *within* a run, and the implementation collapsed both into one list. Sections that own their window are now excluded from the ⚠ and annotated instead: "16384 (finetext 32768)". The alarm is left for what the docstring describes. Requested-over-served is kept and now has a test. It looks wrong — two pre-#153 finetext blocks record req_num_ctx 32768 against num_ctx 16384 — but those are exactly the files where `num_ctx` carries the pre-fold defect of reporting the suite default, so served-first would report a block at a window it did not run at. The qwen3.8 ROCm campaign is re-rendered with both rows, and two things it never disclosed are now on the page. Its finetext arm ran at 32768/4000, not the "16384 throughout" the prose claimed. And the pooled n=5 think-on arm is not homogeneous in num_predict — four runs at 2200 and the NUM_PREDICT=4400 ceiling diagnostic at 4400 — which is the one ⚠ that survives scoping. Pooling those is defensible only because no think-on cell was capped, and the doc now says so rather than leaving it implicit. Mutation-tested: unscoping the warning, dropping the annotation, preferring the served value, and removing the ⚠ entirely each turn the new tests red. Co-authored-by: Local Dev <local@localhost> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…-18 audit (#204) Eight sites where a label described something other than the field under it. Recorded on #195 and left open; closed here. LABELS THAT OVERSTATE WHAT WAS CHECKED - "✅ all Qs + bbox" gates q1, q2 and q4-bbox. The multi-image prompt asks FOUR questions and q3 is never scored, so a cell that answered q3 wrongly still read as a clean sweep. Now "✅ q1 + q2 + q4-bbox". - "name_bbox hits" is a coarse pixel-band match, not an IoU hit; the column now says in-band. - "finetext fabricated" is total_found - sum(recall), which counts every entry that matched no gold code -- malformed and duplicate entries included, not only invented ones. Now "finetext unmatched", which is what the arithmetic supports. EXPLANATIONS THAT NAME THE WRONG LIMIT - summarize_contract_matrix's footnote said `cap` meant generation "never terminated at that window", attributing to num_ctx a stop that num_predict caused. They are different limits and the whole point of the marker is which. - docs/api.md defined eval_count as "number of tokens in the response". It is every generated token, thinking included, and with think+format the total across both passes -- normative here as spec R6, asserted by TestChatThinkFormatMarkerStop (109 = 100 thinking + 9 content), and the reason the vision suite's token column had to stop saying "Answer tok". FIELDS THAT WERE SIMPLY THE WRONG ONE - ctx_for read num_ctx where req_num_ctx is the requested window. Files written before the num_ctx fold (#153) recorded the SUITE default in num_ctx for the finetext block while req_num_ctx kept what was asked, so served-first reports those rows at a window their finetext never ran at. Two of the seven committed runs change, both from "16384" to "16384/32768 ⚠" -- revealing a mixed window that was hidden, not inventing one. Same rule summarize_reps' _window already uses, so the two agree. - summarize_head_to_head's "(?)" marker means "recorded before req_num_ctx existed", but it also fired on any cell sourced from the pre-fold ft_<tag>.json path, which never wrote that field. It now falls back to num_ctx, so the marker identifies what it claims to. - extbench recorded os.environ["THINK"] verbatim while gen() gates on `!= "on"`, so THINK=true wrote "true" into the summary of a run that sent think=False. Records both now: think_env and think_on. Four tests pin the corrected pairings. summarize_lowtemp's "mean IoU (scored cells)" -- the ninth finding, and the one that inflated a mean by dropping genuine 0.0 IoUs on a truthiness check -- needs no fix: #197 retired the file. Co-authored-by: Local Dev <local@localhost> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Two ADRs already settled most of this
ADR 0029 makes
THINK_TEMPERATUREdefault 0 and records the0.01variant as measured and rejected. SPEC H4a makes the context-ladder rung a result, not plumbing — andrun_engine_compare.shnow refuses (exit 2) aCTX_MAXthat leaves no rung above the think-on start.What was actually missing
summarize_reps.pynever rendered the rung, though ADR 0029 requires think-on tables to report it, H4a calls it a throughput fact about the model, and ADR 0012 rule 8 says the reportednum_ctxis the final successful rung and a first-class result. Its own test fixtures carrynum_ctxand nothing read it.The rung goes first, before the metrics, because it conditions everything under it: two arms at different rungs are not comparable on tok/s or req/h at all — KV size drives decode speed — so a table without it invites the one comparison it cannot support.
Distinct values within an arm render
a/b ⚠rather than collapsing to the first: repeats of one arm are supposed to sit at one rung, and more than one means it escalated between repeats.Retires
summarize_lowtemp.pyIts arm is dead under ADR 0029. The three things it did that
summarize_repsdidn't — capped-cell exclusion,num_ctxcolumns, ano resultcount — are unnecessary once the ladder always runs: a cell either finishes at some rung, which is the result, or exhausts the ladder, which the runner reports asNOT CONVERGED.Four references repointed. The negative-result document it rendered stays — it's the evidence ADR 0029 rests on.
Verified
test_summarizers.py9/9.🤖 Generated with Claude Code