parakeet-ultra for LiteRT

This repository is a conversion of moondream/parakeet-ultra (speech-to-text in 25 languages) to LiteRT, made with litert-torch 0.9.4 and ai-edge-quantizer 0.10.0 for LiteRT 2.3.0: on a Galaxy S26 its float16 encoders on the NPU transcribe 115Γ— faster than real time, 39Γ— on the GPU, and its int8 encoders 34Γ— on the CPU and 10Γ— on a Pixel 8a's CPU (655 LibriSpeech test-clean utterances, one after another, measured 2026-10-31). On all of LibriSpeech test-clean the word error rate on the Galaxy S26's NPU is 1.417 %, against 1.426 % for our float32 PyTorch run of the same windows.

moondream/parakeet-ultra is a post-trained version of NVIDIA's parakeet-tdt-0.6b-v3 with the same architecture, the same tokenizer and the same 0.6B parameters (its card); its config.json is byte-identical to v3's. The checkpoint stores its weight matrices (linear, convolution, LSTM) in float16 and its norms in float32. The graphs are built by the same code as litert-community/parakeet-redux's (the ternary sibling of the same architecture) from parakeet-ultra's weights, and the Android runner is parakeet-redux's with two options added (--pipeline and --pipeline-depth, see How it works). The speeds on this card are for this repository's .tflite files run with LiteRT 2.3.0's C API, not for LiteRT-LM or for any other conversion of this architecture.

Files

file bytes what backend
parakeet_ultra_encoder_10s_i8.tflite 616,306,528 encoder for windows up to 10 s; int8 weights, one scale per output channel, in the linear layers and the two 1Γ—1 convolutions of the subsampling, with int8 activations computed at run time; the depthwise convolutions and the 24 relative-position tables stay float32 CPU
parakeet_ultra_encoder_20s_i8.tflite 640,882,528 the same, up to 20 s CPU
parakeet_ultra_encoder_30s_i8.tflite 665,458,528 the same, up to 30 s CPU
parakeet_ultra_encoder_10s_f16.tflite 1,194,680,704 encoder for windows up to 10 s; float16 weights in the linear and convolution layers (the checkpoint's float16 values; linear weights that absorb a constant scale of the graph are rounded to float16 again), LayerNorm inputs rescaled so that float16 arithmetic does not overflow GPU, NPU
parakeet_ultra_encoder_20s_f16.tflite 1,219,256,704 the same, up to 20 s GPU, NPU
parakeet_ultra_encoder_30s_f16.tflite 1,243,832,704 the same, up to 30 s GPU, NPU
parakeet_ultra_mel_10s.tflite 1,608,068 log-mel front end, 10 s of 16 kHz audio (no weights: the same bytes as parakeet-redux's) CPU
parakeet_ultra_mel_20s.tflite 2,252,068 the same, 20 s CPU
parakeet_ultra_mel_30s.tflite 2,896,076 the same, 30 s CPU
parakeet_ultra_decoder_i8.tflite 17,866,768 TDT prediction network (predict) and joint network (joint), int8 weights CPU
tokenizer.json 1,159,960 the original's tokenizer (byte-identical to nvidia/parakeet-tdt-0.6b-v3's) host
ultra_asr_runner_p.cc, build_android.sh a command-line runner for Android (LiteRT C API) and its build script: parakeet-redux's runner (redux_asr_runner_b.cc) with --pipeline and --pipeline-depth added; with --pipeline 0 it gives the same tokens as parakeet-redux's (the runner reads the model files from its arguments)
tdt_text.py turns the runner's token ids into text (parakeet-redux's file, unchanged) host

Each encoder file holds the whole encoder; the three window lengths only save the work of padding short audio. Take the i8 set for the CPU (1.95 GB with the mel and decoder files) or the f16 set for the GPU or the NPU (3.68 GB with them).

How it works

audio (16 kHz mono) β†’ 30 s windows β†’ mel front end β†’ encoder β†’ greedy TDT decoding β†’ text

  • Windows. The audio is cut into consecutive windows of 479,840 samples (30 s); the last one is shorter. A window under 320 samples (two mel frames) is dropped and has no text. Each window is transcribed on its own, and the window texts are joined with one space. The checkpoint's voice-activity head is not converted, so long audio is cut at fixed 30 s points, not at pauses, and a word that crosses a cut can be split, lost or repeated.
  • Buckets. Each window goes to the smallest graph pair that holds it: up to 160,000 samples β†’ the 10 s mel and encoder, up to 320,000 β†’ 20 s, else 30 s. The shorter graphs only skip the work on padding: in float32 they gave the same tokens as the 30 s graphs on all 83 windows of our 82-utterance test subset.
  • Mel front end (parakeet_ultra_mel_*, inputs audio [1, samples] float32 and n_valid [1] int32): pre-emphasis, STFT (512 points, 400-sample Hann window, hop 160), 128 Slaney mel bins, log and per-window normalization over the valid frames, as transformers' ParakeetFeatureExtractor. Outputs features [1, 128, T], mel_mask [1, T] and frame_mask [1, T / 8] (T = 1,000 / 2,000 / 3,000).
  • Encoder (parakeet_ultra_encoder_*, inputs features and mel_mask as the mel graph gives them): output enc [1, T / 8, 640]; rows past the valid frames are undefined.
  • Decoding (on the host, parakeet_ultra_decoder_i8): predict (token [1, 1] int32, h and c [2, 1, 640]) β†’ dec_out [1, 640] and the new h, c; joint (one enc row [1, 640], dec_out) β†’ 8,198 logits = 8,193 token logits (8192 = blank) + 5 duration logits (0–4 frames). Start from blank with zero state; at each step take the arg-max token and duration; a blank with duration 0 moves one frame; a non-blank token is emitted and fed to predict; ten tokens on one frame move one frame; token 3 ends the window; stop at the last valid frame (the sum of frame_mask) or after 3,750 steps.
  • Pipelining (the Android runner's --pipeline 1). The runner decodes window k on its main thread while a second thread runs the mel front end and the encoder of the next windows (up to two ahead), also across files; --pipeline-depth sets how many (2 by default). Each window's decoding still starts from blank with zero state, so the tokens are the ones --pipeline 0 (one thread, window after window) gives: the same tokens, frames and durations on all 658 windows of our 655-utterance runs, on every backend. With a single window there is nothing to overlap: the gain comes from runs of several windows.
  • Text. Decode each window's token ids with tokenizer.json, special tokens skipped and repeated ids kept (Tokenizer.decode(ids, skip_special_tokens=True)). Id 3 (<|endoftext|>) is not flagged special in tokenizer.json, so a window that ended on it would print the literal token; no window did in our runs.

Use it

1. Download

pip install -U huggingface_hub
hf download litert-community/parakeet-ultra --local-dir parakeet-ultra
cd parakeet-ultra

2. Your audio

Both runners below read 16 kHz mono 16-bit WAV, and the Android runner reads a folder with an index file. The block below writes those WAVs and the index from any format ffmpeg reads; replace sample1.wav sample2.wav with your files.

mkdir -p audio && : > audio/index.tsv && i=0
for f in sample1.wav sample2.wav; do
  id=$(printf %03d $i)
  ffmpeg -loglevel error -y -i "$f" -ac 1 -ar 16000 -c:a pcm_s16le "audio/$id.wav"
  printf '%s\t%s\t%s.wav\n' "$id" "$(basename "$f")" "$id" >> audio/index.tsv
  i=$((i + 1))
done

3a. On a desktop (Python, CPU)

Save this as transcribe.py in the parakeet-ultra folder:

import sys
import time
import wave

import numpy as np
from ai_edge_litert.interpreter import Interpreter
from tokenizers import Tokenizer

BUCKETS = (10, 20, 30)  # seconds: each 30 s window goes to the smallest graph that holds it
mel = {b: Interpreter(f"parakeet_ultra_mel_{b}s.tflite", num_threads=4).get_signature_runner() for b in BUCKETS}
enc = {b: Interpreter(f"parakeet_ultra_encoder_{b}s_i8.tflite", num_threads=4).get_signature_runner() for b in BUCKETS}
dec = Interpreter("parakeet_ultra_decoder_i8.tflite", num_threads=1)
predict, joint = dec.get_signature_runner("predict"), dec.get_signature_runner("joint")
tokenizer = Tokenizer.from_file("tokenizer.json")
BLANK, EOS, WINDOW = 8192, 3, 479840


def read_wav(path):  # 16 kHz mono 16-bit PCM
    with wave.open(path) as w:
        assert (w.getframerate(), w.getnchannels(), w.getsampwidth()) == (16000, 1, 2), path
        return np.frombuffer(w.readframes(w.getnframes()), "<i2").astype(np.float32) / 32768


def transcribe_window(x):
    n = len(x)
    b = next(b for b in BUCKETS if n <= b * 16000)
    audio = np.zeros((1, b * 16000), np.float32)
    audio[0, :n] = x
    m = mel[b](audio=audio, n_valid=np.array([n], np.int32))
    e = enc[b](features=m["features"], mel_mask=m["mel_mask"])["enc"][0]
    frames = int(m["frame_mask"].sum())
    state = predict(token=np.array([[BLANK]], np.int32), h=np.zeros((2, 1, 640), np.float32), c=np.zeros((2, 1, 640), np.float32))
    ids, t, steps, run = [], 0, 0, 0
    while t < frames and steps < 3750:
        steps += 1
        logits = joint(enc_frame=e[t:t + 1], dec_out=state["dec_out"])["logits"][0]
        token, d = int(np.argmax(logits[:8193])), int(np.argmax(logits[8193:]))
        if token == BLANK and d == 0:
            d = 1
        if token != BLANK:
            ids.append(token)
            if token == EOS:
                break
            state = predict(token=np.array([[token]], np.int32), h=state["h_out"], c=state["c_out"])
        if d == 0:
            run += 1
            if run >= 10:
                d = 1
        if d > 0:
            run = 0
        t += d
    return tokenizer.decode(ids, skip_special_tokens=True)


for path in sys.argv[1:]:
    x = read_wav(path)
    t0 = time.perf_counter()
    texts = [transcribe_window(x[s:s + WINDOW]) for s in range(0, len(x), WINDOW) if len(x[s:s + WINDOW]) >= 320]
    print(f"{path}\t{len(x) / 16000:.1f} s audio\t{time.perf_counter() - t0:.2f} s\t" + " ".join(t for t in texts if t))
pip install ai-edge-litert==2.3.0 tokenizers numpy
python transcribe.py audio/*.wav

3b. On an Android phone (native runner)

Build the runner with the Android NDK r29 (we built it on macOS; the path below is Android Studio's default there). The script downloads the LiteRT 2.3.0 C headers (litert_cc_sdk.zip from LiteRT's GitHub release) and the runtime libraries (Google's Maven), and checks their sha256.

NDK=$HOME/Library/Android/sdk/ndk/29.0.13113456 bash build_android.sh

Copy the runner, the CPU files and your audio to the phone, run it, and turn its output into text:

adb shell mkdir -p /data/local/tmp/parakeet-ultra
adb push ultra_asr_runner_p libs/libLiteRt.so parakeet_ultra_mel_*.tflite parakeet_ultra_encoder_*_i8.tflite parakeet_ultra_decoder_i8.tflite audio /data/local/tmp/parakeet-ultra/
adb shell chmod 755 /data/local/tmp/parakeet-ultra/ultra_asr_runner_p
adb shell 'cd /data/local/tmp/parakeet-ultra && LD_LIBRARY_PATH=. ./ultra_asr_runner_p --accel cpu --libdir . \
  --model parakeet_ultra_encoder_30s_i8.tflite --mel parakeet_ultra_mel_30s.tflite \
  --model10 parakeet_ultra_encoder_10s_i8.tflite --mel10 parakeet_ultra_mel_10s.tflite \
  --model20 parakeet_ultra_encoder_20s_i8.tflite --mel20 parakeet_ultra_mel_20s.tflite \
  --dec parakeet_ultra_decoder_i8.tflite --threads 8 --mel-threads 2 --dec-threads 1 --pipeline 1 \
  --fixtures audio --count $(grep -c . audio/index.tsv) --rounds 0 --dump none --out out' > out.jsonl
pip install tokenizers
python tdt_text.py tokenizer.json out.jsonl

Each line of out.jsonl that starts with {"kind":"utt" holds one file's token ids (tok), their encoder frame (frame = window index Γ— 375 + the frame within the window) and duration (dur), and the stage times in ms. The burst_summary line gives rtf_wall, the run's wall clock from the first window's start to the last window's end over the audio time (the model load and the warm-up file excluded), and rtf_burst, the summed stage times over the audio time, which counts the overlapped time twice under --pipeline 1. --pipeline 1 (How it works) was the faster setting on the NPU, the GPU and the Pixel 8a's CPU in our runs; on the Galaxy S26's CPU the two settings were within the run-to-run spread (0.029238 against 0.029363, Performance), and the table uses --pipeline 0. The CPU run prints GPU accelerator could not be loaded and registered on stderr: the GPU library is not on the phone for this run, and nothing else changes.

NPU (Galaxy S26, Qualcomm Hexagon). The runner compiles each f16 encoder for the Hexagon NPU on the phone the first time (LiteRT's Qualcomm compiler plugin, on-device JIT) and keeps the result in --cache-dir. It needs LiteRT's Qualcomm plugin libraries (libLiteRtDispatch_Qualcomm.so and libLiteRtCompilerPlugin_Qualcomm.so, from the litert-npu-runtime-qualcomm package that build_android.sh fetches) and the QNN libraries of the Qualcomm AI Runtime SDK (QAIRT) 2.50.0.260828, which you download from Qualcomm; copy these eight files flat into a folder qnn/: from lib/aarch64-android/, libQnnHtp.so, libQnnHtpPrepare.so, libQnnHtpV81Stub.so, libQnnHtpV81CalculatorStub.so, libQnnSystem.so, libQnnIr.so and libQnnSaver.so; from lib/hexagon-v81/unsigned/, libQnnHtpV81Skel.so. --window-samples is the window each graph holds: 479,840 samples for the 30 s graph, 320,000 and 160,000 for the others. Compile one encoder per process (one compile alone takes the runner to 4.1–6.4 GB, see Notes): the loop stops at the first encoder that does not compile, and the last command runs all three from the cache only when all three compiled. Run this block before the GPU block, with other apps closed:

adb push libs/libLiteRtDispatch_Qualcomm.so libs/libLiteRtCompilerPlugin_Qualcomm.so qnn/. parakeet_ultra_encoder_*_f16.tflite /data/local/tmp/parakeet-ultra/
NPU_ENV='LD_LIBRARY_PATH=. ADSP_LIBRARY_PATH="/data/local/tmp/parakeet-ultra;/vendor/dsp/cdsp;/vendor/lib/rfsa/adsp;/system/lib/rfsa/adsp;/dsp"'
compiled=0
for b in 30 20 10; do
  adb shell "cd /data/local/tmp/parakeet-ultra && $NPU_ENV ./ultra_asr_runner_p --accel npu+cpu --libdir . --cache-dir cache \
    --model parakeet_ultra_encoder_${b}s_f16.tflite --mel parakeet_ultra_mel_${b}s.tflite --window-samples $((b * 16000 - (b / 30) * 160)) \
    --dec parakeet_ultra_decoder_i8.tflite --fixtures audio --count 1 --rounds 0 --dump none --out out_compile" > compile_$b.log &&
    grep -q '^done wall_ms=' compile_$b.log || { echo "the ${b} s encoder did not compile (see compile_$b.log): stopped" >&2; break; }
  compiled=$((compiled + 1))
done
[ "$compiled" = 3 ] && adb shell "cd /data/local/tmp/parakeet-ultra && $NPU_ENV ./ultra_asr_runner_p --accel npu+cpu --libdir . --cache-dir cache \
  --model parakeet_ultra_encoder_30s_f16.tflite --mel parakeet_ultra_mel_30s.tflite \
  --model10 parakeet_ultra_encoder_10s_f16.tflite --mel10 parakeet_ultra_mel_10s.tflite \
  --model20 parakeet_ultra_encoder_20s_f16.tflite --mel20 parakeet_ultra_mel_20s.tflite \
  --dec parakeet_ultra_decoder_i8.tflite --mel-threads 2 --dec-threads 1 --pipeline 1 \
  --fixtures audio --count \$(grep -c . audio/index.tsv) --rounds 0 --dump none --out out" > out.jsonl

GPU. Push libs/libLiteRtClGlAccelerator.so and the f16 encoders, and run the CPU command with --accel gpu --gpu-precision fp16 and the parakeet_ultra_encoder_*_f16.tflite files, without --threads 8 (the encoder no longer runs on the CPU):

adb push libs/libLiteRtClGlAccelerator.so parakeet_ultra_encoder_*_f16.tflite /data/local/tmp/parakeet-ultra/
adb shell 'cd /data/local/tmp/parakeet-ultra && LD_LIBRARY_PATH=. ./ultra_asr_runner_p --accel gpu --gpu-precision fp16 --libdir . \
  --model parakeet_ultra_encoder_30s_f16.tflite --mel parakeet_ultra_mel_30s.tflite \
  --model10 parakeet_ultra_encoder_10s_f16.tflite --mel10 parakeet_ultra_mel_10s.tflite \
  --model20 parakeet_ultra_encoder_20s_f16.tflite --mel20 parakeet_ultra_mel_20s.tflite \
  --dec parakeet_ultra_decoder_i8.tflite --mel-threads 2 --dec-threads 1 --pipeline 1 \
  --fixtures audio --count $(grep -c . audio/index.tsv) --rounds 0 --dump none --out out' > out.jsonl

To remove everything from the phone: adb shell rm -rf /data/local/tmp/parakeet-ultra.

Accuracy

Word error rate (%) of the NPU form on a Galaxy S26 (the f16 encoders on the NPU, the int8 decoder on the CPU), against the PyTorch reference. The reference is transformers 5.20.2 ParakeetForTDT in float32 with the checkpoint's float16 weights raised to float32, the same 30 s windows with a valid-length mask, and the same greedy TDT decoding. LibriSpeech test-clean: every utterance; FLEURS: every utterance of the test split, scored against the Open ASR Leaderboard's text column. In the table, the first pair of WER columns is scored as the Open ASR Leaderboard scores (its English or multilingual normalizer, compound merging, kaldialign), the (jiwer) pair is plain corpus WER (jiwer) on the normalized text, without the compound merging.

set utterances WER, Galaxy S26 NPU WER, PyTorch reference WER (jiwer), Galaxy S26 NPU WER (jiwer), PyTorch reference
LibriSpeech test-clean 2,620 1.417 1.426 1.791 1.796
FLEURS German 862 3.518 3.528 4.360 4.386
FLEURS French 676 4.264 4.215 4.531 4.492
FLEURS Russian 775 4.165 4.113 4.463 4.443

Every backend on the 655-utterance LibriSpeech subset of the performance table, same scoring (reference 1.532 / 1.952):

phone, backend WER WER (jiwer)
Galaxy S26, NPU 1.479 1.914
Galaxy S26, GPU 1.471 1.891
Galaxy S26, CPU 1.487 1.906
Pixel 8a, CPU 1.471 1.906

Performance

phone backend RTF Γ— real time encoder per call, 30 / 20 / 10 s window (ms) mel, 30 s (ms) TDT decoding of a 30 s window (ms) peak memory
Galaxy S26 NPU (Hexagon, f16, --pipeline 1) 0.008713 115Γ— 163.9 / 79.6 / 39.4 3.9 18.6 4.90 GB (4,784,544 kB)
Galaxy S26 GPU (Adreno, f16, fp16 arithmetic, --pipeline 1) 0.025549 39Γ— 156.7 / 107.5 / 60.2 3.6 15.1 7.32 GB (7,151,700 kB)
Galaxy S26 CPU (i8, 8 threads, --pipeline 0) 0.029238 34Γ— 288.8 / 247.1 / 123.1 6.1 31.6 4.51 GB (4,403,600 kB)
Pixel 8a CPU (i8, 8 threads, --pipeline 1) 0.099290 10Γ— 1120.8 / 815.8 / 410.7 39.3 73.7 4.39 GB (4,284,992 kB)
  • RTF = rtf_wall: the wall clock of a run from the first window's start to the last window's end over the audio time, the model load and one warm-up utterance excluded, for 655 LibriSpeech test-clean utterances (4,875.8 s of audio) run one after another in one process with ultra_asr_runner_p as in "Use it" (the mel graphs at 2 threads, the decoder at 1). The windows went 504 / 131 / 23 to the 10 / 20 / 30 s graphs. Each row is the faster --pipeline setting on that phone and backend, the mean of its two runs (the GPU: one run).
  • --pipeline 1 against --pipeline 0 (RTF): NPU 0.008713 against 0.011279 (one session, in the order 0, 1, 1, 0), GPU 0.025549 against 0.025714 (one session, 0 then 1), Galaxy S26 CPU 0.029363 against 0.029238 (one session, 0, 1, 1, 0), Pixel 8a CPU 0.099290 against 0.106763 (two sessions, 0 then 1 and 1 then 0). A session heats the phone: the Galaxy S26's CPU ran its first --pipeline 0 run at 0.026286 and its last at 0.032190.
  • GPU row. In the --pipeline 0 GPU run (655 utterances, started at thermal status 1) the 30 s windows took a median 152.2 ms, close to the 156.7 ms per call, but the 20 s and 10 s windows 206.6 and 148.6 ms, against 107.5 and 60.2 ms per call (its first three 10 s windows: 56.5–56.9 ms); in the table's run (--pipeline 1, started at thermal status 2, right after it) the 10 s windows took 151.1 ms. We have not found the cause. The NPU's 10 s windows took a median 41.8 and 41.3 ms in its two runs, against 39.4 ms per call.
  • Per call: the median of 20 calls after 3 warm-up calls, input write and output read included, on LibriSpeech test-clean 8230-279154-0043 (24.5 s: its 30 s window with 306 valid encoder frames, and its first 20 s and 10 s), each run started from a phone at rest (thermal status 0, no CPU frequency cap). The phones capped the CPU clocks within seconds (the Galaxy S26 to 1.79 / 1.75 GHz, the Pixel 8a to 1.328 / 1.065 / 1.164 GHz), so the CPU numbers are sustained ones; the NPU and GPU calls also ran under a CPU cap.
  • Peak memory: the runner's VmHWM during the 655-utterance run (GB = kB Γ— 1024 / 10⁹; of a row's two runs, the larger).
  • Galaxy S26 (SM-S942Q, Android 16) and Pixel 8a (Tensor G3, Android 16); LiteRT 2.3.0 from Google's Maven; on the NPU the QNN libraries of QAIRT 2.50.0.260828 for Hexagon v81; 2026-10-31.

Notes

  • First NPU run. On a Galaxy S26 the on-device compile took 53–97 s for the 30 s and 20 s encoders and 133–212 s for the 10 s encoder (one encoder per process; six runs, 18 compiles), and each compiled encoder takes 1.2 GB in the cache folder; a later run loads each of the three from the cache in 1.0–3.1 s. While one encoder compiles, the runner's peak memory is 4.1–6.4 GB (VmHWM 4,006,372–6,257,444 kB over the 18 compiles), and the phone's available memory went down to 1.22 GB (1,190,060 kB) in one of them. Start the first NPU run fresh, with other apps closed.
  • GPU and fp16. In the checkpoint's encoder the squared deviation inside the first LayerNorm reaches 105,534,752 over the 95 windows of our range check, beyond float16's largest value 65,504. The f16 encoders scale each of the 120 LayerNorm inputs by 2^-k (k = 3–9 per norm) and its epsilon by 4^-k, which leaves the float32 result bit-identical and keeps every square in range (1,022.5 at most over the same windows); the GPU (float16 arithmetic) and the NPU run these files.
  • Pixel 8a GPU. The three f16 encoders do not run together on the Pixel 8a's GPU in our test: our harness stops a run at the first memory reading under 400,000 kB available, and the second encoder's GPU setup read 46,440 kB. One 30 s f16 encoder alone runs, but it pads every window to 30 s (504 of the 658 windows fit the 10 s graph), so it took longer than the i8 encoders in our runs (the summed encoder time over the same 655 utterances 0.107698 of the audio time, against 0.085992 for the i8 encoders; the GPU run started with the CPU clocks capped by an earlier run).
  • int8 decoder. The decoder's weights are int8, one scale per output channel, with int8 activations computed at run time (dynamic range), as in the i8 encoders. Against the float32 decoder (Mac CPU, float32 encoders) it gives the same token sequence on 77 of the 83 windows of our 82-utterance test subset, and the same WER on it.
  • int8 encoders. The i8 encoders are lossy (the checkpoint is float16, not ternary like parakeet-redux): on a Mac CPU their WER is at most 0.164 points above the reference on the four sets of the accuracy table (FLEURS Russian: 4.264 / 4.607 against 4.113 / 4.443). Their depthwise convolutions stay float32 so that XNNPACK runs them: with int8 depthwise filters (dynamic range), LiteRT 2.3.0 ran those 27 nodes on TFLite's own kernels, and 3,360 of the encoder's 3,390 nodes in XNNPACK in 55 partitions; as shipped, 3,387 in 3.
  • Converted from the weights of transformers 5.20.2's ParakeetForTDT (the float16 weights raised to float32), rewritten as plain PyTorch graphs (masks as float arithmetic, the LSTM step as explicit gates) and exported with litert-torch 0.9.4; the steps and scripts are in hf-to-litertlm (REPRODUCE.md, parakeet-ultra).

License

The model files are under CC-BY-4.0, as moondream/parakeet-ultra and NVIDIA's parakeet-tdt-0.6b-v3 are. The runner and the scripts (ultra_asr_runner_p.cc, build_android.sh, tdt_text.py) are under the Apache License 2.0.

Downloads last month
-
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for litert-community/parakeet-ultra

Quantized
(39)
this model