TensorRT 6.x.x.x — vysoko výkonný inferenčný systém pre modely hlbokého učenia (Object Detection a Segmentation)

TensorRT 6.x.x.x — vysoko výkonný inferenčný systém pre modely hlbokého učenia (Object Detection a Segmentation)
Bolestivé je to iba prvýkrát!

Ahojte všetci! Drahí priatelia, v tomto článku sa chcem podeliť so svojimi skúsenosťami s používaním TensorRT, RetinaNet na základe repozitára github.com/aidonchuk/retinanet-examples (toto je fork oficiálneho repozitára od nvidia, ktorý umožní začať používať optimalizované modely v produkčnom prostredí v čo najkratšom čase). Prechádzajúc správami v komunitných kanáloch ods.ai, sa stretávam s otázkami ohľadom používania TensorRT a väčšinou sa otázky opakujú, preto som sa rozhodol napísať čo najúplnejší návod na používanie rýchlej inferencie založenej na TensorRT, RetinaNet, Unet a dockeri.

Opis úlohy

Navrhujem nastaviť úlohu takto: potrebujeme anotovať dataset, natrénovať na ňom sieť RetinaNet/Unet na Pytorch1.3+, previesť získané váhy do ONNX, potom ich skonvertovať do TensorRT engine a všetko spustiť v dockeri, ideálne na Ubuntu 18 a veľmi žiadúce na ARM(Jetson)* architektúre, čím minimalizujeme manuálne nasadenie prostredia. Nakoniec získame kontajner pripravený nielen na export a školenie RetinaNet/Unet, ale aj na plnohodnotný vývoj a školenie klasifikácie a segmentácie so všetkým potrebným zázemím.

Fáza 1. Príprava prostredia

Je dôležité si všimnúť, že v poslednej dobe som úplne prešiel na nepoužívanie a nasadzovanie akýchkoľvek knižníc na desktopovom stroji, rovnako ako aj na devboxe. Jediné, čo musím vytvoriť a nainštalovať — je python virtuálne prostredie a cuda 10.2 (možno sa obmedziť na jeden ovládač nvidia) z deb.

Predpokladajme, že máte čerstvo nainštalované Ubuntu 18. Nainštalujeme cuda 10.2 (deb), podrobnosti o procese inštalácie nebudem rozoberať, oficiálna dokumentácia je úplne dostatočná.

Teraz nainštalujeme docker, návod na inštaláciu dockera sa dá ľahko nájsť, tu je príklad www.digitalocean.com/community/tutorials/docker-ubuntu-18-04-1-sk, už je dostupná verzia 19+ — nainštalujeme ju. A nezabudnite umožniť používanie dockera bez sudo, takto to bude pohodlnejšie. Po úspešnej inštalácii to urobíme takto:

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

A nemusíte ani nahliadať do oficiálneho repozitára github.com/NVIDIA/nvidia-docker.

Teraz urobíme git clone github.com/aidonchuk/retinanet-examples.

Zostáva už len málo, aby ste mohli začať používať docker s nvidia obrazom. Budeme sa musieť zaregistrovať v NGC Cloud a prihlásiť sa. Prejdite sem ngc.nvidia.com, zaregistrujeme sa a potom, čo sa dostaneme dovnútra NGC Cloud, klikneme na SETUP v ľavom hornom rohu obrazovky alebo prejdeme na tento odkaz ngc.nvidia.com/setup/api-key. Kliknite na "vygenerovať kľúč". Odporúčam ho uložiť, inak ho pri ďalšej návšteve budete musieť generovať znova a, samozrejme, pri nasadzovaní na novom zariadení tento proces zopakovať.

Vykonáme:

docker login nvcr.io
Username: $oauthtoken
Password:  - vygenerovaný kľúč

Username jednoducho skopírujeme. Tak, a máme hotové prostredie!

Krok 2. Sestavenie docker kontajnera

V druhom kroku našej práce zostavíme docker a oboznámime sa s jeho vnútornosťami.
Prejdeme do koreňového priečinka projektu retina-examples a vykonáme

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

Zostavujeme docker s prenosom aktuálneho používateľa — to je veľmi užitočné, ak plánujete niečo písať na pripojenom VOLUME s právami aktuálneho používateľa, inak to bude root a problém.

Kým sa docker zostavuje, poďme preskúmať Dockerfile:

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"]

Ako vidno z textu, vezmeme všetky naše obľúbené knižnice, skompilujeme retinanet, pridáme základné nástroje pre pohodlnú prácu s Ubuntu a nastavíme server openssh. Prvá veta sa zaoberá dedičstvom obrazu nvidia, pre ktorý sme sa prihlasovali do NGC Cloud a ktorý obsahuje Pytorch1.3, TensorRT6.x.x.x a množstvo ďalších knižníc, ktoré umožňujú skompilovať cpp zdrojové súbory nášho detektora.

Fáza 3. Spustenie a ladenie docker kontajnera

Prejdeme k hlavnému prípadu použitia kontajnera a vývojového prostredia, najprv spustíme nvidia docker. Vykonáme:

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

Teraz je kontajner dostupný cez ssh @localhost. Po úspešnom spustení otvoríme projekt v PyCharme. Následne otvoríme

Nastavenia->Interpret Projekti->Pridať->Ssh Interpreter

Krok 1
TensorRT 6.x.x.x — vysoko výkonný inferenčný systém pre modely hlbokého učenia (Object Detection a Segmentation)

Krok 2
TensorRT 6.x.x.x — vysoko výkonný inferenčný systém pre modely hlbokého učenia (Object Detection a Segmentation)

Krok 3
TensorRT 6.x.x.x — vysoko výkonný inferenčný systém pre modely hlbokého učenia (Object Detection a Segmentation)

Vyberieme všetko ako na snímkach obrazovky,

Interpret -> /opt/conda/bin/python

— to bude ln na Python3.6 a

Sync folder -> /workspace/retinanet

Klikneme na dokončiť, čakáme na indexovanie a všetko, prostredie je pripravené na použitie!

DÔLEŽITÉ!!! Ihneď po indexovaní vytiahnuť zo docker skompilované súbory pre Retinanet. V kontextovom menu v koreňovom projekte vyberieme položku

Nasadenie->Stiahnuť

Objaví sa jeden súbor a dve zložky build, retinanet.egg-info a _C.so

TensorRT 6.x.x.x — vysoko výkonný inferenčný systém pre modely hlbokého učenia (Object Detection a Segmentation)

Ak váš projekt vyzerá takto, prostredie vidí všetky potrebné súbory a sme pripravení na výcvik RetinaNet.

Krok 4. Označujeme dáta a trénujeme detektor

Na označovanie väčšinou používam supervise.ly — príjemný a užívateľsky prívetivý nástroj, naposledy opravili množstvo chýb a stal sa podstatne stabilnejším.

Predpokladajme, že ste označili dataset a stiahli ho, ale ihneď ho vložiť do nášho RetinaNet nebude možné, pretože je vo vlastnom formáte a na to je potrebné ho konvertovať na COCO. Nástroj na konverziu sa nachádza v:

markup_utils/supervisly_to_coco.py

Všimnite si, že Category v skripte je príklad a je potrebné vložiť svoje (kategorii background pridávať netreba)

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

Autori originálneho repozitára akosi usúdili, že okrem COCO/VOC nebudete trénovať nič na detekciu, takže bolo potrebné trochu upraviť pôvodný súbor

retinanet/dataset.py

Pridali tu vaše obľúbené augmentácie albumentations.readthedocs.io/en/latest a odstrániť tvrdo zakódované kategórie z COCO. Tiež existuje možnosť orezať veľké oblasti detekcie, ak na veľkých obrázkoch hľadáte malé objekty a máte malý dataset =), a nič nefunguje, ale o tom inokedy.

Všeobecne je train loop tiež slabý, pôvodne neukladal checkpointy, používal nejaký hrozný plánovač atď. Ale teraz vám zostáva len vybrať backbone a vykonať

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

s parametrami:

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

V konzole uvidíte:

Inicializácia modelu...
     model: RetinaNet
  backbone: ResNet18FPN
   triedy: 2, kotvy: 9
Vybraný optimalizačný level O0:  Čisté FP32 tréning.

Predvolené nastavenia pre tento optimalizačný level sú:
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
Spracovanie užívateľských prepisov (ďalšie kwargs, ktoré nie sú None)...
Po spracovaní prepisov sú optimalizačné možnosti:
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
Príprava datasetu...
    loader: pytorch
    resize: [1024, 1280], max: 1280
    device: 4 gpus
    batch: 4, precision: mixed
Tréning modelu na 20000 iterácií...
[    1/20000] fokális strata: 0.95619, strata krabice: 0.51584, 4.042s/4-batch (fw: 0.698s, bw: 0.459s), 1.0 im/s, lr: 0.0001
[   12/20000] fokális strata: 0.76191, strata krabice: 0.31794, 0.187s/4-batch (fw: 0.055s, bw: 0.133s), 21.4 im/s, lr: 0.0001
[   24/20000] fokális strata: 0.65036, strata krabice: 0.30269, 0.173s/4-batch (fw: 0.045s, bw: 0.128s), 23.1 im/s, lr: 0.0001
[   36/20000] fokális strata: 0.46425, strata krabice: 0.23141, 0.178s/4-batch (fw: 0.047s, bw: 0.131s), 22.4 im/s, lr: 0.0001
[   48/20000] fokális strata: 0.45115, strata krabice: 0.23505, 0.180s/4-batch (fw: 0.047s, bw: 0.133s), 22.2 im/s, lr: 0.0001
[   59/20000] fokális strata: 0.38958, strata krabice: 0.25373, 0.184s/4-batch (fw: 0.049s, bw: 0.134s), 21.8 im/s, lr: 0.0001
[   71/20000] fokális strata: 0.37733, strata krabice: 0.23988, 0.174s/4-batch (fw: 0.049s, bw: 0.125s), 22.9 im/s, lr: 0.0001
[   83/20000] fokális strata: 0.39514, strata krabice: 0.23878, 0.181s/4-batch (fw: 0.048s, bw: 0.133s), 22.1 im/s, lr: 0.0001
[   94/20000] fokális strata: 0.39947, strata krabice: 0.23817, 0.185s/4-batch (fw: 0.050s, bw: 0.134s), 21.6 im/s, lr: 0.0001
[  105/20000] fokális strata: 0.37343, strata krabice: 0.20238, 0.182s/4-batch (fw: 0.048s, bw: 0.134s), 22.0 im/s, lr: 0.0001
[  116/20000] fokális strata: 0.19689, strata krabice: 0.17371, 0.183s/4-batch (fw: 0.050s, bw: 0.132s), 21.8 im/s, lr: 0.0001
[  128/20000] fokális strata: 0.20368, strata krabice: 0.16538, 0.178s/4-batch (fw: 0.046s, bw: 0.131s), 22.5 im/s, lr: 0.0001
[  140/20000] fokális strata: 0.22763, strata krabice: 0.15772, 0.176s/4-batch (fw: 0.050s, bw: 0.126s), 22.7 im/s, lr: 0.0001
[  148/20000] fokális strata: 0.21997, strata krabice: 0.18400, 0.585s/4-batch (fw: 0.047s, bw: 0.144s), 6.8 im/s, lr: 0.0001
 Priemerná presnosť (AP) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.52674
 Priemerná presnosť (AP) @[ IoU=0.50      | area=   all | maxDets=100 ] = 0.91450
 Priemerná presnosť (AP) @[ IoU=0.75      | area=   all | maxDets=100 ] = 0.35172
 Priemerná presnosť (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.61881
 Priemerná presnosť (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = -1.00000
 Priemerná presnosť (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = -1.00000
 Priemerné pripomínanie (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=  1 ] = 0.58824
 Priemerné pripomínanie (AR) @[ IoU=0.50:0.95 | area=   all | maxDets= 10 ] = 0.61765
 Priemerné pripomínanie (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.61765
 Priemerné pripomínanie (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.61765
 Priemerné pripomínanie (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = -1.00000
 Priemerné pripomínanie (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = -1.00000
Ukladanie modelu: 148

Aby ste si prezreli celý súbor parametrov, pozrite sa

retinanet/main.py

Vo všeobecnosti sú štandardné pre detekciu a majú popis. Spustite tréning a počkajte na výsledky. Príklad inferencie si môžete pozrieť na:

retinanet/infer_example.py

alebo vykonajte príkaz:

/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

V repozitári je už integrovaný Focal Loss a niekoľko backbone, ako aj jednoduché zapracovanie vlastných.

retinanet/backbones/*.py

V tabuľke autori uvádzajú niektoré charakteristiky:

TensorRT 6.x.x.x — vysoko výkonný inferenčný systém pre modely hlbokého učenia (Object Detection a Segmentation)

Rovnaké je aj backbone ResNeXt50_32x4dFPN a ResNeXt101_32x8dFPN, ktoré sú prevzaté z torchvision.
Dúfam, že sme sa trochu vyznali v detekcii, ale určite stojí za to prečítať si oficiálnu dokumentáciu, aby sme pochopili režimy exportu a logovania..

Krok 5. Export a inferencia modelov Unet s enkóderom Resnet.

Ako ste si pravdepodobne všimli, v Dockerfile boli nainštalované knižnice na segmentáciu a konkrétne skvelá knižnica github.com/qubvel/segmentation_models.pytorch. V balíku unet nájdete príklady inferencie a exportu pytorch checkpointov do engine TensorRT.

Hlavný problém pri exporte modelov podobných Unet z ONNX do TensoRT spočíva v potrebe určiť pevný rozmer Upsample alebo použiť ConvTranspose2D:

import torch.onnx.symbolic_opset9 as onnx_symbolic
        def upsample_nearest2d(g, input, output_size):
            # V súčasnosti, TRT 5.1/6.0 ONNX Parser nepodporuje všetky ONNX operácie
            # potrebné na podporu dynamického upsampling ONNX formátu
            # Tu hardcodujeme scale=2 ako dočasné riešenie
            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

Pomocou tejto transformácie je možné to urobiť automaticky pri exporte do ONNX, ale už v 7. verzii TensorRT tento problém vyriešili, a my sa nemusíme čakať dlho.

Záver

Keď som začal používať docker, mal som pochybnosti o jeho výkonnosti pre moje úlohy. V jednom z mojich agregátov je teraz dosť veľký sieťový prenos vytváraný niekoľkými kamerami.

TensorRT 6.x.x.x — vysoko výkonný inferenčný systém pre modely hlbokého učenia (Object Detection a Segmentation)

Rôzne testy na internete hovorili o relatívne veľkom overheade na sieťovú interakciu a zápis na VOLUME, plus neznámy a strašidelný GIL, a pretože snímanie snímky, práca ovládača a prenos snímky po sieti sú atómové operácie v režime hard real-time, oneskorenia v sieti sú pre mňa veľmi kritické.

Ale všetko dopadlo dobre =)

P.S. Ostáva pridať váš obľúbený train loop pre segmentáciu a do produkcie!

Poďakovanie

Ďakujem komunite ods.ai, bez nej nie je možné rásť! Obrovské ďakujem n01z3, ktorý ma namotivoval zaoberať sa DL, za jeho cenné rady a mimoriadnu profesionalitu!

Používajte v produkcii optimalizované modely!

TensorRT 6.x.x.x — vysoko výkonný inferenčný systém pre modely hlbokého učenia (Object Detection a Segmentation) Aurorai, llc

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster