본문 바로가기

TIL

WASM 온디바이스 추론 — 서버 없이 폰 안에서 모델 돌리기

vlm 기반 앱을 서비스하는 방법은 크게 둘이다. 사진을 서버로 보내 거기서 모델을 돌리거나(서버 추론), 폰 안에서 직접 돌리거나(온디바이스 추론)다. 후자를 브라우저나 앱 웹뷰에서 가능하게 하는 핵심 기술이 WASM이다.

WASM — 브라우저에서 도는 네이티브급 바이트코드

WASM(WebAssembly)은 브라우저와 웹뷰에서 실행되는 저수준 바이트코드 포맷이다. 자바스크립트보다 훨씬 빠르게, 네이티브에 가까운 속도로 계산을 처리한다.

비유하면 만국 공통의 기계어다. 어떤 언어로 짠 계산 코드든 WASM으로 컴파일하면, 브라우저가 OS나 기기 종류와 무관하게 같은 방식으로 빠르게 실행한다. 샌드박스(격리된 안전 영역) 안에서 돌기 때문에 보안도 유지된다.

이미지 모델의 경우, ONNX로 내보낸 모델을 onnxruntime-web이나 transformers.js 같은 라이브러리가 WASM 백엔드로 실행한다. ONNX가 무엇인지는 다른 글에서 다룬다. 여기서는 "폰 안의 실행기가 ONNX 모델을 WASM으로 돌린다"가 핵심이다.

제약 세 가지

WASM은 강력하지만 서버 GPU 환경과는 다른 제약이 있다. 추론 속도를 가늠하려면 이 제약을 알아야 한다.

  • 단일 스레드: 기본적으로 한 번에 한 흐름만 실행한다. 멀티코어를 자동으로 활용하지 못한다(스레드 확장은 별도 설정과 브라우저 지원이 필요).
  • GPU 접근 없음: 기본 WASM은 CPU로만 계산한다. WebGL/WebGPU 백엔드로 GPU를 쓰는 옵션이 있지만 기기·브라우저별 지원 범위가 제한적이다.
  • 메모리 한도: 브라우저 탭 기준 보통 2~4GB로 제한된다. 수 GB짜리 큰 모델은 애초에 올리기 어렵다.

이 제약들이 모이면 결론은 하나다. WASM 온디바이스에는 작고 가벼운 모델이 맞는다. 그래서 ONNX 변환과 INT8 양자화로 모델을 미리 줄여두는 단계가 사실상 세트로 따라온다.

실제 속도

제약이 있어도 작은 분류 모델이면 충분히 빠르다. INT8로 양자화한 ViT-B/32 분류 모델 기준, 모바일 Chrome에서 추론 한 번에 약 200~600ms다.

사용자가 사진을 찍고 결과를 기다리는 흐름에서 600ms는 허용 범위다. 반대로 수 GB짜리 생성형 모델을 WASM에서 돌리면 수초~수분이 걸려 사실상 쓰기 어렵다. 같은 WASM이라도 모델 크기에 따라 체감이 완전히 갈린다.

모델 크기 WASM 추론 시간 온디바이스 적합
작은 분류 모델(ViT-B INT8) ~85MB 200~600ms 적합
큰 생성형 모델(수 GB) 수 GB 수초~수분 부적합

왜 굳이 온디바이스인가

서버에서 큰 GPU로 돌리면 더 빠르고 큰 모델도 쓸 수 있다. 그런데도 온디바이스를 택하는 이유가 있다.

  • 프라이버시: 사진이 기기를 벗어나지 않는다. 음식·신체·아이 사진처럼 민감한 입력을 다루는 앱에서 결정적이다.
  • 비용 0: 추론을 사용자 기기가 처리하므로 서버 GPU 비용이 들지 않는다. 사용자가 늘어도 추론 비용이 비례해 늘지 않는다.
  • 오프라인: 네트워크 없이도 동작한다.
  • 런타임 의존성 없음: WASM 실행기는 앱 패키지 안에 들어가므로, 따로 설치할 무거운 프레임워크가 없다. 모델 파일과 onnxruntime-web 패키지면 끝이다.

이점과 트레이드오프

이점은 위의 네 가지(프라이버시·비용·오프라인·의존성 없음)다.

감수하는 것:

  • 모델 크기 상한: 메모리·속도 제약 때문에 큰 모델을 못 쓴다. 작은 모델로 풀 수 있는 문제여야 한다.
  • 기기 편차: 저사양 기기에서는 추론이 더 느리다. 서버처럼 성능이 균일하지 않다.
  • 속도 한계: 단일 스레드·CPU 기반이라 서버 GPU만큼 빠르진 않다.

정리하면 WASM 온디바이스는 "최대 성능과 모델 크기"를 양보하는 대신 "프라이버시·비용·오프라인"을 얻는 선택이다. 작은 모델로 충분히 풀리는 인식 문제, 그리고 입력이 민감한 앱에서 특히 잘 맞는다.