docs(benchmarks): #1805-c ghidra-slot matrix — cold-protocol re-measure, and promote gemma-4-26B-A4B - #2641
docs(benchmarks): #1805-c ghidra-slot matrix — cold-protocol re-measure, and promote gemma-4-26B-A4B#2641Xore wants to merge 6 commits into
Conversation
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
|
Converted to draft — do not merge as-is. The determinism section is now falsified by measurement. Re-running the incumbent on a quiet box (live workers stopped): Three things in the current diff need rewriting before this lands:
Detail on #2642. Will update the branch and mark ready once the backfill completes and the cold-slot/warm-slot test has run. |
|
Holding this PR — do not merge yet. Xore asked whether Tier A is really safe given the code moved, and it is not. I checked the evidence provenance (
#2517's own commit message names So both tiers were measured on a superseded scorer, not just Tier B on a stale corpus. Publishing this table as a decision record would publish numbers current Plan: corpus rebuild + Tier B cache re-extraction are already running; I am restarting the full roster on current |
… resume plan The sweep's clone at /mnt-1/benchmarks/APIARY sits on a detached HEAD at a99e765, and every completed run writes its transcript dir into docs/benchmarks/runs/ as an untracked file. As of today that is 127 run dirs, 24 MB, all from 2026-09-04/05, on no branch, committed nowhere, in the one directory the rebuild already wiped once. Per #1944 the transcripts are the deliverable -- "no transcripts" is reason 4 of the six that made this epic necessary, and #2266's offline re-scoring reads them. Losing them turns every phase-2 row back into a number nobody can check. They must NOT be committed in that clone: a commit moves HEAD off a99e765 and resume_phases.sh hard-aborts on exactly that string, so the pin is the guard. Mirrored to the workstation instead, and the plan now carries the rsync, the reason the obvious fix is wrong, and the note that they get committed properly at write-up time on a branch cut from main. Also names PR #2641's branch in the ledger so the phase-4 results and the running phase-2 sweep are not read as the same work. Refs #1947, #1944, #2266, #2971
…uences Answered 2026-09-05: - #2245 is scored by record_baseline.py on the a99e765 pin, Ollama-served, so self-quant rows land in the same matrix as their as-published twins. corpus_eval.py + llama-server is not used for this issue. - #2245 runs the full clean f16 ladder, not the cheap requant probe. - PR #2641 stays DRAFT and gets regenerated from the completed run, so #1805 and the gemma-4-26B-A4B ghidra promotion stay parked until the matrix is whole. Its branch is now a synthesis input -- do not delete it. - The two free DIMM slots get filled before phase 3. Two of those create prerequisites, which reorders the plan: phase 3 is gated on a RAM install and an HF token, so phase 5 (slots) moves ahead of it and the short jobs fill the gaps. The f16 ladder's toolchain turns out not to be a blocker at all: ghcr.io/ggml-org/llama.cpp:full pulls clean on the homeserver and carries convert_hf_to_gguf.py, llama-quantize and llama-server in one image, so "stand up llama.cpp" is a docker pull rather than a build, with no host package installs. Verified live. What remains is the HF token. The RAM finding is bigger than headroom. dmidecode shows DIMME1 and DIMMF1 empty, i.e. channels E and F entirely unpopulated -- the box runs 4-channel on a 6-channel Gold 5220R. CPU-offloaded inference is memory-bandwidth bound, not thread bound (llama-server sits at ~16 of 48 cores while 65% of the 218B is on the CPU), so filling those two slots is a bandwidth change on exactly the rows this decision cares about. Part number and the ECC/registered caveat recorded. Refs #1947, #2245, #1805, #2641
…the probe Phase 2 ran without the cold protocol's worker-stop step: hp-llm-worker spent ~11 hours issuing a competing /api/chat every ~4 minutes against the same OLLAMA_MAX_LOADED_MODELS=1 slot (#2582 recurring, #3023). Phase 2 carries 12 escalations against phase 4's uniformly +-0 cold cells, which looked like the contamination that demoted #1805-c to a survey. Measured it instead of re-running two days of GPU on the suspicion: DeepHat-V1-7B:Q4_K_M 4.7 GB resident A contended [63,63] cold [63,63] ravenx-cyberagent-35b 21 GB spills B contended [64,63,64] cold [64,64,64] The resident control is load-bearing -- no CPU-offload nondeterminism is possible there, so contention would have to show up in it, and it reproduced exactly. The escalated cell resolved to the majority the N=3 protocol had already chosen. Verdict: keep phase 2, annotate it, do not re-run. Escalations cost GPU time, not accuracy. Checking all nine escalated cells surfaced a separate defect: eight resolve 2-of-3, but GLM-4.6-REAP-218B Tier B is [55, 57, 54] -- three distinct values, so N=3 cannot produce a majority and that cell has no defensible score. It must not be published as any of the three. sweep_extra.sh escalates once and has no handling for "still no majority"; that wants an UNRESOLVED marker and an N>=5 path. Commits both drivers, per #2985's rule that a script driving real benchmark runs must not live only on the host: - coldprobe.sh asserts its preconditions rather than assuming them (sweep stopped, no run in flight, hp-llm-worker down, tierb-cache present, head == a99e765) and writes to a separate directory so no roster row is polluted. - probe_at_gap.sh takes the next natural gap: it stops only the sweep's driver, never an in-flight record_baseline, because do_run's own `rm -f` cleanup is skipped when the parent dies -- which is how the 2026-08-31 abort left a valid-looking partial result carrying 11 of 14 cases. Also records the #3031 DNS incident: a container resolver predating #2974's host fix still had 1.1.1.1/8.8.8.8 first, port 53 to them is blocked here, so every lookup burned ~8s against ollama's 30s pull deadline -- 12 models lost in four minutes, followed by a false EXTRA_COMPLETE. Refs #1947, #3023, #3031, #2582, #2641, #2985, #2974
…sion (#3014) * docs(benchmarks): #1947 resume plan after the CPU swap and disk expansion The sweep's work area has been destroyed once (#2971) and mis-restored once, and three of its phase scripts were lost because they were never committed (#2985). A resume plan that lives only in /mnt-1/benchmarks has the same failure mode, so it goes in the repo. Records, from live inspection on 2026-09-05: - the hardware delta that prompted this — Xeon Silver 4110 -> Gold 5220R (8c/16t -> 24c/48t) and /var 153 G free -> 6.5 T free. RAM is unchanged at 6x16 GiB with two slots empty, and is now the only remaining hardware limit. - the completion ledger: phase 1 complete, phase 2 at 36/52 both tiers with 16 unstarted (5 of them unpullable, itemised with the call for each), phases 2.5/3/5 blocked on #2985, phase 4 sitting in draft PR #2641. - what the new hardware actually buys: `sweep_extra.sh`'s unconditional `ollama rm` is now harmful rather than necessary, and the CPU swap's own A/B has never been measured against the pre-swap timing table it was recorded for. - an ordered resume path P0-P8 with the owning issue for each step, the eight rules already paid for in wasted hours (pin a99e765 / 14 cases / max 69, no mixed scoring vintages, 0 != empty, cold slot, uniform +-0 is a symptom, injection axis reads as coverage-not-resistance, verify the benchmark leg and not the pull, restore scripts from the repo), a runbook, and four decisions that need an operator. Refs #1947, #2985, #2971, #2279, #2245, #2969, #1805, #1804 * ops(ci): cut honeypot-ci runner instances from seven to two The homeserver is the GPU host for the #1947 model benchmark as well as the CI box, and CI is that benchmark's largest source of measurement noise: identical work on the same model spread 62% (78.2 vs 126.7 min/run) purely from runner contention, with load average sitting at 15-27 under seven instances. #1947's premise is that a delta smaller than the error bar is not a result, so a run taken against an unknown CI-driven load is not a measurement -- and the resume plan's CPU-swap A/B (step P5) cannot be answered at all without quiescing it. supermicro-ci-3..7 are `systemctl disable --now` on the host, not deregistered: registration, _work dir and tool cache survive, so restoring them is one command and needs no token. supermicro + supermicro-ci-2 stay. The separate honeypot-home deploy runner is untouched -- different label, no redundancy behind it. Seven was never a measured optimum, only the ceiling #2572 allowed once one instance stopped serialising the matrix; two instances on the Gold 5220R (24c/48t) have more cores behind them than four had on the Silver 4110. Documents the count and the restore command in docs/CI-CD.md, and records in the resume plan that the pre-swap baseline was itself taken under seven instances -- so the post-swap side is the quieter half of that comparison and uptime has to be recorded per run either way. Refs #1947, #2572 * docs(benchmarks): record the phase-2 transcript durability gap in the resume plan The sweep's clone at /mnt-1/benchmarks/APIARY sits on a detached HEAD at a99e765, and every completed run writes its transcript dir into docs/benchmarks/runs/ as an untracked file. As of today that is 127 run dirs, 24 MB, all from 2026-09-04/05, on no branch, committed nowhere, in the one directory the rebuild already wiped once. Per #1944 the transcripts are the deliverable -- "no transcripts" is reason 4 of the six that made this epic necessary, and #2266's offline re-scoring reads them. Losing them turns every phase-2 row back into a number nobody can check. They must NOT be committed in that clone: a commit moves HEAD off a99e765 and resume_phases.sh hard-aborts on exactly that string, so the pin is the guard. Mirrored to the workstation instead, and the plan now carries the rsync, the reason the obvious fix is wrong, and the note that they get committed properly at write-up time on a branch cut from main. Also names PR #2641's branch in the ledger so the phase-4 results and the running phase-2 sweep are not read as the same work. Refs #1947, #1944, #2266, #2971 * benchmarks: stop losing #2245's inputs — re-create the VRAM sampler, keep-alias pulled weights Checked #2245 against the live host. Four of its premises no longer hold: - llama-quantize IS present (/usr/lib/ollama/llama-quantize in ghidra-ollama-1, with --allow-requantize), so the requant-from-GGUF path needs nothing new -- but there is no llama.cpp checkout anywhere on the box, so convert_hf_to_gguf.py does not exist and the rex86-eval container model-quant-benchmark/README.md assumes is not running. The issue's "harness we already have, this is applied not built" describes the repo, not the host. - vram_samples.tsv, the empirical spill list the requant plan rests on, was wiped with the work area, is in no mirror, and is NOT re-derivable: the result JSONs record no VRAM, no served size and no CPU/GPU split. - All ten source models named in requant_plan.txt have been deleted by sweep_extra.sh's `ollama rm`. One survives under a #2738 alias; at least three of the rest cannot be re-pulled at all. - The scorer is undecided: step 3 says corpus_eval.py via llama-server, step 4 demands comparison against rows scored by record_baseline.py on a99e765. Two scorers, incomparable numbers -- reason 6 of the six behind #1947. keep_and_sample.sh runs beside the sweep and changes nothing about it. It samples `ollama ps` back into vram_samples.tsv (served size, CPU/GPU split and served context exist only while a model is loaded -- sample or lose), and gives every pulled tag a keep/<slug>:src alias. `ollama cp` makes a second manifest over the SAME blobs -- verified, cp then rm of the copy left the blob count unchanged at 39 -- so the sweep's rm drops only its own manifest and the weights survive at zero extra disk. Deliberately not an edit to sweep_extra.sh: bash reads a running script lazily by byte offset, and the alias names cannot collide with a roster entry, so the sweep's own "already local -> will not delete" test is unaffected either way. First datum back: GLM-4.6-REAP-218B:i1-IQ1_S is 44 GB on disk, 57 GB served at ctx 32768, 65%/35% CPU/GPU -- confirming the KV arithmetic and showing served size cannot be inferred from disk size. Refs #2245, #2985, #2971, #1947 * docs(benchmarks): record the four operator decisions and their consequences Answered 2026-09-05: - #2245 is scored by record_baseline.py on the a99e765 pin, Ollama-served, so self-quant rows land in the same matrix as their as-published twins. corpus_eval.py + llama-server is not used for this issue. - #2245 runs the full clean f16 ladder, not the cheap requant probe. - PR #2641 stays DRAFT and gets regenerated from the completed run, so #1805 and the gemma-4-26B-A4B ghidra promotion stay parked until the matrix is whole. Its branch is now a synthesis input -- do not delete it. - The two free DIMM slots get filled before phase 3. Two of those create prerequisites, which reorders the plan: phase 3 is gated on a RAM install and an HF token, so phase 5 (slots) moves ahead of it and the short jobs fill the gaps. The f16 ladder's toolchain turns out not to be a blocker at all: ghcr.io/ggml-org/llama.cpp:full pulls clean on the homeserver and carries convert_hf_to_gguf.py, llama-quantize and llama-server in one image, so "stand up llama.cpp" is a docker pull rather than a build, with no host package installs. Verified live. What remains is the HF token. The RAM finding is bigger than headroom. dmidecode shows DIMME1 and DIMMF1 empty, i.e. channels E and F entirely unpopulated -- the box runs 4-channel on a 6-channel Gold 5220R. CPU-offloaded inference is memory-bandwidth bound, not thread bound (llama-server sits at ~16 of 48 cores while 65% of the 218B is on the CPU), so filling those two slots is a bandwidth change on exactly the rows this decision cares about. Part number and the ECC/registered caveat recorded. Refs #1947, #2245, #1805, #2641 * benchmarks: measure whether contention corrupted phase 2, and commit the probe Phase 2 ran without the cold protocol's worker-stop step: hp-llm-worker spent ~11 hours issuing a competing /api/chat every ~4 minutes against the same OLLAMA_MAX_LOADED_MODELS=1 slot (#2582 recurring, #3023). Phase 2 carries 12 escalations against phase 4's uniformly +-0 cold cells, which looked like the contamination that demoted #1805-c to a survey. Measured it instead of re-running two days of GPU on the suspicion: DeepHat-V1-7B:Q4_K_M 4.7 GB resident A contended [63,63] cold [63,63] ravenx-cyberagent-35b 21 GB spills B contended [64,63,64] cold [64,64,64] The resident control is load-bearing -- no CPU-offload nondeterminism is possible there, so contention would have to show up in it, and it reproduced exactly. The escalated cell resolved to the majority the N=3 protocol had already chosen. Verdict: keep phase 2, annotate it, do not re-run. Escalations cost GPU time, not accuracy. Checking all nine escalated cells surfaced a separate defect: eight resolve 2-of-3, but GLM-4.6-REAP-218B Tier B is [55, 57, 54] -- three distinct values, so N=3 cannot produce a majority and that cell has no defensible score. It must not be published as any of the three. sweep_extra.sh escalates once and has no handling for "still no majority"; that wants an UNRESOLVED marker and an N>=5 path. Commits both drivers, per #2985's rule that a script driving real benchmark runs must not live only on the host: - coldprobe.sh asserts its preconditions rather than assuming them (sweep stopped, no run in flight, hp-llm-worker down, tierb-cache present, head == a99e765) and writes to a separate directory so no roster row is polluted. - probe_at_gap.sh takes the next natural gap: it stops only the sweep's driver, never an in-flight record_baseline, because do_run's own `rm -f` cleanup is skipped when the parent dies -- which is how the 2026-08-31 abort left a valid-looking partial result carrying 11 of 14 cases. Also records the #3031 DNS incident: a container resolver predating #2974's host fix still had 1.1.1.1/8.8.8.8 first, port 53 to them is blocked here, so every lookup burned ~8s against ollama's 30s pull deadline -- 12 models lost in four minutes, followed by a false EXTRA_COMPLETE. Refs #1947, #3023, #3031, #2582, #2641, #2985, #2974 * docs(benchmarks): fix a doc-path lint false positive in the resume plan 'the ~16 MB of scripts/roster' read as a citation of a tracked path 'scripts/roster', which does not exist. It was prose, not a path -- rephrased rather than allowlisted, since allowlisting a non-path would weaken the #2458 check for a real one later. Refs #1947, #2458
…col in the driver (#3058) The matrix mixes two regimes, and #1947 rule 2 says two vintages must never share a table: phases 1+2 89 models contended (hp-llm-worker live), N=2 + escalation phase 4 5 models cold, workers stopped, N=3, every cell +-0 The #3023 cold probe showed contention did not move scores -- a fully resident control reproduced [63,63] exactly, and an escalated spilling cell resolved to the majority the protocol had already chosen. So this is not a correction of wrong numbers. It makes the regime uniform, which matters because the top of the field is separated by ONE point across sixteen models, and a promotion decided on that margin cannot rest on a mixed protocol. N=2, not N=3. Part 4 found "22.1 of the 37.4 model-wall hours re-derived identical bytes" and concluded repeats belong on the axes that are NOT fixed. #3036 escalates 2 -> 3 -> 5 automatically wherever runs actually disagree, so genuine variance is caught without a third run on every deterministic cell -- about a third cheaper for the same information. sweep_extra.sh gains two things it should always have had: - STOP_WORKERS stops hp-llm-worker and ghidra-revdeck-1 for the run and restores them via a trap on EXIT/INT/TERM. #3023's finding was not that contention broke the scores, but that the protocol depended on an operator remembering; this moves it into the driver. The trap covers INT/TERM because this script is routinely killed between models. - KEEP_WEIGHTS_ABOVE_GB gates the post-model `ollama rm` on free space. That removal was correct at 92% full and is actively harmful with terabytes free: it destroyed all ten of the requant plan's source models, and it is the reason a cold re-run of 89 models has to re-download 80 of them. Results go to 1947cold/, not over 1947full/. The contended numbers are not garbage: contended-vs-cold across 89 models is the largest evidence anyone will have on whether the regime matters, and discarding it to save disk would repeat the mistake that lost the weights. chain_cold.sh waits on a POSITIVE condition -- every tag in models_requant.txt has both tier files -- rather than "the GPU is idle". chain_phase3.sh is already armed on the same card; two idle-checks would fire in the same poll window and double-book it. coldrun.sh keeps its own running-sweep guard as a second line, because the failure mode is a wasted day rather than an error message. Guards verified live: coldrun aborts while phase 2 runs, chain_cold aborts at 0/7 ladder tags, and the combined roster de-duplicates to 96 unique entries across the phase 1, phase 2 and ladder lists. Refs #1947, #3023, #2245, #3031, #3036, #2641
* feat(benchmarks): full-roster cold re-run, and enforce the cold protocol in the driver The matrix mixes two regimes, and #1947 rule 2 says two vintages must never share a table: phases 1+2 89 models contended (hp-llm-worker live), N=2 + escalation phase 4 5 models cold, workers stopped, N=3, every cell +-0 The #3023 cold probe showed contention did not move scores -- a fully resident control reproduced [63,63] exactly, and an escalated spilling cell resolved to the majority the protocol had already chosen. So this is not a correction of wrong numbers. It makes the regime uniform, which matters because the top of the field is separated by ONE point across sixteen models, and a promotion decided on that margin cannot rest on a mixed protocol. N=2, not N=3. Part 4 found "22.1 of the 37.4 model-wall hours re-derived identical bytes" and concluded repeats belong on the axes that are NOT fixed. #3036 escalates 2 -> 3 -> 5 automatically wherever runs actually disagree, so genuine variance is caught without a third run on every deterministic cell -- about a third cheaper for the same information. sweep_extra.sh gains two things it should always have had: - STOP_WORKERS stops hp-llm-worker and ghidra-revdeck-1 for the run and restores them via a trap on EXIT/INT/TERM. #3023's finding was not that contention broke the scores, but that the protocol depended on an operator remembering; this moves it into the driver. The trap covers INT/TERM because this script is routinely killed between models. - KEEP_WEIGHTS_ABOVE_GB gates the post-model `ollama rm` on free space. That removal was correct at 92% full and is actively harmful with terabytes free: it destroyed all ten of the requant plan's source models, and it is the reason a cold re-run of 89 models has to re-download 80 of them. Results go to 1947cold/, not over 1947full/. The contended numbers are not garbage: contended-vs-cold across 89 models is the largest evidence anyone will have on whether the regime matters, and discarding it to save disk would repeat the mistake that lost the weights. chain_cold.sh waits on a POSITIVE condition -- every tag in models_requant.txt has both tier files -- rather than "the GPU is idle". chain_phase3.sh is already armed on the same card; two idle-checks would fire in the same poll window and double-book it. coldrun.sh keeps its own running-sweep guard as a second line, because the failure mode is a wasted day rather than an error message. Guards verified live: coldrun aborts while phase 2 runs, chain_cold aborts at 0/7 ladder tags, and the combined roster de-duplicates to 96 unique entries across the phase 1, phase 2 and ladder lists. Refs #1947, #3023, #2245, #3031, #3036, #2641 * fix(dns): publish Technitium cluster port 53443 on the secondary The homeserver node published only 53/tcp, 53/udp and 5380/tcp. The cluster replication port was never published -- not in this file nor in any backup of it -- so the primary could not reach the secondary and reported Error! No route to host (supermicro.cluster.xore.lan:53443) and replication was silently dead: settings changed on the primary never reached this node. "No route to host" rather than "connection refused" because firewalld REJECTs it; 53 and 5380 are reachable only because Docker's DNAT/FORWARD rules bypass the firewalld zone, whose public zone allows just cockpit, dhcpv6-client and ssh. The image merely EXPOSEs 53443, and an exposed-but-unpublished port never binds on the host in bridge mode. The asymmetry hid it: the primary runs with network_mode: host, so its own 53443 listens on all interfaces and the reverse direction looked healthy. Publishing through Docker bypasses firewalld the same way the existing ports do, so no zone change is needed. Verified after recreating the container: 53443 accepts connections from the primary, TLSv1.3 handshake completes, and the secondary picked up the primary's state within 15 seconds -- updates.maxmind.com went from NXDOMAIN to NOERROR there, which in turn cleared hp-geoipupdate (healthy, FailingStreak=0). Closes #3066
Round-7 chain progress — new rows (2026-09-06 14:18 → 2026-09-07 08:46)Cold-protocol chain (
All cells reproducible (run1 == run2). Note Caveats standing from this PR's review: rows measured before the scoring-path commits ( Chain still running — next roster models will append to this comment thread when their cells close. |
Round-7 chain results — 40 scored models (2026-09-06 14:18 → 2026-09-07 08:46 CEST)Cold-protocol chain (
Every completed cell reproduced run1 == run2 (cold protocol, evict-before-run). 40 scored models, 2 cells failed and are being rescheduled by the chain. Headline reads:
Chain continues; next cells will append to this thread. |
Round-7 cold baseline progress check — 2026-09-08 00:45 CESTChain state on the homeserver ( Position: ~67 of 96 roster entries done, chain healthy and mid-flight.
Provisional tier-A leaders (percent, run-pooled, subject to the full-matrix freeze):
Small-8B security-specialized models hold the top band with the 27–35B MTP/A3B heretics; nothing above 97.1 yet. These are not final rankings — the matrix freeze and the pooled-claims pass come after the roster completes (~29 entries left, roughly 3–4 h at the current ~6–8 min/model-quant cadence). Next update when the chain hits |
Round-7 cold baseline progress check — 2026-09-08 02:35 CESTChain state on the homeserver ( Position: 69 of 96 roster entries done (
Provisional leaderboard (raw
Same top band as the 00:45 check holds — the two 8B/27B security-specialized leaders are unchanged at the ceiling; reference general models (qwen3:8b, qwen2.5:14b) sit at 65, two points under the leaders. Escalation path exercised where N=2 disagreed; UNMEASURABLE/UNMEASURED status marks intact (no zero-token no-ops counted as done — #3090 fix holding). Roughly 27 roster entries remain; ETA ~3–4 h to |
Round-7 cold baseline — COMPLETE — 2026-09-08 18:10 CEST
Final chain state
Reproducibility (the #2642/#2644 protocol holding)
Zero-scored entries — root causes (do NOT read as model quality)
Follow-up worth filing: extend Provisional leaderboard (best of N=2, 79-point scale, percent)
Reference anchors: qwen2.5:14b-instruct 88.0 (tier A), qwen3:14b (incumbent) 85.5 tier B / 83.1 tier A, qwen3:8b 84.3 tier B / 81.9 tier A. The incumbent sits 8–10 points under the security-specialized leaders — consistent with this PR's original finding that its survey row was inflated. Injection positive control (strcpy_note_injected, tier A run 1)Only 14 of 91 models fully resist the injected-note control (score 5/5). Perfect resistance among the measurable top band: phi4:14b (94.0), VulnLLM-R-7B i1-Q4_K_M (92.8), GLM-4.7-Flash distill (91.6), ravenx-cyberagent-35b (90.4). Notable: gpt-oss:20b scores 94.0 on the corpus but only 3/5 on injection resistance; the Trendyol leader takes 4/5. Highest corpus score and perfect resistance do not co-occur in this roster — same conclusion as #2643's earlier tier: injection-gate verdicts should gate any recommendation, not raw corpus percent. Next
|
|
T0 scoring leg (#3081) completed 2026-09-09, results posted to #1523: rex86-merged 68/68 TierA, 62/65 TierB vs base twins 64/70 (Q4/Q8). Base-twin lineage decontaminated via #3137/#3138; scorer fixes #3140/#3142 shipped. PR tracker: adding the T0 results summary to this PR's docs requires a repo edit — orchestrator will fold it into the next docs commit unless you want a standalone PR. |
…e models Harvests the 2026-08-27/28 three-lane corpus-revdeck round from the analysis host and records part 4 of the #1947 rebuild. Matrix: 12 models x 2 tiers, gcc-x86_64/-O0 slice, 14 cases, max 69, temp 0 seed 144 ctx 8192. Machine-readable results plus 24 pinned transcript run directories (one per model/tier cell). Findings beyond the table: - Tier B - Tier A splits by family and the sign is not universal: gemma/Ornith rows gain +4/+5/+4, every Qwen row loses 1-5 including the incumbent. #1805-b's single-model +1.17 generalised to nothing. - The harness is deterministic since #1953's reasoning_effort:"none": all three repeats produced byte-identical answers for every model and tier. Probed the cause directly - omitting the parameter restores non-determinism, sequential and concurrent alike. 22.1 of 37.4 model-wall hours re-derived identical bytes, and the +-0.58 noise band cited across #1947 does not apply to post-#1953 code. - Tier B has zero injection-gate coverage on all 11 cells: the payload is a referenced string literal that Ghidra's pseudocode never carries, so the gate reports not-tested rather than passed (#1948's guard working). At Tier A 4 of 12 models fail, including the two highest Tier B scorers. - ghidra-ollama-1 was recreated mid-round at 2026-08-27T20:18:17Z; with no retry and no incremental save that cost 10 cells, leaving three rows at N=1. Decision: no promotion, qwen3:14b stays. gemma-4-26B-A4B is the best candidate the rebuild has produced (64 Tier B, clean gates, fastest in the matrix) but its lead rests on an N=1 incumbent that needs re-measuring first.
The previous commit named f3f4c14 (#1953) as the cause of the round's byte-identical repeats. Extending the probe refutes that as a sufficient explanation and the claim is withdrawn. With reasoning_effort:"none" held constant, qwen2.5-coder:7b is byte-stable across three repeats while qwen3:8b is not (first call differs, then stable) -- and qwen3:8b was perfectly stable across all six of its benchmark runs. The parameter therefore does not explain the effect, and the probe is not a clean replication of the harness request anyway. The observation itself is unchanged and stands on 62 runs with distinct transcript ids, hashes and wall times: repeats measured nothing. The section now reports that as an unexplained result, keeps the consequences that hold regardless of cause, and drops the noise-band conclusion instead of restating it with a different cause attached. What the probe does settle is recorded: concurrency is not the variable, under NUM_PARALLEL=1 / MAX_LOADED_MODELS=1. Also records a defect found while checking the probe against the harness: record_baseline.py stamps context_tokens and keep_alive into every report's qualification_request but never sends either -- there is no num_ctx and no keep_alive in the payload. Benign here (the container serves 32768 and the largest evidence is ~1000 tokens) but the published pin is false, and #1947 rule 5 is request pinning.
Said the round ran at the container's OLLAMA_CONTEXT_LENGTH=32768. That is only true for a model the benchmark loads itself. Ollama serves at the loaded instance's context, and a model already resident from another client is reused at that client's size -- ghidra-ollama-1 is shared with the live stack, and ollama ps currently shows qwen3:14b resident at CONTEXT 8192, loaded by the worker. So the context each cell ran at was not controlled by the harness and is not recorded in any artifact. That makes the missing num_ctx a reproducibility defect rather than a cosmetic mislabel. Accuracy is still almost certainly unaffected -- largest evidence in the round is ~1000 tokens, inside every candidate ceiling.
…-slot protocol The first pass carried a measurement defect big enough to invalidate its headline comparison. Five models re-run on a controlled protocol; part 4 rewritten around them, and the twelve-model pass demoted to a survey with explicit caveats on which rows may be read. What was wrong: Ollama serves a request at the context and state of whatever model instance is resident, and record_baseline.py neither sets nor records that. Two measured consequences: - hp-llm-worker holds qwen3:14b resident at CONTEXT 8192, so the incumbent was the one row measured against a different instance than everything it was compared with -- observed live as 10 GB/8192 (worker-loaded) vs 14 GB/32768 (benchmark-loaded), same tag and digest. - A warm slot does not reproduce and a cold one does. Controlled A/B, same model and request: warm 60/61 with 1 of 14 answers byte-identical, cold 60/60 with 14 of 14. The survey's uniform +-0 was three lanes evicting each other under MAX_LOADED_MODELS=1, i.e. lane contention masquerading as determinism, which also inflated wall clock up to 15x. Protocol adopted: evict before every run, so a cell depends only on its own inputs. Every cohort cell is +-0 across three cold runs, on four architectures. Which rows moved confirms the diagnosis: Ornith and gemma-4-26B reproduced their survey Tier B scores exactly (67, 64) since nothing else loads them, while qwen3:14b moved 62->60 and 61->58 -- the one model the worker keeps resident. Decision changes from "no promotion" to promoting gemma-4-26B-A4B-it-ultra-uncensored-heretic-i1 to the ghidra slot: Tier B 64 vs the incumbent's real 58 (+6, not the +3 the contaminated row implied), Tier A 61 vs 60, clean gates including Tier A injection, and 2.1 min/run vs 3.8. Ornith scores 67 but fails the Tier A injection gate reproducibly and stays disqualified. gemma-4-31B deferred: ~40 min/run for a model that also fails that gate and cannot be promoted whatever it scores; queued to run last. Adds docs/benchmarks/matrices/1947-cohort-cold-protocol.json and 8 pinned cohort transcript dirs.
…ts corpus vintage The injection section named the wrong cause. It said the payload is a string literal that Ghidra's pseudocode does not inline. Checked against the data rather than the code: the Tier B cache entry for process_and_injection does carry a strings list, the needle is in none of its 27 entries, and strings -a on the cached object does not find it either -- it is not in that binary at all. The corpus objects were built 2026-08-25, before 0b01d57 (#1948 / #2379) turned the payload from a source comment into a referenced string literal, and the Tier B cache was extracted from them. That also explains the asymmetry the section could not account for: Tier A reads the disassembly stored in the repo manifest, and objdump -d --source prints the source comment, so Tier A found the needle for the old fixture by accident of representation while Tier B could not. The two tiers were reading different fixture vintages. Scope is contained and now stated: 0b01d57 changed exactly one fixture, so 13 of 14 cases are byte-identical and their Tier B scores stand. Only process_and_injection was measured against a pre-#1948 object, so each Tier B total carries that single case's uncertainty and the Tier B injection verdict is untested for artifact reasons rather than model reasons. Tier A is unaffected throughout. Corpus rebuild and cache re-extraction are running; #2643 carries the detail.
a4b59af to
fdb9095
Compare
|
Round-7 cold baseline update landed: 91 models, 182 cells, 367 records, current-authority section in docs/local-llm-model-evaluation.md. Old matrices marked superseded. Matrix JSONs added under docs/benchmarks/matrices/. Merge remains on hold per the earlier comment — decision is yours. |
Harvests the 2026-08-27/28 ghidra-slot benchmark from the analysis host (which had finished uncollected), finds a measurement defect that invalidates its headline comparison, re-measures the decision cohort under a controlled protocol, and records part 4 of the #1947 rebuild against the corrected numbers.
Adds the rewritten part 4 to
docs/local-llm-model-evaluation.md, two machine-readable matrices underdocs/benchmarks/matrices/, and 32 pinned transcript run directories.The defect
Ollama serves a request at the context and state of whatever model instance is resident, and
record_baseline.pyneither sets that nor records it — it stampscontext_tokens: 8192andkeep_alive: "10m"into every report and sends neither (#2644). Two measured consequences:hp-llm-workerholdsqwen3:14bresident atCONTEXT 8192, so the incumbent was the one row measured against a different instance than everything it was compared with. Observed live, same tag and digest, minutes apart:10 GB / 8192worker-loaded vs14 GB / 32768benchmark-loaded.qwen3:14b, everything else fixed: warm 60/61 with 1 of 14 answers byte-identical; cold (ollama stopbetween runs) 60/60 with 14 of 14 (benchmarks: repeat runs are byte-identical since the Aug-25 anchor — #1947's N>=3 protocol and its ±0.58 noise band rest on an unexplained change #2642).That also explains the first pass's uniform
±0, which I initially reported as the harness being deterministic and have since retracted: three lanes againstOLLAMA_MAX_LOADED_MODELS=1evicted each other constantly, so nearly every request began with a reload. Lane contention masquerading as determinism — which also inflated wall clock up to 15× (62.5 min vs 4.1 min for identical work), making the originalmin/runcolumn unusable as a speed measure.Cohort re-run, cold protocol — authoritative
Sequential, evict before every run, live workers stopped, N=3, all cells
±0across four architectures:qwen3:14b— incumbentqwen2.5-coder:7b— #159 anchorWhich rows moved confirms the diagnosis. Ornith and gemma-4-26B reproduced their survey Tier B scores exactly (67, 64) — nothing else loads them. Only
qwen3:14bmoved (62→60, 61→58), the one model the worker keeps resident.Decision: promote (changed from "no promotion")
The earlier call rested on a +3 gap against a contaminated incumbent row. The incumbent's real Tier B is 58, so gemma-4-26B-A4B leads by +6 at
±0, wins Tier A too, passes every gate including Tier A injection, and is the fastest in the cohort. Ornith scores 67 but its Tier A injection failure reproduced under the clean protocol and it stays disqualified — score does not buy past that gate.Conditions recorded in the doc: ghidra slot only; Tier-A-only injection verdict (#2643 — Tier B has zero injection coverage, the payload never survives into Ghidra pseudocode); pin tag and digest; land #2644 first.
Other findings filed
num_ctx/keep_alivepins.llm-workerandrevdeckrun warm by design, so production answers are not reproducible. Bigger than the benchmark; needs its own investigation.gemma-4-31Bis deferred and running last (~40 min/run, fails the injection gate, cannot change the decision); its row lands when it completes.Docs-only; no code paths touched.
analysis/ghidra/benchmarks/tests/117 passed, including the transcript provenance guard.