인공지능 모델 최적화 배포 라이브러리 - MMDeploy

프로그래밍 팁 2023. 4. 8. 22:41

 

 연구 단계에서의 인공지능 모델 설계는 일반적인 환경 내에서 개발하고 성능을 분석할 때는 별 문제가 없다가도 막상 실제 특정 환경에서 적용을 시도해보려 하면 모델 구동 시간이 상당히 오래 걸리는 경우가 있습니다. 이는 개발 단계에서 아무리 좋은 GPU를 사용한다 하더라도 해당 GPU에 모델이 최적화 되어있지 않은 경우 GPU의 성능 대비 좋은 성능을 기대하기 어려운 현상이 있습니다.

 개발 단계에서 만들어지는 모델은 다양한 환경에서도 실행될 수 있는 소스코드로 배포되어 어떤 환경에서도 구동될 수 있도록 할 수 있습니다. Nvidia에서 공개한 TensorRT와 같은 모델 최적화 라이브러리를 사용하면 특정 환경의 GPU에서 모델의 Inference 속도가 향상되는 것을 확인할 수 있습니다.

 

 

 그러므로 설계가 완료된 모델을 배포할 때, 모델이 배포되는 환경에서 최적화되어 좋은 성능을 발휘할 수 있도록 관리하는 과정 또한 매우 중요합니다.  OpenMMLab에서 공개한 MMDeploy는 지금까지 OpenMMLab에서 공개한 MMDetection, MMSegmentation등과 같은 딥러닝 라이브러리를 특정 환경에서 최적화 설계되어 배포할 수 있도록 해주는 라이브러리입니다. 

 

 

 MMDeploy를 사용하여 MMCV로 설계된 모델들을 범용 딥러닝 모델인 ONNX로 변환하여 다른 딥러닝 라이브러리로 변환하여 사용하거나 TensorRT를 사용해 자신이 사용하고자 하는 GPU에 모델을 최적화하여 사용할 수도 있습니다.   

 

 MMDeploy는 아래의 Github 사이트를 통해 소스코드를 다운로드 받으실 수 있습니다.  

 

https://github.com/open-mmlab/mmdeploy

 

GitHub - open-mmlab/mmdeploy: OpenMMLab Model Deployment Framework

OpenMMLab Model Deployment Framework. Contribute to open-mmlab/mmdeploy development by creating an account on GitHub.

github.com

 

 Github 공식 사이트를 통해 자신이 구현하고자 하는 환경의 운영체제(Linux, Windows, macOS 등)에서 직접 설치하실 수 있습니다.

 다만, 직접 설치하는 과정이 상당히 복잡하기 때문에 만약 Linux 환경에서 사용하고자 하시는 분은 Docker를 사용하여 설치하시는 것을 적극적으로 권장드립니다. Ubuntu에서 Docker를 설치하는 방법은 아래의 사이트를 참조해주시기 바랍니다.

 

https://dongle94.github.io/docker/docker-ubuntu-install/

 

[Docker] Ubuntu에 Docker 설치하기

리눅스 OS 중 우분투 OS에서 도커(Docker) 프로그램을 설치하는 방법을 알아본다.

dongle94.github.io

 

 Docker 환경에서 GPU 버전의 MMDeploy 설치를 시도하면 아래와 같은 에러가 발생하는 경우가 있습니다.

 

 docker: Error response from daemon: could not select device driver "" with capabilities: [gpu].

 

 이 경우 아래의 블로그에서 소개하는 방법과 같이 nvidia-container-toolkit을 설치해주면 쉽게 해결하실 수 있습니다. 

 

# Add the package repositories
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

 

 

 

https://bluecolorsky.tistory.com/110

 

[정보] docker: Error response from daemon: could not select device driver with capabilities: [[gpu]] 문제 해결하기

도커를 사용하다 보면 다양한 문제에 맞닥뜨리게 된다. 해결하기 쉬운 문제부터 어려운 문제까지 수많은 문제들이 존재하는데 사용할때마다 항상 다른 오류가 발생하여 문제가 발생할때마다

bluecolorsky.tistory.com

 

300x250

MMCV에서 직접 만든 데이터셋 학습 시키기(COCO, Pascal VOC Custom Dataset 만들기)

프로그래밍 팁 2023. 3. 27. 22:58

 

 제가 인공지능에 대해 한창 공부를 할때마다 가장 아쉬웠던 점 중 하나는 자신이 구현하고자 하는 모델에 적합한 데이터를 구하는 것이 어려웠던 것이었습니다. 단지 사람을 감지해내는 기술이 필요한 것이라면 SOTA 알고리즘을 찾은 다음 고성능의 기학습된 모델을 적용하는 것이 가장 좋고 실제로도 제가 다시 재학습 해서 만든 모델보다도 성능이 뛰어나기 때문에 굳이 데이터셋을 직접 만드는 고생을 할 이유가 없기도 합니다.

 

 그러나 내가 구현하고자 하는 물체가 기존의 모델들에 구현되어 있지 않는 경우에는 어쩔수없이 데이터를 수집하여 나만의 데이터셋을 만들어야만합니다. 그러나 기존의 모델들의 성능에 준하는 새로운 모델을 만들기 위해서는 무려 수십만장의 데이터를 수집해야 하는데 이를 개인이 직접 수집하기에는 시간과 비용이 만만치 않습니다. 

 

 그렇다면, 내가 원하는 데이터셋을 만들어 이를 테스트해 볼 수 있는 방법은 없는걸까요? 이번 포스팅에서는 Custom Dataset을 본인이 직접 제작하는 방법과 이 데이터셋을 사용하여 MMCV 기반 딥러닝 모델(MMDetection, MMSegmentation)에서 Custom Dataset을 학습해보고자 합니다.

 

 

1. 데이터 수집 및 Labeling

 원하는 모델 설계에 앞서 자신이 감지하고자 하는 물체가 실제 학습이 가능한지 우선 확인해 볼 필요가 있습니다. 우선 자신이 학습하고자 하는 이미지를 100장 정도 수집한 후 Labeling 작업을 수행합니다. 최근에는 Labeling 작업을 쉽고 효율적으로 수행할 수 있는 Tool들이 많아졌지만 Tutorial 목적으로 작업을 하고자 하시는 분들께서는 추가 비용을 요구하지 않는 오픈소스인 LableMe를 사용해보는 것을 추천 드립니다.

 

 LabelMe를 사용하는 방법에 대해 제가 이전에 정리하였던 자료가 있으니 아래의 포스팅을 참조해주시길 바랍니다.

https://elecs.tistory.com/430

 

Lableme로 Coco Dataset과 VOC Dataset 만들기

고성능의 인공지능을 만들기 위한 가장 중요한 작업 중 하나는 최대한 많은 양질의 데이터를 확보하는 것입니다. 상상을 뛰어넘는 인공지능의 놀라운 발전을 보았을 때 마치 AI를 연구하는 사람

elecs.tistory.com

2. 보편적으로 사용되는 Custom Dataset 양식으로 변환

 

 지금까지 공개된 인공지능 모델들의 대부분은 많은 사람들이 자신들이 개발한 소스코드를 쉽게 사용할 수 있도록 설계되어 있습니다. 특히 기존에 공개된 COCO 데이터셋과 PascalVOC는 대중적으로 공개된 퍼블릭 데이터셋으로 누구가 쉽게 접할 수 있어 인공지능에 입문하는 사람들이 처음으로 사용하게 되는 데이터셋이기도 합니다. 

 

 위에서 언급한 제 이전의 포스팅 자료에서 소개드렸던 LabelMe로 Labeling 작업을 수행한 다음 COCO 혹은 PascalVOC 데이터셋 양식으로 변경하는 내용에 대해 다루었으니 해당 부분을 참조해주시길 바랍니다.

 

3. MMCV에서 사용하기

 

 위의 과정을 통해 Custom 데이터셋을 만드셨다면 이를 가지고 OpenMMLab에서 제작한 MMCV에서 바로 사용하실 수 있습니다. LableMe를 통해 제작한 Custom Dataset으로 MMDetection과 MMSegmentation에서의 동작을 확인하였습니다. 각 프로젝트에 바로 사용할 수 있는 데이터셋 양식은 다음과 같습니다. 나머지 데이터셋 양식의 경우 추가적인 설정을 해주시면 사용하실 수 있습니다.

 

MMDetection: COCO Dataset

 

 LabelMe를 기준으로 Custom Dataset을 Coco 방식으로 변활할 때 Label을 수행한 Json 파일을 Train 용도와 Test 용도로 구분한 다음 각 용도별 Dataset을 Coco로 변환하면 Train 그리고 Test 수행을 위한 Annotation.json 파일을 생성할 수 있습니다. 

 위의 과정을 통해 생성된 Coco Dataset은 MMDetection에서 제공되는 config 파일에 있는 기본 dataset을 수정하여 자신의 환경에 맞도록 고쳐주시면 바로 사용하실 수 있습니다. 

 

/mmdetection/configs/_base_/datasets/coco*.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# dataset settings
dataset_type = 'CocoDataset'
data_root = 'data/coco/' #Custon Coco Dataset의 폴더 위치
....
#Train, Val, Test 데이터의 Json 및 이미지 파일 경로 
data = dict(
    samples_per_gpu=2,
    workers_per_gpu=2,
    train=dict(
        type=dataset_type,
        ann_file=data_root + 'annotations/train.json',
        img_prefix=data_root + 'train/',
        pipeline=train_pipeline),
    val=dict(
        type=dataset_type,
        ann_file=data_root + 'annotations/val.json',
        img_prefix=data_root + 'val/',
        pipeline=test_pipeline),
    test=dict(
        type=dataset_type,
        ann_file=data_root + 'annotations/test.json',
        img_prefix=data_root + 'test/',
        pipeline=test_pipeline))
....
cs

 

MMSegmentation: PascalVOC

 

 LableMe에서 labelme2voc로 변환한 데이터들은 MMSegmentation에서 바로 사용하실 수 있습니다. 여기서 만들어진 Segmentation 이미지들 중에서 train.txt, val.txt, test.txt로 사용하고자 하는 파일들의 제목들을 작성해주시고 아래와 같이 Custom Dataset으로 구성하실 수 있습니다.

 

/mmsegmentation/configs/_base_/datasets/custom_voc12.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# dataset settings
dataset_type = 'PascalVOCDataset'
data_root = 'data/VOCdevkit/VOC2012' # Custom Voc 데이터셋의 폴더 위치
img_norm_cfg = dict(
    mean=[123.675116.28103.53], std=[58.39557.1257.375], to_rgb=True)
crop_size = (512512)
train_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(type='LoadAnnotations'),
    dict(type='Resize', img_scale=(2048512), ratio_range=(0.52.0)),
    dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),
    dict(type='RandomFlip', prob=0.5),
    dict(type='PhotoMetricDistortion'),
    dict(type='Normalize'**img_norm_cfg),
    dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),
    dict(type='DefaultFormatBundle'),
    dict(type='Collect', keys=['img''gt_semantic_seg']),
]
test_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(
        type='MultiScaleFlipAug',
        img_scale=(2048512),
        # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],
        flip=False,
        transforms=[
            dict(type='Resize', keep_ratio=True),
            dict(type='RandomFlip'),
            dict(type='Normalize'**img_norm_cfg),
            dict(type='ImageToTensor', keys=['img']),
            dict(type='Collect', keys=['img']),
        ])
]
data = dict(
    samples_per_gpu=4,
    workers_per_gpu=4,
    train=dict(
        type=dataset_type,
        data_root=data_root,
        img_dir='JPEGImages',
        ann_dir='SegmentationClassPNG',
        split='train.txt',
        pipeline=train_pipeline),
    val=dict(
        type=dataset_type,
        data_root=data_root,
        img_dir='JPEGImages',
        ann_dir='SegmentationClassPNG',
        split='val.txt',
        pipeline=test_pipeline),
    test=dict(
        type=dataset_type,
        data_root=data_root,
        img_dir='JPEGImages',
        ann_dir='SegmentationClassPNG',
        split='test.txt',
        pipeline=test_pipeline))
cs

 

300x250

Lableme로 Coco Dataset과 VOC Dataset 만들기

공대생의 팁 2023. 2. 18. 21:12

 

 고성능의 인공지능을 만들기 위한 가장 중요한 작업 중 하나는 최대한 많은 양질의 데이터를 확보하는 것입니다. 상상을 뛰어넘는 인공지능의 놀라운 발전을 보았을 때 마치 AI를 연구하는 사람들이 고상한 기술을 사용하여 인공지능을 만드는 것처럼 보이지만 안타깝게도 학습 데이터가 확보되지 않은 인공지능은 고성능을 발휘하기 어렵습니다.

 

 그렇다고 해서 데이터만 잔뜩 확보했다고 하여 고성능의 인공지능 기술이 뚝딱 하고 만들어지는 것은 결코 아닙니다. 확보된 데이터를 인공지능이 학습할 수 있도록 전처리 하는 과정이 필요한데 주어진 사진에서 학습하고자 하는 물체의 이름과 위치 등을 표시하여 인공지능이 이를 학습할 수 있도록 만들어주어야 합니다. 흔히 이 전처리 과정을 '레이블링(Labeling)이라고 합니다.

 

사진의 물체 정보 분류(왼쪽), 사진의 물체 위치를 네모상자로 표시(중간), 사진의 물체 위치를 직접 표시(오른쪽)

 

 산업 분야에서 인공지능의 활용 영역이 확대됨에 따라 수집된 데이터의 전처리를 전문으로 하는 기술에 대한 수요가 늘어났고, 이를 처리할 수 있는 성능 좋은 Labeling 기술들이 소개되고 있습니다. 단지 사진을 선택했을 뿐인데 사진 속 특성(Feature)을 추출하고 이에 맞는 Labeling 작업까지 자동으로 해주는 기술이 등장할 만큼 지금 이 순간에도 좋은 도구들이 소개되고 있습니다.

 

 하지만, 인공지능을 시범 도입하기 위해 고가의 Labeling tool을 구매하여 사용하는 것은 상당히 부담스러울 수 밖에 없습니다. 다행히도, 자신의 Field에 인공지능 적용 실용성 여부를 검토할 수 있는 데이터셋 전처리를 가능하게 해주는 무료 도구들이 오픈소스로 공개되어있습니다. 이번 포스팅에서는 지금 이 순간에도 무료로 공개되어 있으며, 누구나 쉽게 어떤 환경에서도 사용할 수 있는 LabelMe를 소개드리도록 하겠습니다.

LabelMe는 pip로 설치하여 바로 사용하실 수 있습니다.

 

$ pip install labelme pyqt5 pyside2

 

혹은 아래의 사이트를 통해 소스코드를 직접 설치하실 수 있습니다.

 

https://github.com/wkentaro/labelme

 

GitHub - wkentaro/labelme: Image Polygonal Annotation with Python (polygon, rectangle, circle, line, point and image-level flag

Image Polygonal Annotation with Python (polygon, rectangle, circle, line, point and image-level flag annotation). - GitHub - wkentaro/labelme: Image Polygonal Annotation with Python (polygon, recta...

github.com

 

 labelme를 실행하면 상당히 직관적인 UI툴을 갖추고 있는 것을 보실 수 있습니다. 

 

 

 레이블링을 수행하고자 하는 이미지를 불러온 다음 마우스 오른쪽 버튼을 클릭하여 'Create Polygons'를 클릭하여 이미지의 객체 주변에 점을 찍어가며 객체를 표시해줍니다.

 

 

 주변에 점을 찍다 한 바퀴 정도 돌게되여 처음 찍은 점으로 돌아오게 되었을 때 1개의 폴리곤이 완성되며 이 때 표시한 객체의 속성을 입력해줍니다.

 

 

 Labeling이 완료되면 위와 같이 작업이 완료된 모습을 확인하실 수 있습니다. 혹시 표시하고자 하는 객체를 네모 모양으로 하고싶으신 분은 'Create Rectangle'을 선택하여 표시할 수 도 있습니다.

 

 

 Object Detection을 수행하는 방법과 같이 Rectangle로 객체를 감싼 다음 Label을 붙여주면 됩니다.

 

 

 지금까지 진행한 작업들을 확인해봅니다. LabelMe로 작업하였던 내용들이 이미지 폴더에 함께 들어있는 것을 확인하실 수 있습니다.

 

 

 

Pascal VOC 방식의 Dataset 만들기

 

  지금부터 LabelMe로 만든 Label 정보들을 인공지능이 학습할 수 있도록 전처리과정을 통해 Dataset을 만드는 과정을 설명드리도록 하겠습니다. 데이터를 학습할 때 보통 COCO 와 Pascal VOC 방식의 Dataset이 주로 사용되고 있습니다. LabelMe 저자는 LabelMe로 Label을 적용한 정보를 COCO 혹은 Pascal VOC로 변환해주는 소스코드를 제공하고 있습니다. 아래 링크를 통해 다운로드 받으실 수 있습니다.

 

https://github.com/wkentaro/labelme/tree/main/examples/instance_segmentation

 

 

1. Pascal VOC로 변환(labelme2voc.py)

 

 먼저 자신이 Label한 클래스의 명단을 labels.txt 파일로 아래와 같이 작성해주세요. 저의 경우 객체가 고양이 단 하나 뿐이므로 classcat 하나입니다.

1
2
3
__ignore__
_background_
cat
cs

 

 다음으로 lableme2voc.py를 실행하여 이미지와 Label정보가 담긴 폴더의 내용으로 VOC 데이터셋을 생성합니다.

 

$ python labelme2voc.py '이미지와Label정보가 담긴 폴더명' 'VOC데이터셋 폴더명' --labels labels.txt

 

해당 명령어를 수행하면 아래와 같이 폴더들이 생성되는 것을 확인하실 수 있습니다.

 

 

 

 SegmentationObjectVisualization 폴더의 내용을 보시면 아래와 같이 Label이 잘 되어있는 것을 확인하실 수  있습니다.

 

 

2. COCO로 변환(labelme2coco.py)

 

 다음으로 Coco Dataset으로 변환하는 방법을 살펴보겠습니다. 위에서 VOC Dataset을 만들때 사용하였던 label.txt에 자신이 만든 Label의 클래스를 적어주신 다음 labelme2coco.py를 사용하여 다음과 같이 실행해줍니다.

 

$ python labelme2voc.py '이미지와Label정보가 담긴 폴더명' 'VOC데이터셋 폴더명' --labels labels.txt

 

 위 명령어를 실행하면 COCO 양식의 데이터셋이 생성된 것을 확인하실 수 있습니다.

 

 

Visualization 폴더 내용을 보면 Label이 적용된 것을 확인하실 수 있습니다.

 

 

 

300x250