Companion to openvinotoolkit/omega#12 and huggingface/optimum-intel#1788.
This gist documents the verified-working way to run this model on OpenVINO today, and the known limitation that is not yet fixable without new upstream work.
| Approach | Status |
|---|---|
optimum.intel.OVModelForSpeechSeq2Seq + HF pipeline |
✅ Works (fixed in optimum-intel PR #1788, commit f13d947e) |
openvino_genai.WhisperPipeline |
❌ Not supported — genuine architecture mismatch, documented, not a quick fix |
The exact command matters. Passing an explicit --task does not auto-append -with-past
(a real usability trap — see root cause section below), so you must include it yourself:
pip install "git+https://github.com/huggingface/optimum-intel.git@fix/cohere-asr-with-tests"
# (until PR #1788 merges to main; afterwards use the released version)
optimum-cli export openvino \
--model CohereLabs/cohere-transcribe-03-2026 \
--task automatic-speech-recognition-with-past \
--weight-format fp16 \
--trust-remote-code \
./cohere-transcribe_ovVerify the export is correct before proceeding:
python -c "
import openvino as ov
enc = ov.Core().read_model('./cohere-transcribe_ov/openvino_encoder_model.xml')
dec = ov.Core().read_model('./cohere-transcribe_ov/openvino_decoder_model.xml')
print('encoder inputs:', [i.get_any_name() for i in enc.inputs]) # expect input_features + length
print('decoder inputs:', [i.get_any_name() for i in dec.inputs]) # expect beam_idx present
"If length is missing from the encoder or beam_idx is missing from the decoder, you exported
without -with-past or with a stale/older optimum-intel — re-check the command above.
from transformers import AutoProcessor, pipeline
from optimum.intel import OVModelForSpeechSeq2Seq
import librosa
model_path = "./cohere-transcribe_ov"
model = OVModelForSpeechSeq2Seq.from_pretrained(model_path, trust_remote_code=True)
processor = AutoProcessor.from_pretrained(model_path, trust_remote_code=True)
speech_recognition = pipeline(
"automatic-speech-recognition",
model=model,
tokenizer=processor.tokenizer,
feature_extractor=processor.feature_extractor,
)
audio, sr = librosa.load("jfk.wav", sr=16000)
result = speech_recognition(audio)
print(result["text"])Device selection: pass device="GPU.0" / "GPU.1" / "CPU" to from_pretrained(..., ov_config={"CACHE_DIR": "..."}) or set model.to("GPU.0") — verified working on CPU, iGPU
(GPU.0) and discrete Arc Pro B60 (GPU.1) with 3s/7s/11s audio clips, no shape errors, no cache
errors.
Known, pre-existing, unrelated caveat: on the current CohereLabs/cohere-transcribe-03-2026
Hub revision, generate() output quality itself is currently degraded (garbled/repetitive text)
— this reproduces identically on eager PyTorch (no OpenVINO involved at all), so it is not
caused by this fix or by OpenVINO/optimum-intel. It appears to be Hub-side remote-code drift: an
older revision's feature extractor supported decoder_input_ids/language-conditioning that the
current revision's CohereAsrFeatureExtractor no longer honors. If you need production-quality
WER, track this separately — it is out of scope for the export/inference-contract bugs fixed
here. The originally reported reference WER numbers (1.20% CPU / 1.25% reference) were measured
against an older Hub revision and can no longer be reproduced as-is.
import openvino_genai as ov_genai
pipe = ov_genai.WhisperPipeline("./cohere-transcribe_ov", "CPU")This will not work, even against the fixed export above. It is not a config issue and not a one-line fix. Root causes (three independent, structural mismatches):
generation_config.jsonfields:WhisperGenerationConfigrequires a Whisper-stylemax_length(and other Whisper-only fields likelang_to_id) that Cohere-ASR's config doesn't have and can't gain without misrepresenting the model. Without it,max_new_tokensunderflows toSIZE_MAXandpipe.generate()raisesValueError: vector::reserve.- Missing
length-tensor threading:whisper.cpp'sencode()only ever sets theinput_featurestensor; it has no concept of the new dynamiclengthinput this model's encoder requires. Even bypassing failure #1, the Conformer's internal length-based masking collapses a dimension to 0 and OpenVINO throws aBroadcastshape-inference error. - Incompatible mel-feature-extraction algorithm:
ov::genai::WhisperFeatureExtractoris a fixed-30s-chunk, non-length-aware,log10mel implementation matching OpenAI Whisper exactly.CohereAsrFeatureExtractoris a NeMo-styleFilterbankFeaturesextractor withlength-masked per-feature (per-mel-bin) CMVN normalization, different log compression, dither, and optional frame splicing — there is no way to numerically reproduce this inside the currentWhisperFeatureExtractorimplementation.
Supporting this model in openvino_genai would require a new, dedicated Conformer/NeMo-ASR
pipeline type (own feature extractor, own generation-config handling, length-tensor threading)
— genuinely new-pipeline-type-scope work, not a bugfix. This has been documented directly in the
openvino.genai docs (site/docs/supported-models/index.mdx) so it isn't silently reattempted;
a full technical gap analysis with exact file/line references is attached in this gist
(genai_gap_analysis.md) for whoever picks up that follow-up.
- optimum-intel PR #1788 (branch
fix/cohere-asr-with-tests, commitf13d947e): fixed the encoder's static-3000-frame dummy-input contract (now dynamic +length-aware), and fixed the decoder's broken with-past export (trace-time-constant cache-length bug in the Hub remote code, patched for trace duration only). New regression tests added (tests/openvino/test_seq2seq.py). - openvino.genai: no code changed.
cohere_asr/ NeMo-Conformer-style ASR architectures documented as explicitly unsupported byWhisperPipeline, with a link back to this issue. - Both changes validated end-to-end on real hardware: CPU (Core Ultra 9 285K), GPU.0 (Arrow Lake-U iGPU), GPU.1 (Arc Pro B60 dGPU).