Skip to content

필사 모드: 비전 모델 개발·파인튜닝 완전 가이드 2026 — CNN, ViT, DETR, SAM 2, VLM 까지 실전 의사결정 트리

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

프롤로그 — 2026년의 비전 엔지니어가 마주하는 진짜 질문

2026년 5월 어느 월요일, 비전팀 리드가 받은 티켓 한 줄:

> "공장 라인 카메라 영상에서 불량 부품을 표시해 주세요. 클래스는 12개, 하루 30만 장 처리, 정확도 95% 이상, 엣지 디바이스(Jetson Orin Nano)에서 30fps."

같은 요구사항을 2018년에 받았다면 답은 명확했다 — ResNet50 백본에 RetinaNet 헤드, COCO 사전학습 후 자체 데이터로 파인튜닝. 끝.

2026년에는 답이 8개쯤 된다.

1. YOLOv11/12 로 그냥 파인튜닝

2. RT-DETR 로 트랜스포머 기반 탐지

3. SAM 2 로 마스크를 뽑고 분류기를 얹는다

4. Florence-2 같은 비전 파운데이션 모델에 프롬프트만 던진다

5. Gemini 2.5 Vision 이나 Claude Vision 에 사진을 보내서 자연어로 결과를 받는다

6. CLIP 으로 임베딩만 뽑고 kNN 으로 분류한다

7. OWLv2/Grounding DINO 로 텍스트 프롬프트 기반 zero-shot 탐지

8. 위 중 두세 개를 파이프라인으로 결합한다

이 글은 그 8개의 선택지를 **언제, 왜, 어떻게** 골라야 하는지에 대한 가이드다. 단순히 "최신 모델이 좋다"가 아니라, **데이터 규모·정확도 요구·지연 예산·운영 비용** 네 축으로 의사결정 트리를 만든다.

> **2026년 비전 엔지니어의 핵심 스킬은 더 이상 "모델 학습"이 아니다. "어떤 모델을 학습할지, 학습할 필요가 있긴 한지를 결정하는 것"이다.**

1장 · 아키텍처 가족 — CNN 부터 VLM 까지 한눈에

비전 모델은 결국 "이미지 → 무언가"인데, 그 "무언가"가 무엇인지에 따라 아키텍처 가족이 갈린다.

| 가족 | 대표 모델 | 출현 시점 | 입력 처리 | 강점 | 약점 |

| --- | --- | --- | --- | --- | --- |

| CNN | ResNet, EfficientNet, ConvNeXt v2 | 2012~ | 합성곱 + 풀링 | 적은 데이터, 빠름 | 글로벌 컨텍스트 약함 |

| ViT | ViT, DeiT, Swin v2, EVA-02 | 2020~ | 패치 + Self-Attention | 데이터 많을 때 최강 | 데이터 적으면 약함 |

| DETR 계열 | DETR, Deformable DETR, RT-DETR | 2020~ | 인코더-디코더 + 쿼리 | NMS 없는 탐지 | 학습 수렴 느림 |

| SAM 계열 | SAM, SAM 2, HQ-SAM | 2023~ | ViT 백본 + 마스크 디코더 | 프롬프트 가능한 세그멘테이션 | 의미적 분류 못 함 |

| VLM | LLaVA-1.6, Qwen2.5-VL, Gemini Vision, Claude Vision, GPT-4V | 2023~ | 이미지 인코더 + LLM | 자연어로 추론, OCR, VQA | 비싸고 느림, 정확도 비결정적 |

| 멀티모달 파운데이션 | Florence-2, InternVL3, DINOv2 | 2023~ | 통합 ViT, multi-task head | zero-shot · few-shot | 파인튜닝 노하우 필요 |

이 표는 외워야 한다. 다음 8장에 걸쳐 이 표의 각 행을 풀어쓴다.

> **핵심 원리:** 모든 비전 모델은 결국 *"이미지를 토큰의 시퀀스로 본다"* — CNN은 그것을 공간 격자로, ViT는 패치 시퀀스로, SAM은 프롬프트와 함께, VLM은 LLM의 입력 토큰으로. **표현(representation)이 모델을 정의한다.**

2장 · CNN 은 죽지 않았다 — 2026년의 위치

ViT가 모든 걸 다 잡아먹었다는 마케팅과 달리, **2026년에도 CNN은 살아있다.** 특히 다음 상황에서.

CNN을 골라야 할 때

1. **데이터가 적다** — 라벨 1만 장 이하. ViT는 사전학습 없이는 거의 학습이 안 된다.

2. **엣지에서 돌려야 한다** — Jetson, Coral, 휴대폰. ConvNeXt-Tiny가 ViT-Tiny보다 같은 FLOPs에서 빠르다.

3. **지연이 진짜 빡빡하다** — 1ms 이하. 작은 CNN은 GPU에서 0.5ms도 가능하다.

4. **해상도가 매우 높다** — 4K 의료 영상. ViT는 패치 수가 폭발한다.

timm 으로 모델 한 줄 로드

PyTorch Image Models(`timm`)는 2026년에도 비전 백본의 사실상 표준이다. 1000개 이상의 사전학습 백본을 한 줄로 부른다.

ConvNeXt v2 large, ImageNet-22k 사전학습, 22k-1k 파인튜닝

model = timm.create_model(

'convnextv2_large.fcmae_ft_in22k_in1k_384',

pretrained=True,

num_classes=12, # 우리 태스크의 클래스 수

)

입력 변환은 모델이 알려준다

data_config = timm.data.resolve_model_data_config(model)

transform = timm.data.create_transform(**data_config, is_training=True)

배치 차원을 포함한 텐서 모양은 `B x C x H x W`

x = torch.randn(2, 3, 384, 384)

logits = model(x) # shape: 2 x 12

`timm.list_models('convnext*', pretrained=True)` 로 후보를 본다. `pretrained_cfg` 안에 `mean`, `std`, `input_size`, `crop_pct` 가 들어있어서 변환을 통일하기 쉽다.

CNN 학습 레시피 — 작은 데이터에서 잘 되는 법

- **사전학습 → 헤드만 학습 → 전체 파인튜닝** 의 3단계

- **Mixup, CutMix, RandAugment** — 라벨 1만 장 이하면 거의 필수

- **EMA(Exponential Moving Average)** — 검증 정확도 1~2%p 공짜로 얻는다

- **Cosine schedule + 짧은 warmup** — `OneCycleLR` 도 좋다

- **AdamW + weight decay 0.05** — 옛날의 SGD는 잊자

3장 · ViT — 데이터가 충분할 때의 챔피언

ViT(Vision Transformer)는 이미지를 16x16 같은 패치로 잘라 시퀀스로 만들고, 그 위에 Transformer를 얹는다. 핵심 통찰은 *"이미지에 inductive bias가 적은 모델이 데이터만 충분하면 CNN을 이긴다"* 였다.

2026년의 ViT 변종

- **Swin Transformer v2** — 윈도우 어텐션, 고해상도 입력 효율적

- **DeiT III** — 데이터 효율적 학습 레시피

- **EVA-02** — Masked Image Modeling, 22B 파라미터까지 스케일

- **DINOv2** — 자기지도학습, 라벨 없이 학습된 강력한 백본

- **SigLIP / SigLIP 2** — 대조학습 기반, 강력한 이미지-텍스트 임베딩

ViT를 골라야 할 때

| 조건 | 추천 |

| --- | --- |

| 라벨 데이터 10만 장 이상 | ViT 또는 Swin |

| 라벨이 적지만 이미지가 100만 장 이상 (자기지도학습 가능) | DINOv2 사전학습 → 헤드만 파인튜닝 |

| OCR · 텍스트가 많은 이미지 | SigLIP 2 또는 ViT-L 패치 14 |

| 다국어 OCR · 표 인식 | InternVL3 의 ViT 백본 |

Hugging Face transformers 로 ViT 분류기 한 줄

from transformers import AutoImageProcessor, AutoModelForImageClassification

from PIL import Image

processor = AutoImageProcessor.from_pretrained('facebook/dinov2-large')

model = AutoModelForImageClassification.from_pretrained(

'facebook/dinov2-large',

num_labels=12,

ignore_mismatched_sizes=True, # 헤드만 새로

)

img = Image.open('part.jpg').convert('RGB')

inputs = processor(images=img, return_tensors='pt')

with torch.no_grad():

outputs = model(**inputs)

pred = outputs.logits.argmax(-1).item()

`facebook/dinov2-large` 대신 `microsoft/swinv2-large-patch4-window12-192-22k` 같은 백본도 동일 API다.

4장 · 객체 탐지 — YOLO vs DETR vs RT-DETR

탐지는 "어디에 무엇이"를 동시에 푸는 태스크다. 2026년 시점에서 실무는 크게 둘로 갈린다.

YOLO 가족 — 압도적 실전 점유율

Ultralytics 의 YOLOv8 부터 YOLOv12 까지, 그리고 YOLO-NAS, YOLOv9, YOLOv10 같은 변종들. **속도와 배포 편의성**에서는 여전히 YOLO가 1등이다.

from ultralytics import YOLO

사전학습 모델 로드

model = YOLO('yolo11x.pt')

자체 데이터셋으로 파인튜닝

results = model.train(

data='factory_parts.yaml', # train/val 경로 + 클래스 이름

epochs=100,

imgsz=640,

batch=32,

device=0,

optimizer='AdamW',

lr0=0.001,

cos_lr=True,

patience=20, # early stopping

project='runs/factory',

)

ONNX 로 내보내기 (엣지 배포)

model.export(format='onnx', dynamic=True, simplify=True)

TensorRT 로 내보내기 (Jetson)

model.export(format='engine', half=True)

`factory_parts.yaml` 은 다음 형태다.

path: /data/factory

train: images/train

val: images/val

names:

0: scratch

1: dent

2: discoloration

3: missing_screw

YOLO의 단점: **NMS 기반**이라 빽빽한 객체 · 작은 객체에 약하고, **DETR 류에 비해 글로벌 컨텍스트가 약하다**.

DETR 가족 — NMS 없는 트랜스포머 탐지

DETR(DEtection TRansformer)는 객체 쿼리와 헝가리안 매칭으로 NMS를 제거했다. 2026년에는 **RT-DETR** 이 실용적 선택이다.

from transformers import RTDetrV2ForObjectDetection, RTDetrImageProcessor

processor = RTDetrImageProcessor.from_pretrained('PekingU/rtdetr_v2_r50vd')

model = RTDetrV2ForObjectDetection.from_pretrained(

'PekingU/rtdetr_v2_r50vd',

num_labels=12,

ignore_mismatched_sizes=True,

)

YOLO vs DETR — 의사결정

| 상황 | 추천 |

| --- | --- |

| 30fps 이상 엣지 추론 | YOLO |

| COCO 평균 ish 객체 밀도 | YOLO |

| 빽빽한 작은 객체 (위성, 의료) | RT-DETR 또는 Co-DETR |

| 텍스트 프롬프트로 unseen 클래스 탐지 | Grounding DINO / OWLv2 |

| 비디오 추적까지 필요 | YOLO + ByteTrack 또는 SAM 2 |

OpenMMLab 은 언제 쓰나

`mmdetection`, `mmsegmentation` 등 OpenMMLab 생태계는 **연구·실험에 강점**이다. 같은 코드베이스에서 50+ 탐지 모델을 비교하고, 설정 파일 한 줄로 백본을 교체한다. 다만 **학습 곡선이 가파르고 배포는 별도 도구**가 필요하다. 프로덕션 첫 모델로는 Ultralytics 가 훨씬 빠르다.

5장 · 세그멘테이션과 SAM 2

세그멘테이션은 "픽셀 단위로 어디"다. 2026년에는 **SAM 2** 가 거의 모든 경우의 출발점이다.

SAM 2 — 이미지와 비디오를 모두 다루는 promptable segmentation

Meta 가 2024년 7월 공개한 SAM 2 는 *"클릭·박스·마스크 프롬프트만 주면 어떤 객체든 세그먼트하고, 비디오 프레임 간에 자동 추적"* 하는 모델이다. 핵심은:

- **이미지 + 비디오 통합** — 같은 모델로 둘 다

- **메모리 어텐션** — 비디오에서 객체를 추적하기 위해 과거 프레임의 표현을 기억

- **promptable** — 마스크가 아니라 클릭/박스 같은 사용자 입력으로 분할

from sam2.build_sam import build_sam2

from sam2.sam2_image_predictor import SAM2ImagePredictor

from PIL import Image

sam2 = build_sam2('configs/sam2.1/sam2.1_hiera_l.yaml', 'sam2.1_hiera_large.pt')

predictor = SAM2ImagePredictor(sam2)

img = np.array(Image.open('part.jpg'))

predictor.set_image(img)

클릭 한 번으로 마스크

point_coords = np.array([[450, 320]])

point_labels = np.array([1]) # 1 = foreground

masks, scores, _ = predictor.predict(

point_coords=point_coords,

point_labels=point_labels,

multimask_output=True,

)

SAM 2 의 진짜 활용법 — "분할은 SAM, 분류는 별도"

SAM 2 는 **무엇인지** 알려주지 않는다. *"이 마스크는 객체 1, 저 마스크는 객체 2"* 라고만 한다. 의미적 라벨이 필요하면 두 단계 파이프라인이다.

1. SAM 2 로 마스크 생성

2. 각 마스크 영역을 잘라서 CLIP 또는 SigLIP 으로 분류

이게 **2026년의 "zero-shot 세그멘테이션" 표준 레시피**다. 라벨 데이터 없이도 동작한다.

HQ-SAM, MobileSAM, EfficientSAM 의 자리

- **HQ-SAM** — 더 정밀한 경계, 의료 · 위성 영상

- **MobileSAM / EfficientSAM** — 엣지 디바이스용 경량

- **SAM 2.1** — 비디오 추적 정밀도 강화 버전

6장 · VLM — 자연어로 이미지를 다루는 시대

Vision-Language Model 은 *"이미지를 LLM 의 입력 토큰으로 변환"* 한다. 사용자는 자연어로 질문하고, 모델은 자연어로 답한다.

2026년의 주요 VLM

| 모델 | 강점 | 약점 |

| --- | --- | --- |

| **Claude Sonnet/Opus Vision** | 차트 · 다이어그램 · 문서 OCR · 추론 | API only, 가격 |

| **Gemini 2.5 Pro Vision** | 긴 비디오, 멀티 이미지, 다국어 OCR | API only |

| **GPT-5 Vision** | 일반 추론, 코드와 결합 | API only |

| **Qwen2.5-VL 72B / 7B** | 오픈웨이트, GUI 이해, 비디오 | 자체 호스팅 필요 |

| **LLaVA-OneVision / LLaVA-1.6** | 학습 레시피 공개, 연구 친화 | 최신 모델 대비 약함 |

| **InternVL3 78B / 8B** | 멀티이미지, 문서, 오픈웨이트 강자 | VRAM 요구 큼 |

| **Molmo** | 포인팅 능력, 데이터 투명 | 정확도 평균 |

| **Pixtral 12B** | Mistral 의 오픈 VLM | OCR 약점 |

VLM 을 "프롬프트만 잘 짜서" 쓸 때

라벨 데이터가 거의 없거나, 클래스가 자주 바뀌거나, "왜 그렇게 판단했는가" 설명이 필요한 경우 — VLM 에 사진과 시스템 프롬프트만 던지는 게 ROI가 가장 높다.

client = anthropic.Anthropic()

with open('part.jpg', 'rb') as f:

img_b64 = base64.standard_b64encode(f.read()).decode()

resp = client.messages.create(

model='claude-opus-4-7',

max_tokens=512,

system=(

'당신은 자동차 부품 검사관이다. 사진을 보고 다음 JSON 으로만 답하라. '

'schema: {"defect": one of [scratch, dent, discoloration, missing_screw, none], '

'"severity": one of [low, medium, high], "reasoning": short string}'

),

messages=[{

'role': 'user',

'content': [

{'type': 'image', 'source': {'type': 'base64', 'media_type': 'image/jpeg', 'data': img_b64}},

{'type': 'text', 'text': '이 부품을 검사하라.'},

],

}],

)

print(resp.content[0].text)

VLM 의 한계 — 무조건 좋지 않다

- **비용** — 사진 한 장에 0.01~0.05달러. 하루 30만 장이면 월 9만~45만 달러. 자체 모델 학습 비용과 비교해 보자.

- **지연** — 200ms~2s. 30fps 엣지에서 못 쓴다.

- **비결정성** — 같은 사진에 다른 답이 가끔 나온다. 임계값 기반 의사결정에는 보정 필요.

- **JSON 안 지키기** — `response_format` 또는 도구 호출(tool use) 로 강제해야 한다.

- **데이터 거버넌스** — 사진을 외부 API로 보낼 수 있는가? 법무팀과 먼저 이야기하자.

7장 · 어떤 태스크 → 어떤 아키텍처 매트릭스

위 6장을 한 표로 압축한다. 첫 모델을 고를 때 이 표만 봐도 80%는 맞다.

| 태스크 | 데이터 1k 이하 | 데이터 10k~100k | 데이터 100k 이상 | 라벨 거의 없음 |

| --- | --- | --- | --- | --- |

| 이미지 분류 | CLIP zero-shot 또는 ConvNeXt-T 파인튜닝 | ConvNeXt-Base, ViT-B | EVA-02, DINOv2-L 사전학습 후 헤드 | CLIP/SigLIP zero-shot |

| 객체 탐지 | YOLO11n + 강한 증강 | YOLO11x 또는 RT-DETR | DETR 변종 + 자체 백본 사전학습 | Grounding DINO, OWLv2 |

| 세그멘테이션 | SAM 2 + CLIP 라벨 | SAM 2 파인튜닝 또는 Mask2Former | Mask2Former + Swin v2 | SAM 2 zero-shot |

| OCR | TrOCR 파인튜닝 | TrOCR 또는 PaddleOCR | 자체 학습 + 데이터 합성 | Claude/Gemini Vision |

| 캡셔닝 | BLIP-2 프롬프트 | BLIP-2 또는 LLaVA 파인튜닝 | InternVL3 파인튜닝 | VLM 직접 호출 |

| 시각 QA | VLM API 직접 호출 | LLaVA-OneVision LoRA | Qwen2.5-VL 72B 파인튜닝 | VLM API 직접 호출 |

| 변칙 탐지 | PatchCore, PaDiM | EfficientAD | 자체 학습 + 합성 결함 | DINOv2 임베딩 + kNN |

규칙 한 줄: **데이터가 적으면 사전학습된 거대 백본 + 작은 헤드. 데이터가 많으면 자체 학습. 라벨이 없으면 VLM 또는 임베딩.**

8장 · 데이터 — 얼마나, 어떻게, 어디서

"모델보다 데이터가 더 중요하다"는 클리셰는 2026년에도 사실이다.

필요한 데이터 양 (대략)

| 태스크 | 클래스당 최소 | 권장 | 충분 |

| --- | --- | --- | --- |

| 분류 (강한 사전학습 사용) | 50 | 500 | 5,000 |

| 객체 탐지 | 200 박스 | 2,000 박스 | 20,000 박스 |

| 세그멘테이션 (SAM 2 사용 시 줄어듦) | 50 마스크 | 500 마스크 | 5,000 마스크 |

| OCR (라인 단위) | 1,000 라인 | 10,000 라인 | 100,000 라인 |

| VLM 파인튜닝 (LoRA) | 200 예시 | 2,000 예시 | 20,000 예시 |

공개 데이터셋 — 2026년에도 살아있는 것들

- **ImageNet-22k / -1k** — 분류 사전학습의 변하지 않는 기준

- **COCO 2017** — 탐지 · 키포인트 · 캡션, 여전히 벤치마크 표준

- **Open Images V7** — 9M+ 이미지, 약한 라벨 포함

- **LAION-5B / DataComp** — CLIP 류 학습용 대규모 이미지-텍스트 쌍 (저작권 검토 필수)

- **LVIS** — 1200+ 클래스, long-tail 탐지

- **ADE20K, Cityscapes, Mapillary** — 세그멘테이션

- **DocVQA, ChartQA, InfographicVQA** — 문서/차트 VQA

- **OpenX-Embodiment, Ego4D** — 로봇·1인칭 비디오

- **SA-1B** — SAM 학습 데이터, 1.1B 마스크

라벨링 도구 — 2026년 실용 비교

| 도구 | 강점 | 약점 | 가격 |

| --- | --- | --- | --- |

| **Label Studio** | 오픈소스, 모든 태스크 | UI 무거움 | 무료 / Enterprise 유료 |

| **CVAT** | 비디오 탐지·세그 최강, 오픈소스 | 호스팅 부담 | 무료 / Cloud 유료 |

| **Roboflow** | 빠른 시작, 자동 라벨링, SAM 통합 | 클라우드 의존 | 프리/팀/엔터프라이즈 |

| **V7 Darwin** | 의료·복잡한 워크플로 | 가격 | 유료 |

| **Encord** | 비디오·LLM/VLM 평가 | 가격 | 유료 |

| **Scale AI / Surge AI** | 휴먼 어노테이션 외주 | 단가 | 시간당 또는 라벨당 |

> **2026년의 라벨링 비밀:** 1차로 SAM 2 + Grounding DINO 로 자동 라벨링 → Roboflow/CVAT 에서 사람이 교정. 라벨링 시간이 5~10배 줄어든다.

9장 · 학습 vs 파인튜닝 vs 프롬프팅 — 비용 모델

| 전략 | 데이터 요구 | 학습 비용 | 추론 비용 | 변경 비용 | 정확도 상한 |

| --- | --- | --- | --- | --- | --- |

| 처음부터 학습 | 100M+ 이미지 | $100k+ | 가장 낮음 | 매우 큼 | 매우 높음 |

| 파인튜닝(전체) | 10k~1M | $100~$10k | 낮음 | 작음 | 높음 |

| 파인튜닝(LoRA/QLoRA) | 200~50k | $10~$1k | 낮음 | 매우 작음 | 중간~높음 |

| 프롬프팅(VLM) | 0~수십 예시 | $0 | 가장 높음 | 0 | 모델 한계만큼 |

| 임베딩 + kNN | 50~5k | $0~$100 | 낮음 | 작음 | 중간 |

규칙: **데이터가 늘수록 학습 비용이 합리화된다. 추론 트래픽이 늘수록 자체 모델이 합리화된다.** 두 축을 같이 봐야 한다.

LoRA / QLoRA — VLM 파인튜닝의 실전 표준

VLM 전체를 풀파인튜닝하는 건 80GB VRAM x 4장 시대도 빡빡하다. LoRA 가 답이다.

from transformers import AutoModelForVision2Seq, AutoProcessor

from peft import LoraConfig, get_peft_model

from trl import SFTTrainer, SFTConfig

model_id = 'Qwen/Qwen2.5-VL-7B-Instruct'

processor = AutoProcessor.from_pretrained(model_id)

model = AutoModelForVision2Seq.from_pretrained(

model_id,

torch_dtype=torch.bfloat16,

device_map='auto',

)

lora_cfg = LoraConfig(

r=16,

lora_alpha=32,

target_modules=['q_proj', 'k_proj', 'v_proj', 'o_proj'],

lora_dropout=0.05,

bias='none',

task_type='CAUSAL_LM',

)

model = get_peft_model(model, lora_cfg)

model.print_trainable_parameters() # 보통 0.1~1% 만 학습

cfg = SFTConfig(

output_dir='runs/qwen-vl-defect',

num_train_epochs=3,

per_device_train_batch_size=2,

gradient_accumulation_steps=8,

learning_rate=1e-4,

lr_scheduler_type='cosine',

warmup_ratio=0.03,

bf16=True,

gradient_checkpointing=True,

logging_steps=20,

save_strategy='epoch',

)

train_dataset 은 {"image": PIL.Image, "messages": [...]} 의 시퀀스

trainer = SFTTrainer(model=model, args=cfg, train_dataset=train_ds, processing_class=processor)

trainer.train()

QLoRA(4bit 양자화 + LoRA)면 24GB VRAM 한 장으로 7B VLM 파인튜닝이 가능하다. 70B 급은 80GB 한 장.

10장 · 배포 — ONNX, TensorRT, Core ML, TFLite

학습은 끝의 시작이다. 배포 단계에서 잘못된 선택을 하면 **추론 비용이 10배** 든다.

배포 타깃별 추천

| 타깃 | 추천 포맷 | 비고 |

| --- | --- | --- |

| **NVIDIA GPU 서버** | TensorRT, 또는 ONNX + TensorRT EP | FP16/INT8 양자화, dynamic batch |

| **CPU 서버** | ONNX Runtime, OpenVINO | INT8 양자화 필수, AVX-512 활용 |

| **Jetson (엣지 GPU)** | TensorRT | 모델별 엔진 빌드, JetPack 버전 매칭 |

| **iOS** | Core ML | `coremltools` 로 변환, ANE 활용 |

| **Android** | TFLite, LiteRT, ONNX Runtime Mobile | NNAPI 또는 GPU delegate |

| **웹 브라우저** | ONNX Runtime Web, WebGPU | 모델 크기 1~50MB |

| **로컬 데스크톱 LLM/VLM** | llama.cpp (GGUF), Ollama, MLX | Apple Silicon 강력 |

PyTorch → ONNX → TensorRT 흐름

from ultralytics import YOLO

model = YOLO('runs/factory/best.pt')

1) ONNX

model.export(format='onnx', dynamic=True, simplify=True, opset=17)

2) TensorRT (NVIDIA GPU) — Ultralytics가 직접 지원

model.export(format='engine', half=True, workspace=4)

수동으로 한다면 `trtexec --onnx=model.onnx --saveEngine=model.engine --fp16` 가 가장 간단하다. INT8 양자화는 calibration dataset 이 필요하다.

Core ML / TFLite — 모바일

Core ML

mlmodel = ct.convert(traced_model, inputs=[ct.ImageType(shape=(1, 3, 224, 224))])

mlmodel.save('Model.mlpackage')

TFLite (PyTorch → TF는 ai-edge-torch 권장)

edge_model = ai_edge_torch.convert(model.eval(), sample_inputs)

edge_model.export('model.tflite')

11장 · 실패 모드 — 현장에서 마주치는 진짜 문제들

| 증상 | 원인 | 대처 |

| --- | --- | --- |

| 검증 정확도 99%, 프로덕션 70% | 분포 이동(domain shift) | 프로덕션 샘플로 추가 학습 또는 도메인 적응 |

| 클래스 한 개만 잘 맞춤 | 클래스 불균형 | focal loss, class-balanced sampler, oversampling |

| 추론 메모리 폭주 | dynamic shape, batch 1 만 학습 | dynamic axes export, max-batch 고정 |

| 같은 사진에 다른 결과 | nondeterminism, half-precision | seed 고정, FP32 검증, `torch.backends.cudnn.deterministic` |

| 작은 객체 못 잡음 | 입력 해상도 낮음, anchor 미스매치 | 입력 해상도 증가, slice-and-merge (SAHI) |

| VLM이 JSON 안 지킴 | 프롬프트 약함 | 도구 호출(tool use) 강제, 또는 `response_format=json_schema` |

| 라벨 노이즈 | 어노테이션 품질 낮음 | 라벨러 간 합의(IAA) 측정, confident learning |

| 학습 후 일반화 실패 | 데이터 누수, 검증셋이 학습셋과 겹침 | hash 기반 분할, 시간 기준 분할 |

| GPU 활용률 30% | 데이터 로더 병목 | num workers 늘리기, persistent workers, NVIDIA DALI |

| 학습이 발산 | learning rate 너무 큼, gradient explosion | warmup 늘리기, grad clip, mixed precision 끄고 디버그 |

> **현장 격언:** "정확도가 안 나오면 모델을 바꾸지 말고 데이터를 다시 봐라. 다섯 번 중 네 번은 데이터가 문제다."

12장 · 의사결정 트리 — 30초 안에 결정하기

새 비전 문제를 받으면 이 순서로 던진다.

1. **"이 문제, VLM 한 줄로 풀려?"** — Claude/Gemini Vision 에 사진 10장을 손으로 던져 보자. 90% 정확도가 나오면, 그게 베이스라인이다.

2. **"라벨 데이터가 있는가?"** — 없으면 VLM 또는 zero-shot(CLIP, Grounding DINO, SAM 2).

3. **"라벨이 1만 장 이상인가?"** — Yes → 자체 학습. No → 사전학습 + 파인튜닝.

4. **"엣지에서 돌아야 하는가?"** — Yes → CNN 또는 작은 YOLO. No → ViT 자유.

5. **"30fps 이상 필요한가?"** — Yes → YOLO + TensorRT/Core ML. No → DETR 류도 OK.

6. **"왜 그렇게 판단했는지 설명이 필요한가?"** — Yes → VLM 또는 attention 시각화. No → 일반 모델.

7. **"오류 비용이 큰가?"** (의료·자율주행) — Yes → 앙상블, 캘리브레이션, human-in-the-loop.

이 7가지 질문이면 첫 모델 선택의 80%는 끝난다.

에필로그 — 체크리스트, 안티패턴, 다음 글 예고

첫 비전 모델을 만들기 전 체크리스트

- 데이터 라벨 분포를 봤는가? (클래스 불균형은 학습 시작 전에 알아야 한다)

- 검증셋이 학습셋과 시간/소스가 겹치지 않는가?

- 베이스라인이 있는가? (가장 단순한 모델, 또는 사람의 정확도, 또는 무조건 다수 클래스)

- VLM 한 줄 호출의 정확도와 비용을 측정해 봤는가?

- 학습 비용과 추론 비용을 같이 비교했는가?

- 배포 타깃의 메모리·지연 제약을 알고 있는가?

- 라벨러 간 합의(IAA)를 측정했는가?

- 결함 케이스(corner case) 100장으로 별도 검증셋을 만들었는가?

- 모니터링 — 프로덕션 분포 이동을 어떻게 감지할 건가?

- 롤백 — 모델이 망가졌을 때 이전 버전으로 돌아갈 수 있는가?

자주 보는 안티패턴

- **"최신 SOTA 가 뭐죠?"로 시작하기** — 데이터부터 보자.

- **사전학습 없이 ViT 부터 시작** — 1만 장 이하면 거의 실패한다.

- **검증셋을 학습 중 여러 번 보면서 튜닝** — 사실상 학습셋. 별도 테스트셋이 필요하다.

- **mAP 만 보고 배포** — 클래스별 PR 곡선, 작은 객체 metric, 추론 지연도 같이.

- **VLM 결과를 후처리 없이 신뢰** — JSON 스키마 검증, fallback, 캐싱.

- **단일 모델로 모든 클래스를 잡으려는 욕심** — 자주 출현 클래스 + long-tail 분리.

- **데이터 증강을 모델보다 늦게 신경** — 증강이 모델보다 정확도에 더 큰 영향을 주는 경우가 많다.

- **학습 코드와 평가 코드의 transform 불일치** — 가장 흔한 디버그 시간 소모 원인 1번.

다음 글 예고

- *"비전 모델 운영 — 분포 이동 감지, A/B, 카나리아, active learning loop 까지"*

- *"VLM 으로 라벨링 자동화하기 — Claude/Gemini/Qwen-VL 로 어노테이션 90% 자동화 파이프라인"*

- *"엣지 비전 추론 — Jetson, Coral, iPhone, Android 에서 같은 모델 돌리기"*

참고 / References

아키텍처 페이퍼

- ViT — *"An Image is Worth 16x16 Words"* — https://arxiv.org/abs/2010.11929

- Swin Transformer v2 — https://arxiv.org/abs/2111.09883

- ConvNeXt v2 — https://arxiv.org/abs/2301.00808

- DINOv2 — https://arxiv.org/abs/2304.07193

- DETR — *"End-to-End Object Detection with Transformers"* — https://arxiv.org/abs/2005.12872

- RT-DETR — https://arxiv.org/abs/2304.08069

- SAM — https://arxiv.org/abs/2304.02643

- SAM 2 — https://arxiv.org/abs/2408.00714

- LLaVA — https://arxiv.org/abs/2304.08485

- Qwen2.5-VL — https://arxiv.org/abs/2502.13923

- InternVL — https://arxiv.org/abs/2312.14238

- Grounding DINO — https://arxiv.org/abs/2303.05499

- Florence-2 — https://arxiv.org/abs/2311.06242

- LoRA — https://arxiv.org/abs/2106.09685

- QLoRA — https://arxiv.org/abs/2305.14314

도구 / 라이브러리

- timm (PyTorch Image Models) — https://github.com/huggingface/pytorch-image-models

- Hugging Face transformers — https://huggingface.co/docs/transformers

- Ultralytics YOLO — https://docs.ultralytics.com/

- OpenMMLab MMDetection — https://github.com/open-mmlab/mmdetection

- Segment Anything 2 — https://github.com/facebookresearch/sam2

- PEFT (LoRA/QLoRA) — https://github.com/huggingface/peft

- TRL (SFT) — https://github.com/huggingface/trl

라벨링 도구

- Label Studio — https://labelstud.io/

- CVAT — https://www.cvat.ai/

- Roboflow — https://roboflow.com/

- V7 Darwin — https://www.v7labs.com/

- Encord — https://encord.com/

데이터셋

- ImageNet — https://www.image-net.org/

- COCO — https://cocodataset.org/

- Open Images V7 — https://storage.googleapis.com/openimages/web/index.html

- LAION — https://laion.ai/

- LVIS — https://www.lvisdataset.org/

- ADE20K — https://groups.csail.mit.edu/vision/datasets/ADE20K/

- SA-1B — https://ai.meta.com/datasets/segment-anything/

배포 / 추론

- ONNX Runtime — https://onnxruntime.ai/

- NVIDIA TensorRT — https://developer.nvidia.com/tensorrt

- Apple Core ML Tools — https://github.com/apple/coremltools

- ai-edge-torch (PyTorch → TFLite) — https://github.com/google-ai-edge/ai-edge-torch

- OpenVINO — https://docs.openvino.ai/

VLM API

- Anthropic Claude Vision — https://docs.anthropic.com/en/docs/build-with-claude/vision

- Google Gemini Vision — https://ai.google.dev/gemini-api/docs/vision

- OpenAI Vision — https://platform.openai.com/docs/guides/vision

현재 단락 (1/360)

2026년 5월 어느 월요일, 비전팀 리드가 받은 티켓 한 줄:

작성 글자: 0원문 글자: 15,725작성 단락: 0/360