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.
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
| Capability | State | Evidence |
|---|---|---|
safetensors → BUMPWGT5 conversion (--arch parakeet_tdt) | Implemented + tested | 699 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 + tested | 50/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 thresholds | Implemented + tested | frontend 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 + tested | transcript_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 + tested | 44/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 windows | Implemented + tested | two 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 / resampling | Tested, synthetic only | a 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 robustness | Not tested | all retained evidence is English; no silence-specific fixture |
| Streaming / partial hypotheses, concurrent sessions | Not implemented | the 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) | Implemented | frontend, 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 diarization | Separate capability | out 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-tuning | Not implemented | inference-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.
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.
| Stage | Circuit block | Selected providers | Kernel map / contract | Docs |
|---|---|---|---|---|
| PCM decode, pre-emphasis, STFT, log-mel, normalize | frontend | 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 | version/v8/kernel_maps/audio_*.json | Audio deep dive (same provider family, Whisper context; log-mel contract split) |
| Grouped Conv2D subsampling + projection | encoder.subsampling | audio_conv2d_whc_grouped_f32, relu_forward_inplace, gemm_nt_f32_llama_production_parallel_dispatch | audio_conv2d_whc_grouped_f32.json | Resolution algorithm |
| Relative positions + Transformer-XL attention | encoder.fastconformer_blocks | audio_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.json | v8 numerical contracts; how this kernel works |
| Convolution module (pointwise → GLU → depthwise → BatchNorm → SiLU → pointwise) | encoder.fastconformer_blocks | audio_conv1d_channel_major_grouped_f32 (new, optional bias), audio_glu_split_channel_major_f32, audio_batch_norm_inference_channel_major_f32 (new), recurrent_silu_forward | audio_conv1d_channel_major_grouped_f32.json, audio_batch_norm_inference_channel_major_f32.json | Cohere kernel story (the Transcribe provider foundation these extend); how this kernel works |
| Macaron FFN halves, five LayerNorm sites, residual adds, encoder projector | encoder | gemm_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.json | v8 kernel architecture |
| Prediction network (embedding + 2-layer LSTM + projector) | transducer | audio_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.json | TDT decode below; how this kernel works |
| Joint add + ReLU + 8198-wide head | transducer | relu_forward_inplace, gemm_nt_f32_llama_production_parallel_dispatch | existing FP32 exact maps | — |
| Greedy TDT state machine, argmax decisions, detokenization, timestamps | transducer.tdt_greedy_step | generated 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.json | Tokenizer 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:
- 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.
- 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.
- 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]. - 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. - Termination. The loop stops when the frame index reaches 93 (the encoder length). A hard bound of
10 × 93 = 930steps raisesTDT decoder exceeded its encoder-derived step boundinstead of looping forever.
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.”
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
| Symptom | Likely cause | Where to look |
|---|---|---|
| Conversion exits with a mapping/coverage error | checkpoint revision drift; a tensor the strict parakeet_tdt map does not own | version/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 errors | runner pointed at an unconverted or partially converted model directory | rerun 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 dtype | re-convert with --dtype fp32; only FP32 is certified |
| WAV rejected before any compute | wrong channels/rate/depth, or a non-PCM container | normalize with the ffmpeg line in the runbook; audio_wav_parse_memory status codes surface the exact rejection |
frontend_rmse_at_most_5e_4 check fails | frontend 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 fails | a 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 false | decode-state or joint-head mismatch late in the network | report'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 bound | joint 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 input | the diagnostic runner exceeds the checkpoint's 5,000-position limit | use 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 match | tokenizers package not installed in the environment | install 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
24-layer FastConformer, width 1024
2-layer LSTM, width 640
723 tensors, 2,508,311,120 bytes
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.
- Fixture report (JSON)
- Intermediate tensors (NPZ)
- Complete 723-tensor manifest (JSON)
- Operation-reuse inventory (JSON)
- Remaining host-math ownership inventory (JSON)
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.
- Exact short native report (JSON)
- Exact short report after native residual and argmax integration (JSON)
- Five-minute native report (JSON)
- Five-minute repeat and quality certification (JSON)
- Matched Parakeet and Whisper result (JSON)
- Two-window short-audio reconciliation result (JSON)
- Five-minute chunking certification (JSON)
- 42-minute certification summary (JSON)
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.
| Stage | Required operation | Disposition | CKE foundation and exact gap |
|---|---|---|---|
| frontend | PCM decode and mono conversion | Reusable | audio_wav_decode_memory_pcm16_mono_window_f32; audio_pcm_s16_to_mono_f3216-bit WAV is directly covered; FLAC remains host/frontend decoding before native session input. |
| frontend | sample-rate validation and resampling | Contract extension | audio_resample_windowed_sinc_f32The pinned processor rejects non-16 kHz input. CKE may expose explicit resampling, but must record this policy and certify its filter separately. |
| frontend | pre-emphasis x[t]-0.97*x[t-1] | Candidate reuse | audio_preemphasis_f32Arithmetic and first-sample rule match; real-fixture comparison remains required. |
| frontend | centered STFT power, n_fft=512, win=400, hop=160 | Candidate reuse | audio_stft_power_centered_window_f32Use an explicit non-periodic Hann window and zero padding. Existing provider supports the shape; compare direct-DFT accumulation with torch.stft. |
| frontend | Slaney mel filter bank, 128 bins | Candidate reuse | audio_whisper_mel_filters_slaney_f32Provider is dimension-general despite its legacy name. Compare every filter coefficient with the pinned librosa FP32 bank. |
| frontend | natural-log mel projection | Candidate reuse | audio_log_mel_time_major_f32Time-major layout and ln(sum+epsilon) match structurally; freeze the pinned epsilon and accumulation tolerance. |
| frontend | per-feature normalization over live frames | Candidate reuse | audio_feature_normalize_per_feature_f32Sample variance uses N-1 and epsilon after sqrt. Batched padding masks need composition around the provider. |
| encoder | three-stage grouped Conv2D subsampling | Candidate reuse | audio_conv2d_whc_grouped_f32Covers regular, depthwise, and 1x1 stages with bias. Circuit must reproduce masking after every Conv2D and CHW/time reshapes. |
| encoder | subsampling ReLU | Map promotion | relu_forwardKernel exists but lacks a current v8 inference kernel map; promote a narrow FP32 map or fuse only after parity. |
| encoder | subsampling flatten and linear projection | Reusable | gemm_nt_fp32_exactOptional bias is supported. Layout conversion from [C,H,W] to time-major C*W must be declared. |
| encoder | relative sinusoidal position encoding | Missing provider | noneNeeds FP32 descending relative positions [T-1..-(T-1)], sin/cos interleave, and exact cast boundaries. |
| encoder | LayerNorm at five block sites | Candidate reuse | layernorm_fp32_exactShape fits, but existing exact contract targets ggml reduction order. PyTorch FP32 CPU parity must be measured before selection. |
| encoder | Macaron FFN linear-SiLU-linear | Composition gap | gemm_nt_fp32_exact; recurrent_silu_forwardLinear provider is reusable. Standalone SiLU needs an architecture-neutral map and PyTorch FP32 numerical certification. |
| encoder | half-scaled FFN residual | Composition gap | add_stream_inplaceDSL needs explicit 0.5 branch scaling at both FFN residual sites with preserved operation order. |
| encoder | Transformer-XL relative self-attention | Composition gap | gemm_nt_fp32_exact; audio_relative_shift_f32Q/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. |
| encoder | Conformer pointwise/depthwise Conv1D | Contract extension | audio_conv1d_channel_major_f32Kernel 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. |
| encoder | channel-split GLU | Candidate reuse | audio_glu_split_channel_major_f32Layout and value*sigmoid(gate) match; compare libm/SLEEF behavior against pinned PyTorch. |
| encoder | inference BatchNorm1D | Missing provider | noneNeeds running mean/variance, affine weight/bias, epsilon, FP32 order, no training-state updates, and no per-call allocation. |
| encoder | padding-mask zeroing before convolution | Composition gap | noneDeclare masked fill over channel-major activations; must use post-subsampling live lengths. |
| transducer | encoder 1024-to-640 projector | Reusable | gemm_nt_fp32_exactBias is present and provider dimensions fit. |
| prediction | 8193-by-640 token embedding | Candidate reuse | embedding_forward_fp32Vocabulary includes blank id 8192. Select the FP32 variant without positional embeddings. |
| prediction | two-layer 640-wide LSTM prediction network | Missing provider | noneNeeds prepared/session-owned hidden and cell state, PyTorch gate order and nonlinearities, explicit reset/reuse semantics, and no compute-time heap allocation. |
| prediction | decoder 640-to-640 projector | Reusable | gemm_nt_fp32_exactBias is present. |
| joint | joint encoder-plus-decoder add and ReLU | Map promotion | add_stream_inplace; relu_forwardElementwise kernels exist; ReLU needs a v8 inference map and broadcast/add shapes must be declared. |
| joint | joint 640-to-8198 token-duration head | Reusable | gemm_nt_fp32_exactOutput splits into 8193 token logits and five duration logits. |
| decode | greedy TDT token-duration state machine | Missing runtime | noneArgmax 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. |
| decode | Metaspace BPE decode | Contract extension | existing tokenizer infrastructureTokenizer JSON has 8192 BPE entries with Metaspace replacement U+2581. Verify repeated tokens, blank/pad suppression, punctuation, and UTF-8 languages. |
| decode | token timestamps | Missing runtime | noneCumulative duration gives frame index; frame rate is 0.08 s. Punctuation is collapsed to the previous token endpoint by the pinned processor. |
| conversion | safetensors to BUMP plus sidecar conversion | Missing composition | convert_safetensors_to_bump_v8.py foundationAdd strict Parakeet name/shape rules and require all 723 tensors to be consumed or explicitly classified; do not load Transformers during inference. |
| runtime | Parakeet circuit and native session | Missing composition | v8 circuit/lowering/runtime foundationsAdd 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
| # | Milestone | State | Exit evidence |
|---|---|---|---|
| 1 | frontend and subsampling comparison | Done (PR #504) | recorded frontend RMSE 4.06e-4 vs fixture (gate 5e-4); subsampling boundary comparison available via --stop-after-layer -1. |
| 2 | one FastConformer block | Done (PR #504) | layer-0 boundary comparison available via --stop-after-layer 0; BatchNorm and relative-attention contracts declared in the circuit. |
| 3 | full encoder | Done (PR #504) | recorded projected-encoder RMSE 9.08e-6 vs fixture (gate 2e-5); layer-23 boundary comparison available via --stop-after-layer 23. |
| 4 | prediction, joint, and TDT decode | Done (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. |
| 5 | BUMP conversion and native runner | Done (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. |
| 6 | long audio and multilingual coverage | In 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.