ARM環境(aarch64, arm64)でNVENC
最近は、モバイル・組み込み以外にもarm系統のCPUが広がってきていて、PC・サーバーでも見かけるようになってきたと思う。
とはいえ、(Jetson以外)ARM + NVIDIA GPUな環境はなさそうかな、と思っていたのだけど、そんな中、AWS g5gインスタンスなるものがあることを(いまさら)知った。どうも去年の年末に出たらしく、Graviton2 + Tesla T4GというARM CPU + NVIDIA GPUな環境が用意されているようだ。
まあ普通の人はここで機械学習とかやるのだろうけど、ここではそうじゃなくて、NVENCが動くのかを試してみた。
結論から言うと、NVEncCはそのままではarm環境でビルドできなかったので、コードにちょっと修正をいれた。すると、普通にビルドは完了。
実行については、hwエンコードはできるけど、hwデコードするとエラー終了するという状況。そもそもx86環境では問題ないこともあって、hwデコードがarm環境でうまくいかない原因はまだよくわかっていない。
↓hwエンコード+swデコードでエンコードできた例。

GPUがTesla T4G。Turing世代。
CPUがNeoverse-N1 aarch64となっていて、これがGraviton2のことのようだ。
詳細は続きに。
NVEncCのビルド
とりあえず、今回は一番簡単そうなUbuntu 22.04 arm64版で試してみた。
まず、CUDAをインストールする。
あとは、普通にNVEncCをビルドする手順通りだった。
必須ライブラリを放り込んで、
ビルドするだけ。
Tesla T4G
--check-featuresで問題なく情報取得できた。Tesla T4GはTuring世代なので、HEVC 10bit Bフレームまで対応。
NVENCでエンコード
普通にhwデコード→hwエンコードしようとすると、エラー終了してしまう。少しデバッグして調べてみたが、特にこれという問題は見つからず、残念ながら原因不明のまま。AWS上でデバッグしていると当然GPUインスタンスの費用がじわじわかかるので…(g5g.xlargeで$0.42/hとかだけど)。g5g.microとかないですかね…。
nvenccのバグなのか、ドライバの問題かはわからないけど、どうもhwデコード結果を取得するcuvidMapVideoFrameがうまく動いていないのかなあという感じ。
x86環境ではWindows/Linuxとも問題ないので、うーん、これはいったい…。

--avswをつけて、swデコード→hwエンコードは問題なさそう。H.264エンコード/HEVCエンコードともに問題なかった。

とりあえずARMでもNVENCできた
なぜかhwデコードに失敗してしまい、原因がわからないのが残念だが、hwエンコードは無事NVEncCで動かすことができた。
※ Jetson系統もARM + NVIDIAで、あちらはNVENCのHWエンコード回路はあるけど、NVEncCの必要とするlibnvidia-encode.so/libnvcuvid.soが存在していないので、NVEncCは動かない。(NVENCはgstream APIとかいうのから使うらしい)
まあ、今のところAWSでしかできなさそうだし需要は全くなさそうだけど、今後ARM+NVIDIA GPUな環境がもっと出てきたらこの実装が役立つ…かもしれない。
とはいえ、(Jetson以外)ARM + NVIDIA GPUな環境はなさそうかな、と思っていたのだけど、そんな中、AWS g5gインスタンスなるものがあることを(いまさら)知った。どうも去年の年末に出たらしく、Graviton2 + Tesla T4GというARM CPU + NVIDIA GPUな環境が用意されているようだ。
まあ普通の人はここで機械学習とかやるのだろうけど、ここではそうじゃなくて、NVENCが動くのかを試してみた。
結論から言うと、NVEncCはそのままではarm環境でビルドできなかったので、コードにちょっと修正をいれた。すると、普通にビルドは完了。
実行については、hwエンコードはできるけど、hwデコードするとエラー終了するという状況。そもそもx86環境では問題ないこともあって、hwデコードがarm環境でうまくいかない原因はまだよくわかっていない。
↓hwエンコード+swデコードでエンコードできた例。

GPUがTesla T4G。Turing世代。
CPUがNeoverse-N1 aarch64となっていて、これがGraviton2のことのようだ。
詳細は続きに。
NVEncCのビルド
とりあえず、今回は一番簡単そうなUbuntu 22.04 arm64版で試してみた。
まず、CUDAをインストールする。
sudo apt install -y build-essential
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/sbsa/cuda-ubuntu2204.pin
sudo mv cuda-ubuntu2204.pin /etc/apt/preferences.d/cuda-repository-pin-600
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/sbsa/3bf863cc.pub
sudo add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/sbsa/ /"
sudo apt-get update
sudo apt-get -y install cuda
sudo reboot
あとは、普通にNVEncCをビルドする手順通りだった。
必須ライブラリを放り込んで、
sudo apt -y install \
libavcodec-extra libavcodec-dev libavutil-dev \
libavformat-dev libswresample-dev libavfilter-dev \
libass9 libass-dev
ビルドするだけ。
git clone https://github.com/rigaya/NVEnc --recursive
cd NVEnc
./configure
make -j4
Tesla T4G
--check-featuresで問題なく情報取得できた。Tesla T4GはTuring世代なので、HEVC 10bit Bフレームまで対応。
NVEnc (x64) 6.05 (r2212) by rigaya, Jun 15 2022 11:43:43 (gcc 11.2.0/Linux)
[NVENC API v11.1, CUDA 11.7]
reader: raw, y4m, avs, vpy, avsw, avhw [H.264/AVC, H.265/HEVC, MPEG2, VP8, VP9, VC-1, MPEG1, MPEG4, AV1]
Environment Info
OS : Ubuntu 22.04 LTS (5.15.0-1011-aws)
CPU: Neoverse-N1 aarch64 (4C/4T)
RAM: Used 945 MB, Total 7772 MB
#0: NVIDIA T4G (2560 cores, 1590 MHz)[2147483.64]
NVEnc features
Codec: H.264/AVC
Encoder Engines 1
Max Bframes 4
B Ref Mode 3 (each + only middle)
RC Modes 63
Field Encoding 0 (no)
MonoChrome no
FMO no
Quater-Pel MV yes
B Direct Mode yes
CABAC yes
Adaptive Transform yes
Max Temporal Layers 4
Hierarchial P Frames yes
Hierarchial B Frames yes
Max Level 62 (6.2)
Min Level 10 (1)
4:4:4 yes
Min Width 145
Max Width 4096
Min Height 49
Max Height 4096
Multiple Refs yes
Max LTR Frames 8
Dynamic Resolution Change yes
Dynamic Bitrate Change yes
Forced constant QP yes
Dynamic RC Mode Change no
Subframe Readback yes
Constrained Encoding yes
Intra Refresh yes
Custom VBV Bufsize yes
Dynamic Slice Mode yes
Ref Pic Invalidiation yes
PreProcess no
Async Encoding no
Max MBs 65536
Lossless yes
SAO no
Me Only Mode 1 (I,P frames)
Lookahead yes
AQ (temporal) yes
Weighted Prediction yes
10bit depth no
Codec: H.265/HEVC
Encoder Engines 1
Max Bframes 5
B Ref Mode 3 (each + only middle)
RC Modes 63
Field Encoding 0 (no)
MonoChrome no
Quater-Pel MV yes
B Direct Mode no
Max Temporal Layers 0
Hierarchial P Frames no
Hierarchial B Frames no
Max Level 186 (6.2)
Min Level 30 (1)
4:4:4 yes
Min Width 129
Max Width 8192
Min Height 33
Max Height 8192
Multiple Refs yes
Max LTR Frames 7
Dynamic Resolution Change yes
Dynamic Bitrate Change yes
Forced constant QP yes
Dynamic RC Mode Change no
Subframe Readback yes
Constrained Encoding yes
Intra Refresh yes
Custom VBV Bufsize yes
Dynamic Slice Mode yes
Ref Pic Invalidiation yes
PreProcess no
Async Encoding no
Max MBs 262144
Lossless yes
SAO yes
Me Only Mode 1 (I,P frames)
Lookahead yes
AQ (temporal) yes
Weighted Prediction yes
10bit depth yes
NVDec features
H.264/AVC: nv12, yv12
H.265/HEVC: nv12, yv12, yv12(10bit), yv12(12bit), yuv444, yuv444(10bit), yuv444(12bit)
MPEG1: nv12, yv12
MPEG2: nv12, yv12
MPEG4: nv12, yv12
VP8: nv12, yv12
VP9: nv12, yv12, yv12(10bit), yv12(12bit)
VC-1: nv12, yv12
NVENCでエンコード
普通にhwデコード→hwエンコードしようとすると、エラー終了してしまう。少しデバッグして調べてみたが、特にこれという問題は見つからず、残念ながら原因不明のまま。AWS上でデバッグしていると当然GPUインスタンスの費用がじわじわかかるので…(g5g.xlargeで$0.42/hとかだけど)。g5g.microとかないですかね…。
nvenccのバグなのか、ドライバの問題かはわからないけど、どうもhwデコード結果を取得するcuvidMapVideoFrameがうまく動いていないのかなあという感じ。
x86環境ではWindows/Linuxとも問題ないので、うーん、これはいったい…。

--avswをつけて、swデコード→hwエンコードは問題なさそう。H.264エンコード/HEVCエンコードともに問題なかった。

とりあえずARMでもNVENCできた
なぜかhwデコードに失敗してしまい、原因がわからないのが残念だが、hwエンコードは無事NVEncCで動かすことができた。
※ Jetson系統もARM + NVIDIAで、あちらはNVENCのHWエンコード回路はあるけど、NVEncCの必要とするlibnvidia-encode.so/libnvcuvid.soが存在していないので、NVEncCは動かない。(NVENCはgstream APIとかいうのから使うらしい)
まあ、今のところAWSでしかできなさそうだし需要は全くなさそうだけど、今後ARM+NVIDIA GPUな環境がもっと出てきたらこの実装が役立つ…かもしれない。
スポンサーサイト