中文 English

RTX 5060 Ti 跑 FlashVSR:我把 480P 视频“拉”到 1728×960,顺便踩完了这些坑

发布时间: 2026-08-10 · 阅读量 --
AI Video FlashVSR CUDA PyTorch NVIDIA RTX-5060-Ti Windows

写在前面

“把一段 480P 视频变清楚”听起来像把图片放大两倍,但真正运行一次才知道:视频超分更像是请一位修图师,连续修理上百张照片,还要保证相邻照片里的人脸、文字和光线不会突然跳变。本文记录一次完整的 FlashVSR_plus 实战:从 RTX 50 系兼容性判断、便携 Miniconda 安装,到模型下载、源码 bug、FFmpeg 音频合并,再到可复用的 Windows、Ubuntu 和 macOS 脚本。

本文使用的社区版 FlashVSR_plus 并非官方仓库,命令和参数会随版本变化。文中的路径均已改为公开示例路径,不包含原始机器信息;原视频、模型和终端日志没有上传到博客。

1. 最终结果先看:成功,但不是“魔法变成 1080P”

源视频是 864×480、24 FPS、约 5.17 秒。使用 2× 放大后,最终得到 1728×960、H.264、24 FPS 的视频,再把源文件中的 AAC 音频安全合并进去。文件可以正常播放,声音和画面时长一致。

FlashVSR 工作流图 图 1:从解码、分块推理到音频合并的完整流程

这里有一个很容易被标题党掩盖的事实:2× 不等于严格 1920×1080。864×480 的比例不是 16:9,简单乘以二就是 1728×960。如果硬拉成 1920×1080,就会改变画面比例或引入裁切。因此这次的目标应该说是“接近 1080P 的清晰度档位”,而不是承诺输出尺寸一定为 1920×1080。

分辨率变化示意图 图 2:保留源比例时,2× 输出是 1728×960

2. 为什么先研究 RTX 50 系兼容性?

RTX 5060 Ti 属于 Blackwell 世代。很多 AI 项目在新显卡上市时,并不是模型本身坏了,而是“翻译链”中有一层还不认识新硬件:驱动负责看见显卡,CUDA runtime 负责解释 GPU 指令,PyTorch wheel 再把这些能力交给上层应用。任何一层出错,上层都可能只告诉你“没有设备”。

CUDA 分层图 图 3:把驱动、CUDA、PyTorch 和 FlashVSR 想成四层翻译链

我的实际验证结果是:驱动报告 CUDA 13.1,环境里的 PyTorch 为 2.8.0+cu128,内置 CUDA runtime 为 12.8,torch.cuda.is_available() 返回 True,设备名称正确显示为 RTX 5060 Ti。这里最重要的经验是:不要只看驱动面板上的 CUDA 版本,也不要把某一个版本号写成永恒真理,直接在目标环境中验证。

python -c "import torch; print(torch.__version__); print(torch.version.cuda); print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0)); print(torch.cuda.get_device_capability(0))"

显卡检测截图 图 4:脱敏后的显卡检测结果

PyTorch CUDA 截图 图 5:脱敏后的 PyTorch 验证结果

官方 FlashVSR 使用的 Block-Sparse-Attention 对 CUDA 编译环境更敏感;社区版 FlashVSR_plus 提供了 SageAttention、DiT 分块和 VAE 分块选项,更适合先在消费级 Windows 机器上验证。分块就像把一张大海报裁成小方块逐片处理,显存峰值会下降,但边界需要 overlap 进行柔和拼接。

3. 安装路线:为什么 PyTorch 要单独装?

我选择便携 Miniconda,并建立 Python 3.11 环境。安装顺序很重要:

  1. 克隆 FlashVSR_plus 到一个不含隐私信息的目录,例如 D:\AI\FlashVSR
  2. 创建 flashvsr 环境。
  3. 从 PyTorch CUDA wheel 源单独安装 torch 和 torchvision。
  4. 再从普通 PyPI 安装 gradio、einops、safetensors、imageio-ffmpeg 等依赖。
  5. 将模型下载到项目自己的 models/FlashVSR 缓存目录。

曾经踩过的坑是把整个 requirements.txt 都配上 PyTorch 专用 index,结果 gradio 根本找不到。原因很简单:专用仓库像“只卖显卡的商店”,不负责普通 Python 包。

# PyTorch 使用官方 CUDA wheel index;版本请以官方选择器为准
python -m pip install torch==2.8.0 torchvision==0.23.0 `
  --index-url https://download.pytorch.org/whl/cu128

# 普通依赖回到 PyPI
python -m pip install gradio einops safetensors tqdm pillow `
  imageio imageio-ffmpeg ffmpeg-python huggingface_hub hf-xet triton-windows

模型首次运行会下载 JunhaoZhuang/FlashVSR。如果模型已经缓存,后续可以断网运行;镜像地址应作为可选配置,不要把 token 写进脚本或文章。

4. 问题表现一:明明有显卡,却说没有设备

第一次运行直接失败:

RuntimeError: No devices found to run FlashVSR!

设备探测错误截图 图 6:第一层错误并不等于显卡不兼容

根因在源码:run.py 导入时就缓存了 devices = get_device_list(),而 get_device_list() 为了“友好”地吞掉 CUDA 初始化异常,使用了宽泛的 except。一旦初始化时机不对,后续即使显式传入 -d cuda:0,缓存也可能仍为空。

排查顺序应该是:

  1. 用同一个 Python 解释器单独验证 torch CUDA。
  2. 确认 ComfyUI 等程序已经关闭,避免显存被占满。
  3. 显式传入 -d cuda:0
  4. 如果仍失败,再检查驱动、PyTorch wheel 和项目依赖,而不是马上重装整个系统。

5. 问题表现二:temp_name 未初始化

模型下载成功后,第二次失败更具体:

UnboundLocalError: cannot access local variable 'temp_name'

源码 bug 截图 图 7:tiled tiny 模式的变量初始化 bug

代码只在 tiny-long 分支里定义临时视频文件名,但 tiny 分支也把这个变量传给了 pipeline。解决办法不是改参数,而是给每一个 tile 都先分配名字:

temp_name = os.path.join(temp, f"tile_{i+1:05d}.mp4")
if mode == "tiny-long":
    temp_name = os.path.join(local_temp, f"{i+1:05d}.mp4")

这是一次典型的“用户配置错误”和“项目源码 bug”边界案例。看到 traceback 后,先定位变量生命周期,不要把所有问题都归结为显卡性能。

6. 问题表现三:FFmpeg 明明安装了,程序还是找不到

conda 版本 FFmpeg 曾出现 Windows DLL 启动异常。后来改用 imageio-ffmpeg 自带的静态程序,并把它所在的 binaries 目录加入 PATH。原因是 FlashVSR 的检查方式是 shutil.which('ffmpeg'),它只认 PATH,不会自动读取 Python 包内部路径。

$env:PATH="$env:CONDA_PREFIX\Lib\site-packages\imageio_ffmpeg\binaries;$env:PATH"
ffmpeg -version

音频合并截图 图 8:视频流复制、音频重新编码并合并

FlashVSR 输出默认没有音频,因此最后用 FFmpeg 做 mux:

ffmpeg -y -i superres.mp4 -i input.mp4 `
  -map 0:v:0 -map 1:a:0? -c:v copy -c:a aac -shortest final.mp4

-map 1:a:0? 中的问号很有用:如果输入没有音频,命令不会因为“找不到可选音频流”而失败。原始文件只读,输出写入新文件。

7. 真正的内存瓶颈:不是显存,而是 CPU RAM

最容易误判的一次失败是:显卡显存还有余量,但程序在 CPU 上申请约 1.24 GB 的画布时失败。

RuntimeError: DefaultCPUAllocator: not enough memory

tiled_dit 只降低了 GPU 侧的峰值;tiny 模式仍会为所有帧创建完整的 final_output_canvasweight_sum_canvas。这就像把大海报分块送进打印机,却仍然要求桌面先铺开两张完整海报。

解决策略:

成功 tile 推理截图 图 9:成功完成 8 个 tile 的脱敏日志

8. 最终输出与可复用脚本

最终文件的关键属性如下:

最终文件信息截图 图 10:最终 H.264 + AAC 输出

项目 结果
输入 864×480,24 FPS
输出 1728×960,24 FPS
视频 H.264
音频 AAC
时长 约 5.17 秒
推理 RTX 5060 Ti,2×,tiled

8.1 Windows 11

下载 flashvsr-win11.ps1,放在 FlashVSR 项目目录。脚本会检查输入、Python、CUDA、FFmpeg 和可用内存;默认使用 tiny-long,避免本次遇到的 CPU canvas 分配错误。

Set-ExecutionPolicy -Scope Process Bypass
.\flashvsr-win11.ps1 `
  -InputPath "D:\video\input.mp4" `
  -OutputDir "D:\video\output" `
  -Scale 2

如果模型已缓存,脚本不需要外部服务。需要镜像时显式加 -UseHfMirror

8.2 Ubuntu 26.04

下载 flashvsr-ubuntu26.sh,设置 FLASHVSR_DIRFLASHVSR_PYTHON 后运行:

chmod +x flashvsr-ubuntu26.sh
FLASHVSR_DIR="$HOME/AI/FlashVSR" \
FLASHVSR_PYTHON="$HOME/AI/FlashVSR/.venv/bin/python" \
./flashvsr-ubuntu26.sh ./input.mp4 ./output 2

脚本会要求 nvidia-smi、PyTorch CUDA 和 FFmpeg 都可用。Ubuntu 的驱动和 CUDA 安装方式可能不同,建议使用发行版与 NVIDIA 官方文档的当前版本。

8.3 macOS 26

下载 flashvsr-macos26.sh。它会做硬件检查,然后明确停止。原因不是脚本偷懒,而是本文验证的是 CUDA/SageAttention 路径,不能把 Apple GPU 的 MPS 兼容性伪装成已验证功能。若未来项目提供经过测试的 MPS 后端,应单独测试,不要照搬 CUDA 参数。

8.4 人工执行和 Agent 执行

人工执行适合想掌握每一步的人:先验证硬件,再安装环境,再运行短视频,最后 mux 音频。Agent 自动配置适合重复部署,但必须遵守“只读探测—展示计划—获得批准—执行—验证”的顺序。博客同时提供 flashvsr-agent-template.md,其中明确禁止删除原视频、上传数据和输出隐私信息。

9. Q&A

Q1:为什么不直接输出 1920×1080?

因为源视频比例不是 16:9。可以在后处理阶段选择裁切或加黑边,但那已经是构图决策,不应悄悄由超分脚本替你决定。

Q2:RTX 50 系一定要某个固定 CUDA 版本吗?

不要这样下结论。驱动、runtime 和 PyTorch wheel 是不同层。使用官方安装选择器,并在目标环境运行 CUDA 探针最可靠。

Q3:tiled 能解决所有内存问题吗?

不能。它主要降低 GPU 峰值;如果代码还在 CPU 创建完整输出画布,系统内存仍可能成为瓶颈。

Q4:为什么输出没有声音?

视频超分模型通常只处理视频帧,音频需要用 FFmpeg 从原文件映射到新文件。使用 -c:v copy 可以避免再次压缩视频。

Q5:社区版和官方版如何选择?

先看目标平台和显卡。官方版更接近论文与上游实现;社区版通常提供消费级 GPU 更容易运行的参数。无论选哪一个,都应锁定版本、保存日志,并先用短片测试。

10. 参考资料

最后的经验:超分项目最难的部分,常常不是按下“运行”,而是知道每一层出了什么问题。把环境探针、资源预检、可回退模式和音频 mux 都写进脚本,下一次就不必从一堆 traceback 里猜答案了。

本文阅读量 --