Skip to main content

Automatic Speech Recognition

Convert and Optimize Model​

Download and convert an automatic speech recognition model (e.g. openai/whisper-base) to OpenVINO format from Hugging Face:

optimum-cli export openvino --model openai/whisper-base whisper_ov

See all supported Speech Recognition Models.

info

Refer to the Model Preparation guide for detailed instructions on how to download, convert and optimize models for OpenVINO GenAI.

Run Model Using OpenVINO GenAI​

OpenVINO GenAI introduces the ASRPipeline pipeline for automatic speech recognition models (ASR). You can construct it straight away from the folder with the converted model. It will automatically load the model, tokenizer, detokenizer and default generation configuration.

info

ASRPipeline expects normalized audio files in WAV format at sampling rate of 16 kHz as input.

import openvino_genai as ov_genai
import librosa

def read_wav(filepath):
raw_speech, samplerate = librosa.load(filepath, sr=16000)
return raw_speech.tolist()

raw_speech = read_wav('sample.wav')

pipe = ov_genai.ASRPipeline(model_path, "CPU")
result = pipe.generate(raw_speech, max_new_tokens=100)
print(result)
tip

Use CPU or GPU as devices without any other code change.

Additional Usage Options​

tip

Check out Python, C++, and JavaScript speech recognition samples.

Use Different Generation Parameters​

Generation Configuration Workflow​

  1. Get the model default config with get_generation_config()
  2. Modify parameters
  3. Apply the updated config using one of the following methods:
    • Use set_generation_config(config)
    • Pass config directly to generate() (e.g. generate(prompt, config))
    • Specify options as inputs in the generate() method (e.g. generate(prompt, max_new_tokens=100))

Basic Generation Configuration​

import openvino_genai as ov_genai

pipe = ov_genai.ASRPipeline(model_path, "CPU")

# Get default configuration
config = pipe.get_generation_config()

# Modify parameters
config.max_new_tokens = 100
config.temperature = 0.7
config.top_k = 50
config.top_p = 0.9
config.repetition_penalty = 1.2

# Generate text with custom configuration
result = pipe.generate(raw_speech, config)
Understanding Basic Generation Parameters
  • max_new_tokens: The maximum numbers of tokens to generate, excluding the number of tokens in the prompt. max_new_tokens has priority over max_length.
  • temperature: Controls the level of creativity in AI-generated text:
    • Low temperature (e.g. 0.2) leads to more focused and deterministic output, choosing tokens with the highest probability.
    • Medium temperature (e.g. 1.0) maintains a balance between creativity and focus, selecting tokens based on their probabilities without significant bias.
    • High temperature (e.g. 2.0) makes output more creative and adventurous, increasing the chances of selecting less likely tokens.
  • top_k: Limits token selection to the k most likely next tokens. Higher values allow more diverse outputs.
  • top_p: Selects from the smallest set of tokens whose cumulative probability exceeds p. Helps balance diversity and quality.
  • repetition_penalty: Reduces the likelihood of repeating tokens. Values above 1.0 discourage repetition.

For the full list of generation parameters, refer to the Generation Config API.

Beam search helps explore multiple possible text completions simultaneously, often leading to higher quality outputs.

import openvino_genai as ov_genai

pipe = ov_genai.ASRPipeline(model_path, "CPU")

# Get default generation config
config = pipe.get_generation_config()

# Modify parameters
config.max_new_tokens = 256
config.num_beams = 15
config.num_beam_groups = 3
config.diversity_penalty = 1.0

# Generate text with custom configuration
result = pipe.generate(raw_speech, config)
Understanding Beam Search Generation Parameters
  • max_new_tokens: The maximum numbers of tokens to generate, excluding the number of tokens in the prompt. max_new_tokens has priority over max_length.
  • num_beams: The number of beams for beam search. 1 disables beam search.
  • num_beam_groups: The number of groups to divide num_beams into in order to ensure diversity among different groups of beams.
  • diversity_penalty: value is subtracted from a beam's score if it generates the same token as any beam from other group at a particular time.

For the full list of generation parameters, refer to the Generation Config API.

note

Beam search support depends on the selected model architecture. Qwen3-ASR models do not support beam search decoding.

Transcription​

Language handling depends on the model architecture. Models with language identification support can automatically detect the language of the input audio. You can also specify the language to improve accuracy. The detected or specified language is available in the result via the languages field.

pipe = ov_genai.ASRPipeline(model_path, "CPU")

# Automatic language detection for models with language identification support
raw_speech = read_wav("speech_sample.wav")
result = pipe.generate(raw_speech)
print(result.languages[0]) # e.g. "en", "fr", "de"

# Explicitly specify language. In the form of `en`, `<|en|>` for Whisper and `English` for Qwen3-ASR
result = pipe.generate(raw_speech, language="en")
print(result.languages[0]) # "en"

# French speech sample
raw_speech = read_wav("french_sample.wav")
result = pipe.generate(raw_speech, language="<|fr|>")
print(result.languages[0]) # "fr"

SenseVoiceSmall-specific Options​

info

These features are specific to SenseVoiceSmall used with ASRPipeline. They do not apply to other ASR model architectures.

note

SenseVoiceSmall supports automatic language identification (language="auto") and explicit language selection using language codes such as en, zh, yue, ja, and ko.

Inverse Text Normalization​

SenseVoiceSmall supports inverse text normalization (ITN) during transcription. By default, use_itn=false selects the woitn mode. Set use_itn=true to select the withitn mode.

pipe = ov_genai.ASRPipeline(model_path, "CPU")

# Example output for the same audio with ITN disabled and enabled:
# use_itn=False: "...presented him with fifty pieces of gold"
# use_itn=True: "...presented him with 50 pieces of gold."
result = pipe.generate(raw_speech, use_itn=True)
note

SenseVoiceSmall does not currently generate segment-level or word-level timestamps. return_timestamps and word_timestamps are accepted but ignored, and chunks and words remain unset. Normal transcription and streaming are unaffected.

For supported languages, word-level timestamps can be generated separately using ASRForcedAligner: first transcribe the audio with SenseVoiceSmall, then pass the audio and transcription to the standalone aligner. See Word-level Timestamps Prediction for details.

Whisper-specific Features​

info

These features are specific to Whisper models used with ASRPipeline. They may not apply to other ASR model architectures.

Translation​

By default, Whisper performs transcription, keeping the output in the same language as the input. To translate non-English speech to English, use the translate task:

pipe = ov_genai.ASRPipeline(model_path, "CPU")

# Translate French audio to English
raw_speech = read_wav("french_sample.wav")
result = pipe.generate(raw_speech, task="translate")

Timestamps Prediction​

Whisper can predict timestamps for each segment of speech, which is useful for synchronization or creating subtitles:

pipe = ov_genai.ASRPipeline(model_path, "CPU")

# Enable timestamp prediction
result = pipe.generate(raw_speech, return_timestamps=True)

# Print timestamps and text segments
for chunk in result.chunks[0]:
print(f"timestamps: [{chunk.start_ts:.2f}, {chunk.end_ts:.2f}] text: {chunk.text}")

Word-level Timestamps Prediction​

Whisper can predict timestamps for each word of speech, which provides more granular timing information compared to segment-level timestamps.

# Word timestamps require decomposition of cross-attention decoder SDPA layers,
# so word_timestamps must be passed to the pipeline constructor (not just in generation config)
pipe = openvino_genai.ASRPipeline(model_path, "CPU", word_timestamps=True)

# Enable word-level timestamp prediction
result = pipe.generate(raw_speech, word_timestamps=True)

# Print word-level timestamps
for word in result.words[0]:
print(f"[{word.start_ts:.2f}, {word.end_ts:.2f}]: {word.text}")

For Qwen3-ASR word timestamps, OpenVINO GenAI uses the companion Qwen3 Forced Aligner model.

OpenVINO GenAI currently supports forced-alignment timestamps for Chinese, Cantonese, English, German, Spanish, French, Italian, Portuguese, and Russian. The Qwen3 Forced Aligner model also supports Japanese and Korean, but Japanese and Korean segmentation are not currently implemented in OpenVINO GenAI.

Qwen3-ASR and its forced aligner are distributed separately and should be exported to separate directories. Install qwen-asr before export.

pip install qwen-asr

# Required for ASRPipeline transcription with Qwen3-ASR.
optimum-cli export openvino \
--model Qwen/Qwen3-ASR-0.6B \
--task automatic-speech-recognition-with-past \
--trust-remote-code \
qwen3-asr-ov

# Required for forced alignment (standalone or ASRPipeline word timestamps).
optimum-cli export openvino \
--model Qwen/Qwen3-ForcedAligner-0.6B \
--task automatic-speech-recognition-with-past \
--trust-remote-code \
qwen3-forced-aligner-ov

Construct the ASRForcedAligner and pass the instance into ASRPipeline. The ASR pipeline and forced aligner may use different devices.

aligner = openvino_genai.ASRForcedAligner(forced_aligner_model_path, "CPU")
pipe = openvino_genai.ASRPipeline(asr_model_path, "GPU", forced_aligner=aligner)

result = pipe.generate(raw_speech, word_timestamps=True, language="English")

for word in result.words[0]:
print(f"[{word.start_ts:.2f}, {word.end_ts:.2f}]: {word.text}")

When word timestamps are enabled for Qwen3-ASR, audio is processed in chunks of approximately 180 seconds. This can change chunk boundaries and therefore the transcription compared with plain transcription.

The forced aligner is also available as a standalone ASRForcedAligner class, usable independently of ASRPipeline.

aligner = openvino_genai.ASRForcedAligner(forced_aligner_model_path, "CPU")

words = aligner.align(raw_speech, transcript, language="english")

for word in words:
print(f"[{word.start_ts:.2f}, {word.end_ts:.2f}]: {word.text}")

Long-Form Audio Processing​

Whisper models are designed for audio segments up to 30 seconds in length. For longer audio, the OpenVINO GenAI ASR pipeline automatically handles Whisper processing using a sequential chunking algorithm ("sliding window"):

  1. The audio is divided into 30-second segments
  2. Each segment is processed sequentially
  3. Results are combined to produce the complete transcription

This happens automatically when you input longer audio files.

Using Initial Prompts and Hotwords​

You can improve transcription quality and guide the model's output style by providing initial prompts or hotwords using the following parameters:

  • initial_prompt: initial prompt tokens passed as a previous transcription (after <|startofprev|> token) to the first processing window.
  • hotwords: hotwords tokens passed as a previous transcription (after <|startofprev|> token) to the all processing windows.

Whisper models can use that context to better understand the speech and maintain a consistent writing style. However, prompts do not need to be genuine transcripts from prior audio segments. Such prompts can be used to steer the model to use particular spellings or styles:

pipe = ov_genai.ASRPipeline(model_path, "CPU")

result = pipe.generate(raw_speech)
# He has gone and gone for good answered Paul Icrom who...

result = pipe.generate(raw_speech, initial_prompt="Polychrome")
# He has gone and gone for good answered Polychrome who...
info

For the ASR API, refer to the ASR Generation Config API.

Performance Metrics​

ASRPipeline returns ASRDecodedResults with a perf_metrics field of type ASRPerfMetrics, which extends PerfMetrics.

In addition to common metrics (TTFT, TPOT, throughput, etc.), ASRPerfMetrics provides:

MetricTypeDescription
get_features_extraction_duration()MeanStdPair, msTime spent extracting audio features (mel spectrogram)
get_encode_inference_duration()MeanStdPair, msEncoder model inference duration
get_decode_inference_duration()MeanStdPair, msDecoder model inference duration (all token generation steps)
get_word_level_timestamps_processing_duration()MeanStdPair, msTime spent processing word-level timestamps

Raw values are available in the asr_raw_metrics field of ASRPerfMetrics.

Streaming the Output​

Refer to the Streaming guide for more information on streaming the output with OpenVINO GenAI.