Skip to content

EPIC E2 0.73: Verbs Are Fast #3598

Open
16 of 22 issues completed
Open

Description

@noahgift

owner: la-0.71 (re-owned 2026-10-09 by clerk aprender-3e for cop aprender-13: works child #4925 (open PR #4923))

Spec: APR-EPIC-001 §2 · Epic: E2 · Train: 0.71 · Successor at cut: E6

Theme

Verbs Are Fast

done_when

Qwen3.5 TTFT ≤ 2× llama.cpp d1d3c3396 on the same GGUF [O 2026-09-20]; apr serve resident with continuous batching; tok/s is generation-only; decode at 32k context ≥ [U]× llama.cpp (instrument first, then ratchet).

Budget

At most 7 open children (docs/roadmaps/epics.yaml). Repo-wide cap 100 open issues; andon at 95.

Absorbs

#4249

Prior body

Three rows, one lane: make apr run say where the time went, make the load cost payable once, and stop apr devices lying about the backend. Operator ruling 2026-09-20 — 0.69 measures performance, 0.70 improves it.

Row 1 — apr run --json gains load_ms · h2d_ms · prefill_ms · decode_ms · tokens_out (closes #3542)

This is the row every other performance fix depends on, and the evidence is that wall-clock cannot substitute for it. Measured on noah-Lambda-Vector (RTX 4090 sm_89), Qwen3.5-4B-Q4_K_M.gguf, published 0.68.2, all layers on GPU:

apr llama.cpp d1d3c3396
load + prefill + 1 tok 14.06 / 14.19 / 16.19 s 1.82 / 1.82 / 2.85 s
wall, 384 tokens 16.99 / 18.98 / 21.79 s 3.80 / 3.91 / 3.95 / 4.05 s
generation rate unmeasurable 179.7–189.4 t/s

From that data the cop named the mechanism twice and was wrong twice inside fifteen minutes:

  • "The 14 s is load" — killed by a 2-char prompt costing 6.8 s, so ~7 s is prompt-dependent.
  • "Prefill runs at ~4.7 tok/s, 170× slower" — killed by 144→288 words costing only ~2 s; the marginal rate at the long end is ~24× better than that two-point slope implied.

Scaling, --max-tokens 1: Hi 6.77/6.80 · 24w 12.76 · 72w 17.69 · 144w 17.17/17.66/16.71 · 288w 19.01/19.18. Not linear. Consistent with a large one-time cost a trivial prompt skips plus a low marginal cost — chunked prefill with an expensive first chunk, a one-time graph capture or JIT, or KV/buffer allocation rounded to a context size. Three candidates, and wall clock admits all three. Run-to-run variance is ±2 s on identical work (token counts were identical across trials), which is larger than the signal being chased.

done_when

  1. apr run --json emits load_ms, h2d_ms, prefill_ms, decode_ms, tokens_out.
  2. Falsifier: the fields sum to within a stated tolerance of wall clock, and a planted delay in one stage moves that field and only that field. A timing row that cannot localise a planted delay is decoration.
  3. The JSON goes to one declared stream. Today Backend: goes to stderr and Completed in … to stdout; a consumer cannot guess.
  4. The (cached) suffix on Completed in N s states what was cached or is removed — it currently prints on runs that demonstrably executed.
  5. Slow is allowed in 0.69; invisible is not. Landing this makes the 14 s honest.

Row 2 — apr serve resident (#3571)

For every consumer that keeps a process up — arbiter, apex, chat — the fixed cost is paid once, not per call. That converts a ~5× user-visible gap into a one-time cost today, before the root cause is known, which is why it is 0.69 and the fix is not.

done_when: model resident across requests; m=1; OpenAI-shape endpoint; health; a parity receipt at the serving shape (not the CLI shape — a receipt for a different shape is not a receipt for this one).

Row 3 — apr devices must not report NotCompiled on a CUDA build (#3545)

A verb that lies about the backend is the 0.69 headline defect in miniature. done_when: on a CUDA build it reports CUDA; the falsifier is a non-CUDA build still reporting honestly, so the fix is not "always say yes".

Constraints

Refs #3542, #3571, #3545, #3596, #3569, #3080.

Parked

Closed over budget (APR-EPIC-001 rule 5). Reopen = pull (rule 7).

0.7x schedule (release-schedule-07x, 2026-10-08)

Train 0.71.0: plan cut 2026-10-16, tag 2026-10-17 (plan dates, not measured). Report: docs/reports/0.7x-epic-reports.md.

Open children kept in 0.71.0 (owners are proposals; the cop assigns):

Moving to another milestone per the gate-graph walk (triage applies each move):

Activity

  1. added this to the 0.69.0 milestone on Sep 20, 2026
  2. added
    P0Critical priority
    epicEpic — multi-story umbrella
    on Sep 20, 2026
  3. modified the milestones: 0.69.0, 0.70.0 on Sep 21, 2026
  4. noahgift commented on Sep 21, 2026

    @noahgift
    ContributorAuthor

    slipped_from: 0.69.0

    §4.1 freeze (06x-release-schedule.md §1: "scope that is not on the platform rides the next train"). Operator, 2026-09-21, verbatim: "just by these optimization you should be able to release 0.69 today, ensure this happens". The 0.69 platform is #3669 plus the bump.

    Why this row rides 0.70: row 1 (#3606, apr run --json timing) is open with a code conflict against #3634 and is not on the platform. #3608/#3619/#3634 landed or are in #3669.

    — aprender-04 (cop)

  5. modified the milestones: 0.70.0, 0.72.0 on Sep 23, 2026
  6. noahgift commented on Sep 23, 2026

    @noahgift
    ContributorAuthor

    milestone → 0.72.0 per docs/roadmaps/milestone-triage-2026-09-23.md (#4024), operator approval 2026-09-23 (relayed by aprender-cf). Reason: named must-carry in epic #4000

  7. 226 remaining items

  8. added a commit that references this issue on Oct 14, 2026
  9. modified the milestones: 0.71.0, 0.73.0 on Oct 14, 2026
  10. noahgift commented on Oct 14, 2026

    @noahgift
    ContributorAuthor

    Epic update after v0.71.3 (published 2026-10-14, release 13:47Z).

    Shipped in this release:

    Still open, with milestone now:

    Done/total (direct children): 15/20

  11. changed the title [-]EPIC E2 0.71: Verbs Are Fast[/-] [+]EPIC E2 0.73: Verbs Are Fast[/+] on Oct 14, 2026
  12. noahgift commented on Oct 14, 2026

    @noahgift
    ContributorAuthor

    Retitled after the 0.71 release (v0.71.x shipped; no further 0.71.x). New train: 0.73. Done/total (direct children): 15/20. Open children by milestone: 0.73.0: 4; none: 1; . The children outside this train were moved by the 2026-10-14 milestone fix (floor rows F1-F10 stay in 0.72.0).

  13. noahgift commented on Oct 14, 2026

    @noahgift
    ContributorAuthor

    Folded into this epic's checklist from #4220 (same theme; text kept verbatim; owner owner:la-0.71 keeps the work).

    Original text of #4220

    Operator, verbatim, 2026-09-24: "lets dedicate a worker per CRUX on this 0.69.3 issue ie. ollama, llama.cpp, vllm, llamafile and figure out how to make parity work, or even beat them for these models."

    One worker per CRUX engine. This ticket covers ollama.

    Deliverables:

    1. A same-GGUF, same-host table for apr serve vs ollama. Columns: prefill tok/s at 850/4k/32k, decode tok/s, TTFT. Run correctness first (temp 0, token-identical, or name the divergence). Prove the GPU path with a trace line. Record the ollama version and SHA; it must be the latest release.
    2. The top 3–5 techniques ollama uses that apr lacks, each with the file or kernel it lives in and the estimated gain. Rank them by gain ÷ effort.
    3. One child ticket per technique, with a milestone: 0.69.3 only if it lands before the tag, otherwise backlog/0.70.
      Coordinate with Time-to-first-token on Qwen3.5-4B-Q4_K_M is 14-16s vs llama.cpp's 1.8-2.9s on the same box (7.7x); apr's decode rate is unmeasurable with shipped tooling #3596 (batched prefill, aprender-f5), apr serve (0.69.1) has no prompt-prefix reuse on the qwen35 CUDA path: an identical ~850-token prompt costs 11.0 s on both runs (ollama: 8.2k tok/s uncached, 37k cached) #4214/apr serve (0.69.1) decodes Qwen3.5-4B Q4_K_M at ~87 tok/s on RTX 4090 vs ollama 0.34.2 at ~149 tok/s (0.58x) on the same box #4215/0.71: qwen35-0.8b-q4km golden thinking-ON never closes on apr (greedy near-tie path, no localized defect) — shipped as known RED in 0.69.1 #4030 (infra-c2/infra-76) and Release gate: apr serve throughput vs llama.cpp on the SAME GGUF (Qwen3.5 0.8B/2B/4B/9B/27B) — a regression ratchet that blocks the tag, plus a published parity target #4218 (speed gate, aprender-75). Don't duplicate them.

    Collapsed rows (APR-EPIC-001 rule 20)

    One issue per PR: tick a line when its PR merges; the PR closing the last line says Closes #4220, the others Refs #4220 row <id>.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High priorityepicEpic — multi-story umbrellaowner:la-0.71Owned by the 0.71 look-ahead slot

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions