Benchmark a model on this machine
Whether a model meets your latency and throughput targets is a property of this machine, this quantization and this serving shape, and bench measures exactly that. Every runnable text family provides it, the flow drives the same serving pipeline prompt and serve run on, and the result is a structured table, never ad-hoc prints.
The default sweep
clika-modelverse meta-llama/Llama-3.2-1B-Instruct bench --device cuda
The default sweep runs three serving-shaped cells (balanced 128:128, prefill-heavy 2048:128, decode-heavy 128:1024) over the default concurrency ladder (1, 4, 8), each cell strictly one at a time so cells never contend with each other. One CSV row per cell and concurrency, the last column naming what the row measured:
isl,osl,concurrency,ttft_ms,prefill_tok_s,itl_p50_ms,itl_p99_ms,prefill_chunk_ms_p50,prefill_chunk_ms_max,decode_tok_s,speedup_vs_c1,batching_efficiency,admitted_tok,retires,status,reason,notes
128,128,1,6.864928,18645.498,4.660638,8.971654,0,0,203.36226,1,1,0,2,ok,"",prompts=cold (a fresh prompt every iteration; prefill_tok_s prices prompt ingest)
128,128,4,19.85135,6447.924,5.458697,13.789374,0,0,651.78723,3.2050552,0.8012638,0,8,ok,"",prompts=cold (a fresh prompt every iteration; prefill_tok_s prices prompt ingest)
128,128,8,33.74735,3910.5552,4.789912,12.197703,0,0,1545.349,7.598996,0.9498745,0,16,ok,"",prompts=cold (a fresh prompt every iteration; prefill_tok_s prices prompt ingest)
2048,128,1,61.346237,33384.28,4.935648,9.665019,0,0,178.64566,1,1,0,2,ok,"",prompts=cold (a fresh prompt every iteration; prefill_tok_s prices prompt ingest)
2048,128,4,186.73393,14730.354,6.8231645,27.292572,0,0,478.35248,2.6776607,0.6694152,0,8,ok,"",prompts=cold (a fresh prompt every iteration; prefill_tok_s prices prompt ingest)
2048,128,8,443.7948,4614.745,5.977193,15.1585245,0,0,817.9034,4.578356,0.5722945,0,16,ok,"",prompts=cold (a fresh prompt every iteration; prefill_tok_s prices prompt ingest)
128,1024,1,6.130809,20878.158,4.774493,9.330061,0,0,203.21771,1,1,0,2,ok,"",prompts=cold (a fresh prompt every iteration; prefill_tok_s prices prompt ingest)
128,1024,4,16.072428,8384.906,5.683443,14.419685,0,0,695.1792,3.4208593,0.85521483,0,8,ok,"",prompts=cold (a fresh prompt every iteration; prefill_tok_s prices prompt ingest)
128,1024,8,31.530767,4059.5269,5.0563264,13.9837,0,0,1479.9001,7.282338,0.91029227,0,16,ok,"",prompts=cold (a fresh prompt every iteration; prefill_tok_s prices prompt ingest)
The numbers are one machine's run (an RTX 4080, this model at its checkpoint dtype, bf16, cold prompts, the default); yours are the point. Stdout carries the CSV, ready for a spreadsheet or a script; diagnostics ride stderr. A failed cell reports error in status without invalidating the rows around it, and the reason column carries the model's own refusal or the cell's first failure in words (empty on an ok row). With --output, the report streams to disk as rows complete, so a run killed at its deadline keeps every finished cell.
Shape the sweep to your workload
--cells 512:256,4096:64: your ownisl:osllist, replacing the default three.--isl/--oslset a single cell directly.--concurrency 1,4,16: the parallel-session ladder;speedup_vs_c1andbatching_efficiencyin the report tell you what the added concurrency actually bought.--shared-prefix 256: how many prompt tokens every session shares (a system prompt, a RAG preamble); with it theadmitted_tokandretirescolumns show the paged prefix cache engaging. Every LLM cell runs cold prompts by default (a fresh random prompt per session every iteration, so a paged prefix cache serves no repeat;--unique-promptsnames that default and stays accepted).--repeat-promptsis the warm protocol: the warm-up and every iteration reuse one prompt set, soprefill_tok_sreads cache admits, and the row'snotessay so.--warmupand--iters: runs discarded before timing, then runs averaged.- The load knobs apply unchanged:
--kvcache paged|continuous,--prefill-chunk,--step-token-budget, a GGUF weight selector on the source,--max-seq. --output PREFIXwrites the report to files beside the terminal view;--profileadds the per-op profile on stderr (the summary opens withProfiling Report Summary:, itstop_ops:block ranks op groups by self time, and the per-op table carries anAvgSelf(us)column, the per-op average that excludes nested spans),--profile-pipelinethe per-node one.
Reading the columns
ttft_ms is the enqueue-to-first-token wall, the number an interactive user feels. prefill_tok_s is prompt ingest; decode_tok_s is the aggregate generation rate across sessions. The inter-token percentiles itl_p50_ms/itl_p99_ms sample decode-only gaps; on a chunked-prefill run the chunk boundary walls report separately (prefill_chunk_ms_p50/_max), so a decode tail is never polluted by an ingest wall. When the p99 sits far above the p50, the deployment story is a batching or cache-pressure story, and the concurrency ladder narrows down which. The -v diagnostics carry the load and peak-memory figures the Model requirements page's estimates are checked against.
Audio and media axes
A speech-to-text family's bench sweeps audio length instead of token shapes (--audio-seconds 5,30,120, with the same --concurrency ladder), reporting ingest as encoder frames over the end-to-end transcribe wall. Multimodal families add mm_bench, the media sweep over the serving path: --images per request, --image-resolution, --video-frames, with effective_isl reporting what the prefill actually ingested once media expansions counted, so a media-heavy row's ingest rate stays comparable to a text row's.
Benchmark the quantization you intend to ship (Run a specific GGUF quantization); a Q4_K_M and a Q8_0 of the same model can sit on different sides of a latency target. The serving flags that shaped a good bench row carry directly onto serve (Serve an OpenAI-compatible endpoint).