← Blog
Section 1 of 4
  1. The split
  2. The key idea: don’t trust the small model, check it
  3. The numbers
  4. What I’d tell someone trying this

← Blog

Big model plans, small model does the repetitive work: subtitling a 30-minute interview with a local LLM

How I split a video job between Claude and a Qwen model running on my Mac: the frontier model did the judgment work and wrote the code, the local model did almost 400 subtitle lines, and cheap checks in code made its output safe to ship.

Written by
Naresh Kumar
Published
Reading time
5 min
Topic
Tech & AI

I recently edited a 30-minute interview for Big’s Backyard Ultra’s YouTube channel. Race director Gary “Laz” Cantrell talks with Belgian runners Ivo Steyaert and Merijn Geerts, who ran 124 hours side by side and set a new backyard world record. They did it at the 2026 World Team Championship, and the video’s graphics use the final results from the live dashboard I built for it. The finished video has subtitles in English, Dutch and French.

I did the edit with Claude Code. That covered planning the cut, writing the render pipeline, building the on-screen graphics from the official race data, and making the shorts. But one part of the job didn’t need a frontier model at all: going through almost 400 subtitle lines, one by one. I gave that part to a model running on my own Mac.

The video’s thumbnail: “124 hours, Ivo and Merijn talk to Laz”, with Ivo and Merijn making a heart with their arms at the finish

Watch the video on YouTube. Photo: Legends Backyard Belgium.

The split

Job Who did it Why
Edit decisions, pipeline code, graphics, prompts, quality checks Claude (frontier model) Needs judgment, context and code
Fixing punctuation and capitals on every caption line Local Qwen model Repetitive, high volume, easy to check
Translating every line into Dutch and French Local Qwen model Same: lots of small, bounded jobs

I asked Claude to do this. It wrote a small script that sends the captions to the local model, 24 lines per request with 4 requests running in parallel, through an OpenAI-compatible server (oMLX) on localhost. All the line-by-line work ran on my machine, with no API bill.

Who does what, and where the checks sit Claude, in the cloud, plans the edit and writes the script, the prompts and the checks. On my Mac, the script sends 388 lines in batches of 24, four at a time, to a local Qwen model through oMLX, which does punctuation and then Dutch and French. Every line it returns goes through checks in code: the same words, every number and name, a sensible length. A line that passes is kept. A line that fails is retried with context, and otherwise the original is kept. Claude, in the cloud Plans the edit; writes the script, prompts and checks writes ON MY MAC The script 388 lines, in batches of 24, four at a time Local Qwen model, through oMLX Punctuation, then Dutch and French Checks in code, on every line Same words? Every number and name? Sane length? Pass The line is kept Fail Retry with context, else keep the original

The key idea: don’t trust the small model, check it

A local model will sometimes slip. So the script checks every line it returns, mechanically:

  • Punctuation pass: the model may only change punctuation and capital letters. If the words in a returned line differ in any way from the original, the line is rejected and the original is kept.
  • Translation pass: a translated line must keep every number (124, 52:48…) and every name (Ivo, Merijn, Laz…), and it must be a sensible length compared with the English. If a line fails, it is re-sent on its own with the lines around it for context. If it still fails, it stays in English, and the script reports it.
def ok(src, tr):
    if not tr: return False
    if nums(src) != nums(tr): return False                      # every number survives
    if any(n in src and n not in tr for n in NAMES): return False # every name survives
    return 0.4 < len(tr) / max(1, len(src)) < 2.4                 # no runaway or truncated lines

A short glossary in the prompt keeps race terms consistent: “yard”, “backyard”, “Big’s”, “nocebo” and the bell.

Here is one real line from the finished video, as it shipped in all three languages, and what the checks looked for:

One caption line in three languages, and its checks Caption 176 in English: "Ivo, for you, your night average was 52:48 in the dark and". In Dutch: "Ivo, voor jou was je gemiddelde in de nacht 52:48 in het donker en". In French: "Ivo, pour toi, ta moyenne de nuit était de 52:48 dans le noir et". Both translations kept the number 52:48 and the name Ivo, and both are about 1.1 times the length of the English, so both passed. EN Ivo, for you, your night average was 52:48 in the dark and NL Ivo, voor jou was je gemiddelde in de nacht 52:48 in het donker en FR Ivo, pour toi, ta moyenne de nuit était de 52:48 dans le noir et Checks on the Dutch and French ✓ Number 52:48 kept ✓ Name Ivo kept ✓ Length 1.1× the English, inside 0.4–2.4×
Caption 176, from the finished subtitle files. The name and the number are what the checks hold on to.

This is what makes offloading safe. The small model does the volume, and cheap deterministic checks catch the worst failures: a lost number, a dropped name, a rewritten line.

The numbers

  • Punctuation: 117 of 390 lines repunctuated in under 4 minutes. Every change was checked to be word-for-word identical to the original.
  • Translation: every line passed the checks in both languages.
  • Re-edit: after a late change to the cut, the script matched the old captions to the new ones. It reused 383 lines and sent only 5 new ones to the model, instead of redoing the whole file.

I then benchmarked the four models I have locally on the same Dutch translation (144 lines each):

Translation speed of four local models, in tokens per second Qwen3.8 27B, dense: 15 tokens per second on one request, 40 with four in parallel. Qwen3.6 35B-A3B, mixture of experts: 100 on one request, 150 in parallel. Gemma 4 26B-A4B, mixture of experts: 72 and 133. Qwen3.8 Flash-Next, 106 GB: 68 and 74. All four passed all 144 lines. One request Four in parallel Qwen3.8 27B, dense 15 tok/s 40 Qwen3.6 35B-A3B, mixture of experts 100 tok/s 150 Gemma 4 26B-A4B, mixture of experts 72 tok/s 133 Qwen3.8 Flash-Next, 106 GB 68 tok/s 74
Same task, same 144 lines. All four models passed every check, so speed decided it.
Model Single request 4 in parallel Passed checks
Qwen3.8 27B (dense, 8-bit) 15 tok/s 40 tok/s 144/144
Qwen3.6 35B-A3B (MoE, 8-bit) 100 tok/s 150 tok/s 144/144
Gemma 4 26B-A4B (MoE, 8-bit) 72 tok/s 133 tok/s 144/144
Qwen3.8 Flash-Next (106 GB) 68 tok/s 74 tok/s 144/144

All four passed every check, so speed decided it. The mixture-of-experts model, with only ~3B parameters active per token, was more than 6× faster than the dense 27B on a single request. I re-ran the full Dutch and French translation with it: 388 lines in each language in 1 minute 37 seconds, every line passing.

The biggest model was not the best one for this job. For short, well-defined tasks, a small-active-parameter MoE gives you most of the quality at a fraction of the wait.

What I’d tell someone trying this

  1. Give the local model jobs with a checkable output. “Change only punctuation” and “keep every number and name” can be verified in code. “Make this sound good” can’t.
  2. Keep the big model for the parts that need judgment, like story, structure, code and design. Use it to write the prompts and the checks, not to grind through rows.
  3. Process only what changed. Matching old lines to new ones turned a re-edit from a full re-run into 5 lines.
  4. Benchmark on your actual task. Model size was a poor predictor here. Throughput on my real prompt was what mattered.
  5. Still get a native speaker to read it. The checks catch broken lines, not awkward phrasing. They make the output safe to ship, not perfect.

Big model to plan, small model to do the volume, and code to check the small model’s work. That combination was the best thing I took away from this project.

Thanks to Laz, Ivo and Merijn, and to Legends Backyard Belgium for the finish-line photo.