This is a submission for the
Demo
The video shows the engine selector, the model picker with five variants, and a live dictation with Gemma 4.
Code
Source, ADRs, and benchmark configs: : the recognizer that talks to Whisper is great on clean read English. It gets noticeably worse on conversational or noisy audio. Gemma 4 has a conformer audio encoder. Google's own evaluations show it reaching 4.17% WER on LibriSpeech-test-clean, which is competitive with much larger Whisper variants. For a voice-to-text app, the typical user is dictating to themselves into a focused text field. That noise profile is closer to "clean read" than to "AMI meeting", so Gemma 4 is a real alternative. Giving people the choice felt right. Either way, privacy does not depend on which model is loaded. I looked at several inference paths before picking E2B has no Q4_K_M. That asset does not exist in the repo. I learned this when manual testing returned a 404. After that, I rebuilt the catalog from the actual file lists on HuggingFace. I ran each variant against Whisper (Small, Medium, LargeV3Turbo) on 50 samples of LibriSpeech The Three things I learned from doing this: Maksim Demin is a .NET engineer building Parlotype, a voice-to-text desktop app. He writes about cross-platform .NET, Avalonia, and local AI.llama-server.
through : the benchmark data behind the choices below.
How I Used Gemma 4
Why a separate engine at all
Why llama-server as the runtime
llama-server, the HTTP server from llama.cpp. The constraints were: no cloud, Windows desktop, single end-user installer, cross-vendor GPU support, no Python runtime in the user's install.
onnxruntime-genai does not support Gemma 4's architecture yet (per-layer embeddings, variable head dimensions). Tracking issue: ). Lemonade is AMD-only.
llama-server with the pre-built Vulkan/CUDA Windows binaries hits all of these. Cross-vendor GPU support from one download. A stable OpenAI-compatible HTTP API at /v1/chat/completions, with input_audio blocks for audio. A release cadence I can manage from in-app updates. ):
ModelId
GGUF
Size on disk (with bf16 mmproj)
gemma-4-E2B-it-Q8_0
E2B Q8_0
~5.5 GiB
gemma-4-E2B-it-bf16
E2B BF16
~9.6 GiB
gemma-4-E4B-it-Q4_K_M
E4B Q4_K_M
~5.9 GiB
gemma-4-E4B-it-Q8_0
E4B Q8_0
~8.4 GiB
gemma-4-E4B-it-bf16
E4B BF16
~15 GiB
test-other, which is the "harder" English split. Same machine, same warm-up methodology, both engines on CUDA. Whisper used greedy decoding (beam=1) so the runs are reproducible.
Rank
Engine
Model
WER %
CER %
RTF
Model load (s)
1
Whisper (CUDA)
LargeV3Turbo
11.48
4.97
0.055
1.31
2
Whisper (CUDA)
Medium
12.18
5.41
0.073
1.28
3
Whisper (CUDA)
Small
13.10
5.87
0.034
0.71
4
Gemma 4 (llama.cpp)
E2B-it-BF16
13.15
4.95
0.038
6.70
5
Gemma 4 (llama.cpp)
E4B-it-Q4_K_M
13.82
5.80
0.038
6.73
6
Gemma 4 (llama.cpp)
E4B-it-BF16
14.20
5.40
0.038
6.72
7
Gemma 4 (llama.cpp)
E4B-it-Q8_0
14.39
5.79
0.044
9.25
8
Gemma 4 (llama.cpp)
E2B-it-Q8_0
19.22
8.95
0.315
6.74
llama-server binary itself is also managed by the app. turned the hardcoded prompt into a small registry with a built-in default and a {language} placeholder. The placeholder is there for a future feature that picks the source language from the active keyboard layout.
What this taught me
The model card's headline numbers do not transfer to your stack. Google's reported 4.17% WER on LibriSpeech-clean is real. But the path from "the model can do 4.17%" to "my app does 13.82% on noisy audio with the quantization that fits on user disks" goes through five variant choices, a runtime choice, and the measurement methodology. Benchmark on your own stack.
Most of the work is in the catalog, not in the inference call. The actual /v1/chat/completions HTTP call is about 30 lines of code. The variant catalog, the download manager, the side-by-side install of llama-server backends, the prompt registry. That is where most of the engineering went.
Asymmetric quantization coverage is the rule, not the exception. E2B has no Q4_K_M in the published GGUFs. The catalog has to reflect what is actually on HuggingFace, not what would be theoretically nicest.
Try Parlotype
llama-server and the GGUF for you.
SOCIAL SHARE CARD GENERATOR