If you read one thing, read this. Every flag is justified by a measurement below.
llama-server -m Qwen3.8-27B-UD-Q4_K_M.gguf \
-ngl 999 -fa on --jinja \
-c 262144 -b 1024 -ub 1024 \
--cache-type-k q4_0 --cache-type-v q4_0 \
--spec-type draft-mtp --spec-draft-n-max 5 \
--reasoning-effort low \
--parallel 1 --no-mmap \
--host 127.0.0.1 --port 8080
| Flag | Effect | Evidence |
|---|---|---|
| --spec-draft-n-max 5 | +137% | Swept 2–12, sharp peak at 5. Community default of 2 costs 35 tok/s here. |
| --reasoning-effort low | ~4.2× | Time-to-answer 231 s+ → 55 s on an identical prompt. |
| --spec-type draft-mtp | enables | MTP heads ship inside the GGUF as blk.*.nextn.*; ignored without this. |
| -fa on | required | Saves ~2.3 GB. Without it 256K will not fit. |
| --cache-type-k/v q4_0 | required | Lighter and faster than f16. 256K lands at 23,504 of 24,462 MB. |
| --parallel 1 | protects | Speculative decode is single-stream; the gain vanishes above 1. |
| -c 262144 | −2% | 81.2 vs 82.9 tok/s at 32K. Nearly free to allocate. |
| --no-mmap | neutral | Weights live in VRAM; mmap only helps when paging. |
off — 33 s, pure code, best draft acceptance. low — 55 s, still
reasons, the general default. medium — 91 s, real deliberation.
xhigh — the shipped default, and it did not finish inside 16,384 tokens.
Structured output wants a much wider draft window than prose or code.
Set --spec-draft-n-max 10 when generating JSON, HTML, XML or any rigid format;
5 for code and prose. Using 5 on JSON costs 21% (141.6 → 112.1 tok/s).
| Workload | Set n-max | Decode | vs baseline |
|---|---|---|---|
| JSON / structured | 10 | 141.6 | +250% |
| HTML / markup | 10 | 118.1 | +192% |
| Code | 5 | 93.7 | +131% |
| Prose | 5 | 58.4 | +45% |
Each of these was a fork where the obvious choice was wrong.
| Decision | Chosen | Reasoning |
|---|---|---|
| CUDA version | 12.8.1 | The 13.x line crashes the Blackwell MMQ kernel. winget only offers 13.3, so this must come from NVIDIA's archive manually. 12.8+MMQ benchmarks ~6,500 t/s prefill against ~750 for 13.x+cuBLAS. |
| Driver | keep 610.88 | The 12.8.1 installer bundles 572.61. Installing it would be a downgrade, so Display.Driver is omitted from the subpackage list. |
| Quantizer | Unsloth | Their GGUFs preserve the blk.*.nextn.* MTP tensors. Not every quantizer keeps them, and without them the single largest speed lever is dead. |
| Quant level | UD-Q4_K_M | 15.32 GiB leaves ~8 GB for KV cache, which is what makes 256K context reachable. Q5/Q6 would trade context headroom for fidelity. |
| Generator | Ninja | Much faster than MSBuild, but does not auto-discover MSVC — vcvars64.bat must be imported first. |
| Shell | PowerShell | Git Bash cannot load the built binaries at all (UCRT resolution failure). |
| Bench tool | llama-cli | llama-bench has no speculative-decoding flags, so it cannot measure the thing that matters most. |
MSVC is the usual blocker. Check before downloading 3 GB of toolkit.
winget --version
git --version
& "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" `
-products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 `
-property installationPath
If VS Build Tools is absent, install it with the C++ workload — the bare package is not enough:
winget install --id Microsoft.VisualStudio.2022.BuildTools --exact `
--override "--quiet --wait --norestart `
--add Microsoft.VisualStudio.Workload.VCTools --includeRecommended"
winget install --id Kitware.CMake --exact
winget install --id Ninja-build.Ninja --exact
If winget reports exit 43 (“no applicable upgrade”),
the package is already installed — but your --override was
not applied. Verify cl.exe exists rather than trusting the exit code.
curl.exe -L -o cuda_12.8.1.exe `
https://developer.download.nvidia.com/compute/cuda/12.8.1/local_installers/cuda_12.8.1_572.61_windows.exe
# 3.14 GB. Verify the signature before running it.
(Get-AuthenticodeSignature .\cuda_12.8.1.exe).Status # -> Valid
# Explicit subpackages. Display.Driver deliberately ABSENT.
.\cuda_12.8.1.exe -s -n `
nvcc_12.8 cudart_12.8 thrust_12.8 `
cublas_12.8 cublas_dev_12.8 `
nvrtc_12.8 nvrtc_dev_12.8 `
cuda_profiler_api_12.8 nvtx_12.8 nvml_dev_12.8 `
cuobjdump_12.8 nvdisasm_12.8 nvprune_12.8 cuxxfilt_12.8 `
nvfatbin_12.8 nvjitlink_12.8 `
visual_studio_integration_12.8
verify:
nvcc --version -> release 12.8, V12.8.93
nvidia-smi --query-gpu=driver_version --format=csv,noheader -> 610.88 (unchanged)
One invalid subpackage name aborts the entire install. Exit
-522190823 = 0xE0E00019. The NVIDIA log ends normally at 2.101 s with
no error text and nothing is installed. There is no cuda_cccl; it is
nvrtc_12.8 and nvml_dev_12.8, not the cuda_-prefixed
forms. Get names from NVIDIA's Windows install guide — never guess.
The installer does not do this, and nothing tells you.
$cuda = 'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.8\bin'
[Environment]::SetEnvironmentVariable('Path',
[Environment]::GetEnvironmentVariable('Path','Machine') + ";$cuda", 'Machine')
Without this, every llama.cpp binary exits -1073741515
(0xC0000135, STATUS_DLL_NOT_FOUND) producing
no stdout and no stderr at all. --help returns nothing.
git clone --depth 1 https://github.com/ggml-org/llama.cpp
cd llama.cpp
# Ninja does not auto-discover MSVC; import vcvars into the session first.
$vc = 'C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvars64.bat'
cmd /c "`"$vc`" && set" | ForEach-Object {
if ($_ -match '^([^=]+)=(.*)$') { Set-Item "env:$($matches[1])" $matches[2] }
}
# Delete build/ EVERY time. See Trap 03.
Remove-Item build -Recurse -Force -ErrorAction SilentlyContinue
cmake -B build -S . -G Ninja `
-DCMAKE_BUILD_TYPE=Release `
-DGGML_CUDA=ON `
-DCMAKE_CUDA_ARCHITECTURES=120 `
-DGGML_CUDA_FORCE_CUBLAS=OFF `
-DGGML_CUDA_F16=ON `
-DLLAMA_CURL=OFF
cmake --build build -j 24
# verify you are on the fast path, not silently on cuBLAS:
Select-String build\CMakeCache.txt -Pattern 'FORCE_CUBLAS|CUDA_ARCHITECTURES'
GGML_CUDA_FORCE_CUBLAS:BOOL=OFF <- must be OFF
CMAKE_CUDA_ARCHITECTURES:UNINITIALIZED=120
# confirm the GPU is seen with the right compute capability:
.\build\bin\llama-bench.exe --list-devices
Device 0: NVIDIA GeForce RTX 5090 Laptop GPU, compute capability 12.0, VRAM 24462 MiB
GGML_CUDA_FORCE_CUBLAS persists in CMakeCache.txt
across reconfigures. If it was ever ON, it stays ON, the MMQ path is
disabled, and you lose 5–6× on prefill with no warning whatsoever. Delete
build/ and grep the cache afterwards.
MSVC 14.44 compiles cleanly against CUDA 12.8 despite postdating it. Do not
pre-emptively add -allowUnsupportedCompiler.
curl.exe -L --fail --retry 3 -o Qwen3.8-27B-UD-Q4_K_M.gguf `
https://huggingface.co/unsloth/Qwen3.8-27B-GGUF/resolve/main/Qwen3.8-27B-UD-Q4_K_M.gguf
# verify byte-exact against the remote Content-Length:
(Get-Item Qwen3.8-27B-UD-Q4_K_M.gguf).Length -> 16464440224
Reported by llama.cpp as qwen35 27B Q4_K - Medium, 15.32 GiB, 27.32 B params.
NVIDIA Control Panel → Manage 3D Settings → CUDA - Sysmem Fallback Policy →
Prefer No Sysmem Fallback, scoped to llama-server.exe. Restart the process
— the policy binds at CUDA context creation.
Since driver 536.40, Windows does not OOM when you overfill VRAM. It spills into shared system memory over PCIe. No error, no crash, and llama.cpp still reports “using GPU”. At 256K context you hold 958 MB of headroom, so you want a loud failure rather than a quiet one.
Every failure encountered, with its exact symptom. Ordered by cost.
| # | Trap | Symptom | Fix |
|---|---|---|---|
| Build & toolchain | |||
| 01 | Bad CUDA subpackage name | exit -522190823 | Aborts whole install, no error text. Use documented names. |
| 02 | CUDA bin not on PATH | exit -1073741515 | STATUS_DLL_NOT_FOUND, zero output. Add to machine PATH. |
| 03 | Stale FORCE_CUBLAS | silent, 5–6× slower | Delete build/; grep CMakeCache.txt. |
| 04 | CUDA 13.x on Blackwell | segfault / cuBLAS | Use 12.8. winget only has 13.3. |
| 05 | Ninja can't find MSVC | compiler test fails | Import vcvars64.bat before configure. |
| 06 | Bundled driver downgrade | 610.88 → 572.61 | Omit Display.Driver from subpackages. |
| 07 | winget exit 43 | override ignored | Package present; workload may not be. Verify cl.exe. |
| Shell & flags | |||
| 08 | Git Bash runs the exe | api-ms-win-crt-heap | Use PowerShell. Failure line starts with the exe path, not error: — a naive grep reports success. |
| 09 | -no-cnv removed | invalid argument | Use -st/--single-turn. Present in arg.cpp but unregistered — trust --help. |
| 10 | llama-bench for MTP | flags absent | Use llama-cli/llama-server. |
| 11 | PowerShell arg splatting | mangled args | Verify the binary received what you sent before blaming the flag. |
| Model & measurement | |||
| 12 | -effort minimal | Jinja Exception | Only low/medium/xhigh exist. |
| 13 | -effort high | silently faked | Falls back to xhigh. Byte-identical output proves it. |
| 14 | Token cap too low | truncated mid-word | Invalidates time-to-answer. Verify output completes. |
| 15 | Sysmem fallback | silent 5–10× | Set “Prefer No Sysmem Fallback”. |
| 16 | Benchmarking at -np > 1 | MTP gain vanishes | Speculative decode is single-stream. |
| 17 | -f plus empty -p | hangs forever | llama-cli waits on stdin; under a non-interactive shell it never returns. Model loads (VRAM occupied) then sits at idle power. Pass -f alone. |
| 18 | $args in PowerShell | --model is required | $args is an automatic variable; assigning to it and splatting silently drops everything. Rename it. |
--reasoning-effort high returns plausible numbers, so it looks like data. Stripping
timing lines and hashing the output bodies proves all three are the same generation:
high.log 14190 bytes 64.0 t/s md5 4df134687af5408a19b989dc4b5c8530
xhigh.log 14190 bytes 63.7 t/s md5 4df134687af5408a19b989dc4b5c8530
default.log 14190 bytes 63.9 t/s md5 4df134687af5408a19b989dc4b5c8530
The 0.3 tok/s spread is run noise on identical work. Generalisable lesson: when a flag has no documented value list, verify it changed the output before you trust the number.
Individual runs, not just means. --temp 0 and a fixed seed make speculative decoding
deterministic run-to-run, but NOT byte-identical across draft widths — see the corrected methodology note below.
| Config | Run 1 | Run 2 | Mean | Spread | vs base | Prompt t/s |
|---|---|---|---|---|---|---|
| baseline | 40.9 | 40.6 | 40.8 | 0.3 | — | 219 / 225 |
| n-max 2 | 61.1 | 61.1 | 61.1 | 0.0 | +49.9% | 199 / 197 |
| n-max 3 | 65.2 | 65.2 | 65.2 | 0.0 | +60.0% | 194 / 192 |
| n-max 4 | 63.8 | 63.8 | 63.8 | 0.0 | +56.6% | 203 / 197 |
| n-max 5 | 96.7 | 96.9 | 96.8 | 0.2 | +137.5% | 193 / 199 |
| n-max 6 | 94.7 | 95.2 | 95.0 | 0.5 | +133.0% | 188 / 189 |
| n-max 7 | 93.9 | 93.9 | 93.9 | 0.0 | +130.4% | 194 / 188 |
| n-max 8 | 94.1 | 93.7 | 93.9 | 0.4 | +130.4% | 190 / 193 |
| n-max 10 | 89.2 | 89.6 | 89.4 | 0.4 | +119.4% | 193 / 184 |
| n-max 12 | 83.1 | 83.2 | 83.2 | 0.1 | +104.0% | 184 / 191 |
| Config | Run 1 | Run 2 | Run 3 | Mean | vs base |
|---|---|---|---|---|---|
| baseline | 40.9 | 40.5 | 40.6 | 40.7 | — |
| n-max 2 | 46.3 | 46.3 | 46.3 | 46.3 | +13.9% |
| n-max 3 | 43.3 | 43.3 | 43.4 | 43.3 | +6.6% |
| n-max 5 | 51.8 | 51.7 | 51.7 | 51.7 | +27.2% |
| n-max 6 | 47.1 | 47.0 | 47.3 | 47.1 | +15.9% |
| n-max 8 | 51.0 | 51.4 | 51.2 | 51.2 | +25.9% |
| draft-dspark | 40.3 | — | — | 40.3 | −1.0% |
| Effort | Answer time | Tokens | Decode | Status | Note |
|---|---|---|---|---|---|
| off | 33.2 s | ~3,008 | 90.6 | complete | No thinking block emitted. |
| low | 55.1 s | ~4,783 | 86.8 | complete | Thinks, then answers. |
| medium | 91.4 s | ~8,436 | 92.3 | complete | Extended deliberation. |
| xhigh (default) | 231 s+ | >16,384 | 70.3 | truncated | Hit the cap still mid-thinking. 231 s is a floor. |
| high | — | — | 64.0 | fake | Silently resolves to xhigh. |
| minimal | — | — | — | error | Jinja exception; not a valid level. |
| Context | Decode | Prompt | Peak VRAM | % of 24,462 MB | Headroom |
|---|---|---|---|---|---|
| 32,768 | 82.9 | 111.3 | 17,262 MB | 70.6% | 7,200 MB |
| 131,072 | 81.3 | 100.2 | 19,920 MB | 81.4% | 4,542 MB |
| 262,144 | 81.2 | 102.1 | 23,504 MB | 96.1% | 958 MB |
| Depth | Prefill | Decode | Retention | Peak VRAM | Wall |
|---|---|---|---|---|---|
| empty (ref) | — | 83.4 | 100% | 17,262 MB | — |
| 24K filled | 1357.5 | 63.8 | 76% | 17,272 MB | 37.9 s |
| 100K filled | 807.3 | 57.5 | 69% | 19,930 MB | 155.9 s |
| 200K filled | 522.2 | 36.1 | 43% | 23,514 MB | 466.1 s |
At 200K filled, decode is 36.1 tok/s — below the 40.8 tok/s unoptimised baseline we started from. Deep context costs more than MTP and reasoning-effort tuning gained combined. Every other speed figure in this guide is a shallow-depth figure.
Prefill degrades too: 1357 → 807 → 522 t/s with depth. At 200K that is roughly 6.4 minutes of ingest before the first token. Time-to-first-token, not decode rate, dominates a genuinely long session.
Peak VRAM at 200K filled (23,514 MB) matches the allocated-only figure (23,504 MB) almost exactly, confirming the KV cache is preallocated rather than grown. VRAM planning can use the empty-window numbers; throughput planning cannot. Note also that Experiment D's “Prompt t/s” column (~100–111) is overhead on a tiny prompt, not a real prefill rate — the true rates are in Experiment F.
| Shape | base | n2 | n3 | n4 | n5 | n6 | n8 | n10 | n12 | n16 | n20 | Best |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| code | 40.5 | 60.3 | 62.6 | 61.2 | 93.7 | 89.8 | 93.1 | — | — | — | — | n5 +131% |
| prose | 40.4 | 48.5 | 45.8 | 38.6 | 58.4 | 53.8 | 49.0 | — | — | — | — | n5 +45% |
| json | 40.4 | 63.9 | 71.6 | 71.3 | 112.1 | 120.0 | 130.7 | 141.6 | 137.1 | 130.5 | 122.2 | n10 +250% |
| markup | 40.4 | 64.3 | 70.7 | 69.3 | 109.0 | 111.8 | 115.6 | 118.1 | 111.2 | 101.1 | 96.0 | n10 +192% |
Three things worth extracting. The optimum moves with output shape — n5 for code and prose, n10 for JSON and HTML. The gain varies by 5×, from +45% on prose to +250% on JSON; rigid formats are trivially predictable, so drafts land far more often. And n4 on prose is actively harmful (38.6 against a 40.4 baseline) — the only measured config anywhere in this guide that is slower than no speculation at all.
141.6 tok/s on JSON is the fastest figure measured on this box, well above the 96.8 headline, which was code-shaped. If your workload is structured extraction or API-shaped output, the ceiling here is considerably higher than the front page suggests.
| Limit | Decode (tg128) | Prefill (pp512) | Verdict |
|---|---|---|---|
| 95 W default | 40.86 ± 0.68 | 1664.14 ± 1.73 | — |
| 175 W enforced | 40.94 ± 0.58 | 1661.82 ± 9.09 | No effect. Difference is inside error bars in both directions. |
Sampled at 2 Hz during Experiment B, with the limit raised to 175 W.
| Run | Samples | Peak W | Avg W | Peak SM | Avg SM | Mem clk | Peak °C |
|---|---|---|---|---|---|---|---|
| baseline | 41 | 171.2 | 109.3 | 1987 | 1687 | 14101 | 51 |
| mtp-n2 | 40 | 170.6 | 100.0 | 2100 | 1574 | 14101 | 56 |
| mtp-n3 | 41 | 170.3 | 103.7 | 2017 | 1612 | 14101 | 57 |
| mtp-n4 | 41 | 170.9 | 101.8 | 2047 | 1602 | 9001 | 58 |
| mtp-n5 | 38 | 169.9 | 95.0 | 2272 | 1545 | 14101 | 56 |
| dspark | 42 | 173.3 | 108.5 | 2460 | 1572 | 14101 | 57 |
Three things fall out of this. Average draw is 95–109 W against a 170 W ceiling — the GPU is not power-starved even at the 95 W default, which is why raising the limit changed nothing. Peak temperature is 58 °C, so thermal throttling is simply not a factor on this chassis; the common advice to power-cap for sustained throughput does not apply here. The fastest config draws the least power — n-max 5 averages 95.0 W, the lowest of the set, while being the fastest. Speculative decoding replaces memory traffic with cheap parallel verification.
The mtp-n4 trace caught a memory clock of 9001 MHz against 14101 MHz
elsewhere — a momentary downclock. n4 is also the one config that underperforms its neighbours
(63.8 against 65.2 at n3). Not enough samples to call it causal; flagged for anyone re-running.
n4→n5 jumps 52% between adjacent integers (63.8→96.8), and n5 beats n6. With run-to-run spread of ±0.2 this is not noise. The same cliff appears with thinking on (43.9→51.7), just smaller. This is kernel tiling: certain draft widths produce batch shapes that map well onto the hardware.
Practical consequence: you cannot interpolate. A coarse sweep of 2/4/8 would have found 63.8, 63.8, 93.9 and concluded “bigger is better, use 8” — missing the peak entirely. Sweep every integer through the plausible range.
Not directly reported, but inferable. Speedup ≈ 1 + (mean accepted drafts per verify step):
| Mode | Speedup | Implied extra tokens/step | Reading |
|---|---|---|---|
| reasoning off | 2.37× | ~1.37 of 5 | Code output drafts well. |
| thinking on | 1.27× | ~0.27 of 5 | Reasoning prose drafts badly. |
Roughly 5× better acceptance on code than on reasoning prose, consistent with the commonly cited ~0.80 vs ~0.60 acceptance figures. Marked derived, not measured — llama.cpp did not print acceptance counters in these runs.
Rarely mentioned and worth knowing: enabling MTP reduces prompt throughput. Thinking-on runs show baseline 301.4 t/s prompt against 254–259 with MTP — roughly −15%. Reasoning-off runs show ~222 baseline against ~193 — about −12%.
Net strongly positive for generation-heavy work. But for a workload that ingests huge prompts and emits little — bulk classification, reranking — MTP may be a net loss. Measure your own shape.
Decode rate across effort levels spans only 70–92 tok/s. Token spend spans
3,008 to over 16,384 — more than 5×. Optimising tok/s would have picked
medium (92.3, the highest of the completed runs) when off answers the
same question in a third of the time. Measure time to a complete answer.
The laptop 5090 has 896 GB/s against the desktop's 1792 — exactly half. A pure bandwidth model predicts ~30 tok/s baseline against the desktop's 61.4. It measured 40.8, or ~67% of desktop, not 50%. Decode is bandwidth-bound but not purely so. Predictions from bandwidth ratios alone will be pessimistic.
| Tried | Result | Why |
|---|---|---|
| 95 W → 175 W | 0% | 40.86→40.94 tok/s. GPU genuinely drew 171 W peak at 1987–2472 MHz, but averaged only 95–109 W — it was never power-starved. Decode is bandwidth-bound and GDDR7 clocks don't scale with power budget. |
| draft-dspark | −1% | 40.3 vs 40.8 baseline. No benefit over no speculation at all. |
| n-max > 8 | falls off | n10 89.4, n12 83.2. Wider drafts cost more than they recover. |
| -effort high | fake | Byte-identical to xhigh. Plausible numbers that are just the default — worse than an error. |
| -effort minimal | error | Jinja Exception: Unexpected reasoning effort minimal. Supported types are xhigh (default), medium, and low. |
| Thermal power-capping | n/a | Peak 58 °C. Standard advice to cap at 75–80% for sustained throughput solves a problem this chassis does not have. |
| Git Bash as host shell | cannot run | UCRT resolution failure on every binary. |
Two methodology errors were made and corrected during this work. Both are easy to repeat and neither announces itself.
| Rule | Reason |
|---|---|
| Verify output completes | At -n 3072 the high-effort runs were cut off mid-token, so “time to answer” was really “time to hit the cap”. Even -n 16384 did not finish xhigh. Read the tail of the output, don't trust the timer. |
| Confirm the flag did something | -effort high was benchmarked before anyone noticed it silently resolves to the default. Hash the output body against a known config. |
--temp 0 + fixed seed | Corrected. An earlier version of this guide claimed speculative decoding is lossless and therefore byte-identical across draft widths. That is false. Each config is deterministic run-to-run (rep1 == rep2, always), but configs diverge from each other by 98–117 lines. Cause: batched draft verification uses different matmul shapes than single-token decode; floating-point addition is not associative, an argmax flips, and divergence cascades. Lossless in theory, not bit-exact in practice. The fixed seed still gives reproducibility within a config, which is what makes the timings comparable. |
| Check quality across draft widths | Because output genuinely differs by n-max, wider drafts could in principle trade quality for speed. Probed on structured output: JSON stayed valid with all 10 records and every required field at base, n5, n10 and n20. Reassuring, but one probe on one task type — not a general guarantee. |
| Verify the flag changed the output | Hash the output body against a known-good config. Two separate settings in this guide (--reasoning-effort high, and thinking:{type:'disabled'} on the API side) produced plausible numbers that were measuring something other than what was intended. |
--parallel 1 | Speculative decode is single-stream. Mixed parallelism produces incomparable numbers. |
| Generate ≥ 400 tokens | Short generations pay more in speculation overhead than they recover. |
| Subtract model load | ~12.7 s constant on this box. Measure it once with -n 1 and subtract, or it swamps short runs. |
| Sample telemetry alongside | Power and clock traces are what proved the limit change was inert, rather than assuming it helped. |
| Retain invalid runs | The truncated and faked runs are the most instructive rows in the dataset. |
$common = @('-m',$model,'-ngl','999','-fa','on',
'-ctk','q4_0','-ctv','q4_0',
'-c','32768','-n','1024','--seed','42','--temp','0',
'-st','--no-warmup','--reasoning','off','-p',$prompt)
foreach ($n in 2,3,4,5,6,7,8,10,12) {
for ($i=1; $i -le 2; $i++) {
& $cli @common --spec-type draft-mtp --spec-draft-n-max $n *> "$out\n$n-$i.log"
}
}
# llama-cli reports: [ Prompt: NNN t/s | Generation: NN.N t/s ]
# NOT the llama_perf_context_print / "eval time" format older guides parse.
Stated so nobody mistakes absence of data for absence of a problem.
-effort low is a reasonable default rests on it completing sensibly, not on evidence
it answers as well as xhigh.The laptop 5090 is a different part from the desktop 5090 — 24 GB on a 256-bit bus at 896 GB/s, against 32 GB / 512-bit / 1792 GB/s. Roughly half the bandwidth and three-quarters the VRAM. Published desktop figures do not transfer, and neither do these in the other direction.
-DCMAKE_BUILD_TYPE=Release
-DGGML_CUDA=ON
-DCMAKE_CUDA_ARCHITECTURES=120
-DGGML_CUDA_FORCE_CUBLAS=OFF
-DGGML_CUDA_F16=ON
-DLLAMA_CURL=OFF