cpueval CLI¶
Matrix-first CLI for running comprehensive CPU benchmarks. Most suites run full test matrices by default—no --model required!
Philosophy¶
- Matrix suites run complete test matrices (models × cores × workloads/scenarios) by default
- Easy overrides to narrow scope when needed
- Single-shot suites for targeted deep testing
Quick Start¶
# One-time: Ansible, Galaxy collections, tab completion
./cpueval install
# Matrix suites - run full matrices (no --model required!)
./cpueval --suite rhaiis-sweep # 60 combinations: 5 models × 3 cores × 4 workloads
./cpueval --suite embedding # 30 combinations: 5 models × 3 cores × 2 scenarios
./cpueval --suite offline-batch # 33 runs: use-cases 3
./cpueval --suite audio # Default: all models, transcription-throughput scenario, 32 cores
# Override to narrow
./cpueval --suite rhaiis-sweep --models tiny --cores 8
./cpueval --suite embedding --models quick --cores 4
# Single-shot suites (--model required)
./cpueval --suite chat-smoke --model TinyLlama/TinyLlama-1.1B-Chat-v1.0 --cores 8
# Explore
./cpueval list # Shows Matrix vs Single type
./cpueval show rhaiis-sweep # View default matrix
./cpueval results --last # View results
Installation¶
From the repository root:
./cpueval install
That command installs system packages (when dnf is present), Ansible Galaxy
collections, and bash/zsh tab completion. The ./cpueval launcher automatically
creates a virtual environment on first run. It requires Python 3.10+. On
RHEL 9 / UBI 9, python3 is 3.9; the launcher looks for python3.12 /
python3.11 / python3.10 and will install python3.12 via dnf if needed.
See install - Install prerequisites for
flags (--skip-system-deps, --dry-run, and so on).
For a manual venv only (no system packages or collections):
cd automation/cli
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
Shell Completion¶
cpueval supports tab-completion for bash and zsh.
Install (one-time, auto-detects shell):
./cpueval install # includes completion for cpueval and ./cpueval
# completion only (same ./cpueval registration):
./cpueval install --skip-system-deps --skip-collections
exec zsh # or exec bash
Uninstall:
./cpueval --uninstall-completion
exec zsh # or exec bash
What completes:
| Typing… | Completes with… |
|---|---|
./cpueval <TAB> |
doctor, install, list, run, show, … |
cpueval run --suite <TAB> |
audio, chat-smoke, concurrent-load, … |
cpueval run --suite ch<TAB> |
chat-smoke |
cpueval run --model <TAB> |
model names discovered from your results directories |
cpueval run --models t<TAB> |
tiny (preset) + any discovered models starting with t |
cpueval run --models Red<TAB> |
RedHatAI/… models |
cpueval run --profile <TAB> |
profile names from automation/cli/profiles/ |
cpueval show <TAB> |
all suite names |
Note:
--modellists models you have already benchmarked (results directory must exist).--modelsalso includes preset names (all,tiny,llama,qwen,granite, …).
Show the completion script without installing (useful for custom setups):
./cpueval --show-completion
PATH requirement: Completion is registered for both cpueval and ./cpueval,
so tab-complete works from the repo launcher after a shell restart. If you invoke
the command as cpueval (no ./), it still needs to be on your PATH — add the
repo root:
# Add to ~/.zshrc or ~/.bashrc
export PATH="$PATH:/path/to/vllm-cpu-perf-eval"
Environment Setup¶
Managed mode (default - vLLM on DUT, tests from load generator):
export DUT_HOSTNAME=<dut-host>
export LOADGEN_HOSTNAME=<loadgen-host>
export HF_TOKEN=<token> # for gated models
# Optional
export ANSIBLE_SSH_USER=<user>
export ANSIBLE_SSH_KEY=<path-to-key>
External endpoint mode (test existing vLLM server or load balancer):
export VLLM_ENDPOINT_MODE=external
export VLLM_ENDPOINT_URL=http://your-vllm-host:8000
Or pass the URL per run with --endpoint-url (sets both variables automatically):
./cpueval --suite concurrent-load \
--models tiny --cores 8 --workloads chat \
--endpoint-url http://your-vllm-host:8080
Scale-out workflow (nginx load balancer)¶
Use this when multiple vLLM instances sit behind a load balancer (for example after
start-vllm-scaleout.yml from the scale-out playbooks). cpueval does not deploy the
stack today — point benchmarks at the LB URL instead of a single managed instance.
# 1. Deploy scale-out on the DUT (Ansible; see docs/vllm-scaleout.md when merged)
ansible-playbook -i inventory/hosts.yml start-vllm-scaleout.yml \
-e "scaleout_num_instances=3 scaleout_cores_per_instance=16"
# 2. Benchmark through the load balancer (port 8080 by default)
./cpueval --suite concurrent-load \
--models tiny \
--cores 32 \
--workloads chat \
--endpoint-url http://<DUT_HOSTNAME>:8080 \
--skip-doctor
# 3. Narrow matrix while validating a new instance count
./cpueval --suite concurrent-load \
--models TinyLlama/TinyLlama-1.1B-Chat-v1.0 \
--cores 8 \
--workload chat \
--endpoint-url http://<DUT_HOSTNAME>:8080 \
--extra guidellm_profile=synchronous \
--extra guidellm_max_seconds=120 \
--skip-doctor
# 4. Tear down when done
ansible-playbook -i inventory/hosts.yml stop-vllm-scaleout.yml
In external mode, --cores, --vllm-cpus, --vllm-cpu-start, and --profile pinning
are ignored (the endpoint manages its own CPUs). GuideLLM still runs on the load
generator with normal inventory settings.
Note:
--vllm-cpu-startis deprecated. Use--vllm-cpus RANGEinstead to specify an explicit CPU set (e.g.,--vllm-cpus 64-95). The legacy option still works but will emit a deprecation warning.
Commands¶
list - Show available suites¶
./cpueval list
Example output:
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
┃ Name ┃ Type ┃ Runner ┃ Description ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
│ rhaiis-sweep │ Matrix │ script │ RHAIIS model │
│ │ │ │ concurrent load │
│ embedding │ Matrix │ script │ Embedding model │
│ │ │ │ performance │
│ offline-batch │ Matrix │ script │ Offline batch │
│ │ │ │ processing │
│ audio │ Matrix │ script │ Audio model │
│ │ │ │ benchmarking │
│ concurrent-load │ Matrix │ script │ LLM concurrent load │
│ chat-smoke │ Single │ ansible │ Quick LLM chat test │
│ health │ Single │ ansible │ Health check │
└───────────────────────────┴──────────────┴────────────┴──────────────────────┘
Legend: Matrix = full test matrix by default, Single = requires --model
show - Suite details¶
./cpueval show <suite-name>
# Examples
./cpueval show rhaiis-sweep
./cpueval show embedding
Example output (./cpueval show rhaiis-sweep):
Suite: rhaiis-sweep
Description: RHAIIS model concurrent load sweep - full test matrix by default
Runner: script
Type: Matrix suite (runs full test matrix by default)
Default Parameters:
models: all
cores: 8,16,32
workloads: chat,code,summarization,rag
phase: 1
Parameter Mappings:
--models → --models
--cores → --cores
--workloads → --workloads
--workload → --workloads
Suite definition: .../automation/cli/src/cpueval/suites/rhaiis-sweep.yaml
Edit that file to change permanent defaults.
Tip: The suite YAML path is printed at the bottom of every
showoutput. Edit it to permanently change defaults; use CLI flags (e.g.--cores) to override for a single run.
install - Install prerequisites¶
Automates the dependency setup steps required before running benchmarks.
# Full install: system packages + Ansible collections + shell completion
./cpueval install
# Skip system packages (already installed)
./cpueval install --skip-system-deps
# Skip Ansible collection install
./cpueval install --skip-collections
# Skip tab-completion setup
./cpueval install --skip-completion
# Preview commands without executing
./cpueval install --dry-run
Example output:
cpueval install
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Step ┃ Status ┃ Details ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ System packages │ ✓ │ dnf: python3-pip, git; pip: ansible-core>=2.14 │
│ Ansible collections │ ✓ │ collections installed │
│ Shell completion │ ✓ │ bash completion at ~/.bash_completions/… │
└──────────────────────────────┴────────────┴──────────────────────────────────────────────┘
✓ Install complete
Next step: verify with cpueval doctor
Enable tab completion in this shell with exec bash or exec zsh, then try ./cpueval <TAB>
What it installs:
| Step | Tool | Notes |
|---|---|---|
| System packages | python3-pip, git, ansible-core |
dnf on RHEL/Fedora; UBI 9 has no ansible-core RPM so install falls back to pip in the cpueval venv |
| Ansible collections | containers.podman, ansible.posix |
From automation/test-execution/ansible/requirements.yml |
| Shell completion | bash/zsh tab completion | Registers cpueval and ./cpueval; restart the shell once (exec bash / exec zsh) |
On macOS/Ubuntu, git/pip are left to the OS; ansible-core is installed into
the venv with pip. If pip cannot install Ansible, the step fails with a brew /
apt one-liner — install Ansible manually, then re-run
./cpueval install --skip-system-deps to install the collections.
After installing, restart the shell (exec bash or exec zsh) so ./cpueval <TAB>
works, then verify with ./cpueval doctor. Use --skip-completion to leave
tab-completion alone; ./cpueval --install-completion still works as a standalone
reinstall.
doctor - Health checks¶
# Full check (including host ping)
./cpueval doctor
# Skip ping (faster, good for CI)
./cpueval doctor --no-ping
Example output:
cpueval system health check
┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Check ┃ Status ┃ Details ┃
┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ ansible-playbook │ ✓ │ unknown │
│ Ansible collections │ ✗ │ containers.podman collection not found │
│ Inventory file │ ✓ │ .../ansible/inventory/hosts.yml │
│ Environment vars │ ✗ │ Missing: DUT_HOSTNAME, LOADGEN_HOSTNAME│
└──────────────────────┴──────────────┴────────────────────────────────────────┘
✗ Some checks failed
Tip: Missing Ansible or collections? Run:
./cpueval install
Verifies: - ansible-playbook available - Ansible collections installed (containers.podman) - Inventory file exists - Required environment variables set - Host connectivity (unless --no-ping)
Execute benchmarks¶
cpueval run --suite …is also accepted for backward compatibility.
Common options:
- --suite/-s (required); Suite name
- --model/-m; Model ID (overrides suite default)
- --cores/-c; CPU core count
- --workload/-w; Workload type
- --scenario; Test scenario (audio suites)
- --dry-run; Print command without running
- --skip-doctor; Skip health checks
LLM Examples:
# Quick chat smoke test
./cpueval --suite chat-smoke \
--model meta-llama/Llama-3.2-1B-Instruct \
--cores 16 \
--workload chat
# Concurrent load sweep (narrowed to single model/workload)
./cpueval --suite concurrent-load \
--model meta-llama/Llama-3.2-1B-Instruct \
--cores 32 \
--workload summarization
# Dry run to see command
./cpueval --suite concurrent-load \
--model TinyLlama/TinyLlama-1.1B-Chat-v1.0 \
--cores 16 \
--dry-run
--dry-run prints the underlying command without executing (ansible-playbook for ansible suites, bash script for script suites):
ansible-playbook -i .../inventory/hosts.yml .../llm-benchmark-auto.yml \
-e workload_type=chat \
-e test_model=TinyLlama/TinyLlama-1.1B-Chat-v1.0 \
-e requested_cores=16
Audio Examples:
# Transcription throughput test (single model)
./cpueval --suite audio \
--models openai/whisper-small \
--scenario transcription-throughput \
--cores 32
# Quick audio test (single model)
./cpueval --suite audio \
--models openai/whisper-tiny \
--scenario quick-test \
--cores 16
Embedding Example:
./cpueval --suite embedding \
--model RedHatAI/granite-embedding-english-r2 \
--cores 16
Offline Batch Example:
# Default: all 11 use cases, 3 runs each
./cpueval --suite offline-batch
# All use cases, all RedHatAI models, 5 runs each
./cpueval --suite offline-batch --mode use-cases --runs 5 --models all
# Single use case with core sweep
./cpueval --suite offline-batch \
--mode use-case-sweep \
--use-case summarization \
--models all \
--cores 8,16,24,32 \
--runs 3
# Fast smoke test (minimal tokens)
./cpueval --suite offline-batch \
--mode run_test \
--model RedHatAI/TinyLlama-1.1B-Chat-v1.0-pruned2.4 \
--dataset random \
--num-prompts 3 \
--cores 8 \
--input-len 32 \
--output-len 16
# Technical benchmarks
./cpueval --suite offline-batch --mode batch-scaling --model <model> --cores 16
# RHAIIS container image
export VLLM_CONTAINER_IMAGE=registry.redhat.io/rhaii/vllm-cpu-rhel9:3.4.0
./cpueval --suite offline-batch --mode use-cases --runs 3 --models all
Offline-batch flags: --mode, --runs, --use-case, --models/--model,
--cores, --dataset, --num-prompts, --input-len, --output-len.
Escape hatch: --extra args="...".
Core Sweep (Multiple Core Counts):
# Test with multiple core counts in one run
./cpueval --suite concurrent-load \
--model TinyLlama/TinyLlama-1.1B-Chat-v1.0 \
--extra core_sweep_counts="[8,16,32,64]" \
--workload chat
# Single core count (use --cores for clarity)
./cpueval --suite concurrent-load \
--model TinyLlama/TinyLlama-1.1B-Chat-v1.0 \
--cores 16 \
--workload chat
RHAIIS Quantized Models:
# RHAIIS models work with standard concurrent-load suite
export VLLM_CONTAINER_IMAGE=registry.redhat.io/rhaii/vllm-cpu-rhel9:3.4.0
./cpueval --suite concurrent-load \
--model RedHatAI/Meta-Llama-3.1-8B-Instruct-quantized.w4a16 \
--cores 16 \
--workload chat
# Core sweep with RHAIIS
./cpueval --suite concurrent-load \
--model RedHatAI/Meta-Llama-3.1-8B-Instruct-quantized.w4a16 \
--extra core_sweep_counts="[8,16,32]" \
--workload chat
CPU Pinning¶
Simple pinning via CLI flags:
./cpueval --suite concurrent-load \
--model meta-llama/Llama-3.2-1B-Instruct \
--cores 32 \
--vllm-cpu-start 64 \
--vllm-numa 1 \
--guidellm-cpus 0-31 \
--guidellm-numa 0
Using a profile:
Pass the profile name (without .yaml) — cpueval looks it up in
automation/cli/profiles/. You can also pass a relative or absolute path to a
file anywhere on disk.
# Built-in profile (resolved from automation/cli/profiles/)
./cpueval --suite concurrent-load \
--model meta-llama/Llama-3.2-1B-Instruct \
--cores 32 \
--profile dual-socket-split
# Custom profile by path
./cpueval --suite concurrent-load \
--model meta-llama/Llama-3.2-1B-Instruct \
--cores 32 \
--profile ~/my-profiles/my-server.yaml
Built-in profiles:
| Profile | Use case |
|---|---|
dual-socket-split |
Dual-socket system — vLLM pinned to socket 1 (cores 64–95, NUMA 1), GuideLLM pinned to socket 0 (cores 0–31, NUMA 0) |
vllm_cpusvs--cores: When a profile (or--vllm-cpus) setsvllm_cpus, it specifies a fixed CPU set for vLLM regardless of--cores. For example,--profile dual-socket-split --cores 8pins vLLM to all 32 cores in64-95, not 8 cores starting at 64. Usevllm_cpuswhen you want an explicit range; use--coresalone when you want count-based auto-allocation. The two modes are mutually exclusive:vllm_cpusalways wins.
To list profiles available:
./cpueval profiles
Advanced: extra vars:
./cpueval --suite concurrent-load \
--model meta-llama/Llama-3.2-1B-Instruct \
--cores 32 \
--extra vllm_cpu_start=64 \
--extra vllm_numa_node=1
# Or from a file (path relative to your current working directory, or absolute)
./cpueval --suite concurrent-load \
--model meta-llama/Llama-3.2-1B-Instruct \
--cores 32 \
--extra-vars-file my-config.yaml # relative to CWD
# --extra-vars-file /path/to/my-config.yaml # or absolute
Precedence: suite defaults → profile → CLI flags → --extra → --extra-vars-file
profiles - List CPU pinning profiles¶
./cpueval profiles
Lists all profiles available in automation/cli/profiles/, showing their name and
file path. Use the name with --profile when running a suite.
Example output:
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Name ┃ Path ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ dual-socket-split │ .../automation/cli/profiles/dual-socket-split... │
└───────────────────────────┴──────────────────────────────────────────────────┘
results - View benchmark results¶
# Show last run
./cpueval results --last
# Show specific result
./cpueval results results/llm/TinyLlama__TinyLlama-1.1B-Chat-v1.0/chat-20260623-154515/8cores-single-socket
# List recent results
./cpueval results --list
./cpueval results --list --limit 20
# Open dashboard
./cpueval results --open
# Convert results
./cpueval results --convert
Example output (./cpueval results --last):
Results: results/llm/Qwen__Qwen2.5-0.5B-Instruct/chat-20260729-165311/32cores-numa2-tp1
┌───────────┬────────────────────────────┐
│ Model │ Qwen/Qwen2.5-0.5B-Instruct │
│ Workload │ chat │
│ Timestamp │ 2026-07-29T17:26:30+01:00 │
│ Cores │ 32 │
└───────────┴────────────────────────────┘
┏━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Concurrency ┃ Req/s ┃ Tok/s ┃ TTFT (ms) ┃ TPOT (ms) ┃ Requests ┃
┡━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━┩
│ 1 │ 0.10 │ 106.37 │ 53.48 │ 19.34 │ 26/26 │
│ 8 │ 0.67 │ 710.55 │ 142.20 │ 23.14 │ 168/168 │
│ 32 │ 1.47 │ 1585.99 │ 199.50 │ 41.36 │ 384/384 │
└─────────────┴───────┴─────────┴───────────┴───────────┴──────────┘
Example output (./cpueval results --list):
Recent results (10)
Qwen__Qwen2.5-0.5B-Instruct/chat-20260729-165311/32cores-numa2-tp1
Qwen__Qwen2.5-0.5B-Instruct/summarization-20260729-165210/32cores-numa0-tp1
Qwen__Qwen2.5-0.5B-Instruct/chat-20260729-161939/16cores-numa2-tp1
...
Results display includes: - Model, workload, timestamp, cores - All concurrency points (not just first) - Requests/sec, Tokens/sec, TTFT (ms), TPOT (ms) - Request success/total counts
dashboard - Manage Streamlit dashboard¶
# Start dashboard in background (port 8501)
./cpueval dashboard start
# Stop running dashboard
./cpueval dashboard stop
Launches the interactive results dashboard in your browser. You can also open it
via ./cpueval results --open.
Available Suites¶
Matrix Suites (run full test matrix by default)¶
| Suite | Default Matrix | Description |
|---|---|---|
rhaiis-sweep |
5 models × 3 cores × 4 workloads | RHAIIS model concurrent load sweep (60 tests) |
concurrent-load |
all models × 3 cores × 4 workloads (60 tests) | Upstream LLM concurrent load sweep |
embedding |
5 models × 3 cores × 2 scenarios | Embedding model performance matrix (30 tests) |
offline-batch |
11 use-cases × 3 runs | Offline batch processing suite (33 tests) |
audio |
all models × transcription-throughput × 32 cores |
Audio model benchmarking (Whisper ASR) |
Single-Shot Suites (require --model)¶
| Suite | Description |
|---|---|
chat-smoke |
Quick auto-configured LLM chat test |
setup-platform |
Platform setup and configuration |
health |
Health check for DUT and load generator |
Audio Test Scenarios¶
Available scenarios for the audio suite (--scenario flag):
transcription-throughput- High-throughput ASRtranscription-latency- Low-latency ASRtranscription-quality- Quality-focused ASRaudio-duration-scaling- Variable audio lengthsformat-comparison- Audio format comparisonconstant-rate-stress- Stress testingquick-test- Fast smoke test
Testing custom models¶
Every suite accepts an arbitrary HuggingFace model ID — no changes to any YAML files are needed.
LLM suites (concurrent-load, rhaiis-sweep, chat-smoke, offline-batch)¶
Pass any HuggingFace model ID directly:
# Single-shot test
./cpueval --suite chat-smoke \
--model my-org/my-llm-model \
--cores 32 \
--workload chat
# Concurrent load against a custom model
./cpueval --suite concurrent-load \
--model my-org/my-llm-model \
--cores 16 \
--workload chat
# Offline batch — use-cases mode (comma-separated list also works)
./cpueval --suite offline-batch \
--mode use-cases \
--models my-org/my-llm-model \
--runs 3
# Offline batch — single benchmark mode
./cpueval --suite offline-batch \
--mode batch-scaling \
--model my-org/my-llm-model \
--cores 32
Gated models: set
export HF_TOKEN=hf_xxxxxbefore running.
Audio suite¶
Whisper is the default but any vLLM-compatible audio model works. Non-Whisper models
typically need a larger max_model_len (Whisper's encoder cap is 448 tokens) and
may require an explicit dtype:
# Whisper model — defaults work, no overrides needed
./cpueval --suite audio \
--models openai/whisper-small \
--scenario transcription-throughput \
--cores 32
# Non-Whisper audio model — override max_model_len and dtype
./cpueval --suite audio \
--models fixie-ai/ultravox-v0_5-llama-3_2-1b \
--extra dtype=bfloat16 \
--extra max_model_len=2048 \
--scenario transcription-throughput \
--cores 32
| Extra var | Bash flag | When to use |
|---|---|---|
dtype=float16\|bfloat16\|auto |
--dtype |
Non-Whisper models that recommend a specific dtype |
max_model_len=N |
--max-model-len |
Any model whose max sequence length differs from Whisper's 448 |
Embedding suite¶
./cpueval --suite embedding \
--model my-org/my-embedding-model \
--cores 16
Optional: register the model for KV cache metadata¶
Running with a custom model ID works immediately. To also get accurate KV cache
sizing (rather than the 40 GiB fallback) and include the model in future
--models all sweeps, add an entry to the relevant model matrix:
- LLM models: models/llm-models/model-matrix.yaml
- Embedding models: models/embedding-models/model-matrix.yaml
- Audio models: models/audio-models/model-matrix.yaml
See models/models.md for the full schema and instructions.
Creating Custom Suites¶
You can also edit an existing suite YAML directly to change its permanent defaults (e.g. to add a new core count or workload to the default matrix) rather than creating a new suite from scratch.
Create a YAML file in automation/cli/src/cpueval/suites/:
name: my-suite
description: My custom suite
runner: ansible # or 'script'
target: my-playbook.yml
defaults:
test_model: my-model
requested_cores: 16
param_mappings:
model: test_model
cores: requested_cores
workload: workload_type
Creating CPU Pinning Profiles¶
Create a YAML file in automation/cli/profiles/:
# profiles/my-profile.yaml
vllm_cpu_start: 64
vllm_numa_node: 1
guidellm_cpus: "0-31"
guidellm_numa_node: 0
Use it:
./cpueval --suite concurrent-load --model my-model --cores 32 --profile my-profile
Architecture¶
cpueval is a thin wrapper that:
- Generates ansible-playbook commands from suite definitions;
- Streams stdout/stderr (no log hiding);
- Does NOT reimplement deploy/GuideLLM/vLLM logic;
- Provides progressive disclosure for CPU pinning.
Design principles:
- Thin wrapper only (subprocess invocation, not Python reimplementation);
- Suites are YAML data, not hard-coded;
- Env-based inventory;
- Progressive disclosure (simple --cores, advanced pinning optional).
Troubleshooting¶
Health check failures:
# Check what's failing
./cpueval doctor
# Missing Ansible or collections
./cpueval install
# Common fixes
export DUT_HOSTNAME=my-dut
export LOADGEN_HOSTNAME=my-loadgen
export HF_TOKEN=hf_xxxxx
# Test connectivity
ansible -i automation/test-execution/ansible/inventory/hosts.yml all -m ping
No results found:
# List results to find the right path
./cpueval results --list
# Check results directories
ls -la results/llm/
ls -la results/audio-models/
Module import errors:
# Recreate venv
rm -rf automation/cli/.venv
./cpueval list # Will recreate venv
Development¶
cd automation/cli
# Install in dev mode with test dependencies
pip install -e ".[dev]"
# Run tests
python -m pytest tests/ -v
# Run specific test
python -m pytest tests/test_results.py::test_extract_metrics_guidellm_v06 -v
See Also¶
- Test Suites Overview - All supported suites and how to choose
- Getting Started Guide - Overall framework setup
- Ansible Test Execution - Underlying playbooks
- Dashboards Quickstart - Results visualization
- Terminal Results Viewer - Alternative results viewer