← Intel articles

Intel / NPU performance

Variable-Length Prompts on an NPU: Designing the Test

How to design a fair experiment for first-token latency on an NPU across prompt lengths: length buckets, padding and chunking strategies, and what to record.

Shubham Anandani··4 min read

Problem

A language model has to read the whole prompt before it can produce a first token. That prefill step grows with prompt length, so time to first token depends on the prompt lengths your users actually send.

Intel community guidance and published research on NPU inference say that the NPU in OpenVINO works with static shapes. A prompt of varying length does not fit that directly, so a deployment has to choose a strategy: pad to a fixed length, process in fixed-size pieces, or keep several compiled shapes. Newer OpenVINO and GenAI releases may add dedicated support, so read the release notes for your version before designing around the limitation.

The friction points are choosing a strategy, defining prompt-length buckets that match real use, and measuring the tail instead of the average.

Options and trade-offs

  • Pad to one fixed length: simple and compatible with static shapes. Short prompts pay for the padding, so it favors uniform prompt lengths.
  • Fixed-size chunks: process the prompt piece by piece with a chunk size you choose. It avoids padding everything to the longest length, at the cost of more steps for long prompts. Check whether your OpenVINO and GenAI versions provide this directly.
  • Several compiled shapes: keep one compiled model per length bucket and route each request by its prompt length. It is predictable but uses more memory and more cache entries.
  • Streaming: returning tokens as they are generated improves perceived latency but does not shorten prefill, so track perceived first-token time and true first-token time separately.
  • Measurement unit: use prompt-length buckets such as short, medium, long, and very long, defined in tokens. An average across all prompts hides the long-prompt tail that users notice.
  • Recommendation: begin with your real prompt-length distribution; if you have none, make a reasoned guess, label it as a guess, and plan to replace it. Test each strategy your stack supports against every bucket, changing one thing at a time. Adopt a strategy only if it improves the 95th percentile for the buckets that matter, and keep the simpler setup if it does not.
  • Decision lens: user-visible first-token latency versus implementation complexity. Example setup: an assistant whose prompts are mostly short uses a small fixed length, with a separate path for the rare long prompt.

Minimal working example

Prereqs

  • An NPU machine with a language-model stack that runs on the NPU for your OpenVINO version, set up as that version's documentation describes.
  • Python 3 with transformers for the tokenizer.
  • Your model's tokenizer.

make_prompts.py (build prompts of controlled token length)

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("your-model-name")  # use your model's tokenizer
filler = "The quick brown fox jumps over the lazy dog. " * 2000
ids = tokenizer(filler)["input_ids"]

buckets = {"short": 64, "medium": 512, "long": 2048}
for name, n in buckets.items():
    prompt = tokenizer.decode(ids[:n])
    print(name, len(tokenizer(prompt)["input_ids"]))

Use the prompts with whichever generation API your stack provides, and record the time from sending the request to the first generated token.

Adjust file names, model names, and paths to your own setup.

Test: Build prompts for each bucket with make_prompts.py. For each strategy your stack supports, warm up, then send at least thirty requests per bucket and record time to first token. Report the median and 95th percentile per bucket, with streaming on and off. Keep every other setting the same between runs.

Record: NPU, driver, OpenVINO, and GenAI versions; model and precision; bucket definitions in tokens; time to first token per bucket and strategy as median and 95th percentile; streaming on versus off; your chosen strategy and the reason.

Checklist

  • Read the release notes for your version about NPU and variable prompts.
  • Define buckets from real or clearly labeled estimated lengths.
  • Warm up before measuring and change one setting per run.
  • Report median and 95th percentile per bucket.
  • Track perceived and true first-token time separately, and keep the simpler strategy when a change does not help.
  • Avoid: averaging across prompt lengths.
  • Avoid: assuming a feature from release notes exists in your installed version.

Where this doesn't apply

Pipelines where all prompts have almost the same length, deployments on CPU or GPU, and versions that provide native handling of variable prompts (follow that documentation instead).

Sources

---