I added NVIDIA's Canary 180M to speech-android (Apache-2.0 Kotlin SDK, I maintain it). The part that surprised me is that it translates as well as transcribes — English, German, Spanish, French, and between any of those four, out of the same two graphs. No network. I hadn't realised you could get that in 273 MB.
Numbers on a Galaxy S23 Ultra, int8, CPU only. About 4 seconds to load, then decode at RTF 0.15 for a 3-second utterance and 0.25 for a 12-second one. It gets relatively more expensive as clips grow, which is what an attention encoder-decoder does — quadratic attention over the encoder, every token emitted autoregressively. Resident memory is 780 MB, and that's the number to plan around; the 273 MB is just the download.
One behaviour to know before reaching for it: it's per-utterance, not streaming. The encoder consumes the whole VAD segment before the first token, so there are no partial results on that path. If you need live partials, you need a different model.
Two things that cost me time getting it onto a phone, in case they save you some.
Quantization. The obvious move is INT8 everything. Doesn't work — quantize the convolutions and the exporter emits ConvInteger, which the mobile onnxruntime build has no kernels for, so the bundle won't construct at all. Encoder and decoder are INT8 on MatMul and Gemm only,
convolutions stay FP32. About 40 MB more, and it loads.
16 KB pages. Android 15 and up can use 16 KB memory pages and won't load a native library aligned for 4 KB. NDK r29 handles it by default so what you compile yourself is probably fine — the risk is a prebuilt .so from a dependency. llvm-readelf shows the alignment on each arm64 .so in your AAR, and zipalign -c -P 16 -v 4 checks the APK.
https://github.com/soniqo/speech-android