MLOps c BentoML, MLflow и Kubeflow: автоматическое развертывание ML-модели

MLOPS Kubeflow MLflow CI CD BentoML Yatai примеры курсы обучение, MLflow примеры курсы обучение, курсы MLOps MLFlow Machine Learning DevOps Для дата-инженеров, MLFlow MLOps, обучение инженеров Machine Learning, Школа Больших Данных Учебный Центр Коммерсант

Чтобы сделать наши курсы для DevOps-инженеров и специалистов по Machine Learning еще более полезными, сегодня рассмотрим, как автоматизировать развертывание и обслуживание ML-моделей согласно концепции MLOps с помощью GitLab CI/CD, BentoML, Yatai, MLflow и Kubeflow.

BentoML для CI в MLOPS

При развертывании ML-модели необходимо учитывать следующие аспекты:

  • как была построена модель и что влияет на ее обслуживание;
  • как будет использоваться обслуживаемая модель;
  • как масштабировать рабочие нагрузки;
  • как контролировать сервис и реализовать логирование;
  • как модель может быть переобучена и автоматически развернута.

Концепция MLOps предполагает целостное решение всех этих вопросов через использование специальных открытых и проприетаных инструментов, которые позволяют выстроить сквозной конвейер разработки, оразвертывания и поддержки эксплуатации системы машинного обучения. К таким инструментам относятся  Kubeflow, MLflow и BentoML. О том, что представляет собой Kubeflow и MLflow, мы писали здесь.

А BentoML – это открытая библиотека для быстрого создания MVP систем машинного обучения. Она упрощает создание API методов для доступа к обученной ML-модели и совместима со всеми крупными фреймворками: Tensorflow, Keras, PyTorch, XGBoost, scikit-learn и fastai. BentoML поддерживает адаптивную микропакетную обработку данных, а также предоставляет функции управления моделью и ее развертывания. Поэтому BentoML отлично реализует идеи MLOps, позволяя разработчикам моделей машинного обучения использовать лучшие практики DevOps.

Специалисты по Data Science и инженеры Machine Learning используют BentoML для ускорения и стандартизации процесса запуска моделей в производство, позволяя создавать масштабируемые и высокопроизводительные ML-сервисы. Библиотека поддерживает непрерывное развертывание, мониторинг и сопровождение сервисов в производственной среде.

Впрочем, перед автоматизированным развертыванием модели необходимо автоматизировать ее обучение. Это можно сделать, реализовав конвейер с использованием Kubeflow, что гарантирует повторяемость и воспроизводимость обучения ML-модели. Как только модель успешно обучена, она регистрируется в реестре моделей с помощью MLFlow. Также автоматически регистрируются такие показатели работы ML-модели, в частности, точность. Благодаря регистрации модели в реестре MLflow к ней можно будет обратиться по уникальному URL-адресу, например:

model = mlflow.sklearn.load_model(f"runs:/{run_id}/model")

Здесь run_id — это уникальный идентификатор, к примеру, 8aa4630a023c4e94b22c6e738127ee7a. Он будет передаваться в инструмент непрерывного развертывания (CI, Continuous Integration), который запускается после успешного обучения модели. Используя GitLab CI/CD, можно запустить задание CI с помощью инструмента командной строки curl, передав HTTP-методом POST идентификатор запуска MLflow в качестве переменной среды при выполнении задания:

curl --request POST \
  --form token=<token> \
  --form ref=<branch> \
  --form "variables[MLFLOW_RUN_ID]=8aa4630a023c4e94b22c6e738127ee7a" \
  "https://gitlab.com/api/v4/projects/<project-id>/trigger/pipeline"

Это можно быстро превратить в код Python используя один из многочисленных конвертеров, например, https://curlconverter.com/, чтобы быстро создать компонент Kubeflow:

def trigger_ci(mlflow_run_id: str, branch: str = "main"):  
    import requests  
  
    files = {  
        "token": (None, "your-token-here"),  
    "ref": (None, branch),  
    "variables[MLFLOW_RUN_ID]": (None, mlflow_run_id),  
  }  
  
    response = requests.post(  
        "https://gitlab.com/api/v4/projects/project-id/trigger/pipeline", files=files  
    )  
  
    return response.text

Чтобы развернуть ML-модель, упакованную в RESTfull API решение с помощью BentoML, в Kubernetes, можно воспользоваться сервисом Yatai, который обеспечивает развертывание, сопровождение и масштабирование BentoML-решений в Kubernetes. Как это сделать, рассмотрим далее.

Автоматизация развертывания Bento-службы в Yatai

Следующий YAML-файл .gitlabci.yml содержит все необходимые команды BentoML:

bentoml-build-and-push:  
  image: "python:3.8"  
  stage: bentoml  
  script:  
    - apt-get update -y  
    - apt-get install -y jq  
    - pip install --upgrade pip  
    - pip install -r $CI_PROJECT_DIR/bento/requirements.txt  
    - export BENTO_MODEL="aml-case"  
    - python $CI_PROJECT_DIR/bento/save_model_to_bentoml.py --model_name ${BENTO_MODEL} --run_id $MLFLOW_RUN_ID  
    - bentoml build -f $CI_PROJECT_DIR/bento/bentofile.yaml  
    - bentoml yatai login --api-token $YATAI_API_TOKEN --endpoint http://yatai.yatai-system.svc.cluster.local  
    - export BENTO_DEPLOYMENT_NAME="${BENTO_MODEL}-${CI_COMMIT_SHORT_SHA}"  
    - bentoml push ${BENTO_MODEL}  
    - export BENTO_MODEL_AND_TAG=`bentoml list ${BENTO_MODEL} -o json | jq '.[0]["tag"]'`  
    - cp $CI_PROJECT_DIR/bento/deployment.yaml ./deployment.yaml  
    - 'sed -i "s/BENTO_MODEL_AND_TAG/$BENTO_MODEL_AND_TAG/g" ./deployment.yaml'  
    - 'sed -i "s/BENTO_DEPLOYMENT_NAME/$BENTO_DEPLOYMENT_NAME/g" ./deployment.yaml'  
    - 'sed -i "s/BENTO_MODEL/$BENTO_MODEL/g" ./deployment.yaml'  
  artifacts:  
    paths:  
      - deployment.yaml  
  only:  
    - triggers  
  
  
bentoml-deploy:  
  image: bitnami/kubectl:latest  
  stage: bentoml  
  script:  
    - kubectl create -f deployment.yaml  
  needs: ["bentoml-build-and-push"]  
  only:  
    - triggers

Первые четыре команды устанавливают jq, необходимый для работы с JSON, и зависимости для службы BentoML, включая scikit-learn и MLflow. Команда save_model_to_bentoml.py сохраняет ML-модель, с указанием ее имени и идентификатором run_id, который ранее передавался при ручном запуске CI. Код регистрации модели в реестре BentoML выглядит следующим образом:

def main(model_name: str, run_id: str):  
    model = mlflow.sklearn.load_model(f"runs:/{run_id}/model")  
  
    saved_model = bentoml.picklable_model.save_model(  
        name=model_name, model=model, signatures={"predict_proba": {"batchable": True}}  
    )  
 
    runner = bentoml.picklable_model.get(f"{model_name}:latest").to_runner()  
    runner.init_local()  
  
    EXAMPLE_INPUT = np.random.rand(4, 24)  
    data = pd.DataFrame(EXAMPLE_INPUT)  
    predicted_probs = [x[1] for x in model.predict_proba(data)]  
    
    print(predicted_probs)  
 
if __name__ == "__main__":  
    parser = argparse.ArgumentParser()  
    parser.add_argument("--model_name")  
    parser.add_argument("--run_id")  
    args = parser.parse_args()  
    main(model_name=args.model_name, run_id=args.run_id)

Первые две строки этого скрипта загружают модель из MLflow, используя идентификатор run_id, а затем сохраняют ее в реестре моделей BentoML с ранее переданным именем. После того, как модель зарегистрирована в реестре BentoML, можно начать создание службы Bento. Остальная часть скрипта выполняет проверку работоспособности, удостоверяясь, что загруженная модель в BentoML может работать с некоторыми случайными входными данными. YAML-файл службы Bento довольно прост:

model = mlflow.sklearn.load_model(f"runs:/{run_id}/model")  
  
saved_model = bentoml.picklable_model.save_model(  
    name=model_name, 
    model=model, 
    signatures={"predict_proba": {"batchable": True}})

Команда bentoml build -f $CI_PROJECT_DIR/bento/bentofile.yaml создает службу Bento, которая упаковывает все в единый артефакт, чтобы использовать его для развертывания ML-модели. Сервис Yatai играет роль центрального хранилища Bento-моделей. Перед развертыванием в Yatai, нужно войти в кластер с токеном API:

bentoml yatai login --api-token $YATAI_API_TOKEN --endpoint http://yatai.yatai-system.svc.cluster.local

И выполнить команду проталкивания Bento-службы в Yatai:

bentoml push ${BENTO_MODEL}

В случае успеха Yatai приступит к контейнеризации Bento, а пока это происходит, можно подготовить развертывание Bento, подготовив YAML-файл deployment.yaml:

apiVersion: serving.yatai.ai/v1alpha2  
kind: BentoDeployment  
metadata:  
  name: BENTO_DEPLOYMENT_NAME  
  namespace: ds-models  
spec:  
  bento_tag: BENTO_MODEL_AND_TAG  
  ingress:  
    enabled: true  
  resources:  
    limits:  
        cpu: "1"  
  memory: "1Gi"  
  requests:  
        cpu: "500m"  
  memory: "512m"  
  runners:  
  - name: BENTO_MODEL  
    resources:  
      limits:  
        cpu: "1"  
  memory: "1Gi"  
  requests:  
        cpu: "500m"  
  memory: "512m"

Чтобы упростить управление развертываниями, их можно называть по имени ML-модели и версии Git. Это позволит сопоставить, какое развертывание было получено из какой фиксации Git. Затем следует создать образ Docker, который будет использовать Bento-развертывание с нужными sed и jq:

export BENTO_DEPLOYMENT_NAME="${BENTO_MODEL}-${CI_COMMIT_SHORT_SHA}"  
export BENTO_MODEL_AND_TAG=`bentoml list ${BENTO_MODEL} -o json | jq '.[0]["tag"]'`  
cp $CI_PROJECT_DIR/bento/deployment.yaml ./deployment.yaml  
'sed -i "s/BENTO_MODEL_AND_TAG/$BENTO_MODEL_AND_TAG/g" ./deployment.yaml'  
'sed -i "s/BENTO_DEPLOYMENT_NAME/$BENTO_DEPLOYMENT_NAME/g" ./deployment.yaml'  
'sed -i "s/BENTO_MODEL/$BENTO_MODEL/g" ./deployment.yaml'

Команда cp $CI_PROJECT_DIR/bento/deployment.yaml ./deployment.yaml  создает копию файла deployment.yaml, который будет передаваться на следующий шаг CI-конвейера. Чтобы завершить развертывания Bento, осталось выполнить команду ее создания в kubectl:

bentoml-deploy:  
  image: bitnami/kubectl:latest  
  stage: bentoml  
  script:  
    - kubectl create -f deployment.yaml  
  needs: ["bentoml-build-and-push"]  
  only:  
    - triggers

По завершении развертывания оно отобразится в пользовательском интерфейсе Yatai, где также можно выполнять обслуживание, мониторинг и ведение журнала. При этом мониторинг и ведение журнала нужно сперва включить вручную:

BentoML Yatai MLOps
Развертывания служб Bento в GUI-интерфейсе Yatai

После этого каждая развертываемая вами модель будет сопровождаться мониторингом через Grafana и ведением журнала через Loki. А используя URL-адрес конечной точки развернутой ML-модели, можно перейти в веб-инструмент тестирования REST API Swagger, чтобы проверить ее работу:

Swagger BentoML Yatai MLOps
тестирование REST API модели машинного обучения в Swagger

В заключение отметим, что все рассмотренные MLOPS-инструменты также поддерживают переобучение моделей Machine Learning. В частности, можно просто запланировать периодический запуск конвейера Kubeflow по расписанию. Это позволит не ждать, пока сработают предупреждения об обнаружении дрейфа данных или модели, а начать ее переобучение, когда для этого будут доступны свежие данные. Для этого нужны метрики оценки, чтобы сравнить новые модели с теми, которые работают в производстве. Сделать это поможет компонент Trigger CI в GitLab. Альтернативой является простое переключение службы в Ingress на модель с наилучшей производительностью. Напомним, Ingress — объект API, который управляет внешним доступом к объектам Service в проекте Kubernetes, он идентифицирует маршруты HTTP и HTTPS из внешней среды для объектов Service проекта. Маршрутизация трафика контролируется правилами, определенными для ресурса Ingress.

Например, если имеется следующий вход:

apiVersion: networking.k8s.io/v1  
kind: Ingress  
metadata:  
  name: aml  
  namespace: ds-models  
spec:  
  rules:  
  - host: aml-case.ds-models.dev.jago.data  
    http:  
      paths:  
      - backend:  
          service:  
            name: "aml-123"  
            port:  
              number: 3000  
        path: /  
        pathType: ImplementationSpecific

Ingress указывает на службу aml-123, которую можно заменить на другую вручную или с помощью триггера CI.

Таким образом, Kubeflow, MLflow и BentoML с Yatai позволяют автоматизировать развертывание и переобучение модели Machine Learning в любой среде.

Как применять эти и другие современные инструменты MLOps в проектах аналитики больших данных, вы узнаете на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:

Я даю свое согласие на обработку персональных данных и соглашаюсь с политикой конфиденциальности.

Источники

  1. https://medium.com/dkatalis/automated-model-deployment-with-bentoml-and-kubeflow-3ac5bc0d1b3d
  2. https://www.bentoml.com/
  3. https://docs.gitlab.com/ee/ci/triggers/

Поиск по сайту