요즘 테크 뉴스나 소셜 미디어를 보면 온통 생성형 AI, 거대 언어 모델(LLM), 비전 인공지능에 대한 이야기로 도배가 되어 있습니다. 대기업이나 잘 나가는 대형 스타트업이 아니면 감히 엄두도 내지 못할 거대한 성벽처럼 느껴지기도 합니다. 수천만 장의 데이터를 모아야 할 것 같고, 수억 원에 달하는 서버 인프라를 구축해야만 비로소 '인공지능 서비스'라는 명함을 내밀 수 있을 것 같은 압박감이 들곤 하죠. 저 역시 직접 부딪쳐 보기 전까지는 인공지능을 우리 서비스에 도입한다는 게 아득한 먼 나라 이야기처럼 보였습니다.
그런데 결론부터 말씀드리면, 막상 소매를 걷어붙이고 컴퓨터 앞에 앉아 하나씩 실행해 보니 인공지능 모델을 학습시키고 활용하는 파이프라인이 생각보다 너무나도 직관적이고 단순했습니다. 흔히 겪는 진입장벽이나 막연한 두려움과는 완전히 딴판이었습니다. 복잡한 고등 수학 공식을 미분하고 함수를 뜯어고칠 필요가 전혀 없었던 겁니다. 오픈소스로 워낙 잘 다듬어진 프레임워크 덕분에, 전체적인 흐름은 오히려 기존의 일반적인 소프트웨어 개발 루틴과 크게 다르지 않았습니다.
기본적인 메커니즘은 아주 명쾌합니다. 우리가 해결하고자 하는 도메인 목적에 맞춰 정해진 규격대로 데이터셋을 예쁘게 구성해 두고, 오픈소스로 전 세계 개발자들에게 검증된 훌륭한 베이스 모델 하나를 골라잡은 뒤, 터미널에서 간단한 명령어 한 줄만 시원하게 던져주면 끝입니다. 컴퓨터가 알아서 밤새 지식을 흡수하고 나면, 개발자는 그저 그 학습의 결과물로 툭 튀어나온 가중치 파일 하나만 쏙 끄집어내어 우리 서비스에 연결하면 되는 구조였습니다.
우리가 웹 개발을 할 때 데이터베이스를 설계하고 API를 연결하는 프로그래밍을 하듯, AI 구현 역시 잘 만들어진 엔진을 규격에 맞게 다루는 일종의 '엔지니어링 인터페이스'에 가까웠던 것이죠. "인공지능은 어렵고 복잡하다"는 편견을 깨부수는 순간, 개발자로서 구현할 수 있는 서비스의 지평이 순식간에 몇 배는 넓어지는 짜릿한 경험을 할 수 있었습니다.
물론 이 과정에서 데이터의 경로가 꼬여 에러 로그를 마주하기도 하고, 생소한 확장자들을 보며 고개를 갸웃거리기도 했습니다. 하지만 그 이면의 원리를 하나씩 이해하고 나니, 이 거대한 인공지능이라는 도구가 얼마나 합리적이고 정교하게 설계되어 있는지 무릎을 탁 치게 되더군요. 인공지능 도입을 망설이고 계시거나 도대체 밑바닥에서 무슨 일이 일어나는지 궁금한 개발자분들을 위해, 제가 직접 로컬 환경에서 부딪치고 깨달은 실전 YOLOv8 학습기의 생생한 이야기를 지금부터 하나씩 아주 쉽게 풀어보려 합니다. 문을 열고 들어가 보면, 정말 생각보다 별거 아닙니다.
JSON 파일들이었습니다. 그 안에는 이미지 촬영 정보부터 시작해 카메라 센서 값, 클래스 이름, 그리고 물체의 완벽한 절대 픽셀 좌표까지 온갖 정보들이 빽빽하게 담겨 있었죠. 인공지능 학습을 하려면 이 방대한 메타데이터를 다 분석해야 하는 걸까 덜컥 겁이 났다.JSON 파일이 일종의 세세한 정보를 모두 담은 '교과서 원본'이라면, YOLO 모델이 실제로 공부할 때 읽는 책은 따로 있었습니다. 바로 labels 폴더 안에 이미지와 1:1로 매핑되어 숨어있던 초경량 TXT 파일들이었습니다.[클래스 번호] [상대 좌표 4개] 형태의 지극히 단순한 숫자 다섯 개만 덜렁 적혀 있더군요. 컴퓨터가 가장 빠르게 연산할 수 있도록 핵심만 요약해 둔 '시험장용 요약 노트'였던 셈입니다. 이 정교한 규칙을 이해하고 나니 데이터셋을 바라보는 눈이 한결 가벼워졌습니다.watch 명령어로 results.csv 성적표를 10초마다 실시간으로 훔쳐보며 box_loss와 cls_loss 오차값이 뚝뚝 떨어지는 것을 확인했습니다. "아, 내 컴퓨터가 지금 안전모와 사람을 제대로 구분하는 방법을 배우고 있구나!" 눈으로 직접 확인하는 짜릿한 순간이었습니다.그런데 학습이 모두 완료된 후, 결과물 폴더를 확인하다가 도무지 상식적으로 이해가 가지 않는 기묘한 현상을 발견했습니다.
yolov8n.pt 파일의 크기는 **6.3MB **였습니다. 그런데 여기에 내가 가진 안전모 데이터셋 지식을 밤새도록 주입하여 완성한 최종 결과물 best.pt 파일의 크기를 확인해 보니, 도리어 **6.0MB **로 용량이 더 줄어들어 있는 것이 아니겠습니까?일반적인 소프트웨어 개발 관점에서는 데이터가 쌓이고 로직이 추가되면 파일 용량이 커지는 게 당연합니다. 지식을 더 얹어서 열심히 훈련을 시켰는데 왜 모델의 피지컬 용량은 거꾸로 다이어트가 되어 툭 튀어나왔을까? 머릿속에 거대한 물음표가 떴습니다. 인공지능 모델의 내부 세계를 들여다보지 않고서는 도저히 풀리지 않는 미스터리 같은 흥미로운 현상이었죠. 대단히 역설적이게도 이 줄어든 용량 안에, 우리가 그토록 원하는 온디바이스 AI의 강력한 힌트가 숨어 있었습니다.
지식이 추가되었는데 용량이 줄어든 미스터리, 그 베일을 벗겨보니 인공지능 프레임워크의 대단히 합리적인 엔지니어링 구조가 숨어 있었습니다.
yolov8n.pt 공식 베이스 모델 안에는 전 세계 개발자들이 언제든 이어서 훈련을 진행할 수 있도록 경사하강법(Optimizer)의 이전 상태 정보, 학습률 스케줄러 메타데이터 등 '공부용 준비물'이 함께 포장되어 있습니다.best.pt 파일은 오직 실전 추론(Inference)만을 목적으로 합니다. 따라서 배포에 방해가 되는 거대하고 무거운 학습용 파라미터들을 내부적으로 싹 정제(Strip)해 버립니다. 지퍼백의 공기를 빼듯 핵심 알맹이 가중치만 남기기 때문에 용량이 가벼워지는 것이죠.여기에 결정타를 날리는 것이 바로 '클래스(nc) 수의 축소'입니다. 순정 YOLO 모델은 전 세계의 수많은 사물(사람, 자동차, 고양이, 의자 등) 80가지를 구별할 수 있는 거대한 최종 출력 레이어를 가지고 있습니다. 하지만 이번에 제가 학습시킨 커스텀 모델은 오직 '안전모'와 '사람' 같은 몇 가지 특정 카테고리만 저격해서 맞추면 됩니다. 클래스 수가 80개에서 단 몇 개로 쪼그라들면서 최종 출력층의 연산 파라미터 구조가 대폭 축소되었고, 이 헤더 다이어트 덕분에 최종 용량이 6.0MB라는 날씬한 스펙으로 완성될 수 있었던 것입니다.
이 원리를 정확히 깨닫고 나니, 인공지능 서비스를 빌드할 때 우리가 목적에 맞춰 어떤 '포맷'을 선택해야 하는지에 대한 눈이 번쩍 뜨였습니다.
애초에 제가 세그멘테이션(Segmentation)이 아닌 객체 탐지(Object Detection) 모델을 선택한 것도 바로 이 '경량화'와 맞닿아 있습니다. 우리가 흔히 말하는 AI 이미지 인식은 크게 두 가지 갈래로 나뉩니다. 물체의 위치를 사각형 네모 박스로만 뚝딱 찾아내는 객체 탐지와, 물체의 굴곡진 외곽선 실루엣을 픽셀 단위로 칼같이 따내는 세그멘테이션입니다.
-seg가 붙으며, 정답지(TXT) 구조부터 내부 레이어 스케일이 훨씬 더 무겁고 복잡합니다. 반면, 제가 선택한 객체 탐지(Detection)는 중심점과 가로세로 크기라는 딱 5개의 숫자 데이터만 다루기 때문에 연산 속도가 압도적으로 빠르고 파일도 가볍습니다.현장에서 안전모 착용 여부나 작업자의 유무를 실시간으로 판단하는 비즈니스 목적이라면, 굳이 무거운 세그멘테이션을 쓸 필요 없이 가볍고 칼같이 빠른 객체 탐지 모델이 정답이었던 것이죠. 내 목적에 최적화된 6.0MB짜리 슬림한 인공지능 두뇌를 직접 눈으로 확인하는 순간, 이 정도 스펙이라면 서버 비용 걱정 없이 사용자의 스마트폰 단말기 안에서 100% 자급자족하는 '온디바이스(On-Device) AI 앱'도 충분히 구현해 낼 수 있겠다는 강력한 확신과 욕구가 솟구쳤습니다. 부딪쳐 깨달은 지식이 확신으로 변하는 순간이었습니다.
best.pt 가중치 파일. 이 가벼우면서도 정교한 두 두뇌를 내 손안의 스마트폰으로 이식하는 상상을 하자 가슴이 뛰기 시작했습니다. 이 정도 크기라면 요즘 출시되는 스마트폰의 성능으로 볼 때 하드웨어 렉(Lag)이나 버벅임 없이 초당 30프레임 이상의 부드러운 실시간 추론이 충분히 가능하겠다는 계산이 섰습니다. 하지만 인공지능 엔지니어링의 세계는 마지막 배포 단계에서 또 한 번의 냉정한 변환 파이프라인을 요구하더군요.가장 먼저 맞닥뜨린 과제는 포맷의 변환이었습니다. 스마트폰 환경(Android/iOS)은 우리가 학습을 진행했던 무거운 파이썬 가상환경이나 대용량 PyTorch 라이브러리를 통째로 얹어서 굴릴 수 없습니다. 모바일 기기가 파일 내부를 해석하는 연산 리소스조차 아끼고, 램(RAM)에 올리자마자 즉시 가볍게 읽어낼 수 있도록 데이터를 일렬로 구조화한 모바일 전용 포맷, 즉 TFLite(TensorFlow Lite)의 형태로 변환해 주어야 했습니다.
format=tflite 옵션을 주고 내보내기(Export) 명령어를 던지는 과정은 순탄치만은 않았습니다. 최근 릴리즈된 NumPy 2.0 버전과 기존 라이브러리 간의 호환성이 깨지며 AttributeError 버그가 터져 나왔고, 텐서플로우 기반의 추가 패키지들이 누락되어 빌드가 멈추기도 했습니다. 하지만 침착하게 가상환경의 NumPy 버전을 안정적인 1.2x 대 버전으로 롤백하고, 필요한 엣지 변환 컴포넌트들을 수동으로 밀어 넣으며 트래커를 정비해 나갔습니다. 마침내 에러 로그를 뚫고 최종 변환된 best_float32.tflite 파일을 손에 쥐었을 때의 성취감은 이루 말할 수 없었습니다.모바일 온디바이스 AI 앱 구현의 핵심은 메인 UI 스레드를 완벽하게 방어하는 것입니다. 스마트폰 카메라는 초당 30프레임 이상의 이미지를 무섭게 뿜어내지만, 아무리 가벼운 모델이라도 모바일 프로세서가 이 프레임을 매 순간 전부 계산하게 만들면 발열이 심해지고 앱 전체가 뚝뚝 끊기게 됩니다.
따라서 AI 엔진이 연산에 집중하고 있을 때는 새로 들어오는 카메라 프레임을 과감하게 무시해 버리는 비동기 프레임 드롭(Frame Drop) 락(Lock) 로직을 상태 관리단에 설계해 주어야 합니다. 여기에 더해, 영상 화면에서 객체가 생겼다 사라졌다를 반복하며 개발자를 괴롭히는 고질적인 깜빡임(Flickering) 문제를 원천 차단하기 위해, 객체에 고유 ID를 부여하는 트래커 알고리즘을 결합하고 최소 0.5초 이상 상태가 유지될 때만 알림을 발생하는 윈도우 스무딩 비즈니스 로직을 얹어주면 완벽한 상용 스펙의 AI 서비스가 완성됩니다.
인공지능 모델을 내 도메인에 맞춰 학습시키는 것은 전체 프로젝트의 20%에 불과할지도 모릅니다. 진짜 가치는 그렇게 깎아낸 무기를 들고 실제 모바일 환경에 적용할 때 증명됩니다. 사용자의 스마트폰 화면 위에 좌표를 역산하고, 완벽한 네모 박스를 실시간으로 그려내는(Overlay Decorating) 이 엔지니어링 단계야말로 온디바이스 AI의 꽃입니다.
assets/에 심어보십시오. 방구석 노트북 한 대로 시작한 상상이 여러분의 스마트폰 화면 속에서 실시간으로 살아 움직이는 마법 같은 순간을 직접 경험하게 될 것입니다. 다음 포스트에서는 플러터 앱 내부에서 카메라 스트리밍 피드를 받아 실시간으로 좌표를 매핑하는 구체적인 다트(Dart) 구현 코드를 코드로 뜯어보며 설명해 드리겠습니다. 함께 현실로 만들어 가시죠!