Skip to content

helion-rag: four-arm head-to-head autotuning experiment (LFBO / LLM / hybrid / RAG-LLM) - #3292

Draft
IshanAryendu wants to merge 5 commits into
helion-rag-prfrom
iaryendu/rag-autotune-head-to-head
Draft

helion-rag: four-arm head-to-head autotuning experiment (LFBO / LLM / hybrid / RAG-LLM)#3292
IshanAryendu wants to merge 5 commits into
helion-rag-prfrom
iaryendu/rag-autotune-head-to-head

Conversation

@IshanAryendu

@IshanAryendu IshanAryendu commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

What this is

We ran a head-to-head campaign comparing four Helion autotuning strategies over 33 GPU kernel shapes × 5 paired repetitions (660 runs) on a single H100, to answer one question: is retrieval-augmented LLM autotuning worth pursuing?

The answer is promising but modest, and the numbers are interesting enough that I'd like others to try to replicate or break them. This PR is the harness, the analysis, and the reference results — opened as a draft because it's an experiment to evaluate, not a feature to land.

The four arms

Arm HELION_AUTOTUNER Retrieval LLM requests
lfbo LFBOTreeSearch off 0
llm LLMGuidedSearch off 1
hybrid_lfbo_llm LLMSeededLFBOTreeSearch off 1
contextual_rag_llm LLMGuidedSearch on 1

llm and contextual_rag_llm share identical provider, model, and round settings, so retrieval is the only difference between them. Everything else in the design exists to keep that one contrast clean.

Results

Arm latency GM (ms) readiness GM (s) regret vs LFBO correct tokens
lfbo 0.0909 108.9 0% 164/165 0
llm 0.0825 62.8 −9.3% 164/165 746k
hybrid_lfbo_llm 0.0743 175.1 −18.3% 164/165 747k
contextual_rag_llm 0.0808 71.8 −11.1% 164/165 875k

There's no single winner — there's a frontier. Hybrid buys the best kernels with 2.8× LFBO's search time. LLM is by far the fastest to be ready and still beats LFBO on quality.

On the contrast the experiment was built for: retrieval beats context-free LLM search by 1.9% on selected latency (ratio 0.981, 95% CI 0.964–0.994, Holm-adjusted p=0.034), at 14.3% more readiness time and 17.3% more provider tokens.

That's a real effect but a small one. Whether 1.9% justifies operating a retrieval corpus is exactly the question I'd like the team's read on.

Design notes

  • Paired and balanced. Same seed across all four arms per (workload, repetition) block; execution order is a balanced Latin square so machine drift can't favour an arm.
  • Frozen controls. study_manifest.json hashes every control; a resume refuses to mix results from a different hash.
  • Cold every time. Per-run Helion/Inductor/Triton/temp dirs; exact-cache reads, best-available reads, and cache writes all off.
  • One shared budget for the hybrid. Its LLM and LFBO stages charge a single 80-attempt ledger and one continuous clock, so stage two can't quietly claim a second allowance. llm/contextual_rag_llm typically stop early at ~26 attempts; that realized effort is reported, not padded.
  • Statistics. Per-kernel median matched-repetition ratios, geometric-mean aggregation, 200k-resample kernel bootstrap CIs, Wilcoxon on log ratios, all 12 contrasts Holm-corrected as one family.

Limitations

One host, one GPU (H100), one model (claude-opus-4-8 via Vertex), 5 seeds. 33 workloads is enough for the paired statistics used here, but family-level effects are noisy. The oracle is bounded by what the campaign observed, not exhaustive search, so absolute regret is a lower bound. Retrieval quality is capped by the corpus generation the index was built from.

Replicating

Start at docs/rag_autotuning_experiment.md. Reference numbers to diff against are checked into scripts/helion_rag/results/2026-07-26-h100/, including all 12 Holm-corrected contrasts, so a replication can be compared contrast by contrast rather than headline to headline. The claims worth checking are the relative ones — especially whether contextual_rag_llm still beats llm at all.

Scope

Stacked on #3045 (helion-rag: standalone retrieval over CI autotuning artifacts); this PR is only the experiment on top of it.

Deliberately not included: an earlier tiered-RAG confirmatory-study framework (~17k lines) that was built but never ran — it's blocked on pre-registered data stop-conditions and would only be noise here. The HELION_RAG_FROZEN_MANIFEST verification path in the adapter existed solely to serve that study and is removed too; it was never activated by any shipped driver. Both are recoverable from branch history if we come back to them.

Test plan

  • PYTHONPATH=scripts/helion_rag pytest scripts/helion_rag/tests -q — 167 passed
  • pytest test/test_rag_*.py test/test_candidate_attempt_budget.py test/test_llm_*.py -q — 235 passed, 65 subtests
  • ruff check / ruff format --check clean; pyrefly check at 124 errors, unchanged from the base branch
  • Full re-analysis of the 660-run campaign reproduces every published number
  • Live 4-arm single-workload pilot on an H100: all four arms completed and correct, RAG arm reaching lookup_tier: 1 / decision: ContextualSearch with no fallback

Adds the opt-in retrieval path Helion's autotuner uses when
HELION_RAG_ENABLED=1, plus the autotuner changes the four-arm head-to-head
campaign needs to compare search strategies fairly.

helion/autotuner/rag/ runs a fixed runtime order behind a kill switch: exact
cache probe, workload description, frozen retrieval, a pure policy decision,
then execution behind a single typed fallback boundary. Every side-effecting
dependency is injected, so the wrapper is tested without CUDA, faiss, or a
provider. Retrieval failures degrade to BaselineSearch and are recorded rather
than raised.

candidate_budget.py turns the per-search attempt counter into a run-level
shared ledger, so LLMSeededLFBOTreeSearch's two stages charge one 80-attempt
ceiling and one continuous trajectory clock instead of the second stage
silently claiming a fresh allowance.

Every arm, including the RAG-disabled ones, emits the same canonical
instrumentation event under HELION_AUTOTUNE_EMIT_EVENT, which is what makes
the arms comparable at all.

Test plan: pytest test/test_rag_*.py test/test_candidate_attempt_budget.py
test/test_llm_*.py -q -- 235 passed, 65 subtests passed.
The offline half of the experiment: the frozen arm table, balanced scheduling,
the benchmarkable workload registry, and the event schema every arm emits.

experiment/head_to_head.py is the single source of truth for what is held
fixed. build_study_manifest() hashes every control -- seeds, attempt limit,
effort profile, provider/model, LLM round settings, cache policy, workload
list -- so a resume can refuse to mix results produced under a different
configuration. llm and contextual_rag_llm share identical provider settings,
which is what makes retrieval the only difference between them.

experiment/workloads/ auto-imports its submodules, so adding a kernel shape is
adding a file; torch and Helion imports stay inside each build closure so
importing the registry pulls no CUDA. The shapes reuse the kernels already in
examples/ rather than restating them.

Also extends the standalone retrieval package with the shape-aware reranking,
signature-checked index loading, and Ed25519 generation signing the RAG arm
depends on.

Test plan: PYTHONPATH=scripts/helion_rag pytest scripts/helion_rag/tests -q.
660 run units across four arms takes ~14 h, so the driver is built to be
interrupted rather than babysat.

Each run's terminal outcome is written atomically to a file keyed by
(workload, arm, repetition), and runs.jsonl is reconstructed from those files
rather than from append order -- an interrupted append can never be mistaken
for a result. --resume verifies the manifest hash before reusing anything and
refuses to mix in runs from a different budget, model, generation, code
identity, or schedule.

A subprocess that dies before emitting any event is retried once with the same
seed and a fresh cache directory; anything that already emitted a terminal
event, failed correctness, or timed out is never retried. Timeouts are
recorded as censored rather than dropped, so partial data stays analyzable. A
PID lock stops two campaigns from targeting one directory.

Test plan: PYTHONPATH=scripts/helion_rag pytest
scripts/helion_rag/tests/test_head_to_head_campaign.py -q; plus a live
4-arm single-workload pilot on an H100 -- all four arms completed and correct,
with the RAG arm reaching lookup_tier 1 and decision ContextualSearch.
analyze_head_to_head.py turns a campaign directory into the tables and figures
the study is read from: per-run and per-kernel CSVs, the all-arm table,
trajectories, and eleven gnuplot figures.

Inference is paired throughout. Per kernel we take the median matched-
repetition ratio between two arms; across kernels we aggregate with geometric
means, a 200,000-resample percentile kernel bootstrap for CIs, and a Wilcoxon
signed-rank test on log ratios. All 12 performance/readiness contrasts are
Holm-corrected as one family, so no arm gets credit for a contrast that only
survives in isolation. Regret is reported against both a bounded campaign
oracle and LFBO.

Figures render through gnuplot so the analysis needs no Python plotting
dependency; plot_narrative_figures.py holds the two matplotlib charts gnuplot
cannot do well and is gated behind an optional `figures` extra. Both skip with
a note rather than failing when their renderer is absent.

Test plan: PYTHONPATH=scripts/helion_rag pytest
scripts/helion_rag/tests/test_head_to_head_analysis.py
scripts/helion_rag/tests/test_plot_narrative_figures.py -q; plus a full
re-analysis of the 660-run campaign, which reproduces every published number.
docs/rag_autotuning_experiment.md is the entry point: the design, the
controls, how to run it, how to read the output, and the limitations.

scripts/helion_rag/results/2026-07-26-h100/ checks in the reference numbers so
a replication can be diffed against ours rather than judged in isolation --
the frozen manifest, the analysis CSVs, five figures, and the full write-up.
*.csv is gitignored repo-wide, so the bundle needs a scoped negation.
trajectory_long.csv (4.2 MB) and the PDF/PNG renderings are left out; both
regenerate from a campaign directory.

Headline, 33 workloads x 4 arms x 5 repetitions on one H100: hybrid wins on
kernel quality (-18.3% regret vs LFBO) at 2.8x LFBO's search time, plain LLM is
fastest to be ready (62.8 s geomean) and still beats LFBO, and retrieval beats
context-free LLM search by 1.9% on selected latency (CI 0.964-0.994, adjusted
p=0.034) for 14.3% more time and 17.3% more tokens. Real, but modest -- whether
that justifies a retrieval corpus in production is the open question.

Test plan: numbers in the docs cross-checked against
analysis/aggregate_statistics.csv in the bundle.
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Aug 5, 2026
@IshanAryendu IshanAryendu changed the title iaryendu/rag autotune head to head helion-rag: four-arm head-to-head autotuning experiment (LFBO / LLM / hybrid / RAG-LLM) Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant