Развертывание языковых моделей в пакетных конечных точках

ОБЛАСТЬ ПРИМЕНЕНИЯ:Расширение машинного обучения Azure CLI версии 2 (current)Python SDK azure-ai-ml версии 2 (current)

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

Об этом примере

Модель, с которыми мы будем работать, была создана с использованием популярных преобразователей библиотеки из HuggingFace вместе с предварительно обученной моделью из Facebook с архитектурой BART. Она была представлена в документе BART: отмена предварительного обучения последовательности и последовательности для создания естественного языка. Эта модель имеет следующие ограничения, которые важно учитывать при развертывании:

  • Он может работать с последовательности до 1024 токенов.
  • Он обучен для суммирования текста на английском языке.
  • Мы будем использовать Факел в качестве серверной части.

Пример в этой статье основан на примерах кода, содержащихся в репозитории azureml-examples . Чтобы выполнить команды локально без необходимости копирования и вставки YAML и других файлов, сначала клонируйте репозиторий, а затем измените каталоги в папку:

git clone https://github.com/Azure/azureml-examples --depth 1
cd azureml-examples/cli

Файлы для этого примера находятся в следующих файлах:

cd endpoints/batch/deploy-models/huggingface-text-summarization

Следуйте инструкциям в Jupyter Notebooks

Вы можете следовать этому примеру в Jupyter Notebook. В клонируемом репозитории откройте записную книжку: text-summarization-batch.ipynb.

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

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

  • Подписка Azure. Если у вас еще нет подписки Azure, создайте бесплатную учетную запись, прежде чем начинать работу. Попробуйте бесплатную или платную версию Машинного обучения Azure.

  • Рабочая область Машинного обучения Azure. Если у вас нет одного, выполните действия, описанные в статье "Управление Машинное обучение Azure рабочими областями", чтобы создать ее.

  • Убедитесь, что в рабочей области есть следующие разрешения:

    • Создание конечных точек и развертываний пакетной службы или управление ими: используйте роль владельца, участника или настраиваемую роль, которая позволяет Microsoft.MachineLearningServices/workspaces/batchEndpoints/*.

    • Создайте развертывания ARM в группе ресурсов рабочей области: используйте роль владельца, участника или настраиваемую роль, которая позволяет Microsoft.Resources/deployments/write в группе ресурсов, в которой развернута рабочая область.

  • Для работы с Машинное обучение Azure необходимо установить следующее программное обеспечение:

    Azure CLI и mlрасширение для Машинное обучение Azure.

    az extension add -n ml
    

    Примечание.

    Развертывания компонентов конвейера для конечных точек пакетной службы появились в версии 2.7 ml расширения для Azure CLI. Используется az extension update --name ml для получения последней версии.

Подключение к рабочей области

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

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

az account set --subscription <subscription>
az configure --defaults workspace=<workspace> group=<resource-group> location=<location>

Регистрация модели

Из-за размера модели он не был включен в этот репозиторий. Вместо этого можно скачать копию из центра модели HuggingFace. Вам нужны пакеты transformers и torch установленные в среде, которую вы используете.

%pip install transformers torch

Используйте следующий код, чтобы скачать модель в папку model:

from transformers import pipeline

model = pipeline("summarization", model="facebook/bart-large-cnn")
model_local_path = 'model'
summarizer.save_pretrained(model_local_path)

Теперь эту модель можно зарегистрировать в реестре Машинное обучение Azure:

MODEL_NAME='bart-text-summarization'
az ml model create --name $MODEL_NAME --path "model"

Создание конечной точки

Мы создадим пакетную конечную точку с именем text-summarization-batch , в которой будет развернута модель HuggingFace для выполнения сводных данных по текстовым файлам на английском языке.

  1. Определите имя конечной точки. Имя конечной точки заканчивается в URI, связанном с конечной точкой. Из-за этого имена конечных точек пакетной службы должны быть уникальными в пределах региона Azure. Например, в ней может быть только одна конечная точка пакетной службы с именем mybatchendpointwestus2.

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

    ENDPOINT_NAME="text-summarization-batch"
    
  2. Настройка конечной точки пакетной службы

    Следующий ФАЙЛ YAML определяет конечную точку пакетной службы:

    endpoint.yml

    $schema: https://azuremlschemas.azureedge.net/latest/batchEndpoint.schema.json
    name: text-summarization-batch
    description: A batch endpoint for summarizing text using a HuggingFace transformer model.
    auth_mode: aad_token
    
  3. Создание конечной точки:

    az ml batch-endpoint create --file endpoint.yml  --name $ENDPOINT_NAME
    

Создание развертывания

Создадим развертывание, на котором размещена модель:

  1. Нам нужно создать скрипт оценки, который может считывать CSV-файлы, предоставляемые пакетным развертыванием, и возвращать оценки модели с сводкой. Следующий скрипт выполняет следующие действия:

    • Указывает init функцию, которая обнаруживает конфигурацию оборудования (ЦП и GPU) и загружает модель соответствующим образом. Модель и маркеризатор загружаются в глобальные переменные. Мы не используем pipeline объект из HuggingFace для учета ограничения последовательности lenghs модели, используемой в настоящее время.
    • Обратите внимание, что мы выполняем оптимизацию моделей для повышения производительности использования optimum и accelerate библиотек. Если модель или оборудование не поддерживает ее, мы будем запускать развертывание без такой оптимизации.
    • Указывает функцию, выполняемую run для каждого мини-пакета, которую предоставляет пакетное развертывание.
    • Функция run считывает весь пакет с помощью библиотеки datasets . Текст, который нужно свести к сводные данные, находится в столбце text.
    • Метод run выполняет итерацию по каждой строке текста и выполняет прогноз. Так как это очень дорогая модель, выполнение прогноза по всем файлам приведет к исключению из памяти. Обратите внимание, что модель не выполняется с pipeline объектом из transformers. Это делается для учета длинных последовательностей текста и ограничения 1024 маркеров в базовой модели, используемой нами.
    • Он возвращает сводку предоставленного текста.

    код/batch_driver.py

    import os
    import time
    import torch
    import subprocess
    import mlflow
    from pprint import pprint
    from transformers import AutoTokenizer, BartForConditionalGeneration
    from optimum.bettertransformer import BetterTransformer
    from datasets import load_dataset
    
    
    def init():
        global model
        global tokenizer
        global device
    
        cuda_available = torch.cuda.is_available()
        device = "cuda" if cuda_available else "cpu"
    
        if cuda_available:
            print(f"[INFO] CUDA version: {torch.version.cuda}")
            print(f"[INFO] ID of current CUDA device: {torch.cuda.current_device()}")
            print("[INFO] nvidia-smi output:")
            pprint(
                subprocess.run(["nvidia-smi"], stdout=subprocess.PIPE).stdout.decode(
                    "utf-8"
                )
            )
        else:
            print(
                "[WARN] CUDA acceleration is not available. This model takes hours to run on medium size data."
            )
    
        # AZUREML_MODEL_DIR is an environment variable created during deployment
        model_path = os.path.join(os.environ["AZUREML_MODEL_DIR"], "model")
    
        # load the tokenizer
        tokenizer = AutoTokenizer.from_pretrained(
            model_path, truncation=True, max_length=1024
        )
    
        # Load the model
        try:
            model = BartForConditionalGeneration.from_pretrained(
                model_path, device_map="auto"
            )
        except Exception as e:
            print(
                f"[ERROR] Error happened when loading the model on GPU or the default device. Error: {e}"
            )
            print("[INFO] Trying on CPU.")
            model = BartForConditionalGeneration.from_pretrained(model_path)
            device = "cpu"
    
        # Optimize the model
        if device != "cpu":
            try:
                model = BetterTransformer.transform(model, keep_original_model=False)
                print("[INFO] BetterTransformer loaded.")
            except Exception as e:
                print(
                    f"[ERROR] Error when converting to BetterTransformer. An unoptimized version of the model will be used.\n\t> {e}"
                )
    
        mlflow.log_param("device", device)
        mlflow.log_param("model", type(model).__name__)
    
    
    def run(mini_batch):
        resultList = []
    
        print(f"[INFO] Reading new mini-batch of {len(mini_batch)} file(s).")
        ds = load_dataset("csv", data_files={"score": mini_batch})
    
        start_time = time.perf_counter()
        for idx, text in enumerate(ds["score"]["text"]):
            # perform inference
            inputs = tokenizer.batch_encode_plus(
                [text], truncation=True, padding=True, max_length=1024, return_tensors="pt"
            )
            input_ids = inputs["input_ids"].to(device)
            summary_ids = model.generate(
                input_ids, max_length=130, min_length=30, do_sample=False
            )
            summaries = tokenizer.batch_decode(
                summary_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False
            )
    
            # Get results:
            resultList.append(summaries[0])
            rps = idx / (time.perf_counter() - start_time + 00000.1)
            print("Rows per second:", rps)
    
        mlflow.log_metric("rows_per_second", rps)
        return resultList
    

    Совет

    Хотя файлы предоставляются в мини-пакетах развертывания, этот скрипт оценки обрабатывает одну строку за раз. Это распространенный шаблон при работе с дорогостоящими моделями (например, преобразователями), так как попытка загрузить весь пакет и отправить его в модель одновременно может привести к высокой нагрузке на пакетный исполнитель (OOM exeptions).

  2. Нам нужно указать, в какой среде мы будем запускать развертывание. В нашем случае наша модель выполняется Torch и требует transformersбиблиотек, accelerateа также optimum от HuggingFace. Машинное обучение Azure уже имеет среду с поддержкой Torch и GPU. Мы просто добавим пару зависимостей в conda.yaml файл.

    environment/torch200-conda.yaml

    name: huggingface-env
    channels:
      - conda-forge
    dependencies:
      - python=3.8.5
      - pip
      - pip:
        - torch==2.0
        - transformers
        - accelerate
        - optimum
        - datasets
        - mlflow
        - azureml-mlflow
        - azureml-core
        - azureml-dataset-runtime[fuse]
    
  3. Мы можем использовать файл conda, упоминание, как показано ниже.

    Определение среды включается в файл развертывания.

    deployment.yml

    compute: azureml:gpu-cluster
    environment:
      name: torch200-transformers-gpu
      image: mcr.microsoft.com/azureml/openmpi4.1.0-cuda11.8-cudnn8-ubuntu22.04:latest
    

    Внимание

    Для созданной среды torch200-transformers-gpu требуется устройство, совместимое с CUDA 11.8, для запуска Torch 2.0 и Ubuntu 20.04. Если устройство GPU не поддерживает эту версию CUDA, вы можете проверка альтернативную torch113-conda.yaml среду conda (также доступной в репозитории), которая запускает Torch 1.3 в Ubuntu 18.04 с CUDA 10.1. Однако ускорение с помощью optimumaccelerate библиотек не будет поддерживаться в этой конфигурации.

  4. Каждое развертывание выполняется в вычислительных кластерах. Они поддерживают оба кластера Машинное обучение Azure вычислительных кластеров (AmlCompute) или Кластеры Kubernetes. В этом примере наша модель может воспользоваться ускорением GPU, поэтому мы используем кластер GPU.

    az ml compute create -n gpu-cluster --type amlcompute --size STANDARD_NV6 --min-instances 0 --max-instances 2
    

    Примечание.

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

  5. Теперь создадим развертывание.

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

    deployment.yml

    $schema: https://azuremlschemas.azureedge.net/latest/modelBatchDeployment.schema.json
    endpoint_name: text-summarization-batch
    name: text-summarization-optimum
    description: A text summarization deployment implemented with HuggingFace and BART architecture with GPU optimization using Optimum.
    type: model
    model: azureml:bart-text-summarization@latest
    compute: azureml:gpu-cluster
    environment:
      name: torch200-transformers-gpu
      image: mcr.microsoft.com/azureml/openmpi4.1.0-cuda11.8-cudnn8-ubuntu22.04:latest
      conda_file: environment/torch200-conda.yaml
    code_configuration:
      code: code
      scoring_script: batch_driver.py
    resources:
      instance_count: 2
    settings:
      max_concurrency_per_instance: 1
      mini_batch_size: 1
      output_action: append_row
      output_file_name: predictions.csv
      retry_settings:
        max_retries: 1
        timeout: 3000
      error_threshold: -1
      logging_level: info
    

    Затем создайте развертывание с помощью следующей команды:

    az ml batch-deployment create --file deployment.yml --endpoint-name $ENDPOINT_NAME --set-default
    

    Внимание

    В этом развертывании вы заметите большое значение в timeout параметре retry_settings. Причина этого обусловлена характером выполняемой модели. Это очень дорогая модель и вывод по одной строке может занять до 60 секунд. Параметры timeout управляют временем, сколько времени пакетное развертывание должно ожидать завершения обработки каждого мини-пакета скрипта оценки. Так как наша модель выполняет прогнозы по строкам, обработка длинного файла может занять некоторое время. Кроме того, обратите внимание, что для каждого пакета задано значение 1 (mini_batch_size=1). Это снова связано с характером выполняемой работы. Обработка одного файла за один пакет достаточно дорого, чтобы оправдать его. Вы заметите, что это шаблон в обработке NLP.

  6. Хотя вы можете вызвать определенное развертывание внутри конечной точки, обычно требуется вызвать саму конечную точку и разрешить конечной точке решить, какое развертывание следует использовать. Такое развертывание называется развертыванием по умолчанию. Это дает возможность изменять развертывание по умолчанию и, следовательно, изменять модель, обслуживающую развертывание, без изменения контракта с пользователем, вызывающим конечную точку. Чтобы обновить развертывание по умолчанию, используйте следующую инструкцию:

    DEPLOYMENT_NAME="text-summarization-hfbart"
    az ml batch-endpoint update --name $ENDPOINT_NAME --set defaults.deployment_name=$DEPLOYMENT_NAME
    
  7. На этом этапе наша конечная точка пакетной службы готова к использованию.

Тестирование развертывания

Для тестирования нашей конечной точки мы будем использовать пример набора данных BillSum: Корпус для автоматической сводки законодательства США. Этот пример включен в репозиторий в папку data. Обратите внимание, что формат данных — CSV, и содержимое, которое нужно свести в столбец text, как ожидается, моделью.

  1. Давайте вызовем конечную точку:

    JOB_NAME=$(az ml batch-endpoint invoke --name $ENDPOINT_NAME --input data --input-type uri_folder --query name -o tsv)
    

    Примечание.

    jq Программа не может быть установлена во всех установках. Вы можете получить инструкции по этой ссылке.

    Совет

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

  2. Пакетное задание запускается сразу после возврата команды. Вы можете отслеживать состояние задания, пока оно не завершится:

    az ml job show -n $JOB_NAME --web
    
  3. После завершения развертывания можно скачать прогнозы:

    Чтобы скачать прогнозы, используйте следующую команду:

    az ml job download --name $JOB_NAME --output-name score --download-path .
    

Рекомендации при развертывании моделей, обрабатывающих текст

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

  • Некоторые модели NLP могут быть очень дорогими с точки зрения памяти и времени вычислений. Если это так, попробуйте уменьшить количество файлов, включенных в каждый мини-пакет. В приведенном выше примере число было принято к минимуму, 1 файл на пакет. Хотя это может быть не так, учитывайте, сколько файлов модель может оценить каждый раз. Имейте в виду, что связь между размером входных данных и объемом памяти модели может не быть линейной для моделей глубокого обучения.
  • Если модель не может одновременно обрабатывать один файл (например, в этом примере), рассмотрите возможность чтения входных данных в строках или блоках. Реализуйте пакетную обработку на уровне строк, если необходимо достичь более высокой пропускной способности или аппаратного использования.
  • Задайте значение развертывания точно так timeout , как дорого ваша модель и сколько данных вы ожидаете обработать. Помните, что указывает время timeout , когда пакетное развертывание будет ожидать выполнения скрипта оценки для заданного пакета. Если пакет содержит много файлов или файлов с множеством строк, это влияет на правильное значение этого параметра.

Рекомендации по модели MLflow, обрабатывающие текст

Те же рекомендации, упоминание приведенные выше, применяются к моделям MLflow. Однако, так как вам не требуется предоставлять скрипт оценки для развертывания модели MLflow, некоторые рекомендации, упоминание, могут потребовать другого подхода.

  • Модели MLflow в пакетной конечной точке поддерживают чтение табличных данных в виде входных данных, которые могут содержать длинные последовательности текста. Сведения о поддерживаемых типах файлов см. в разделе " Типы файлов".
  • Пакетные развертывания вызывают прогнозную функцию модели MLflow с содержимым всего файла в виде кадра данных Pandas. Если входные данные содержат много строк, вероятность выполнения сложной модели (например, представленной в этом руководстве) приводит к исключению из памяти. Если это ваш случай, вы можете рассмотреть следующее: