Поделиться через


Отладка скриптов оценки с помощью HTTP-сервера вывода машинного обучения Azure

Машинное обучение Azure http-сервер вывода — это пакет Python, который предоставляет функцию оценки как конечную точку HTTP и упаковывает код и зависимости сервера Flask в единый пакет. Сервер вывода включается в предварительно созданные образы Docker для вывода , которые используются при развертывании модели в Машинном обучении Azure. При использовании пакета можно развернуть модель локально для производства. Вы также можете легко протестировать свой скрипт для оценки в локальной среде разработки. Если с скриптом оценки возникла проблема, сервер вывода возвращает ошибку и расположение ошибки.

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

Эта статья предназначена для разработчиков, которые хотят использовать сервер обоснования для локальной отладки. В этой статье показано, как использовать сервер вывода с сетевыми конечными точками.

Необходимые компоненты

  • Python 3.8 или более поздней версии
  • Анаконда

Сервер вывода работает в операционных системах под управлением Windows и Linux.

Изучение параметров локальной отладки для сетевых конечных точек

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

В следующей таблице представлен обзор поддержки, которую предлагает каждый вариант для различных сценариев отладки:

Сценарий Сервер инференса Локальная конечная точка
Обновление локальной среды Python без перестроения образа Docker Да Нет
Обновление сценария оценки Да Да
Обновление конфигураций развертывания (развертывание, среда, код, модель) Нет Да
Интеграция отладчика Microsoft Visual Studio Code (VS Code) Да Да

В этой статье описывается, как использовать сервер вывода.

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

Отладка скрипта оценки локально

Для локальной отладки скрипта оценки существует несколько вариантов тестирования поведения сервера вывода:

В следующих разделах содержатся сведения о каждом варианте.

Используйте тестовый скрипт оценки для проверки поведения сервера вывода заключений

  1. Создайте каталог с именем server_quickstart для хранения файлов:

    mkdir server_quickstart
    cd server_quickstart
    
  2. Чтобы избежать конфликтов пакетов, создайте виртуальную среду, например myenvи активируйте ее:

    python -m virtualenv myenv
    

    Примечание.

    В Linux выполните source myenv/bin/activate команду, чтобы активировать виртуальную среду.

    После тестирования сервера вывода можно выполнить deactivate команду, чтобы отключить виртуальную среду Python.

  3. Установите azureml-inference-server-http пакет из репозитория индекса пакетов Python (PyPI):

    python -m pip install azureml-inference-server-http
    
  4. Создайте скрипт записи. В следующем примере создается базовый скрипт записи и сохраняется в файл с именем score.py:

    echo -e 'import time\ndef init(): \n\ttime.sleep(1) \n\ndef run(input_data): \n\treturn {"message":"Hello, World!"}' > score.py
    
  5. Используйте команду azmlinfsrv, чтобы запустить сервер вывода данных и задать файл score.py в качестве скрипта входа.

    azmlinfsrv --entry_script score.py
    

    Примечание.

    Сервер выводов размещён на IP-адресе 0.0.0.0, что означает, что он прослушивает все IP-адреса хост-компьютера.

  6. curl Используйте программу для отправки запроса оценки на сервер вывода:

    curl -p 127.0.0.1:5001/score
    

    Сервер вывода отправляет следующий ответ:

    {"message": "Hello, World!"}
    
  7. После завершения тестирования нажмите клавиши CTRL+C , чтобы остановить сервер вывода.

Вы можете изменить файл скрипта оценки score.py. Затем вы можете протестировать изменения с помощью azmlinfsrv --entry_script score.py команды, чтобы снова запустить сервер вывода.

Интеграция с VS Code

В VS Code можно использовать расширение Python для отладки с пакетом azureml-inference-server-http . VS Code предлагает два режима отладки: запуск и подключение.

Перед использованием любого режима установите azureml-inference-server-http пакет, выполнив следующую команду:

python -m pip install azureml-inference-server-http

Примечание.

Чтобы избежать конфликтов пакетов, установите сервер вывода в виртуальной среде. Вы можете использовать pip install virtualenv команду для включения виртуальных сред для конфигурации.

Режим запуска

Для режима запуска выполните следующие действия, чтобы настроить файл конфигурации VS Code launch.json и запустить сервер вывода в VS Code:

  1. Запустите VS Code и откройте папку, содержащую скрипт score.py.

  2. Для этой рабочей области в VS Code добавьте следующую конфигурацию в файл launch.json:

    {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "Debug score.py",
                "type": "debugpy",
                "request": "launch",
                "module": "azureml_inference_server_http.amlserver",
                "args": [
                    "--entry_script",
                    "score.py"
                ]
            }
        ]
      }
    
  3. Запустите сеанс отладки в VS Code, выбрав запустить запуск>отладки или выбрав F5.

Режим подключения

Для режима подключения выполните следующие действия, чтобы использовать VS Code с расширением Python для подключения к процессу сервера вывода:

Примечание.

Для Linux сначала установите gdb пакет, выполнив sudo apt-get install -y gdb команду.

  1. Запустите VS Code и откройте папку, содержащую скрипт score.py.

  2. Для этой рабочей области в VS Code добавьте следующую конфигурацию в файл launch.json:

    {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "Python: Attach using Process ID",
                "type": "debugpy",
                "request": "attach",
                "processId": "${command:pickProcess}",
                "justMyCode": true
            }
        ]
      }
    
  3. В командном окне запустите сервер вывода, выполнив azmlinfsrv --entry_script score.py команду.

  4. Выполните следующие действия, чтобы запустить сеанс отладки в VS Code:

    1. Выберите "Запустить запуск отладки>" или нажмите клавишу F5.

    2. В командном окне выполните поиск журналов с сервера вывода инференса, чтобы найти идентификатор процесса azmlinfsrv.

      Снимок окна командной строки, в котором показаны журналы сервера вывода выводов. В одной записи журнала выделен идентификатор процесса команды azmlinfsrv.

      Не забудьте найти идентификатор azmlinfsrv процесса, а не gunicorn процесса.

    3. В отладчике VS Code введите идентификатор azmlinfsrv процесса.

      Если вы не видите диспетчер процессов VS Code, вручную введите идентификатор процесса в поле processId файла launch.json для рабочей области.

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

Использование комплексного примера

Следующая процедура выполняет сервер вывода результатов локально с образцами файлов из репозитория примеров Azure Machine Learning. Примеры файлов включают скрипт оценки, файл модели и файл среды. Дополнительные примеры использования этих примеров файлов см. в статье "Развертывание и оценка модели машинного обучения с помощью сетевой конечной точки".

  1. Клонируйте пример репозитория и перейдите в папку, содержащую соответствующие примеры файлов:

    git clone --depth 1 https://github.com/Azure/azureml-examples
    cd azureml-examples/cli/endpoints/online/model-1/
    
  2. Используйте conda для создания и активации виртуальной среды:

    В этом примере azureml-inference-server-http пакет устанавливается автоматически. Пакет включается в качестве зависимой библиотеки azureml-defaults пакета, которая указана в файле conda.yaml.

    # Create the environment from the YAML file.
    conda env create --name model-env -f ./environment/conda.yaml
    # Activate the new environment.
    conda activate model-env
    
  3. Просмотрите скрипт оценки, onlinescoring/score.py:

    import os
    import logging
    import json
    import numpy
    import joblib
    
    
    def init():
        """
        This function is called when the container is initialized/started, typically after create/update of the deployment.
        You can write the logic here to perform init operations like caching the model in memory
        """
        global model
        # AZUREML_MODEL_DIR is an environment variable created during deployment.
        # It is the path to the model folder (./azureml-models/$MODEL_NAME/$VERSION)
        # Please provide your model's folder name if there is one
        model_path = os.path.join(
            os.getenv("AZUREML_MODEL_DIR"), "model/sklearn_regression_model.pkl"
        )
        # deserialize the model file back into a sklearn model
        model = joblib.load(model_path)
        logging.info("Init complete")
    
    
    def run(raw_data):
        """
        This function is called for every invocation of the endpoint to perform the actual scoring/prediction.
        In the example we extract the data from the json input and call the scikit-learn model's predict()
        method and return the result back
        """
        logging.info("model 1: request received")
        data = json.loads(raw_data)["data"]
        data = numpy.array(data)
        result = model.predict(data)
        logging.info("Request processed")
        return result.tolist()
    
  4. Запустите сервер вывода, указав скрипт оценки и путь к папке модели.

    Во время развертывания AZUREML_MODEL_DIR переменная определяется для хранения пути к папке модели. Укажите это значение в параметре model_dir . При запуске скрипта оценки он извлекает значение из переменной AZUREML_MODEL_DIR .

    В этом случае используйте текущий каталог ./ в качестве значения, потому что скрипт оценки model_dir указывает подкаталог как model/sklearn_regression_model.pkl.

    azmlinfsrv --entry_script ./onlinescoring/score.py --model_dir ./
    

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

  5. Протестируйте скрипт оценки с примерами данных, выполнив следующие действия.

    1. Откройте другое командное окно и перейдите в тот же рабочий каталог, в который вы выполнили azmlinfsrv команду.

    2. Используйте следующую curl служебную программу для отправки примера запроса на сервер вывода и получения результата оценки:

      curl --request POST "127.0.0.1:5001/score" --header "Content-Type:application/json" --data @sample-request.json
      

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

Проверка маршрутов сервера инференса

Сервер вывода прослушивает порт 5001 по умолчанию по следующим маршрутам:

Имя. Маршрут
Проверка активности 127.0.0.1:5001/
Балл 127.0.0.1:5001/score
OpenAPI (swagger) 127.0.0.1:5001/swagger.json

Проверка параметров сервера инференции

Сервер вывода принимает следующие параметры:

Параметр Обязательное поле По умолчанию. Описание:
entry_script Истина Н/П Определяет относительный или абсолютный путь к скрипту оценки
model_dir Неправда Н/П Определяет относительный или абсолютный путь к каталогу, в котором содержится модель, используемая для вывода
port Неправда 5001 Указывает обслуживающий порт сервера вывода
worker_count Неправда 1 Предоставляет количество рабочих потоков для обработки одновременных запросов
appinsights_instrumentation_key Неправда Н/П Предоставляет ключ инструментирования для экземпляра Application Insights, в котором публикуются журналы.
access_control_allow_origins Неправда Н/П Включает совместное использование ресурсов между источниками (CORS) для указанных источников, где несколько источников разделены запятыми (,), например microsoft.com, bing.com

Изучение обработки запросов инференс-сервера

Ниже показано, как сервер вывода обрабатывает azmlinfsrvвходящие запросы:

  1. Оболочка интерфейса командной строки Python находится вокруг сетевого стека сервера вывода и используется для запуска сервера вывода.

  2. Клиент отправляет запрос серверу вывода.

  3. Сервер вывода отправляет запрос через сервер интерфейса шлюза веб-сервера (WSGI), который отправляет запрос одному из следующих рабочих приложений Flask:

  4. Приложение Flask рабочей роли обрабатывает запрос, который включает загрузку скрипта записи и любых зависимостей.

  5. Скрипт записи получает запрос. Входной скрипт выполняет вызов для вывода с загруженной моделью и возвращает ответ.

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

Изучение журналов сервера вывода

Существует два способа получения данных журнала для теста сервера вывода:

  • azureml-inference-server-http Запустите пакет локально и просмотрите выходные данные журнала.
  • Используйте сетевые конечные точки и просмотрите журналы контейнеров. Журнал для сервера вывода называется > HTTP-сервера вывода.

Примечание.

Формат ведения журнала изменился с версии 0.8.0. Если журнал использует другой стиль, чем ожидалось, обновите azureml-inference-server-http пакет до последней версии.

Просмотр журналов запуска

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

Azure ML Inferencing HTTP server <version>


Server Settings
---------------
Entry Script Name: <entry-script>
Model Directory: <model-directory>
Config File: <configuration-file>
Worker Count: <worker-count>
Worker Timeout (seconds): None
Server Port: <port>
Health Port: <port>
Application Insights Enabled: false
Application Insights Key: <Application-Insights-instrumentation-key>
Inferencing HTTP server version: azmlinfsrv/<version>
CORS for the specified origins: <access-control-allow-origins>
Create dedicated endpoint for health: <health-check-endpoint>


Server Routes
---------------
Liveness Probe: GET   127.0.0.1:<port>/
Score:          POST  127.0.0.1:<port>/score

<logs>

Например, при запуске сервера инференса, выполнив пример от начала до конца, журналы содержат следующие сведения:

Azure ML Inferencing HTTP server v1.2.2


Server Settings
---------------
Entry Script Name: /home/user-name/azureml-examples/cli/endpoints/online/model-1/onlinescoring/score.py
Model Directory: ./
Config File: None
Worker Count: 1
Worker Timeout (seconds): None
Server Port: 5001
Health Port: 5001
Application Insights Enabled: false
Application Insights Key: None
Inferencing HTTP server version: azmlinfsrv/1.2.2
CORS for the specified origins: None
Create dedicated endpoint for health: None

Server Routes
---------------
Liveness Probe: GET   127.0.0.1:5001/
Score:          POST  127.0.0.1:5001/score

2022-12-24 07:37:53,318 I [32726] gunicorn.error - Starting gunicorn 20.1.0
2022-12-24 07:37:53,319 I [32726] gunicorn.error - Listening at: http://0.0.0.0:5001 (32726)
2022-12-24 07:37:53,319 I [32726] gunicorn.error - Using worker: sync
2022-12-24 07:37:53,322 I [32756] gunicorn.error - Booting worker with pid: 32756
Initializing logger
2022-12-24 07:37:53,779 I [32756] azmlinfsrv - Starting up app insights client
2022-12-24 07:37:54,518 I [32756] azmlinfsrv.user_script - Found user script at /home/user-name/azureml-examples/cli/endpoints/online/model-1/onlinescoring/score.py
2022-12-24 07:37:54,518 I [32756] azmlinfsrv.user_script - run() is not decorated. Server will invoke it with the input in JSON string.
2022-12-24 07:37:54,518 I [32756] azmlinfsrv.user_script - Invoking user's init function
2022-12-24 07:37:55,974 I [32756] azmlinfsrv.user_script - Users's init has completed successfully
2022-12-24 07:37:55,976 I [32756] azmlinfsrv.swagger - Swaggers are prepared for the following versions: [2, 3, 3.1].
2022-12-24 07:37:55,976 I [32756] azmlinfsrv - Scoring timeout is set to 3600000
2022-12-24 07:37:55,976 I [32756] azmlinfsrv - Worker with pid 32756 ready for serving traffic

Общие сведения о формате данных журнала

Все логи с сервера обработки данных, кроме скрипта запуска, представляют данные в следующем формате:

<UTC-time> <level> [<process-ID>] <logger-name> - <message>

Каждая запись состоит из следующих компонентов:

  • <UTC-time>: время ввода записи в журнал
  • <level>: первый символ уровня ведения журнала для записи, например E для ERROR, I для INFO и т. д.
  • <process-ID>: идентификатор процесса, связанного с записью
  • <logger-name>: имя ресурса, связанного с записью журнала
  • <message>: содержимое сообщения журнала

В Python существует шесть уровней ведения журнала. Каждый уровень имеет назначенное числовое значение в соответствии с его серьезностью:

Уровень ведения журнала Числовое значение
КРИТИЧЕСКИЙ; 50
ОШИБКИ 40
ПРЕДУПРЕЖДЕНИЕ 30
ИНФОРМАЦИЯ 20
ОТЛАЖИВАТЬ 10
NOTSET 0

Устранение неполадок с сервером вывода

В следующих разделах приведены основные советы по устранению неполадок сервера вывода. Для устранения неполадок онлайн-конечных точек см. Устранение неполадок с развертыванием и оценкой онлайн-конечных точек.

Проверка установленных пакетов

Выполните следующие действия, чтобы устранить проблемы с установленными пакетами:

  1. Сбор сведений об установленных пакетах и версиях среды Python.

  2. В файле среды проверьте версию указанного azureml-inference-server-http пакета Python. В журналах запуска HTTP-сервера машинного обучения Azure проверьте версию сервера прогнозирования, которая отображается. Убедитесь, что совпадают две версии.

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

  3. Если вы указываете Flask или его зависимости в вашей среде, удалите эти элементы.

    • Зависимые пакеты включают flask, , jinja2, itsdangerouswerkzeug, markupsafeи click.
    • Пакет flask указан как зависимость в пакете сервера вывода. Лучший подход — разрешить серверу вывода установить flask пакет.
    • Когда сервер вывода настроен на поддержку новых версий Flask, сервер вывода автоматически получает обновления пакета по мере их доступности.

Проверка версии сервера вывода

Пакет azureml-inference-server-http сервера публикуется в PyPI. На странице PyPI перечислены журнал изменений и все версии пакета.

Если вы используете раннюю версию пакета, обновите конфигурацию до последней версии. В следующей таблице приведены стабильные версии, распространенные проблемы и рекомендуемые корректировки:

Версия пакета Описание: Проблема Решение
0.4.x Включенные в обучающие образы, датированные 20220601 или ранее, и версии пакетов от 0.1.34 до 1.43. Последняя стабильная версия — 0.4.13. Для версий сервера, предшествующих версии 0.4.11, могут возникнуть проблемы с зависимостью Flask, например can't import name Markup from jinja2. При возможности обновите до версии 0.4.13 или 1.4.x, последнюю версию.
0.6.x Предварительно установлен в изображениях вывода, датированных 20220516 и более ранних версий. Последняя стабильная версия — 0.6.1. Н/П Н/П
0.7.x Поддерживает Flask 2. Последняя стабильная версия — 0.7.7. Н/П Н/П
0.8.x Использует обновленный формат журнала. Заканчивает поддержку Python 3.6. Н/П Н/П
1.0.x Заканчивает поддержку Python 3.7. Н/П Н/П
1.1.x Переход на pydantic 2.0. Н/П Н/П
1.2.x Добавляет поддержку Python 3.11. Обновляется gunicorn до версии 22.0.0. Обновляет werkzeug до версии 3.0.3 и более поздних версий. Н/П Н/П
1.3.x Добавляет поддержку Python 3.12. certifi Обновляется до версии 2024.7.4. flask-cors Обновляется до версии 5.0.0. Обновляет пакеты gunicorn и pydantic. Н/П Н/П
1.4.x waitress Обновляется до версии 3.0.1. Заканчивает поддержку Python 3.8. Удаляет слой совместимости, который предотвращает сбой кода объекта запроса при обновлении до Flask 2.0. Если вы зависите от уровня совместимости, код объекта запроса может не работать. Перенос вашего скрипта подсчета на Flask 2.

Проверка зависимостей пакета

Ниже перечислены наиболее важные зависимые пакеты для azureml-inference-server-http пакета сервера:

  • flask
  • opencensus-ext-azure
  • inference-schema

Если указать azureml-defaults пакет в среде Python, azureml-inference-server-http пакет является зависимым пакетом. Зависимость устанавливается автоматически.

Совет

Если вы используете SDK машинного обучения Azure для Python версии 1 и не указываете пакет azureml-defaults в своей среде Python, SDK может автоматически его добавить. Однако версия пакета заблокирована относительно версии SDK. Например, если версия пакета SDK 1.38.0, в требования pip среды добавляется запись azureml-defaults==1.38.0.

TypeError во время запуска сервера вывода

Во время запуска инференс-сервера вы можете столкнуться со следующим TypeError:

TypeError: register() takes 3 positional arguments but 4 were given

  File "/var/azureml-server/aml_blueprint.py", line 251, in register

    super(AMLBlueprint, self).register(app, options, first_registration)

TypeError: register() takes 3 positional arguments but 4 were given

Эта ошибка возникает при установке Flask 2 в среде Python, но версия azureml-inference-server-http пакета не поддерживает Flask 2. Поддержка Flask 2 доступна в пакете azureml-inference-server-http 0.7.0 и более поздних версиях, а azureml-defaults также в пакете 1.44 и более поздних версиях.

  • Если вы не используете пакет Flask 2 в образе Docker Машинное обучение Azure, используйте последнюю версию azureml-inference-server-http пакета или azureml-defaults пакета.

  • Если вы используете пакет Flask 2 в Docker-образе для машинного обучения Azure, убедитесь, что версия сборки July 2022 или более поздняя.

    Версию образа можно найти в журналах контейнеров. Например, обратите внимание на следующие записи журнала:

    2022-08-22T17:05:02,147738763+00:00 | gunicorn/run | AzureML Container Runtime Information
    2022-08-22T17:05:02,161963207+00:00 | gunicorn/run | ###############################################
    2022-08-22T17:05:02,168970479+00:00 | gunicorn/run | 
    2022-08-22T17:05:02,174364834+00:00 | gunicorn/run | 
    2022-08-22T17:05:02,187280665+00:00 | gunicorn/run | AzureML image information: openmpi4.1.0-ubuntu20.04, Materialization Build:20220708.v2
    2022-08-22T17:05:02,188930082+00:00 | gunicorn/run | 
    2022-08-22T17:05:02,190557998+00:00 | gunicorn/run | 
    

    Дата сборки изображения отображается после Materialization Build нотации. В предыдущем примере версия образа — 202207088 июля 2022 г. Изображение в этом примере совместимо с Flask 2.

    Если в журнале контейнеров не отображается аналогичное сообщение, образ устарел и должен быть обновлен. Если вы используете образ CUDA и не можете найти более новый, проверьте репозиторий Контейнеров AzureML, чтобы узнать, не устарел ли ваш образ. Вы можете найти назначенные замены для устаревших образов.

    Если вы используете сервер вывода с веб-конечной точкой, вы также можете найти журналы в Студии машинного обучения Azure. На странице конечной точки выберите вкладку "Журналы".

При развертывании с использованием SDK версии 1 и если вы не указываете явно образ в конфигурации развертывания, сервер инференции применяет пакет openmpi4.1.0-ubuntu20.04 с версией, которая соответствует вашему локальному набору инструментов SDK. Однако установленная версия может не быть последней доступной версией образа.

Для SDK версии 1.43 сервер выводов по умолчанию устанавливает openmpi4.1.0-ubuntu20.04:20220616 версию пакета, но она несовместима с SDK 1.43. Убедитесь, что для развертывания используется последняя версия пакета SDK.

Если вы не можете обновить изображение, можно временно избежать проблемы, закрепив azureml-defaults==1.43azureml-inference-server-http~=0.4.13 записи или записи в файле среды. Эти записи направляют сервер прогнозирования, чтобы установить более старую версию flask 1.0.x.

ImportError или ModuleNotFoundError во время запуска сервера предсказаний

Во время запуска сервера вывода может возникнуть ImportError или ModuleNotFoundError на определенных модулях, например opencensus, jinja2, markupsafe или click. В следующем примере показано сообщение об ошибке:

ImportError: cannot import name 'Markup' from 'jinja2'

Ошибки импорта и модуля возникают при использовании версии 0.4.10 или более ранних версий сервера вывода, которые не закрепляют зависимость Flask к совместимой версии. Чтобы предотвратить проблему, установите более позднюю версию сервера вывода.