브라우저에서 AI 모델을 직접 실행해보고 Core Web Vitals에 미치는 영향을 측정해 보았습니다
요약
본 기사는 브라우저 환경에서 AI 신경망을 직접 실행할 때 사용자 경험(UX)과 웹 성능 지표에 미치는 영향을 측정했습니다. WebAssembly와 Transformers.js를 사용하여 4가지 모델(DistilBERT, BERT-base, Whisper Tiny, MobileViT-S)의 Core Web Vitals 중 INP(Interaction to Next Paint) 측정을 진행한 결과, 단순히 파라미터 크기만으로는 성능을 예측할 수 없음을 보여주었습니다. 특히 아키텍처가 메인 스레드를 차단하는 방식(예: Whisper Tiny의 자기회귀 디코드 루프)이 INP에 치명적인 영향을 미치며, 이는 양자화 같은 최적화 기법으로 해결하기 어렵다는 점을 발견했습니다.
핵심 포인트
- 브라우저에서 AI 모델 추론은 Core Web Vitals 중 INP(Interaction to Next Paint)에 직접적인 영향을 줍니다. 메인 스레드 차단이 발생하면 사용자의 상호작용 지연 시간이 길어집니다.
- AI 모델의 성능 저하 원인은 단순히 파라미터 크기(Parameter count)가 아니라 아키텍처(Architecture)와 추론 방식에 달려 있습니다.
- Whisper Tiny처럼 자기회귀 디코드 루프를 사용하는 모델은 반복적인 메인 스레드 차단이 발생하여 INP 등급을 'Poor'로 만들 수 있으며, 이는 양자화만으로는 해결하기 어렵습니다.
- MobileViT-S와 같은 비전 트랜스포머 기반의 아키텍처가 텍스트 모델 대비 더 빠르고 효율적인 성능을 보여주었습니다.
모두가 AI 기능을 출시하고 있습니다. 사용자 입력에 대한 감성 분석 (Sentiment analysis), 오디오를 서버로 전송하지 않는 음성 인식 (Speech recognition), 기기를 떠나지 않는 이미지 분류 (Image classification) 등이 그것입니다. 개인정보 보호라는 명분도 실질적이며, 지연 시간 (Latency) 감소라는 명분도 실질적입니다. 하지만 아무도 당연한 질문을 던지지 않습니다: 브라우저에서 신경망 (Neural network)을 실행하는 것이 실제로 사용자에게 어떤 비용을 치르게 할까요? 저는 이를 알아보기로 했습니다. 저는 벤치마크 하네스 (Benchmark harness)를 구축하고, Chrome stable 버전에서 4개의 양자화된 (Quantized) 모델을 실행하여 Core Web Vitals — 특히 Google이 사이트 순위를 매길 때 사용하는 지표인 INP에 미치는 영향을 측정했습니다. 제가 발견한 내용은 다음과 같습니다.
설정 (The Setup)
테스트에는 WebAssembly를 통해 Hugging Face 모델을 브라우저에서 직접 실행할 수 있게 해주는 라이브러리인 Transformers.js를 사용했습니다. 모든 모델은 실제 운영 환경을 반영하기 위해 INT8 양자화 형식 (q8)으로 로드되었습니다. 서로 다른 아키텍처 (Architecture)와 양식 (Modalities)을 다루기 위해 선택된 4개의 모델은 다음과 같습니다:
| 모델 | 파라미터 (Params) | 작업 (Task) | 아키텍처 (Architecture) |
|---|---|---|---|
| DistilBERT | 66M | 감성 분석 (Sentiment analysis) | Encoder (6 layers) |
| BERT-base | 110M | 특징 추출 (Feature extraction) | Encoder (12 layers) |
| Whisper Tiny | 39M | 음성 인식 (Speech recognition) | Encoder-Decoder |
| MobileViT-S | 5.7M | 이미지 분류 (Image classification) | Vision Transformer |
벤치마크 하네스는 benchmark.mspk.me에서 라이브로 확인할 수 있으며, github.com/srikarphanikumar/cwv-ai-benchmark 에서 오픈 소스로 공개되어 있습니다. 직접 실행해 보세요.
INP란 무엇이며 왜 중요한가?
INP (Interaction to Next Paint)는 2024년 3월에 Google의 상호작용성 지표로서 First Input Delay를 대체했습니다. 이는 클릭, 탭, 키 누름과 같은 사용자의 상호작용에 브라우저가 응답하고 결과를 화면에 그리는 (Paint) 데 시간이 얼마나 걸리는지를 측정합니다.
Google의 임계값 (Thresholds):
✅ 좋음 (Good): 200ms 미만
⚠️ 개선 필요 (Needs Improvement): 200–500ms
❌ 나쁨 (Poor): 500ms 초과
INP는 검색 순위에 영향을 미칩니다. 더 중요한 것은, 사용자가 귀하의 앱이 반응성이 좋은지 아니면 고장 난 것처럼 느끼는지에 영향을 미친다는 점입니다. 브라우저의 메인 스레드 (Main thread)에서 신경망 추론 (Inference)을 실행하면 스레드를 차단 (Blocking)하게 됩니다. 즉, 추론이 실행되는 동안 사용자가 무언가를 클릭하면, 모델이 완료될 때까지 클릭이 처리되지 않습니다. 그 지연 시간이 바로 귀하의 INP입니다.
결과
Apple M-series MacBook Pro, 16GB RAM의 Chrome stable 버전에서 측정한 전체 테이블입니다:
| 모델 | 로드 시간 (Load Time) | 평균 추론 (Avg Inference) | INP | INP 등급 | 메모리 변화 (Mem Δ) | 메모리 압박 (Mem Pressure) |
| :--- | :--- | :--- | :--- | :--- | :--- | : |
| DistilBERT | 7.85s | 25.1ms ±0.5 | 27.8ms | ✅ Good | +59.6MB | 2.5% |
| BERT-base | 6.07s | 83.3ms ±1.5 | 85.0ms | ⚠️ Needs Improvement | +65.3MB | 4.1% |
| Whisper Tiny | 6.71s | 496.9ms ±6.2 | 540.3ms | ❌ Poor | +123.9MB | 7.1% |
| MobileViT-S | 1.15s | 66.7ms ±1.0 | 75.6ms | ⚠️ Needs Improvement | +37.0MB | 8.0% |
놀라운 발견들
-
파라미터(Parameter) 수가 INP를 예측하지 못함
Whisper Tiny는 테스트된 모델 중 가장 적은 39M개의 파라미터를 가지고 있습니다. 하지만 540.3ms라는 가장 최악의 INP를 기록했는데, 이는 66M개의 파라미터를 가진 DistilBERT보다 19배 이상 나쁜 수치입니다. 원인은 크기가 아니라 아키텍처(Architecture)에 있습니다. Whisper는 인코더-디코더(Encoder-decoder) 모델입니다. 단일 순전파(Forward pass)로 전체 입력을 처리하는 것이 아니라, 출력 토큰을 하나씩 생성하는 자기회귀 디코드 루프(Autoregressive decode loop)를 실행합니다. 각 반복(Iteration)이 메인 스레드(Main thread)를 차단합니다. 가중치(Weights)를 아무리 공격적으로 양자화(Quantize)하더라도 총 차단 시간(Total blocking time)은 누적됩니다. 즉, 어떤 양자화도 메인 스레드에서 Whisper의 INP를 해결할 수 없음을 의미합니다. 이는 튜닝의 문제가 아니라 아키텍처의 제약 사항입니다. -
MobileViT-S는 6배 더 빠르지만 여전히 "Good" 등급에는 미치지 못함
텍스트 모델들이 6~8초 걸리는 것에 비해 MobileViT-S는 1.15초 만에 로드됩니다. 이는 초기 로딩 측면에서 엄청난 UX(User Experience) 이점입니다. 하지만 5.7M개의 파라미터만 가지고 있음에도 불구하고, 75.6ms의 INP를 기록하며 "Needs Improvement" 영역에 머물렀습니다. WASM(WebAssembly) 환경에서는 비전 트랜스포머(Vision transformer) 추론이 파라미터 수에 비해 불균형적으로 높은 비용을 발생시킵니다. 이미지 분류 기능을 구축 중이라면 주의 깊게 살펴봐야 할 부분입니다. -
메모리 압박(Memory pressure) ≠ 메모리 변화(Memory delta)
MobileViT-S는 절대적인 메모리 소비량(+37MB)은 가장 낮지만, 메모리 압박은 8.0%로 가장 높습니다. 그 37MB는 예상보다 사용 가능한 JS 힙(JS heap)에서 더 큰 비중을 차지하며, 이는 힙 제한이 훨씬 엄격한 중급형 Android 기기들에 영향을 미칠 수 있습니다.
이것이 여러분의 아키텍처(Architecture)에 의미하는 바
인코더 전용(encoder-only) 텍스트 모델(DistilBERT 클래스)로 구축하고 있다면: 메인 스레드(main thread)는 괜찮습니다. 27.8ms의 INP는 무시할 수 있는 수준입니다. CWV(Core Web Vitals) 저하를 걱정하지 않고 사용자 상호작용 시 직접 추론(inference)을 실행해도 됩니다.
더 큰 인코더 모델(BERT-base 클래스)을 사용하고 있다면: 상호작용 시 동기적(synchronously)으로 추론을 실행하지 마세요. 85ms의 경우, 이를 다른 메인 스레드 작업과 쌓게 되면 200ms를 초과할 위험이 있습니다. 상호작용 이후의 백그라운드 단계로 옮기세요. 즉, 응답을 이미 페인트(paint)한 후에 추론을 실행하십시오.
인코더-디코더(encoder-decoder) 모델(Whisper, T5, BART 등)을 사용하고 있다면: 반드시 Web Worker로 오프로드(offload)해야 합니다. 이것은 최적화가 아니라 필수 사항입니다. 무엇을 하든 메인 스레드는 수백 밀리초 동안 차단될 것입니다. Transformers.js는 Web Worker 실행을 기본적으로 지원합니다:
import { pipeline } from '@xenova/transformers';
// 메인 스레드 차단을 피하기 위해 Web Worker에서 실행
const transcriber = await pipeline('automatic-speech-recognition', 'Xenova/whisper-tiny', { worker: true });
비전 트랜스포머(vision transformers)를 사용하고 있다면: 배포하기 전에 실제 모바일 하드웨어에서 테스트하십시오. M-시리즈 Mac에서의 메모리 압박(memory pressure) 수치는 중급형 Android에서는 매우 다르게 나타날 것입니다.
알아야 할 한계점
배포된 환경에서는 TBT를 포착할 수 없었습니다. Long Tasks API는 교차 출처(cross-origin)로 배포된 컨텍스트에서는 사용할 수 없으며, 로컬로 서빙되거나 Chrome DevTools Protocol 환경에서만 사용할 수 있습니다. INP 측정값은 실제이지만, 전체 메인 스레드 차단 프로필을 제대로 측정하려면 다른 설정이 필요합니다.
모든 수치는 하이엔드(high-end) 하드웨어 기준입니다. Apple M-시리즈 Mac은 전 세계 웹 사용자의 중간값(median) 기기가 아닙니다. 중급형 Android에서의 INP 값은 현저히 높을 것이며, 잠재적으로 3~5배에 달할 수 있습니다. 모델 간의 상대적인 순위는 유지되겠지만, 이 절대적인 수치를 모바일용 프로덕션 임계값(thresholds)으로 사용하지 마십시오.
직접 시도해 보세요
벤치마크는 라이브 상태이며 오픈 소스입니다.
여러분의 기기, 네트워크 환경, 하드웨어 프로필에서 직접 실행해 보세요. 결과는 JSON 또는 CSV로 내보낼 수 있습니다. 라이브 벤치마크 (Live benchmark): benchmark.mspk.me 소스 코드 (Source code): github.com/srikarphanikumar/cwv-ai-benchmark 전체 논문 (Full paper): arXiv 링크 곧 공개 예정. 만약 중급형 Android나 저사양 기기에서 실행한 후 그 수치를 공유해 주신다면 정말 감사하겠습니다. 그것이 바로 이 연구에 필요한 후속 데이터입니다.
요약 (TL;DR)
- DistilBERT는 메인 스레드(main thread)에서 Google의 "Good" INP 범위 내에 머무는 유일한 모델입니다.
- Whisper Tiny는 가장 작은 모델임에도 불구하고 "Poor" 등급을 받았습니다 — 아키텍처(architecture)가 양자화 (quantization)보다 중요합니다.
- 인코더-디코더 (Encoder-decoder) 모델은 예외 없이 Web Worker 오프로딩 (offloading)이 필요합니다.
- 파라미터 수 (Parameter count)는 브라우저 추론 (inference) 비용을 나타내는 좋지 않은 대리 지표입니다.
- 모바일에서의 메모리 압박 (Memory pressure)은 메모리 소비 (memory consumption)와는 별개의 문제입니다.
클라이언트 사이드 AI (client-side AI)의 시대가 왔습니다. 이제 우리는 그것이 실제로 어떤 비용을 치르는지 측정해야 합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기