cd /news/large-language-models/fitting-whisperx-large-v3-a-24b-llm-… Β· home β€Ί topics β€Ί large-language-models β€Ί article
[ARTICLE Β· art-19854] src=dev.to pub= topic=large-language-models verified=true sentiment=Β· neutral

Fitting WhisperX large-v3 + a 24B LLM on one 3090: a reproducible context-capping recipe

A developer successfully ran both WhisperX large-v3 (7.7GB) and a 24B parameter LLM (Devstral Small 2) simultaneously on a single 24GB RTX 3090 by reducing the LLM's context window from 40,960 to 8,192 tokens. This cut the KV cache from 6.1GB to 1.25GB, bringing total VRAM usage to 21.9GB and eliminating CUDA out-of-memory errors that occurred when both services overlapped. The fix uses the model's native 8K context length, which covers all real-world triage prompts without quality degradation from rope extrapolation.

read5 min publishedJun 3, 2026

This is the technical, reproducible version of a fix I shipped on my own homelab. If you want the narrative version, that's on Medium. This one is the recipe: the measurements, the math, the Modelfile, and the exact prompt I gave Claude Code to generate it. Copy-paste friendly.

Repo for the dashboard used throughout: https://github.com/SikamikanikoBG/homelab-monitor

18.3 + 7.7 = 26GB

β†’ CUDA OOM whenever they overlapped.num_ctx

to 8192 β†’ KV cache drops from ~6.1GB to ~1.25GB β†’ model footprint ~18.3GB β†’ 14.2 + 7.7 = 21.9GB

β†’ both resident, zero OOM, no quality loss.

Host:    openSUSE, Xeon (56 threads), 125GB RAM, 1x RTX 3090 (24GB)
GPU svc: WhisperX large-v3  (speech-to-text)
GPU svc: Ollama -> devstral-small-2 (24B, Q4_K_M) for background email triage

Both services run all the time. The OOM only happened when I dictated to my assistant (WhisperX) while the triage loop was active.

nvidia-smi

shows instantaneous VRAM. It can't show you which service spiked or when two of them overlapped β€” and an intermittent OOM is a timing problem. You need per-service VRAM history.

I use my own dashboard (homelab-monitor) for this. The relevant view is "AI Models", which attributes VRAM per model server and per loaded model, over a time range, with OOM markers and a capacity ceiling line.

What the history showed at the overlap window:

Service Peak VRAM
Devstral 24B (triage) ~18.3 GB
WhisperX large-v3 7.7 GB
Total
~26 GB on a 24 GB card

If you want to reproduce the measurement, the dashboard runs as a single container:

git clone https://github.com/SikamikanikoBG/homelab-monitor
cd homelab-monitor
docker compose up -d --build

(NVIDIA Container Toolkit required for GPU metrics. Remote hosts are monitored over SSH, no agent.)

Weights are a fixed cost (~15GB for Devstral 24B at Q4_K_M). The variable cost is the KV cache, which scales linearly with num_ctx

. So the question is: how much context does background email triage actually use?

I pulled the request traces from Langfuse. The triage pipeline:

Real prompts never exceeded ~5–8k tokens. The model was loaded with a 40k window β€” ~32k tokens of reserved KV cache doing nothing.

Devstral Small is mistral3

. Pull the architecture straight from Ollama:

curl -s http://localhost:11434/api/show -d '{"name":"devstral-small-2:latest"}' \
  | python -c "import sys,json;mi=json.load(sys.stdin)['model_info'];\
print({k:v for k,v in mi.items() if 'head_count' in k or 'block_count' in k or 'length' in k})"

Relevant values:

block_count (layers)      = 40
attention.head_count_kv   = 8
attention.key_length      = 128
attention.value_length    = 128
context_length (native)   = 8192   # rope-extended to 393216

KV cache per token (f16) = 2 (K+V) Γ— layers Γ— kv_heads Γ— head_dim Γ— 2 bytes

:

2 Γ— 40 Γ— 8 Γ— 128 Γ— 2  =  163,840 bytes  β‰ˆ  0.156 MB / token

So:

num_ctx KV cache (f16)
40,960 ~6.1 GB
16,384 ~2.5 GB
8,192
~1.25 GB
4,096 ~0.6 GB

8192 is the sweet spot: it's above the real worst-case prompt (~5–8k) and it's the model's native context length, so there's no rope extrapolation quality hit. I rejected 4096 β€” a 10-email batch with 2k generation can brush up against it.

Ollama lets you inherit existing weights and override parameters in a Modelfile, so this costs no extra disk and no re-download.

Modelfile.triage

:

FROM devstral-small-2:latest

PARAMETER num_ctx 8192
PARAMETER temperature 0
PARAMETER num_predict 2048

SYSTEM """You are a background email-triage engine. Follow the exact output
format in each request. Output only the requested label(s) or field(s). Never
add explanations, preamble, or commentary. When uncertain, pick the closest
valid option. Be terse and deterministic."""

Build it:

ollama create devstral-small-2:triage -f Modelfile.triage

The optional SYSTEM

block is a small bonus: triage prompts want terse, structured output, and pinning that behaviour cuts stray preamble (fewer reparse/retry calls = less GPU time).

I let Claude Code do the measuring and the Modelfile generation. The prompt, roughly:

Analyze my background email triage. Pull the Langfuse traces to find the real prompt/context sizes the triage job uses, decide a safe

num_ctx

cap that won't truncate worst-case batches, confirm the KV-cache savings against the model's actual architecture, and generate an Ollama Modelfile for a context-capped:triage

variant. Then tell me the expected VRAM footprint.

It came back with: traces show ≀8k tokens, cap at 8192 (native window), ~5GB KV saved, expected footprint ~14–16GB. Which matched what the dashboard measured after I deployed it.

curl -s http://localhost:11434/api/generate \
  -d '{"model":"devstral-small-2:triage","prompt":"ping","stream":false}' >/dev/null

curl -s http://localhost:11434/api/ps \
  | python -c "import sys,json;[print(m['name'],round(m['size_vram']/1e9,1),'GB ctx',m['context_length']) for m in json.load(sys.stdin)['models']]"

Result: the triage model holds ~14GB resident at ctx=8192

, down from ~18GB.

Before After
Triage LLM ~18.3 GB ~14.2 GB
WhisperX large-v3 7.7 GB 7.7 GB
Combined
~26 GB β†’ OOM
~21.9 GB β†’ fits

Both services now sit on the card together. Full STT quality, email triage in parallel, ~2GB headroom. No quant change, no CPU offload, no smaller Whisper.

nvidia-smi

can't diagnose it β€” get per-service VRAM num_ctx

to the real workload.Dashboard used for the per-service VRAM history: ** https://github.com/SikamikanikoBG/homelab-monitor** β€” it's open source, runs in one container, and exists because I needed exactly this view and

nvidia-smi

wouldn't give it to me.

── more in #large-language-models 4 stories Β· sorted by recency
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/fitting-whisperx-lar…] indexed:0 read:5min 2026-06-03 Β· β€”