File size: 8,050 Bytes
66ea1a8 9ecc3a5 66ea1a8 9ecc3a5 66ea1a8 9ecc3a5 66ea1a8 9ecc3a5 66ea1a8 9ecc3a5 66ea1a8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | ---
license: apache-2.0
language:
- ar
- de
- el
- en
- es
- fr
- it
- ja
- ko
- nl
- pl
- pt
- vi
- zh
pipeline_tag: automatic-speech-recognition
tags:
- audio
- speech-recognition
- transcription
- onnx
- onnxruntime
- conformer
- cohere
library_name: onnxruntime
base_model: CohereLabs/cohere-transcribe-03-2026
---
# Cohere Transcribe - ONNX
ONNX conversion of [CohereLabs/cohere-transcribe-03-2026](https://huggingface.co/CohereLabs/cohere-transcribe-03-2026), a 2B parameter Conformer-based speech recognition model supporting 14 languages.
Runs locally with [ONNX Runtime](https://onnxruntime.ai/) in Python, C#, C++, Java, JavaScript, or any ONNX-compatible runtime. No Python, no cloud APIs, no GPU required.
## What's Included
INT8 dynamically quantized ONNX model (2.75 GB total):
| File | Size | Description |
|------|------|-------------|
| `cohere-encoder.int8.onnx` | 3 MB | Encoder graph (weights in .data file) |
| `cohere-encoder.int8.onnx.data` | 2.6 GB | Encoder weights |
| `cohere-decoder.int8.onnx` | 147 MB | Decoder (self-contained) |
| `tokens.txt` | 219 KB | 16,384-entry vocabulary |
Plus:
- Export and quantization scripts (reproduce FP32 or re-quantize from the [original model](https://huggingface.co/CohereLabs/cohere-transcribe-03-2026))
- C# inference example
- Complete porting guide with all concepts explained
## Quick Start (Python)
```bash
pip install onnxruntime numpy soundfile librosa
```
```python
import onnxruntime as ort
import numpy as np
import librosa
# Load audio (must be 16kHz mono)
audio, sr = librosa.load("your_audio.wav", sr=16000, mono=True)
# Load models
enc = ort.InferenceSession("cohere-encoder.int8.onnx")
dec = ort.InferenceSession("cohere-decoder.int8.onnx")
# Load tokens
tokens = {}
with open("tokens.txt", "r", encoding="utf-8") as f:
for line in f:
parts = line.strip().rsplit(" ", 1)
if len(parts) == 2:
tokens[int(parts[1])] = parts[0]
token_to_id = {v: k for k, v in tokens.items()}
# Build prompt (change <|en|> to <|de|>, <|fr|>, etc.)
prompt_ids = [token_to_id[t] for t in [
"<|startofcontext|>", "<|startoftranscript|>", "<|emo:undefined|>",
"<|en|>", "<|en|>", "<|pnc|>", "<|noitn|>", "<|notimestamp|>", "<|nodiarize|>"
]]
# Run encoder (raw audio in, encoder representations out)
cross_k, cross_v = enc.run(None, {"audio": audio.reshape(1, -1).astype(np.float32)})
# Run decoder (autoregressive greedy decoding)
N_LAYERS, HEADS, HEAD_DIM, MAX_CTX = 8, 8, 128, 1024
self_k = np.zeros((N_LAYERS, 1, HEADS, MAX_CTX, HEAD_DIM), dtype=np.float32)
self_v = np.zeros((N_LAYERS, 1, HEADS, MAX_CTX, HEAD_DIM), dtype=np.float32)
eos_id = token_to_id["<|endoftext|>"]
generated = list(prompt_ids)
current = np.array([prompt_ids], dtype=np.int64)
offset = np.array(0, dtype=np.int64)
for _ in range(256):
logits, self_k, self_v = dec.run(None, {
"tokens": current, "in_n_layer_self_k_cache": self_k,
"in_n_layer_self_v_cache": self_v, "n_layer_cross_k": cross_k,
"n_layer_cross_v": cross_v, "offset": offset,
})
next_id = int(np.argmax(logits[0, -1, :]))
if next_id == eos_id:
break
generated.append(next_id)
offset = np.array(int(offset) + current.shape[1], dtype=np.int64)
current = np.array([[next_id]], dtype=np.int64)
# Decode to text
text = "".join(
tokens.get(t, "").replace("\u2581", " ")
for t in generated[len(prompt_ids):]
if not tokens.get(t, "").startswith("<|")
).strip()
print(text)
```
## Quick Start (C#)
```
dotnet add package Microsoft.ML.OnnxRuntime
```
See `CohereTranscribe.cs` for a complete example. For GPU acceleration on Windows:
```
dotnet add package Microsoft.ML.OnnxRuntime.DirectML
```
## Supported Languages
| Code | Language | Code | Language |
|------|----------|------|----------|
| en | English | nl | Dutch |
| de | German | pl | Polish |
| fr | French | el | Greek |
| es | Spanish | ar | Arabic |
| it | Italian | ja | Japanese |
| pt | Portuguese | zh | Chinese |
| vi | Vietnamese | ko | Korean |
Change language by swapping `<|en|>` in the prompt to the desired language code.
## Performance (INT8)
All benchmarks run on a Windows 11 machine with **CPU only** (no dedicated GPU), 24 GB shared RAM, using the INT8 variant. No special optimization or batching -- just sequential chunk-by-chunk processing.
| Audio | Language | Duration | Processing Time | Speed | Tokens Generated |
|-------|----------|----------|----------------|-------|-----------------|
| Voice memo | English | 30.5s | 5.4s | **5.6x realtime** | 61 |
| Interview podcast (Mike Agugliaro / Jay Abraham) | English | 57.1 min | 14 min 53s | **3.8x realtime** | ~14,500 |
| Language learning podcast (Easy German) | German | 35.0 min | 9 min 24s | **3.7x realtime** | ~8,900 |
### What the Numbers Mean
- **5.6x realtime** means 1 second of audio is transcribed in ~0.18 seconds
- **3.7-3.8x realtime** on longer files (the slight slowdown vs short clips is because longer audio produces more decoder tokens per chunk)
- **Encoder** takes ~3.5-7s per 30s chunk (the heavy lifting -- 48 Conformer layers)
- **Decoder** takes ~1.5-3s per chunk depending on how many words are spoken
### Memory Usage
| Component | RAM |
|-----------|-----|
| Encoder session (loaded once) | ~2.6 GB |
| Decoder session (loaded once) | ~146 MB |
| Per-chunk inference overhead | ~300-500 MB |
| Decoder KV cache | ~256 MB |
| **Peak total** | **~3.5-4 GB** |
Peak RAM stays constant regardless of audio length -- only one chunk is in memory at a time. A 5-minute file and a 5-hour file use the same amount of RAM.
### GPU Acceleration
These benchmarks are CPU-only. For GPU acceleration on Windows, use DirectML (works with any DirectX 12 GPU -- AMD, NVIDIA, Intel). Expected 3-5x additional speedup, bringing throughput to 15-25x realtime.
## Long Audio
The encoder handles up to ~35 seconds per call. For longer audio, split into overlapping chunks:
- **Chunk size**: 30 seconds
- **Overlap**: 5 seconds
- **Stride**: 25 seconds
Transcribe each chunk, join results with spaces.
## How This Was Made
The original PyTorch model was converted to ONNX with several engineering adaptations:
1. **Feature extraction baked in** -- The encoder takes raw 16kHz audio, not mel spectrograms. STFT is implemented via Conv1d DFT filters (since torch.stft doesn't export to ONNX).
2. **Cross-attention K/V pre-computed** -- The encoder pre-computes Key/Value projections for all 8 decoder layers, matching the Whisper-style encoder-decoder ONNX pattern.
3. **Selective quantization** -- INT8 quantization protects convolutional and batch normalization layers in the audio frontend for accuracy preservation.
See [PORTING_GUIDE.md](PORTING_GUIDE.md) for the complete technical writeup with every concept explained.
## ONNX Tensor Contract
### Encoder
```
Input: audio (batch, samples) float32, raw 16kHz mono
Output: n_layer_cross_k (8, batch, T', 1024) float32
n_layer_cross_v (8, batch, T', 1024) float32
```
### Decoder
```
Input: tokens (batch, n_tokens) int64
in_n_layer_self_k_cache (8, batch, 8, 1024, 128) float32
in_n_layer_self_v_cache (8, batch, 8, 1024, 128) float32
n_layer_cross_k (8, batch, T', 1024) float32
n_layer_cross_v (8, batch, T', 1024) float32
offset () int64 scalar
Output: logits (batch, n_tokens, 16384) float32
out_n_layer_self_k_cache (8, batch, 8, 1024, 128) float32
out_n_layer_self_v_cache (8, batch, 8, 1024, 128) float32
```
## Attribution
Original model: [CohereLabs/cohere-transcribe-03-2026](https://huggingface.co/CohereLabs/cohere-transcribe-03-2026) by [Cohere](https://cohere.com) and [Cohere Labs](https://cohere.com/research).
ONNX conversion, quantization, and documentation: community contribution.
License: Apache 2.0
|