KServe Inference — demo_credit_risk_plugin (#1472)
demo_credit_risk_plugin@Staging v1 (MLflow run 3459533cfa184e59b67703f2e6782e3a)
의 KServe InferenceService 실 배포 + /v1/models/.../predict evidence.
audit (wu3opbm4y) 발견 — m3-e2e 3건에 KServe inference 경로 미증명 → 본 가이드가 ML lifecycle 의 인퍼런스 단계 를 prod 에서 closing.
사전 조건
- MLflow registered model:
demo_credit_risk_plugin@Staging(PR #1454 lifecycle 결과) - MLflow artifact 가 SeaweedFS S3 에 저장 (
s3://mlflow-artifacts/0/<run_id>/artifacts/model) - KServe controller + ClusterServingRuntime
kserve-sklearnserver(prod 가동 —kservenamespace) - ServiceAccount
kserve-sa가kserve-s3-credentialsSecret 자동 mount
배포
kubectl --context aks-genos-prod apply -f infra/kserve/demo-credit-risk-plugin-inferenceservice.yaml
manifest (infra/kserve/demo-credit-risk-plugin-inferenceservice.yaml) 주요 필드:
predictor.serviceAccountName: kserve-sa— S3 credentials 자동 mountpredictor.sklearn.storageUri: s3://mlflow-artifacts/0/<run_id>/artifacts/modelpredictor.sklearn.protocolVersion: v1— sklearn server 기본- 리소스: 100m/256Mi requests, 500m/1Gi limits (PoC 규모)
검증
1. InferenceService READY
kubectl --context aks-genos-prod -n gend get inferenceservice demo-credit-risk-plugin
# NAME URL READY
# demo-credit-risk-plugin http://demo-credit-risk-plugin-gend.example.com True
2. Model ready
kubectl --context aks-genos-prod -n gend run kserve-test --rm -i --restart=Never \
--image=curlimages/curl:latest --command -- \
curl -sS http://demo-credit-risk-plugin-predictor/v1/models/demo-credit-risk-plugin
# {"name":"demo-credit-risk-plugin","ready":true}
3. Predict (v1 sklearn protocol)
kubectl --context aks-genos-prod -n gend run kserve-test --rm -i --restart=Never \
--image=curlimages/curl:latest --command -- \
curl -sS -X POST http://demo-credit-risk-plugin-predictor/v1/models/demo-credit-risk-plugin:predict \
-H "Content-Type: application/json" \
-d '{"instances": [[35.0, 50000.0, 5.0], [60.0, 100000.0, 25.0], [22.0, 25000.0, 1.0]]}'
# {"predictions":[1,-1,-1]}
instances 의 feature 순서 — sklearn_baseline 의 _DEMO_FEATURE_COLUMNS:
(age, income, credit_history_len). IsolationForest 응답: 1=inlier, -1=anomaly.
ML lifecycle 단계 통합 — 본 PR 가 closing
| 단계 | 위치 | 상태 |
|---|---|---|
| 모델 코드 작성 (provider) | sklearn_baseline / random_forest_classifier (#1477) | ✓ multi-provider |
| 학습 (train) | POST /api/v1/ml-plugins/{id}/train → Dagster ml_plugin_train_job | ✓ run 96d1ae3b (#1454) |
| MLflow 등록 | demo_credit_risk_plugin@Staging v1 | ✓ run 3459533c (#1454) |
| 인퍼런스 (predict) | /v1/models/demo-credit-risk-plugin:predict | ✓ 본 PR |
| 데이터-모델 연결 | dataset_uri demo:// / trino://... (#1451) | ✓ |
| 드리프트 모니터링 | drift_check=true job (#1480) + compute_ks_drift | ✓ |
cross-reference (이전 사이클)
ml-lifecycle-live-run.md의credit-riskInferenceService 와 본demo-credit-risk-plugin는 별개:credit-risk— 수동 PoC 사이클 (3d17h ago, 본 ml_plugin lifecycle 외부)demo-credit-risk-plugin— ml_plugin train SUCCESS (#1454) 의 결과물 → KServe (본 PR)
- 두 InferenceService 가 동시에 살아있어도 충돌 없음 (별도 namespace 리소스).
회귀 가드
scripts/test_cross_pr_consistency.py::test_kserve_inferenceservice_manifest_existsinfra/kserve/demo-credit-risk-plugin-inferenceservice.yaml존재 확인- storageUri 가 MLflow artifact 형식 (
s3://...artifacts/model) - protocolVersion 명시 (v1 또는 v2)
- serviceAccountName 명시 (Secret 자동 mount 패턴)
트러블슈팅
| 증상 | 원인 | 해결 |
|---|---|---|
Init:CrashLoopBackOff + NoCredentialsError | predictor 가 ServiceAccount 미명시 → kserve-s3-credentials Secret 미마운트 | spec.predictor.serviceAccountName: kserve-sa 추가 |
Predictor ingress not created (5분+ 지속) | Pod 자체가 RunningReady 안 됨 → storage-initializer 실패 가능성 | kubectl logs <predictor-pod> -c storage-initializer |
| predict 호출 응답 shape 불일치 | sklearn protocolVersion v2 (Open Inference Protocol) 사용 시 request shape 다름 | v2 사용 시 {"inputs":[{"name":"input","shape":[...]}]} 패턴 |
| 모델 schema 검증 fail | mlflow log_model 시 input_example 누락 | mlflow.sklearn.log_model(sk_model=..., input_example=...) 으로 재학습 |