A video generation pipeline experienced a critical performance bottleneck during frame rendering, achieving only 7-8 frames per second (FPS) on a 32-core CPU. This bottleneck resulted in a rendering time of approximately 15 minutes for a 7-minute video, with 90% of the pipeline time consumed by sequential frame generation.
Issue
The frame rendering process was constrained by MoviePy’s sequential make_frame callback architecture. Each frame was processed one at a time, resulting in minimal CPU utilization (only 3% of a single core). Despite having 32 available CPU cores, the system utilized only one core during frame generation, leading to inefficiencies and extended processing times.
Culprit
The root cause was the design of MoviePy’s callback system, which enforced single-threaded execution for frame rendering. This included:
- Single-threaded execution: MoviePy’s architecture processes frames one-by-one without parallelization.
- Redundant calculations: Tokenization, syntax highlighting, and character positioning were recalculated for every frame, causing unnecessary overhead.
- CPU underutilization: Only 3% of CPU resources were utilized during frame generation, despite the availability of 32 cores.
Solution
A parallel processing architecture was implemented to address these inefficiencies. This involved:
- Pre-calculation phase: All character positions and frame metadata were computed once to reduce per-frame calculations.
- Parallel rendering phase: Frame rendering was distributed across all 32 CPU cores using multiprocessing, achieving a 13x speedup.
- Direct FFmpeg encoding: FFmpeg’s native multithreading capabilities were utilized for efficient encoding, reducing the encoding time by 2.5x.
Performance Improvements
| Metric | Before (Sequential) | After (Parallel) | Improvement |
|---|---|---|---|
| Frame Rendering | 7-8 FPS | 104 FPS | 13x |
| 7-min Video Time | ~15 minutes | ~22-25 seconds | 36x |
| CPU Utilization | 3% (1 core) | 100% (32 threads) | 32x |
| Encoding Speed | ~4 seconds | ~1.6 seconds | 2.5x |
The solution transformed the frame rendering phase from a 90% bottleneck to a minor component of the pipeline, significantly improving overall performance while maintaining frame-perfect compatibility.