啟用 GPU 視訊解碼器/編碼器¶
TorchAudio 可以使用底層 FFmpeg 函式庫所支援的基於硬體的視訊解碼和編碼,這些函式庫在執行時連結。
使用 NVIDIA 的 GPU 解碼器和編碼器,也可以直接傳遞 CUDA Tensor,也就是將視訊解碼到 CUDA tensor 中,或從 CUDA tensor 編碼視訊,而無需在 CPU 之間移動資料。
這顯著提高了視訊吞吐量。但是,請注意,並非所有視訊格式都支援硬體加速。
本頁介紹如何使用硬體加速建置 FFmpeg。有關 GPU 解碼器和編碼器的效能詳情,請參閱NVDEC 教學和NVENC 教學。
概述¶
在 TorchAudio 中使用它們需要額外的 FFmpeg 配置。
在下面,我們研究如何使用NVIDIA 的視訊編解碼器 SDK 啟用 GPU 視訊解碼。要將 NVENC/NVDEC 與 TorchAudio 結合使用,需要以下項目。
具有硬體視訊解碼器/編碼器的 NVIDIA GPU。
使用 NVDEC/NVENC 支援編譯的 FFmpeg 函式庫。 †
具有 CUDA 支援的 PyTorch / TorchAudio。
TorchAudio 的官方二進位發行版經過編譯,可以使用 FFmpeg 函式庫,並且它們包含使用硬體解碼/編碼的邏輯。
在下面,我們建置具有 NVDEC/NVENC 支援的 FFmpeg 4 函式庫。您也可以使用 FFmpeg 5 或 6。
以下程序已在 Ubuntu 上進行測試。
† 有關 NVDEC/NVENC 和 FFmpeg 的詳細資訊,請參閱以下文章。
檢查 GPU 和 CUDA 版本¶
首先,檢查可用的 GPU。在這裡,我們安裝了 CUDA Toolkit 11.2 的 Tesla T4。
$ nvidia-smi
Fri Oct 7 13:01:26 2022
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 460.32.03 Driver Version: 460.32.03 CUDA Version: 11.2 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|===============================+======================+======================|
| 0 Tesla T4 Off | 00000000:00:04.0 Off | 0 |
| N/A 56C P8 10W / 70W | 0MiB / 15109MiB | 0% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| No running processes found |
+-----------------------------------------------------------------------------+
檢查運算能力 (Compute Capability)¶
稍後,我們需要此 GPU 支援的運算能力版本。以下頁面列出了 GPU 和對應的運算能力。 T4 的運算能力為 7.5
。
安裝 NVIDIA Video Codec 標頭檔¶
要使用 NVDEC/NVENC 建置 FFmpeg,我們首先需要安裝 FFmpeg 用來與 Video Codec SDK 互動的標頭檔。
由於我們的系統中 CUDA 11 可以正常運作,因此我們使用 n11
標籤之一。
git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git
cd nv-codec-headers
git checkout n11.0.10.1
sudo make install
可以使用 make PREFIX=<DESIRED_DIRECTORY> install
變更安裝位置。
Cloning into 'nv-codec-headers'...
remote: Enumerating objects: 819, done.
remote: Counting objects: 100% (819/819), done.
remote: Compressing objects: 100% (697/697), done.
remote: Total 819 (delta 439), reused 0 (delta 0)
Receiving objects: 100% (819/819), 156.42 KiB | 410.00 KiB/s, done.
Resolving deltas: 100% (439/439), done.
Note: checking out 'n11.0.10.1'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b <new-branch-name>
HEAD is now at 315ad74 add cuMemcpy
sed 's#@@PREFIX@@#/usr/local#' ffnvcodec.pc.in > ffnvcodec.pc
install -m 0755 -d '/usr/local/include/ffnvcodec'
install -m 0644 include/ffnvcodec/*.h '/usr/local/include/ffnvcodec'
install -m 0755 -d '/usr/local/lib/pkgconfig'
install -m 0644 ffnvcodec.pc '/usr/local/lib/pkgconfig'
安裝 FFmpeg 依賴套件¶
接下來,我們安裝 FFmpeg 建置期間所需的工具和函式庫。最低要求是 Yasm。在這裡,我們額外安裝 H264 視訊編碼器和 HTTPS 協定,稍後我們將使用它們來驗證安裝。
sudo apt -qq update
sudo apt -qq install -y yasm libx264-dev libgnutls28-dev
... Omitted for brevity ...
STRIP install-libavutil-shared
Setting up libx264-dev:amd64 (2:0.152.2854+gite9a5903-2) ...
Setting up yasm (1.3.0-2build1) ...
Setting up libunbound2:amd64 (1.6.7-1ubuntu2.5) ...
Setting up libp11-kit-dev:amd64 (0.23.9-2ubuntu0.1) ...
Setting up libtasn1-6-dev:amd64 (4.13-2) ...
Setting up libtasn1-doc (4.13-2) ...
Setting up libgnutlsxx28:amd64 (3.5.18-1ubuntu1.6) ...
Setting up libgnutls-dane0:amd64 (3.5.18-1ubuntu1.6) ...
Setting up libgnutls-openssl27:amd64 (3.5.18-1ubuntu1.6) ...
Setting up libgmpxx4ldbl:amd64 (2:6.1.2+dfsg-2) ...
Setting up libidn2-dev:amd64 (2.0.4-1.1ubuntu0.2) ...
Setting up libidn2-0-dev (2.0.4-1.1ubuntu0.2) ...
Setting up libgmp-dev:amd64 (2:6.1.2+dfsg-2) ...
Setting up nettle-dev:amd64 (3.4.1-0ubuntu0.18.04.1) ...
Setting up libgnutls28-dev:amd64 (3.5.18-1ubuntu1.6) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
Processing triggers for libc-bin (2.27-3ubuntu1.6) ...
建置支援 NVDEC/NVENC 的 FFmpeg¶
接下來,我們下載 FFmpeg 4 的原始碼。這裡我們使用 4.4.2。
wget -q https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n4.4.2.tar.gz
tar -xf n4.4.2.tar.gz
cd FFmpeg-n4.4.2
接下來,我們設定 FFmpeg 建置。請注意以下事項:
我們提供諸如
-I/usr/local/cuda/include
、-L/usr/local/cuda/lib64
之類的 flag,以讓建置過程知道 CUDA 函式庫的位置。我們提供諸如
--enable-nvdec
和--enable-nvenc
之類的 flag,以啟用 NVDEC/NVENC。我們還提供 NVCC flag,其運算能力為
75
,對應於 T4 的7.5
。 †我們將函式庫安裝在
/usr/lib/
中。
注意
† 設定腳本透過編譯範例程式碼來驗證 NVCC。 預設情況下,它使用舊的運算能力,例如 30
,CUDA 11 不再支援此功能。 因此,需要設定正確的運算能力。
prefix=/usr/
ccap=75
./configure \
--prefix="${prefix}" \
--extra-cflags='-I/usr/local/cuda/include' \
--extra-ldflags='-L/usr/local/cuda/lib64' \
--nvccflags="-gencode arch=compute_${ccap},code=sm_${ccap} -O2" \
--disable-doc \
--enable-decoder=aac \
--enable-decoder=h264 \
--enable-decoder=h264_cuvid \
--enable-decoder=rawvideo \
--enable-indev=lavfi \
--enable-encoder=libx264 \
--enable-encoder=h264_nvenc \
--enable-demuxer=mov \
--enable-muxer=mp4 \
--enable-filter=scale \
--enable-filter=testsrc2 \
--enable-protocol=file \
--enable-protocol=https \
--enable-gnutls \
--enable-shared \
--enable-gpl \
--enable-nonfree \
--enable-cuda-nvcc \
--enable-libx264 \
--enable-nvenc \
--enable-cuvid \
--enable-nvdec
install prefix /usr/
source path .
C compiler gcc
C library glibc
ARCH x86 (generic)
big-endian no
runtime cpu detection yes
standalone assembly yes
x86 assembler yasm
MMX enabled yes
MMXEXT enabled yes
3DNow! enabled yes
3DNow! extended enabled yes
SSE enabled yes
SSSE3 enabled yes
AESNI enabled yes
AVX enabled yes
AVX2 enabled yes
AVX-512 enabled yes
XOP enabled yes
FMA3 enabled yes
FMA4 enabled yes
i686 features enabled yes
CMOV is fast yes
EBX available yes
EBP available yes
debug symbols yes
strip symbols yes
optimize for size no
optimizations yes
static no
shared yes
postprocessing support no
network support yes
threading support pthreads
safe bitstream reader yes
texi2html enabled no
perl enabled yes
pod2man enabled yes
makeinfo enabled no
makeinfo supports HTML no
External libraries:
alsa libx264 lzma
bzlib libxcb zlib
gnutls libxcb_shape
iconv libxcb_xfixes
External libraries providing hardware acceleration:
cuda cuvid nvenc
cuda_llvm ffnvcodec v4l2_m2m
cuda_nvcc nvdec
Libraries:
avcodec avformat swscale
avdevice avutil
avfilter swresample
Programs:
ffmpeg ffprobe
Enabled decoders:
aac hevc rawvideo
av1 mjpeg vc1
h263 mpeg1video vp8
h264 mpeg2video vp9
h264_cuvid mpeg4
Enabled encoders:
h264_nvenc libx264
Enabled hwaccels:
av1_nvdec mpeg1_nvdec vp8_nvdec
h264_nvdec mpeg2_nvdec vp9_nvdec
hevc_nvdec mpeg4_nvdec wmv3_nvdec
mjpeg_nvdec vc1_nvdec
Enabled parsers:
h263 mpeg4video vp9
Enabled demuxers:
mov
Enabled muxers:
mov mp4
Enabled protocols:
file tcp
https tls
Enabled filters:
aformat hflip transpose
anull null trim
atrim scale vflip
format testsrc2
Enabled bsfs:
aac_adtstoasc null vp9_superframe_split
h264_mp4toannexb vp9_superframe
Enabled indevs:
lavfi
Enabled outdevs:
License: nonfree and unredistributable
現在我們建置並安裝
make clean
make -j
sudo make install
... Omitted for brevity ...
INSTALL libavdevice/libavdevice.so
INSTALL libavfilter/libavfilter.so
INSTALL libavformat/libavformat.so
INSTALL libavcodec/libavcodec.so
INSTALL libswresample/libswresample.so
INSTALL libswscale/libswscale.so
INSTALL libavutil/libavutil.so
INSTALL install-progs-yes
INSTALL ffmpeg
INSTALL ffprobe
檢查安裝¶
為了驗證我們建置的 FFmpeg 是否支援 CUDA,我們可以檢查可用的解碼器和編碼器清單。
ffprobe -hide_banner -decoders | grep h264
VFS..D h264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
V..... h264_cuvid Nvidia CUVID H264 decoder (codec h264)
ffmpeg -hide_banner -encoders | grep 264
V..... libx264 libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (codec h264)
V....D h264_nvenc NVIDIA NVENC H.264 encoder (codec h264)
以下命令從遠端伺服器獲取影片,使用 NVDEC (cuvid) 解碼,然後使用 NVENC 重新編碼。如果此命令不起作用,則 FFmpeg 安裝存在問題,TorchAudio 也將無法使用它們。
$ src="https://download.pytorch.org/torchaudio/tutorial-assets/stream-api/NASAs_Most_Scientifically_Complex_Space_Observatory_Requires_Precision-MP4_small.mp4"
$ ffmpeg -hide_banner -y -vsync 0 \
-hwaccel cuvid \
-hwaccel_output_format cuda \
-c:v h264_cuvid \
-resize 360x240 \
-i "${src}" \
-c:a copy \
-c:v h264_nvenc \
-b:v 5M test.mp4
請注意,這裡有 Stream #0:0 -> #0:0 (h264 (h264_cuvid) -> h264 (h264_nvenc))
,這表示影片是使用 h264_cuvid
解碼器和 h264_nvenc
編碼器進行解碼。
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'https://download.pytorch.org/torchaudio/tutorial-assets/stream-api/NASAs_Most_Scientifically_Complex_Space_Observatory_Requires_Precision-MP4_small.mp4':
Metadata:
major_brand : mp42
minor_version : 512
compatible_brands: mp42iso2avc1mp41
encoder : Lavf58.76.100
Duration: 00:03:26.04, start: 0.000000, bitrate: 1294 kb/s
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 960x540 [SAR 1:1 DAR 16:9], 1156 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default)
Metadata:
handler_name : ?Mainconcept Video Media Handler
vendor_id : [0][0][0][0]
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : #Mainconcept MP4 Sound Media Handler
vendor_id : [0][0][0][0]
Stream mapping:
Stream #0:0 -> #0:0 (h264 (h264_cuvid) -> h264 (h264_nvenc))
Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
Output #0, mp4, to 'test.mp4':
Metadata:
major_brand : mp42
minor_version : 512
compatible_brands: mp42iso2avc1mp41
encoder : Lavf58.76.100
Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), cuda(tv, bt709, progressive), 360x240 [SAR 1:1 DAR 3:2], q=2-31, 5000 kb/s, 29.97 fps, 30k tbn (default)
Metadata:
handler_name : ?Mainconcept Video Media Handler
vendor_id : [0][0][0][0]
encoder : Lavc58.134.100 h264_nvenc
Side data:
cpb: bitrate max/min/avg: 0/0/5000000 buffer size: 10000000 vbv_delay: N/A
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : #Mainconcept MP4 Sound Media Handler
vendor_id : [0][0][0][0]
frame= 6175 fps=1712 q=11.0 Lsize= 37935kB time=00:03:26.01 bitrate=1508.5kbits/s speed=57.1x
video:34502kB audio:3234kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.526932%
從 TorchAudio 使用 GPU 解碼器/編碼器¶
檢查安裝¶
一旦 FFmpeg 能夠正常運作硬體加速功能,我們需要檢查 TorchAudio 是否可以正確地將其拾取。
在 torchaudio.utils.ffmpeg_utils
中有一些實用函數可以用來查詢 FFmpeg 的功能。
您可以先使用 get_video_decoders()
和 get_video_encoders()
來檢查是否列出了 GPU 解碼器和編碼器 (例如 h264_cuvid
和 h264_nvenc
)。
通常情況下,系統中有多個 FFmpeg 安裝,而 TorchAudio 載入的與預期不同。在這種情況下,使用 ffmpeg
檢查安裝沒有幫助。您可以使用諸如 get_build_config()
和 get_versions()
之類的函數來獲取有關 TorchAudio 載入的 FFmpeg 函式庫的資訊。
from torchaudio.utils import ffmpeg_utils
print("Library versions:")
print(ffmpeg_utils.get_versions())
print("\nBuild config:")
print(ffmpeg_utils.get_build_config())
print("\nDecoders:")
print([k for k in ffmpeg_utils.get_video_decoders().keys() if "cuvid" in k])
print("\nEncoders:")
print([k for k in ffmpeg_utils.get_video_encoders().keys() if "nvenc" in k])
Library versions:
{'libavutil': (56, 31, 100), 'libavcodec': (58, 54, 100), 'libavformat': (58, 29, 100), 'libavfilter': (7, 57, 100), 'libavdevice': (58, 8, 100)}
Build config:
--prefix=/usr --extra-version=0ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
Decoders:
['h264_cuvid', 'hevc_cuvid', 'mjpeg_cuvid', 'mpeg1_cuvid', 'mpeg2_cuvid', 'mpeg4_cuvid', 'vc1_cuvid', 'vp8_cuvid', 'vp9_cuvid']
Encoders:
['h264_nvenc', 'nvenc', 'nvenc_h264', 'nvenc_hevc', 'hevc_nvenc']
使用硬體解碼器和編碼器¶
一旦安裝和執行階段連結都正常工作,您就可以使用以下程式碼測試 GPU 解碼。