Decide vLLM on compute capability, not on VRAM - #29
Conversation
plan_for_budget recommended vLLM from the memory tier alone, and every tier carried its own hardcoded clause: "not viable" below 9 GB, "worth measuring" from 26, "worth evaluating at this scale" from 45. Memory is the wrong axis to decide it on by itself. vLLM's advantage over llama.cpp is throughput from resident weights and fast low-precision kernels, and which kernels exist is a property of the GPU's compute capability. Two A4000s are 31 GB, which landed this rig in the tier that says "worth measuring", and sm_86, where native FP8 does not exist -- that is Ada, sm_89 -- and NVFP4 does not either, that being Blackwell. An FP8 checkpoint does still load on Ampere, dequantized weight-only through FP8 Marlin, so the honest statement is not "no FP8" but "the memory saving without the arithmetic". INT4/INT8 Marlin are the only real vLLM path here. The second thing a VRAM check cannot see: vLLM holds the whole model in VRAM and has no --n-cpu-moe equivalent. A 118B MoE that llama.cpp runs out of system RAM does not run slower under vLLM, it does not run. So abundant system RAM is an argument AGAINST vLLM, which is the opposite of what a memory-keyed rule infers -- and the more RAM there is relative to VRAM, the stronger it gets. lib/runtime.sh derives the verdict from the capability and says which capability it read, so the claim can be checked against NVIDIA's table rather than believed. The boundaries are asserted on both sides, because an off-by-one tells someone their card can do FP8 when it cannot. An unreadable capability returns `unknown` and declines to advise. It deliberately does not share an answer with "too old": an empty string in an arithmetic comparison is zero, which would have classified an undetected card as pre-Volta -- confident, specific and wrong, which is the failure mode this whole change is about. plan_for_budget takes the capability as a third, optional argument and sets PLAN_VLLM. The tiers now state only what this rig uses; a test asserts none of them mentions vLLM again, since those five strings are what made the advice unfixable in one place. TUNING.md's existing vLLM bullet gains the hardware reasoning and, more usefully, the condition that reverses it: one Blackwell card with 48 GB or more, where NVFP4 plus Poolside's DFlash speculative decoding -- not in mainline llama.cpp -- makes vLLM the better stack. Closes #28 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rammsguns
left a comment
There was a problem hiding this comment.
PM review: the Ampere correction is accepted, but two precision fixes are required before merge.
-
sm_75is currently classified asint, andvllm_advice 7.5 ...therefore says there is “no FP8 path at all.” Current vLLM FP8 documentation says FP8 checkpoints run on compute capability >= 7.5 as weight-only W8A16 through FP8 Marlin. Split or adjust the 7.5 boundary, update the prose/table, and add boundary tests at 7.4/7.5. Do not imply that Turing has native FP8. -
The documented reversal condition is one Blackwell card with >=48 GB, but the
fp4branch says vLLM “pulls clearly ahead” for everysm_100+device regardless of capacity;fit_total_mbdoes not gate that conclusion. Make the positive verdict reflect both kernel capability and resident-memory viability (or soften it to a capability statement when capacity is below/unknown), and test both sides of the chosen capacity boundary.
The A4000/sm_86 conclusion remains correct: FP8 can load as W8A16, yielding weight-memory savings without native FP8 arithmetic, and Laguna XS FP8 still exceeds this rig's usable VRAM.
After these changes, merge current main into this branch because #24 and #25 also touch TUNING.md, rerun CI, and report any conflict resolution explicitly.
Two precision fixes from review. Both are cases of a true statement being applied one step too widely. FP8 has two floors, not one. Native W8A8 arithmetic starts at compute capability 8.9, but *loading* an FP8 checkpoint works from 7.5 through FP8 Marlin as weight-only W8A16. The table put the weight-only floor at 8.0, so a Turing owner was told there was "no FP8 path at all" when they have exactly the path Ampere has. 7.5 now joins the int-fp8-weight class and 7.0 keeps the older verdict, asserted on both sides. Correcting that boundary also turned a hardcoded string into a lie: the class sentence read "(Ampere)", which is wrong for every Turing card in it. The architecture name is derived from the capability now, and a test asserts a Turing card is never called Ampere. TUNING.md says the reversal condition is one Blackwell card with >=48 GB. The code said NVFP4, full stop -- so a 12 GB Blackwell laptop chip was told vLLM "pulls clearly ahead" on a card that cannot hold the model resident, which is the single thing vLLM requires. The positive verdict now needs both halves; below the gate it reports the kernels honestly and names capacity as the binding constraint. The gate is measured on the weight budget after the KV reserve, which is the only memory figure vllm_advice is handed. That makes it stricter than a 48 GB sticker price. Deliberate, and written down where the number is: under-promising about hardware nobody here has run is the safe direction. Ampere's verdict is unchanged, and tests assert the gate does not leak into the other kernel classes -- memory cannot conjure kernels, and Ada does not lose native FP8 for being small. Also: the advice line now names vLLM in every branch. 00-specs.sh prints it bare, and only the two early returns carried the label -- so on a box whose RAM does not dwarf its VRAM the report emitted an unattributed sentence about compute capability.
|
Both fixes are in 1. The 7.5 boundary. You are right, and the doc says so plainly: FP8 W8A8 needs ≥8.9, but "FP8 models will run on compute capability >= 7.5 (Turing) as weight-only W8A16, utilizing FP8 Marlin." Turing has exactly the path Ampere has, and the table was telling those owners they had none.
Correcting the boundary exposed a second defect you did not ask about: the class sentence hardcoded the literal string 2. The capacity gate. Also right, and worse than a hedge — a 12 GB Blackwell laptop chip was being told vLLM "pulls clearly ahead" on a card that cannot hold the model resident at all, which is the one thing vLLM requires. One thing to overrule if you disagree: the 48 GB is measured on the weight budget after the KV reserve, since that is the only memory figure 3. Found while in there. Merge-down and conflicts. The #24/#25 collision was real and was resolved on #25 by keeping both sections — rollback first, since it closes out the tuning content the page is about, then reproducibility — plus one sentence tying them together, that pinning the software is only half a reproducible measurement if the machine underneath has drifted. Nothing was dropped from either side. 480 tests pass across 15 suites, both runners. Still not measured: no Turing card, no Blackwell card, and no vLLM install. Every boundary here is read off vLLM's documentation, and the 48 GB figure is a product decision rather than an observation. That is why the citation sits in the source. |
One conflict, in README.md, and it was an insertion collision rather than a disagreement: this branch adds "Rating the models you serve" immediately before "## Configuration", and #25 adds "The llama-swap binary is pinned and verified" in the same place. Neither edits the other's text. Both sections are kept, ratings first. The ratings section continues the catalog thread the surrounding prose is already on -- it opens by answering "a quarter of the score is a neutral placeholder", which is the sentence two sections above it -- and the llama-swap section is about 40-serve.sh, so it reads as the last thing before Configuration rather than an interruption. Nothing was dropped from either side. Everything else merged clean, including the two places most likely to have collided: catalog_ratings() in lib/catalog.sh, where #27 added two Laguna rows carrying unknown ratings while this branch changes how ratings are produced, and tests/cases/catalog_test.sh.
Closes #28.
The advice was keyed on VRAM, which cannot see which low-precision kernels a card has. On this rig that produced a confidently wrong recommendation, so the fix is to derive the verdict from
GPU_CC— already detected and exported bylib/detect.sh— and to name the capability in the output so the claim is checkable.A positive verdict now needs two things: kernels the card has, and enough resident room to put a model in front of them. Each axis alone has already produced advice that was wrong.
Before and after, same machine
Two A4000s, 21,453 MB usable after the KV reserve, ~109 GB system RAM:
Change nothing but the capability to 10.0 and the same budget gets a different sentence. That divergence is the property that was missing, and it is what the central test asserts.
Boundaries
noneintint-fp8-weightfp8fp4unknownunknownis deliberately not the same answer asnone. An empty string in an arithmetic comparison is zero, which would classify an undetected card as pre-Volta — the same species of confident wrongness this PR exists to remove.Two corrections from review, and one found while making them
FP8 has two floors, not one. The table put weight-only FP8 at 8.0. It is 7.5. vLLM's FP8 documentation: "FP8 computation is supported on NVIDIA GPUs with compute capability >= 8.9" and "FP8 models will run on compute capability >= 7.5 (Turing) as weight-only W8A16, utilizing FP8 Marlin." So a Turing owner was being told there was "no FP8 path at all" when they have exactly the path Ampere has. 7.5 now joins
int-fp8-weight; 7.0 keeps the older verdict; both sides of 7.4/7.5 are asserted, and a test states plainly that Turing must never be described as having FP8 hardware. (vLLM FP8 docs)NVFP4 alone did not earn "pulls clearly ahead." TUNING.md's reversal condition is one Blackwell card with ≥48 GB, and the code only checked the kernels — so a 12 GB Blackwell laptop chip was told vLLM pulls clearly ahead, on a card that cannot hold the model resident at all, which is the single thing vLLM requires. The positive verdict now needs both halves. Below the gate the kernels are still reported honestly and capacity is named as the binding constraint. Both sides of 49,151 / 49,152 MB are asserted, and a further test checks the gate does not leak into the other classes — memory cannot conjure kernels for Ampere, and Ada does not lose native FP8 for being small.
Found while fixing the first one: the
int-fp8-weightsentence hardcoded the string(Ampere), which became a lie for every Turing card the moment 7.5 moved into that class. The architecture name is derived from the capability now, and a test asserts a Turing card is never called Ampere.Judgement calls
PLAN_RUNTIMEstates what the rig uses,PLAN_VLLMjudges the alternative.00-specs.shprints the verdict unconditionally, as its own line. It is an opinion about something you are not running, so hiding it when negative would make the report only ever advertise vLLM. Because it prints bare, with no label around it, the sentence now names vLLM in every branch — previously only the two early returns did, so on a box whose RAM does not dwarf its VRAM the report emitted an unattributed sentence about compute capability.gpu_ccis an optional third argument rather than read from the environment, to keepplan_for_budgetpure and testable. Omitted, you get "not assessed".vllm_adviceis handed. That makes it stricter than a 48 GB sticker price — a 48 GB card with a 10 GB reserve lands near 38 GB and gets the hedged sentence. Deliberate, and written down at the constant: nobody here has run a Blackwell box, and under-promising about hardware you do not own is the safe direction to be wrong in. Easy to lower if you would rather it track card capacity; that would mean threading total VRAM through as a fourth argument.Docs
TUNING.md's existing vLLM bullet under Rejected, with reasons is expanded rather than duplicated — it previously rejected vLLM on workload grounds only (prefix caching, single user, no NVLink), which is true but the weaker half of the argument. It now carries the hardware reasoning, both FP8 floors, and the reversal condition with both halves marked load-bearing. README says the same in one paragraph.
Not done
vLLM was not installed or benchmarked here. The claims are about which kernels the hardware has, which is a specification, not a measurement — and the one measurement that would settle it (INT4 Laguna XS under vLLM with TP=2 vs llama.cpp) needs a 19 GB download and a working vLLM install to produce a number that only describes this box. Happy to do it if you want the empirical version.
No Turing or Blackwell card was tested either. Those boundaries are read off vLLM's documentation, which is why the citation is in the source next to the numbers.
Conflict note
mainhas been merged down after #24 and #25 landed. No conflict — those two both inserted new top-level sections before Known rough edges, while this PR edits a bullet inside Rejected, with reasons, so git took all three. The resulting section order is Rejected → Rolling the OS tuning back → Reproducibility of the stack itself → Known rough edges. (The #24/#25 collision was real and was resolved on #25.)Tests
480 pass across 15 suites, both runners green.
tests/cases/runtime_test.shis 21 tests, 7 of them added by this review pass: the 7.4/7.5 boundary, Turing's weight-only path, Volta keeping the no-FP8-at-all verdict, derived architecture names, NVFP4-without-capacity, both sides of the 48 GB gate, and the gate not leaking into the other classes.