Skip to main content

Speech Recognition

Self-hosting Vosk: from a 41.9MB model on a Raspberry Pi to CUDA batch decoding

Vosk is Alpha Cephei's offline streaming speech recognition engine built on Kaldi — Apache 2.0, 20+ languages, download the model and it runs. Nothing leaves your machine, nothing is billed per minute. It works nothing like the Transformer ASR you are used to, and that difference decides whether you need a GPU at all.

Start with the thing search results get wrong: Vosk does not need a GPU. The official model page is blunt about it — a small model such as vosk-model-small-cn-0.22 (41.9MB) uses roughly 300MB of memory at runtime and runs on phones and Raspberry Pis; the big models (vosk-model-cn-0.22 at 1.3GB, vosk-model-en-us-0.22 at 1.8GB) apply CARPA rescoring and Alpha Cephei recommends budgeting up to 16GB — of system RAM, not VRAM. So the honest answer to "how much VRAM does Vosk need" is: on the default path, none. Decoding happens on the CPU.

So when is a card actually worth renting? Three cases. One, you have thousands of hours of archived audio to transcribe, which is what vosk-api's CUDA batch path exists for — BatchModel / BatchRecognizer / GpuInit wrap Kaldi's cudafeat and cudadecoder, and the source ships defaults of max_batch_size=32, num_channels=600 and use_gpu_feature_extraction=true, feeding dozens of streams through one card at a throughput CPU decoding cannot touch. Two, Vosk emits no punctuation and no casing, so you bolt on recasepunc — a BERT model, 1.6GB for English, happiest on a GPU. Three, you want Vosk and faster-whisper side by side on one box, which is the spend most teams should actually make.

A few things you will definitely hit when self-hosting, stated up front: there is still no official GPU pip package (issue #1287, "Package vosk with GPU support", is open in the vosk-api repo), so the CUDA route means building from source against Dockerfile.kaldi-vosk-server-gpu. PyPI's vosk stops at 0.3.45 from December 2022 while the GitHub tag is v0.3.50 and master keeps moving through August 2026 — endpointer config, ITN, the Golang GPU batch API are all unavailable via pip. The only official GPU image is English (alphacep/kaldi-en-gpu); for Chinese you swap MODEL_VERSION in the Dockerfile and rebuild. And the GPU server defaults to VOSK_SAMPLE_RATE=8000, so pointing a 16kHz model at it gives you fluent nonsense. None of this is mysterious — it is an hour of rented time to work through, one item at a time.

01 —

Vosk models still in service, and what they actually cost you in memory

The official model list carries 131 entries, most flagged obsolete. These are the ones still maintained; every WER/CER number comes from the alphacephei.com table.

VersionParametersVRAMContextNotes
vosk-model-small-cn-0.22Small / Kaldi nnet3 chainNo VRAM needed; ~300MB RAM at runtime16kHz mono streaming, vocabulary swappable at runtime41.9MB, the default choice for Chinese on-device. CER 23.54 (SpeechIO-02), 38.29 (SpeechIO-06), 17.15 (THCHS). SetGrammar works, so command words, digit strings and fixed call scripts do well.
vosk-model-cn-0.22Big model with CARPA rescoringBudget 16GB RAM on CPU; a 16GB-class card for CUDA batch decoding16kHz mono streaming, static vocabulary1.3GB, the only maintained Chinese server model. CER 13.98 (SpeechIO-02), 27.30 (SpeechIO-06), 7.43 (THCHS). Solid on read speech and clean recordings; far-field and heavy-accent meeting audio degrades noticeably.
vosk-model-small-en-us-0.15Small / Kaldi nnet3 chainNo VRAM needed; ~300MB RAM at runtime16kHz mono streaming, dynamic vocabulary supported39.3MB, the standard build for Android and Raspberry Pi. WER 9.85 (librispeech test-clean), 10.38 (tedlium). Good enough for post-wake-word commands and replacing IVR keypresses.
vosk-model-en-us-0.22 / -lgraph1.8GB big model / 124.5MB dynamic-graph build16GB RAM for the big model; a few hundred MB for lgraph16kHz mono streamingThe English workhorse. 0.22 scores WER 5.69 (librispeech test-clean), 6.05 (tedlium), 29.78 (callcenter); the lgraph build scores 7.82 but buys you runtime vocabulary changes. Pick lgraph if hotwords matter more than the last point of accuracy.
vosk-model-en-us-0.42-gigaspeechLargest official English package, 2.3GB16GB RAM, plus ~5GB disk for the unpacked model16kHz mono streamingTrained by Kaldi on Gigaspeech. WER 5.64 (librispeech test-clean), 6.24 (tedlium). Alpha Cephei says outright it is for podcasts, not telephony — 30.17 on callcenter, slightly worse than 0.22. Do not point it at contact-centre QA.
vosk-model-spk-0.4 + vosk-recasepunc-en-0.2213MB speaker embeddings / 1.6GB punctuation restorationspk is negligible; recasepunc is a BERT, put it on the GPUspk works across languages; recasepunc ships only for en / ru / deVosk's main models emit no punctuation and no casing — recasepunc fills that gap. There is no official Chinese recasepunc, so a Chinese deployment has to train one or wire in a third-party punctuation model. This is the step most self-hosting plans forget.

02 —

Which card, chosen by what you are doing rather than by spec sheet

Vosk is a CPU-first engine. A rented GPU earns its keep on batch throughput, punctuation restoration and head-to-head comparison. We are not going to tell you to book an H100 for this.

  • Small-model streaming service and concurrency testing (decoding stays on CPU)

    Tesla V100 32GB$0.188/GPU-hr

    The cheapest hour on the network. vosk-model-small-cn-0.22 uses about 300MB of RAM, so the card idles at first — and when you move to CUDA batch decoding, 32GB holds the decoding graph comfortably.

  • CUDA batch decoding of archived audio (BatchModel defaults: batch 32, 600 channels)

    Tesla T4 16GB$0.298/GPU-hr

    Kaldi's cudadecoder was tuned around inference cards of exactly this class. 16GB fits the decoding graph plus 32 channels of batch state at the lowest cost per hour of audio processed.

  • Vosk plus recasepunc, or an A/B against faster-whisper on one box

    RTX 4090 24GB$0.540/GPU-hr

    1.6GB of recasepunc and Whisper large-v3 both stay resident in 24GB, so a single rental answers the only question that matters: is Vosk good enough for your audio?

  • Compiling vosk with HAVE_CUDA=1 yourself (no official GPU package exists)

    RTX 3090 24GB$0.193/GPU-hr

    Building Kaldi's cudafeat and cudadecoder needs a real card present to validate against. The 3090 is the cheapest 24GB option; push the image to your registry and stop the instance.

03 —

Four steps to a running Vosk service

From bare instance to a WebSocket endpoint doing streaming recognition — about an hour the first time, and per-second billing means that hour costs less than a coffee.

  1. 01

    Start an instance and pull the model

    Boot an Ubuntu or PyTorch image from console.nexgpu.net, SSH in, and download directly. Every official model lives under alphacephei.com/vosk/models/ and the filename is the URL. Swap in the small build first if you are only sizing things up. The unpacked model is a directory: am/, graph/, ivector/ and rescore/ all have to be there — copying final.mdl alone will not work.

    wget https://alphacephei.com/vosk/models/vosk-model-cn-0.22.zip && unzip vosk-model-cn-0.22.zip
  2. 02

    Get a batch of files through vosk-transcriber first

    The pip package ships a CLI that shells out to ffmpeg, so mp4/mp3/m4a go straight in; -t takes txt or srt and --tasks sets parallel recognition tasks (default 10). If you use the Python API instead, audio must be mono 16-bit PCM WAV at the model's sample rate. Feeding it 44.1kHz stereo raises no error — it just quietly floors your accuracy, and it is the single most common self-hosting mistake.

    pip install vosk && vosk-transcriber -m vosk-model-cn-0.22 -i meeting.mp4 -t srt -o meeting.srt --tasks 16
  3. 03

    Stand up the streaming WebSocket server

    vosk-server offers WebSocket, gRPC, MQTT and WebRTC; the official images listen on port 2700. Use alphacep/kaldi-cn for Chinese, alphacep/kaldi-en for English, and bind-mount your own directory over the model path to swap in an adapted model. The repo's test.py verifies the endpoint in one command. If you are wiring this into Asterisk or FreeSWITCH, use the 8kHz configuration.

    docker run -d -p 2700:2700 -v /opt/model:/opt/vosk-model-cn/model alphacep/kaldi-cn:latest
  4. 04

    Switch on CUDA batch decoding

    The GPU route uses alphacep/kaldi-en-gpu, based on nvidia/cuda:12.1.0-devel-ubuntu22.04, with Kaldi built for cudafeat and cudadecoder and vosk-api compiled with HAVE_CUDA=1. Only the English image is published; for other languages change MODEL_VERSION in docker/Dockerfile.kaldi-en-gpu and rebuild. Two details worth pinning: the GPU server defaults to VOSK_SAMPLE_RATE=8000, so 16kHz models need it overridden, and python/example/test_gpu_batch.py prints xRT when it finishes — trust that number on your own card over anyone's published benchmark.

    docker run --gpus all -d -p 2700:2700 alphacep/kaldi-en-gpu:latest

The arithmetic, in full

Case one, 1,000 hours of Chinese call recordings transcribed in batch: rent a Tesla T4 16GB at $0.298/GPU-hr and run the bundled test_gpu_batch.py to get the real xRT for your audio. Assume you measure 60x realtime — 1,000 ÷ 60 ≈ 16.7 GPU-hours, and 16.7 × $0.298 ≈ $4.98 to transcribe the lot. The 1.3GB model sitting in storage costs 1.3 × $0.414 ≈ $0.54/month; pulling 200MB of transcripts back out is 0.2 × $0.0081 ≈ $0.002, which rounds to nothing. An RTX 4090 24GB at $0.540/GPU-hr is usually faster and proportionally dearer, so the totals land close together and the choice is about how soon you want the results. Case two, an always-on streaming service: Tesla V100 32GB at $0.188 × 24 × 30 = $135.36/month for a persistent machine with a card in it, where the small model takes 300MB and the rest of the box is yours. Case three, you only want to find out whether self-hosting is worth it at all: per-second billing turns a 40-minute load test into $0.188 × 0.67 ≈ $0.13, with no minimum, no setup fee and no quota request. Compute billing stops the moment the instance stops; storage keeps accruing until you destroy it.

04 —

FAQ

How much VRAM does Vosk actually need? Do I need a GPU at all?

Not on the default path. Small models use about 300MB of memory at runtime, and Alpha Cephei recommends budgeting up to 16GB for the big models — system RAM, not VRAM, because decoding runs on the CPU. A card only matters for CUDA batch decoding, recasepunc punctuation restoration, or benchmarking against Whisper on the same box. A Tesla T4 16GB at $0.298/GPU-hr covers all three, billed by the second on NexGPU.

Vosk or Whisper / faster-whisper?

The trade is clean. Vosk is genuinely streaming — partial results as the speaker talks, near-zero latency, runs on CPU, and the vocabulary can change at runtime. Whisper-family models are more accurate and more robust but decode in chunks, so real-time takes extra engineering. For Chinese, vosk-model-cn-0.22 scores CER 13.98 on SpeechIO-02: fine for read speech, weaker in noisy far-field. Don't take our word for it — put both stacks on one RTX 4090 24GB at $0.540/GPU-hr and run your own audio through them.

Does pip install vosk give me the latest version?

No. PyPI stops at 0.3.45, released December 2022. The GitHub tag is v0.3.50 and master has commits running through August 2026 — endpointer configuration, ITN, the Golang GPU batch API all sit outside the pip release. New features mean building from source, and there has never been an official GPU wheel (issue #1287 is still open). Doing that build once on an RTX 3090 24GB at $0.193/GPU-hr and pushing the image to your own registry is the least painful route.

Why does Vosk output have no punctuation or capitalisation?

By design — Kaldi emits a bare word sequence. Alpha Cephei recommends recasepunc for restoration, but only English (1.6GB), Russian (1.6GB) and German (1.1GB) models are published; there is no official Chinese one, so you train it or wire in a third-party punctuation model. recasepunc is BERT-based and belongs on the same card as everything else: an RTX 4090 24GB holds it alongside a Whisper model for comparison.

How do I add proper nouns or hotwords to Vosk?

Depends on the model class. Small and lgraph models take a JSON word list at recognizer construction — KaldiRecognizer(model, 16000, '["one two three four", "[unk]"]') — and SetGrammar swaps it mid-stream. Big models are static graphs; you can only rebuild Gr.fst with Kaldi's OpenFST/OpenGRM to reweight existing words, and the docs are explicit that this cannot introduce new ones. Genuinely new vocabulary means rebuilding the lexicon and the full decoding graph, a CPU- and memory-hungry job that suits renting a large-memory node by the hour and releasing it when the build lands.

How fast is CUDA batch decoding really?

Ignore any fixed multiplier you are quoted — clip length distribution, sample rate and model size all move it. The repo's python/example/test_gpu_batch.py prints xRT when it completes, so measure it with your audio on the card you are about to commit to. NexGPU runs 2,498 GPUs across 75 models, so T4, V100, 4090 and A6000 are all one click away, billed per second, and compute billing stops when you stop the instance. Measure first, then pick the card — that was always the right order.

Start building on NexGPU

Enterprise R&D team or solo developer — either way, your first job can be running in minutes.

Sign up to browse live network pricing. No payment method required.