[Tech Series 03] Web ML 개발 프로세스: 모델 변환부터 배포까지
Python으로 만들어진 AI 모델을 웹에서 실행 가능한 형태로 변환하고 통합하는 개발 워크플로우를 단계별로 설명합니다.
![[Tech Series 03] Web ML 개발 프로세스: 모델 변환부터 배포까지](/images/blog/model_conversion_flow.png)
Web ML 개발 프로세스: 모델 변환부터 배포까지
웹 브라우저에서 AI 모델을 실행하기 위해서는 단순히 코드를 복사해서 붙여넣는 것으로는 부족합니다. Python 중심의 AI 연구 환경(PyTorch, TensorFlow)에서 개발된 모델을 JavaScript 및 WebGPU 환경으로 가져오기 위해서는 체계적인 변환 및 배포 파이프라인이 필요합니다.
1. 모델 학습 및 선정 (Python Environment)
모든 Web ML 프로젝트의 시작은 여느 AI 프로젝트와 같습니다.
학습 (Training)
PyTorch나 TensorFlow를 사용하여 목적에 맞는 모델을 학습시킵니다. 이 과정에서 중요한 점은 웹 환경의 제약사항을 미리 고려하는 것입니다.
import torch
import torch.nn as nn
class LightweightModel(nn.Module):
def __init__(self):
super().__init__()
# 웹 배포를 위해 파라미터 수를 최소화
self.conv1 = nn.Conv2d(3, 32, 3, padding=1)
self.conv2 = nn.Conv2d(32, 64, 3, padding=1)
self.fc = nn.Linear(64 * 56 * 56, 10)
def forward(self, x):
x = torch.relu(self.conv1(x))
x = torch.max_pool2d(x, 2)
x = torch.relu(self.conv2(x))
x = torch.max_pool2d(x, 2)
x = x.view(x.size(0), -1)
return self.fc(x)
# 모델 학습
model = LightweightModel()
# ... 학습 코드
사전 학습 모델 선정 (Pre-trained Model Selection)
Hugging Face와 같은 모델 허브에서 프로젝트에 적합한 사전 학습 모델을 찾습니다. 이 단계에서는 모델의 성능뿐만 아니라 크기를 중요하게 고려해야 합니다. 웹 환경은 다운로드 속도와 메모리 제약이 있기 때문입니다.
선택 기준:
- 모델 크기: 50MB 이하 권장 (초기 로딩)
- 추론 속도: 실시간 처리 가능 여부
- 브라우저 호환성: WebGL/WebGPU 지원
- 라이선스: 상업적 사용 가능 여부
2. 모델 변환 (Model Conversion)
브라우저는 .pt (PyTorch)나 .h5 (Keras) 파일을 직접 실행할 수 없습니다. 따라서 웹 친화적인 포맷으로 변환하는 과정이 필수적입니다.
TensorFlow.js Converter
TensorFlow 저장 포맷(SavedModel)을 웹에서 로드 가능한 model.json과 바이너리 샤드 파일들로 변환합니다.
# TensorFlow 모델을 TensorFlow.js 형식으로 변환
tensorflowjs_converter \
--input_format=tf_saved_model \
--output_format=tfjs_graph_model \
--signature_name=serving_default \
--saved_model_tags=serve \
/path/to/saved_model \
/path/to/tfjs_model
변환 옵션:
- 양자화 (Quantization): 가중치를 float32에서 int8로 변환하여 크기 75% 감소
- 샤딩 (Sharding): 대용량 모델을 여러 파일로 분할하여 병렬 다운로드
- 그래프 최적화: 불필요한 연산 제거 및 최적화
ONNX (Open Neural Network Exchange)
PyTorch 모델은 보통 ONNX라는 중간 포맷으로 변환됩니다.
import torch
import torch.onnx
# PyTorch 모델을 ONNX로 내보내기
dummy_input = torch.randn(1, 3, 224, 224)
torch.onnx.export(
model,
dummy_input,
"model.onnx",
export_params=True,
opset_version=12,
do_constant_folding=True,
input_names=['input'],
output_names=['output']
)
ONNX Runtime Web을 사용하면 이 포맷을 브라우저에서 직접 실행할 수 있어 호환성이 매우 높습니다.
// ONNX Runtime Web으로 모델 실행
import * as ort from "onnxruntime-web";
const session = await ort.InferenceSession.create("model.onnx");
const results = await session.run(feeds);
MLC-LLM (대규모 언어 모델용)
최근 주목받는 LLM을 웹에서 실행하기 위해서는 TVM 컴파일러 기반의 MLC-LLM 툴체인을 사용합니다.
# LLM을 WebGPU용으로 컴파일
mlc_llm compile \
--model HuggingFaceH4/zephyr-7b-beta \
--target webgpu \
--quantization q4f16_1 \
--output dist/
이는 Python 모델을 분석하여 WebGPU 셰이더 코드로 컴파일하고, 가중치를 효율적인 구조로 패키징합니다.
3. 최적화 및 테스트
변환 후에는 성능 최적화와 철저한 테스트가 필요합니다.
성능 벤치마킹
// 추론 시간 측정
const iterations = 100;
const startTime = performance.now();
for (let i = 0; i < iterations; i++) {
await model.predict(inputTensor);
}
const avgTime = (performance.now() - startTime) / iterations;
console.log(`평균 추론 시간: ${avgTime.toFixed(2)}ms`);
크로스 브라우저 테스트
- Chrome (WebGPU 우선)
- Firefox (WebGL 폴백)
- Safari (Metal 백엔드)
- Edge (DirectX 백엔드)
정확도 검증
Python 원본 모델과 변환된 웹 모델의 출력을 비교하여 정확도 손실이 허용 범위 내인지 확인합니다.
4. 웹 애플리케이션 통합 및 배포

변환된 모델은 정적 파일 형태로 웹 서버나 CDN에 배포됩니다.
모델 로딩
// TensorFlow.js 모델 로드 예시
async function loadModel() {
console.log("모델 로딩 시작...");
// 진행률 표시
const model = await tf.loadLayersModel(
"https://cdn.example.com/my-model/model.json",
{
onProgress: (fraction) => {
console.log(`로딩 진행률: ${(fraction * 100).toFixed(1)}%`);
updateProgressBar(fraction);
},
},
);
console.log("모델 로딩 완료!");
return model;
}
캐싱 전략
Service Worker를 활용하여 모델 파일을 캐싱하면 재방문 시 로딩 시간을 대폭 단축할 수 있습니다.
// service-worker.js
self.addEventListener("install", (event) => {
event.waitUntil(
caches.open("ml-models-v1").then((cache) => {
return cache.addAll([
"/models/model.json",
"/models/group1-shard1of4.bin",
"/models/group1-shard2of4.bin",
// ... 나머지 샤드 파일들
]);
}),
);
});
사용자 경험 최적화
Progressive Loading (점진적 로딩)
대용량 모델의 경우 전체 다운로드를 기다리는 대신, 일부 레이어만으로 먼저 동작을 시작하고 나머지는 백그라운드에서 로드합니다.
Warm-up 추론
첫 추론은 GPU 초기화 시간 때문에 느릴 수 있습니다. 더미 입력으로 한 번 실행하여 GPU를 준비시킵니다.
// GPU Warm-up
await model.predict(tf.zeros([1, 224, 224, 3])).data();
5. CI/CD 파이프라인
자동화된 배포 파이프라인을 구축하면 모델 업데이트가 훨씬 수월합니다.
# GitHub Actions 예시
name: Deploy ML Model
on:
push:
branches: [main]
jobs:
convert-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Convert Model
run: |
python convert_to_tfjs.py
- name: Deploy to CDN
run: |
aws s3 sync ./models s3://my-cdn-bucket/models/
aws cloudfront create-invalidation --distribution-id XYZ
마무리
Web ML 개발은 단순한 모델 변환 이상의 종합적인 엔지니어링 작업입니다. 성능, 사용자 경험, 배포 전략을 모두 고려해야 성공적인 서비스를 만들 수 있습니다.
핵심 포인트:
- 웹 환경 제약사항을 처음부터 고려한 모델 설계
- 적절한 변환 도구 선택 (TF.js, ONNX, MLC-LLM)
- 철저한 성능 최적화 및 크로스 테스트
- 사용자 경험을 고려한 로딩 전략
- 자동화된 배포 파이프라인
다음 편에서는 프로덕션 레벨의 Web ML 최적화 기법에 대해 더 깊이 다루겠습니다.

![[Tech Series 01] 웹 브라우저, AI의 새로운 무대가 되다: Edge Intelligence](/images/blog/edge_intelligence_concept.png)
![[Tech Series 02] TensorFlow.js에서 WebLLM까지: Web ML의 진화](/images/blog/web_ml_evolution.png)