Parakeet TDT Generated-C Transcription

CKE generates the Parakeet frontend, complete encoder, and TDT decoder as native model code. A C transcription host invokes the generated model and decodes its token output without a Python runtime. Earlier Python-orchestrated native-kernel measurements remain reference evidence, not measurements of this generated path. Diarization remains a separate milestone.

Current claim boundary
Generated C now owns the frontend, full 24-block encoder and TDT decoder; a native C host performs windowing and token decoding. The historical Python reference matched all 50 short-fixture token/duration decisions, repeated the five-minute runs and completed 17 windows of a 2,542-second recording. Those measurements are not generated-path benchmarks. Generated-path numerical and long-audio claims must cite their own artifact-specific certification. Multilingual quality, concurrent-session isolation, and diarization remain open.

Status: implemented, tested, planned

CapabilityStateEvidence
safetensors → BUMPWGT5 conversion (--arch parakeet_tdt)Implemented + tested699 inference tensors mapped, 24 BatchNorm training counters explicitly excluded, 0 unaccounted; native E2E report
Native FP32 WAV → transcript (frontend, 24-layer encoder, LSTM prediction, joint, greedy TDT)Implemented + tested50/50 token IDs, 50/50 durations, transcript, and 44/44 timestamp entries exact vs pinned Transformers on the short fixture (native residual-add/argmax path, commit d3a6a8e55); kernel oracles in make test-audio; contracts in make test-audio-v8-contracts
Frontend/encoder numerical parity thresholdsImplemented + testedfrontend RMSE 4.06e-4 (gate 5e-4), encoder RMSE 9.08e-6 (gate 2e-5), first-step joint logits finite
Transcript detokenization (Metaspace BPE, 8,192 entries + blank)Implemented + testedtranscript_exact check passes on the short fixture; detokenization uses the tokenizers package, so a missing package records null while token IDs stay exact
Word-level timestamps (cumulative duration × 0.08 s, punctuation-collapsed)Implemented + tested44/44 short-fixture entries exact; 1,296 monotonic entries on the five-minute fixture; monotonic across all 17 windows of the 2,542-second run
Long audio (five-minute, 42-minute) with bounded overlapping windowsImplemented + testedtwo five-minute full-attention runs identical (1,702 steps, WER 10.43% vs the 690-word reference, RTF 1.23); two overlapping-window runs identical (700 words, WER 7.25%, RTF 0.771); 2,542 s recording completes 17/17 windows at RTF 0.847 with resume-unchanged output (no aligned transcript, no WER): five-minute, chunking, 42-minute certifications
Non-16 kHz input / resamplingTested, synthetic onlya synthetic 48 kHz stereo transform of the short fixture reproduces the 16 kHz trajectory after CKE windowed-sinc resampling; real-world resampling quality is not certified
Multilingual speech, silence robustnessNot testedall retained evidence is English; no silence-specific fixture
Streaming / partial hypotheses, concurrent sessionsNot implementedthe decode loop is offline over the complete encoder memory; the bounded window policy resets encoder/decoder state per window, which is not streaming; TDT's architecture permitting streaming is not a CKE streaming claim
Generated-circuit execution (IR-lowered generated C, as in the Whisper lane)Implementedfrontend, complete encoder schedule, and TDT decoding execute through generated libmodel.so; ck-audio-transcribe-v8 is the native host. The host-math inventory describes the earlier Python reference path.
Speaker diarizationSeparate capabilityout of scope for this model lane; diarization is a separate milestone that first integrates with the Whisper path, not a Parakeet transcription feature
Training / fine-tuningNot implementedinference-only providers; BatchNorm runs in frozen inference mode

How audio becomes text

The pipeline has four compute stages plus a decode state machine declared in the Parakeet circuit. The generated libmodel.so owns their execution; the native C host supplies WAV windows and consumes token output. run_parakeet_native_v8.py remains a separate Python-orchestrated reference for diagnosis. The frontend turns PCM samples into 128-bin log-mel frames; three stride-2 grouped Conv2D stages subsample 743 live frames to a 93×1024 token grid; 24 FastConformer blocks and a 1024→640 projection produce the 93×640 encoder memory; the transducer loop then walks that memory frame by frame.

1. frontend - WAV to log-mel features WAV PCM16 mono 16 kHz 16-bit pre-emphasis x[t]-0.97x[t-1] STFT power 512 / win 400 / hop 160 Slaney log-mel 128 bins, ln(x+2^-24) per-feature norm sample var, live frames features 744 x 128 audio_wav_decode_pcm16_mono_f32 | audio_preemphasis_f32 | audio_stft_power_centered_window_f32 | audio_whisper_mel_filters_slaney_f32 + audio_log_mel_time_major_f32 | audio_feature_normalize_per_feature_f32 2. encoder - FastConformer memory Conv2D subsampling 3x stride-2 grouped, x8 743 -> 93 frames 24 x FastConformer block (width 1024, 8 heads) 0.5 x FFN rel-pos MHSA conv module 0.5 x FFN LayerNorm audio_relative_sinusoidal_position_f32 + audio_conformer_relative_attention_f32 audio_conv1d_channel_major_grouped_f32 + audio_glu_split + audio_batch_norm_inference encoder projector 1024 -> 640 gemm + bias memory 93 x 640 3. transducer - token and duration decisions (greedy TDT) encoder[t] 640-vec row joint network add + ReLU + head 8198 two argmaxes token 0..8192 | dur 0..4 TDT advance rule blank + dur 0 -> advance 1 else frame += dur nonblank dur 0 -> hold frame stop when frame >= 93 prediction network embed + 2x LSTM 640 (h,c session) runs only after a nonblank token token IDs 44 nonblank / 50 Metaspace BPE tokenizer.json -> text audio_lstm_step_f32 (IFGO gate order, 4H caller scratch) loop bound: 10 symbols/frame x 93 frames Worked example (recorded native trajectory): step 1: f=0 blank d=0->1 forced | step 2: f=1 blank d=4 -> f=5 | step 3: f=5 id499 d=1 -> f=6 | step 4: f=6 id530 d=2 -> f=8 ... step 49: f=92 blank d=1 -> f=93 stop | sum(d) = 93 frames x 0.08 s = 7.44 s covers the 7.435 s clip Evidence (PRs #503, #504): native FP32 run from BUMPWGT5 weights - 50/50 token IDs and 50/50 durations exact vs the pinned Transformers reference (commit 909a2c164). Caveats: diagram depicts the 7.435 s fixture trajectory; deterministic five-minute and bounded 42-minute runs also pass (PR #507); multilingual, real-world resampling quality, streaming, concurrency, diarization untested.
click / tap the diagram to expand

Stage-to-artifact map

Every stage binds to declared artifacts: the circuit block, the selected providers, the kernel-map contracts, and the documentation that explains that layer of the system. Kernel maps are the resolver-facing contracts described in Kernel Maps — anatomy; provider math for the shared frontend family is walked stage by stage in the Audio Kernels Deep Dive.

StageCircuit blockSelected providersKernel map / contractDocs
PCM decode, pre-emphasis, STFT, log-mel, normalizefrontendaudio_wav_decode_pcm16_mono_f32, audio_preemphasis_f32, audio_stft_power_centered_window_f32, audio_whisper_mel_filters_slaney_f32, audio_log_mel_time_major_f32, audio_feature_normalize_per_feature_f32version/v8/kernel_maps/audio_*.jsonAudio deep dive (same provider family, Whisper context; log-mel contract split)
Grouped Conv2D subsampling + projectionencoder.subsamplingaudio_conv2d_whc_grouped_f32, relu_forward_inplace, gemm_nt_f32_llama_production_parallel_dispatchaudio_conv2d_whc_grouped_f32.jsonResolution algorithm
Relative positions + Transformer-XL attentionencoder.fastconformer_blocksaudio_relative_sinusoidal_position_f32, audio_conformer_relative_attention_f32 (PR #504; head-parallel since PR #507 with one caller-owned score row per head, no heap)audio_relative_sinusoidal_position_f32.json, audio_conformer_relative_attention_f32.jsonv8 numerical contracts; how this kernel works
Convolution module (pointwise → GLU → depthwise → BatchNorm → SiLU → pointwise)encoder.fastconformer_blocksaudio_conv1d_channel_major_grouped_f32 (new, optional bias), audio_glu_split_channel_major_f32, audio_batch_norm_inference_channel_major_f32 (new), recurrent_silu_forwardaudio_conv1d_channel_major_grouped_f32.json, audio_batch_norm_inference_channel_major_f32.jsonCohere kernel story (the Transcribe provider foundation these extend); how this kernel works
Macaron FFN halves, five LayerNorm sites, residual adds, encoder projectorencodergemm_nt_f32_llama_production_parallel_dispatch, recurrent_silu_forward, layernorm_naive_serial_matched_precision, audio_scaled_residual_add_f32 (scaled and unscaled residual adds, PR #507)existing FP32 exact maps + audio_scaled_residual_add_f32.jsonv8 kernel architecture
Prediction network (embedding + 2-layer LSTM + projector)transduceraudio_lstm_step_f32 (new in PR #504; PyTorch IFGO gate order, session-owned h/c state, caller-owned 4H gate scratch)audio_lstm_step_f32.jsonTDT decode below; how this kernel works
Joint add + ReLU + 8198-wide headtransducerrelu_forward_inplace, gemm_nt_f32_llama_production_parallel_dispatchexisting FP32 exact maps—
Greedy TDT state machine, argmax decisions, detokenization, timestampstransducer.tdt_greedy_stepgenerated model TDT decode with audio_argmax_first_f32 for deterministic argmax; native host token decoding. ParakeetSession.decode and the Python tokenizers package belong to the older reference path.circuit contract keys blank_token_id, durations, max_symbols_per_step + audio_argmax_first_f32.jsonTokenizer docs

The frontend, complete encoder schedule, and TDT decoder lower through IR into generated C in libmodel.so. The native host invokes ck_model_transcribe_audio_wav and native token decoding. The earlier ctypes session is retained as a diagnostic reference; its results do not certify generated-path performance. Codegen and X-Ray apply to the generated components.

audio_fastconformer_block_f32 is an explicit composite provider. Its declared subgraph is two half-scaled feed-forward branches, relative attention, the convolution module, residuals, and final LayerNorm. It fixes the current FP32 internal providers and rounding boundaries, requires caller-owned scratch, permits declared input/output aliasing, and exposes the block boundary rather than every fused internal tensor. No backward implementation is claimed; an unfused diagnostic or future backward path must implement the same declared subgraph contract.

TDT decode: blank handling and time advancement

The greedy TDT loop holds an LSTM hidden/cell state, a current token (initially blank 8192), a reused decoder projection cache, and a frame index into the 93-row encoder memory. The generated path owns this loop; ParakeetSession.decode is its historical reference. Each iteration:

  1. Prediction network, conditionally. The two-layer LSTM is stepped only when the previously emitted token was nonblank (or on the first iteration). After a blank, the cached decoder projection is reused unchanged — blank frames do not advance the language-model state.
  2. Joint. The current encoder row and the decoder projection are summed, passed through ReLU, and projected to 8,198 logits: 8,193 token logits (vocabulary 0–8191 plus blank 8192) followed by 5 duration logits.
  3. Two independent argmaxes. The token is the argmax of the token logits; the duration is durations[argmax(duration_logits)] with the checkpoint's table [0, 1, 2, 3, 4].
  4. Advance rule. If the token is blank and the predicted duration is 0, the duration is forced to 1 — a blank may never freeze the loop. A nonblank token with duration 0 is legal and holds the frame (multiple symbols on one encoder frame, bounded by max_symbols_per_step = 10). The frame index then advances by the duration.
  5. Termination. The loop stops when the frame index reaches 93 (the encoder length). A hard bound of 10 × 93 = 930 steps raises TDT decoder exceeded its encoder-derived step bound instead of looping forever.
tdt greedy decode - the state machine (state: frame f, last token, lstm h/c, decoder projection cache) loop state frame f (0 .. 93) last token (init: blank 8192) lstm h[2,640], c[2,640] cached decoder projection [640] 1. joint (always runs) relu(encoder[f] + cache) -> head GEMM 8198 logits = 8193 token + 5 duration blank = id 8192 runs even when the cache is reused 2. two independent argmaxes token = argmax(logits[0:8193]) d = durations[argmax(logits[8193:8198])] durations table [0, 1, 2, 3, 4] audio_argmax_first_f32 - first-index ties blank + d=0 (forced) d := 1 - a blank may never freeze the loop f += 1 | cache kept no LSTM step blank + d>0 f += d | cache kept no LSTM step skips silence fast: recorded step 2 jumps f=1 -> 5 nonblank + d=0 (hold) frame f held LSTM step: h/c + cache updated multiple symbols on one frame, bounded by max_symbols = 10 nonblank + d>0 f += d LSTM step: h/c + cache updated the common emit-and-move: 44 of 50 recorded steps emit next iteration loop while f < 93 - stop when f >= 93, then detokenize (Metaspace BPE) and emit timestamps hard bound: 10 x 93 = 930 steps - exceeding it raises "TDT decoder exceeded its encoder-derived step bound" Execution: generated TDT loop and native host; reference: ParakeetSession.decode; circuit: blank_token_id, durations, max_symbols_per_step. Evidence: 50/50 token IDs and 50/50 durations exact vs the pinned Transformers reference; the worked-trajectory strip lives in the architecture diagram above.
click / tap the diagram to expand

Worked example from the recorded native trajectory (see the diagram strip): the first two steps are blanks — step 1 predicts duration 0, forced to 1; step 2 predicts duration 4, skipping frames 1–4 (leading silence). Step 3 emits token 499 at frame 5, and only then does the LSTM step. Across the clip, 6 of the 50 recorded entries are blank (including the initial state), 44 are emissions, and the durations sum to exactly 93 frames × 0.08 s = 7.44 s of coverage for the 7.435 s clip. Token timestamps are emitted as cumulative duration × 0.08 s with the reference processor's punctuation-collapsing refinement (decode_token_timestamps); the short fixture matches all 44 reference timestamp entries exactly.

Runbook: reproduce the certified path

Choose the execution path. The current cks-v8-run audio convenience command dispatches Parakeet to the Python-orchestrated reference long-audio runner. It is useful for conversion and diagnostics, but is not the standalone generated-C path. For that path, build the generated model bundle and invoke the native host below. The historical runbook and its measurements are retained for reference.

Supported checkpoint. Exactly one: nvidia/parakeet-tdt-0.6b-v3 revision 541d1f99...defd82b (CC BY 4.0), converted with --arch parakeet_tdt --dtype fp32. Other revisions or dtypes are outside the certified claim.

Input requirements. Mono, 16 kHz, 16-bit PCM WAV (RIFF). Anything else is rejected with Parakeet frontend currently requires mono 16-bit PCM WAV at 16000 Hz; normalize first, e.g. ffmpeg -i in.mp3 -ac 1 -ar 16000 -c:a pcm_s16le out.wav. The committed fixture version/v8/test_assets/parakeet_tdt_0_6b_v3/2086-149220-0033.wav is the certified input.

Step 1 — download the pinned checkpoint (cold, once, ~2.4 GB):

hf download nvidia/parakeet-tdt-0.6b-v3 \
  --revision 541d1f99c6b0c3cd0b11a95167540bb8edefd82b \
  --local-dir .ck_models/parakeet-tdt-0.6b-v3

Step 2 — convert to BUMPWGT5 (cold, once): writes weights.bump (2,508,517,458 bytes in the recorded run), config.json, and weights_manifest.json. Conversion time is one-time setup cost and is excluded from the warm transcription timings below.

python version/v8/scripts/convert_safetensors_to_bump_v8.py \
  --checkpoint .ck_models/parakeet-tdt-0.6b-v3 \
  --output .ck_build/parakeet-tdt-0.6b-v3/weights.bump \
  --config-out .ck_build/parakeet-tdt-0.6b-v3/config.json \
  --manifest-out .ck_build/parakeet-tdt-0.6b-v3/weights_manifest.json \
  --arch parakeet_tdt --dtype fp32

Generated-C native host. With a Parakeet runtime bundle already compiled from the circuit and BUMP weights (libmodel.so, weights.bump, weights_manifest.map, and its declared native dependencies), build and run the C host. The optional final arguments set window and overlap seconds. The host requires mono PCM16 WAV at 16 kHz and emits JSON.

make ck-audio-transcribe-v8
./build/ck-audio-transcribe-v8 \
  /path/to/parakeet-runtime/libmodel.so \
  /path/to/parakeet-runtime/weights.bump \
  /path/to/parakeet-runtime/weights_manifest.map \
  recording.wav 180 30

The standalone generated-path certifier is certify_parakeet_generated_tdt_v8.py; its tests include tests/test_v8_parakeet_generated_tdt.py. Artifact-specific output quality and long-audio speed require the corresponding generated-runtime report.

Historical Python reference, step 3 — build the native kernel libraries (cold, once per checkout):

make build/libckernel_engine.so libckernel_audio.so

Historical Python reference, step 4 — run transcription (warm):

python version/v8/scripts/run_parakeet_native_v8.py \
  --model .ck_build/parakeet-tdt-0.6b-v3 \
  --audio version/v8/test_assets/parakeet_tdt_0_6b_v3/2086-149220-0033.wav \
  --fixture docs/notes/artifacts/parakeet_tdt_0_6b_v3_2086-149220-0033_fp32.npz \
  --decode --output .ck_build/parakeet-tdt-0.6b-v3/native-e2e.json

--fixture and --decode turn the run into a certification: without them the runner still transcribes but has nothing to compare against. --stop-after-layer -1|0|23 bisects the encoder against fixture boundaries for debugging.

Output format. The report ("kind": "cke.parakeet.native_e2e") records runtime-library and weight SHA-256 provenance, per-stage seconds, frontend/encoder/first-logit RMSE comparisons, the full token-ID and duration sequences, the first divergent index for each, the detokenized transcript, punctuation-collapsed token timestamps, a checks map (including transcript_exact and timestamps_exact when a reference is supplied), and an overall "status": "pass". The recorded evidence is the committed native residual/argmax E2E report (44/44 timestamps exact).

Reference-path evidence and warm timing, not generated-C performance. On the recorded run (commit 909a2c164, PR #504, Ryzen 9 9950X3D per the README evidence table, FP32, workload = the 7.435-second fixture; the report JSON records platform and Python 3.14.4 but not thread count): frontend 0.069 s, encoder 1.027 s, total run 2.25 s including hashing, decode, and tokenizer work that sit outside the two stage timers. Expected output transcript: “Well, I don't wish to see it any more, observed Phoebe, turning away her eyes. It is certainly very like the old portrait.”

Verification status of this runbook. The checkpoint is not in the local model cache on this machine, so the commands above are verified-by-CI/evidence, not re-executed here: argument names are checked against the scripts' argparse definitions, and the expected outputs are the committed artifacts. Ordinary CI coverage is make test-audio (which runs unittest/test_audio_encoder.py PyTorch oracles for the Parakeet providers) and make test-audio-v8-contracts (which runs tests/test_v8_parakeet_inventory.py and tests/test_v8_parakeet_native.py). The full-checkpoint, five-minute, and 42-minute runs have no nightly job; the committed reports are cached Ryzen evidence from the PR #504/#507 validation runs.

When it fails: where to look

SymptomLikely causeWhere to look
Conversion exits with a mapping/coverage errorcheckpoint revision drift; a tensor the strict parakeet_tdt map does not ownversion/v8/model_maps/safetensors_ck_map.json (architectures.parakeet_tdt); tests/test_v8_parakeet_native.py::test_complete_checkpoint_mapping_has_no_silent_leftovers encodes the 699+24 split; conversion audit JSON (--audit-out)
expected BUMPWGT5 header or manifest errorsrunner pointed at an unconverted or partially converted model directoryrerun step 2; the runner reads weights_manifest.json entries and memmaps weights.bump
Parakeet native FP32 path cannot load ...weights converted at a non-FP32 dtypere-convert with --dtype fp32; only FP32 is certified
WAV rejected before any computewrong channels/rate/depth, or a non-PCM containernormalize with the ffmpeg line in the runbook; audio_wav_parse_memory status codes surface the exact rejection
frontend_rmse_at_most_5e_4 check failsfrontend drift (window, epsilon, or normalization mismatch)report's frontend block (max_abs/mean_abs/RMSE); stage math in Audio Kernels Deep Dive; fixture arrays frontend.* in the NPZ
encoder_rmse_at_most_2e_5 check failsa FastConformer block diverged (attention, conv module, BatchNorm)bisect with --stop-after-layer -1 (subsampling), 0, 23 against encoder.subsampling, encoder.layer.0, encoder.layer.23 fixture boundaries; provider oracles in unittest/test_audio_encoder.py
sequences_equal/durations_equal falsedecode-state or joint-head mismatch late in the networkreport's first_divergent_sequence/first_divergent_duration index; joint.first_logits comparison isolates the joint head; LSTM oracle check_lstm_step in unittest/test_audio_encoder.py
TDT decoder exceeded its encoder-derived step boundjoint never advancing the frame (pathological duration-0 emissions)inspect recorded durations in the report; the bound is max_symbols_per_step × encoder frames from config.json
full-attention run fails closed on long inputthe diagnostic runner exceeds the checkpoint's 5,000-position limituse the bounded overlapping-window policy through the reference front door (180 s windows, 30 s overlap, per-window state reset); resume with --resume — reports resume only at completed window boundaries
transcript is null but token IDs matchtokenizers package not installed in the environmentinstall tokenizers; certification is at token-ID level and does not require it
want per-operation build/selection reasoning—X-Ray, the resolution algorithm, and Codegen's failure table explain the generated path; the historical ctypes reference remains useful for differential diagnosis

Frozen reference

Checkpoint
nvidia/parakeet-tdt-0.6b-v3
541d1f99...defd82b
CC BY 4.0
Reference code
Transformers commit 66799f45...
FP32 eager CPU
Model shape
24-layer FastConformer, width 1024
2-layer LSTM, width 640
723 tensors, 2,508,311,120 bytes
Decoder
8,193 token logits including blank 8192
durations [0, 1, 2, 3, 4]
0.08-second encoder frames

The checkpoint metadata says 5.6.0.dev0. The released v5.6.0 source does not contain ParakeetForTDT, so certification pins the executable source commit directly.

First reference fixture

The 7.435-second mono 16 kHz utterance 2086-149220-0033.wav is the sample linked by NVIDIA's model card and comes from the CC BY 4.0 LibriSpeech corpus. On Ryzen with PyTorch 2.13.0+cpu, 16 threads, and the pinned Transformers commit, the reference completed in 0.39 seconds and produced 50 decode steps, 44 nonblank emissions, durations, and token timestamps.

Well, I don't wish to see it any more, observed Phoebe, turning away her eyes. It is certainly very like the old portrait.

The compressed tensor fixture retains audio, normalized frontend features and mask, subsampling, encoder layers 0 and 23, projected encoder output, initial decoder output, all 8,198 first-step joint logits, generated token IDs, and durations. Every recorded array is finite and has an independent content hash.

Historical Python-reference execution evidence

The short native path converts all 699 inference tensors to BUMPWGT5 and excludes 24 BatchNorm training counters explicitly. On Ryzen, the frontend, all 24 FastConformer blocks, prediction network, joint network, greedy TDT decoder, tokenizer, and token timestamps complete without importing PyTorch or Transformers. The retained short result matches 50 of 50 token IDs, 50 of 50 durations, the decoded transcript, and all 44 timestamp entries.

The five-minute fixture consumes all 4,800,000 source samples and produces a complete transcript and monotonic token timestamps. Two runs produced identical token IDs, durations, transcript, and 1,296 timestamp entries. The retained repeat took 369.19 seconds (RTF 1.23) and 2.87 GB peak RSS on Ryzen. Its WER is 10.43% against the curated 690-word transcript.

Whisper Base on the identical PCM completed in 10.19 seconds (RTF 0.034) with 5.65% WER using its per-window fallback. Whisper's default persistent-worker path failed before inference with a dynamic-module pickling error, which is retained as a separate runtime limitation. Full Parakeet attention uses one caller-owned score row per head and schedules heads independently; the provider does not allocate heap memory. The complete selected call chain still needs repeated-call allocation instrumentation before an allocation-free runtime claim.

A synthetic 48 kHz stereo transform of the short fixture also reproduces the 16 kHz mono trajectory after CKE windowed-sinc resampling. This validates the wiring and deterministic fixture transform; broader real-world resampling quality is not yet certified.

The bounded long-audio policy uses 180-second full-attention windows with 30 seconds of overlap. Encoder and decoder state reset for each window. Each word belongs to the window whose ownership region contains its timestamp midpoint; ownership regions meet at the midpoint of each overlap. Two five-minute runs produced identical 700-word trajectories, exact 0–300 second coverage, and 7.25% WER. The retained repeat took 231.19 seconds (RTF 0.771) with 3.24 GB peak RSS.

The encoder's scaled and unscaled residual additions and both TDT argmax decisions now use declared native providers. On the clean Ryzen build at commit d3a6a8e55, this path preserved all 50 reference token IDs and all 50 duration decisions exactly. The machine-readable host-math inventory distinguishes the remaining model, layout, session, and planner ownership work.

Run the reference front door

The current Python audio front door recognizes the checkpoint architecture, creates the FP32 BUMP bundle, builds native kernel libraries, and selects the reference long-audio policy. It is not the standalone generated-C host shown above. The output report can resume only at completed window boundaries.

version/v8/scripts/cks-v8-run audio \
  hf://nvidia/parakeet-tdt-0.6b-v3 \
  --wav recording.wav \
  --output build/parakeet-transcript.json \
  --resume

Original operation-reuse inventory

This table records the pre-implementation inventory from PR #503: reusable meant the provider's interface fit, candidate reuse meant an interface fit still required comparison at the named fixture boundary, and missing composition meant the mathematical pieces existed without a declared Parakeet graph. PRs #504 and #507 closed the missing provider/runtime/composition rows with the providers named in the stage map and the parakeet_tdt circuit; the dispositions below are the historical record in the inventory JSON, whose top-level status is now native_five_minute_chunked_e2e_pass.

StageRequired operationDispositionCKE foundation and exact gap
frontendPCM decode and mono conversionReusableaudio_wav_decode_memory_pcm16_mono_window_f32; audio_pcm_s16_to_mono_f32
16-bit WAV is directly covered; FLAC remains host/frontend decoding before native session input.
frontendsample-rate validation and resamplingContract extensionaudio_resample_windowed_sinc_f32
The pinned processor rejects non-16 kHz input. CKE may expose explicit resampling, but must record this policy and certify its filter separately.
frontendpre-emphasis x[t]-0.97*x[t-1]Candidate reuseaudio_preemphasis_f32
Arithmetic and first-sample rule match; real-fixture comparison remains required.
frontendcentered STFT power, n_fft=512, win=400, hop=160Candidate reuseaudio_stft_power_centered_window_f32
Use an explicit non-periodic Hann window and zero padding. Existing provider supports the shape; compare direct-DFT accumulation with torch.stft.
frontendSlaney mel filter bank, 128 binsCandidate reuseaudio_whisper_mel_filters_slaney_f32
Provider is dimension-general despite its legacy name. Compare every filter coefficient with the pinned librosa FP32 bank.
frontendnatural-log mel projectionCandidate reuseaudio_log_mel_time_major_f32
Time-major layout and ln(sum+epsilon) match structurally; freeze the pinned epsilon and accumulation tolerance.
frontendper-feature normalization over live framesCandidate reuseaudio_feature_normalize_per_feature_f32
Sample variance uses N-1 and epsilon after sqrt. Batched padding masks need composition around the provider.
encoderthree-stage grouped Conv2D subsamplingCandidate reuseaudio_conv2d_whc_grouped_f32
Covers regular, depthwise, and 1x1 stages with bias. Circuit must reproduce masking after every Conv2D and CHW/time reshapes.
encodersubsampling ReLUMap promotionrelu_forward
Kernel exists but lacks a current v8 inference kernel map; promote a narrow FP32 map or fuse only after parity.
encodersubsampling flatten and linear projectionReusablegemm_nt_fp32_exact
Optional bias is supported. Layout conversion from [C,H,W] to time-major C*W must be declared.
encoderrelative sinusoidal position encodingMissing providernone
Needs FP32 descending relative positions [T-1..-(T-1)], sin/cos interleave, and exact cast boundaries.
encoderLayerNorm at five block sitesCandidate reuselayernorm_fp32_exact
Shape fits, but existing exact contract targets ggml reduction order. PyTorch FP32 CPU parity must be measured before selection.
encoderMacaron FFN linear-SiLU-linearComposition gapgemm_nt_fp32_exact; recurrent_silu_forward
Linear provider is reusable. Standalone SiLU needs an architecture-neutral map and PyTorch FP32 numerical certification.
encoderhalf-scaled FFN residualComposition gapadd_stream_inplace
DSL needs explicit 0.5 branch scaling at both FFN residual sites with preserved operation order.
encoderTransformer-XL relative self-attentionComposition gapgemm_nt_fp32_exact; audio_relative_shift_f32
Q/K/V/O and relative-K projections reuse GEMM. Bias-u/v, content/position score composition, non-causal mask, FP32 softmax, value product, and layout contracts need a declared composite/provider.
encoderConformer pointwise/depthwise Conv1DContract extensionaudio_conv1d_channel_major_f32
Kernel covers stride/padding. Parakeet weights omit convolution bias, while the map currently requires one; bind a prepared zero bias or add an optional-bias contract.
encoderchannel-split GLUCandidate reuseaudio_glu_split_channel_major_f32
Layout and value*sigmoid(gate) match; compare libm/SLEEF behavior against pinned PyTorch.
encoderinference BatchNorm1DMissing providernone
Needs running mean/variance, affine weight/bias, epsilon, FP32 order, no training-state updates, and no per-call allocation.
encoderpadding-mask zeroing before convolutionComposition gapnone
Declare masked fill over channel-major activations; must use post-subsampling live lengths.
transducerencoder 1024-to-640 projectorReusablegemm_nt_fp32_exact
Bias is present and provider dimensions fit.
prediction8193-by-640 token embeddingCandidate reuseembedding_forward_fp32
Vocabulary includes blank id 8192. Select the FP32 variant without positional embeddings.
predictiontwo-layer 640-wide LSTM prediction networkMissing providernone
Needs prepared/session-owned hidden and cell state, PyTorch gate order and nonlinearities, explicit reset/reuse semantics, and no compute-time heap allocation.
predictiondecoder 640-to-640 projectorReusablegemm_nt_fp32_exact
Bias is present.
jointjoint encoder-plus-decoder add and ReLUMap promotionadd_stream_inplace; relu_forward
Elementwise kernels exist; ReLU needs a v8 inference map and broadcast/add shapes must be declared.
jointjoint 640-to-8198 token-duration headReusablegemm_nt_fp32_exact
Output splits into 8193 token logits and five duration logits.
decodegreedy TDT token-duration state machineMissing runtimenone
Argmax token and duration independently; blank with predicted duration zero advances by one; nonblank duration zero stays on frame; max output is bounded by encoder traversal.
decodeMetaspace BPE decodeContract extensionexisting tokenizer infrastructure
Tokenizer JSON has 8192 BPE entries with Metaspace replacement U+2581. Verify repeated tokens, blank/pad suppression, punctuation, and UTF-8 languages.
decodetoken timestampsMissing runtimenone
Cumulative duration gives frame index; frame rate is 0.08 s. Punctuation is collapsed to the previous token endpoint by the pinned processor.
conversionsafetensors to BUMP plus sidecar conversionMissing compositionconvert_safetensors_to_bump_v8.py foundation
Add strict Parakeet name/shape rules and require all 723 tensors to be consumed or explicitly classified; do not load Transformers during inference.
runtimeParakeet circuit and native sessionMissing compositionv8 circuit/lowering/runtime foundations
Add declared frontend, encoder, prediction, joint, and decode components. No model-specific branches in generic emitters and no per-call heap allocation in selected compute paths.

Implementation milestones

#MilestoneStateExit evidence
1frontend and subsampling comparisonDone (PR #504)recorded frontend RMSE 4.06e-4 vs fixture (gate 5e-4); subsampling boundary comparison available via --stop-after-layer -1.
2one FastConformer blockDone (PR #504)layer-0 boundary comparison available via --stop-after-layer 0; BatchNorm and relative-attention contracts declared in the circuit.
3full encoderDone (PR #504)recorded projected-encoder RMSE 9.08e-6 vs fixture (gate 2e-5); layer-23 boundary comparison available via --stop-after-layer 23.
4prediction, joint, and TDT decodeDone (PRs #504, #507)50/50 token IDs, 50/50 durations, transcript, and 44/44 timestamp entries exact on the short fixture; both argmax decisions use the deterministic first-index provider.
5BUMP conversion and native runnerDone (PRs #504, #507)699 mapped + 24 explicitly excluded + 0 unaccounted; inference imports no torch/transformers/safetensors (guarded by tests/test_v8_parakeet_native.py); remaining NumPy host math is tracked in the host-math inventory. Generated-circuit lowering is explicitly not part of this milestone as delivered.
6long audio and multilingual coverageIn progress (PR #507)deterministic five-minute full-attention evidence passes (1,702 steps, 1,296 timestamps, WER 10.43%, RTF 1.23) and overlapping-window evidence passes (700 words, WER 7.25%, RTF 0.771); the matched Whisper Base control passes (WER 5.65%, RTF 0.034); the complete 42-minute input passes the bounded 17-window policy at RTF 0.847 with 3.29 GiB peak RSS. Multilingual quality remains open.

New production compute paths must use planner-declared scratch or session-owned state. They may not allocate or free heap memory per call, hide allocation in helpers, substitute large stack buffers, or share mutable scratch across sessions. The Parakeet providers follow this: attention uses one caller-owned score row per head; the LSTM uses caller-owned 4H gate scratch and session-owned state (guarded by tests/test_v8_parakeet_native.py).

Reproduce the reference capture

Download the exact Hugging Face revision once into the shared model cache, then run the fixture tool. Transformers, PyTorch, librosa, and soundfile belong to this certification environment; the CKE inference path does not depend on them.

export CKE_MODEL_CACHE="$HOME/.cache/cke/models"
hf download nvidia/parakeet-tdt-0.6b-v3 \
  --revision 541d1f99c6b0c3cd0b11a95167540bb8edefd82b \
  --local-dir "$CKE_MODEL_CACHE/parakeet-tdt-0.6b-v3-541d1f99"

PYTHONPATH="$HOME/.cache/cke/reference/transformers-66799f45" \
python version/v8/scripts/capture_parakeet_reference_v8.py \
  --model-dir "$CKE_MODEL_CACHE/parakeet-tdt-0.6b-v3-541d1f99" \
  --audio version/v8/test_assets/parakeet_tdt_0_6b_v3/2086-149220-0033.wav \
  --output-json /tmp/parakeet-reference.json \
  --output-npz /tmp/parakeet-reference.npz \
  --model-revision 541d1f99c6b0c3cd0b11a95167540bb8edefd82b \
  --transformers-revision 66799f45cea7513712580c6170cdaa4438df702a

Next work

The historical Python-reference run consumed the complete 42-minute recording with overlap coverage ending at 2,542.0 seconds. Its 7,225-word output has no aligned human transcript, so this result establishes execution, coverage, timestamp, and resource behavior for that path rather than WER or generated-path speed. The full-attention diagnostic runner fails closed above the checkpoint's 5,000-position limit. Generated-C execution is now implemented separately; multilingual coverage and diarization remain separate evidence lanes.

Image
100% | |
Scroll to zoom | Drag to pan | W/H to fit | 0 to reset | ESC to close