Performance Optimization#

Furiosa-LLM provides settings to improve throughput and latency by tuning request admission, decode batching, token sampling, and KV cache reuse. Choose optimizations based on your workload and compare throughput, time to first token (TTFT), and time per output token (TPOT) under representative load.

Limiting the Context Length#

Setting a context limit that matches your workload can increase concurrency and throughput, especially for requests without an explicit output-token limit.

By default the server accepts requests up to the smallest of the model’s max_position_embeddings, the context length covered by the loaded FXB, and what the KV cache can hold. --max-model-len lowers that limit:

furiosa-llm serve [MODEL_ID_OR_PATH] --max-model-len 8192

The value caps the total tokens a single request may use — prompt plus generated tokens. It applies to every request, including those that do not set max_tokens: the implicit generation budget shrinks with the cap as well. The limit advertised on /v1/models is whichever of those four bounds is smallest, so on a memory-tight deployment it can be the KV-derived one even with no cap set. A request exceeding it is rejected with a context-length error.

The cap may only lower the limit. A value above either the model’s max_position_embeddings or the context length covered by the loaded FXB is rejected at startup, so a typo fails fast instead of being ignored.

By default, the scheduler decides whether to admit a request using its estimated lifetime KV cache demand: prompt tokens plus the maximum output tokens, accounting for prefix-cache hits. If neither the request nor the model’s generation defaults sets an output-token limit, the remaining context window becomes the output budget. An unnecessarily large context limit can therefore reduce concurrency even when actual responses are short.

For example, suppose the model, FXB, and KV cache support a 128K-token context, but your application needs at most 8K tokens per request, including input and output. The command above sets this 8K limit with --max-model-len 8192. For requests without an output-token limit, this reduces the scheduler’s per-request KV budget from 128K to 8K tokens before accounting for prefix-cache hits. The same KV cache can then accommodate more concurrent requests, potentially increasing throughput.

The benefit is limited when requests already specify an appropriate max_tokens or another constraint, such as --max-concurrency or NPU compute capacity, limits throughput. The setting does not speed up individual kernel executions or reduce allocated NPU memory; weights, compiled buckets, and the KV pool stay the same.

Note

fxb build takes an option of the same name, but it means something different there: at build time --max-model-len shapes which buckets are compiled into the FXB. At serving time the bucket set is fixed by the loaded FXB, and this option only caps admission.

Profile-Guided Decode Batching#

Profile-guided decode batching uses measured execution costs to choose decode batch composition and compiled buckets. It can improve throughput and TPOT when concurrent requests have different context lengths and batching choices affect execution cost. On startup, Furiosa-LLM profiles NPU execution and input transfers for different batch and KV-cache shapes, adding an initial profiling cost. It caches these profiles and reuses them when compatible with the FXB and runtime.

The feature is enabled by default for generative models. Pooling models disable it automatically because they have no decode phase. --batch-scheduling-budget-ms (default: 1 ms) sets the CPU search budget for the default decode-batch optimizer. It is not a hard limit on total scheduling latency, and does not bound the separate experimental aggressive-batching policy. The budget is ignored when profile-guided batching is disabled. Start with the default budget; increasing it allows a longer search for efficient batches but can add CPU scheduling overhead. Compare throughput and TPOT before keeping a larger budget.

furiosa-llm serve <model> \
  --profile-guided-decode-batching --batch-scheduling-budget-ms 1

Use --no-profile-guided-decode-batching to disable profiling and its use in decode batching. The Python equivalents are SchedulerConfig.profile_guided_decode_batching and SchedulerConfig.batch_scheduling_budget_ms. The profile_guided_decode_batching setting replaces enable_exec_stats without a compatibility alias; the budget setting retains its name.

Profile-guided batching selects batches using execution measurements; overlap scheduling overlaps CPU preparation with NPU execution. They can be used together for supported models. The separate experimental aggressive-batching policy requires profile-guided batching and cannot be combined with an explicit max_concurrency.

Benefits depend on the workload’s context lengths and available buckets. Compare throughput, TPOT, TTFT, and startup profiling time with your own traffic. The 2026.4 release notes include an illustrative ON/OFF comparison.

Experimental NPU Sampling#

NPU sampling selects the next token on the NPU for supported generative models. Use it when CPU token selection or logits transfers contribute significantly to decode latency, especially with larger batches. Moving sampling to the NPU can reduce TPOT and improve output throughput. Compatible FXB builds include sampling kernels by default; enable the path explicitly:

furiosa-llm serve <model> --experimental-enable-npu-sampling

For the Python API, set SchedulerConfig(enable_npu_sampling=True). The serving default is host sampling. Engine startup fails if NPU sampling is enabled with an FXB that lacks the required sampling kernel.

The NPU sampler supports greedy and random sampling, including temperature, top_k, top_p, min_p, repetition penalties, minimum token lengths, and structured-output masks. Requests for output logprobs require transferring and processing logits on the host, while token selection remains on the NPU. The runtime can skip full-logit transfers when no request in the batch needs logits on the host.

This feature remains experimental. It works with eager scheduling and with supported overlap-scheduling configurations, but not with speculative decoding. See Overlap Scheduling for configuration details.

Experimental Overlap Scheduling#

Overlap scheduling prepares the next batch on the CPU while the NPU executes the current batch. Use it when CPU batch preparation leaves gaps between NPU executions, particularly during sustained generation. It can improve throughput and TPOT, but may increase TTFT for newly arriving requests.

The feature is experimental and disabled by default. Enable it with:

furiosa-llm serve <model> --enable-overlap-scheduling

Keep it enabled when throughput and TPOT improve while TTFT remains within your latency target. See Overlap Scheduling for configuration and compatibility.

Experimental Hierarchical Prefix Caching#

Hierarchical prefix caching (HiCache) extends prefix reuse beyond NPU memory by offloading KV cache to host memory. Use it when requests repeatedly share long prefixes and the reusable working set exceeds the NPU cache capacity. Avoiding repeated prefill computation can reduce TTFT and improve throughput when reloading KV data is cheaper than recomputing the prefix.

The feature is experimental and disabled by default. For example, enable a process-wide 16 GiB host KV cache with:

furiosa-llm serve <model> --experimental-kv-offload-host-memory-gb 16

A larger host cache can retain more reusable prefixes, at the cost of host memory and transfer bandwidth. Benefits are limited when prompts rarely share prefixes or the NPU cache already holds the working set. See Hierarchical Prefix Caching for host-memory sizing and retention policies.