Bereitstellen von Sprachmodellen in Batchendpunkten

GILT FÜR:Azure CLI ML-Erweiterung v2 (aktuell)Python SDK azure-ai-ml v2 (aktuell)

Batchendpunkte können verwendet werden, um teure Modelle wie Sprachmodelle über Textdaten bereitzustellen. In diesem Tutorial erfahren Sie, wie Sie ein Modell bereitstellen, das Textzusammenfassungen langer Textsequenzen mithilfe eines Modells von HuggingFace erstellen kann. Außerdem wird gezeigt, wie Sie Rückschlüsse mithilfe von HuggingFace optimum und accelerate-Bibliotheken durchführen.

Informationen zu diesem Beispiel

Das Modell, mit dem wir arbeiten werden, wurde mit den beliebten Bibliothekstransformatoren von HuggingFace zusammen mit einem vorab trainierten Modell von Facebook mit der BART-Architektur entwickelt. Es wurde im folgenden Whitepaper eingeführt: BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation. Dieses Modell weist die folgenden Einschränkungen auf, die bei der Implementierung beachtet werden müssen:

  • Es kann mit Sequenzen bis zu 1.024 Token arbeiten.
  • Es ist für die Zusammenfassung von Texten in englischer Sprache trainiert.
  • Wir werden Torch als Back-End verwenden.

Das Beispiel in diesem Artikel basiert auf Codebeispielen, die im Repository azureml-examples enthalten sind. Um die Befehle lokal auszuführen, ohne YAML und andere Dateien kopieren/einfügen zu müssen, klonen Sie zunächst das Repository, und ändern Sie dann die Verzeichnisse zum Ordner:

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

Die Dateien für dieses Beispiel befinden sich in:

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

Folgen in Jupyter Notebooks

Sie können diesem Beispiel in einem Jupyter Notebook folgen. Öffnen Sie in dem geklonten Repository folgendes Notebook: text-summarization-batch.ipynb.

Voraussetzungen

Stellen Sie vor dem Ausführen der Schritte in diesem Artikel sicher, dass Sie über die folgenden erforderlichen Komponenten verfügen:

  • Ein Azure-Abonnement. Wenn Sie nicht über ein Azure-Abonnement verfügen, können Sie ein kostenloses Konto erstellen, bevor Sie beginnen. Probieren Sie die kostenlose oder kostenpflichtige Version von Azure Machine Learning aus.

  • Ein Azure Machine Learning-Arbeitsbereich. Wenn Sie keins haben, führen Sie die Schritte im Artikel Verwalten von Azure Machine Learning-Arbeitsbereichen aus, um einen Arbeitsbereich zu erstellen.

  • Stellen Sie sicher, dass Sie im Arbeitsbereich über die folgenden Berechtigungen verfügen:

    • Erstellen oder Verwalten von Batchendpunkten und Batchbereitstellungen: Verwenden Sie die Rolle für Besitzer oder Mitwirkende oder eine benutzerdefinierte Rolle, die Microsoft.MachineLearningServices/workspaces/batchEndpoints/* zulässt.

    • Erstellen von ARM-Bereitstellungen in der Arbeitsbereichsressourcengruppe: Verwenden Sie die Rolle für Besitzer oder Mitwirkende oder eine benutzerdefinierte Rolle, die Microsoft.Resources/deployments/write in der Ressourcengruppe zulässt, in der der Arbeitsbereich bereitgestellt wird.

  • Für die Arbeit mit Azure Machine Learning müssen Sie die folgende Software installieren:

    Die Azure CLI und die ml-Erweiterung für Azure Machine Learning.

    az extension add -n ml
    

    Hinweis

    Bereitstellungen der Pipelinekomponenten für Batchendpunkte wurden in Version 2.7 der Erweiterung ml für die Azure CLI eingeführt. Verwenden Sie az extension update --name ml, um die letzte Version davon zu erhalten.

Herstellen einer Verbindung mit Ihrem Arbeitsbereich

Der Arbeitsbereich ist die Ressource der obersten Ebene für Azure Machine Learning und ein zentraler Ort für die Arbeit mit allen Artefakten, die Sie während der Nutzung von Azure Machine Learning erstellen. In diesem Abschnitt stellen wir eine Verbindung mit dem Arbeitsbereich her, in dem Sie die Bereitstellung vornehmen werden.

Übergeben Sie die Werte für Ihre Abonnement-ID, Ihren Arbeitsbereich, Ihren Standort und Ihre Ressourcengruppe im folgenden Code:

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

Registrieren des Modells

Aufgrund der Größe des Modells ist es in diesem Repository nicht enthalten. Stattdessen können Sie eine Kopie vom Hub des HuggingFace-Modells herunterladen. Sie müssen die Pakete transformers und torch in der Umgebung, die Sie verwenden, installiert haben.

%pip install transformers torch

Verwenden Sie den folgenden Code, um das Modell in einen model-Ordner herunterzuladen:

from transformers import pipeline

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

Wir können dieses Modell jetzt in der Azure Machine Learning-Registrierung registrieren:

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

Erstellen des Endpunkts

Wir erstellen einen Batchendpunkt mit dem Namen text-summarization-batch, an dem das HuggingFace-Modell implementiert werden soll, um die Textzusammenfassung für Textdateien in englischer Sprache auszuführen.

  1. Entscheiden Sie sich für den Namen des Endpunkts. Der Name des Endpunkts wird in dem URI angezeigt, der Ihrem Endpunkt zugeordnet ist. Daher müssen die Namen der Batchendpunkte innerhalb einer Azure-Region eindeutig sein. Beispielsweise kann es nur einen Endpunkt namens mybatchendpoint in westus2 geben.

    In diesem Fall platzieren wir den Namen des Endpunkts in einer Variable, damit wir später problemlos darauf verweisen können.

    ENDPOINT_NAME="text-summarization-batch"
    
  2. Konfigurieren Ihres Batchendpunkts

    Die folgende YAML-Datei definiert einen Batchendpunkt:

    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. Erstellen des Endpunkts:

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

Erstellen der Bereitstellung

Erstellen wir die Bereitstellung, die das Modell hosten soll:

  1. Wir müssen ein Bewertungsskript erstellen, das die von der Batchbereitstellung bereitgestellten CSV-Dateien lesen und die Bewertungen des Modells mit der Zusammenfassung zurückgeben kann. Mit diesem Skript werden die folgenden Aktionen ausgeführt:

    • Zeigt eine init-Funktion an, die die Hardwarekonfiguration (CPU im Vergleich zur GPU) erkennt und das Modell entsprechend lädt. Sowohl das Modell als auch der Tokenizer werden in globalen Variablen geladen. Wir verwenden kein pipeline-Objekt von HuggingFace, um die Einschränkung in den Sequenzlängen des derzeit verwendeten Modells zu berücksichtigen.
    • Beachten Sie, dass wir Modelloptimierungen durchführen, um die Leistung mithilfe von optimum- sowie accelerate-Bibliotheken zu verbessern. Wenn das Modell oder die Hardware dies nicht unterstützen, führen wir die Bereitstellung ohne solche Optimierungen aus.
    • Gibt eine run-Funktion an, die für jeden Minibatch ausgeführt wird, den die Batchbereitstellung bereitstellt.
    • Die run-Funktion liest den gesamten Batch mithilfe der datasets-Bibliothek. Der Text, den wir zusammenfassen müssen, befindet sich in der Spalte text.
    • Die run-Methode durchläuft alle Zeilen des Texts und führt die Vorhersage aus. Da dies ein sehr teures Modell ist, führt das Ausführen der Vorhersage über sämtliche Dateien zu einer Ausnahme aufgrund ungenügenden Arbeitsspeichers. Beachten Sie, dass das Modell nicht mit dem pipeline-Objekt aus transformers ausgeführt wird. Dies geschieht, um lange Textsequenzen und die Einschränkung von 1.024 Token im zugrunde liegenden Modell zu berücksichtigen.
    • Es gibt die Zusammenfassung des bereitgestellten Texts zurück.

    code/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
    

    Tipp

    Obwohl die Dateien von der Bereitstellung in Minibatches zur Verfügung gestellt werden, verarbeitet dieses Bewertungsskript eine Zeile nach der anderen. Dies ist ein gängiges Muster im Umgang mit teuren Modellen (wie Transformatoren), da es bei dem Versuch, den gesamten Batch zu laden und zugleich an das Modell zu senden, zu einer hohen Arbeitsspeicherauslastung auf dem Batch Executor kommen kann (OOM-Ausnahmen).

  2. Wir müssen angeben, in welcher Umgebung wir die Bereitstellung ausführen werden. In unserem Fall wird unser Modell auf Torch ausgeführt und erfordert die Bibliotheken transformers, accelerate und optimum von HuggingFace. Azure Machine Learning verfügt bereits über eine verfügbare Umgebung mit Torch- und GPU-Unterstützung. Wir werden nur einige Abhängigkeiten in einer conda.yaml-Datei hinzufügen.

    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. Wir können die zuvor erwähnte Conda-Datei wie folgt verwenden:

    Die Umgebungsdefinition wird in die Bereitstellungsdatei aufgenommen.

    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
    

    Wichtig

    Die von uns erstellte Umgebung torch200-transformers-gpu erfordert ein CUDA 11.8-kompatibles Hardwaregerät, um Torch 2.0 und Ubuntu 20.04 auszuführen. Wenn Ihr GPU-Gerät diese Version von CUDA nicht unterstützt, können Sie die alternative Conda-Umgebung torch113-conda.yaml (auch im Repository verfügbar) überprüfen, in der Torch 1.3 über Ubuntu 18.04 mit CUDA 10.1 ausgeführt wird. Beschleunigung mithilfe der Bibliotheken optimum und accelerate wird in dieser Konfiguration jedoch nicht unterstützt.

  4. Jede Bereitstellung wird auf Computeclustern ausgeführt. Sie unterstützen sowohl Azure Machine Learning Compute-Cluster (AmlCompute) als auch Kubernetes-Cluster. In diesem Beispiel kann unser Modell von der GPU-Beschleunigung profitieren, weshalb wir einen GPU-Cluster verwenden.

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

    Hinweis

    Zu diesem Zeitpunkt werden Ihnen noch keine Computeressourcen in Rechnung gestellt, da der Cluster bei 0 Knoten verbleibt, bis ein Batchendpunkt aufgerufen und ein Batchbewertungsauftrag übermittelt wird. Erfahren Sie mehr über das Verwalten und Optimieren von Kosten für AmlCompute.

  5. Erstellen wir nun die Bereitstellung.

    Um eine neue Bereitstellung unter dem erstellten Endpunkt zu erstellen, erstellen Sie eine YAML-Konfiguration wie die folgende. Sie können das vollständige YAML-Schema des Batchendpunkts auf zusätzliche Eigenschaften überprüfen.

    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
    

    Erstellen Sie dann die Bereitstellung mit dem folgenden Befehl:

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

    Wichtig

    In dieser Bereitstellung wird ein hoher Wert im timeout im Parameter retry_settings angezeigt. Der Grund dafür ist die Art des Modells, das wir ausführen. Dies ist ein sehr teures Modell und ein Rückschluss auf eine einzelne Zeile kann bis zu 60 Sekunden dauern. Die timeout-Parameter steuern, wie lange die Batchbereitstellung auf das Bewertungsskript wartet, um die Verarbeitung jedes Minibatchs abzuschließen. Da unser Modell die Vorhersagen Zeile für Zeile erstellt, kann die Verarbeitung einer langen Datei dauern. Beachten Sie auch, dass die Anzahl der Dateien pro Batch auf 1 (mini_batch_size=1) festgelegt ist. Dies ist wieder mit der Art der Arbeit verbunden, die wir verrichten. Die Verarbeitung einer Datei pro Batch ist teuer genug, um sie zu rechtfertigen. Sie werden feststellen, dass dies ein Muster in der NLP-Verarbeitung ist.

  6. Sie können zwar eine bestimmte Bereitstellung innerhalb eines Endpunkts aufrufen, in der Regel rufen Sie jedoch den Endpunkt selbst auf und überlassen diesem die Entscheidung, welche Bereitstellung verwendet werden soll. Eine derartige Bereitstellung wird als "Standard"-Bereitstellung bezeichnet. Dadurch erhalten Sie die Möglichkeit, die Standardbereitstellung und somit das Modell für die Bereitstellung zu ändern, ohne den Vertrag mit dem Benutzer ändern zu müssen, der den Endpunkt aufruft. Verwenden Sie die folgende Anweisung, um die Standardbereitstellung zu aktualisieren:

    DEPLOYMENT_NAME="text-summarization-hfbart"
    az ml batch-endpoint update --name $ENDPOINT_NAME --set defaults.deployment_name=$DEPLOYMENT_NAME
    
  7. An diesem Punkt ist unser Batchendpunkt zur Verwendung bereit.

Durchtesten der Bereitstellung

Zum Testen unseres Endpunkts verwenden wir ein Beispiel des Datasets BillSum: A Corpus for Automatic Summarization of US Legislation (Korpus zur automatischen Zusammenfassung der US-Rechtsprechung). Dieses Beispiel ist im Repository im Ordner data enthalten. Beachten Sie, dass das Format der Daten CSV ist und dass sich der zusammenzufassende Inhalt, wie vom Modell erwartet, in der Spalte text befindet.

  1. Rufen wir den Endpunkt auf:

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

    Hinweis

    Das Hilfsprogramm jq wird möglicherweise nicht auf jeder Installation installiert. Anweisungen erhalten Sie unter diesem Link.

    Tipp

    Beachten Sie, dass die Daten durch Angabe eines lokalen Pfads als Eingabe in das Standardspeicherkonto von Azure Machine Learning hochgeladen werden.

  2. Ein Batchauftrag wird gestartet, sobald der Befehl zurückgegeben wird. Sie können den Status des Auftrags überwachen, bis er abgeschlossen ist:

    az ml job show -n $JOB_NAME --web
    
  3. Nachdem die Bereitstellung abgeschlossen wurde, können wir die Vorhersagen herunterladen:

    Verwenden Sie den folgenden Befehl, um die Vorhersagen herunterzuladen:

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

Überlegungen beim Bereitstellen von Textverarbeitungsmodellen

Wie in einigen Hinweisen in diesem Tutorial erwähnt, kann die Verarbeitung von Text einige Besonderheiten aufweisen, die eine bestimmte Konfiguration der Batchbereitstellungen erfordern. Berücksichtigen Sie beim Gestalten der Batchbereitstellung Folgendes:

  • Einige NLP-Modelle können in Bezug auf Arbeitsspeicher und Computezeit sehr teuer sein. Wenn dies der Fall ist, verringern Sie die Anzahl der Dateien, die in jedem Minibatch enthalten sind. Im Beispiel oben wurde die Zahl auf den Mindestwert von einer Datei pro Batch festgelegt. Auch wenn dies bei Ihnen möglicherweise nicht der Fall ist, berücksichtigen Sie jedoch, wie viele Dateien Ihr Modell jedes Mal bewerten kann. Denken Sie daran, dass die Beziehung zwischen der Größe der Eingabe und dem Speicherbedarf Ihres Modells bei Deep Learning-Modellen möglicherweise nicht linear ist.
  • Wenn Ihr Modell nicht einmal eine Datei auf einmal verarbeiten kann (wie in diesem Beispiel), sollten Sie die Eingabedaten in Zeilen/Blöcken einlesen. Implementieren Sie die Batchverarbeitung auf Zeilenebene, wenn Sie einen höheren Durchsatz oder eine höhere Hardwareauslastung erzielen müssen.
  • Legen Sie den timeout-Wert Ihrer Bereitstellung entsprechend der Kosten Ihres Modells und der Datenmenge fest, die Sie verarbeiten möchten. Denken Sie daran, dass timeout angibt, wie lange die Batchbereitstellung warten würde, bis das Bewertungsskript für einen bestimmten Batch ausgeführt wird. Wenn Ihr Batch viele Dateien oder Dateien mit vielen Zeilen enthält, wirkt sich dies auf den Wert dieses Parameters aus.

Überlegungen zu MLflow-Modellen, die Text verarbeiten

Die oben genannten Überlegungen gelten für MLflow-Modelle. Da Sie jedoch kein Bewertungsskript für ihre MLflow-Modellimplementierung bereitstellen müssen, erfordern einige der erwähnten Empfehlungen möglicherweise eine andere Herangehensweise.

  • MLflow-Modelle in Batchendpunkten unterstützen das Lesen von Tabellendaten als Eingabedaten, die lange Textsequenzen enthalten können. Weitere Informationen zu den unterstützten Dateitypen finden Sie unter Unterstützung von Dateitypen.
  • Batchbereitstellungen rufen die Vorhersagefunktion Ihres MLflow-Modells mit dem Inhalt einer gesamten Datei als Pandas-Datenrahmen auf. Wenn Ihre Eingabedaten viele Zeilen enthalten, besteht die Wahrscheinlichkeit, dass die Ausführung eines komplexen Modells (wie in diesem Tutorial dargestellt) zu einer Ausnahme wegen unzureichenden Arbeitsspeichers führt. Ist dies bei Ihnen der Fall, können Sie dies in Betracht ziehen: