Skip to main content

Overview

Text generation in ONNX Runtime GenAI is controlled by the Search and Generator classes, which implement various decoding strategies for selecting tokens. The library supports both deterministic and stochastic generation methods.

The Generation Loop

The generation process follows this pattern (from src/generators.h:99):
1

Initialize Generator

Create a Generator with a Model and GeneratorParams.
2

Append Input Tokens

Feed the prompt tokens using AppendTokens() or AppendTokenSequences().
3

Generate Tokens

Call GenerateNextToken() in a loop until IsDone() returns true.Each iteration:
  1. Runs model inference via State::Run()
  2. Retrieves logits
  3. Applies logit processors (penalties, constraints)
  4. Selects next token(s) via search strategy
  5. Updates KV cache
  6. Checks termination conditions
4

Retrieve Results

Extract generated sequences using GetSequence().

Example

Search Strategies

ONNX Runtime GenAI implements two primary search strategies (from src/search.h): Greedy search selects the token with the highest probability at each step. It’s fast and deterministic but may not produce the most diverse or creative outputs. When to use:
  • Factual question answering
  • Code generation
  • Translation tasks where determinism is preferred
Configuration:
Implementation (from src/search.h:68):
Beam search maintains multiple hypotheses (beams) and explores different token sequences in parallel. It finds higher-quality sequences but is more computationally expensive. When to use:
  • Translation tasks
  • Summarization
  • Tasks requiring high-quality, coherent outputs
Configuration:
Implementation (from src/search.h:99):
The BeamSearchScorer (from src/beam_search_scorer.h) manages:
  • Beam hypothesis tracking
  • Score normalization with length penalty
  • Early stopping logic
  • Final sequence selection

Search Parameters

All search parameters are defined in src/config.h:293:

Core Parameters

int
required
Maximum length of generated sequence (including input tokens). Defaults to model.context_length if not set.
int
default:"0"
Minimum length before EOS token is allowed. Useful for preventing premature termination.
int
default:"1"
Number of independent sequences to generate in parallel.
int
default:"1"
Number of beams for beam search. Set to 1 for greedy search.
int
default:"1"
Number of sequences to return from beam search. Must be ≤ num_beams.

Sampling Parameters

bool
default:"false"
Enable randomized sampling. When false, greedy/beam search is deterministic.
int
default:"50"
Number of highest probability tokens to keep for top-k filtering. Set to 0 to disable.
float
default:"0.0"
Cumulative probability threshold for nucleus sampling. Only tokens with cumulative probability ≤ top_p are kept. Range: (0, 1]. Set to 0 to disable.
float
default:"1.0"
Controls randomness in sampling. Lower values make output more deterministic, higher values increase diversity.
  • 0.1-0.5: More focused and deterministic
  • 0.7-0.9: Balanced creativity and coherence
  • 1.0+: More random and creative
int
default:"-1"
Random seed for sampling. Set to -1 for non-deterministic random seeding.

Penalty Parameters

float
default:"1.0"
Penalty for token repetition. Values > 1.0 discourage repetition, < 1.0 encourage it. Typical range: 1.0-1.5.
int
default:"0"
Prevent repeating n-grams of this size. Currently unused in implementation.

Beam Search Parameters

float
default:"1.0"
Exponential penalty applied to sequence length in beam search.
  • > 1.0: Favors longer sequences
  • < 1.0: Favors shorter sequences
  • = 1.0: No length penalty
bool
default:"true"
Stop beam search when num_beams complete sentences are found.
float
default:"0.0"
Penalty to encourage diverse beams. Currently unused in implementation.

Sampling Methods

When do_sample=true, tokens are selected probabilistically rather than deterministically.

Top-K Sampling

Selects from the K most likely tokens (from src/search.cpp:173):
Example:

Top-P (Nucleus) Sampling

Selects from tokens whose cumulative probability exceeds threshold P (from src/search.cpp:195):
Example:

Top-K + Top-P Sampling

Combines both strategies: first applies top-k, then top-p within those k tokens (from src/search.cpp:227):

Temperature Scaling

Temperature is applied before softmax to control randomness:

Logits Processing

Before token selection, logits are processed to enforce constraints and apply penalties.

Repetition Penalty

Penalizes tokens that already appear in the sequence (from src/search.cpp):

Minimum Length

Suppresses EOS token until minimum length is reached:

Constrained Decoding

The ConstrainedLogitsProcessor (from src/constrained_logits_processor.h) enables grammar-based generation for structured outputs like JSON:
See the Constrained Decoding guide for details.

Termination Conditions

Generation stops when (from src/generators.h:102):
  1. EOS Token: An end-of-sequence token is generated (for greedy search)
  2. Max Length: The sequence reaches max_length
  3. Beam Search Done: All beams have completed (with early_stopping=true)
  4. Manual Termination: User interrupts generation

Streaming Generation

For real-time output, use TokenizerStream to decode tokens incrementally:
The stream handles multi-byte UTF-8 characters correctly, buffering partial characters until complete.

Batched Generation

Generate multiple independent sequences in parallel:

Advanced Features

Continuous Decoding

Rewind generation to a previous state and continue from there:
This is useful for:
  • Speculative decoding
  • Tree-based search
  • Alternative hypothesis exploration

Custom Logits

Manipulate logits directly:

Performance Considerations

Search Strategy Performance

  • Greedy: Fastest, ~1x baseline
  • Beam Search (4 beams): ~3-4x slower than greedy
  • Sampling: Similar to greedy, small overhead for RNG

Optimization Tips

  1. Use greedy search for latency-critical applications
  2. Enable past_present_share_buffer for CUDA with greedy search
  3. Limit max_length to avoid unnecessary computation
  4. Use batching to amortize overhead across multiple sequences
  5. Adjust temperature instead of using extreme top_k/top_p values

Next Steps

KV Cache

Learn how KV cache improves generation performance

Constrained Decoding

Generate structured outputs with grammar constraints

API Reference

Explore the complete API

Examples

See generation in action