[MLOps] k3s에서 모델 검증 - MLflow·Feast·KServe
해당 포스팅은 현재 재직 중인 회사와 관련이 없고, 개인 역량 개발을 위한 스터디 자료로 활용할 예정입니다.
참고 자료: 최성욱 님의 ML Platform Engineering Part 2 핸즈온(확인한 커밋
162b2f7, 2026-11-02)과 Machine Learning Platform Engineering 4~6장. 참고 저장소의 도메인은 성인 소득 분류다. 이 글은 서울 공공자전거 시간별 수요 모델로 별도 실험한 결과이며, 참고 저장소의 실행 수치를 내 결과로 옮기지 않았다.직접 실행한 범위: 2026년 11월 5일 Mac Rancher Desktop k3s에서 MLflow·Feast·BentoML·KServe 사이의 계약을 검사하는 Kubernetes Job을 실행했다. 같은 클러스터에 Kubeflow Notebook 컨트롤러와 자전거 노트북을 띄워 데이터 점검 셀도 실행했다. 기존 KFP는 standalone 설치이며, 이번 검증 Job은 KFP를 사용하지 않았다. Kubeflow 전체 배포판과 GitOps PR 프리뷰를 설치한 결과도 아니다.
시리즈 순서: Feast·MLflow·KFP 잇기 (모델·피처·배치 추론) → BentoML 서빙과 Evidently 드리프트 검증 → KFP v2 데이터 준비·검증 → 이 글, k3s 모델 검증 (Notebook·KServe 정합성 검사).
앞선 글들에서는 서울 자전거 데이터로 시차 피처를 만들고, MLflow에 모델을 등록하고, Feast로 피처를 조회하고, KFP로 미래 구간을 평가했다. 이어서 등록된 모델을 BentoML API로 서빙했고, 같은 UCI 원본의 데이터 준비를 별도의 KFP 파이프라인으로 실행했다. 이 글에는 이번 검증 Job에 필요한 선행 환경을 만드는 파일과 실행 명령을 본문에 실었다. 다른 글이나 코드 저장소를 열지 않아도 이 글의 실험용 파일을 구성할 수 있다. 이렇게 구성요소를 하나씩 확인하면 각각은 정상처럼 보인다. 그러나 한 가지 질문은 남는다.
지금 API가 반환하는 숫자는 어떤 원본 데이터로 훈련한 모델이 어느 시각의 피처를 받아 계산한 값인가?
KFP 데이터 준비 글과 이 글의 범위는 다르다. 그 글에서는 다운로드·검증·피처 생성·시간 분할·QA를 KFP의 서로 다른 Pod에서 실행하고, 단계별 Dataset 아티팩트가 SeaweedFS를 거쳐 전달되는지 확인했다. 이 글의 4.0절에 넣은 collect → features → train → infer → online은 Notebook·KServe 검증의 선행 환경을 만드는 일반 Kubernetes Job이다. KFP 데이터 준비 결과를 MLflow·Feast 훈련 입력으로 자동 승격시키는 연결은 아직 만들지 않았다. 따라서 이 글만으로 KFP 데이터 준비 실험까지 재현했다고 볼 수는 없다.
참고 저장소의 Part 2에서 가장 배울 만한 점은 이 질문을 시스템 경계마다 확인한다는 것이다. MLflow의 모델 별칭에서 출처 Run과 데이터 기록까지 거슬러 올라가고, Feast의 오프라인·온라인 값을 대조하고, 서빙 API 결과를 직접 추론값과 비교한다. 참고 저장소에는 KServe가 Ready인데도 훈련과 서빙의 라이브러리 차이로 예측값이 달라진 사례가 있다. 이 글에서는 같은 입력에 대해 직접 추론·BentoML·KServe가 같은 값을 내는지 Kubernetes Job으로 확인하고, Kubeflow Notebook에서 그 입력 데이터의 시간 규칙도 다시 검사했다.