Quickstart
This guide takes you from an empty machine to a completed LLM measurement against the in-repo dummy model server. Follow each step in order. Once the toolchain is installed, the loop usually takes under ten minutes.
What you'll do
- Install a release binary or build from source
- Start the dummy OpenAI-compatible server
- Write a tiny JSONL prompt file
- Run
metrum-ai-bench-cli-llm(or the unifiedmetrum-ai-bench-cli llmentry) - Inspect the JSONL data log and end-of-run summary
If you already have a binary and only need a smoke check:
metrum-ai-bench-cli selftest
Before you start
You'll need:
- A Linux (
x86_64oraarch64glibc) or macOS Darwin host for release binaries, or Rust 1.85+ to build from source. Windows has no release binaries (see Platforms). - Go 1.26.6+ only if you start the dummy model server from a source
clone with
go run(matchesdummy-model-server/go.modand CI). Release tarballs already shipbin/dummy-model-serverand need no Go. - Network access only if you download a GitHub Release or fetch the prompt
library later. The dummy-server loop needs no API key beyond the literal
value
dummy.
1. Install
Option A: GitHub Release (preferred for binaries)
- Open Releases and download
the archive for your target (replace
VERSIONandTARGETbelow). - Verify the checksum (and Sigstore bundle when present):
# SHA-256 of the tarball (file next to the archive on the release)
shasum -a 256 -c metrum-ai-bench-cli-vVERSION-TARGET.tar.gz.sha256
# Optional: Sigstore keyless verify (requires cosign)
cosign verify-blob \
--bundle metrum-ai-bench-cli-vVERSION-TARGET.tar.gz.sigstore.json \
metrum-ai-bench-cli-vVERSION-TARGET.tar.gz
Each target also publishes a CycloneDX SBOM as
metrum-ai-bench-cli-TARGET.cdx.json on the same release.
- Unpack so the binaries are on your
PATH. The archive has a versioned root withbin/inside it; do not strip that layout into~/.local/bindirectly:
mkdir -p ~/.local/opt ~/.local/bin
tar -xzf metrum-ai-bench-cli-vVERSION-TARGET.tar.gz -C ~/.local/opt
ln -sf ~/.local/opt/metrum-ai-bench-cli-vVERSION-TARGET/bin/* ~/.local/bin/
Release archives are cross-built with cargo-zigbuild for:
| Target | Notes |
|---|---|
Linux *-unknown-linux-gnu | glibc 2.17 floor; not musl |
| macOS Darwin | x86_64 / aarch64 |
TLS uses rustls (no OpenSSL link). Install from a GitHub Release tarball or build from source; there is no Homebrew install path.
Option B: Build from source
git clone https://github.com/metrum-ai/bench-cli.git
cd bench-cli
cargo build --release
Binaries land under target/release/. Run tests when you want a local gate:
cargo test --all-targets --all-features
Release archives include the otlp feature but not tokenizer. See
Platforms for the feature matrix.
2. Start the dummy server
From a GitHub Release tarball (no Go required; second terminal is fine):
bin/dummy-model-server -port 18321 -latency 100ms -chunk-interval 20ms
If you installed under ~/.local/opt/.../bin and that directory is on PATH,
the same binary name works without the bin/ prefix:
dummy-model-server -port 18321 -latency 100ms -chunk-interval 20ms
From a source clone (needs Go 1.26.6+), from the repository root:
go run ./dummy-model-server/cmd/dummy-model-server \
-port 18321 -latency 100ms -chunk-interval 20ms
Leave it running. The server speaks OpenAI-compatible paths used by the
modality tools. Use --api-key dummy on the client.
This is the Go dummy model server (modality compatibility). For strategic
sweeps, embeddings, and rerank fixtures, use the separate Rust
metrum-ai-bench-cli-mock-server instead - see
Strategic benchmarking.
3. Create a prompt file
Prompt and input files are JSONL only (.csv is rejected).
printf '%s\n' '{"prompt":"Hi"}' > /tmp/metrum-prompts.jsonl
4. Run the LLM client
metrum-ai-bench-cli-llm \
--url http://127.0.0.1:18321/v1/chat/completions \
--api-key dummy \
--scenario reference \
--num-requests 16 \
--concurrency 4 \
--prompts /tmp/metrum-prompts.jsonl \
--mode chat \
--streaming \
--model dummy \
--max-tokens 20 \
--seed 7 \
--warmup-requests 0 \
--data-log /tmp/metrum-reference.jsonl \
--log-level error
Or through the unified entry point (forward modality flags after --):
metrum-ai-bench-cli llm -- \
--url http://127.0.0.1:18321/v1/chat/completions \
--api-key dummy \
--scenario reference \
--num-requests 16 \
--concurrency 4 \
--prompts /tmp/metrum-prompts.jsonl \
--mode chat \
--streaming \
--model dummy \
--max-tokens 20 \
--seed 7 \
--warmup-requests 0 \
--data-log /tmp/metrum-reference.jsonl \
--log-level error
During the v1.x compatibility period the four modality binaries can also be
invoked directly. Prefer the metrum-ai-bench-cli* names; older shim aliases
were removed in 1.3.0.
What success looks like
- Request records stream into
--data-logas each request finishes. - A
summary.v3object is appended when the run completes. - Console statistics match the same
RunSummary/DistSummaryvalues written to JSONL.
Against this dummy configuration on an unloaded machine, the checked-in reproduction guide expects roughly:
| Metric | Expected band |
|---|---|
| Mean TTFT | 0.100–0.200 s |
| Mean E2E latency | 0.420–0.650 s |
| Mean ITL | 0.010–0.040 s |
Those bands surround the dummy server's timing model for
-latency 100ms -chunk-interval 20ms with --max-tokens 20: TTFT ~ 120 ms
(latency + first chunk) and response time ~ 500 ms (100 + 20*20). See
dummy-model-server/README.md in the repository. E2E scales with
--max-tokens; a README quickstart that uses 64 is healthy but will not
land in this table.
Scheduling and counts should match test-data/reference-result.json when you
follow reproducing the reference
exactly. Wall-clock timestamps, UUIDs, hostname, and exact timings differ by
design.
5. Read the result
Every completed request is flushed incrementally to JSONL. Warmup records remain
auditable but are excluded from measured distributions. A graceful Ctrl-C stops
issuance, drains already-started work, and emits partial: true on the summary.
Next steps:
- User Guide for vocabulary and run shapes
- Modalities for VLM, ASR, and imagegen
- Performance Methodology for metric definitions
- Publishing-oriented runs before you publish a named result