TensorRT 6.x.x.x - højtydende inferens for dyb læringsmodeller (Object Detection og Segmentation)

TensorRT 6.x.x.x - højtydende inferens for dyb læringsmodeller (Object Detection og Segmentation)
Det gør kun ondt første gang!

Hej alle! Kære venner, i denne artikel vil jeg dele min erfaring med at bruge TensorRT, RetinaNet baseret på repository github.com/aidonchuk/retinanet-examples (dette er en fork af det officielle repo fra nvidia, som vil gøre det muligt at begynde at bruge optimerede modeller i produktionen på kort tid). Når jeg ruller gennem beskeder i fællesskabets kanaler ods.ai, støder jeg på spørgsmål om brugen af TensorRT, og størstedelen af spørgsmålene går igen, så jeg besluttede at skrive en så fuldstændig som muligt vejledning til brug af hurtig inferens baseret på TensorRT, RetinaNet, Unet og docker.

Beskrivelse af opgaven

Jeg foreslår at formulere opgaven således: vi skal annotere et datasæt, træne en RetinaNet/Unet model på Pytorch1.3+, konvertere de opnåede vægte til ONNX, derefter konvertere dem til TensorRT engine og køre hele dette setup i docker, helst på Ubuntu 18 og meget gerne på ARM(Jetson)* arkitektur, dermed minimere manuel opsætning af miljøet. I sidste ende vil vi få en container klar til ikke kun eksport og træning af RetinaNet/Unet, men også til den fulde udvikling og træning af klassifikation, segmentering med alt nødvendigt tilbehør.

Trin 1. Klargøring af miljøet

Det er vigtigt at bemærke, at jeg for nylig helt er gået væk fra at bruge og opsætte nogen biblioteker på desktop maskinen, ligesom på devbox. Det eneste, jeg skal oprette og installere – er python virtuel miljø og cuda 10.2 (man kan klart nøjes med en nvidia driver) fra deb.

Lad os antage, at du har en nyinstalleret Ubuntu 18. Lad os installere cuda 10.2(deb), jeg vil ikke gå i detaljer med installationsprocessen, den officielle dokumentation er helt tilstrækkelig.

Lad os nu installere docker, en vejledning til installation af docker kan nemt findes, her er et eksempel www.digitalocean.com/community/tutorials/docker-ubuntu-18-04-1-da, version 19+ er allerede tilgængelig — lad os installere den. Og glem ikke at gøre det muligt at bruge docker uden sudo, så er det nemmere. Når det hele er klaret, gør vi således:

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

Og man kunne endda undgå at kigge i det officielle repository github.com/NVIDIA/nvidia-docker.

Nu laver vi git clone github.com/aidonchuk/retinanet-examples.

Der er kun lidt tilbage, før du kan begynde at bruge Docker med Nvidia-billedet, vi skal registrere os i NGC Cloud og logge ind. Gå hertil ngc.nvidia.com, registrer dig, og efter vi kommer ind i NGC Cloud, klikker vi på SETUP i øverste venstre hjørne af skærmen eller går til dette link ngc.nvidia.com/setup/api-key. Klik på 'generere nøgle'. Jeg anbefaler at gemme den, ellers skal den genereres igen ved næste besøg, og dermed skal denne proces gentages, når du opretter på en ny maskine.

Lad os udføre:

docker login nvcr.io
Brugernavn: $oauthtoken
Adgangskode:  - den genererede nøgle

Vi kopierer blot brugernavnet. Nå, nu er miljøet næsten oprettet!

Trin 2. Bygning af Docker-container

I det andet trin af vores arbejde vil vi opbygge Docker og lære om dets indre funktioner.
Lad os navigere til rodmappen i forhold til projektet retina-examples og udføre

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

Vi opbygger Docker ved at passere den aktuelle bruger gennem, hvilket er meget nyttigt, hvis du skal skrive noget på det monterede VOLUME med den aktuelle brugers rettigheder, ellers vil det være root, og det er besværligt.

Mens Docker bygges, lad os tage et kig på Dockerfilen:

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

Som det fremgår af teksten, tager vi alle vores yndlingsbiblioteker, kompilerer retinanet, tilføjer grundlæggende værktøjer til arbejde med Ubuntu, og konfigurerer serveren openssh. Den første linje handler om arven fra nvidia-billedet, som vi loggede ind på i NGC Cloud, og som indeholder Pytorch1.3, TensorRT6.x.x.x og en masse biblioteker, der gør det muligt at kompilere cpp-kildekoden til vores detektor.

Trin 3. Start og fejlfinding af docker-containeren

Lad os gå videre til det primære anvendelsessag for containeren og udviklingsmiljøet, først skal vi starte nvidia docker. Udfør:

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

Nu er containeren tilgængelig via ssh @localhost. Efter en vellykket opstart åbner vi projektet i PyCharm. Dernæst åbner vi

Indstillinger-> Projektfortolker-> Tilføj-> Ssh-fortolker

Trin 1
TensorRT 6.x.x.x - højtydende inferens for dyb læringsmodeller (Object Detection og Segmentation)

Trin 2
TensorRT 6.x.x.x - højtydende inferens for dyb læringsmodeller (Object Detection og Segmentation)

Trin 3
TensorRT 6.x.x.x - højtydende inferens for dyb læringsmodeller (Object Detection og Segmentation)

Vi vælger alt som på skærmbillederne,

Fortolker -> /opt/conda/bin/python

— det vil være ln til Python3.6 og

Synkroniseringsmappe -> /workspace/retinanet

Vi klikker på afslut, venter på indeksering, og så er miljøet klar til brug!

VIGTIGT!!! Straks efter indeksering trækker vi de kompilerede filer til Retinanet fra docker. I kontekstmenuen i rodmappen af projektet vælger vi punktet

Deployment-> Download

Der vil dukke en fil og to mapper op: build, retinanet.egg-info og _C.so

TensorRT 6.x.x.x - højtydende inferens for dyb læringsmodeller (Object Detection og Segmentation)

Hvis dit projekt ser sådan ud, så ser miljøet alle de nødvendige filer, og vi er klar til træning af RetinaNet.

Trin 4. Vi mærker data og træner detektoren

For annotering bruger jeg primært supervise.ly — et behageligt og brugervenligt værktøj, som i den seneste tid har rettet mange fejl og er blevet betydeligt bedre.

Antag, at du har annoteret datasættet og downloadet det, men du kan ikke straks bruge det i vores RetinaNet, da det er i et eget format, og vi derfor skal konvertere det til COCO. Værktøjet til konvertering findes i:

markup_utils/supervisly_to_coco.py

Bemærk, at Category i scriptet er et eksempel, og du skal indsætte dine egne (kategorien baggrund skal ikke tilføjes)

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

Forfatterne af det originale repositorium mente åbenbart, at du ikke ville træne noget andet end COCO/VOC til detektion, så jeg måtte redigere kildefilen lidt

retinanet/dataset.py

Ved at tilføje her de yndlingsaugmentationer albumentations.readthedocs.io/en/latest og og fjerne hårdt indlejrede kategorier fra COCO. Der er også mulighed for at beskære store detektionsområder, hvis du leder efter små objekter på store billeder, har et lille datasæt =), og intet fungerer, men det er et emne for en anden gang.

Generelt er træningssløjfen også svag, den gemte oprindeligt ikke checkpoints, brugte en forfærdelig scheduler osv. Men nu er det kun tilbage at vælge backbone og udføre.

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

med parametre:

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

I konsollen vil du se:

Initialisering af model...
     model: RetinaNet
  backbone: ResNet18FPN
   klasser: 2, ankre: 9
Valgt optimeringsniveau O0: Ren FP32 træning.

Standarder for dette optimeringsniveau er:
tændt                  : Sand
opt_niveau              : O0
cast_model_type        : torch.float32
patch_torch_functions  : Falsk
keep_batchnorm_fp32    : Ingen
master_weights         : Falsk
loss_scale             : 1.0
Behandler brugeroverskridelser (yderligere kwargs, der ikke er None)...
Efter behandling af overskridelser er optimeringsmulighederne:
tændt                  : Sand
opt_niveau              : O0
cast_model_type        : torch.float32
patch_torch_functions  : Falsk
keep_batchnorm_fp32    : Ingen
master_weights         : Falsk
loss_scale             : 128.0
Forbereder datasæt...
    loader: pytorch
    størrelse: [1024, 1280], maks: 1280
    enhed: 4 gpu'er
    batch: 4, præcision: blandet
Træner model i 20000 iterationer...
[    1/20000] fokus tab: 0.95619, boks tab: 0.51584, 4-batch 4.042s (fw: 0.698s, bw: 0.459s), 1.0 im/s, lr: 0.0001
[   12/20000] fokus tab: 0.76191, boks tab: 0.31794, 0.187s/4-batch (fw: 0.055s, bw: 0.133s), 21.4 im/s, lr: 0.0001
[   24/20000] fokus tab: 0.65036, boks tab: 0.30269, 0.173s/4-batch (fw: 0.045s, bw: 0.128s), 23.1 im/s, lr: 0.0001
[   36/20000] fokus tab: 0.46425, boks tab: 0.23141, 0.178s/4-batch (fw: 0.047s, bw: 0.131s), 22.4 im/s, lr: 0.0001
[   48/20000] fokus tab: 0.45115, boks tab: 0.23505, 0.180s/4-batch (fw: 0.047s, bw: 0.133s), 22.2 im/s, lr: 0.0001
[   59/20000] fokus tab: 0.38958, boks tab: 0.25373, 0.184s/4-batch (fw: 0.049s, bw: 0.134s), 21.8 im/s, lr: 0.0001
[   71/20000] fokus tab: 0.37733, boks tab: 0.23988, 0.174s/4-batch (fw: 0.049s, bw: 0.125s), 22.9 im/s, lr: 0.0001
[   83/20000] fokus tab: 0.39514, boks tab: 0.23878, 0.181s/4-batch (fw: 0.048s, bw: 0.133s), 22.1 im/s, lr: 0.0001
[   94/20000] fokus tab: 0.39947, boks tab: 0.23817, 0.185s/4-batch (fw: 0.050s, bw: 0.134s), 21.6 im/s, lr: 0.0001
[  105/20000] fokus tab: 0.37343, boks tab: 0.20238, 0.182s/4-batch (fw: 0.048s, bw: 0.134s), 22.0 im/s, lr: 0.0001
[  116/20000] fokus tab: 0.19689, boks tab: 0.17371, 0.183s/4-batch (fw: 0.050s, bw: 0.132s), 21.8 im/s, lr: 0.0001
[  128/20000] fokus tab: 0.20368, boks tab: 0.16538, 0.178s/4-batch (fw: 0.046s, bw: 0.131s), 22.5 im/s, lr: 0.0001
[  140/20000] fokus tab: 0.22763, boks tab: 0.15772, 0.176s/4-batch (fw: 0.050s, bw: 0.126s), 22.7 im/s, lr: 0.0001
[  148/20000] fokus tab: 0.21997, boks tab: 0.18400, 0.585s/4-batch (fw: 0.047s, bw: 0.144s), 6.8 im/s, lr: 0.0001
 Gennemsnitlig præcision (AP) @[ IoU=0.50:0.95 | område=   alt | maxDets=100 ] = 0.52674
 Gennemsnitlig præcision (AP) @[ IoU=0.50      | område=   alt | maxDets=100 ] = 0.91450
 Gennemsnitlig præcision (AP) @[ IoU=0.75      | område=   alt | maxDets=100 ] = 0.35172
 Gennemsnitlig præcision (AP) @[ IoU=0.50:0.95 | område= lille | maxDets=100 ] = 0.61881
 Gennemsnitlig præcision (AP) @[ IoU=0.50:0.95 | område=middel | maxDets=100 ] = -1.00000
 Gennemsnitlig præcision (AP) @[ IoU=0.50:0.95 | område= stor | maxDets=100 ] = -1.00000
 Gennemsnitlig tilbagekaldelse (AR) @[ IoU=0.50:0.95 | område=   alt | maxDets=  1 ] = 0.58824
 Gennemsnitlig tilbagekaldelse (AR) @[ IoU=0.50:0.95 | område=   alt | maxDets= 10 ] = 0.61765
 Gennemsnitlig tilbagekaldelse (AR) @[ IoU=0.50:0.95 | område=   alt | maxDets=100 ] = 0.61765
 Gennemsnitlig tilbagekaldelse (AR) @[ IoU=0.50:0.95 | område= lille | maxDets=100 ] = 0.61765
 Gennemsnitlig tilbagekaldelse (AR) @[ IoU=0.50:0.95 | område=middel | maxDets=100 ] = -1.00000
 Gennemsnitlig tilbagekaldelse (AR) @[ IoU=0.50:0.95 | område= stor | maxDets=100 ] = -1.00000
Gemmer model: 148

For at lære alle parametrene, se venligst

retinanet/main.py

Generelt er de standard for detektion, og de har en beskrivelse. Start træningen og vent på resultaterne. Et eksempel på inferens kan findes i:

retinanet/infer_example.py

eller udfør kommandoen:

/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

I repositoriet er der allerede indbygget Focal Loss og flere backbone, og man kan nemt integrere sine egne.

retinanet/backbones/*.py

I tabellen giver forfatterne nogle specifikationer:

TensorRT 6.x.x.x - højtydende inferens for dyb læringsmodeller (Object Detection og Segmentation)

Der er også backbone ResNeXt50_32x4dFPN og ResNeXt101_32x8dFPN, taget fra torchvision.
Jeg håber, at vi har fået styr på detektion, men det er vigtigt at læse den officielle dokumentation for at forstå eksport- og loggingsindstillingerne..

Trin 5. Eksport og inferens af Unet-modeller med Resnet-encoder.

Som du nok har bemærket, er der blevet installeret biblioteker til segmentering i Dockerfile, især det fremragende bibliotek github.com/qubvel/segmentation_models.pytorch.I Unet-pakken kan du finde eksempler på inferens og eksport af pytorch checkpoints til TensorRT-motoren.

Det primære problem ved eksport af Unet-lignende modeller fra ONNX til TensorRT er behovet for at angive en fast størrelse for Upsample eller bruge ConvTranspose2D:

import torch.onnx.symbolic_opset9 as onnx_symbolic
        def upsample_nearest2d(g, input, output_size):
            # I øjeblikket understøtter TRT 5.1/6.0 ONNX Parser ikke alle ONNX-funktioner
            # nødvendige for at understøtte dynamisk opskalerings ONNX-formulering.
            # Her hardcoder vi scale=2 som en midlertidig løsning.
            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

Med denne transformation kan dette gøres automatisk ved eksport til ONNX, men i den 7. version af TensorRT er dette problem blevet løst, og vi skal blot vente lidt.

Konklusion

Da jeg begyndte at bruge Docker, havde jeg mine tvivl om dets ydeevne til mine opgaver. I en af mine aggregationer genereres der nu en ret stor netværkstrafik af flere kameraer.

TensorRT 6.x.x.x - højtydende inferens for dyb læringsmodeller (Object Detection og Segmentation)

Forskellige tests på internettet talte om en relativt stor overhead ved netværksinteraktion og skrivning til VOLUME, plus den ukendte og skræmmende GIL, og da optagelse af et billede, arbejde med driveren og overførsel af et billede over nettet er atomare operationer i tilstand hard real-time, er netværksforsinkelse meget kritisk for mig.

Men alt gik godt =)

P.S. Husk at tilføje din yndlings træningsløkke for segmentering og i produktion!

Taknemmelighed

Tak til fællesskabet ods.ai, uden det er det umuligt at udvikle sig! Mange tak n01z3, som fik mig til at tage fat på DL, for hans uvurderlige råd og ekstreme professionalisme!

Brug optimerede modeller i produktionen!

TensorRT 6.x.x.x - højtydende inferens for dyb læringsmodeller (Object Detection og Segmentation) Aurorai, llc

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster