Delen via


Taalmodellen implementeren in batch-eindpunten

VAN TOEPASSING OP:Azure CLI ml extension v2 (current)Python SDK azure-ai-ml v2 (current)

Batch-eindpunten kunnen worden gebruikt voor het implementeren van dure modellen, zoals taalmodellen, via tekstgegevens. In deze zelfstudie leert u hoe u een model implementeert dat tekstsamenvatting van lange reeksen tekst kan uitvoeren met behulp van een model van HuggingFace. Ook ziet u hoe u deductieoptimalisatie kunt uitvoeren met HuggingFace optimum en accelerate bibliotheken.

Over dit voorbeeld

Het model waarmee we gaan werken, is gebouwd met behulp van de populaire bibliotheektransformatoren van HuggingFace, samen met een vooraf getraind model van Facebook met de BART-architectuur. Het werd geïntroduceerd in het document BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation. Dit model heeft de volgende beperkingen, die belangrijk zijn om rekening te houden met de implementatie:

  • Het kan werken met reeksen tot 1024 tokens.
  • Het is getraind voor samenvatting van tekst in het Engels.
  • We gaan Torch gebruiken als back-end.

Het voorbeeld in dit artikel is gebaseerd op codevoorbeelden in de opslagplaats azureml-examples . Als u de opdrachten lokaal wilt uitvoeren zonder YAML en andere bestanden te hoeven kopiëren/plakken, kloont u eerst de opslagplaats en wijzigt u vervolgens mappen in de map:

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

De bestanden voor dit voorbeeld bevinden zich in:

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

Volgen in Jupyter Notebooks

U kunt dit voorbeeld volgen in een Jupyter Notebook. Open in de gekloonde opslagplaats het notebook: text-summarization-batch.ipynb.

Vereisten

Voordat u de stappen in dit artikel volgt, moet u ervoor zorgen dat u over de volgende vereisten beschikt:

  • Een Azure-abonnement. Als u nog geen abonnement op Azure hebt, maak dan een gratis account aan voordat u begint. Probeer de gratis of betaalde versie van Azure Machine Learning.

  • Een Azure Machine Learning-werkruimte. Als u nog geen werkruimte hebt, gebruikt u de stappen in het artikel Azure Machine Learning-werkruimten beheren om er een te maken.

  • Zorg ervoor dat u over de volgende machtigingen in de werkruimte beschikt:

    • Batch-eindpunten en -implementaties maken of beheren: gebruik een eigenaar, inzender of aangepaste rol die dit toestaat Microsoft.MachineLearningServices/workspaces/batchEndpoints/*.

    • ARM-implementaties maken in de resourcegroep van de werkruimte: gebruik een eigenaar, inzender of aangepaste rol die het mogelijk maakt Microsoft.Resources/deployments/write in de resourcegroep waarin de werkruimte wordt geïmplementeerd.

  • U moet de volgende software installeren om te kunnen werken met Azure Machine Learning:

    De Azure CLI en de mlextensie voor Azure Machine Learning.

    az extension add -n ml
    

    Notitie

    Implementaties van pijplijnonderdelen voor Batch-eindpunten zijn geïntroduceerd in versie 2.7 van de ml extensie voor Azure CLI. Gebruik az extension update --name ml deze om de laatste versie ervan op te halen.

Verbinding maken met uw werkruimte

De werkruimte is de resource op het hoogste niveau voor Azure Machine Learning en biedt een gecentraliseerde werkplek met alle artefacten die u maakt in Azure Machine Learning. In deze sectie maken we verbinding met de werkruimte waarin u implementatietaken uitvoert.

Geef de waarden voor uw abonnements-id, werkruimte, locatie en resourcegroep door in de volgende code:

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

Het model registreren

Vanwege de grootte van het model is het niet opgenomen in deze opslagplaats. In plaats daarvan kunt u een kopie downloaden van de hub van het HuggingFace-model. U hebt de pakketten transformers nodig en torch geïnstalleerd in de omgeving die u gebruikt.

%pip install transformers torch

Gebruik de volgende code om het model te downloaden naar een map model:

from transformers import pipeline

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

We kunnen dit model nu registreren in het Azure Machine Learning-register:

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

Het eindpunt maken

We gaan een batch-eindpunt maken met de naam text-summarization-batch waar het HuggingFace-model moet worden geïmplementeerd om tekstsamenvatting uit te voeren op tekstbestanden in het Engels.

  1. Bepaal de naam van het eindpunt. De naam van het eindpunt eindigt in de URI die is gekoppeld aan uw eindpunt. Daarom moeten namen van batcheindpunten uniek zijn binnen een Azure-regio. Er kan bijvoorbeeld slechts één batcheindpunt zijn met de naam mybatchendpoint in westus2.

    In dit geval plaatsen we de naam van het eindpunt in een variabele, zodat we er later eenvoudig naar kunnen verwijzen.

    ENDPOINT_NAME="text-summarization-batch"
    
  2. Uw batch-eindpunt configureren

    Het volgende YAML-bestand definieert een batch-eindpunt:

    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. Maak het eindpunt:

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

De implementatie maken

Laten we de implementatie maken die als host fungeert voor het model:

  1. We moeten een scorescript maken waarmee de CSV-bestanden die door de batchimplementatie worden geleverd, kunnen worden gelezen en de scores van het model met de samenvatting kunnen worden geretourneerd. Met het volgende script worden deze acties uitgevoerd:

    • Geeft een init functie aan die de hardwareconfiguratie (CPU versus GPU) detecteert en het model dienovereenkomstig laadt. Zowel het model als de tokenizer worden geladen in globale variabelen. We gebruiken pipeline geen object van HuggingFace om rekening te houden met de beperking in de reeks lengten van het model dat we momenteel gebruiken.
    • U ziet dat we modeloptimalisaties uitvoeren om de prestaties te verbeteren met behulp van optimum en accelerate bibliotheken. Als het model of de hardware dit niet ondersteunt, voeren we de implementatie uit zonder dergelijke optimalisaties.
    • Geeft een run functie aan die wordt uitgevoerd voor elke minibatch die de batch-implementatie biedt.
    • De run functie leest de volledige batch met behulp van de datasets bibliotheek. De tekst die we moeten samenvatten, bevindt zich in de kolom text.
    • De run methode doorloopt elk van de rijen van de tekst en voert de voorspelling uit. Omdat dit een zeer duur model is, leidt het uitvoeren van de voorspelling over hele bestanden tot een uitzondering met onvoldoende geheugen. U ziet dat het model niet wordt uitgevoerd met het pipeline object van transformers. Dit wordt gedaan om rekening te houden met lange reeksen tekst en de beperking van 1024 tokens in het onderliggende model dat we gebruiken.
    • Hiermee wordt de samenvatting van de opgegeven tekst geretourneerd.

    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
    

    Tip

    Hoewel bestanden worden geleverd in minibatches door de implementatie, verwerkt dit scorescript één rij tegelijk. Dit is een veelvoorkomend patroon bij het omgaan met dure modellen (zoals transformatoren) als het laden van de hele batch en het tegelijk naar het model verzenden, kan leiden tot een hoge geheugenbelasting op de batchuitvoering (OOM-exeptions).

  2. We moeten aangeven over welke omgeving we de implementatie gaan uitvoeren. In ons geval wordt ons model uitgevoerd Torch en vereist het de bibliotheken transformers, accelerateen optimum van HuggingFace. Azure Machine Learning heeft al een omgeving met ondersteuning voor Torch en GPU. We gaan gewoon een aantal afhankelijkheden toevoegen aan een conda.yaml bestand.

    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. We kunnen het eerder genoemde Conda-bestand als volgt gebruiken:

    De omgevingsdefinitie is opgenomen in het implementatiebestand.

    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
    

    Belangrijk

    Voor de omgeving torch200-transformers-gpu die we hebben gemaakt, is een CUDA 11.8-compatibel hardwareapparaat vereist om Torch 2.0 en Ubuntu 20.04 uit te voeren. Als uw GPU-apparaat deze versie van CUDA niet ondersteunt, kunt u de alternatieve torch113-conda.yaml Conda-omgeving controleren (ook beschikbaar in de opslagplaats), waarop Torch 1.3 wordt uitgevoerd via Ubuntu 18.04 met CUDA 10.1. Versnelling met behulp van de optimum en accelerate bibliotheken wordt echter niet ondersteund voor deze configuratie.

  4. Elke implementatie wordt uitgevoerd op rekenclusters. Ze ondersteunen zowel Azure Machine Learning Compute-clusters (AmlCompute) als Kubernetes-clusters. In dit voorbeeld kan ons model profiteren van GPU-versnelling. Daarom gebruiken we een GPU-cluster.

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

    Notitie

    Er worden op dit moment geen kosten in rekening gebracht voor berekening omdat het cluster op 0 knooppunten blijft staan totdat een batcheindpunt wordt aangeroepen en er een batchscoretaak wordt verzonden. Meer informatie over het beheren en optimaliseren van kosten voor AmlCompute.

  5. Nu gaan we de implementatie maken.

    Als u een nieuwe implementatie wilt maken onder het gemaakte eindpunt, maakt u een YAML configuratie zoals hieronder. U kunt het YAML-schema voor het volledige batcheindpunt controleren op extra eigenschappen.

    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
    

    Maak vervolgens de implementatie met de volgende opdracht:

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

    Belangrijk

    U ziet in deze implementatie een hoge waarde in timeout de parameter retry_settings. De reden hiervoor is dat het te wijten is aan de aard van het model dat we uitvoeren. Dit is een zeer duur model en deductie op één rij kan tot 60 seconden duren. De timeout parameters bepalen hoeveel tijd de Batch-implementatie moet wachten totdat het scorescript klaar is met het verwerken van elke minibatch. Omdat het model voorspellingsrij per rij uitvoert, kan het verwerken van een lang bestand enige tijd duren. U ziet ook dat het aantal bestanden per batch is ingesteld op 1 (mini_batch_size=1). Dit is weer gerelateerd aan de aard van het werk dat we doen. Het verwerken van één bestand per batch is duur genoeg om het te rechtvaardigen. U zult merken dat dit een patroon is in NLP-verwerking.

  6. Hoewel u een specifieke implementatie binnen een eindpunt kunt aanroepen, wilt u meestal het eindpunt zelf aanroepen en het eindpunt laten bepalen welke implementatie moet worden gebruikt. Deze implementatie heet de standaardimplementatie. Dit biedt u de mogelijkheid om de standaardimplementatie te wijzigen en daarom het model te wijzigen dat de implementatie bedient zonder het contract te wijzigen met de gebruiker die het eindpunt aanroept. Gebruik de volgende instructie om de standaardimplementatie bij te werken:

    DEPLOYMENT_NAME="text-summarization-hfbart"
    az ml batch-endpoint update --name $ENDPOINT_NAME --set defaults.deployment_name=$DEPLOYMENT_NAME
    
  7. Op dit moment is ons batcheindpunt gereed om te worden gebruikt.

De implementatie testen

Voor het testen van ons eindpunt gebruiken we een voorbeeld van de gegevensset BillSum: A Corpus for Automatic Sumization of US Legislation. Dit voorbeeld is opgenomen in de opslagplaats in de map data. U ziet dat de indeling van de gegevens CSV is en dat de inhoud die moet worden samengevat, zich onder de kolom textbevindt, zoals verwacht door het model.

  1. Laten we het eindpunt aanroepen:

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

    Notitie

    Het hulpprogramma jq is mogelijk niet geïnstalleerd op elke installatie. In deze koppeling vindt u instructies.

    Tip

    U ziet dat door een lokaal pad als invoer aan te geven, de gegevens worden geüpload naar het standaardopslagaccount van Azure Machine Learning.

  2. Er wordt een batchtaak gestart zodra de opdracht wordt geretourneerd. U kunt de status van de taak controleren totdat deze is voltooid:

    az ml job show -n $JOB_NAME --web
    
  3. Zodra de implementatie is voltooid, kunnen we de voorspellingen downloaden:

    Gebruik de volgende opdracht om de voorspellingen te downloaden:

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

Overwegingen bij het implementeren van modellen die tekst verwerken

Zoals vermeld in sommige notities in deze zelfstudie, kan het verwerken van tekst enkele bijzonderheden hebben die specifieke configuratie vereisen voor batchimplementaties. Houd rekening met het volgende bij het ontwerpen van de batchimplementatie:

  • Sommige NLP-modellen kunnen erg duur zijn in termen van geheugen en rekentijd. Als dit het geval is, kunt u overwegen het aantal bestanden in elke minibatch te verlagen. In het bovenstaande voorbeeld is het getal naar het minimum, 1 bestand per batch genomen. Hoewel dit mogelijk niet het geval is, moet u rekening houden met het aantal bestanden dat uw model op elk moment kan scoren. Houd er rekening mee dat de relatie tussen de grootte van de invoer en de geheugenvoetafdruk van uw model mogelijk niet lineair is voor deep learning-modellen.
  • Als uw model niet eens één bestand tegelijk kan verwerken (zoals in dit voorbeeld), kunt u overwegen de invoergegevens in rijen/segmenten te lezen. Implementeer batchverwerking op rijniveau als u een hogere doorvoer of hardwaregebruik wilt bereiken.
  • Stel de timeout waarde van uw implementatie in overeenstemming met hoe duur uw model is en hoeveel gegevens u verwacht te verwerken. Houd er rekening mee dat de timeout tijd aangeeft waarop de batchimplementatie wacht totdat uw scorescript voor een bepaalde batch is uitgevoerd. Als uw batch veel bestanden of bestanden met veel rijen heeft, heeft dit invloed op de juiste waarde van deze parameter.

Overwegingen voor MLflow-modellen die tekst verwerken

Dezelfde overwegingen die hierboven worden genoemd, zijn van toepassing op MLflow-modellen. Omdat u echter geen scorescript hoeft op te geven voor de implementatie van uw MLflow-model, is voor sommige van de vermelde aanbevelingen mogelijk een andere benadering vereist.

  • MLflow-modellen in Batch-eindpunten ondersteunen het lezen van tabelgegevens als invoergegevens, die lange reeksen tekst kunnen bevatten. Zie de ondersteuning voor bestandstypen voor meer informatie over welke bestandstypen worden ondersteund.
  • Batch-implementaties roepen de voorspellingsfunctie van uw MLflow-model aan met de inhoud van een volledig bestand in als Pandas-gegevensframe. Als uw invoergegevens veel rijen bevatten, is de kans groot dat het uitvoeren van een complex model (zoals in deze zelfstudie) resulteert in een uitzondering met onvoldoende geheugen. Als dit uw geval is, kunt u het volgende overwegen:
    • Pas aan hoe uw model voorspellingen uitvoert en batchverwerking implementeert. Zie Aangepaste modellen vastleggen voor meer informatie over het aanpassen van de deductie van het MLflow-model.
    • Een scorescript maken en uw model laden met behulp van mlflow.<flavor>.load_model(). Zie MLflow-modellen gebruiken met een scorescript voor meer informatie.