Skip to main content
TACAVAR
Build in Public

I Replaced a $200 Upscaler With a Free CUDA Script

A $200 GUI upscaler replaced by 40 lines of Python. One ffmpeg flag nearly broke everything. That isn't a headline, it's the audit report for Tacavar's video pipeline. We ran Topaz Video AI for months because the output was good and the GUI was comfortable. But comfortable doesn't scale, and the license fee was the smallest line on the invoice. The real cost was manual clicks, broken cron jobs, and a Windows desktop that had to stay alive just to upscale a batch of MP4s.

Why I was paying for Topaz Video AI

Topaz Video AI produces clean 4x results. I'll give it that. But Tacavar runs hundreds of video jobs a month, and every one that needed upscaling required a human to open a GUI, load the source, pick a model, set the output, and babysit the render. On busy weeks that meant someone stayed late just to click "Start." We were paying $200 per machine and still eating more engineering time than the software was worth.

The breaking point came on a night batch. A render failed at 2 a.m. because the screen locked. Nothing was wrong with the source footage; the machine lost keyboard focus and the GUI silently paused. That's when I started looking for a way to replace Topaz with free upscaler alternatives—something that could sit inside a shell script and never ask for a login. I already knew Real-ESRGAN was good for images; the real test was whether real-esrgan video upscaling could hold up at 4x for our footage. It could, but the path there had a few sharp edges.

The 40-line Real-ESRGAN replacement

The replacement is simple: a Python script that loads the Real-ESRGAN model, reads frames from the source video, runs inference with CUDA, and writes frames back to an output file. No GUI, no network, no license check. When I ran the RTX 5080 CUDA upscaler on Tacavar's workstation, it delivered 4x output that matched Topaz closely enough that our internal review team couldn't tell the difference in a blind test. The entire script is around 40 lines of Python, plus a shell wrapper that handles input and output paths.

There is no magic in the model loading. You initialize the RealESRGANer from basicsr, set scale=4, point it at the model weights, and call it on each frame. The first version was up and running in 30 minutes. The next four hours were spent on two problems that weren't in the README: a pixel format trap and an import error in a dependency.

The silent corruption trap: gbrp vs yuv420p

The first output file looked perfect in VLC and then failed in Windows Media Player with a generic "corrupt" message. It wasn't corrupt. The ffmpeg encoder, told to write RGB frames, selected the gbrp pixel format. Most players honestly show broken color or refuse playback, but some render something that looks almost right. Windows Media Player just calls it corrupt and refuses to open. The fix is one flag at the end of the ffmpeg command: -pix_fmt yuv420p. In my wrapper, I added it to the output arguments and the files became universally playable.

This is the "ffmpeg yuv420p fix" that shows up in no example script. The model emits RGB; ffmpeg needs to convert to 4:2:0 YUV for broad compatibility. Without that flag, every video in the batch is silently broken. The scary part? Our own validation script initially passed because it only checked file size and duration. It took a human opening a file to see it. Tacavar's pipeline now has an explicit pixel-format assertion in every upscale job.

Patching basicsr and torchvision for a clean install

The second problem appeared on a fresh install. basicsr still imports the old torchvision.transforms.functional_tensor module, which disappeared in newer torchvision builds. The initial error is buried inside degradations.py: an import that doesn't exist anymore. If you install straight from the repo, the first upscale crashes before the model even loads.

The fix is a small patch to degradations.py—replace the old import with the current torchvision.transforms.functional API. I also added a hasattr check in the script so the patch is idempotent and works across environments. This isn't a feature; it's maintenance. But for an operator, the lesson matters: open-source dependency chains are not turnkey. You need to know the four files that will break and patch them before you declare victory.

Wiring the upscaler into a cron watcher

Tacavar already had a directory watcher for incoming jobs, topaz_watcher.sh. It polled a folder, detected new source videos, launched an upscale job, and moved the output when finished. The only change was pointing that wrapper at the new Python script instead of the Topaz CLI. Now the nightly batch runs from cron, with no GUI and no human at the workstation.

The whole thing is a headless video upscaling pipeline: watch folder triggers the script, CUDA runs on the RTX 5080, ffmpeg emits yuv420p, and a validation step confirms the output before it moves to the delivery folder. If a job fails, the script logs the exit code and our healthcheck pings. If it succeeds, no one has to think about it. That is the difference between paying for a tool and owning an outcome.

What the switch actually cost me

The license for Topaz Video AI was $200 per machine. The Real-ESRGAN replacement costs $0 in software, but the real math isn't the price tag. It took me about a day to build the script and patch the dependency chain. The pixel format bug cost another hour of digging. After that, the marginal cost of upscaling a video on a machine we already own is effectively zero. No per-video fee, no screen-lock pause, no GUI sitting in the queue.

For Tacavar, the switch also made the pipeline more honest. We now know exactly which model runs, which flags get used, and which pixel format leaves the encoder. There is no black box between source and output. If a client asks what happened to their video, I can show the exact command line. That alone is worth more than the $200 license.

Run this same headless upscaler in your pipeline with Tacavar's video infrastructure playbooks at tacavar.com.