MCPInstall

benchmark-vllm-model

Benchmark throughput and cost-per-token of a model served on vLLM in Chalk's container infrastructure. Use when someone asks for $/token, $/request, tokens/sec, "how much would it cost to self-host this model", GPU sizing for an LLM, or wants to compare a self-hosted model's economics against a hosted API.

Installs
920
Last 24h
+54
Trending rank
#3184
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/chalk-ai/chalk-ai-plugins --skill benchmark-vllm-model
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads benchmark-vllm-model automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

Benchmark $/token for a model on vLLM in Chalk

Produces a defensible cost-per-token number: serve the model on a GPU, drive it to saturation, confirm the GPU is actually the limiter, then divide authoritative cloud pricing by measured throughput.

The order matters. A throughput number without a saturation check is unfalsifiable, and a $/hr figure pulled from a blog post is usually wrong (see step 5).

1. Serve the model

chalk container run --dir <chalk-project> --json --no-spinners \
  -i vllm/vllm-openai:latest -n bench-server \
  --gpu nvidia-l4:1 --cpu 4 --memory 16Gi --port 8000 --lifetime 2h \
  --env "HF_TOKEN=$HF_TOKEN" --env HF_HOME=/root/.cache/huggingface \
  --await-running --await-timeout 20m \
  -e vllm -- serve <MODEL> --port 8000 \
  --dtype bfloat16 --max-model-len 16384 --gpu-memory-utilization 0.90

chalk container get --name bench-server returns webUrl (publicly reachable) and podName. Poll GET $webUrl/health — it returns 503 until weights are loaded, then 200. Expect several minutes for a 7B download.

GPU selection. Only GPU pools labelled chalk.ai/workload-type=compute can run container/sandbox workloads. On the staging cluster that is l4-gpus (L4, 24GB, native bf16), capped at 2 nodes x 1 GPU. A pool that lacks the label (e.g. t4-gpus) will leave the pod Unschedulable and the controller gives up after 300s — shorter than a cold GPU node autoscale, so a valid request can fail purely on capacity. Free a GPU and retry.

Turing (T4) has no native bf16; use --dtype float16 there.

2. Serving flags that change the answer

Benchmark the config you intend to run, and say which flags you set. These materially move the result:

FlagWhy it matters
--max-num-seqsCaps concurrent sequences. Too high wastes scheduler time on short requests — throughput can fall as you raise it. Sweep it.
--max-num-batched-tokensPrefill chunk budget. The binding constraint for prompt-heavy / short-output workloads.
--enable-prefix-cachingOn by default in vLLM V1. Inflates apparent prompt throughput (see pitfalls).
--limit-mm-per-prompt '{"image":1}'Multimodal models profile peak activation memory against worst-case images per prompt, stealing KV cache. Pin it.
--dtypebf16 on Ada/Hopper; fp16 on Turing.
--enforce-eagerSkips CUDA graph capture: faster startup, slower decode. Fine for 1-token outputs, wrong for general serving. Don't leave it on in a benchmark you intend to generalize.
--api-keyThe container webUrl is publicly resolvable. An unauthenticated LLM endpoint is exposed. Pair with chalk container run --authenticated.

3. Drive load

Use scripts/bench.py (bundled with this skill). It sweeps prompt length and concurrency, and reads throughput from vLLM's own Prometheus counters (vllm:prompt_tokens_total, vllm:generation_tokens_total, vllm:request_success_total) across a steady-state window.

./scripts/bench.py --base-url "$URL" --model "$MODEL" \
  --input-lens 128,512 --concurrency 8,32,64 --duration 30

Methodology rules, each of which fixes a real failure mode:

  • Sustained windows, not fixed request counts. Sub-10s windows are dominated by jitter. Use >=20s and a warm ramp before the measured window.
  • Server-side counters, not client timing. Removes client overhead and WAN latency from the measurement.
  • Sweep concurrency until throughput stops rising. One concurrency level tells you nothing about where saturation is.
  • Unique prompt prefixes. Identical prompts hit the prefix cache and inflate results (bundled script seeds each request).
  • Watch for client-side bottlenecks. If throughput drops at high concurrency, suspect the load generator's CPU before the server. Re-run from a bigger box, or from inside the cluster.

Where to run the driver. From a laptop is fine to start. To rule out the network path, run it as a container inside the cluster (--cpu 6, the vLLM image already has Python + httpx) and point it at the server's pod IP (kubectl get pod <podName> -o jsonpath='{.status.podIP}'), then repeat against the public webUrl. If the two agree, the ingress is not your bottleneck — measure this rather than assuming it.

4. Confirm the GPU is the limiter

A throughput number is only a hardware number if the hardware was saturated. Check DCGM on the node running the model:

NODE=$(kubectl -n ns-<env> get pod <podName> -o jsonpath='{.spec.nodeName}')
DCGM=$(kubectl -n chalk-telemetry get pods -o wide | grep "dcgm.*$NODE" | awk '{print $1}')
kubectl -n chalk-telemetry port-forward "$DCGM" 19400:9400 &
curl -s localhost:19400/metrics | grep -E '^DCGM_FI_DEV_(GPU_UTIL|POWER_USAGE|FB_USED)'

Sample it during the run. GPU_UTIL at 100 and POWER_USAGE at the card's TDP (72W for L4, 300W for A100 40GB) means you are GPU-bound and the number is real. Utilization well under 100% means you measured your client, the network, or a scheduler cap — not the GPU. Note the exporter scrapes on an interval, so identical consecutive samples are expected.

5. Get the real $/hr

Do not trust third-party pricing pages or a web search summary. For GPU machine families the accelerator is often a separate SKU from vCPU and RAM, and aggregator sites frequently omit it — which understates the node by 3x.

Query GCP's Cloud Billing Catalog directly (Compute Engine service 6F81-5844-456A), summing the SKUs that make up the node:

# paginate skus?pageSize=5000&currencyCode=USD with an Authorization: Bearer token
# from `gcloud auth print-access-token`, filter serviceRegions for your region,
# then match description against your machine family and accelerator.

Worked example, g2-standard-8 (8 vCPU, 32 GiB, 1x L4) in us-central1:

SKURateQtySubtotal
G2 Instance Core running in Americas$0.024988 /hr8$0.199904
G2 Instance Ram running in Americas$0.002927 /GiB-hr32$0.093664
Nvidia L4 GPU running in Americas$0.560040 /hr1$0.560040
$0.853608 /hr

Omitting the GPU SKU yields $0.2936/hr — a number that appears on public pricing aggregators and is wrong. Sanity-check by computing spot the same way and confirming it lands at the expected discount.

Also pull Spot and 1yr/3yr CUD rates; they are separate SKUs and are what a production deployment would actually pay.

6. Compute the cost

$/sec        = node_hourly / 3600
$/1M in-tok  = $/sec / prompt_tok_per_s * 1e6
$/1M req     = $/sec / rps * 1e6

Report $/1M input tokens and $/1M requests, plus the on-demand / spot / CUD variants.

Pick the right unit. For a classifier or guardrail that emits a single token, output tokens are identical to requests and "$/output token" is a degenerate metric — lead with $/classification. For a chat or coding model, decode dominates and $/output token is the meaningful figure; set --output-tokens to a realistic completion length rather than 1.

Pitfalls

  • Prefix caching inflates $/input-token. A shared system prompt gets cached, so prompt_tokens_total counts tokens that were never recomputed. The bundled script reports the hit rate. It is a fair comparison against a vendor who bills you for every input token, but it is not your real compute headroom — say which one you are quoting.
  • Saturation numbers are a floor, not a forecast. These are 100%-duty-cycle figures. At 20% real utilization, multiply by 5. Idle GPU time is the dominant cost in most production deployments.
  • Tool-calling models need the right parser and the right checkpoint. --enable-auto-tool-choice --tool-call-parser hermes plus an instruct model. Some Coder-tuned checkpoints emit tool calls as fenced JSON text that the parser ignores, so tool_calls returns null under tool_choice: auto while tool_choice: required works (guided decoding forces the shape).
  • Completed container pods are garbage-collected, taking their logs. End a one-shot driver script with sleep so you can still kubectl logs it.
  • chalk container exec is unimplemented for k8s containers (only implemented for host containers). Drive work via the entrypoint, or use --compute-class host / the sandbox API.
  • Piping a script into bash breaks silently if it invokes anything that reads stdin — the child eats the rest of the script. Write it to a file and add exec </dev/null.
  • Sandboxes have no network egress and no flag to grant it; even public IPs are blocked. Use chalk container run --route <CIDR> when the workload must reach anything.

Reporting

State the model, GPU, every non-default serving flag, the measured throughput, the DCGM saturation evidence, and the SKU breakdown behind the $/hr. A cost-per-token figure without those is not reproducible and should not be quoted.

FAQ

What does the benchmark-vllm-model skill do?

Benchmark throughput and cost-per-token of a model served on vLLM in Chalk's container infrastructure. Use when someone asks for $/token, $/request, tokens/sec, "how much would it cost to self-host this model", GPU sizing for an LLM, or wants to compare a self-hosted model's economics against a hosted API.

How do I install benchmark-vllm-model?

Run npx skills add https://github.com/chalk-ai/chalk-ai-plugins --skill benchmark-vllm-model in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/benchmark-vllm-model/ (personal) or .claude/skills/benchmark-vllm-model/ (project).

Which AI agents can use benchmark-vllm-model?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is benchmark-vllm-model safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains benchmark-vllm-model?

It is published by chalk-ai in chalk-ai/chalk-ai-plugins. It has 920 recorded installs.

More from chalk-ai/chalk-ai-plugins

View all →

accelerate-python-resolvers

chalk-ai/chalk-ai-plugins

Make Chalk Python resolvers statically accelerable. Use when the user asks to accelerate resolvers, fix static-acceleration diagnostics, check why a resolver "can't be accelerated", or speed up Python feature pipelines in a Chalk project (a repo with chalk.yaml/chalk.yml).

921 installs

debug-plan-cache-misses

chalk-ai/chalk-ai-plugins

Find and debug Chalk query plan cache misses from engine logs. Use when a query is replanning on every request, an "ad-hoc query request missed the plan cache" warning shows up, latency spikes from repeated planning, or someone asks why two seemingly identical queries don't share a cached plan. Drives the chalk logs CLI search.

deploy-chalk-function

chalk-ai/chalk-ai-plugins

How to deploy a chalk function ("chalkcompute.function"). Useful for deploying a stand-alone python function in Chalk's container infrastructure. Use when someone wants to run a python function remotely on Chalk, deploy a chalkcompute function, or asks about the chalkcompute SDK.

DevOps & Cloud918 installs

chalk-hello

chalk-ai/chalk-ai-plugins

Print a friendly greeting from the Chalk plugin marketplace, used to verify plugin installation.

918 installs

Popular backend & apis skills

View category →

find-skills

vercel-labs/skills

Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.

OfficialBackend & APIs4.1M installs

entra-app-registration

microsoft/azure-skills

Guides Microsoft Entra ID app registration, OAuth 2.0 authentication, and MSAL integration. USE FOR: create app registration, register Azure AD app, configure OAuth, set up authentication, add API permissions, generate service principal, MSAL example, console app auth, Entra ID setup, Azure AD authentication. DO NOT USE FOR: Key Vault secrets (use azure-keyvault-expiration-audit), general Azure resource security guidance.

OfficialBackend & APIs566.7K installs

This skill should be used when the user wants to "write agent code", "build an agent with ADK", "add a tool", "create a callback", "define an agent", "use state management" — in a project that needs ADK (Agent Development Kit) API patterns and code examples. It provides a quick reference for agent types, tool definitions, orchestration patterns, callbacks, state management, the graph Workflow API, and reference recipes to study. Do NOT use for scaffolding (use google-agents-cli-scaffold) or deployment (use google-agents-cli-deploy).

Backend & APIs514.8K installs

embedded-captions

heygen-com/hyperframes

Add captions or subtitles to an existing single-subject talking-head video without editing the footage. Use for plain verbatim captions, cinematic captions embedded behind the subject, VFX captions, “炸/特效/酷炫字幕,” or a named identity from the 35-style catalog. Route by visual identity, not by backend engine. The quiet anchor rail is the default; embed every word only when the user explicitly wants a fully cinematic treatment. The workflow runs locally end to end, including transcription and subject matting; split multi-shot footage before applying it.

Backend & APIs453.3K installs

entra-agent-id

microsoft/azure-skills

Provision Microsoft Entra Agent Identity Blueprints, BlueprintPrincipals, and per-instance Agent Identities via Microsoft Graph, and configure OAuth 2.0 token exchange (fmipath, OBO, cross-tenant) including the Microsoft Entra SDK for AgentID sidecar. USE FOR: Agent Identity Blueprint, BlueprintPrincipal, agent OAuth, fmipath token exchange, agent OBO, Workload Identity Federation for agents, polyglot agent auth, Microsoft.Identity.Web.AgentIdentities. DO NOT USE FOR: standard Entra app registration (use entra-app-registration), Microsoft Foundry agent authoring (use microsoft-foundry).

OfficialBackend & APIs336.6K installs

neon

neondatabase/agent-skills

Overview of Neon, a complete set of cloud backend primitives around Lakebase Postgres: Auth, Object Storage, Functions, the AI Gateway, and Realtime. Start here to choose Neon for undecided login, files, APIs, and LLM calls, set up the CLI or MCP server, and follow the branch-first workflow. Use when building an app or backend on Neon, or when "Neon" or "Lakebase Postgres" is mentioned. Child skill neon-postgres wins for an existing DATABASEURL, SQL, schema, inspect, or search. Child skill neon-auth wins for login, users, sessions, identity routing, and Managed Better Auth setup. Child skill neon-realtime wins for live queries in reactive apps and agents. Also use for object storage, S3, buckets, serverless functions, function triggers, cron, AI gateway, LLM calls, realtime, logs, Loki, Grafana, observability, postgres, database, backend, Claimable Neon, neon.new, or a no-signup database.

Backend & APIs237.1K installs