Skip to content

[RFC][Frontend/CLI]: Offline prefix-cache workload analyzer #47993

Description

@raravind007

Motivation

vLLM's automatic prefix caching reuses KV-cache blocks only when the computed block-hash chain matches at full-block granularity. The hash includes the parent block hash, the current block tokens, and optional extra keys such as LoRA IDs, multimodal input hashes, and cache salts. As a result, small prompt-formatting differences, per-request metadata, different chat templates, LoRA/multimodal metadata, or cache-salt differences can prevent reuse even when prompts look similar to a human.

Today, users can inspect prefix-cache behavior through runtime logs, Prometheus metrics, and benchmark scripts, but there is no user-facing, no-GPU way to analyze a request dataset before deployment and answer whether its prompt structure is cache-friendly. This makes it difficult to reason about RAG, agent, tool-calling, and multi-turn workloads before spending GPU time on a serving run.

Related user pain: #29944, #12077, #24394, and the forum thread "How log kvcache usage and prefix hit rate in offline infer?".

Proposal

Add an offline prefix-cache analyzer CLI, tentatively:

vllm analyze-prefix-cache \
  --model meta-llama/Meta-Llama-3-8B-Instruct \
  --input requests.jsonl \
  --format openai-chat \
  --block-size 16 \
  --output-format text

Given a JSONL of requests and a model/tokenizer, the analyzer would:

  • Parse OpenAI batch-style requests and/or plain prompt JSONL.
  • Apply the selected chat template and tokenize each request.
  • Compute the same full-block hash-chain structure used by vLLM prefix caching, reusing existing request/block hashing utilities rather than reimplementing hashing logic.
  • Group requests by shared hash-chain prefixes.
  • Report offline cacheability estimates, including:
    • total prompt tokens
    • total full-block tokens
    • estimated reusable full-block tokens
    • estimated cacheability ratio
    • top shared prefix groups
    • request groups that diverge after a common prefix
  • Support both human-readable text output and machine-readable JSON output.

This is static analysis over tokenized requests and existing hashing utilities. It should not instantiate the engine, execute model weights, or require GPU access.

Design question: internal API usage

The hashing logic this proposal depends on (hash_block_tokens, generate_block_hash_extra_keys, get_request_block_hasher) currently lives in vllm/v1/core/kv_cache_utils.py — internal to the engine core. A CLI/frontend module importing directly from v1/core crosses a layering boundary that may not be acceptable as-is. Before implementation, we'd like maintainer input on whether this warrants a small, stable public helper for offline hash-chain construction, versus importing the internal utilities directly for a first version.

Scope for v1

  • CLI command for offline workload analysis.
  • Text output by default.
  • JSON output for automation and CI/capacity-planning workflows.
  • Support for plain prompt JSONL and OpenAI-compatible chat/batch request JSONL.
  • Block-size parameter support, with optional comparison across multiple block sizes.
  • Mechanical divergence reporting: show where hash chains stop matching and which request groups share common full-block prefixes.
  • Documentation with RAG, agent, tool-calling, and multi-turn examples.

Explicit non-goals for v1

  • Exact runtime prefix-cache hit-rate prediction.
  • Modeling scheduler behavior, eviction, memory pressure, request arrival order, preemption, KV offload, or disaggregated serving.
  • Natural-language cause classification such as "this miss was caused by timestamps" or "this miss was caused by per-user IDs."
  • Full multimodal/LoRA/cache-salt inference unless the relevant metadata is present in the input format and can be passed through the same hashing path.
  • Engine behavior changes.

The analyzer should present results as an offline upper-bound or cacheability estimate, not as a guarantee of production hit rate.

Alternatives considered

Existing runtime metrics — Runtime metrics and logs can show prefix-cache behavior after a server or offline inference run, but they do not provide a pre-flight analysis tool for a request corpus.

benchmarks/benchmark_prefix_caching.py — Benchmarks prefix-caching performance by running an actual model with fixed prompts or ShareGPT-style prompts. This proposal is different: it does not run inference, does not require GPU, and analyzes a user's request dataset structurally before deployment.

Hash microbenchmarks — Existing hash benchmarks are useful for comparing hashing throughput and algorithm choices, but they do not estimate cacheability of a real prompt workload.

Open questions

  • Should this be a top-level command such as vllm analyze-prefix-cache, or should it live under an existing CLI family such as vllm bench prefix-cache-analyze?
  • What input formats should v1 support beyond plain prompts and OpenAI-compatible request JSONL?
  • Should JSON output be considered stable in v1, or marked experimental?
  • How much LoRA, multimodal, and cache-salt metadata should v1 support?
  • Should block-size comparison be built into v1, or added later?

Happy to implement this if the design direction is acceptable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions