“torchcodec is not available”,这行报错我前前后后帮人排查过不少次。它最让人头疼的地方不在于报错本身,而是它出现的位置五花八门:有时候是 import 直接失败,有时候是在 torchvision 里读视频时才蹦出来,还有时候是你在跑某个视频数据集脚本,脚本里 try-except 把真正的 ImportError 吞了,只留给你这么一句含糊的提示。我见过不少同学在这上面折腾一整天,最后发现其实是 Python 环境装错了地方。
先把认知拉齐:torchcodec 是 PyTorch 官方推出的基于 FFmpeg 的视频解码库,它能把视频帧直接解码成 torch.Tensor,支持流式读取、切片读取,也能走 NVDEC 硬件解码。它跟 PyAV、decord 这类库是同一赛道,但因为是官方出品,跟 torch 的 Tensor 类型、DataLoader 协作起来更顺。你只要在做视频预处理、多模态训练、视频推理,大概率会碰到它。这篇文章就把这个报错的底层原因、排查路径、安装和编译注意事项一次讲透。
1. 先搞清楚报错到底是从哪一层蹦出来的
1.1 三种最容易触发这个报错的代码路径
很多人在搜索这个问题时,第一步就搜歪了。因为“torchcodec is not available”并不是 torchcodec 自己定义的唯一错误文案,它通常是你代码里某条 import 语句、某个库内部的兼容检测逻辑、甚至是 torch.ops 加载扩展失败的统一提示。我见过至少三种完全不同的触发场景:
第一种是最直白的:你直接写import torchcodec,而当前 Python 环境里根本没有装这个包。这时 Python 会抛ModuleNotFoundError。如果这段代码被某个框架包了一层,框架在 except 里统一打印“torchcodec is not available”,那你看到的就只有这句提示,真正的 ModuleNotFoundError 反而被吞了。
第二种是走 torchvision 的后端路径。torchvision 从某个版本开始,read_video这类接口允许你显式指定后端:backend="torchcodec"。如果你指定的后端在当前环境里不可用,torchvision 就会报类似“torchcodec backend is not available”的信息。很多人根本没意识到自己在用 torchcodec,只是写“我用 torchvision 读视频”,结果错误却指向 torchcodec,一脸懵。
第三种最隐蔽:依赖 torchcodec 的 C++ 扩展库通过torch.ops注册算子,运行时加载.so或者动态库失败。这种失败会由 PyTorch 的调度机制捕获并报告“operator is not available”。表面看是“torchcodec 不可用”,实际是扩展库虽然装了,但动态库依赖的libtorch符号版本对不上、FFmpeg 动态库缺失、或者 ABI 不兼容,导致算子注册被跳过。
1.2 先定位报错形态,再决定下一步
我的经验是:收到这类报错时,别急着去 pip install,先把完整的错误堆栈显示出来。在 Python 脚本里不要轻易用except Exception吞异常,至少要把traceback.format_exc()打出来。你真正要找的是底层那一行“Caused by”或者最底部那几行 ImportError。
判断一句话:如果报错里同时出现ModuleNotFoundError,基本就是“没安装”或者“装错了环境”;如果报错里有ImportError: undefined symbol或者OSError: libavcodec.so.xx: cannot open shared object file,那就是典型的动态库/ABI 问题;如果报错里带torch.ops字样,那是扩展注册失败。定位到这三类中的哪一类,下面三分之一的排查工作基本就完成了。
提示:排查这类问题最忌讳的就是反复重装 torchcodec,重装不能解决“装错环境”和“ABI 不匹配”两类问题。先看清完整错误,比盲目操作高效得多。
2. 五分钟环境诊断:一屏命令看清真实状态
2.1 一份可以直接抄的检查清单
不管报错形态是哪一种,我建议先从命令行把环境里里外外查一遍。下面这套命令我几乎每次排查都用,信息密度很高:
python --version which python python -c "import sys; print(sys.executable)" python -c "import torch; print('torch', torch.__version__)" python -c "import torchvision; print('torchvision', torchvision.__version__)" python -c "import torchcodec; print('torchcodec', torchcodec.__version__)" pip show torchcodecwhich python和sys.executable这两个最重要。很多人的问题就是:在 VSCode 里选了一个解释器,在终端里用另一个解释器,或者 conda base 跟虚拟环境相互覆盖。你用 pip 装包时,pip指向哪个 Python,import时的 Python 又是哪个,两者只要不一致,后患无穷。
如果上述命令能正常打印 torchcodec 版本,说明库本身已经装好,问题基本在调用方。如果pip show torchcodec有输出但import torchcodec报错,那就是动态库加载问题,下面会细化。
2.2 版本匹配的经验法则
关于版本匹配,我的建议很朴素:优先把 PyTorch 升级到当前最新稳定版,再安装最新稳定版 torchcodec,这是踩坑最少的组合。torchcodec 的 C++ 扩展跟 PyTorch 的 C++ 接口绑定很深,老版本 torch 配新版本 torchcodec 经常出现符号缺失;反过来,老版本 torchcodec 配新版本 torch 一般还好,但官方通常只维护当前 1-2 个 torch 版本。
我自己比较常用的组合参考(以 2025 年上半年的状态为例):
| Python | PyTorch | torchcodec | 结论 |
|---|---|---|---|
| 3.10 / 3.11 | 最新稳定版 | 最新稳定版 | 最省心 |
| 3.10 / 3.11 | 2.2 及更老 | 最新版 | 可能编译失败,建议升级 torch |
| 3.12 | 最新稳定版 | 旧版本 | 常有 wheel 缺失,建议升级 torchcodec |
| 3.8 | 任意 | 任意 | 老环境就别折腾 torchcodec 了 |
这里有一个需要特别注意的细节:torchcodec 的 whl 包名就叫torchcodec,官方在 PyPI 上同时发布正式版和预发布版,预发布版一般对应最新开发特性。如果你只需要稳定的读视频能力,用正式版就够。如果你是冲着 CUDA 硬件解码或新接口去的,才需要考虑预发布版。
2.3 装了却不可用:最隐蔽的三个环境原因
第一种是“装到了 conda 的 base,跑代码却在 venv”。这种情况pip show torchcodec在某个终端里明明有输出,换一个终端/project 解释器就没有。解决方式很简单:只保留一个 Python 环境,或者每次操作前确认sys.executable。
第二种是“系统里存在多个 torch 副本”。比如 conda 里一份、系统/usr/lib/python3/dist-packages里一份,import torch时加载了系统那份,而pip install torchcodec却把扩展装到了 conda 环境的 site-packages。两边 torch 版本不同,torchcodec 加载时就会因为符号版本不匹配而失败。
第三种是“FFmpeg 动态库缺失”。torchcodec 官方 wheel 会把 FFmpeg 静态链接进去,所以你用官方 wheel 一般不会遇到这个问题。但如果是从源码编的,或者某些 Linux 发行版的 Python 环境做了拆分,就可能出现libavcodec.so找不到。排查这类问题可以用:
ldd <torchcodec 安装路径下找到的 .so 文件>看是否有“not found”的输出。这条命令能直接暴露动态库缺失情况。
3. 安装到真正可用:从 wheel 到源码编译的全路径
3.1 官方 wheel 安装的正确姿势
绝大多数情况下,问题的最终解法就是一次干净安装。我推荐的顺序是:
# 第一步:升级 PyTorch 和 torchvision 到最新稳定版 pip install --upgrade torch torchvision # 第二步:安装 torchcodec pip install torchcodec如果官方 PyPI 上只有预发布版适合你的环境,或者你想尝鲜新特性:
pip install --pre torchcodec安装完成后,建议立刻做一次最小验证:
python -c "import torchcodec; print(torchcodec.__version__)"能打印版本号,这个环境基本就通了。这里多说一句:torchcodec 的 wheel 体积偏大,因为它捆绑了 FFmpeg 静态库,下载慢、安装慢都很正常,不要以为卡死了。这个体积也是很多人“pip install 之后以为没装上”的原因,耐心一点。
3.2 源码编译时最容易翻车的几个点
如果你需要定制 FFmpeg 组件、调试底层解码逻辑,或者官方 wheel 不支持你的平台,就得走源码编译。编译 torchcodec 的前提是当前 Python 环境已经装好 torch,并且能找到 FFmpeg 开发库。Linux 下的典型步骤:
sudo apt install -y cmake libavcodec-dev libavformat-dev libavutil-dev libswscale-dev git clone https://github.com/pytorch/torchcodec.git cd torchcodec python setup.py install这里我踩过的坑有三个,逐一说明。第一个是编译时用错了 Python 环境:务必用你最终跑代码的那个解释器来执行python setup.py install,因为setup.py会通过torch.utils.cpp_extension去定位 torch 的 include 路径和库目录,如果当前 Python 里的 torch 跟你实际要用的 torch 不一致,编出来的扩展等于白编。第二个是 FFmpeg dev 包必须齐:只装libavcodec-dev不够,libavformat-dev和libavutil-dev也会用到,缺一个就可能在 cmake 阶段报 “Could NOT find FFmpeg”。第三个是 C++ ABI 一致性:如果你的 torch 是官方预编译版,默认用的_GLIBCXX_USE_CXX11_ABI=1;如果你用系统 GCC 从源码编译,有时默认是 0,两边对不上就会出现 undefined symbol。遇到这类报错,给setup.py显式传编译选项,把自己的构建对齐到 torch 的 ABI。
3.3 和 torchvision 后端联动的配置细节
torchvision 从新版本开始,read_video接口增加了 backend 参数。常见写法是:
from torchvision.io import read_video frames, audio, info = read_video( "video.mp4", backend="torchcodec", )如果你没有安装 torchcodec,或者 torchcodec 在当前环境不可用,这里就会报出跟标题一模一样的错误。解法就一句话:先让import torchcodec能通过,再回到这段代码。
如果你不想显式写 backend,torchvision 会按内置优先级自动选择可用的后端。这时候你需要确认 torchvision 是否优先选中了 torchcodec。可以这样查:
import torchvision from torchvision.io import read_video print(vars(read_video))看里面的 backend 相关默认值。实际上,对你来说最关键的是理解:torchvision 的可选后端机制,决定了“torchcodec 不可用”是很常见的中间态错误。只要你的环境里既有 torchvision 又有 torchcodec,两者版本差得不太离谱,一般会自动选择成功。
4. 实操中真正困扰人的几个场景
4.1 WSL2 环境下的“灵异”现象
我在 WSL2 上也被这个问题坑过。现象描述起来很“诡异”:Windows 侧能import torchcodec,WSL2 里却报不可用;或者反过来。原因其实不复杂——WSL2 是一个独立的 Linux 环境,它的 Python、库目录、动态链接路径跟 Windows 侧完全隔离。你在 Windows 的 CMD 里 pip install 的包,WSL2 里一个都用不上。
所以 WSL2 用户的第一原则是:在 WSL2 内部的终端重新装一遍 torch、torchvision、torchcodec。如果你在 WSL2 里用 conda,记得先激活目标环境再装。
还有一个 WSL2 特有的坑:如果你在 WSL2 里从源码编译 torchcodec,apt 安装的 FFmpeg dev 包版本可能偏旧,导致编出来的库跟某些视频格式不兼容。这时候优先考虑直接用官方 manylinux wheel,绕开本地的 FFmpeg 依赖链。
4.2 内存明明很充裕却提示不足:swap 满和 available 的真相
这个话题看着跟 torchcodec 没关系,但在视频解码场景里经常一起出现。用户会把“swap 用满但 available 还剩很多”当作系统异常,怀疑是 torchcodec 泄漏内存。实际上这是 Linux 内存管理的正常表现:大量解码产生的 page cache 可以被系统回收,free里的available统计的就是可回收内存,所以 swap 高不一定代表内存不够,关键是看available是否持续走低。
真正需要注意的点是 torchcodec 的读取方式。一次性把所有帧读进内存(比如很多人习惯的frames = decoder[:])会在短时间内吃掉大量内存,大视频足以触发 OOM。正确做法是用迭代器逐帧读取:
from torchcodec.decoders import VideoDecoder with VideoDecoder("video.mp4") as decoder: for frame, metadata in decoder: # 逐帧处理,内存占用稳定 ...这段代码背后的原理是:逐帧读取时,FFmpeg 的解码缓冲区和 torch tensor 的申请都控制在单帧级别,内存峰值低得多。如果你确实需要批量读取,也建议先读取 metadata 估算帧数,再分块切片处理,而不是一把梭。
4.3 GPU 解码:为什么装了 CUDA 版还是不行
torchcodec 的硬件解码走的是 NVDEC,跟 PyTorch 的 CUDA 运算是两套体系。很多人以为 “torch 是 CUDA 版,torchcodec 就能用 GPU 解码”,这完全不对。NVDEC 需要 FFmpeg 在构建时启用对应 hwaccel,并且你的驱动要支持对应视频编码格式。
判断你的环境能不能用 GPU 解码,先看两个基本点:第一,torch.cuda.is_available()必须为 True;第二,torchcodec 的构建配置里是否带了 CUDA 支持。官方 wheel 的 GPU 支持范围通常写在发布说明里,如果你是源码编译,需要在 cmake 阶段显式开启。如果你的解码任务是 CPU 为主的大批量短视频,GPU 加速带来的调度开销有时反而让整体更慢,所以不要盲目追求硬件解码。
5. 全套报错速查表:把“不可用”翻译成人话
我把实际工作中遇到过、以及社区里高频出现的几类报错整理成一张速查表,排查时可以先对照定位方向。
| 报错信息 | 真实含义 | 最直接的解决办法 |
|---|---|---|
ModuleNotFoundError: No module named 'torchcodec' | 当前环境没装 | 确认sys.executable,用正确解释器的 pip 安装 |
RuntimeError: torchcodec is not available | 有安装但加载失败,或被上层吞掉了异常 | 去掉异常捕获,打印完整 traceback |
ImportError: undefined symbol | C++ ABI 或 torch 版本不匹配 | 升级 torch/torchcodec 到匹配版本,或源码编译时对齐 ABI |
OSError: libavcodec.so: cannot open shared object file | 动态库缺失 | 官方 wheel 一般不会出现,多半是源码编译缺 FFmpeg |
Could NOT find FFmpeg | 编译时找不到 FFmpeg dev 包 | 安装 libavcodec-dev 等开发包 |
torchvisionread_video报后端不可用 | 显式指定了 torchcodec 但环境未安装 | 先验证import torchcodec,再回来调接口 |
| 解码某个视频时提示无 decoder | FFmpeg 不认识该视频编码 | 用ffprobe查视频编码格式,换合法编码 |
再补充一个排查思路:在环境变量里临时打开详细日志,往往能看到被隐藏的真实错误:
export TORCH_LOGS=+torchcodec这样再跑你的脚本,torchcodec 内部初始化的过程会被打印出来,哪里失败一目了然。实测下来比盲猜快得多。
最后再分享一个小技巧:不要在一个虚拟环境里把“PyTorch 视频生态”相关的东西装得过于杂乱。torchvision、torchcodec、PyAV、decord 这四兄弟很容易在 site-packages 里打架,因为它们都依赖 FFmpeg,但捆绑的 FFmpeg 版本和链接方式不同。我的习惯是项目里只用 torchvision + torchcodec,要么只用 PyAV,从不混着用。一旦你把“torchcodec is not available”定位成环境层面的问题,最干净的收尾方式就是新建一个虚拟环境,只装当前项目需要的依赖,然后再跑一遍验证脚本。大部分顽固问题,在这一步之后都消失了。