Uporaba grafičnih procesnih enot
Grafična procesna enota (angl. graphics processing unit) ali GPE je poseben procesor, v osnovi namenjen izrisovanju slike na zaslon. Med drugim so GPE optimizirane za hitro računanje z vektorji in matrikami, ki je pogosta operacija pri delu z grafiko. Čeprav GPE niso primerne za reševanje splošnih problemov, se izkaže, da so operacije, ki jih znajo GPE zelo hitro izvesti uporabne tudi v drugih domenah, na primer strojnem učenju in rudarjenju kriptovalut. Prav tako imajo sodobne GPE vgrajeno podporo za delo z nekaterimi vrstami videoposnetkov. Poglejmo, kako lahko uporabimo GPE za hitrejšo pretvorbo videoposnetka v drug zapis.
Programi, kot je ffmpeg
, lahko GPE različnih proizvajalcev uporabljajo preko standardnih vmesnikov. Najpogosteje se uporabljata OpenCL in CUDA. Slednji je namenjen samo za grafične procesne enote podjetja Nvidia. Ti so nameščeni tudi v gruči ARNES.
Pripravljanje vsebnika
Program ffmpeg
privzeto ne podpira GPE, temveč ga moramo prevesti s posebnimi nastavitvami. Tu bomo uporabili obstoječi vsebnik za Docker, ki že vsebuje ustrezno različico programa ffmpeg
. V vsebnik za Apptainer ga pretvorimo z ukazom
$ apptainer pull docker://jrottenberg/ffmpeg:7-nvidia
apptainer pull docker://jrottenberg/ffmpeg:7-nvidia
V trenutnem imeniku smo ustvarili vsebnik ffmpeg_7-nvidia.sif
. Ta vsebnik uporabimo kot običajno z ukazom apptainer exec
:
$ apptainer exec ffmpeg_7-nvidia.sif ffmpeg -version
fmpeg version 7.0 Copyright (c) 2000-2024 the FFmpeg developers
built with gcc 13 (Ubuntu 13.2.0-23ubuntu4)
configuration: --disable-debug --disable-doc --disable-ffplay --enable-cuda --enable-cuvid ...
apptainer exec ffmpeg_7.nvidia.sif ffmpeg -version
Zgronji ukaz vidimo nam izpiše nastavitve, ki vklopijo podporo za GPE (CUDA) in sorodne tehnologije. Tehnologije, ki jih podpira neka različica ffmpeg
, lahko preverimo z argumentom -hwaccels
:
$ apptainer exec ffmpeg_7-nvidia.sif ffmpeg -hwaccels
ffmpeg version 7.0 Copyright (c) 2000-2024 the FFmpeg developers
...
Hardware acceleration methods:
vdpau
cuda
vaapi
drm
apptainer exec ffmpeg_7-nvidia.sif ffmpeg -hwaccels
Obdelava videoposnetka na grafični procesni enoti
Najprej moramo nastaviti ustrezno okoljsko spremenljivko, s katero definiramo vrste operacij, ki jih lahko izvajamo na grafični procesni enoti.
$ export NVIDIA_DRIVER_CAPABILITIES=compute,utility,video
export NVIDIA_DRIVER_CAPABILITIES=compute,utility,video
Preizkusili bomo knjižnico cuda
, ki med drugim zna kodirati zapis H.264 na grafični procesni enoti. Če želimo v poslih uporabljati grafične procesne enote, moramo podati ustrezne argumente:
$ srun --partition=gpu --gpus=1 apptainer exec --nv ffmpeg_7-nvidia.sif ffmpeg \
-hwaccel cuda -hwaccel_output_format cuda \
-y -i llama.mp4 -codec:a copy -filter:v scale_npp=640:360 \
-codec:v h264_nvenc gpe-llama.mp4
srun --partition=gpu --gpus=1 apptainer exec --nv ffmpeg_7-nvidia.sif ffmpeg -hwaccel cuda -hwaccel_output_format cuda -y -i llama.mp4 -codec:a copy -filter:v scale_npp=640:360 -codec:v h264_nvenc gpe-llama.mp4
Najprej z argumentom --gpus=1
od Slurma zahtevamo vozlišče z eno grafično procesno enoto. Na dodeljenem vozlišču zaženemo vsebnik s apptainer exec --nv
. S stikalom --nv
dovolimo, da programi v vsebniku lahko dostopajo do grafične procesne enote. Končno zahtevamo, da program ffmpeg
dejansko uporabi grafično pospeševanje za kodiranje videa. Ker ffmpeg
ne zna avtomatsko zaznati prisotnosti grafične procesne enote in zagnati ustreznih funkcij, zahteve podamo sami:
- s
-hwaccel cuda -hwaccel_output_format cuda
naložimo ustrezne knjižnice, - s
scale_npp
povemo, naj namesto običajnega filtrascale
uporablja filter, pripravljen za grafične procesne enote (npp - Nvidia performance primitives), - s
-codec:v h264_nvenc
pa izberemo kodirni algoritem H.264, pripravljen za grafične procesne enote.
Ostale nastavitve so enake kot prej. V vseh dosedanjih klicih programa ffmpeg
nismo navajali kodirnega algoritma, saj je nastavitev -codec: v h264
privzeta in jo zato lahko izpustimo.
Če je šlo vse po sreči, poteka kodiranje zdaj precej hitreje:
frame=19037 fps=273 q=14.0 Lsize= 162042kB time=00:10:34.55 bitrate=2091.9kbits/s speed= 9.1x
Za razliko od prejšnjih pristopov te pohitritve nismo dosegli z vzporedno obdelavo na nivoju datotek, temveč smo za samo kodiranje videoposnetka uporabili strojno opremo, ki zna zahtevane operacije izvajati veliko hitreje. Tudi tu gre v resnici za vzporedno računanje, a na precej nižjem nivoju, saj lahko GPE pri kodiranju vsake posamezne sličice izvaja več sto ali tisoč vzporednih operacij.
Vaja
Na povezavi najdete naloge za utrditev znanja o postopku paralelizacije obdelave videoposnetkov na gruči.