TensorRT 6.x.x.x — nagy teljesítményű inferálás mélytanulási modellekhez (Objektum Detektálás és Szegmentáció)

TensorRT 6.x.x.x — nagy teljesítményű inferálás mélytanulási modellekhez (Objektum Detektálás és Szegmentáció)
Csak az első alkalommal fáj!

Helló mindenkinek! Kedves barátok, ebben a cikkben szeretném megosztani tapasztalataimat a TensorRT és a RetinaNet használatáról a repozitóriumból github.com/aidonchuk/retinanet-examples (ez a hivatalos repó forkja, nvidia, amely lehetővé teszi, hogy a termelésben gyorsan használjunk optimalizált modelleket). A közösségi csatornákbana ods.aifutása közben rúgok fel a TensorRT használatára vonatkozó kérdésekkel, és főként a kérdések ismétlődnek, ezért úgy döntöttem, hogy a lehető legteljesebb útmutatót írok a TensorRT, RetinaNet, Unet és docker alapú gyors inferálás használatához.

A feladat leírása

Javaslom, hogy a feladatot úgy fogalmazzuk meg: szükségünk van egy adatbázis megjelölésére, a RetinaNet/Unet háló tanítására Pytorch1.3+-on, a nyert súlyok ONNX formátumba való átalakítására, majd az ezekből készült TensorRT engine konvertálására, és mindezt docker alatt, lehetőleg Ubuntu 18-on és lehetőleg ARM (Jetson)* architektúrán futtatni, így minimalizálva a környezet manuális telepítését. Ennek eredményeként egy konténert kapunk, amely nemcsak a RetinaNet/Unet exportálására és tanítására, hanem a klasszifikáció és a szegmentálás teljes körű fejlesztésére és tanítására is alkalmas minden szükséges kötelékével.

1. lépés: A környezet előkészítése

Itt fontos megjegyezni, hogy az utóbbi időben teljes mértékben elhagytam bármilyen könyvtár használatát és telepítését desktop gépen, akárcsak devbox-on. Az egyetlen, amit létre kell hoznunk vagy telepítenünk, az a python virtuális környezet és a cuda 10.2 (elég egy nvidia meghajtó is) deb formátumban.

Tegyük fel, hogy egy frissen telepített Ubuntu 18-as van. Telepítsük a cuda 10.2-t (deb), a telepítési folyamatra részletesen nem fogok kitérni, a hivatalos dokumentáció bőségesen elegendő.

Most telepítsük a dockert, a docker telepítési útmutatója könnyen megtalálható, itt egy példa www.digitalocean.com/community/tutorials/docker-ubuntu-18-04-1-hu, már elérhető a 19+ verzió — telepítsük azt. Ne felejtsük el lehetővé tenni a docker használatát sudo nélkül, így kényelmesebb lesz. Miután minden sikerült, ezt csináljuk:

distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list

sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker

És még az official repositoryba sem kell benéznünk. github.com/NVIDIA/nvidia-docker.

Most csináljunk egy git clone-t. github.com/aidonchuk/retinanet-examples.

Már csak egy kicsit van hátra, hogy elkezdhessük használni a dockert az nvidia-image-val, regisztrálnunk kell az NGC Cloud-ba, és be kell jelentkezni. Irány ide: ngc.nvidia.com, regisztrálunk, és miután beléptünk az NGC Cloud-ba, kattintsunk a SETUP gombra a bal felső sarokban, vagy kövessük ezt a linket: ngc.nvidia.com/setup/api-key. Kattints a "kulcs generálására". Javaslom, hogy mentsd el, különben a következő látogatáskor újra generálnod kell, így amikor új gépre telepítesz, ezt a műveletet ismételni kell.

Futtatjuk:

docker login nvcr.io
Felhasználónév: $oauthtoken
Jelszó:  - generált kulcs

A felhasználónevet egyszerűen másoljuk. Nos, ez így jól néz ki, a környezet készen áll!

2. lépés. Docker konténer építése

A munka második lépésében össze fogjuk állítani a dockert, és megismerkedünk a belső működésével.
Lépjünk a retina-examples projekthez tartozó gyökérmappa alá, és hajtsuk végre:

docker build --build-arg USER=$USER --build-arg UID=$UID --build-arg GID=$GID --build-arg PW=alex -t retinanet:latest retinanet/

A dockert úgy építjük, hogy átadjuk neki a jelenlegi felhasználót - ez nagyon hasznos, ha valamit írsz egy csatolt VOLUME-ra a jelenlegi felhasználó jogainak megfelelően, különben root lesz, ami problémás.

Amíg épül a docker, nézzük meg a Dockerfile-t:

FROM nvcr.io/nvidia/pytorch:19.10-py3

ARG USER=alex
ARG UID=1000
ARG GID=1000
ARG PW=alex
RUN useradd -m ${USER} --uid=${UID} && echo "${USER}:${PW}" | chpasswd

RUN apt-get -y update && apt-get -y upgrade && apt-get -y install curl && apt-get -y install wget && apt-get -y install git && apt-get -y install automake && apt-get install -y sudo && adduser ${USER} sudo
RUN pip install git+https://github.com/bonlime/pytorch-tools.git@master

COPY . retinanet/
RUN pip install --no-cache-dir -e retinanet/
RUN pip install /workspace/retinanet/extras/tensorrt-6.0.1.5-cp36-none-linux_x86_64.whl
RUN pip install tensorboardx
RUN pip install albumentations
RUN pip install setproctitle
RUN pip install paramiko
RUN pip install flask
RUN pip install mem_top
RUN pip install arrow
RUN pip install pycuda
RUN pip install torchvision
RUN pip install pretrainedmodels
RUN pip install efficientnet-pytorch
RUN pip install git+https://github.com/qubvel/segmentation_models.pytorch
RUN pip install pytorch_toolbelt

RUN chown -R ${USER}:${USER} retinanet/

RUN cd /workspace/retinanet/extras/cppapi && mkdir build && cd build && cmake -DCMAKE_CUDA_FLAGS="--expt-extended-lambda -std=c++14" .. && make && cd /workspace

RUN apt-get install -y openssh-server && apt install -y tmux && apt-get -y install bison flex && apt-cache search pcre && apt-get -y install net-tools && apt-get -y install nmap
RUN apt-get -y install libpcre3 libpcre3-dev && apt-get -y install iputils-ping

RUN mkdir /var/run/sshd
RUN echo 'root:pass' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed 's@sessions*requireds*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile
CMD ["/usr/sbin/sshd", "-D"]

Ahogy a szövegből látható, az összes kedvenc könyvtárunkat vesszük, lefordítjuk a retinanet-et, és hozzáadunk alapvető eszközöket az Ubuntu használatához, miközben beállítjuk az openssh szervert. Az első sorban éppen az nvidia kép öröklése történik, amelyhez a NGC Cloud-on bejelentkeztünk, és amely tartalmazza a Pytorch 1.3-at, TensorRT 6.x.x.x-t, és még sok más könyvtárat, amelyek lehetővé teszik a cpp forráskódunk fordítását.

3. lépés. A docker konténer indítása és hibakeresése

Lépjünk a konténer és a fejlesztői környezet fő használati esetére, először indítsuk el a nvidia dockert. Futtassuk:

docker run --gpus all --net=host -v /home/:/workspace/mounted_vol -d -P --rm --ipc=host -it retinanet:latest

Most a konténer ssh-n keresztül elérhető @localhost. A sikeres indítás után nyissuk meg a projektet a PyCharm-ban. Ezután nyissuk meg

Beállítások->Projektinterpreter->Hozzáadás->Ssh Interpreter

1. lépés
TensorRT 6.x.x.x — nagy teljesítményű inferálás mélytanulási modellekhez (Objektum Detektálás és Szegmentáció)

2. lépés
TensorRT 6.x.x.x — nagy teljesítményű inferálás mélytanulási modellekhez (Objektum Detektálás és Szegmentáció)

3. lépés
TensorRT 6.x.x.x — nagy teljesítményű inferálás mélytanulási modellekhez (Objektum Detektálás és Szegmentáció)

Válasszunk mindent, mint a képernyőképeken:

Interpreter -> /opt/conda/bin/python

— ez lesz a link a Python3.6-ra és

Szinkronizálási mappa -> /workspace/retinanet

Kattintsunk a befejezésre, várjuk meg az indexelést, és kész, a környezet készen áll a használatra!

FONTOS!!! Az indexelés után azonnal húzzuk ki a dockerből a lefordított fájlokat a Retinanet számára. A projekt gyökérmappájában a kontextuális menüben válasszuk a

Telepítés->Letöltés

Megjelenik egy fájl és két mappa: build, retinanet.egg-info és _С.so

TensorRT 6.x.x.x — nagy teljesítményű inferálás mélytanulási modellekhez (Objektum Detektálás és Szegmentáció)

Ha a projekted így néz ki, akkor a környezet látja az összes szükséges fájlt, és készen állunk a RetinaNet betanítására.

4. lépés. Az adatok megjelölése és a detektor betanítása

A megjelöléshez főként a következőt használom supervise.ly — egy kellemes és kényelmes eszköz, az utóbbi időben sok hibát javítottak ki, és most sokkal jobban viselkedik.

Tegyük fel, hogy megjelölte az adatbázist és letöltötte, de közvetlenül nem tudja a RetinaNetbe behelyezni, mivel a saját formátumában van, és ahhoz, hogy COCO formátumba konvertálhassa, szükség van a következőre. A konvertáló eszköz a következő helyen található:

markup_utils/supervisly_to_coco.py

Kérlek, vedd figyelembe, hogy a Category a szkriptben példa, és neked a saját kategóriádat kell megadnod (a background kategóriát ne add hozzá).

categories = [{'id': 1, 'name': '1'}, 
                  {'id': 2, 'name': '2'}, 
                  {'id': 3, 'name': '3'},
                  {'id': 4, 'name': '4'}] 

Az eredeti tároló szerzői valamiért úgy döntöttek, hogy nem tanítanak mást, csak COCO/VOC-t a detekciós feladathoz, ezért egy kicsit módosítani kellett az alap fájlt.

retinanet/dataset.py

Hozzáadva a kedvenc augmentációidat itt, albumentations.readthedocs.io/en/latest és eltávolítva a COCO-ba keményen beépített kategóriákat. Lehetőség van nagy detekciós területek kivágására is, ha nagy képeken keresel kis objektumokat, és kis adatbázissal rendelkezel =), és semmi nem működik, de erről majd máskor.

Összességében a tanító ciklus is gyenge volt, kezdetben nem mentette a checkpointokat, egy szörnyű scheduler-t használt, stb. De most már csak annyit kell tenned, hogy kiválasztod a backbone-t és végrehajtod

/opt/conda/bin/python retinanet/main.py

a következő paraméterekkel:

train retinanet_rn34fpn.pth
--backbone ResNet34FPN
--classes 12
--val-iters 10
--images /workspace/mounted_vol/dataset/train/images
--annotations /workspace/mounted_vol/dataset/train_12_class.json
--val-images /workspace/mounted_vol/dataset/test/images_small
--val-annotations /workspace/mounted_vol/dataset/val_10_class_cropped.json
--jitter 256 512
--max-size 512
--batch 32

A konzolban ezt fogod látni:

A modell inicializálása...
     modell: RetinaNet
  háttér: ResNet18FPN
   osztályok: 2, horgonyok: 9
Kiválasztott optimalizálási szint O0: Tiszta FP32 képzés.

Az optimalizálási szint alapértelmezett beállításai:
enabled                : True
opt_level              : O0
cast_model_type        : torch.float32
patch_torch_functions  : False
keep_batchnorm_fp32    : None
master_weights         : False
loss_scale             : 1.0
Feldolgozás felhasználói felülírások (további kwargs, amelyek nem None)...
A felülírások feldolgozása után az optimalizálási lehetőségek:
enabled                : True
opt_level              : O0
cast_model_type        : torch.float32
patch_torch_functions  : False
keep_batchnorm_fp32    : None
master_weights         : False
loss_scale             : 128.0
Adatbázis előkészítése...
    loader: pytorch
    méretezés: [1024, 1280], max: 1280
    eszköz: 4 gpu
    batch: 4, precízió: vegyes
A modell tanítása 20000 iteráción keresztül...
[    1/20000] fókusz veszteség: 0.95619, doboz veszteség: 0.51584, 4-batch idő: 4.042s (fw: 0.698s, bw: 0.459s), 1.0 im/s, lr: 0.0001
[   12/20000] fókusz veszteség: 0.76191, doboz veszteség: 0.31794, 0.187s/4-batch (fw: 0.055s, bw: 0.133s), 21.4 im/s, lr: 0.0001
[   24/20000] fókusz veszteség: 0.65036, doboz veszteség: 0.30269, 0.173s/4-batch (fw: 0.045s, bw: 0.128s), 23.1 im/s, lr: 0.0001
[   36/20000] fókusz veszteség: 0.46425, doboz veszteség: 0.23141, 0.178s/4-batch (fw: 0.047s, bw: 0.131s), 22.4 im/s, lr: 0.0001
[   48/20000] fókusz veszteség: 0.45115, doboz veszteség: 0.23505, 0.180s/4-batch (fw: 0.047s, bw: 0.133s), 22.2 im/s, lr: 0.0001
[   59/20000] fókusz veszteség: 0.38958, doboz veszteség: 0.25373, 0.184s/4-batch (fw: 0.049s, bw: 0.134s), 21.8 im/s, lr: 0.0001
[   71/20000] fókusz veszteség: 0.37733, doboz veszteség: 0.23988, 0.174s/4-batch (fw: 0.049s, bw: 0.125s), 22.9 im/s, lr: 0.0001
[   83/20000] fókusz veszteség: 0.39514, doboz veszteség: 0.23878, 0.181s/4-batch (fw: 0.048s, bw: 0.133s), 22.1 im/s, lr: 0.0001
[   94/20000] fókusz veszteség: 0.39947, doboz veszteség: 0.23817, 0.185s/4-batch (fw: 0.050s, bw: 0.134s), 21.6 im/s, lr: 0.0001
[  105/20000] fókusz veszteség: 0.37343, doboz veszteség: 0.20238, 0.182s/4-batch (fw: 0.048s, bw: 0.134s), 22.0 im/s, lr: 0.0001
[  116/20000] fókusz veszteség: 0.19689, doboz veszteség: 0.17371, 0.183s/4-batch (fw: 0.050s, bw: 0.132s), 21.8 im/s, lr: 0.0001
[  128/20000] fókusz veszteség: 0.20368, doboz veszteség: 0.16538, 0.178s/4-batch (fw: 0.046s, bw: 0.131s), 22.5 im/s, lr: 0.0001
[  140/20000] fókusz veszteség: 0.22763, doboz veszteség: 0.15772, 0.176s/4-batch (fw: 0.050s, bw: 0.126s), 22.7 im/s, lr: 0.0001
[  148/20000] fókusz veszteség: 0.21997, doboz veszteség: 0.18400, 0.585s/4-batch (fw: 0.047s, bw: 0.144s), 6.8 im/s, lr: 0.0001
A Pontosság Átlag (AP) @[ IoU=0.50:0.95 | terület=   mind | maxDets=100 ] = 0.52674
A Pontosság Átlag (AP) @[ IoU=0.50      | terület=   mind | maxDets=100 ] = 0.91450
A Pontosság Átlag (AP) @[ IoU=0.75      | terület=   mind | maxDets=100 ] = 0.35172
A Pontosság Átlag (AP) @[ IoU=0.50:0.95 | terület= kicsi | maxDets=100 ] = 0.61881
A Pontosság Átlag (AP) @[ IoU=0.50:0.95 | terület=közepes | maxDets=100 ] = -1.00000
A Pontosság Átlag (AP) @[ IoU=0.50:0.95 | terület= nagy | maxDets=100 ] = -1.00000
A Visszahívás Átlag (AR) @[ IoU=0.50:0.95 | terület=   mind | maxDets=  1 ] = 0.58824
A Visszahívás Átlag (AR) @[ IoU=0.50:0.95 | terület=   mind | maxDets= 10 ] = 0.61765
A Visszahívás Átlag (AR) @[ IoU=0.50:0.95 | terület=   mind | maxDets= 100 ] = 0.61765
A Visszahívás Átlag (AR) @[ IoU=0.50:0.95 | terület= kicsi | maxDets=100 ] = 0.61765
A Visszahívás Átlag (AR) @[ IoU=0.50:0.95 | terület=közepes | maxDets=100 ] = -1.00000
A Visszahívás Átlag (AR) @[ IoU=0.50:0.95 | terület= nagy | maxDets=100 ] = -1.00000
A modell mentése: 148

A teljes paramétersorozat megtekintéséhez nézze meg

retinanet/main.py

Alapvetően ezek az észleléshez szabványos beállítások, és van leírásuk. Indítsa el a tanítást, és várja meg az eredményeket. Példa az inferálásra megtalálható itt:

retinanet/infer_example.py

vagy futtassa a parancsot:

/opt/conda/bin/python retinanet/main.py infer retinanet_rn34fpn.pth 
--images /workspace/mounted_vol/dataset/test/images 
--annotations /workspace/mounted_vol/dataset/val.json 
--output result.json 
--resize 256 
--max-size 512 
--batch 32

A Focal Loss és több backbone már be van építve a tárolóba, és könnyedén integrálhatók a saját megoldások.

retinanet/backbones/*.py

A táblázatban a szerzők néhány jellemzőt sorolnak fel:

TensorRT 6.x.x.x — nagy teljesítményű inferálás mélytanulási modellekhez (Objektum Detektálás és Szegmentáció)

Van továbbá ResNeXt50_32x4dFPN és ResNeXt101_32x8dFPN backbone is, amelyek a torchvision-ből származnak.
Remélem, hogy a detektálással kicsit tisztábban látunk, de mindenképpen érdemes átnézni a hivatalos dokumentációt, hogy megértsük az exportálási és naplózási módokat..

5. lépés. Unet modellek exportálása és inferálása Resnet enkóderrel.

Ahogy bizonyára észrevették, a Dockerfile-ban telepítve lettek a szegmentációhoz szükséges könyvtárak, és különösen a csodálatos könyvtár github.com/qubvel/segmentation_models.pytorch. A uNet csomagban található példák a PyTorch checkpointok inferálására és exportálására az engine TensorRT-be.

A fő probléma a Unet-szerű modellek ONNX-ból TensorRT-be való exportálásakor az, hogy rögzített méretű Upsample értéket kell megadni, vagy a ConvTranspose2D-t kell használnunk:

import torch.onnx.symbolic_opset9 as onnx_symbolic
        def upsample_nearest2d(g, input, output_size):
            # Jelenleg a TRT 5.1/6.0 ONNX Parser nem támogatja az összes ONNX op-t,
            # amire szükség van a dinamikus Upsampling ONNX képlet támogatásához.
            # Itt a skálát 2-re keménykódoljuk, mint ideiglenes megoldás.
            scales = g.op("Constant", value_t=torch.tensor([1., 1., 2., 2.]))
            return g.op("Upsample", input, scales, mode_s="nearest")

        onnx_symbolic.upsample_nearest2d = upsample_nearest2d

Ezzel a transzformációval ezt automatikusan meg tudjuk tenni az ONNX-be való exportáláskor, de a TensorRT 7-es verziójában ezt a problémát megoldották, és már csak egy kicsit kell várnunk.

Zárás

Amikor elkezdtem használni a Dockert, kétségeim voltak a teljesítménye miatt a feladataimhoz. Az egyik aggregátoromban most meglehetősen nagy hálózati forgalom keletkezik több kamerából.

TensorRT 6.x.x.x — nagy teljesítményű inferálás mélytanulási modellekhez (Objektum Detektálás és Szegmentáció)

Különböző tesztek az interneten viszonylag nagy overheadről beszéltek a hálózati interakciók és a VOLUME-ra való írás esetén, plusz a rejtélyes és félelmetes GIL miatt, és mivel a keretek rögzítése, a meghajtó működése és a keretek hálózaton való továbbítása atomáris művelet a hard real-time, a hálózati késések számomra nagyon kritikusak.

De végül minden rendben lett =)

P.S. Csak annyit kell még hozzátenni, hogy a kedvenc train loop-ját szegmentáláshoz és irány a termelés!

Hálák

Köszönet a közösségnek ods.ai, nélküle lehetetlen fejlődni! Hatalmas köszönet n01z3, aki arra ösztönzött, hogy a DL-vel foglalkozzam, az értékes tanácsaiért és rendkívüli szakértelméért!

Használjon optimalizált modelleket a termelésben!

TensorRT 6.x.x.x — nagy teljesítményű inferálás mélytanulási modellekhez (Objektum Detektálás és Szegmentáció) Aurorai, llc

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster