Pairing WhisperX with LLM's
Pairing WhisperX with LLM's
I've found some time to continue my project. In my last article, I mentioned that I was using faster-whisper for both transcription and translation, as well as dealing with the annoying issue of overlapping or misaligned subtitles that needed manual correction.
To fix this, I decided to switch to the WhisperX library.faster-whisper under the hood and layers forced phoneme alignment on top.
To solve this, I bypassed Whisper's native translation entirely and routed the transcriptions through Google's Gemini LLMs to translate them into my preferred language.
Technical Details
Next, I had to figure out how to structure the data for translation. In my code, a subtitle "Cue" is defined simply as
@dataclass(frozen=True)class Cue: start: float end: float text: str
When building the prompt for Gemini, I decided it needed three distinct layers of context to produce an accurate translation:
Global context: The overarching theme or subject of the entire video.
Local context: A sliding window of cues immediately before and after the target cue.
Target cue: The specific text block needing translation.
Conveniently, Google's genai client is asynchronous, which allowed me to batch all the API calls and process the cue translations concurrently.
I am incredibly happy with the results. While Whisper's built-in translation model struggles with low-resource languages, its transcription engine remains solid—and pairing it with an LLM via smart context batching completely solved my subtitle pipeline.