다음을 통해 공유


MLflow 모델 로깅

이 문서에서는 학습된 모델(또는 아티팩트)을 MLflow 모델로 로그하는 방법을 설명합니다. MLflow에서 모델을 패키지하는 방법과 해당 모델을 실행하는 방법을 사용자 지정하는 다양한 방법을 살펴봅니다.

아티팩트 대신 모델을 로깅하는 이유는?

MLflow의 아티팩트에서 모델로는 로깅 MLflow 모델과 비교하여 아티팩트 또는 파일 로깅 간의 차이점을 설명합니다.

MLflow 모델도 아티팩트입니다. 그러나 해당 모델에는 모델을 만든 사람과 해당 모델을 사용하려는 사용자 간의 계약 역할을 하는 특정 구조가 있습니다. 이 계약은 아티팩트 자체와 해당 의미 사이를 연결하는 데 도움이 됩니다.

모델 로깅에는 다음과 같은 이점이 있습니다.

  • mlflow.<flavor>.load_model을 사용하여 유추를 위해 모델을 직접 로드할 수 있으며 predict 함수를 사용할 수 있습니다.
  • 파이프라인 입력은 모델을 직접 사용할 수 있습니다.
  • 채점 스크립트 또는 환경을 표시하지 않고 모델을 배포할 수 있습니다.
  • Swagger는 배포된 엔드포인트에서 자동으로 사용하도록 설정되며 Azure Machine Learning 스튜디오는 테스트 기능을 사용할 수 있습니다.
  • 책임 있는 AI 대시보드를 사용할 수 있습니다.

이 섹션에서는 MLflow를 사용하여 Azure Machine Learning에서 모델의 개념을 사용하는 방법을 설명합니다.

autolog를 사용하여 모델 로깅

MLflow 자동 로그 기능을 사용할 수 있습니다. 자동 로그를 사용하면 MLflow에서 프레임워크가 관련 있는 것으로 간주하는 모든 메트릭, 매개 변수, 아티팩트 및 모델을 로그하도록 프레임워크에 지시할 수 있습니다. 기본적으로 자동 로그를 사용하도록 설정하면 대부분의 모델이 기록됩니다. 경우에 따라 일부 버전이 모델을 로그하지 않을 수 있습니다. 예를 들어 PySpark 버전은 특정 크기를 초과하는 모델을 로그하지 않습니다.

mlflow.autolog() 또는 mlflow.<flavor>.autolog()를 사용하여 자동 로깅을 활성화합니다. 이 예제에서는 autolog()를 사용하여 XGBoost로 학습된 분류자 모델을 로그합니다.

import mlflow
from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score

mlflow.autolog()

model = XGBClassifier(use_label_encoder=False, eval_metric="logloss")
model.fit(X_train, y_train, eval_set=[(X_test, y_test)], verbose=False)

y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)

Machine Learning 파이프라인(예: Scikit-Learn 파이프라인)을 사용하는 경우 해당 파이프라인 버전의 autolog 기능을 사용하여 모델을 로그합니다. 모델 로깅은 파이프라인 개체에서 fit() 메서드를 호출할 때 자동으로 발생합니다. MLflow Notebook를 사용하여 XGBoost 분류자 학습 및 추적은 파이프라인을 사용하여 전처리로 모델을 로그하는 방법을 보여 줍니다.

사용자 지정 서명, 환경 또는 샘플을 사용하여 모델 로깅

MLflow mlflow.<flavor>.log_model 메서드는 모델을 수동으로 로그할 수 있습니다. 이 워크플로는 모델 로깅의 다양한 측면을 제어할 수 있습니다.

이 방법을 사용하는 경우는 다음과 같습니다.

  • pip 패키지 또는 자동으로 검색되는 환경과 다른 conda 환경을 나타내려고 합니다.
  • 입력 예제를 포함하려고 합니다.
  • 필요한 패키지에 특정 아티팩트를 포함하려고 합니다.
  • autolog에서 서명을 올바르게 유추하지 않습니다. 이는 서명에 특정 셰이프가 필요한 텐서 입력을 처리할 때 중요합니다.
  • 자동 로그 동작은 어떤 이유로 사용자의 용도를 다루지 않습니다.

이 코드 예제에서는 XGBoost 분류자용 모델을 로그합니다.

import mlflow
from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score
from mlflow.models import infer_signature
from mlflow.utils.environment import _mlflow_conda_env

mlflow.autolog(log_models=False)

model = XGBClassifier(use_label_encoder=False, eval_metric="logloss")
model.fit(X_train, y_train, eval_set=[(X_test, y_test)], verbose=False)
y_pred = model.predict(X_test)

accuracy = accuracy_score(y_test, y_pred)

# Signature
signature = infer_signature(X_test, y_test)

# Conda environment
custom_env =_mlflow_conda_env(
    additional_conda_deps=None,
    additional_pip_deps=["xgboost==1.5.2"],
    additional_conda_channels=None,
)

# Sample
input_example = X_train.sample(n=1)

# Log the model manually
mlflow.xgboost.log_model(model, 
                         artifact_path="classifier", 
                         conda_env=custom_env,
                         signature=signature,
                         input_example=input_example)

참고 항목

  • autolog에는 log_models=False 구성이 있습니다. 이를 통해 자동 MLflow 모델 로깅이 방지됩니다. 자동 MLflow 모델 로깅은 수동 프로세스로 나중에 발생합니다.
  • infer_signature 메서드를 사용하여 입력 및 출력에서 직접 서명을 유추합니다.
  • mlflow.utils.environment._mlflow_conda_env 메서드는 MLflow SDK의 프라이빗 메서드입니다. 이 예제에서는 코드를 더 간단하게 만들지만 주의해서 사용합니다. 이는 향후 변경될 수 있습니다. 또는 YAML 정의를 Python 사전으로 수동으로 생성할 수 있습니다.

predict 메서드에서 다른 동작을 사용하여 모델 로깅

mlflow.autolog 또는 mlflow.<flavor>.log_model을 사용하여 모델을 로깅할 때 모델 버전에 따라 유추를 실행하는 방법과 모델이 반환하는 내용이 결정됩니다. MLflow는 predict 결과 생성에 대한 특정 동작을 적용하지 않습니다. 일부 시나리오에서는 모델이 실행되기 전과 후에 일부 전처리 또는 후처리를 수행할 수 있습니다.

이 경우 입력에서 출력으로 직접 이동하는 기계 학습 파이프라인을 구현합니다. 이 구현은 가능하고 때로는 성능을 향상시키는 것이 권장되지만 달성하기 어려울 수 있습니다. 이러한 경우 다음 섹션에서 설명한 대로 모델이 유추를 처리하는 방법을 사용자 지정하는 데 도움이 될 수 있습니다.

사용자 지정 모델 로깅

MLflow는 다음을 포함하여 많은 기계 학습 프레임워크를 지원합니다.

  • CatBoost
  • FastAI
  • h2o
  • Keras
  • LightGBM
  • MLeap
  • MXNet Gluon
  • ONNX
  • Prophet
  • PyTorch
  • Scikit-Learn
  • spaCy
  • Spark MLLib
  • statsmodels
  • TensorFlow
  • XGBoost

그러나 버전의 작동 방식을 변경하거나, MLflow에서 기본적으로 지원되지 않는 모델을 로그하거나, 다른 프레임워크의 여러 요소를 사용하는 모델을 로그해야 할 수 있습니다. 이러한 경우 사용자 지정 모델 버전을 만들어야 할 수 있습니다.

이 문제를 해결하기 위해 MLflow는 pyfunc 버전을 도입합니다(Python 함수부터 시작). 이 버전은 개체가 다음 두 가지 조건을 충족하는 한 모든 개체를 모델로 로그할 수 있습니다.

  • 메서드 predict 메서드를 구현합니다(최소한).
  • Python 개체는 mlflow.pyfunc.PythonModel에서 상속됩니다.

Scikit-learn API를 구현하는 직렬화 가능 모델은 Scikit-learn을 사용하여 모델을 빌드했는지 여부에 관계없이 Scikit-learn 버전을 사용하여 모델을 로그할 수 있습니다. 모델을 Pickle 형식으로 유지할 수 있고 개체에 predict()predict_proba() 메서드(최소한)가 있는 경우 mlflow.sklearn.log_model()을 사용하여 MLflow 실행 내에서 모델을 로그할 수 있습니다.

기존 모델 개체 주위에 래퍼를 만드는 경우 사용자 지정 모델에 대한 버전을 만드는 것이 가장 간단합니다. MLflow는 이를 직렬화하고 패키징합니다. Python 개체를 파일(일반적으로 Pickle 형식)로 파일 시스템에 저장할 수 있는 경우 이러한 개체를 직렬화할 수 있습니다. 런타임 시 개체는 해당 파일에서 구체화할 수 있습니다. 이를 통해 저장되었을 때 사용할 수 있는 모든 값, 속성 및 메서드가 복원됩니다.

이 방법을 사용하는 경우는 다음과 같습니다.

  • 모델을 Pickle 형식으로 직렬화할 수 있습니다.
  • 학습 직후와 마찬가지로 모델의 상태를 유지하려고 합니다.
  • predict 함수의 작동 방식을 사용자 지정하려고 합니다.

이 샘플 코드는 XGBoost로 만든 모델을 래핑하여 XGBoost 버전 기본 구현과 다르게 동작하도록 합니다. 클래스 대신 확률을 반환합니다.

from mlflow.pyfunc import PythonModel, PythonModelContext

class ModelWrapper(PythonModel):
    def __init__(self, model):
        self._model = model

    def predict(self, context: PythonModelContext, data):
        # You don't have to keep the semantic meaning of `predict`. You can use here model.recommend(), model.forecast(), etc
        return self._model.predict_proba(data)

    # You can even add extra functions if you need to. Since the model is serialized,
    # all of them will be available when you load your model back.
    def predict_batch(self, data):
        pass

실행 시의 사용자 지정 모델을 로그합니다.

import mlflow
from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score
from mlflow.models import infer_signature

mlflow.xgboost.autolog(log_models=False)

model = XGBClassifier(use_label_encoder=False, eval_metric="logloss")
model.fit(X_train, y_train, eval_set=[(X_test, y_test)], verbose=False)
y_probs = model.predict_proba(X_test)

accuracy = accuracy_score(y_test, y_probs.argmax(axis=1))
mlflow.log_metric("accuracy", accuracy)

signature = infer_signature(X_test, y_probs)
mlflow.pyfunc.log_model("classifier", 
                        python_model=ModelWrapper(model),
                        signature=signature)

여기서 infer_signature 메서드는 y_probs를 사용하여 서명을 유추합니다. 대상 열에는 대상 클래스가 있지만, 이제 모델에서 각 클래스에 대해 두 개의 확률을 반환합니다.

다음 단계