TensorRT 6.x.x.x — inferencĂ« me performancĂ« tĂ« lartĂ« pĂ«r modelet e mĂ«simit tĂ« thellĂ« (Zbulimi i Objekteve dhe Segmentimi)

TensorRT 6.x.x.x — inferencĂ« me performancĂ« tĂ« lartĂ« pĂ«r modelet e mĂ«simit tĂ« thellĂ« (Zbulimi i Objekteve dhe Segmentimi)
Dhemb vetëm herën e parë!

Përshëndetje të gjithëve! Të dashur miq, në këtë artikull dëshiroj të ndaj përvojën time në përdorimin e TensorRT, RetinaNet të bazuar në depo. github.com/aidonchuk/retinanet-examples (kjo është një fork i depozites zyrtare nga nvidia, e cila do të lejojë të filloni të përdorni modele të optimizuara në prodhim në një kohë të shkurtër). Duke shfletuar mesazhet në kanalet e komunitetit ods.ai, has këto pyetje mbi përdorimin e TensorRT, dhe kryesisht pyetjet përsëriten, prandaj vendosa të shkruaj sa më të plota një udhëzues për përdorimin e inferencës së shpejtë bazuar në TensorRT, RetinaNet, Unet dhe docker.

Përshkrimi i detyrës

Propozoj të formulojmë detyrën kështu: na nevojitet të shënojmë dataset-in, të trajnojmë një rrjet RetinaNet/Unet në Pytorch1.3+, të transformojmë peshat e marra në ONNX, më pas të konvertojmë ato në engine TensorRT dhe gjithë këtë ta nisni në docker, preferohet në Ubuntu 18 dhe është shumë e dëshirueshme në arkitekturën ARM(Jetson)*, duke minimizuar kështu vendosjen manuale të ambientit. Në fund, do të na dalë një kontejner i gatshëm jo vetëm për eksport dhe trajnim të RetinaNet/Unet, por edhe për zhvillim dhe trajnim të klasifikimit, segmentimit me të gjithë mbështetje të nevojshme.

Hapi 1. Përgatitja e mjedisit

ËshtĂ« e rĂ«ndĂ«sishme tĂ« theksohet se sĂ« fundmi kam kaluar plotĂ«sisht nĂ« shmangien e pĂ«rdorimit dhe ndĂ«rtimeve tĂ« ndonjĂ« biblioteke nĂ« makinĂ«n desktop, ashtu si dhe nĂ« devbox. E vetmja gjĂ« qĂ« duhet tĂ« krijoj dhe instalojĂ« Ă«shtĂ« mjedisi virtual i Python dhe cuda 10.2 (mund tĂ« mjaftohet me njĂ« driver nvidia) nga deb.

Le të supozojmë se keni një Ubuntu 18 të sapoinstaluar. Do të instalojmë cuda 10.2 (deb), nuk do të ndalem në procesin e instalimit, dokumentacioni zyrtar është mjaftueshëm i detajuar.

Tani do tĂ« instalojmĂ« docker, udhĂ«zimet pĂ«r instalimin e docker-it janĂ« lehtĂ«sisht tĂ« gjetshme, ja njĂ« shembull www.digitalocean.com/community/tutorials/docker-ubuntu-18-04-1-sq, tashmĂ« Ă«shtĂ« nĂ« dispozicion versioni 19+ — e vendosim atĂ«. Dhe mos harroni tĂ« lejoni pĂ«rdorimin e docker pa sudo, kĂ«shtu do tĂ« jetĂ« mĂ« e lehtĂ«. Pasi tĂ« jetĂ« gjithçka e rregullt, bĂ«ni kĂ«shtu:

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

Dhe madje as nuk keni nevojë të shikoni në depozitat zyrtare github.com/NVIDIA/nvidia-docker.

Tani bëni git clone github.com/aidonchuk/retinanet-examples.

Ka mbetur shumë pak për të filluar përdorimin e docker me imazhin nvidia, na nevojitet të regjistrohemi në NGC Cloud dhe të identifikoheshim. Le të shkojmë këtu ngc.nvidia.com, regjistrohemi dhe pasi të hyjmë në NGC Cloud, klikojmë SETUP në cepin e majtë të ekranit ose kalojmë përmes kësaj lidhjeje ngc.nvidia.com/setup/api-key. Klikoni "gjenë çelësin". E rekomandoj ta ruani, përndryshe gjatë vizitës së ardhshme do të duhet ta gjeneroni përsëri dhe, përkatësisht, gjatë instalimeve në një makinë të re, do të duhet të kryeni përsëri këtë operacion.

Le të ekzekutojmë:

docker login nvcr.io
Username: $oauthtoken
Password:  - çelësi i gjeneruar

Username thjesht kopjoni. Ja, konsideroni se mjedisi është instaluar!

Hapi 2. Ndërtimi i kontejnerit docker

Në hapat e dytë të punës sonë, do të ndërtojmë docker dhe do të njihemi me brendësinë e tij.
Do të kalojmë në dosjen rrënjësore në lidhje me projektin retina-examples dhe do të përmbushim

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

Ne po ndĂ«rtojmĂ« docker duke kaluar pĂ«rdoruesin aktual – kjo Ă«shtĂ« shumĂ« e dobishme nĂ«se do tĂ« shkruani diçka nĂ« VOLUME tĂ« koduar me tĂ« drejtat e pĂ«rdoruesit aktuell, ndryshe do tĂ« jetĂ« root dhe e dhimbshme.

Derisa docker është duke u ndërtuar, le të studiojmë Dockerfile:

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

Siç shihet nga teksti, ne marrim të gjitha libraritë tona të preferuara, kompilojmë retinanet, vendosim disa mjete bazë për lehtësi punimi me Ubuntu dhe konfigurojmë serverin openssh. Rreshti i parë është pikërisht trashëgimia e imazhit nvidia, për të cilin ne bëmë hyrjen në NGC Cloud dhe që përmban Pytorch1.3, TensorRT6.x.x.x dhe një sërë bibliotekash tjetër që lejojnë kompilimin e burimeve cpp të detektorit tonë.

Hapi 3. Nisja dhe debugging-u i kontejnerit docker

Të kalojmë në rastin kryesor të përdorimit të kontejnerit dhe mjedisit të zhvillimit, fillimisht do të ngremë nvidia docker. Do të ekzekutojmë:

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

Tani kontejneri është i aksesueshëm përmes ssh @localhost. Pas nisjes së suksesshme, hapim projektin në PyCharm. Më pas hapim

Settings->Project Interpreter->Add->Ssh Interpreter

Hapi 1
TensorRT 6.x.x.x — inferencĂ« me performancĂ« tĂ« lartĂ« pĂ«r modelet e mĂ«simit tĂ« thellĂ« (Zbulimi i Objekteve dhe Segmentimi)

Hapi 2
TensorRT 6.x.x.x — inferencĂ« me performancĂ« tĂ« lartĂ« pĂ«r modelet e mĂ«simit tĂ« thellĂ« (Zbulimi i Objekteve dhe Segmentimi)

Hapi 3
TensorRT 6.x.x.x — inferencĂ« me performancĂ« tĂ« lartĂ« pĂ«r modelet e mĂ«simit tĂ« thellĂ« (Zbulimi i Objekteve dhe Segmentimi)

Zgjidhim gjithçka siç është në screenshot-et,

Interpreter -> /opt/conda/bin/python

— ky do tĂ« jetĂ« ln nĂ« Python3.6 dhe

Sync folder -> /workspace/retinanet

Klikojmë përfundimi, presim indeksimin, dhe gjithçka, mjedisi është i gatshëm për përdorim!

E RËNDËSISHME!!! MenjĂ«herĂ« pas indeksimit, tĂ« tĂ«rheqim nga docker skedarĂ«t e kompiluar pĂ«r Retinanet. NĂ« menynĂ« kontekstuese nĂ« rrĂ«njĂ«n e projektit, do tĂ« zgjedhim opsionin

Deployment->Download

Do të shfaqen një skedar dhe dy dosje build, retinanet.egg-info dhe _Х.so

TensorRT 6.x.x.x — inferencĂ« me performancĂ« tĂ« lartĂ« pĂ«r modelet e mĂ«simit tĂ« thellĂ« (Zbulimi i Objekteve dhe Segmentimi)

Nëse projekti juaj duket kështu, atëherë mjedisi sheh të gjitha skedarët e nevojshëm dhe jemi të gatshëm për të trajnuar RetinaNet.

Hapi 4. Shënjimi i të dhënave dhe trajnimet e detektorit

PĂ«r shĂ«njimin unĂ«, nĂ« pĂ«rgjithĂ«si, pĂ«rdor supervise.ly — njĂ« mjet i kĂ«ndshĂ«m dhe i rehatshĂ«m, sĂ« fundmi janĂ« riparuar shumĂ« probleme dhe tani po sjell rezultate shumĂ« mĂ« tĂ« mira.

Supozoni se keni shënjuar datasetin dhe e keni shkarkuar, por nuk mund ta futni menjëherë në RetinaNet tonë, sepse ai është në formatin e tij dhe për këtë na nevojitet ta konvertojmë në COCO. Mjeti për konvertim ndodhet në:

markup_utils/supervisly_to_coco.py

Kujtoni se Kategoria në skript është një shembull dhe ju duhet të vendosni tuajat (nuk është e nevojshme të shtoni kategorinë background)

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

Autorët e depozitës origjinale për një arsye ose tjetër menduan se nuk do të strehoni asgjë tjetër përveç COCO/VOC për detektimin, prandaj duhej ta redaktojmë pak skedarin fillestar

retinanet/dataset.py

Duke shtuar këtu augmentimet e preferuara albumentations.readthedocs.io/en/latest dhe hiqni kategoritë e ngurta të integruara nga COCO. Ka gjithashtu mundësinë për të prerë zona të mëdha të detektimit, nëse po kërkoni objekte të vogla në imazhe të mëdha, keni një dataset të vogël =), dhe asgjë nuk funksionon, por për këtë një herë tjetër.

Në përgjithësi, tranimi loop është gjithashtu i dobët, në fillim nuk po ruante piketat, përdorte një scheduler të tmerrshëm etj. Por tani ju mbetet vetëm të zgjidhni backbone dhe të ekzekutoni

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

me parametrat:

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

Do të shihni në konsolë:

Duke modelin...
     modeli: RetinaNet
  bazamenti: ResNet18FPN
   klasat: 2, ankorët: 9
Zgjedhur niveli i optimizimit O0:  Trajnim të pastër FP32.

Parazgjedhjet për këtë nivel optimizimi janë:
enabled                : E vërtetë
opt_level              : O0
cast_model_type        : torch.float32
patch_torch_functions  : E falsifikuar
keep_batchnorm_fp32    : Asnjë
master_weights         : E falsifikuar
loss_scale             : 1.0
Po procesojmë mbivendosjet e përdoruesit (kërkesa shtesë që nuk janë asnjë)...
Pas përpunimit të mbivendosjeve, opsionet e optimizimit janë:
enabled                : E vërtetë
opt_level              : O0
cast_model_type        : torch.float32
patch_torch_functions  : E falsifikuar
keep_batchnorm_fp32    : Asnjë
master_weights         : E falsifikuar
loss_scale             : 128.0
Duke përgatitur datasetin...
    ngarkuesi: pytorch
    rihap: [1024, 1280], maksimumi: 1280
    pajisja: 4 gpus
    grupi: 4, saktësia: e përzier
Duke trajnuar modelin për 20000 iteracione...
[    1/20000] humbja fokale: 0.95619, humbja e kutisë: 0.51584, 4.042s/4-grup (fw: 0.698s, bw: 0.459s), 1.0 im/s, lr: 0.0001
[   12/20000] humbja fokale: 0.76191, humbja e kutisë: 0.31794, 0.187s/4-grup (fw: 0.055s, bw: 0.133s), 21.4 im/s, lr: 0.0001
[   24/20000] humbja fokale: 0.65036, humbja e kutisë: 0.30269, 0.173s/4-grup (fw: 0.045s, bw: 0.128s), 23.1 im/s, lr: 0.0001
[   36/20000] humbja fokale: 0.46425, humbja e kutisë: 0.23141, 0.178s/4-grup (fw: 0.047s, bw: 0.131s), 22.4 im/s, lr: 0.0001
[   48/20000] humbja fokale: 0.45115, humbja e kutisë: 0.23505, 0.180s/4-grup (fw: 0.047s, bw: 0.133s), 22.2 im/s, lr: 0.0001
[   59/20000] humbja fokale: 0.38958, humbja e kutisë: 0.25373, 0.184s/4-grup (fw: 0.049s, bw: 0.134s), 21.8 im/s, lr: 0.0001
[   71/20000] humbja fokale: 0.37733, humbja e kutisë: 0.23988, 0.174s/4-grup (fw: 0.049s, bw: 0.125s), 22.9 im/s, lr: 0.0001
[   83/20000] humbja fokale: 0.39514, humbja e kutisë: 0.23878, 0.181s/4-grup (fw: 0.048s, bw: 0.133s), 22.1 im/s, lr: 0.0001
[   94/20000] humbja fokale: 0.39947, humbja e kutisë: 0.23817, 0.185s/4-grup (fw: 0.050s, bw: 0.134s), 21.6 im/s, lr: 0.0001
[  105/20000] humbja fokale: 0.37343, humbja e kutisë: 0.20238, 0.182s/4-grup (fw: 0.048s, bw: 0.134s), 22.0 im/s, lr: 0.0001
[  116/20000] humbja fokale: 0.19689, humbja e kutisë: 0.17371, 0.183s/4-grup (fw: 0.050s, bw: 0.132s), 21.8 im/s, lr: 0.0001
[  128/20000] humbja fokale: 0.20368, humbja e kutisë: 0.16538, 0.178s/4-grup (fw: 0.046s, bw: 0.131s), 22.5 im/s, lr: 0.0001
[  140/20000] humbja fokale: 0.22763, humbja e kutisë: 0.15772, 0.176s/4-grup (fw: 0.050s, bw: 0.126s), 22.7 im/s, lr: 0.0001
[  148/20000] humbja fokale: 0.21997, humbja e kutisë: 0.18400, 0.585s/4-grup (fw: 0.047s, bw: 0.144s), 6.8 im/s, lr: 0.0001
 Saktësia Mesatare (AP) @[ IoU=0.50:0.95 | zona=   të gjithë | maxDets=100 ] = 0.52674
 Saktësia Mesatare (AP) @[ IoU=0.50      | zona=   të gjithë | maxDets=100 ] = 0.91450
 Saktësia Mesatare (AP) @[ IoU=0.75      | zona=   të gjithë | maxDets=100 ] = 0.35172
 Saktësia Mesatare (AP) @[ IoU=0.50:0.95 | zona= e vogël | maxDets=100 ] = 0.61881
 Saktësia Mesatare (AP) @[ IoU=0.50:0.95 | zona=mesatare | maxDets=100 ] = -1.00000
 Saktësia Mesatare (AP) @[ IoU=0.50:0.95 | zona= e madhe | maxDets=100 ] = -1.00000
 Kujtesa Mesatare     (AR) @[ IoU=0.50:0.95 | zona=   të gjithë | maxDets=  1 ] = 0.58824
 Kujtesa Mesatare     (AR) @[ IoU=0.50:0.95 | zona=   të gjithë | maxDets= 10 ] = 0.61765
 Kujtesa Mesatare     (AR) @[ IoU=0.50:0.95 | zona=   të gjithë | maxDets=100 ] = 0.61765
 Kujtesa Mesatare     (AR) @[ IoU=0.50:0.95 | zona= e vogël | maxDets=100 ] = 0.61765
 Kujtesa Mesatare     (AR) @[ IoU=0.50:0.95 | zona=mesatare | maxDets=100 ] = -1.00000
 Kujtesa Mesatare     (AR) @[ IoU=0.50:0.95 | zona= e madhe | maxDets=100 ] = -1.00000
Duke ruajtur modelin: 148

Për të studiuar të gjitha parametrat, shikoni

retinanet/main.py

Në përgjithësi, ato janë standarde për detektimin dhe kanë përshkrim. Nisni trajnimin dhe prisni rezultatet. Shembulli i inferencës mund të shihet në:

retinanet/infer_example.py

ose ekzekutoni komandën:

/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

Në repository tashmë është integruar Focal Loss dhe disa backbone, si dhe është e lehtë të integroni të tuajat

retinanet/backbones/*.py

Në tabelë autorët paraqesin disa karakteristika:

TensorRT 6.x.x.x — inferencĂ« me performancĂ« tĂ« lartĂ« pĂ«r modelet e mĂ«simit tĂ« thellĂ« (Zbulimi i Objekteve dhe Segmentimi)

Ka gjithashtu backbone ResNeXt50_32x4dFPN dhe ResNeXt101_32x8dFPN, të marra nga torchvision.
Shpresojmë të kemi kuptuar pak me detektimin, por është e domosdoshme të lexoni dokumentacionin zyrtar për të kuptuar modet e eksportit dhe të logimit.

Hapi 5. Eksporti dhe inferenca e modeleve Unet me encoder Resnet

Siç e keni vënë re, në Dockerfile u instaluan bibliotekat për segmentimin dhe në veçanti një bibliotekë e shkëlqyer github.com/qubvel/segmentation_models.pytorch. Në paketën Unet mund të gjeni shembuj të inferencës dhe eksportit të chekpoint-eve pytorch në motorin TensorRT.

Problemi kryesor gjatë eksportit të modeleve Unet-like nga ONNX në TensoRT është nevoja për të caktuar një madhësi fikse Upsample ose për të përdorur ConvTranspose2D:

import torch.onnx.symbolic_opset9 as onnx_symbolic
        def upsample_nearest2d(g, input, output_size):
            # Currently, TRT 5.1/6.0 ONNX Parser does not support all ONNX ops
            # needed to support dynamic upsampling ONNX forumlation
            # Here we hardcode scale=2 as a temporary workaround
            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

Me transformimi i kësaj, mund ta bëni këtë automatikisht gjatë eksportimit në ONNX, por që në versionin 7 të TensorRT e kemi zgjidhur këtë problem, dhe na mbetet të presim pak.

Përfundimi

Kur fillova të përdorja docker, kisha dyshime për performancën e tij për detyrat e mia. Në një nga agregatorët e mi tani ka një trafiku të konsiderueshëm rrjetor që krijohet nga disa kamera.

TensorRT 6.x.x.x — inferencĂ« me performancĂ« tĂ« lartĂ« pĂ«r modelet e mĂ«simit tĂ« thellĂ« (Zbulimi i Objekteve dhe Segmentimi)

Testet e ndryshme në internet flisnin për një overhead relativisht të madh në ndërveprimin rrjetor dhe regjistrimin në VOLUME, përveç kësaj edhe GIL-i, që është një mister i frikshëm, dhe pasi kapja e një kadri, funksionimi i drejtuesit dhe transferimi i kadrave në rrjet janë operacione atomike në modalitetin hard real-time, vonesat në rrjet për mua janë shumë kritike.

Por gjithçka doli mirë =)

P.S. Duhet vetëm të shtosh ciklin tënd të preferuar për segmentimin dhe në prodhim!

Faleminderit

Faleminderit komunitetit ods.ai, pa të nuk është e mundur të zhvillohet! Faleminderit shumë n01z3, që më këshilloi të angazhohem në DL, për këshillat e tij të çmuara dhe profesionalizmin e jashtëzakonshëm!

Përdorni modele të optimizuara në production!

TensorRT 6.x.x.x — inferencĂ« me performancĂ« tĂ« lartĂ« pĂ«r modelet e mĂ«simit tĂ« thellĂ« (Zbulimi i Objekteve dhe Segmentimi) Aurorai, llc

Burimi: habr.com

Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« đŸ”„ Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« | ProHoster