Библиотека машинного обучения Azure — отличный инструмент для создания конвейеров обучения и прогнозирования. Microsoft предлагает отличные руководства и множество примеров в своем git. Настоящая проблема начинается, когда возникает необходимость развернуть собственный конвейер машинного обучения в пользовательской среде. Существует множество способов создать среду машинного обучения Azure для конвейеров машинного обучения с помощью azureml Python SDK. Но не хватает руководств, описывающих использование и развертывание пользовательских сред. Кроме того, доступ к базе данных SQL необходим для любой обработки данных и моделирования. Поэтому эта настраиваемая среда включает установку библиотек ODBC, необходимых для подключения к базе данных SQL из скрипта Python.

В этой статье я сосредоточусь на:

  • создание среды с использованием файла Docker
  • развертывание пользовательской среды для пакетного вывода
  • развертывание пользовательской среды в веб-службе ACI

Все это будет достигнуто за счет использования инфраструктуры как кода.

Файл Docker с драйверами ODBC

Сначала я объясню этапы создания контейнерной среды с помощью Docker. Я объясню шаги, связанные с созданием этой среды, и расскажу о некоторых потенциальных ловушках, о которых следует знать, когда вы будете отлаживать свое развертывание.

Сила облачных сервисов в том, что они обеспечивают уровень абстракции, и вам не нужно (или не нужно) управлять всеми зависимостями. Чтобы воспользоваться этим преимуществом, я использую курируемую среду AzureML в качестве основы для этого образа Docker. Я выбрал с установленными библиотеками LightGBH, поскольку моя модель прогнозирования использует их. Кроме того, в этой курируемой среде используются Ubuntu 18.04 и Python 3.7. Так что этими зависимостями управляет Azure.

FROM mcr.microsoft.com/azureml/curated/lightgbm-3.2-ubuntu18.04-py37-cpu:45

Далее мы устанавливаем драйвер ODBC.

Если вы не укажете версию Ubuntu, Azure по умолчанию может использовать версию 16.04, которая больше не поддерживается, и ваш контейнер может случайно выйти из строя.

То же самое касается питона. Если не указано иное, Azure по умолчанию использует python 3.6 и устанавливает туда библиотеки Python. Итак, если вы получаете сообщение об ошибке, указанная вами библиотека в файле требований не существует. Проверьте, где действительно установлены ваши библиотеки Python. Поэтому я рекомендую использовать рекомендуемые среды в качестве базового изображения.

Вот некоторые из проблем, с которыми я столкнулся во время развертывания. Возможно, Microsoft устранит их в будущих обновлениях.

# apt-get and system utilities
RUN apt-get update && apt-get install -y \
   curl apt-transport-https debconf-utils gnupg2

RUN apt-get update && apt-get install -y --no-install-recommends \
    unixodbc-dev \
    unixodbc \
    libpq-dev

# adding custom MS repository
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/ubuntu/18.04/prod.list > /etc/apt/sources.list.d/mssql-release.list

# install SQL Server drivers and tools
RUN apt-get update && ACCEPT_EULA=Y apt-get install -y msodbcsql18 mssql-tools18
RUN echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc
RUN /bin/bash -c "source ~/.bashrc"


RUN apt-get -y install locales \
    && rm -rf /var/lib/apt/lists/*
RUN locale-gen en_US.UTF-8
RUN update-locale LANG=en_US.UTF-8

Следующий шаг указывает версию python и путь к нему. Некоторые из этих шагов могут показаться дубликатами, но я счел их необходимыми, чтобы избежать создания нескольких путей python и дополнительных требований, установленных Microsoft для python 3.6 по умолчанию.

RUN apt-get update && \
  apt-get install -y --no-install-recommends python3 python3.7-distutils && \
  ln -sf /usr/bin/python3 /usr/bin/python

Затем мы устанавливаем библиотеки Python, необходимые для запуска скрипта прогнозирования с использованием pip.

# install dependencies
RUN pip install --upgrade pip==20.1.1

WORKDIR /
COPY requirements.txt .
RUN pip install -r requirements.txt

Следующие команды — это просто проверки работоспособности, которые вы можете использовать для отладки развертывания контейнера, чтобы увидеть, какие библиотеки были действительно установлены.

RUN pip freeze
RUN conda --version
RUN python3 --version

Теперь, собрав все воедино, нажмите здесь, чтобы увидеть полный файл Dockerfile.

Развертывание Dockerfile в Реестре контейнеров Azure

Для этого шага вам потребуется настроить программный доступ для вашей учетной записи Azure. Если у вас его нет, вы можете прочитать о входе с помощью Azure CLI здесь.

Откройте свой терминал и перейдите в каталог, где находится ваш Dockefile. Войдите в свою учетную запись Azure. Это может открыть веб-браузер для аутентификации.

Вы можете создать свой образ в существующем контейнере или создать его. Подробнее о подсказках CLI реестра контейнеров здесь. Последние шаги создают образ из Dockerfile, указанного на предыдущем шаге.

az login
az acr create --resource-group myResourceGroup --name mycontainerregistry --sku Basic
az acr build --image myImageName:Version --registry mycontainerregistry --file Dockerfile .

Создание конфигурации запуска для Azure ML Pipeline

Чтобы использовать контейнерную среду, которую мы развернули на предыдущем шаге в Azure ML Pipelines, нам нужно создать конфигурацию запуска. В следующем скрипте используются переменные среды, которые передаются в скрипт либо из надежно сохраненного локального файла, либо из группы переменных Azure DevOps. Причина этого в том, что эти переменные содержат конфиденциальную информацию, такую ​​как имя пользователя и пароль. Из-за этого они никогда не должны быть частью скрипта по соображениям безопасности.

from azureml.core.runconfig import RunConfiguration
from azureml.core.container_registry import ContainerRegistry


sql_run_config = RunConfiguration()
image_registry_details = ContainerRegistry()
image_registry_details.address = f"{env_variables['IMAGE_USER_NAME']}.azurecr.io"
image_registry_details.username = env_variables['IMAGE_USER_NAME']
image_registry_details.password = env_variables['IMAGE_PWD']
sql_run_config.environment.docker.base_image_registry = image_registry_details

# this is an image in the image_registry
sql_run_config.environment.docker.base_image = env_variables['IMAGE_NAME']
sql_run_config.environment.python.user_managed_dependencies = True

Теперь мы можем передать эту конфигурацию запуска в конвейер машинного обучения Azure. Microsoft предлагает множество руководств по созданию конвейера машинного обучения Azure. Этот шаг довольно прост, и вы можете следовать руководствам Microsoft для полного развертывания, поэтому я не буду подробно рассказывать, как это сделать. Если вы хотите, чтобы я уточнил, пожалуйста, дайте мне знать в комментариях.

Pipeline_step = PythonScriptStep(name = ‘Step1’,
                                  source_directory = experiment_folder,
                                  script_name = "script.py",
                                  compute_target=inference_cluster,
                                  runconfig=sql_run_config,  # custom run configuration,
                                  allow_reuse=False)

Зарегистрируйте пользовательскую среду в Azure ML Worspace

Вы можете использовать Dockerfile, созданный на предыдущем шаге, для регистрации пользовательской среды в Azure ML Workspace с помощью библиотеки python azureml. Затем эту среду можно использовать для создания веб-службы с помощью библиотек azureml. В этом примере я покажу, как развернуть веб-службу как образ контейнера Azure. Обратите внимание, что это развертывание не рекомендуется для рабочих веб-служб машинного обучения из-за ограничений безопасности и отсутствия масштабируемости. Рекомендуемая служба — управляемая конечная точка в Интернете. Использование и развертывание пользовательской среды такое же, как и для веб-службы ACI. Управляемому онлайн-конечному устройству я бы хотел посвятить отдельный пост, так что пока вы можете прочитать об этом здесь.

Во-первых, вам необходимо подключиться к рабочей области Azure ML, где будет зарегистрирована среда.

ws = Workspace.from_config()

Если вы запускаете эти команды из рабочей области ML, эта команда будет использовать файл config.json для получения учетных данных. Вы можете загрузить этот файл для локального подключения к рабочей области или передать учетные данные напрямую. Опять же, из соображений безопасности я рекомендую надежно хранить эти учетные данные и не программировать их жестко.

myenv = Environment(name=env_name)
myenv.from_docker_image(env_name, image_name, container_registry=container_name)
myenv.register(ws)
myenv.build()

Я не рекомендую использовать команду myenv.from_dockerfile(), поскольку требования не устанавливаются в правильной версии Python. Это приводит к ошибке «модуль не найден» при развертывании веб-службы.

В следующем коде показано, как использовать пользовательскую среду для развертывания веб-службы машинного обучения с помощью ACI.

inference_config = InferenceConfig(
    entry_script='script.py',
    source_directory=source_directory,
    environment=myenv)

deployment_config = AciWebservice.deploy_configuration(cpu_cores=1.8,
                                                       memory_gb=7,
                                                       dns_name_label=os.environ['DNS_NAME'],
                                                       enable_app_insights=True)
service = Model.deploy(ws, os.environ['WEB_SERVICE_NAME'], [model], inference_config, deployment_config, overwrite=True)
service.wait_for_deployment(True)

В примере кода используются переменные среды, которые передавались сценарию локально или как часть группы переменных Azure DevOps.

Полный скрипт вы можете найти в моем git-репозитории.

Заключительные слова

Я надеюсь, что это руководство поможет инженерам машинного обучения в развертывании машинного обучения Azure. Я планирую опубликовать больше руководств, посвященных развертыванию Azure ML и созданию конвейеров CI/CD для служб ML в Azure DevOps. Я всегда предпочитаю подход «Инфраструктура как код» из-за его воспроизводимости. Если есть область, на которой вы хотели бы, чтобы я сосредоточился, пожалуйста, дайте мне знать в комментариях.