Skip to content

feat(planner): 0.6.0 — SOTA serving model (continuous batching, prefill/decode, Pareto, variance guard)#3

Merged
Sahil170595 merged 10 commits into
mainfrom
feat/0.6.0-sota
Jul 2, 2026
Merged

feat(planner): 0.6.0 — SOTA serving model (continuous batching, prefill/decode, Pareto, variance guard)#3
Sahil170595 merged 10 commits into
mainfrom
feat/0.6.0-sota

Conversation

@Sahil170595

@Sahil170595 Sahil170595 commented Jun 25, 2026

Copy link
Copy Markdown
Owner

Summary

Makes the capacity planner reflect how LLM inference actually behaves — continuous batching, prefill/decode disaggregation, KV-cache-bound concurrency, goodput/Pareto, variance-aware queueing — instead of modelling every backend as replicas-of-single-stream. Direction validated by a cited deep-research pass over the serving literature.

Increments

  1. KV-cache-bound max concurrency per GPU (max_concurrent_seqs) — the real concurrency limiter.
  2. Prefill/decode splitTTFT (compute-bound, GPU FP16 TFLOPS) + TPOT (bandwidth-bound); end-to-end p95 now includes prefill. GPUSpec.fp16_tflops, --prompt-tokens.
  3. Continuous-batching throughput — vLLM/TGI serve B concurrent sequences per GPU; aggregate rises with batch up to the KV cap, anchored to measured/roofline single-stream (quant-correct). One GPU replaces several Ollama replicas (7B @ 3 req/s on a 4090: Ollama 5 GPUs vs vLLM 1 GPU/batch 8). Candidate.effective_batch.
  4. Pareto frontier (plan --pareto) — the non-dominated cost/latency/quality menu, not one cost-sorted pick.
  5. Variance-aware queueing (plan --workload steady|chatbot|bursty|agent) — two-moment wait (Cs²=0 reproduces M/D/1); high-variance/agent traffic inflates the tail and warns. Closes the "analytical queueing silently approves broken fleets" gap.
  6. Numerical accuracy tests — pin throughput, roofline anchor, VRAM formula, TTFT, and batching invariants to ground truth (falsifiability gate).

Also

  • Fixes (from the cold review): replicas scale linearly (was an Amdahl cap that rejected ≥7B); cost_per_1m_tok no longer understated by instance count.
  • Broader quant support (legacy + i-quants); ASCII-only source; docs realigned to the planner product (research guides archived).

Testing

  • 476 unit tests, lint + format clean.
  • Full end-to-end pass: every one of the 10 commands invoked across success / error / JSON / 0.6.0-feature modes against live Ollama + HF; every failure path exits non-zero with a message (no swallowed errors).
  • Registry-model numbers unchanged where applicable; Cs²=0 reproduces the prior M/D/1 exactly.

First SOTA increment from the cold review: model the real concurrency limiter
for batched backends. VRAMModel.kv_cache_gb() + max_concurrent_seqs() compute,
from first principles (no fitting), how many sequences one GPU can hold after
weights + activations, bounded by per-sequence KV-cache. Surfaced as
Candidate.max_concurrent_seqs and in plan output ("Max concurrent/GPU").

Foundation for batched throughput (next: GPU FLOPS + continuous-batching curve,
then engine integration of per-GPU batching vs replica fan-out). Verified:
3B Q4 @2k on 24GB -> 89 seqs; 14B Q4 @4k -> 19; 7B Q4 @2k on 12GB -> 25.
442 tests (+6).
…consoles)

The top-level --help showed "optimizer <?>" because the help= string used a
non-ASCII em-dash (violates the repo's ASCII-only rule and renders as a
replacement char on cp1252 terminals). Replaced em-dashes / x with ASCII in
the CLI-facing strings, and dropped literal RST backticks from the catalog
help so the command list reads "rebuild it with --build" not "``--build``".

No new `help` command needed -- Typer already lists all 10 commands with
descriptions (`chimeraforge --help`) and full per-command help (`<cmd> --help`).
Repo standard is ASCII-only for universal compatibility. Section dividers used
U+2500 (box-drawing), prose used U+2014 (em dash), one docstring used U+00D7
(multiply). Swept all to ASCII hyphen / 'x' across src/chimeraforge and tests
(comments + docstrings only; no logic or output strings changed), including the
new 0.6.0 code. Folded into the 0.6.0 branch rather than a separate chore branch
to avoid divergence.

442 tests pass; ruff clean on src/chimeraforge; zero non-ASCII remain.
Real SLOs are written against time-to-first-token and time-per-output-token, not
one atomic service time. Separate the two:

- GPUSpec gains fp16_tflops (dense FP16 Tensor, FP32-accumulate). Datacenter from
  official datasheets (A100 312, H100 SXM 989, L4 121, T4 65); consumer Ada
  derived (dense = 2x FP32 shader, cross-checked vs RTX 4090's published 165.2);
  consumer Ampere on the FP32-acc basis (3090 71, 3080 59.5) for one consistent
  basis.
- LatencyModel.predict_ttft_ms(): prefill is compute-bound -- ~2 FLOPs/param/token
  over the prompt / (peak TFLOPS * MFU=0.4). Returns 0.0 when GPU compute is
  unknown (latency falls back to decode-only, no guess).
- p95 service time is now prefill (TTFT) + avg_tokens * decode-per-token (TPOT),
  not decode-only. Candidate carries ttft_ms + tpot_ms; plan shows both plus a
  --prompt-tokens input.

Verified: 7B/512-tok TTFT H100 18ms < 4090 108ms < T4 276ms; 14B = 2x 7B; TPOT
~= 1000/tps. 450 tests (+8).
The docs/ folder and product spec still framed the repo as the Banterhearts
research breakout, predating the model-agnostic CLI. Audit + fix:

- docs/README.md: rewrite the index product-first (plan/suggest/measure/catalog);
  agent/Rust/TR guides preserved under a clearly-labeled Research Archive; drop
  the stale "Last Updated: January 2025" framing.
- docs/planning.md: NEW task-oriented planner usage guide (the missing product doc).
- Dead links fixed: configuration.md (x2) and production_deployment.md removed,
  lowercase contributing.md -> ../CONTRIBUTING.md.
- docs/API.md: v0.2.1 -> v0.5.0.
- docs/ARCHITECTURE.md: scope note (covers the research subsystem, not the CLI).
- Linked the orphaned repo_structure.md from the index.

PRODUCT_SPEC.md was rewritten lean locally (1140 -> ~110 lines) and a VISION.md
split off for the moonshot, but both stay LOCAL: PRODUCT_SPEC.md is gitignored by
design (strategy doc), so VISION.md is gitignored to match and no public doc links
to either. This push is the public docs realignment only.

No code changed; 0 broken markdown links; no tracked cruft found.
…replicate (0.6.0 increment 3)

The SOTA centerpiece: model per-GPU continuous batching so vLLM/TGI stop being
modelled as replicas-of-single-stream. Aggregate decode throughput rises with
batch B up to the KV-cache cap (increment 1), anchored to the measured/roofline
single-stream rate so it stays quant-correct:

  aggregate(B) = B * bw*MBU / (weight_eff + B*kv_per_seq),  weight_eff = bw*MBU/n1_tps

- ThroughputModel.batched_decode_tps(): KV-amortized saturating curve, capped by
  the decode compute ceiling (GPU FP16 TFLOPS).
- Engine: per backend, search (N replicas x B batch/GPU) for the cheapest config
  meeting the rate under the latency SLO; B <= max_concurrent_seqs; Ollama B=1.
  Higher B trades per-request TPOT for aggregate throughput (the real tradeoff).
- LatencyModel.predict_p95 gains concurrent_per_agent, so capacity = N*B/service --
  decoupling per-request latency from aggregate capacity.
- BACKEND_CONTINUOUS_BATCHING (ollama no, vllm/tgi yes); Candidate.effective_batch.

Verified: 7B @ 3 req/s on a 4090 -- Ollama needs 5 GPUs ($216/mo, single-stream);
vLLM serves it on 1 GPU at batch=8 ($43.2/mo). 453 tests (+4), updated the Phase-0
replica tests to the Ollama path (batching now supersedes replicas for vLLM/TGI).
….0 increment 5)

Analytical queueing is conservative for low-variance chat but under-estimates the
tail for high-variance/agent traffic (heavy-tailed service holds slots), where it
can approve fleets that fail SLOs (the cold-review finding). Generalize the M/D/1
wait to the two-moment (Allen-Cunneen) form (Ca^2+Cs^2)/2 x M/M/1; Cs^2=0
reproduces M/D/1 exactly (no change at the default), higher Cs^2 inflates p95.

- LatencyModel.predict_p95: service_cv2 param (default 0 = M/D/1).
- WORKLOAD_CV2 presets (steady 0 / chatbot 1 / bursty 4 / agent 8); plan --workload.
- Above HIGH_VARIANCE_CV2 (4) every candidate carries a loud warning: analytical
  p95 under-estimates the tail, validate with a load test.

Verified: agent vs steady on an 8B/4090 -- agent raises p95 (2903->3220ms),
allocates more batch headroom, and warns. 459 tests (+6).
…u (0.6.0 increment 4)

Expose the non-dominated trade-off frontier instead of a single cost-sorted pick
(the research's "move beyond single-point estimates"). Now that batching sweeps
the throughput<->latency curve, the frontier is the real menu: cheapest,
lowest-latency, highest-quality, and the bends between.

- engine.pareto_frontier(): non-dominated set on (cost down, p95 down, quality up),
  sorted by cost.
- formatter.format_pareto() / format_pareto_json(): trade-off table tagging the
  cheapest / fastest / best-quality picks, plus JSON.
- plan --pareto (works with --json too).

Verified on an 8B/4090: 10 non-dominated configs from $43 vLLM (cheapest+fastest)
to the quality/latency extremes. 464 tests (+5).
- bump 0.5.0 -> 0.6.0 (pyproject, __init__, CLAUDE, API, README)
- CHANGELOG [0.6.0]: continuous batching, prefill/decode TTFT/TPOT, KV-cache
  max-batch, Pareto frontier, variance-aware queueing; linear replicas + cost-per-N
- CLAUDE.md: 0.6.0 serving-model section; test count 476
- tests/test_accuracy.py: numerical falsifiability gates (throughput reproduces
  measured, roofline calibration anchor, VRAM formula, TTFT, batching invariants)
@Sahil170595 Sahil170595 changed the title Feat/0.6.0 sota feat(planner): 0.6.0 — SOTA serving model (continuous batching, prefill/decode, Pareto, variance guard) Jun 26, 2026
Blind multi-agent code audit (23 confirmed findings, 5 refuted). Each
finding re-verified against source before fixing.

HIGH:
- VRAM activation memory is O(context), not O(context^2) -- a quadratic
  term blew up to ~130 GB at 32k for a 3B model, spuriously failing the
  VRAM gate and zeroing max_concurrent_seqs. Coefficient re-pinned to
  preserve the calibrated 2k value.
- bench/refit/compare/report --json now emit valid JSON when piped
  (highlight=False, soft_wrap=True), matching the other six commands.

MEDIUM:
- quality_tier is family-aware (off-registry tier no longer collapses to
  unknown, so the concerning-drop advisory can fire)
- guard ZeroDivisionError on a degenerate "...0b" identifier
- refit --validate gates before the write (no longer persists invalid
  coefficients ahead of the failing exit)
- per-key confidence weighting in refit (each entry blended by its own
  successful-run count, not the global total)
- measure surfaces unknown --backend cleanly; check_model handles
  timeouts/HTTP errors; resolver/discovery raise ResolverError on a
  non-JSON 200 response (no raw traceback)
- bench --context forwards --quant; non-Ollama context sweeps warn the
  per-request override was not applied
- eval --fp16-baseline exposes tier classification
- measured-corpus staleness warning on version mismatch
- build floor setuptools>=77 (PEP 639 license form)

LOW:
- roofline bandwidth-correct above FP16 (FP32 ~ 0.5x); F16/F32 native
  quant normalized; engine spec=None no longer mislabels source as
  registry; strengthened tautological/weak tests; doc fix for classify_tier

Deferred (low impact, noted in CHANGELOG): GB/GiB unit mix, ambiguous
partial GPU-name match, BERTScore-0.0 sentinel.

483 tests pass; lint/format clean; wheel builds under isolation.
@Sahil170595
Sahil170595 merged commit 9a907c1 into main Jul 2, 2026
6 checks passed
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