Repository navigation
1bit serve: draft with a GGUF's own MTP head on HRX by default; --print-backend carries the warm-up - #495
Conversation
…nt-backend carries the warm-up Lemonade's standard benchmark had Lemonade's own Qwen3.8-27B entry drafting with the model's MTP head (`--spec-type draft-mtp`, label "mtp") at 24-28 tok/s while the onebit recipe ran the same file without a drafter at 11-12. And on the one-hop route lemond starts llama-server itself, so the warm-up request serve sends a ready backend (#492) never ran. - launch_for: a .gguf with <architecture>.nextn_predict_layers > 0 on hrx gets `--spec-type draft-mtp` (no -md: llama-server loads the head from -m), as Lemonade's llamacpp recipe does; --mtp-max / --mtp-p-min apply, recipes see drafter=mtp. Not with --mtp / --dflash, --parallel > 1, --embedding / --reranking, on cpu, or with --no-mtp / ONEBIT_NO_MTP=1. Both serve and the one-hop plan. - --print-backend: an hrx chat plan carries "warmup": {path, body}, serve's own warm-up request (shared code now), for Lemonade's onebit recipe to send before it marks the model loaded (lemonade fork #16). ONEBIT_NO_WARMUP=1 leaves it out. - tests/print_backend.sh: the default drafter, its opt-outs and the warmup key. - docs/serve.md: both, with the Lemonade bench numbers (27B chat/code 11.1/11.9 -> 26.2/29.5 tok/s). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PR Reviewer Guide 🔍(Review updated until commit e7653e1)Here are some key observations to aid the review process:
|
|
PR-Agent's two notes: (1) 🤖 Generated with Claude Code |
|
Persistent review updated to latest commit e7653e1 |
|
hw-gate on this branch's build (a8b7060; llama.cpp 5dcf6623, hrx-system 82804197, private gpu-kernels add-on 08bb2241 compiled in),
The 27B KLD ran against the base recorded for this branch's llama.cpp pin (the store's 🤖 Generated with Claude Code |
Gantt row "Lemonade bench: MTP on by default + warm-up on the one-hop path".
Lemonade's standard benchmark (2026-10-21,
~/amd-oss/lemonade-bench-2026-10-21) found two gaps on the product path (Lemonade onebit recipe, one hop):Qwen3.8-27B-GGUFentry has themtplabel, so its llamacpp recipe runs llama-server with--spec-type draft-mtp(the head is inside the UD-Q4_K_XL file,qwen35.nextn_predict_layers = 1,blk.64.nextn.*) and decodes 24-28 tok/s; onebit ran the same file without a drafter at 11-12.1bit serve, but on the one-hop route lemond starts llama-server itself.Changes
launch_for): a.ggufwith<architecture>.nextn_predict_layers > 0onhrxgets--spec-type draft-mtpwith no-md(Lemonade's exact rule and args).--mtp-max/--mtp-p-minapply; recipes seedrafter=mtp. Off for--mtp/--dflash,--parallel > 1,--embedding/--reranking,cpu, and with--no-mtporONEBIT_NO_MTP=1(Lemonade:onebit.args=--no-mtp, allowed by lemonade fork docs: status after steps 1-3, HRX re-verified at the first daily bump #16). Files without the key are unchanged (Qwen3.5-4B UD-Q4_K_XL: no head, plan unchanged apart from the warm-up).--print-backendadds"warmup": {"path", "body"}to anhrxchat plan: serve's own request, now shared code (warmup_body()). Lemonade fork docs: status after steps 1-3, HRX re-verified at the first daily bump #16 sends it after/healthand beforeload()returns.ONEBIT_NO_WARMUP=1leaves it out. I chose the plan field over a lemond-side copy of the request so the engine stays the single owner of what the warm-up is and when it applies.tests/print_backend.sh: 11 new checks (default drafter, its opt-outs, warmup key).docs/serve.md: both, with the numbers below.Lemonade bench standard
lemonade bench MODEL --backend hrx --scenarios chat-short code-short --runs 5 --warmup 1 --auto-pull --json(the pinned CI's P1, a reload before every run). Private lemond on strixhalo (own cache/config dirs,--no-broadcast, cores 0-3, MemoryMax 110G), lemonade fork1bit/onebit-warmup(#16) + this branch built with-DONEBIT_HRX=ON -DONEBIT_GPU_PRIVATE=<gpu-kernels 08bb2241>(the pin; 42register_hip_*symbols inlibggml-hrx.so). One binary for every arm; arms differ only byONEBIT_NO_MTP/ONEBIT_NO_WARMUPin lemond's environment. Model files sha256-checked against HF LFS.0/5 failed runs everywhere; no dmesg amdgpu faults/resets in any hold; no thermal stop.
Greedy equality (MTP vs
--no-mtp, 27B, temperature 0, 128 tokens, 3 prompts)2 of 3 identical. The third diverges at token 21: without MTP
" Earth"logprob -0.684 vs" the"-0.705 (a 0.02 near-tie); with MTP the verify batch (2-4 tokens through the K-quant verify kernels) picks" the", and the rest is the same sentence. Drafting is correct: only tokens the verify pass agrees with are kept; batch-size numerics decide near-ties, as in upstream llama.cpp speculative decoding.What the warm-up does not fix
The 2.3-2.4 s TTFT on chat-short's 67-token prompt stays. It is a first-time cost per prompt length, and some lengths cost much more than others: one server without MTP, after the warm-up: 67 tokens 2,350 ms, then 531 ms; 74 tokens 559 ms, then 528 ms (with MTP, a first 70-token prompt 1,585 ms, then about 600 ms). The warm-up's own 360-token prompt cannot cover other lengths. That needs its own row: which prefill shapes build expensive programs (67 vs 74 tokens), and whether those programs can be built at load or shared across lengths.
hw-gate
The private-add-on build is gated with
scripts/hw-gate.sh --bin <this build>, split into holds of 14 minutes or less; I add the result as a comment. This PR changes no pin and no llama.cpp code.🤖 Generated with Claude Code