TensorRT 6.xxx — Բարձր արդյունավետության եզրակացություն խորը ուսուցման մոդելների համար (օբյեկտների հայտնաբերում և հատվածավորում)

TensorRT 6.xxx — Բարձր արդյունավետության եզրակացություն խորը ուսուցման մոդելների համար (օբյեկտների հայտնաբերում և հատվածավորում)
Միայն առաջին անգամն է ցավում!

Բարև բոլորին։ Սիրելի՛ ընկերներ, այս հոդվածում ես ուզում եմ կիսվել իմ փորձով՝ օգտագործելով TensorRT, RetinaNet՝ հիմնված պահոցի վրա։ github.com/aidonchuk/retinanet-examples (սա պաշտոնական պահոցի ճյուղավորումն է NVIDIA, որը թույլ կտա ձեզ սկսել օպտիմիզացված մոդելների օգտագործումը արտադրության մեջ հնարավորինս կարճ ժամանակում): Համայնքային ալիքներում հաղորդագրությունների մեջ թերթում ods.aiԵս հանդիպում եմ TensorRT-ի օգտագործման վերաբերյալ հարցերի, և հիմնականում հարցերը կրկնվում են, ուստի որոշեցի գրել որքան հնարավոր է ամբողջական TensorRT, RetinaNet, Unet և docker-ի վրա հիմնված արագ եզրակացության օգտագործման ուղեցույց։

Առաջադրանքի նկարագրությունը

Ես առաջարկում եմ առաջադրանքը ձևակերպել հետևյալ կերպ. մենք պետք է պիտակավորենք տվյալների բազմությունը, մարզենք RetinaNet/Unet ցանցը Pytorch 1.3+-ի վրա, ստացված կշիռները փոխարկենք ONNX-ի, այնուհետև փոխարկենք դրանք TensorRT շարժիչի և ամբողջը աշխատացնենք Docker-ում, ցանկալի է՝ Ubuntu 18 և խիստ ցանկալի է ARM (Jetson)* ճարտարապետության վրա, այդպիսով նվազագույնի հասցնելով միջավայրի ձեռքով տեղակայումը: Վերջնական արդյունքը կլինի կոնտեյներ, որը պատրաստ կլինի ոչ միայն RetinaNet/Unet արտահանման և մարզման, այլև դասակարգման և սեգմենտացման համակարգերի լիարժեք մշակման և մարզման համար՝ բոլոր անհրաժեշտ սարքավորումներով:

Քայլ 1. Միջավայրի պատրաստում

Այստեղ կարևոր է նշել, որ վերջերս ես ամբողջությամբ հրաժարվել եմ ցանկացած գրադարաններ օգտագործելուց և տեղակայելուց ինչպես սեղանադիր համակարգչի, այնպես էլ devbox-ի վրա։ Միակ բանը, որ պետք է ստեղծել և տեղադրել, Python վիրտուալ միջավայրն է և deb-ից Cuda 10.2-ը (կարող եք սահմանափակվել մեկ nvidia դրայվերով)։

Ենթադրենք, որ դուք նոր եք տեղադրել Ubuntu 18. Եկեք տեղադրենք cuda 10.2 (deb): Ես չեմ մանրամասնի տեղադրման գործընթացը, պաշտոնական փաստաթղթերը բավականին բավարար են:

Հիմա եկեք տեղադրենք docker-ը, docker-ի տեղադրման ուղեցույցը կարելի է հեշտությամբ գտնել, ահա մի օրինակ www.digitalocean.com/community/tutorials/docker-ubuntu-18-04-1-ru, 19+ տարբերակը արդեն հասանելի է — եկեք տեղադրենք այն։ Եվ մի մոռացեք Docker-ը առանց Sudo-ի օգտագործելու հնարավորություն տալ, դա ավելի հարմար կլինի։ Ամեն ինչ կարգավորելուց հետո արեք այսպես.

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

Եվ դուք նույնիսկ կարիք չունեք նայելու պաշտոնական պահոցը github.com/NVIDIA/nvidia-docker.

Հիմա մենք git կլոնավորում ենք github.com/aidonchuk/retinanet-examples.

Մնացել է մի փոքր ժամանակ, որպեսզի սկսենք օգտագործել docker-ը nvidia պատկերով, մենք պետք է գրանցվենք NGC Cloud-ում և մուտք գործենք։ Մտեք այստեղ։ ngc.nvidia.com, գրանցվեք և NGC Cloud-ում մտնելուց հետո սեղմեք SETUP էկրանի վերին ձախ անկյունում կամ հետևեք այս հղմանը։ ngc.nvidia.com/setup/api-keyՍեղմեք «ստեղծել բանալի»։ Խորհուրդ եմ տալիս պահպանել այն, հակառակ դեպքում հաջորդ անգամ այցելելիս ստիպված կլինեք այն նորից ստեղծել և, համապատասխանաբար, այն նոր մեքենայի վրա տեղադրելիս կրկնել այս գործողությունը։

Եկեք անենք.

docker login nvcr.io
Username: $oauthtoken
Password: <Your Key> - сгенерированный ключ

Մենք պարզապես պատճենում ենք օգտատիրոջ անունը։ Դե, պատկերացրեք տեղակայված միջավայրը։

Քայլ 2. Docker կոնտեյների կառուցում

Մեր աշխատանքի երկրորդ փուլում մենք կկառուցենք docker-ը և կծանոթանանք դրա ներքին կառուցվածքին։
Եկեք գնանք retina-examples նախագծին վերաբերող root թղթապանակ և գործարկենք

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

Մենք docker-ը կառուցում ենք՝ ընթացիկ օգտատիրոջը փոխանցելով դրան։ Սա շատ օգտակար է, եթե դուք պատրաստվում եք ինչ-որ բան գրել միացված VOLUME-ում ընթացիկ օգտատիրոջ իրավունքներով, հակառակ դեպքում դա կլինի root և pain։

Մինչ docker-ը կառուցվում է, եկեք ուսումնասիրենք 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"]

Ինչպես կարող եք տեսնել տեքստից, մենք վերցնում ենք մեր բոլոր սիրելի գրադարանները, կազմում ենք retinanet-ը, ավելացնում ենք մի քանի հիմնական գործիքներ՝ դրանց հետ աշխատանքը հեշտացնելու համար։ Ubuntu և կարգավորել OpenSSH սերվերը։ Առաջին տողը ժառանգում է NVIDIA պատկերը, որի համար մենք ստեղծել ենք NGC Cloud մուտքանունը և որը պարունակում է Pytorch1.3, TensorRT6.xxx և մի շարք այլ գրադարաններ, որոնք թույլ են տալիս մեզ կազմել մեր դետեկտորի CPP կոդը։

Քայլ 3. Docker կոնտեյների գործարկում և վրիպազերծում

Եկեք անցնենք կոնտեյների և մշակման միջավայրի հիմնական օգտագործման դեպքին, նախ կգործարկենք nvidia docker-ը։ Եկեք գործարկենք՝

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

Կոնտեյները այժմ հասանելի է ssh-ի միջոցով @localhost: Հաջող մեկնարկից հետո բացեք նախագիծը PyCharm-ում: Հաջորդը, բացեք

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

Քայլ 1
TensorRT 6.xxx — Բարձր արդյունավետության եզրակացություն խորը ուսուցման մոդելների համար (օբյեկտների հայտնաբերում և հատվածավորում)

Քայլ 2
TensorRT 6.xxx — Բարձր արդյունավետության եզրակացություն խորը ուսուցման մոդելների համար (օբյեկտների հայտնաբերում և հատվածավորում)

Քայլ 3
TensorRT 6.xxx — Բարձր արդյունավետության եզրակացություն խորը ուսուցման մոդելների համար (օբյեկտների հայտնաբերում և հատվածավորում)

Մենք ամեն ինչ ընտրում ենք, ինչպես էկրանի նկարներում,

Interpreter -> /opt/conda/bin/python

- այն կլինի Python3.6-ի վրա և

Sync folder -> /workspace/retinanet

Սեղմեք «Ավարտել» կոճակը, սպասեք ինդեքսավորմանը, և վերջ, միջավայրը պատրաստ է օգտագործման համար։

ԿԱՐԵՎՈՐ !!! Ինդեքսավորումից անմիջապես հետո Docker-ից արդյունահանեք Retinanet-ի համար կազմված ֆայլերը: Նախագծի արմատային մասում գտնվող համատեքստային ցանկում ընտրեք հետևյալ կետը.

Deployment->Download

Կհայտնվեն մեկ ֆայլ և երկու թղթապանակ՝ build, retinanet.egg-info և _С.so

TensorRT 6.xxx — Բարձր արդյունավետության եզրակացություն խորը ուսուցման մոդելների համար (օբյեկտների հայտնաբերում և հատվածավորում)

Եթե ​​ձեր նախագիծը այսպիսի տեսք ունի, ապա միջավայրը տեսնում է բոլոր անհրաժեշտ ֆայլերը, և մենք պատրաստ ենք մարզել RetinaNet-ը։

Քայլ 4. Նշեք տվյալները և մարզեք դետեկտորը

Նշման համար ես հիմնականում օգտագործում եմ supervise.ly — հաճելի և հարմար գործիք, վերջերս մի շարք սխալներ են շտկվել, և այն սկսել է շատ ավելի լավ աշխատել։

Ենթադրենք, որ դուք նշել եք տվյալների բազմությունը և ներբեռնել այն, բայց չեք կարողանա այն անմիջապես տեղադրել մեր RetinaNet-ում, քանի որ այն ունի իր սեփական ձևաչափը, և դրա համար մենք պետք է այն փոխարկենք COCO-ի: Փոխարկման գործիքը գտնվում է հետևյալ հասցեով՝

markup_utils/supervisly_to_coco.py

Խնդրում ենք նկատի ունենալ, որ սկրիպտում «Կատեգորիա» բառը օրինակ է, և դուք պետք է մուտքագրեք ձեր սեփականը (ֆոնային կատեգորիան անհրաժեշտ չէ ավելացնել):

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

Ինչ-ինչ պատճառներով սկզբնական պահոցի հեղինակները որոշեցին, որ դուք COCO/VOC-ից բացի ուրիշ ոչինչ չեք մարզելու հայտնաբերման համար, ուստի ես ստիպված էի մի փոքր խմբագրել սկզբնաղբյուր ֆայլը։

retinanet/dataset.py

Ավելացրեք այստեղ ձեր նախընտրած լրացումները albumentations.readthedocs.io/en/latest և COCO-ից կտրել կոշտ կոդավորված կատեգորիաները: Հնարավոր է նաև կտրել հայտնաբերման մեծ տարածքներ, եթե մեծ պատկերներում փնտրում եք փոքր օբյեկտներ, ունեք փոքր տվյալների բազմություն =), և ոչինչ չի աշխատում, բայց դրա մասին կխոսենք մեկ այլ անգամ:

Ընդհանուր առմամբ, գնացքի ցիկլը նույնպես թույլ է, սկզբում այն ​​չէր պահպանում անցակետերը, օգտագործում էր որոշ սարսափելի ժամանակացույց և այլն: Բայց հիմա դուք միայն պետք է ընտրեք մայրուղին և կատարեք

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

պարամետրերով:

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

Կոնսոլում դուք կտեսնեք.

Initializing model...
     model: RetinaNet
  backbone: ResNet18FPN
   classes: 2, anchors: 9
Selected optimization level O0:  Pure FP32 training.

Defaults for this optimization level are:
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
Processing user overrides (additional kwargs that are not None)...
After processing overrides, optimization options are:
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
Preparing dataset...
    loader: pytorch
    resize: [1024, 1280], max: 1280
    device: 4 gpus
    batch: 4, precision: mixed
Training model for 20000 iterations...
[    1/20000] focal loss: 0.95619, box loss: 0.51584, 4.042s/4-batch (fw: 0.698s, bw: 0.459s), 1.0 im/s, lr: 0.0001
[   12/20000] focal loss: 0.76191, box loss: 0.31794, 0.187s/4-batch (fw: 0.055s, bw: 0.133s), 21.4 im/s, lr: 0.0001
[   24/20000] focal loss: 0.65036, box loss: 0.30269, 0.173s/4-batch (fw: 0.045s, bw: 0.128s), 23.1 im/s, lr: 0.0001
[   36/20000] focal loss: 0.46425, box loss: 0.23141, 0.178s/4-batch (fw: 0.047s, bw: 0.131s), 22.4 im/s, lr: 0.0001
[   48/20000] focal loss: 0.45115, box loss: 0.23505, 0.180s/4-batch (fw: 0.047s, bw: 0.133s), 22.2 im/s, lr: 0.0001
[   59/20000] focal loss: 0.38958, box loss: 0.25373, 0.184s/4-batch (fw: 0.049s, bw: 0.134s), 21.8 im/s, lr: 0.0001
[   71/20000] focal loss: 0.37733, box loss: 0.23988, 0.174s/4-batch (fw: 0.049s, bw: 0.125s), 22.9 im/s, lr: 0.0001
[   83/20000] focal loss: 0.39514, box loss: 0.23878, 0.181s/4-batch (fw: 0.048s, bw: 0.133s), 22.1 im/s, lr: 0.0001
[   94/20000] focal loss: 0.39947, box loss: 0.23817, 0.185s/4-batch (fw: 0.050s, bw: 0.134s), 21.6 im/s, lr: 0.0001
[  105/20000] focal loss: 0.37343, box loss: 0.20238, 0.182s/4-batch (fw: 0.048s, bw: 0.134s), 22.0 im/s, lr: 0.0001
[  116/20000] focal loss: 0.19689, box loss: 0.17371, 0.183s/4-batch (fw: 0.050s, bw: 0.132s), 21.8 im/s, lr: 0.0001
[  128/20000] focal loss: 0.20368, box loss: 0.16538, 0.178s/4-batch (fw: 0.046s, bw: 0.131s), 22.5 im/s, lr: 0.0001
[  140/20000] focal loss: 0.22763, box loss: 0.15772, 0.176s/4-batch (fw: 0.050s, bw: 0.126s), 22.7 im/s, lr: 0.0001
[  148/20000] focal loss: 0.21997, box loss: 0.18400, 0.585s/4-batch (fw: 0.047s, bw: 0.144s), 6.8 im/s, lr: 0.0001
 Average Precision  (AP) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.52674
 Average Precision  (AP) @[ IoU=0.50      | area=   all | maxDets=100 ] = 0.91450
 Average Precision  (AP) @[ IoU=0.75      | area=   all | maxDets=100 ] = 0.35172
 Average Precision  (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.61881
 Average Precision  (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = -1.00000
 Average Precision  (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = -1.00000
 Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=  1 ] = 0.58824
 Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets= 10 ] = 0.61765
 Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.61765
 Average Recall     (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.61765
 Average Recall     (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = -1.00000
 Average Recall     (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = -1.00000
Saving model: 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

Պահոցն արդեն ունի ներկառուցված Focal Loss և մի քանի մայրուղիներ, և հեշտ է նաև ավելացնել ձեր սեփականը։

retinanet/backbones/*.py

Աղյուսակում հեղինակները ներկայացնում են որոշ բնութագրեր.

TensorRT 6.xxx — Բարձր արդյունավետության եզրակացություն խորը ուսուցման մոդելների համար (օբյեկտների հայտնաբերում և հատվածավորում)

Կա նաև Torchvision-ից վերցված ResNeXt50_32x4dFPN մայրուղի և ResNeXt101_32x8dFPN։
Հուսով եմ՝ մենք մի փոքր լուծեցինք հայտնաբերման խնդիրը, բայց անպայման արժե կարդալ պաշտոնական փաստաթղթերը։ հասկանալ արտահանման և գրանցման ռեժիմները.

Քայլ 5. Unet մոդելների արտահանում և եզրակացություն Resnet կոդավորիչով

Ինչպես գուցե նկատել եք, Dockerfile-ը տեղադրել է սեգմենտացիայի համար նախատեսված գրադարաններ, մասնավորապես՝ հրաշալի գրադարանը։ github.com/qubvel/segmentation_models.pytorchUnet փաթեթում կարող եք գտնել pytorch ստուգիչ կետերի եզրակացության և TensorRT շարժիչ արտահանման օրինակներ։

Unet-անման մոդելները ONNX-ից TensoRT արտահանելիս հիմնական խնդիրը Upsample-ի ֆիքսված չափ սահմանելու կամ 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

Այս փոխակերպման միջոցով դուք կարող եք դա անել ավտոմատ կերպով ONNX արտահանելիս, բայց TensorRT-ի 7-րդ տարբերակում այս խնդիրը լուծվեց, և մեզ մնացել է միայն մի փոքր ժամանակ սպասելու։

Ամփոփում

Երբ սկսեցի օգտագործել docker-ը, կասկածներ ունեի դրա արդյունավետության վերաբերյալ իմ առաջադրանքների համար։ Իմ սարքերից մեկը ներկայումս բավականին շատ ցանցային երթևեկություն ունի, որը ստեղծվում է մի քանի տեսախցիկների կողմից։

TensorRT 6.xxx — Բարձր արդյունավետության եզրակացություն խորը ուսուցման մոդելների համար (օբյեկտների հայտնաբերում և հատվածավորում)

Ինտերնետում տարբեր փորձարկումներ ցույց են տվել ցանցային փոխազդեցության և VOLUME-ով ձայնագրման համեմատաբար մեծ ծախսեր, գումարած անհայտ և վախեցնող GIL-ը, և քանի որ կադր նկարահանելը, դրայվերի գործողությունը և կադրի փոխանցումը ցանցով ռեժիմում ատոմային գործողություն են։ դժվար իրական ժամանակ, ցանցի ուշացումները շատ կարևոր են ինձ համար։

Բայց ամեն ինչ լավ ստացվեց =)

Հ.Գ. Մնում է միայն ավելացնել ձեր սիրելի գնացքի օղակը՝ սեգմենտացիայի և արտադրության համար։

Շնորհակալություններ

Շնորհակալություն համայնքին ods.ai, առանց դրա անհնար է զարգանալ։ Շատ շնորհակալ եմ։ n01z3, ով ինձ ոգեշնչեց զբաղվել դիպլոմային ուսմամբ, իր անգնահատելի խորհուրդների և արտակարգ պրոֆեսիոնալիզմի համար։

Օգտագործեք օպտիմիզացված մոդելներ արտադրության մեջ։

TensorRT 6.xxx — Բարձր արդյունավետության եզրակացություն խորը ուսուցման մոդելների համար (օբյեկտների հայտնաբերում և հատվածավորում) Ավրորա, ՍՊԸ

Source: www.habr.com

Գնեք հուսալի հոստինգ DDoS պաշտպանությամբ կայքերի, VPS VDS սերվերների համար 🔥 Գնեք հուսալի կայքերի հոսթինգ՝ DDoS պաշտպանությամբ, VPS VDS սերվերներով | ProHoster