modelctl 모범 사례
워크스테이션의 모델을 air-gapped 엣지 박스로 신뢰성 있게 올리기 위한 지침입니다. 단계별 명령은 modelctl로 모델 준비하기를 참고하세요 — 이 페이지는 그 작업 흐름 위에서의 이유와 해야 할 것/하지 말아야 할 것입니다.
가장 작은 설치 프로필을 선택하세요
섹션 제목: “가장 작은 설치 프로필을 선택하세요”modelctl은 무거운 ML 프레임워크를 선택 사항으로 둡니다. 코어 설치는 PyTorch나
TensorFlow 없이 validate와 package를 실행하므로, 운영자가 가벼운 머신에서 번들을
검증할 수 있습니다. 작업에 필요한 extra만 추가하세요.
pip install modelctl # onnx + onnxruntime + numpy 만pip install 'modelctl[pytorch]' # 또는 [tensorflow] / [all]pip install 'modelctl[quantize]' # INT8용 ml_dtypes 설치자체 완결적인 소스를 전달하세요
섹션 제목: “자체 완결적인 소스를 전달하세요”convert 머신이 학습 코드 없이 로드할 수 있는 모델을 주세요:
- PyTorch → TorchScript
.pt(torch.jit.save). 순수state_dict는 거부됩니다 (아키텍처 없음). pickle된nn.Module은 최선의 대체 경로일 뿐입니다. - TensorFlow → SavedModel 디렉터리 (잘 지원되는 경로;
.keras/.h5도 동작).
이유: convert를 실행하는 워크스테이션은 모델 클래스 정의가 필요 없으며, export는
아티팩트만으로 재현됩니다.
항상 --target-ort를 기기에 맞춰 고정하세요
섹션 제목: “항상 --target-ort를 기기에 맞춰 고정하세요”opset 지원 여부는 워크스테이션이 아니라 엣지 ONNX Runtime 기준으로 확인됩니다. 기기 버전을 고정해서, 너무 새로운 export가 현장이 아니라 책상 위에서 실패하게 하세요:
modelctl validate --model model.onnx --target-ort 1.18기기의 런타임이 실행할 수 없는 opset으로 export된 모델은 “여기선 되고 저기선 안 되는” 가장 흔한 함정입니다. 고정이 번들 출고 전에 이 함정을 막습니다.
validate를 릴리스 게이트로 다루세요
섹션 제목: “validate를 릴리스 게이트로 다루세요”검증은 fail-soft입니다 — 첫 문제에서 멈추지 않고 모든 검사를 실행하고 각각을 보고합니다. exit가 0이 아니면 출고를 막으세요. 전체 목록:
| 검사 | 확인 내용 |
|---|---|
| ONNX schema valid | onnx.checker가 그래프를 허용 |
| Opset supported | opset ≤ 엣지 ORT의 최대값 |
| Single input tensor | 엔진이 정확히 하나의 입력을 위치 기반으로 feed |
| Input dtype float32 | 엔진이 float32를 feed |
| Input rank | 선언된 shape와 일치(제공된 경우) |
| ONNX Runtime load | 런타임이 세션을 인스턴스화 |
| Test inference | 0으로 채운 forward pass 성공 |
도구에서 exit 코드를 매핑하세요:
| Exit | 의미 |
|---|---|
0 | 모든 검사 통과 |
1 | 검증 검사 실패 |
3 | converter 프레임워크(torch/TF) 미설치 |
5 | convert 후 검증 실패 |
7 | 양자화 실패(예: ml_dtypes 누락) |
의도적으로 양자화하고, 다시 검증하세요
섹션 제목: “의도적으로 양자화하고, 다시 검증하세요”Dynamic INT8(modelctl quantize 또는 convert/package의 --quantize)은 정확도를
크기·속도와 맞바꿉니다. 두 가지 규칙:
- 양자화된 모델을 다시 검증하고 대표 데이터로 예측 품질을 확인한 뒤 출고하세요 — 양자화는 출력을 이동시킬 수 있습니다.
- 줄어든다고 가정하지 마세요. 아주 작은 모델에서는 INT8의 scale/zero-point 노드가 절감분을 넘어설 수 있습니다. 이득은 실제 크기의 모델에서 나타납니다.
재현 가능하고 검증 가능한 번들을 출고하세요
섹션 제목: “재현 가능하고 검증 가능한 번들을 출고하세요”timestamp를 고정해 재빌드가 byte-identical이 되게 하세요 — air-gapped 박스로 올릴 때 감사와 변경 검토에 필수입니다:
modelctl package --model model.onnx --name pump-anomaly-v1 --timestamp 1700000000# 또는: export SOURCE_DATE_EPOCH=1700000000그런 다음 활성화 전에 기기에서 무결성을 확인하세요:
cd pump-anomaly-v1 && sha256sum -c checksums.sha256checksums.sha256은 model.onnx, metadata.json, input_schema.json을 포함하므로
변조나 부분 복사가 추론 시점이 아니라 엣지에서 잡힙니다.
엣지 입력 계약을 준수하세요
섹션 제목: “엣지 입력 계약을 준수하세요”런타임은 float32 텐서 하나를 위치 기반으로 feed합니다. 다중 입력이나 float32가
아닌 모델은 로드되지만 박스에서 추론 시 죽습니다. validate가 워크스테이션에서 이를
잡아줍니다 — export 모델을 단일 float32 입력으로 설계하고, window size와 특징
수를 페어링할 datasource와 일치시키세요(모델 배포 참조).
validate를 CI에 연결하세요
섹션 제목: “validate를 CI에 연결하세요”모든 모델 빌드에서 validate를 실행하고 exit 0 기준으로 아티팩트를 게이팅하세요. 이
검사는 torch/TF가 필요 없으므로 잡이 가볍게 유지됩니다:
pip install modelctlmodelctl validate --model build/model.onnx --target-ort 1.18 || exit 1도달할 수 없는 기기에서 발견하는 대신 파이프라인에서 잘못된 export를 잡으세요.