MLflow:Serving
MLflow 내장 서빙
- Serving Machine Learning Model. With MLFlow and Docker | by Xin Cheng | Medium
- MLFlow Serving
- MLflow Serving
MLflow가 자체적으로 제공하는 가장 단순하고 빠른 방법입니다. Local, Docker 환경에서 빠르게 서빙 환경을 구축할 때 유용합니다.
- 동작 방식:
mlflow models serve -m runs:/<run_id>/model -p 5000형태로 명령어를 실행하면, MLflow가 모델의 의존성(Conda/Pip 환경)을 자동으로 구성하고 Flask/FastAPI 기반의 REST API 서버를 띄워줍니다. - 장점: 코드가 거의 필요 없고, MLflow Tracking Server나 Model Registry와 바로 연동됩니다.
- 단점: 고가용성(HA), 오토스케일링, 복잡한 라우팅 등을 직접 구현해야 하므로 대규모 운영 환경(Production)에는 단독으로 쓰기 무겁습니다.
- 추천: PoC(개념 검증), 사내 데모, 또는 트래픽이 적은 내부 서비스용.
MLflow 내장 Docker 빌드 + Container 배포 (가장 추천)
MLflow 내장 서빙 기능을 Docker 이미지로 패키징하여, 기존에 가지고 있는 가벼운 컨테이너 오케스트레이션 시스템에 올리는 방식입니다.
- 동작 방식:
mlflow models build-docker명령어를 사용하면, MLflow가 모델과 실행 환경이 포함된 무결한 Docker 이미지를 빌드해 줍니다. 이 이미지를 AWS ECS, Google Cloud Run, 혹은 가벼운 단일 VM의 Docker Compose 상에 배포합니다. - 장점: KServe처럼 복잡한 K8s 인프라(Istio, Cert-Manager 등)가 필요 없고, Cloud Provider가 제공하는 가벼운 컨테이너 서비스의 오토스케일링과 로드 밸런싱을 그대로 활용할 수 있습니다.
- 추천: K8s 관리 부담을 줄이면서도 운영 환경의 안정성을 확보하고 싶을 때.
입력 데이터 전달 방식
핵심 요약: MLflow 서버(mlflow models serve)는 이미지/텍스트/오디오를 구분하지 않는다. 클라이언트는 항상 JSON 직렬화 가능한 형태(숫자 배열 또는 base64 문자열)로 데이터를 변환해서 보내야 하며, "이게 이미지다"라는 해석은 전적으로 pyfunc.PythonModel.predict() 내부 로직에 달려 있다.
1. Model Signature가 입력 형식을 정의
MLflow 모델은 저장 시 signature(입력/출력 스키마)를 함께 저장한다. 이 signature가 /invocations 요청의 JSON 스키마를 결정한다.
import mlflow
from mlflow.models.signature import infer_signature
# 학습 시 signature 추론 및 저장 / infer and log signature at training time
signature = infer_signature(train_x, model.predict(train_x))
mlflow.pyfunc.log_model(
artifact_path="model",
python_model=my_model,
signature=signature
)
2. 요청 JSON 포맷 (모델 타입 무관 공통 3종)
방식 1: dataframe_split (컬럼 기반, tabular 모델에 흔함)
방식 2: instances (tensor 기반, 이미지 등에 흔함)
방식 3: inputs (단순 배열)
3. 모달리티별 실제 처리 방식
이미지
(a) 클라이언트에서 numpy array로 변환 후 전송
import numpy as np
from PIL import Image
img = np.array(Image.open("photo.jpg").resize((224, 224))) / 255.0
payload = {"inputs": img.tolist()} # shape: (224, 224, 3) -> JSON list
(b) 모델 pyfunc wrapper 안에서 base64 디코딩 처리 (권장 방식)
import base64
from io import BytesIO
from PIL import Image
class ImageModel(mlflow.pyfunc.PythonModel):
def predict(self, context, model_input):
# model_input은 base64 문자열 컬럼을 가진 DataFrame
images = []
for b64_str in model_input["image_base64"]:
img_bytes = base64.b64decode(b64_str)
img = Image.open(BytesIO(img_bytes))
images.append(preprocess(img))
return self.model.predict(images)
요청 예시:
import base64
import requests
with open("photo.jpg", "rb") as f:
b64_img = base64.b64encode(f.read()).decode("utf-8")
requests.post(
"http://localhost:5000/invocations",
json={"dataframe_split": {"columns": ["image_base64"], "data": [[b64_img]]}}
)
텍스트
가장 간단하다. 문자열 배열 그대로 전달하고, tokenizing은 pyfunc wrapper 내부에서 처리한다.
오디오
이미지와 마찬가지로 base64 인코딩이 일반적이며, wrapper 내부에서 librosa 등으로 디코딩한다.
{
"dataframe_split": {
"columns": ["audio_base64", "sample_rate"],
"data": [["<base64 encoded wav bytes>", 16000]]
}
}
4. 핵심 정리
| 요소 | 역할 |
| Signature | |
| | JSON 페이로드 형식 3종 |
| pyfunc wrapper ( | 실제 전처리(base64 디코딩, resize, tokenize 등)를 담당하는 곳 |
5. Signature 확인 방법
# 배포된 모델의 signature 확인 / check signature of deployed model
mlflow models predict -m "models:/my_model/1" --env-manager conda --input-path input.json
또는 MLflow Model Registry UI/API에서 model.metadata.signature를 조회하여 확인 가능하다.
6. 주의사항: Point Cloud / 3D 데이터
Point cloud처럼 큰 3D array를 입력으로 쓰는 모델(예: welding QC PTv3/Pointcept)은 이 방식이 까다로울 수 있다. 3D array를 JSON으로 직렬화하면 payload 크기가 커지고 속도가 느려지므로, 이런 경우에는 gRPC나 별도의 바이너리 프로토콜 사용을 고려하는 것이 낫다.