프로덕션 배포, MLOps 및 거버넌스
弘益人間 · 널리 인간을 이롭게 하라
엔터프라이즈 AI 배포는 강력한 인프라, 모니터링, 거버넌스 및 규정 준수가 필요합니다. WIA-AI-014 신경망 형식 표준은 엔터프라이즈 MLOps 플랫폼과의 원활한 통합을 가능하게 하여 모델이 프로덕션 준비, 보안 및 대규모 관리 가능하도록 보장합니다.
개발에서 프로덕션까지의 완전한 ML 파이프라인:
WIA-AI-014를 사용한 MLOps 파이프라인:
1. 개발
├── 모델 훈련 (PyTorch/TensorFlow)
├── 실험 추적 (MLflow/W&B)
└── 버전 관리 (Git + DVC)
2. 검증
├── WIA-AI-014 형식으로 내보내기
├── 모델 검증 테스트
├── 성능 벤치마킹
└── 보안 스캐닝
3. 등록
├── 모델 레지스트리 (MLflow/Custom)
├── 메타데이터 보강
├── 거버넌스 승인
└── 아티팩트 저장소 (S3/GCS)
4. 배포
├── A/B 테스팅 인프라
├── Blue-Green 배포
├── 카나리 릴리스
└── 멀티 클라우드 지원
5. 모니터링
├── 성능 메트릭
├── 데이터 드리프트 감지
├── 모델 드리프트 감지
└── 알림 및 페이징
6. 유지보수
├── 모델 재훈련
├── 롤백 절차
└── 지속적 개선
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: model-server
labels:
app: ml-model
version: v2.1.0
spec:
replicas: 3
selector:
matchLabels:
app: ml-model
template:
metadata:
labels:
app: ml-model
version: v2.1.0
spec:
containers:
- name: model-server
image: company/model-server:latest
ports:
- containerPort: 8080
env:
- name: MODEL_PATH
value: "/models/resnet50_v2.1.0.onnx"
- name: BATCH_SIZE
value: "32"
resources:
limits:
memory: "4Gi"
cpu: "2"
nvidia.com/gpu: "1"
requests:
memory: "2Gi"
cpu: "1"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 15
periodSeconds: 5
volumeMounts:
- name: model-storage
mountPath: /models
volumes:
- name: model-storage
persistentVolumeClaim:
claimName: model-pvc
---
apiVersion: v1
kind: Service
metadata:
name: model-service
spec:
selector:
app: ml-model
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import onnxruntime as ort
from typing import Dict, List
import numpy as np
app = FastAPI()
class ModelRegistry:
"""모델 레지스트리"""
def __init__(self):
self.models: Dict[str, ort.InferenceSession] = {}
def load_model(self, name: str, path: str):
"""레지스트리에 모델 로드"""
session = ort.InferenceSession(path)
self.models[name] = session
return True
def get_model(self, name: str):
"""레지스트리에서 모델 가져오기"""
if name not in self.models:
raise HTTPException(status_code=404, detail="모델을 찾을 수 없습니다")
return self.models[name]
def list_models(self) -> List[str]:
"""로드된 모든 모델 나열"""
return list(self.models.keys())
registry = ModelRegistry()
# 시작 시 모델 로드
@app.on_event("startup")
async def load_models():
registry.load_model("resnet50_v2", "/models/resnet50_v2.1.0.onnx")
registry.load_model("bert_base", "/models/bert_base_v1.0.0.onnx")
class PredictionRequest(BaseModel):
model_name: str
input_data: List[List[float]]
class PredictionResponse(BaseModel):
model_name: str
predictions: List[float]
latency_ms: float
@app.post("/predict", response_model=PredictionResponse)
async def predict(request: PredictionRequest):
import time
start = time.perf_counter()
# 모델 가져오기
model = registry.get_model(request.model_name)
# 입력 준비
input_array = np.array(request.input_data, dtype=np.float32)
input_name = model.get_inputs()[0].name
# 추론 실행
outputs = model.run(None, {input_name: input_array})
latency = (time.perf_counter() - start) * 1000
return PredictionResponse(
model_name=request.model_name,
predictions=outputs[0].tolist(),
latency_ms=latency
)
@app.get("/models")
async def list_models():
return {"models": registry.list_models()}
@app.get("/health")
async def health():
return {"status": "healthy"}
# 실행: uvicorn server:app --host 0.0.0.0 --port 8080
import random
from enum import Enum
class DeploymentStrategy(Enum):
"""배포 전략"""
BLUE_GREEN = "blue_green"
CANARY = "canary"
AB_TEST = "ab_test"
class ModelRouter:
"""모델 라우팅 시스템"""
def __init__(self):
self.models = {}
self.traffic_split = {}
def register_model(self, name: str, version: str,
session, weight: float = 0.0):
"""트래픽 가중치로 모델 변형 등록"""
key = f"{name}:{version}"
self.models[key] = session
self.traffic_split[key] = weight
def route_request(self, model_name: str):
"""요청을 적절한 모델 버전으로 라우팅"""
# 이 모델의 모든 버전 가져오기
versions = {k: v for k, v in self.traffic_split.items()
if k.startswith(f"{model_name}:")}
if not versions:
raise ValueError(f"{model_name}의 버전을 찾을 수 없습니다")
# 가중치 기반 랜덤 선택
total_weight = sum(versions.values())
rand = random.uniform(0, total_weight)
cumsum = 0
for version_key, weight in versions.items():
cumsum += weight
if rand <= cumsum:
return self.models[version_key]
# 사용 예
router = ModelRouter()
# Blue-Green: v2에 100%, v1은 웜업 유지
router.register_model("resnet50", "v1", model_v1, weight=0.0)
router.register_model("resnet50", "v2", model_v2, weight=1.0)
# 카나리: v1에 95%, v2에 5%
router.register_model("bert", "v1", bert_v1, weight=0.95)
router.register_model("bert", "v2", bert_v2, weight=0.05)
# A/B 테스트: 50/50 분할
router.register_model("gpt", "variant_a", gpt_a, weight=0.5)
router.register_model("gpt", "variant_b", gpt_b, weight=0.5)
# 요청 라우팅
model = router.route_request("resnet50")
output = model.run(None, input_data)
from prometheus_client import Counter, Histogram, Gauge, start_http_server
import time
# 메트릭 정의
prediction_requests = Counter(
'model_prediction_requests_total',
'총 예측 요청 수',
['model_name', 'version', 'status']
)
prediction_latency = Histogram(
'model_prediction_latency_seconds',
'예측 지연 시간 (초)',
['model_name', 'version'],
buckets=[0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0]
)
model_memory_usage = Gauge(
'model_memory_usage_bytes',
'모델 메모리 사용량 (바이트)',
['model_name', 'version']
)
active_requests = Gauge(
'model_active_requests',
'활성 요청 수',
['model_name', 'version']
)
class MonitoredModel:
"""모니터링되는 모델"""
def __init__(self, model, name, version):
self.model = model
self.name = name
self.version = version
def predict(self, input_data):
# 활성 요청 증가
active_requests.labels(
model_name=self.name,
version=self.version
).inc()
start = time.perf_counter()
try:
# 추론 실행
output = self.model.run(None, input_data)
# 성공 기록
prediction_requests.labels(
model_name=self.name,
version=self.version,
status='success'
).inc()
return output
except Exception as e:
# 실패 기록
prediction_requests.labels(
model_name=self.name,
version=self.version,
status='error'
).inc()
raise
finally:
# 지연 시간 기록
latency = time.perf_counter() - start
prediction_latency.labels(
model_name=self.name,
version=self.version
).observe(latency)
# 활성 요청 감소
active_requests.labels(
model_name=self.name,
version=self.version
).dec()
# 메트릭 서버 시작
start_http_server(9090)
# 모니터링되는 모델 사용
monitored = MonitoredModel(onnx_session, "resnet50", "v2.1.0")
output = monitored.predict(input_data)
import numpy as np
from scipy import stats
class DataDriftDetector:
"""데이터 드리프트 감지 시스템"""
def __init__(self, reference_data, significance=0.05):
self.reference_data = reference_data
self.significance = significance
self.reference_stats = self.compute_stats(reference_data)
def compute_stats(self, data):
"""통계 계산"""
return {
'mean': np.mean(data, axis=0),
'std': np.std(data, axis=0),
'min': np.min(data, axis=0),
'max': np.max(data, axis=0)
}
def detect_drift_ks_test(self, current_data):
"""Kolmogorov-Smirnov 테스트로 분포 이동 감지"""
drifted_features = []
for i in range(current_data.shape[1]):
statistic, pvalue = stats.ks_2samp(
self.reference_data[:, i],
current_data[:, i]
)
if pvalue < self.significance:
drifted_features.append({
'feature_index': i,
'statistic': statistic,
'pvalue': pvalue
})
return {
'drifted': len(drifted_features) > 0,
'num_drifted_features': len(drifted_features),
'details': drifted_features
}
def detect_drift_psi(self, current_data, num_bins=10):
"""Population Stability Index"""
psi_values = []
for i in range(current_data.shape[1]):
ref_counts, bin_edges = np.histogram(
self.reference_data[:, i],
bins=num_bins
)
curr_counts, _ = np.histogram(
current_data[:, i],
bins=bin_edges
)
# 정규화
ref_pct = ref_counts / len(self.reference_data)
curr_pct = curr_counts / len(current_data)
# 0으로 나누기 방지
ref_pct = np.where(ref_pct == 0, 0.0001, ref_pct)
curr_pct = np.where(curr_pct == 0, 0.0001, curr_pct)
# PSI 계산
psi = np.sum((curr_pct - ref_pct) * np.log(curr_pct / ref_pct))
psi_values.append(psi)
avg_psi = np.mean(psi_values)
# PSI 해석: <0.1 안정, 0.1-0.2 보통, >0.2 심각
return {
'psi': avg_psi,
'status': '안정' if avg_psi < 0.1 else '보통' if avg_psi < 0.2 else '심각',
'feature_psi': psi_values
}
# 사용 예
detector = DataDriftDetector(reference_data=training_data)
# 정기적으로 프로덕션 데이터 확인
drift_result = detector.detect_drift_ks_test(production_data)
if drift_result['drifted']:
print(f"⚠️ {drift_result['num_drifted_features']}개 특성에서 데이터 드리프트 감지")
# 재훈련 또는 알림 트리거
from cryptography.fernet import Fernet
import hashlib
class SecureModelStorage:
"""보안 모델 저장소"""
def __init__(self, encryption_key=None):
if encryption_key is None:
encryption_key = Fernet.generate_key()
self.cipher = Fernet(encryption_key)
self.key = encryption_key
def encrypt_model(self, model_path, output_path):
"""모델 파일 암호화"""
with open(model_path, 'rb') as f:
model_data = f.read()
encrypted_data = self.cipher.encrypt(model_data)
with open(output_path, 'wb') as f:
f.write(encrypted_data)
# 무결성을 위한 해시 계산
model_hash = hashlib.sha256(model_data).hexdigest()
return model_hash
def decrypt_model(self, encrypted_path, output_path):
"""모델 파일 복호화"""
with open(encrypted_path, 'rb') as f:
encrypted_data = f.read()
decrypted_data = self.cipher.decrypt(encrypted_data)
with open(output_path, 'wb') as f:
f.write(decrypted_data)
return True
# 사용 예
secure_storage = SecureModelStorage()
# 저장 전 암호화
model_hash = secure_storage.encrypt_model(
'model.onnx',
'encrypted_model.enc'
)
# 로드를 위해 복호화
secure_storage.decrypt_model(
'encrypted_model.enc',
'decrypted_model.onnx'
)
class CostOptimizer:
"""비용 최적화 도구"""
def __init__(self):
self.request_costs = {
'cpu': 0.0001, # 요청당
'gpu': 0.001, # 요청당
'memory_gb_hour': 0.01
}
def estimate_monthly_cost(self, requests_per_day, avg_latency_ms,
memory_gb, use_gpu=False):
"""월간 인프라 비용 추정"""
monthly_requests = requests_per_day * 30
compute_type = 'gpu' if use_gpu else 'cpu'
# 컴퓨팅 비용
compute_cost = monthly_requests * self.request_costs[compute_type]
# 메모리 비용 (항상 켜짐 가정)
memory_hours = 24 * 30 # 월간 시간
memory_cost = memory_gb * memory_hours * self.request_costs['memory_gb_hour']
total_cost = compute_cost + memory_cost
return {
'compute_cost': compute_cost,
'memory_cost': memory_cost,
'total_cost': total_cost,
'cost_per_request': total_cost / monthly_requests
}
def recommend_optimization(self, current_cost):
"""비용 최적화 권장사항 제공"""
recommendations = []
if current_cost['compute_cost'] > current_cost['memory_cost'] * 2:
recommendations.append({
'type': '배칭',
'description': '요청 배칭을 구현하여 요청당 오버헤드 감소',
'estimated_savings': current_cost['compute_cost'] * 0.3
})
if current_cost['memory_cost'] > 100:
recommendations.append({
'type': '양자화',
'description': 'INT8 양자화 적용하여 메모리 사용량 감소',
'estimated_savings': current_cost['memory_cost'] * 0.5
})
return recommendations
# 사용 예
optimizer = CostOptimizer()
cost = optimizer.estimate_monthly_cost(
requests_per_day=1000000,
avg_latency_ms=10,
memory_gb=4,
use_gpu=True
)
print(f"월간 비용: ${cost['total_cost']:.2f}")
print(f"요청당 비용: ${cost['cost_per_request']:.6f}")
recommendations = optimizer.recommend_optimization(cost)
for rec in recommendations:
print(f"\n{rec['type']}: {rec['description']}")
print(f"예상 절감액: ${rec['estimated_savings']:.2f}/월")
한국 통신 인프라 — 과기정통부(MSIT)·방송통신위원회(KCC)·정보통신기획평가원(IITP)·정보통신산업진흥원(NIPA)·KISA·NIS·KCMVP·TTA·KATS·KOLAS·NIA·ETRI·KAIST·KIST·POSTECH·삼성·LG·SK·KT·LG U+·NAVER·카카오 협력 「제5차 정보통신 전략 2024-2028」 운영. 「전기통신사업법」·「정보통신망법」·「전파법」·「방송법」·「개인정보 보호법」·「위치정보법」 적용. KS X 3GPP 4G LTE/5G NR/6G·KS X IETF 시리즈·KS X IEEE 802.11/802.15·KS X ITU-T G/H/Y 시리즈·KS X ISO/IEC 27000 시리즈 한국 프로파일 적용. 5G 가입자 3,500만 명 (2024)·6G 상용화 목표 2028년.
한국의 디지털 전환과 표준화는 다음 협력 체계로 운영된다. 디지털 정부: 디지털플랫폼정부위원회(2022년 9월 신설, 대통령 직속)·행정안전부 디지털정부국·전자정부지원센터·정부24·국민비서·KDIS(한국정보화진흥원)·NIA(한국지능정보사회진흥원)·MOIS(행정안전부). K-DNS 인프라: 한국인터넷진흥원(KISA) Korea Internet Center·KISA DNS Root Server·KRNIC(한국인터넷정보센터)·BGP Korea·국가사이버안보센터(NCSC)·KCC(방송통신위원회)·과기정통부(MSIT)·NIA·NIPA. 한국 클라우드 인프라: KT 클라우드·NAVER 클라우드 (NCloud)·삼성 SDS 클라우드·LG U+ 클라우드·NHN 클라우드·카카오엔터프라이즈 클라우드·SK텔레콤 클라우드·KISA 「클라우드 보안 인증제(CSAP)」·KCMVP 검증 클라우드·ISMS-P (정보보호 및 개인정보보호 관리체계). 한국 보안 인증: KISA ISMS-P 인증·KCMVP (국가용 암호모듈 검증제도)·국가정보원 NIS 「국가용 암호기술 운영기준」·NCSC 「국가사이버안보전략 2024-2028」·CC (Common Criteria) 한국 평가기관·EAL4·EAL5·KS X ISO/IEC 15408·19790·24759 한국 프로파일. 한국 데이터 표준: 한국지능정보사회진흥원(NIA) AI Hub·국가 데이터 표준화 위원회·통계청(KOSTAT)·MyData 4개 결합전문기관 (삼성SDS·한국신용정보원·통계청·금융결제원)·국립국어원 한국어 정보처리 표준·국가법령정보센터·국가공간정보플랫폼·국가공간데이터센터·한국공간정보표준. 금융·핀테크 표준: 금융위원회(FSC)·금융감독원(FSS)·금융정보분석원(FIU)·한국은행(BOK)·금융보안원(FSEC)·금융결제원(KFTC)·한국예탁결제원(KSD)·한국거래소(KRX) 8개 기관 협력. 5G/6G 통신 인프라: 5G 가입자 3,500만 명 (2024)·5G 기지국 350,000개·6G 상용화 목표 2028년·5G 특화망 16개 사업자·6G 가속화 추진단(MSIT, 2024) 운영. K-콘텐츠: 한국콘텐츠진흥원(KOCCA)·문화체육관광부(MCST)·한국방송통신전파진흥원(KCA)·한국문화정보원·한국영상자료원·한국출판문화산업진흥원. 「데이터3법」 (개인정보 보호법·신용정보법·정보통신망법, 2020년 시행)·「데이터 산업법」(2021)·「공공데이터법」(2013)·「인공지능 기본법」(2026)·「디지털플랫폼정부 기본법」(2024 발의) 등 한국 디지털 전환 핵심 법령이 운영 중이다.
한국의 산업 생태계와 표준화 체계는 다음 핵심 인프라로 구성된다. 한국 5대 그룹: 삼성·현대자동차·LG·SK·롯데. 각 그룹별 표준화 위원회와 ISO/IEC TC 한국 간사 활동. 삼성전자(반도체·디스플레이·가전·통신)·현대차(자동차·모빌리티)·LG전자(가전·디스플레이·OLED)·SK하이닉스(메모리)·LG에너지솔루션·삼성SDI(이차전지)·POSCO퓨처엠(소재)·현대모비스(부품). 한국 IT 빅테크: NAVER (검색·클라우드·AI 하이퍼클로바)·카카오(메신저·결제·모빌리티·뱅킹)·쿠팡(이커머스·물류)·당근마켓·토스·우아한형제들. 한국 통신3사: SK텔레콤·KT·LG U+. 5G·5G 특화망·B2B 클라우드·AI 사업 운영. 한국 7대 거점 대학: 서울대·KAIST·POSTECH·연세대·고려대·UNIST·DGIST·GIST. 모두 표준화 R&D 거점이며 ISO/IEC/IEEE 한국 의장 활동 중. 한국 정부 산하 출연연구기관(국립연구원·정출연 26개): KIST·KAERI·KIMM·KIER·KFRI·KRICT·KRIBB·KARI·KASI·KIGAM·KICT·KISTI·KETI·ETRI·NIMS·KIMS·KISDI·KOTRA·STEPI·KOEN·KICCE·KIET·KIPF·KIHASA·KICJ·KLRI. 한국 산업단지·테크밸리: 판교 테크노밸리·동탄·광교·송도 IBD·여의도·강남·시화·반월·구미·울산·창원·거제·여수·울산미포·온산·청주·익산·광양·여수·포스코 광양제철소·아산만·서산·송도·인천공항·세종·청라·검단. 한국 무역·금융 인프라: 한국무역협회(KITA)·대한무역투자진흥공사(KOTRA)·한국수출입은행(KEXIM)·한국은행·국민은행·신한·하나·우리·NH농협·기업은행·SC제일·시티·HSBC 한국·DBS 한국 등 14대 한국 은행과 외국계 은행. 한국 K-POP·K-콘텐츠: HYBE·SM·YG·JYP 4대 엔터테인먼트 회사·CJ ENM·tvN·MBC·KBS·SBS·EBS·YTN·연합뉴스TV·JTBC 한국 방송사·NETFLIX 코리아·디즈니플러스·티빙·웨이브·왓챠·쿠팡플레이. 한국 게임 산업: 넥슨·엔씨소프트·크래프톤·넷마블·카카오게임즈·펄어비스·컴투스·게임빌·NHN·스마일게이트·웹젠. 한국 자동차·이차전지: 현대자동차·기아·제네시스·LG에너지솔루션·삼성SDI·SK On·POSCO퓨처엠·에코프로·엘앤에프 이차전지 양극재 공급사. 한국 반도체: 삼성전자(HBM3E·HBM4)·SK하이닉스(HBM3E 12-Hi)·DB하이텍·SK실트론·SK엔펄스·동진세미켐·서울반도체·심텍·삼성디스플레이·LG디스플레이.
한국의 산업·기술 표준화는 다음 협력 체계를 통해 운영된다. 국가표준 거버넌스: 국가표준심의회(국무총리실 소속, 「국가표준기본법」 제5조)·국가기술표준원(KATS)·식품의약품안전처(MFDS)·산업통상자원부(MOTIE)·과학기술정보통신부(MSIT)·행정안전부(MOIS)·환경부(MOE)·보건복지부(MOHW)·국방부(MND)·문화체육관광부(MCST)·외교부(MOFA)·법무부(MOJ)·금융위원회(FSC). 한국 인정기구·시험기관: 한국인정기구(KOLAS, Korea Laboratory Accreditation Scheme)·한국제품인정기관(KAS)·한국시험인증연구원(KTC)·한국화학융합시험연구원(KTR)·한국산업기술시험원(KTL)·한국건설생활환경시험연구원(KCL)·KOLAS 인정 시험기관 800+개·KAS 인정 인증기관 50+개. 전기·전자·통신 인증: 방송통신위원회(KCC)·한국방송통신전파진흥원(KCA)·정보통신기술협회(TTA)·정보통신기획평가원(IITP)·정보통신산업진흥원(NIPA)·한국인터넷진흥원(KISA, Korea Internet & Security Agency)·KCMVP (국가용 암호모듈 검증제도)·NIS(국가정보원)·NSR(국가보안기술연구소)·NCSC(국가사이버안보센터). 국가 R&D 거점: 한국과학기술연구원(KIST)·한국전자통신연구원(ETRI)·한국과학기술원(KAIST)·서울대학교·연세대학교·고려대학교·POSTECH·UNIST·GIST·DGIST·한국과학기술정보연구원(KISTI)·한국에너지기술연구원(KIER)·한국기계연구원(KIMM)·한국화학연구원(KRICT)·한국식품연구원(KFRI)·한국생명공학연구원(KRIBB). 국제 표준 협력: ISO TC/SC 한국 간사·IEC TC/SC 한국 간사·ITU-T SG 한국 의장·3GPP RAN/SA 한국 의장·IEEE 802 한국 의장·W3C 한국지부·OASIS 한국지부·IETF 한국 협력단·OECD CSTP·UN ESCAP·APEC SCSC 한국 협력. 한국 표준 카탈로그: KS X (정보) 25,000+종·KS A (기본) 15,000+종·KS B (기계) 25,000+종·KS C (전기) 18,000+종·KS D (금속) 12,000+종·KS E (광산) 5,000+종·KS F (건설) 18,000+종·KS H (식품) 8,000+종·KS I (환경) 5,000+종·KS J (생물) 3,000+종·KS K (섬유) 15,000+종·KS L (요업) 7,000+종·KS M (화학) 12,000+종·KS P (의료) 5,000+종·KS Q (품질) 4,000+종·KS R (수송기계) 12,000+종·KS S (서비스) 3,000+종·KS T (포장) 4,000+종·KS V (조선) 5,000+종·KS W (항공) 3,000+종 — 총 220,000+ 한국산업표준(KS). 「개인정보 보호법」(법률 제19234호, 2024년 9월 15일 시행)·「전자정부법」·「전자서명법」·「정보통신망법」·「정보통신기반 보호법」·「데이터 산업법」·「공공데이터법」·「인공지능 기본법」(법률 제20212호, 2026년 7월 시행)·「산업기술혁신 촉진법」·「과학기술기본법」 등 70+개 한국 표준화 관련 법령이 운영된다.