제조 AI의 운영 요구사항
컨베이어 벨트는 AI 응답을 기다리지 않습니다. 제조 현장 AI는 < 50ms 추론, 오프라인 동작, 드리프트 감지 세 가지가 필수입니다.
저지연 추론 달성
import onnxruntime as ort
import numpy as np
import time
class FastInference:
def __init__(self, model_path: str):
opts = ort.SessionOptions()
opts.intra_op_num_threads = 4
opts.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
self.sess = ort.InferenceSession(model_path, sess_options=opts)
self.inp = self.sess.get_inputs()[0].name
# 웜업: 첫 추론은 JIT 컴파일로 느림
dummy = np.zeros((1, 128), dtype=np.float32)
for _ in range(10):
self.sess.run(None, {self.inp: dummy})
def predict(self, features: np.ndarray) -> dict:
t0 = time.perf_counter()
out = self.sess.run(None, {self.inp: features})
return {
"value": float(out[0][0]),
"latency_ms": (time.perf_counter() - t0) * 1000
}배치 처리로 처리량 향상
단일 추론보다 배치 추론이 처리량을 10~20배 높입니다.
import asyncio
from collections import deque
class BatchInference:
def __init__(self, model, batch_size=32, max_wait_ms=10):
self.model = model
self.batch_size = batch_size
self.max_wait = max_wait_ms / 1000
self.queue = deque()
asyncio.create_task(self._loop())
async def predict(self, features):
fut = asyncio.Future()
self.queue.append((features, fut))
return await fut
async def _loop(self):
while True:
await asyncio.sleep(self.max_wait)
if not self.queue:
continue
batch, futs = [], []
while self.queue and len(batch) < self.batch_size:
f, fut = self.queue.popleft()
batch.append(f)
futs.append(fut)
results = self.model.predict_batch(np.stack(batch))
for fut, res in zip(futs, results):
fut.set_result(res)예측 유지보수: Isolation Forest
from sklearn.ensemble import IsolationForest
import joblib
# 정상 운전 데이터만으로 학습
clf = IsolationForest(n_estimators=100, contamination=0.01, random_state=42)
clf.fit(normal_sensor_data)
joblib.dump(clf, "pdm_model.pkl")
def score(reading: np.ndarray) -> dict:
s = clf.decision_function(reading.reshape(1, -1))[0]
return {
"score": float(s),
"is_anomaly": s < -0.1,
"severity": "HIGH" if s < -0.3 else "MEDIUM" if s < -0.1 else "NORMAL"
}모델 드리프트 감지
생산 환경이 변하면(계절, 원자재, 설비 노화) 모델 성능이 저하됩니다.
from scipy.stats import ks_2samp
class DriftDetector:
def __init__(self, reference: np.ndarray, threshold: float = 0.05):
self.ref = reference
self.thr = threshold
def check(self, current: np.ndarray) -> list:
drifted = []
for i in range(self.ref.shape[1]):
_, p = ks_2samp(self.ref[:, i], current[:, i])
if p < self.thr:
drifted.append(f"feature_{i}")
if drifted:
print(f"드리프트 감지: {drifted}")
self._trigger_retrain()
return drifted
def _trigger_retrain(self):
import requests
requests.post(os.environ["RETRAIN_WEBHOOK_URL"])운영 지표
| 지표 | 목표 | 경고 기준 |
|---|---|---|
| 추론 지연 P99 | < 50ms | > 100ms |
| 이상 탐지 정밀도 | > 0.90 | < 0.80 |
| 드리프트 감지 주기 | 24시간 | 72시간 초과 |
| 재학습 주기 | 월 1회 이상 | 분기 1회 미만 |
이 3편 시리즈로 산업 현장 AI 통합의 전 과정(게이트웨이→파이프라인→모델 운영)이 완성됩니다.
엣지 노드 모델 교체가 실패할 때: 원인·재현·검증·복구
하이브리드 구조에서 가장 흔한 장애는 추론 자체가 아니라 클라우드에서 내려보낸 새 모델이 일부 엣지 노드에서만 동작하지 않는 상황입니다.
원인
- 런타임 버전 불일치: 클라우드에서 export한 ONNX opset을 엣지의 구버전 ONNX Runtime이 지원하지 않음
- 전송 중 손상 또는 부분 다운로드: 네트워크 단절 후 재시도 로직이 없어 잘린 파일이 로드됨
- 하드웨어 차이: 같은 라인이라도 GPU/NPU 유무가 달라 실행 프로바이더(CUDA/CPU)가 바뀌고 지연이 급증
재현과 검증 명령
# 1) 배포된 모델 무결성: 클라우드에서 발행한 해시와 비교
sha256sum /opt/models/current/model.onnx
# 2) 런타임과 실행 프로바이더 확인
python3 -c "import onnxruntime as ort; print(ort.__version__, ort.get_available_providers())"
# 3) 모델 opset 확인
python3 -c "import onnx; m=onnx.load('/opt/models/current/model.onnx'); print([(o.domain,o.version) for o in m.opset_import])"해시가 다르면 전송 문제, opset이 런타임 지원 범위를 넘으면 export 설정 문제, 프로바이더 목록에 CUDA가 없으면 드라이버·패키지 문제로 분기합니다.
복구: A/B 슬롯 교체
/opt/models/a, /opt/models/b 두 디렉터리를 두고 current 심볼릭 링크만 바꿉니다. 새 슬롯에서 샘플 입력으로 추론 스모크 테스트와 p99 지연 측정을 통과한 경우에만 ln -sfn /opt/models/b /opt/models/current로 전환하고, 실패하면 링크를 되돌려 즉시 이전 모델로 돌아갑니다.
재발 방지
- 롤아웃은 노드 1대 → 라인 1개 → 공장 전체 순서로 단계화하고, 단계마다 지연·오탐률을 게이트로 둡니다.
- 모델 아티팩트와 함께 opset·런타임 최소 버전·해시를 매니페스트로 배포하고, 에이전트가 로드 전에 검사하게 합니다.
글마다 출처와 확인 범위가 다릅니다. 아래에 확인일·확인 범위·출처가 기록된 글만 그 범위에서 확인된 것입니다. 기록이 없는 글은 적용 전 사용 중인 버전의 공식 문서로 직접 확인하고, 오류는 이메일로 알려주세요. 편집 정책 · 이메일로 제보
이 글에는 사람이 확인한 날짜·범위 기록이 아직 없습니다.
댓글
첫 번째 댓글을 남겨보세요.