#5384: Android ASR Runtimes: LiteRT, ExecuTorch, and Why Your Phone Has No VRAM

Why does your phone have no VRAM number? A tour of Android's runtime layer and what it takes to run ASR locally.

Featuring
Listen
0:00
0:00
Episode Details
Episode ID
MWP-5567
Published
Duration
27:53
Audio
Direct link
Pipeline
V5.2
TTS Engine
chatterbox-regular
Script Writing Agent
DeepSeek v4 Pro

AI-Generated Content: This podcast is created using AI personas. Please verify any important information independently.

When you download a model from Hugging Face, you're not downloading something that runs. You're downloading weights — a graph of operations — and something has to load that file, map every operator onto whatever hardware is available, and manage memory while it does it. That something is the runtime, and on Android the runtime landscape is fragmented. LiteRT, Google's successor to TensorFlow Lite, powers AI Edge Gallery and uses an NPU delegate to route supported operators to the Tensor chip's TPU. ONNX Runtime Mobile is cross-platform with a broad operator set but often falls back to CPU on Android without a vendor execution provider. ExecuTorch is PyTorch's on-device runtime, still maturing but appealing to researchers who want to skip a separate conversion pipeline. And llama.cpp, technically an LLM runtime, has become a container for quantized ASR models in GGUF format — it runs almost anywhere, but never touches the NPU.

The reason there's no VRAM equivalent on a phone is that desktop VRAM is a single pool with a single number. On Android you're juggling system RAM, thermal headroom, memory bandwidth, NPU availability, OS process limits, and the runtime's own overhead — and any of those can fail first. They also fail differently: a model can fit in RAM and still throttle to uselessness, or run fine until the memory allocator fragments twenty minutes in.

Operator compatibility is where this gets concrete. If a model uses an operator the runtime doesn't support, it either fails to load or falls back to CPU for that layer — and a single CPU layer in the middle of a TPU-accelerated graph can tank performance by shuttling tensors across the memory bus. Parameter count is a poor sizing proxy too: a 100M-parameter model is roughly 400MB in float32 but about 100MB in int8, and the NPU has its own memory constraints separate from system RAM.

TPU-optimized models, like the ones in AI Edge Gallery for the Pixel 11's Tensor chip, are compiled for that specific silicon — lower latency and power draw, but they won't run on a Snapdragon NPU or MediaTek APU. For finding ASR models that actually work, the workflow is: filter by LiteRT or TFLite tags, read the README for an on-device deployment section, check quantization (int8 is the mobile sweet spot), prefer pre-converted tflite or onnx files, verify operators against the runtime's supported set, and stay under roughly 200 million parameters for sustained transcription on mid-range hardware.

Downloads

Episode Audio

Download the full episode as an MP3 file

Download MP3
Transcript (TXT)

Plain text transcript file

Transcript (PDF)

Formatted PDF with styling

#5384: Android ASR Runtimes: LiteRT, ExecuTorch, and Why Your Phone Has No VRAM

Corn
Daniel's been digging into on-device transcription again, and this time he's gone below the model layer entirely. He wants to talk runtimes, compatibility, what a TPU actually changes, and how to find an ASR model on Hugging Face that won't just crash your phone. He's used to sizing desktop models by VRAM, and he's noticed Android doesn't give you that same single number. He also mentions his wife picked up a Pixel 11 and has been downloading TPU-optimized variants from AI Edge Gallery, which he recommends as a quick way to test whether your device can run local models at all. Then he wants the emerging options beyond Moonshine and Parakeet, and what they're actually optimizing for.
Herman
So let's start with the layer most people never see. The runtimes that sit between the model file and the silicon.
Corn
Right. Because when you download a model from Hugging Face, you're not downloading something that runs. You're downloading weights. A graph of operations. Something has to load that file, map every operator onto whatever hardware is available, and manage the memory while it's doing it. That something is the runtime.
Herman
And Android has a fragmented runtime landscape. You've got LiteRT, which is Google's successor to TensorFlow Lite, and it's the runtime behind AI Edge Gallery. It has an NPU delegate that lets models run on the Tensor chip's TPU. Then there's ONNX Runtime Mobile, which is cross-platform and has a broad operator set, but on Android it frequently falls back to CPU unless there's a vendor-specific execution provider available. Then ExecuTorch, which is PyTorch's on-device runtime, still maturing but gaining traction because researchers can ship models without a separate conversion pipeline. And llama.cpp, which is technically an LLM runtime, but it's increasingly used for ASR models converted to GGUF, including Whisper variants.
Corn
And then the vendor stacks underneath all of that. Qualcomm's QNN, MediaTek's NeuroPilot. The things nobody wants to think about until their model loads and immediately dies.
Herman
The runtime choice often determines which models you can even attempt. A model compiled for one runtime's operator set may not load in another at all. It's not like desktop where you mostly pick PyTorch or ONNX and move on. On Android, the runtime is the first compatibility gate.
Corn
So the question Daniel's really asking is, why is there no VRAM equivalent on a phone? And the answer is that on desktop, VRAM is a single pool with a single number. You know if a model fits. On Android, you've got system RAM, but you've also got thermal headroom, memory bandwidth, NPU availability, OS-level process limits, and the runtime's own overhead. Any of those can be the thing that fails first.
Herman
And they fail differently. A model can fit in RAM and still throttle to uselessness because it's drawing too much power for sustained transcription. Or it can fit and run, but the runtime's memory allocator fragments after twenty minutes and the whole thing falls over. Desktop VRAM never does that.
Corn
So the single number was always a convenience, not a law of physics. Phones just refuse to give you the convenience.
Herman
Let's talk about LiteRT first, because it's the one most people will actually encounter. It's Google's successor to TensorFlow Lite, and the NPU delegate is the key piece. When you load a model through LiteRT with the NPU delegate enabled, the runtime partitions the graph. Operators the TPU supports get sent to the TPU. Everything else stays on CPU. The delegate is the handshake that makes that happen.
Corn
And AI Edge Gallery is built on top of this. It's Google's sandbox for trying on-device AI, and it ships TPU-optimized variants of models for Pixel devices. So when Daniel's wife downloads a TPU-optimized model in the gallery, she's getting a file that's been converted and compiled specifically for the Tensor TPU, often with int8 or int4 quantization and operator fusion tuned for that silicon.
Herman
What that means in practice is that the graph has been partitioned ahead of time. Operators are mapped to TPU-supported equivalents. The result is a tflite file with the TPU delegate baked in, so most of the compute runs on the TPU instead of the CPU. Lower latency, lower power draw. For transcription, which is a sustained workload, that's the difference between a phone that gets warm and a phone that gets hot.
Corn
ONNX Runtime Mobile is the other big one. Its strength is portability. You can take the same ONNX file and run it on Windows, Linux, iOS, Android. Broad operator set. But on Android, unless you have a vendor execution provider, it falls back to CPU. And an execution provider is just the backend that maps operators to specific hardware. Qualcomm has one for their NPU. MediaTek has one. If you don't have the right one for your chip, you're on CPU, and CPU transcription on a phone is slow.
Herman
ExecuTorch is interesting because it's PyTorch's answer to this whole mess. The pitch is that you take a model you trained in PyTorch, export it once, and run it on device without a separate conversion pipeline. That's appealing for researchers who don't want to learn TFLite's quirks. The Android support is through Java and Kotlin bindings. It's still maturing, but it's gaining traction because the friction is lower.
Corn
And llama.cpp is the odd one out. It's an LLM runtime, but the GGUF format has become a kind of universal container for quantized models, including Whisper variants. The advantage is it runs almost anywhere. The disadvantage is it doesn't use the NPU or TPU at all. It's CPU-only, maybe GPU if you're on desktop. On a phone, that means it works, but you're leaving the most efficient silicon on the device completely idle.
Herman
The operator compatibility problem is where all of this gets concrete. A model is a graph of operators. Convolutions, attention, layer norm, that kind of thing. Each runtime implements a subset. If your model uses an operator the runtime doesn't support, one of two things happens. Either the model fails to load entirely, or the runtime falls back to CPU for that layer. And a single CPU layer in the middle of a TPU-accelerated graph can tank performance, because now you're shuttling tensors back and forth across the memory bus.
Corn
So you can have a model that's ninety-five percent TPU-accelerated, and the five percent that isn't becomes the bottleneck. It's like having a highway with one traffic light in the middle.
Herman
And this is why parameter count is such a poor sizing proxy on Android. On desktop, more parameters means more VRAM, full stop. On Android, a hundred million parameter model in float32 is roughly four hundred megabytes. The same model in int8 is roughly a hundred megabytes. Same parameter count, quarter of the memory. Quantization changes the footprint dramatically. Operator fusion changes it again. And the NPU has its own memory constraints that are completely separate from system RAM.
Corn
So you could have a model that fits comfortably in system RAM and still not fit on the TPU's local memory. Or the reverse. The parameter count tells you almost nothing about either.
Herman
Whisper Tiny is the classic example. Thirty-nine million parameters. If you run it through LiteRT with int8 quantization, you're looking at roughly forty megabytes. If you run the same model through ONNX Runtime in float32, it's over a hundred and fifty megabytes. Same model. Same parameter count. And then the question of whether the encoder and decoder are split across CPU and NPU changes the latency profile entirely.
Corn
So when someone says "my phone can run a hundred million parameter model," the correct response is, which runtime, which quantization, which operators, and what's the thermal budget?
Herman
And that last one matters more than people think. Transcription isn't a benchmark. It's a sustained workload. You're not running one inference, you're running hundreds of them back to back as audio streams in. A phone that can spike to peak performance for ten seconds will throttle to half that after two minutes of continuous transcription. The TPU helps because it's more efficient per operation, but the thermal envelope is still the ceiling.
Corn
So that's the runtime layer. Now let's talk about what changes when you add a TPU to the mix, because Daniel's wife's Pixel 11 is a different deployment target than a phone without one.
Herman
The Pixel 11 uses Google's Tensor chip, which includes a dedicated TPU. And Google ships TPU-optimized model variants in AI Edge Gallery. These are models that have been converted and compiled specifically for the Tensor TPU, often with int8 or int4 quantization and operator fusion tuned for that silicon.
Corn
So when we say TPU-optimized, we mean the graph has been partitioned, operators mapped to TPU-supported equivalents, and the result is a tflite file with the TPU delegate that runs the bulk of the compute on the TPU. The payoff is lower latency and lower power draw. For transcription, that's the difference between a phone that can transcribe all day and a phone that gives you twenty minutes before it's too hot to hold.
Herman
The tradeoff is portability. A model compiled for the Tensor TPU won't run on a Snapdragon NPU or a MediaTek APU. You're trading flexibility for performance. And this is the thing people miss when they see TPU-optimized and assume it's universally better. It's better on that specific TPU. On other hardware, it may not run at all.
Corn
Which is a real consideration if you're building an app. Do you ship one model that runs everywhere but slower, or do you ship three models and detect the hardware at runtime? Most apps do the latter, but it's a build and maintenance burden.
Herman
And the fragmentation is only going to get worse as more vendors ship their own NPUs. Qualcomm has its own. MediaTek has its own. Samsung has its own. Google has the TPU. Each one has its own operator set, its own quantization preferences, its own execution provider. The runtime layer is supposed to abstract this, but the abstraction leaks constantly.
Corn
Let's get practical. Daniel asked for concrete tips on finding an ASR model on Hugging Face that will actually run on Android. What's the workflow?
Herman
First, filter by tags. Hugging Face model cards have tags, and you can filter for LiteRT or TFLite. That immediately narrows you to models that have been converted for mobile. Second, look for an Android or on-device deployment section in the README. If the model author bothered to document mobile deployment, that's a strong signal they've actually tested it. Third, check the quantization info. int8 is the sweet spot for mobile ASR. It's accurate enough for transcription and small enough to fit in NPU memory.
Corn
Fourth, look for models that ship with a tflite or onnx file directly, not just PyTorch weights. If you have to convert it yourself, you're signing up for a whole afternoon of operator compatibility debugging. Fifth, check the operator list against the runtime's supported operators. Most model cards won't list this explicitly, but if the model uses something exotic, it'll usually show up in the issues or discussions.
Herman
Sixth, prefer models with a parameter count under about two hundred million for sustained ASR on mid-range devices. That's not because the parameter count itself is the limit. It's because models in that range tend to quantize well and fit in NPU memory. Above that, you're fighting the thermal budget even if the model technically loads.
Corn
That's the discovery workflow. Filter by tags, read the README, check quantization, prefer pre-converted files, verify operators, and stay under two hundred million parameters unless you have a reason not to.
Herman
The reason not to would be something like, you need multilingual coverage and the only model that does it well is bigger. Or you're running on a flagship with a TPU and you can afford it. But for most people, the sweet spot is smaller than they think.
Corn
Now the emerging options. Daniel mentioned Moonshine and Parakeet, but the space is moving fast. The newer entrants tend to target specific tradeoffs. Some prioritize streaming, which means low-latency chunked inference. The model starts transcribing before the sentence is finished. That's critical for live captions or dictation. Others prioritize multilingual coverage. Others prioritize tiny footprint for wearables and earbuds.
Herman
Many of these ship as LiteRT or ONNX models first, with PyTorch weights as an afterthought. That's a reversal from the desktop world, where PyTorch is the default and everything else is a conversion. On mobile, the deployment format is the product.
Corn
The practical implication is that the best ASR model on Android is not the most accurate one. It's the one that fits your runtime, your silicon, and your thermal budget. Accuracy benchmarks on desktop GPUs are misleading for mobile deployment. A model that wins on a desktop benchmark might be unusable on a phone because it uses an operator the NPU doesn't support, or it's too big to quantize well, or it draws too much power for sustained use.
Herman
That's the shift in mindset. On desktop, you look at the leaderboard and pick the top model. On Android, you look at the runtime support first, then the quantization, then the accuracy. The model that wins is the one that actually runs.
Corn
What's actually out there beyond Moonshine and Parakeet? The streaming models are interesting because they're designed around the chunked inference pattern that mobile transcription needs. They don't wait for the full utterance. They process audio as it arrives and emit tokens incrementally. That's a fundamentally different architecture than batch models, and it changes what the runtime has to do.
Herman
The multilingual models are also getting better. Whisper variants with expanded language coverage, some of them distilled down to tiny sizes. The distillation is the interesting part. You train a large model, then use it to train a smaller model that mimics its outputs. You get most of the accuracy at a fraction of the size. That's how you get a forty million parameter model that transcribes twenty languages reasonably well.
Corn
Then there's the wearable-tier stuff. Models with ten or twenty million parameters that run on earbuds. Those are int4 quantized, heavily fused, and they do one thing: wake word detection plus short command transcription. Not general ASR, but the same runtime considerations apply.
Herman
What I'm watching is the convergence of streaming and multilingual. The first model that does both well at under a hundred million parameters with clean LiteRT support is going to become the default for a lot of apps. Nobody's quite there yet, but the gap is closing.
Corn
The runtime layer is the thing that determines what you can even attempt. The TPU changes the math for specific devices but fragments the ecosystem. And the discovery workflow on Hugging Face is a set of filters and signals that most people skip because they're used to desktop, where you just download the biggest model that fits in VRAM.
Herman
The thermal budget is the thing that bites you later. You can get a model running on a phone and think you're done, then find out it throttles after ten minutes of continuous transcription. The benchmark looked great. The real-world experience is a phone that's hot and a transcription that's dropping words.
Corn
The runtime's memory allocator matters too. Some runtimes fragment memory over long sessions. LiteRT is generally solid here. ONNX Runtime Mobile has improved. ExecuTorch is still working on it. If you're building an app that transcribes for hours, you need to test for memory leaks and fragmentation, not just accuracy.
Herman
That's the kind of thing that never shows up in a model card. The model author tested it for five minutes on their desk and called it good. The person who runs it for three hours in the field finds the problem.
Corn
The question Daniel's really circling is, how do you make a decision in an environment where the ground keeps shifting? The runtimes are still maturing. The silicon is fragmenting. The models are getting better every month. What's the stable principle?
Herman
The stable principle is that the runtime is the first gate. Before you ask whether a model is accurate, ask whether it loads. Before you ask whether it fits, ask which runtime and which quantization. And before you ship, test it for the actual workload: sustained transcription, not a single inference.
Corn
The second stable principle is that portability and performance are in tension. The more you optimize for a specific TPU, the less portable you are. The more portable you are, the less you're using the specific silicon. There's no free lunch.
Herman
The third is that parameter count is a proxy that mostly works on desktop and mostly doesn't on mobile. The real constraints are quantization, operator support, and thermal headroom. If you hold those three in your head, you can evaluate any model on any device.
Corn
When someone says "my phone can run a hundred million parameter model," the correct response is, which runtime, which quantization, which operators, and what's the thermal budget?
Herman
That's the thing I keep coming back to. The desktop mindset is a single number. The mobile reality is a set of interacting constraints. Once you internalize that, the rest is just details.
Corn
What happens when you add a TPU? You get a new constraint and a new capability at the same time. The TPU can run int8 operations extremely efficiently, which means you can run bigger models at lower power. But you also now have a second memory pool to worry about, and a second operator set to check.
Herman
The TPU's memory is separate from system RAM. A model that fits in system RAM might not fit in TPU memory. And the TPU's operator support is narrower than the CPU's. So you have to check both. The TPU delegate handles the partitioning, but you need to know what's actually going to the TPU and what's staying on CPU.
Corn
The AI Edge Gallery is the easiest way to see this in action. You download a TPU-optimized model, run it, and watch the latency and power draw. Then download the non-optimized version of the same model and compare. The difference is usually dramatic.
Herman
That's one of the reasons Daniel recommends it. It's a quick way to test whether your device can run local models at all, and it gives you a baseline for what's possible. You can then take that baseline to Hugging Face and look for models that match it.
Corn
The workflow is: test your device with AI Edge Gallery, see what runs and how fast, then go to Hugging Face with that knowledge and filter for models that match your runtime and quantization. That's a much better starting point than just downloading the most popular ASR model and hoping.
Herman
The model card tags are the first filter. LiteRT, TFLite, onnx, gguf. Those tell you what format the model is actually available in. If it only has PyTorch weights, you're signing up for conversion work. If it has a tflite file, someone already did that work for you.
Corn
The README is the second filter. A model author who's actually tested on Android will say so. They'll mention which devices they tested on, which runtime they used, what the latency was. That's gold. A model card with no deployment section is a gamble.
Herman
The quantization info is the third filter. int8 is the sweet spot. float16 is workable if you have a TPU. float32 is desktop territory. int4 is aggressive but works for tiny models. If the model card doesn't mention quantization, assume float32 and move on.
Corn
Then the operator check. This is the one most people skip because it's tedious. But if the model uses an operator your runtime doesn't support, it'll either fail to load or fall back to CPU for that layer. And a CPU layer in the middle of a TPU graph is a performance disaster.
Herman
The parameter count is the last filter, not the first. Under two hundred million for sustained ASR on mid-range devices. Above that, you're fighting the thermal budget even if the model loads.
Corn
That's the concrete workflow. And the emerging options are all over this map. Some are streaming-first, some are multilingual-first, some are tiny-footprint-first. The one you pick depends on which constraint matters most for your use case.
Herman
The use case matters more than people think. Live captions need streaming. Podcast transcription can use batch. Multilingual dictation needs broad language coverage. Voice commands for an app need a tiny model that responds instantly. These are different models, different runtimes, different tradeoffs.
Corn
Daniel's question about emerging options is really a question about which tradeoff to optimize for. And the answer is, it depends on what you're building. But the good news is that the options are getting better across the board. Streaming models are getting more accurate. Multilingual models are getting smaller. Tiny models are getting more capable.
Herman
The distillation work is the quiet revolution here. A large model trains a small model to mimic its behavior. The small model inherits most of the accuracy at a fraction of the size. That's how you get a forty million parameter model that transcribes twenty languages reasonably well. And it's why the parameter count is so misleading. A distilled forty million parameter model can outperform a non-distilled hundred million parameter model.
Corn
The parameter count was never the right metric. It was just the one that was easy to see. The real metrics are quantization, operator support, and thermal behavior. And those are the ones you have to dig for.
Herman
Which is why the Hugging Face workflow matters. The tags, the README, the quantization info, the operator list. Those are the signals that tell you whether a model will actually run on your phone. The parameter count is a distraction.
Corn
The runtime is the thing that ties it all together. Pick the wrong runtime and even a perfect model won't load. Pick the right runtime and a mediocre model will sing.
Herman
The practical advice is: start with AI Edge Gallery to see what your device can do. Then go to Hugging Face and filter by runtime tags. Read the READMEs. Check the quantization. Verify the operators. And don't trust desktop benchmarks.
Corn
The models that win on Android are the ones that ship with the best runtime support and the most forgiving operator sets. Not the ones with the highest accuracy on a desktop GPU.

Hilbert: My brother-in-law sells phones. He's been doing it since the two-thousands. He told me once the problem with dedicated silicon is the day they stop making it. You've got a drawer full of devices that worked fine until the chip revision changed. The firmware was locked to the specific revision. No update. No fix. Just a paperweight.

Hilbert: I worked a stint at a repair shop around then. We had a drawer full of dead smart devices. They all had dedicated DSPs for audio. The DSP firmware was locked to the chip revision. When the manufacturer moved to the next revision, the old firmware stopped getting updates. The devices still powered on. They just couldn't do the thing they were bought for.

Hilbert: When I hear TPU-optimized, I think, that's great until the TPU changes. The model you optimized for today's Tensor chip may not run on next year's. And you won't know until you try. The compatibility cliff is real.

Hilbert: I'm not saying don't use the TPU. I'm saying don't build your whole workflow around it. Keep a CPU path. Keep a portable model. Because the day they change the silicon, you'll be glad you did.

Hilbert: I've still got one of those dead DSP devices in a box in the garage. Been meaning to see if I can get it to boot. The box is labeled, do not open, two thousand seven.
Corn
A box labeled do not open from two thousand seven. That's not a box, that's a time capsule.
Herman
The compatibility cliff is a real concern. We're seeing it already with the vendor NPUs. Qualcomm's operator set is different from MediaTek's, which is different from Google's TPU. A model optimized for one doesn't carry to the others. And when the next generation of each arrives, the old optimizations may not carry forward either.
Corn
The question is whether the runtimes can abstract enough of this away. LiteRT and ExecuTorch are trying. The NPU delegate is supposed to handle the partitioning and the operator mapping. But the abstraction leaks. And every time it leaks, someone has to debug a model that worked yesterday and doesn't today.
Herman
The models that survive that churn are the ones with the most forgiving operator sets. The ones that don't depend on a specific silicon quirk. The ones that run acceptably on CPU and better on NPU. Those are the ones worth building on.
Corn
That's the open question. As Android gets more NPU variants, does the ecosystem fragment further, or do the runtimes abstract enough to keep models portable? I don't think we know yet. The next two or three years will decide it.
Herman
My bet is on fragmentation in the short term and abstraction in the long term. The runtimes will eventually catch up. But in the meantime, the practical advice is to keep a CPU fallback and test on real hardware.
Corn
The misconception people have is that parameter count is the deciding factor for what their Android device can run. It isn't. Quantization, operator compatibility, and runtime overhead all matter more. A thirty-nine million parameter model can be forty megabytes or a hundred and fifty, depending on how it's packaged.
Herman
A TPU-optimized model is not universally better. It's better on that specific TPU. On other hardware, it may not run at all. The optimization is a trade, not a free upgrade.
Corn
If you've tried running ASR on Android, leave a review and tell us what runtime and model you landed on. We're curious what the field looks like in practice.
Herman
Thanks to our producer, Hilbert Flumingtop, for keeping the show running.
Corn
This has been My Weird Prompts, the human-AI collaboration podcast.
Herman
We'll be back soon.

This episode was generated with AI assistance. Hosts Herman and Corn are AI personalities.