Views
No views yet
CompiledModel GPU (ML Drift) — with zero FFT anywhere: the raw 16 kHz waveform goes
straight into a wav2vec2-style 1D-conv frontend (no mel/fbank even on the host), then a
Zipformer encoder (6 multi-rate stacks) and a CTC head, all in one GPU graph.
| File | Size | Input | Output | API |
|---|---|---|---|---|
ja_zipformer_ctc_fp16.tflite | 197 MB | waveform [1,256000] + 4 mask biases | CTC logits [1,799,3004] | CompiledModel GPU |
0 real / -1000 pad) at the internal frame
rates: [1,799], [1,400], [1,200], [1,100]. Build the 50 Hz bias with
valid = conv_frames(n_samples + 16000) and take [::2], [::4], [::8] slices
(conv_frames: fold L=(L-k)//s+1 over (10,5)(3,2)(3,2)(3,2)(3,2)(2,2)(2,2)).<unk> in vocab.json but it
behaves as the CTC blank — icefall convention), BPE vocab 3004 (vocab.json).1import json, numpy as np, torch, torchaudio
2from ai_edge_litert.interpreter import Interpreter
3
4wave, _ = torchaudio.load("speech_16k.wav") # 16 kHz mono, [-1,1]
5a = wave[0]; lead = 8000
6x = torch.zeros(1, 256000)
7n = min(a.shape[0], 256000 - 2 * lead)
8x[0, lead:lead + n] = a[:n]
9
10L = n + 2 * lead
11for k, s in [(10,5),(3,2),(3,2),(3,2),(3,2),(2,2),(2,2)]:
12 L = (L - k) // s + 1 # valid 50 Hz frames
13b = np.full((1, 799), -1000.0, np.float32); b[0, :L] = 0.0
14biases = {799: b, 400: b[:, ::2], 200: b[:, ::4], 100: b[:, ::8]}
15
16it = Interpreter(model_path="ja_zipformer_ctc_fp16.tflite"); it.allocate_tensors()
17for d in it.get_input_details():
18 s = list(d["shape"])
19 it.set_tensor(d["index"], x.numpy() if s[1] == 256000
20 else np.ascontiguousarray(biases[s[1]]))
21it.invoke()
22logits = it.get_tensor(it.get_output_details()[0]["index"])[0] # [799, 3004]
23
24vocab = {i: t for t, i in json.load(open("vocab.json")).items()}
25out, prev = [], -1
26for i in logits[:L].argmax(-1):
27 if i != prev and i != 0: out.append(vocab[int(i)])
28 prev = i
29print("".join(out).replace("▁", " ").strip())1val model = CompiledModel.create(modelPath, CompiledModel.Options(Accelerator.GPU), null)
2val inputs = model.createInputBuffers()
3val outputs = model.createOutputBuffers()
4
5// resolve slots by capacity: waveform 256000, biases 799/400/200/100 floats
6val waveSlot = inputs.indexOfFirst { it.readFloat().size == 256000 }
7inputs[waveSlot].writeFloat(pcm) // [-1,1], 0.5 s lead pad, zero-padded
8for (len in intArrayOf(799, 400, 200, 100)) { // additive masks: 0 real / -1000 pad
9 val slot = inputs.indexOfFirst { it.readFloat().size == len }
10 val ds = (799 + len - 1) / len
11 inputs[slot].writeFloat(FloatArray(len) { i -> if (i * ds < valid50) 0f else -1000f })
12}
13
14model.run(inputs, outputs)
15val logits = outputs[0].readFloat() // [799 * 3004], readback syncs the GPU
16// greedy CTC: per-frame argmax, drop blanks (id 0) + repeats, BPE detok ('▁' -> space)LiteRtException: Failed to invoke the compiled model. The GPU row below is the only S26 figure for it. A clean compile is not evidence that a model runs.| backend | inference (median / min) | load |
|---|---|---|
| GPU (Adreno) | 129.4 ms / 126.0 ms | 3176 ms |
CompiledModel 2.2.0, one accelerator per process, 5 warm-up runs then N=50 timed runs, median reported. The run held thermal status NONE throughout. Headroom 0.67-0.70, where 1.0 is the throttling threshold.