TensorRT 6.x.x.x — visoko zmogljivo sklepanje za modele globokega učenja (odkrivanje objektov in segmentacija)

TensorRT 6.x.x.x — visoko zmogljivo sklepanje za modele globokega učenja (odkrivanje objektov in segmentacija)
Boli le samo prvi put!

Zdravo svima! Dragi prijatelji, u ovom članku želim da podelim svoje iskustvo korišćenja TensorRT-a, RetinaNet baziranog na repozitorijumu github.com/aidonchuk/retinanet-examples (to je fork zvanične repozitorije od nvidia, koji omogućava brzo korišćenje optimizovanih modela u produkciji). Dok pretražujem poruke u zajednici ods.ai, suočavam se sa pitanjima o korišćenju TensorRT-a, a većina pitanja se ponavlja, pa sam odlučio da napišem što potpunije vodič o korišćenju brzog inferensa zasnovanog na TensorRT-u, RetinaNet-u, Unet-u i docker-u.

Opis naloge

Prvo, postavićemo zadatak: potrebno je da označimo dataset, obučimo mrežu RetinaNet/Unet na Pytorch-u 1.3+, pretvorimo dobijene težine u ONNX, zatim ih konvertujemo u TensorRT engine i sve to pokrenemo u docker-u, poželjno na Ubuntu 18 i izrazito poželjno na ARM (Jetson)* arhitekturi, čime minimiziramo ručno postavljanje okruženja. Na kraju dobijamo kontejner spreman ne samo za izvoz i obučavanje RetinaNet/Unet-a, već i za kompletnu razvoj i obuku klasifikacije, segmentacije sa svom potrebnom opremom.

Faza 1. Priprema okruženja

Važno je napomenuti da sam u poslednje vreme potpuno prestao sa korišćenjem i postavljanjem bilo kojih biblioteka na desktop mašini, kao i na devbox-u. Jedino što treba da se kreira i instalira je python virtual environment i cuda 10.2 (može se ograničiti na samo nvidia drajver) iz deb.

Pretpostavimo da imate sveže instaliran Ubuntu 18. Instalirajmo cuda 10.2 (deb), neću se zadržavati na procesu instalacije, zvanična dokumentacija je sasvim dovoljno.

Sada instalirajmo docker, uputstvo za instalaciju dockera lako možete pronaći, evo primera www.digitalocean.com/community/tutorials/docker-ubuntu-18-04-1-ru, verzija 19+ je već dostupna — instalirajte je. I ne zaboravite omogućiti korišćenje dockera bez sudo-a, biće praktičnije. Nakon što je sve uspelo, uradite ovako:

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

Možda čak nećete morati da zavirujete u zvanični repozitorijum github.com/NVIDIA/nvidia-docker.

Sada radimo git clone github.com/aidonchuk/retinanet-examples.

Ostalo je samo malo da počnemo koristiti docker s nvidia slikom, potrebno je da se registriramo na NGC Cloud i prijavimo. Idemo ovdje ngc.nvidia.com, registriramo se i nakon što uđemo u NGC Cloud, kliknemo na SETUP u gornjem lijevom kutu ekrana ili odlazimo na ovu vezu ngc.nvidia.com/setup/api-key. Kliknite „generiraj ključ“. Preporučujem da ga sačuvate, inače ćete ga sljedeći put morati ponovo generirati i, prema tome, prilikom postavljanja na novom uređaju ponovo izvesti ovu operaciju.

Izvršimo:

docker login nvcr.io
Username: $oauthtoken
Password:  - generirani ključ

Username jednostavno kopiramo. Pa, to bi bilo to, okruženje je postavljeno!

Faza 2. Izrada docker kontejnera

U drugoj fazi našeg rada sastavit ćemo docker i upoznati se s njegovim unutrašnjostima.
Prelazimo u korijensku mapu u odnosu na projekt retina-examples i izvršavamo

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

Sastavljamo docker prosljeđujući trenutačnog korisnika — to je vrlo korisno ako ćete pisati na montiranom VOLUME s pravima trenutnog korisnika, inače će biti root i bolno.

Dok se docker sastavlja, razmotrimo 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"]

Kot se vidi iz besedila, vzamemo vse naše najljubše knjižnice, skompiliramo retinanet, dodamo osnovna orodja za delo z Ubuntu in nastavimo strežnik openssh. Prva vrstica je pravzaprav dedovanje slike nvidia, za katero smo se prijavili v NGC Cloud in vsebuje Pytorch1.3, TensorRT6.x.x.x in še kup knjižnic, ki omogočajo kompajliranje cpp izvornih datotek našega detektorja.

Faza 3. Zagon in odkrivanje napak v Docker kontejnerju

Poglejmo glavni primer uporabe kontejnerja in razvojnega okolja, najprej zaženimo nvidia docker. Izvedite:

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

Zdaj je kontejner dostopen preko ssh @localhost. Po uspešnem zagonu odpiramo projekt v PyCharm. Nato odpiramo

Nastavitve->Interpreter projekta->Dodaj->Ssh Interpreter

Korak 1
TensorRT 6.x.x.x — visoko zmogljivo sklepanje za modele globokega učenja (odkrivanje objektov in segmentacija)

Korak 2
TensorRT 6.x.x.x — visoko zmogljivo sklepanje za modele globokega učenja (odkrivanje objektov in segmentacija)

Korak 3
TensorRT 6.x.x.x — visoko zmogljivo sklepanje za modele globokega učenja (odkrivanje objektov in segmentacija)

Izberemo vse kot na posnetkih zaslona,

Interpreter -> /opt/conda/bin/python

— to bo ln na Python3.6 in

Sync folder -> /workspace/retinanet

Pritisnemo zaključek, počakamo na indeksacijo, in vse, okolje je pripravljeno za uporabo!

POMEMBNO!!! Takoj po indeksaciji prenesite iz dockerja skompilirane datoteke za Retinanet. V kontekstnem meniju na korenu projekta izberite možnost

Namestitev->Prenesi

Pojavili se bodo ena datoteka in dve mapi build, retinanet.egg-info in _С.so

TensorRT 6.x.x.x — visoko zmogljivo sklepanje za modele globokega učenja (odkrivanje objektov in segmentacija)

Če vaš projekt izgleda tako, potem okolje vidi vse potrebne datoteke in smo pripravljeni na usposabljanje RetinaNet.

Faza 4. Označimo podatke in usposabljamo detektor

Za oznake večinoma uporabljam supervise.ly — prijetna in uporabna orodja, v zadnjem času so odpravili veliko napak in deluje bistveno bolje.

Recimo, da ste označili nabor podatkov in ga prenesli, vendar ga takoj uporabiti v našem RetinaNet ne bo šlo, ker je v svojem formatu in zato ga moramo pretvoriti v COCO. Orodje za pretvorbo se nahaja v:

markup_utils/supervisly_to_coco.py

Upoštevajte, da je Kategorija v skriptu primer in morate vstaviti svoje (kategorija background se ne dodaja)

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

Avtorji izvornega repozitorija so nekako sklenili, da ne boste izobraževali ničesar razen COCO/VOC za detekcijo, zato je bilo potrebno nekoliko popraviti izvorno datoteko

retinanet/dataset.py

Dodaj tudi naše najljubše augmentacije albumentations.readthedocs.io/en/latest in odstranite trdo vgrajene kategorije iz COCO. Prav tako imate možnost, da obrežete velike območja zaznavanja, če iščete majhne objekte na velikih slikah, imate majhen niz podatkov =) in nič ne deluje, vendar o tem drugič.

Na splošno je tudi train loop šibek, sprva ni shranjeval kontrolnih točk, uporabljal je nek grozen scheduler itd. Ampak zdaj vam je ostalo le še, da izberete backbone in izvedete

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

z parametri:

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 konzoli boste videli:

Загрузка модели...
     модель: RetinaNet
  основа: ResNet18FPN
   классы: 2, якоря: 9
Выбран уровень оптимизации O0:  Чистое FP32 обучение.

Значения по умолчанию для этого уровня оптимизации:
включено                : True
уровень_оптимизации      : O0
тип_модели_приведения    : torch.float32
патч_функций_pytorch     : False
сохранять_batchnorm_fp32  : None
основные_веса           : False
масштаб_потерь           : 1.0
Обработка пользовательских переопределений (дополнительные аргументы, которые не равны None)...
После обработки переопределений параметры оптимизации:
включено                : True
уровень_оптимизации      : O0
тип_модели_приведения    : torch.float32
патч_функций_pytorch     : False
сохранять_batchnorm_fp32  : None
основные_веса           : False
масштаб_потерь           : 128.0
Подготовка набора данных...
    загрузчик: pytorch
    изменение_размера: [1024, 1280], максимум: 1280
    устройство: 4 gpu
    пакет: 4, точность: смешанная
Обучение модели в течение 20000 итераций...
[    1/20000] фокальная потеря: 0.95619, потеря коробки: 0.51584, 4.042с/4-пакет (вперед: 0.698с, назад: 0.459с), 1.0 им/с, lr: 0.0001
[   12/20000] фокальная потеря: 0.76191, потеря коробки: 0.31794, 0.187с/4-пакет (вперед: 0.055с, назад: 0.133с), 21.4 им/с, lr: 0.0001
[   24/20000] фокальная потеря: 0.65036, потеря коробки: 0.30269, 0.173с/4-пакет (вперед: 0.045с, назад: 0.128с), 23.1 им/с, lr: 0.0001
[   36/20000] фокальная потеря: 0.46425, потеря коробки: 0.23141, 0.178с/4-пакет (вперед: 0.047с, назад: 0.131с), 22.4 им/с, lr: 0.0001
[   48/20000] фокальная потеря: 0.45115, потеря коробки: 0.23505, 0.180с/4-пакет (вперед: 0.047с, назад: 0.133с), 22.2 им/с, lr: 0.0001
[   59/20000] фокальная потеря: 0.38958, потеря коробки: 0.25373, 0.184с/4-пакет (вперед: 0.049с, назад: 0.134с), 21.8 им/с, lr: 0.0001
[   71/20000] фокальная потеря: 0.37733, потеря коробки: 0.23988, 0.174с/4-пакет (вперед: 0.049с, назад: 0.125с), 22.9 им/с, lr: 0.0001
[   83/20000] фокальная потеря: 0.39514, потеря коробки: 0.23878, 0.181с/4-пакет (вперед: 0.048с, назад: 0.133с), 22.1 им/с, lr: 0.0001
[   94/20000] фокальная потеря: 0.39947, потеря коробки: 0.23817, 0.185с/4-пакет (вперед: 0.050с, назад: 0.134с), 21.6 им/с, lr: 0.0001
[  105/20000] фокальная потеря: 0.37343, потеря коробки: 0.20238, 0.182с/4-пакет (вперед: 0.048с, назад: 0.134с), 22.0 им/с, lr: 0.0001
[  116/20000] фокальная потеря: 0.19689, потеря коробки: 0.17371, 0.183с/4-пакет (вперед: 0.050с, назад: 0.132с), 21.8 им/с, lr: 0.0001
[  128/20000] фокальная потеря: 0.20368, потеря коробки: 0.16538, 0.178с/4-пакет (вперед: 0.046с, назад: 0.131с), 22.5 им/с, lr: 0.0001
[  140/20000] фокальная потеря: 0.22763, потеря коробки: 0.15772, 0.176с/4-пакет (вперед: 0.050с, назад: 0.126с), 22.7 им/с, lr: 0.0001
[  148/20000] фокальная потеря: 0.21997, потеря коробки: 0.18400, 0.585с/4-пакет (вперед: 0.047с, назад: 0.144с), 6.8 им/с, lr: 0.0001
Средняя точность (AP) @[ IoU=0.50:0.95 | область=   вся | максимальные детекторы=100 ] = 0.52674
Средняя точность (AP) @[ IoU=0.50      | область=   вся | максимальные детекторы=100 ] = 0.91450
Средняя точность (AP) @[ IoU=0.75      | область=   вся | максимальные детекторы=100 ] = 0.35172
Средняя точность (AP) @[ IoU=0.50:0.95 | область= маленькая | максимальные детекторы=100 ] = 0.61881
Средняя точность (AP) @[ IoU=0.50:0.95 | область=средняя | максимальные детекторы=100 ] = -1.00000
Средняя точность (AP) @[ IoU=0.50:0.95 | область= большая | максимальные детекторы=100 ] = -1.00000
Средняя отзывчивость (AR) @[ IoU=0.50:0.95 | область=   вся | максимальные детекторы=  1 ] = 0.58824
Средняя отзывчивость (AR) @[ IoU=0.50:0.95 | область=   вся | максимальные детекторы= 10 ] = 0.61765
Средняя отзывчивость (AR) @[ IoU=0.50:0.95 | область=   вся | максимальные детекторы=100 ] = 0.61765
Средняя отзывчивость (AR) @[ IoU=0.50:0.95 | область= маленькая | максимальные детекторы=100 ] = 0.61765
Средняя отзывчивость (AR) @[ IoU=0.50:0.95 | область=средняя | максимальные детекторы=100 ] = -1.00000
Средняя отзывчивость (AR) @[ IoU=0.50:0.95 | область= большая | максимальные детекторы=100 ] = -1.00000
Сохранение модели: 148

Чтобы ознакомиться со всеми параметрами, обратите внимание на

retinanet/main.py

В целом, они стандартные для детекции и имеют свое описание. Запустите обучение и дождитесь результатов. Пример инференса можно найти в:

retinanet/infer_example.py

или выполните команду:

/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 repozitoriju je že vgrajen Focal Loss in več backbonov, poleg tega je enostavno dodati svoje.

retinanet/backbones/*.py

V tabeli avtorji navajajo nekatere značilnosti:

TensorRT 6.x.x.x — visoko zmogljivo sklepanje za modele globokega učenja (odkrivanje objektov in segmentacija)

Na voljo sta tudi backbone ResNeXt50_32x4dFPN in ResNeXt101_32x8dFPN, vzeta iz torchvision.
Upam, da smo se malo razjasnili glede detekcije, vendar je nujno prebrati uradno dokumentacijo, da razumemo načine izvoza in logiranja..

Korak 5. Izvoz in inferenca modelov Unet z encoderjem Resnet.

Kot ste verjetno opazili, so bile v Dockerfile nameščene knjižnice za segmentacijo in med njimi odlična knjižnica github.com/qubvel/segmentation_models.pytorch. V paketu Unet lahko najdete primere inference in izvoza pytorch kontrolnih točk v engine TensorRT.

Glavna težava pri izvozu modelov Unet-like iz ONNX v TensorRT je potreba po določanju fiksne velikosti Upsample ali uporabi ConvTranspose2D:

import torch.onnx.symbolic_opset9 as onnx_symbolic
        def upsample_nearest2d(g, input, output_size):
            # Trenutno, TRT 5.1/6.0 ONNX Parser ne podpira vseh ONNX operacij
            # potrebnih za podporo dinamičnemu upsampling ONNX formulaciji
            # Tukaj strogo določimo scale=2 kot začasno rešitev
            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

S tem pretvorbo je to mogoče avtomatizirati pri izvozu v ONNX, vendar je v 7. različici TensorRT ta težava rešena, in ostalo nam je le še malo počakati.

Zaključek

Ko sem začel uporabljati docker, sem imel dvome o njegovi zmogljivosti za moje naloge. V enem od mojih agregatorjev zdaj ustvarjam precejšen omrežni promet z več kamerami.

TensorRT 6.x.x.x — visoko zmogljivo sklepanje za modele globokega učenja (odkrivanje objektov in segmentacija)

Različni testi na spletu so govorili o razmeroma velikem overheadu za omrežno interakcijo in zapisovanje na VOLUME, poleg tega pa je neznani in strašni GIL, saj je zajemanje okvirjev, delovanje gonilnika in prenos okvirjev po omrežju atomarna operacija v načinu hard real-time, zamude v omrežju so zame zelo kritične.

A vse je šlo dobro =)

P.S. Ne pozabite dodati svojega najljubšega train loop za segmentacijo in v produkcijo!

Zahvale

Hvala skupnosti ods.ai, brez nje ni mogoče napredovati! Ogromno hvala n01z3, ki me je spodbudil, da se ukvarjam z DL, za njegove neprecenljive nasvete in izjemno profesionalnost!

Uporabite optimizirane modele v produkciji!

TensorRT 6.x.x.x — visoko zmogljivo sklepanje za modele globokega učenja (odkrivanje objektov in segmentacija) Aurorai, llc

Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster