Skip to content

feat: ADR-018 AC-3 cross-turn prefix reuse (v0.3.11) + full-suite benchmark#12

Merged
Tovli merged 3 commits into
masterfrom
ktlo/performence-phase0.5
Jun 23, 2026
Merged

feat: ADR-018 AC-3 cross-turn prefix reuse (v0.3.11) + full-suite benchmark#12
Tovli merged 3 commits into
masterfrom
ktlo/performence-phase0.5

Conversation

@Tovli

@Tovli Tovli commented Jun 23, 2026

Copy link
Copy Markdown
Owner

Summary

Performance phase 0.5: lands ADR-018 AC-3 (cross-turn prefix reuse / incremental prefill), bumps the workspace to 0.3.11, and documents the measured win with a full-suite el-bench report plus a README progression table.

Three focused commits:

Commit What
feat(runtime,engine): ADR-018 AC-3 Reuse the KV cached for the longest matching token prefix and prefill only the divergent suffix, instead of re-prefilling the whole conversation each turn.
chore: bump workspace version to 0.3.11 cargo set-version --workspace 0.3.11 (follows master's 0.3.10).
docs(benchmarks): AC-3 report + README New 2026-06-23 report and a benchmark progression table in the README.

What AC-3 changes

  • el-runtimeInferenceSession::continue_prompt + the InferenceEngine::prefill_reuse port. Safe default re-prefills the full context; stateful engines override for the fast path. A failed continue leaves a recoverable session.
  • el-engine-candleQwenEngine::prefill_reuse does longest-common-prefix reuse against the live cache and falls back to a full prefill on any mismatch.
  • Soundness — reuse must leave the cache byte-identical to a fresh prefill: proven by the ReuseEngine mock test prefill_reuse_leaves_same_state_as_a_fresh_prefill, and it fails open on a wrong/short match.

Measured impact (full el-bench suite, Qwen2.5-0.5B q4_k_m, i5-14500)

Same harness/inputs/host as the 2026-06-22 run; only the AC-3 code differs. 66 tasks → 97/97 replies, 0 errors.

Metric 2026-06-22 (no AC-3) 2026-06-23 (AC-3) Change
Full-suite wall 3221 s (53.7 min) 2141.5 s (35.7 min) −33.5%
Prefill share of compute 56.8% 29.5% −65% wall
Prefill forwards (27,148 prompt tok) ~27,148 (1/token) 9,893 64% served from cache
mindeval (multi-turn) avg ms/reply 52,225 17,478 ~3× faster

Honest caveat (in the report): the prefill kernel is unchanged — per-forward rate is still ~15 tok/s — so AC-3 wins by doing less work, not faster math. ADR-020 (batched prefill) is still pending for cold/first-turn prefill, and the ~14 tok/s decode floor is now the dominant cost.

Verification

  • cargo build --workspace — clean at 0.3.11 (excluding el-chat, whose binary was locked by a stale local process; el-chat source is untouched by this PR and compiled fine).
  • cargo test -p el-runtime31/31 pass, including the AC-3 soundness and recoverable-session tests.
  • The benchmark itself ran end-to-end through the real SDK path with 0 errors and matching completion-token counts vs the prior run (AC-3 changed speed, not output).

Notes for reviewers

  • The AC-3 implementation (session.rs, ports.rs, el-engine-candle/src/lib.rs, ADR-018 doc) was already present in the working tree at the start of this work; this PR commits it as-is alongside the version bump and benchmark docs.
  • The branch was rebased onto current master (which had advanced to 0.3.10) before committing, so the diff is clean — no spurious revert of master's README/CI/packaging commits.
  • The prior 2026-06-22 report's "prefill is the Add multi-registry release CI (crates.io · npm · pub.dev) — ADR-011 #1 cost" conclusion is now superseded on the prefill axis by the new report (left intact for history).

🤖 Generated with Claude Code

Tovli added 3 commits June 23, 2026 21:30
…ntal prefill)

Reuse the KV already cached for the longest matching token prefix and feed only
the divergent suffix, instead of re-prefilling the whole conversation every turn.

- el-runtime: `InferenceSession::continue_prompt` + the `InferenceEngine::prefill_reuse`
  port. Safe default re-prefills the full context; stateful engines override for
  the fast path. A failed continue leaves a recoverable session.
- el-engine-candle: `QwenEngine::prefill_reuse` does longest-common-prefix reuse
  against the live cache and falls back to a full prefill on any mismatch.
- Soundness: reuse must leave the cache byte-identical to a fresh prefill — proven
  by the `ReuseEngine` mock (`prefill_reuse_leaves_same_state_as_a_fresh_prefill`)
  and it fails open on a wrong/short match.

Measured on the full el-bench suite this cuts multi-turn (mindeval) ~3x and the
whole-suite wall by a third (see docs/benchmarks/2026-06-23-...).
…ion in README

- New report 2026-06-23-adr-018-ac3-prefix-reuse-full-suite.md: full el-bench run
  (66 tasks / 97 replies, 0 errors, 35.7 min) on the same i5-14500 host as the prior
  reports. AC-3 cuts prefill from 56.8% to 29.5% of compute and the whole-suite wall
  by 33.5% vs the 2026-06-22 run; mindeval ~3x faster. Notes that the prefill *kernel*
  is unchanged (~15 tok/s per forward) so ADR-020 batched prefill is still pending,
  and decode (~14 tok/s) is now the dominant cost.
- README: replace the single-report Benchmarks blurb with a progression table across
  the three perf reports plus a clinical-safety headline.
@Tovli
Tovli merged commit 5d8c129 into master Jun 23, 2026
5 checks passed
@Tovli
Tovli deleted the ktlo/performence-phase0.5 branch June 23, 2026 18:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant