Использование класса Environment с прогонами конвейера - PullRequest
1 голос
/ 08 октября 2019

Я использую шаг оценки для конвейера, использующего класс Environment, для того, чтобы иметь собственный образ Docker, так как мне нужно несколько пакетов apt-get, чтобы иметь возможность установить конкретный пакет pip. Из журналов видно, что он полностью игнорирует, в отличие от неконвейерной версии оценщика, докерскую часть переменной среды. Очень просто, это выглядит не так:

Я работаю на SDK v1.0.65, и мой dockerfile полностью игнорируется, я использую

FROM mcr.microsoft.com/azureml/base:latest\nRUN apt-get update && apt-get -y install freetds-dev freetds-bin vim gcc

в свойстве base_dockerfile моего кода,Вот фрагмент моего кода:

from azureml.core import Environment
from azureml.core.environment import CondaDependencies
conda_dep = CondaDependencies()
conda_dep.add_pip_package('pymssql==2.1.1')
myenv = Environment(name="mssqlenv")
myenv.python.conda_dependencies=conda_dep
myenv.docker.enabled = True
myenv.docker.base_dockerfile = 'FROM mcr.microsoft.com/azureml/base:latest\nRUN apt-get update && apt-get -y install freetds-dev freetds-bin vim gcc'
myenv.docker.base_image = None

Это хорошо работает, когда я использую Оценщик сам по себе, но если я вставляю этот оценщик в Конвейер, он терпит неудачу. Вот мой код для запуска его из прогона конвейера:

from azureml.pipeline.steps import EstimatorStep

sql_est_step = EstimatorStep(name="sql_step", 
                         estimator=est, 
                         estimator_entry_script_arguments=[],
                         runconfig_pipeline_params=None, 
                         compute_target=cpu_cluster)
from azureml.pipeline.core import Pipeline
from azureml.core import Experiment
pipeline = Pipeline(workspace=ws, steps=[sql_est_step])
pipeline_run = exp.submit(pipeline)

При запуске этого журнала журналы для службы построения контейнеров показывают:

FROM continuumio/miniconda3:4.4.10... etc.

Что означает, что он игнорирует мой FROM mcr....оператор в классе Environment, который я связал с этим Оценщиком, и мой pip install не выполняется.

Я что-то упустил? Есть ли обходной путь?

Ответы [ 3 ]

2 голосов
/ 10 октября 2019

Я могу подтвердить, что это ошибка на стороне конвейера AML. В частности, свойство runconfig environment.docker.base_dockerfile не проходит правильно в конвейерных заданиях. Мы работаем над исправлением. Тем временем вы можете использовать обходной путь из этого потока, чтобы сначала создать образ докера и указать его с помощью environment.docker.base_image (которое передается правильно).

2 голосов
/ 09 октября 2019

На данный момент я нашел обходной путь, который заключается в создании собственного образа Docker. Это можно сделать с помощью следующих параметров DockerSection of the Environment:

myenv.docker.base_image_registry.address = '<your_acr>.azurecr.io'
myenv.docker.base_image_registry.username = '<your_acr>'
myenv.docker.base_image_registry.password = '<your_acr_password>'
myenv.docker.base_image = '<your_acr>.azurecr.io/testimg:latest'

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

Чтобы создать образ, вы должны запустить что-то вроде этого в командной строке машины, которая может создать контейнер на основе Linux (например, ВМ для ноутбука):

docker build . -t <your_image_name>
# Tag it for upload
docker tag <your_image_name:latest <your_acr>.azurecr.io/<your_image_name>:latest
# Login to Azure
az login
# login to the container registry so that the push will work
az acr login --name <your_acr>
# push the image
docker push <your_acr>.azurecr.io/<your_image_name>:latest

После того, как изображение будет передано, выдолжен быть в состоянии заставить это работать.

0 голосов
/ 09 октября 2019

Я также изначально использовал EstimatorStep для пользовательских изображений, но недавно выяснил, как успешно передать Environment сначала RunConfiguration, а затем PythonScriptStep. (пример ниже)

Еще один обходной путь, похожий на ваш обходной путь, заключается в публикации вашего пользовательского образа докера в Docker-концентраторе, тогда параметр docker_base_image становится URI, в нашем случае mmlspark:0.16.

def get_environment(env_name, yml_path, user_managed_dependencies, enable_docker, docker_base_image):
    env = Environment(env_name)
    cd = CondaDependencies(yml_path)
    env.python.conda_dependencies = cd
    env.python.user_managed_dependencies = user_managed_dependencies
    env.docker.enabled = enable_docker
    env.docker.base_image = docker_base_image
    return env


spark_env = f.get_environment(env_name='spark_env',
                              yml_path=os.path.join(os.getcwd(), 'compute/aml_config/spark_compute_dependencies.yml'),
                              user_managed_dependencies=False, enable_docker=True,
                              docker_base_image='microsoft/mmlspark:0.16')

# use pyspark framework
spark_run_config = RunConfiguration(framework="pyspark")
spark_run_config.environment = spark_env

roll_step = PythonScriptStep(
    name='rolling window',
    script_name='roll.py',
    arguments=['--input_dir', joined_data,
                '--output_dir', rolled_data,
                '--script_dir', ".",
                '--min_date', '2015-06-30',
                '--pct_rank', 'True'],
    compute_target=compute_target_spark,
    inputs=[joined_data],
    outputs=[rolled_data],
    runconfig=spark_run_config,
    source_directory=os.path.join(os.getcwd(), 'compute', 'roll'),
    allow_reuse=pipeline_reuse
)


Несколько других моментов (которые могут быть неправильными):

  • PythonScriptStep фактически является оберткой для ScriptRunConfig, которая принимает run_config в качестве аргумента
  • Estimator - это оболочка для ScriptRunConfig, где настройки RunConfig доступны как параметры
  • IMHO EstimatorStep не должно существовать, потому что лучше определять Env и шаги отдельно, а не нав одно и то же время за один звонок.
...