Distribuera språkmodeller i batchslutpunkter
GÄLLER FÖR:Azure CLI ml extension v2 (current)Python SDK azure-ai-ml v2 (aktuell)
Batchslutpunkter kan användas för att distribuera dyra modeller, till exempel språkmodeller, över textdata. I den här självstudien får du lära dig hur du distribuerar en modell som kan utföra textsammanfattning av långa textsekvenser med hjälp av en modell från HuggingFace. Den visar också hur du gör slutsatsdragningsoptimering med huggingFace optimum
och accelerate
bibliotek.
Om det här exemplet
Modellen som vi ska arbeta med byggdes med hjälp av de populära bibliotekstransformatorerna från HuggingFace tillsammans med en förtränad modell från Facebook med BART-arkitekturen. Den introducerades i tidningen BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation. Den här modellen har följande begränsningar, som är viktiga att tänka på för distributionen:
- Det kan fungera med sekvenser upp till 1 024 token.
- Den tränas för sammanfattning av text på engelska.
- Vi ska använda Torch som en serverdel.
Exemplet i den här artikeln baseras på kodexempel som finns på lagringsplatsen azureml-examples . Om du vill köra kommandona lokalt utan att behöva kopiera/klistra in YAML och andra filer klonar du först lagringsplatsen och ändrar sedan kataloger till mappen:
git clone https://github.com/Azure/azureml-examples --depth 1
cd azureml-examples/cli
Filerna för det här exemplet finns i:
cd endpoints/batch/deploy-models/huggingface-text-summarization
Följ med i Jupyter Notebooks
Du kan följa det här exemplet i en Jupyter Notebook. På den klonade lagringsplatsen öppnar du notebook-filen: text-summarization-batch.ipynb.
Förutsättningar
En Azure-prenumeration. Om du inte har någon Azure-prenumeration kan du skapa ett kostnadsfritt konto innan du börjar. Prova den kostnadsfria eller betalda versionen av Azure Mašinsko učenje.
En Azure Machine Learning-arbetsyta. Information om hur du skapar en arbetsyta finns i Hantera Azure Mašinsko učenje-arbetsytor.
Kontrollera att du har följande behörigheter på Mašinsko učenje-arbetsytan:
- Skapa eller hantera batchslutpunkter och distributioner: Använd en ägare, deltagare eller anpassad roll som tillåter
Microsoft.MachineLearningServices/workspaces/batchEndpoints/*
. - Skapa Azure Resource Manager-distributioner i arbetsytans resursgrupp: Använd en roll som ägare, deltagare eller anpassad som tillåter
Microsoft.Resources/deployments/write
i den resursgrupp där arbetsytan distribueras.
- Skapa eller hantera batchslutpunkter och distributioner: Använd en ägare, deltagare eller anpassad roll som tillåter
Installera följande programvara för att arbeta med Mašinsko učenje:
Kör följande kommando för att installera Azure CLI och
ml
tillägget för Azure Mašinsko učenje:az extension add -n ml
Distributioner av pipelinekomponenter för Batch-slutpunkter introduceras i version 2.7 av
ml
tillägget för Azure CLI.az extension update --name ml
Använd kommandot för att hämta den senaste versionen.
Anslut till din arbetsyta
Arbetsytan är resursen på den översta nivån för Mašinsko učenje. Den ger en central plats där du kan arbeta med alla artefakter som du skapar när du använder Mašinsko učenje. I det här avsnittet ansluter du till arbetsytan där du utför dina distributionsuppgifter.
I följande kommando anger du värdena för ditt prenumerations-ID, arbetsyta, plats och resursgrupp:
az account set --subscription <subscription>
az configure --defaults workspace=<workspace> group=<resource-group> location=<location>
Registrera modellen
På grund av modellens storlek har den inte inkluderats i den här lagringsplatsen. I stället kan du ladda ned en kopia från HuggingFace-modellens hubb. Du behöver paketen transformers
och torch
installeras i den miljö som du använder.
%pip install transformers torch
Använd följande kod för att ladda ned modellen till en mapp model
:
from transformers import pipeline
model = pipeline("summarization", model="facebook/bart-large-cnn")
model_local_path = 'model'
summarizer.save_pretrained(model_local_path)
Nu kan vi registrera den här modellen i Azure Mašinsko učenje-registret:
MODEL_NAME='bart-text-summarization'
az ml model create --name $MODEL_NAME --path "model"
Skapa slutpunkten
Vi ska skapa en batchslutpunkt med namnet text-summarization-batch
där huggingFace-modellen ska distribueras för att köra textsammanfattning på textfiler på engelska.
Bestäm namnet på slutpunkten. Namnet på slutpunkten hamnar i den URI som är associerad med slutpunkten. Därför måste batchslutpunktsnamn vara unika i en Azure-region. Det kan till exempel bara finnas en batchslutpunkt med namnet
mybatchendpoint
iwestus2
.Konfigurera batchslutpunkten
Skapa slutpunkten:
Skapa distributionen
Nu ska vi skapa den distribution som är värd för modellen:
Vi måste skapa ett bedömningsskript som kan läsa CSV-filerna som tillhandahålls av batchdistributionen och returnera poängen för modellen med sammanfattningen. Följande skript utför följande åtgärder:
- Anger en
init
funktion som identifierar maskinvarukonfigurationen (CPU jämfört med GPU) och läser in modellen i enlighet med detta. Både modellen och tokeniseraren läses in i globala variabler. Vi använder inte ettpipeline
-objekt från HuggingFace för att ta hänsyn till begränsningen i sekvensen för den modell som vi använder för närvarande. - Observera att vi utför modelloptimeringar för att förbättra prestandan med hjälp av
optimum
ochaccelerate
bibliotek. Om modellen eller maskinvaran inte stöder den kör vi distributionen utan sådana optimeringar. - Anger en
run
funktion som körs för varje mini-batch som batchdistributionen tillhandahåller. - Funktionen
run
läser hela batchen med hjälp avdatasets
biblioteket. Texten som vi behöver sammanfatta finns i kolumnentext
. - Metoden
run
itererar över var och en av raderna i texten och kör förutsägelsen. Eftersom det här är en mycket dyr modell resulterar körningen av förutsägelsen över hela filer i ett undantagsfel utan minne. Observera att modellen inte körs med objektetpipeline
fråntransformers
. Detta görs för att ta hänsyn till långa textsekvenser och begränsningen för 1 024 token i den underliggande modellen som vi använder. - Den returnerar sammanfattningen av den angivna texten.
kod/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
Dricks
Även om filer tillhandahålls i mini-batchar av distributionen bearbetar det här bedömningsskriptet en rad i taget. Detta är ett vanligt mönster när du hanterar dyra modeller (till exempel transformatorer) eftersom försök att läsa in hela batchen och skicka den till modellen på en gång kan leda till hög minnesbelastning på batchexekutor (OOM-exeptions).
- Anger en
Vi måste ange över vilken miljö vi ska köra distributionen. I vårt fall körs vår modell på
Torch
och den kräver bibliotekentransformers
,accelerate
ochoptimum
från HuggingFace. Azure Mašinsko učenje har redan en miljö med stöd för Torch och GPU. Vi ska bara lägga till ett par beroenden i enconda.yaml
fil.miljö/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]
Vi kan använda conda-filen som nämnts tidigare enligt följande:
Miljödefinitionen ingår i distributionsfilen.
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
Viktigt!
torch200-transformers-gpu
Miljön som vi har skapat kräver en CUDA 11.8-kompatibel maskinvaruenhet för att köra Torch 2.0 och Ubuntu 20.04. Om GPU-enheten inte stöder den här versionen av CUDA kan du kontrollera den alternativatorch113-conda.yaml
conda-miljön (även tillgänglig på lagringsplatsen), som kör Torch 1.3 över Ubuntu 18.04 med CUDA 10.1. Acceleration med hjälp av bibliotekenoptimum
ochaccelerate
stöds dock inte i den här konfigurationen.Varje distribution körs på beräkningskluster. De stöder både Azure Mašinsko učenje Compute-kluster (AmlCompute) eller Kubernetes-kluster. I det här exemplet kan vår modell dra nytta av GPU-acceleration, vilket är anledningen till att vi använder ett GPU-kluster.
az ml compute create -n gpu-cluster --type amlcompute --size STANDARD_NV6 --min-instances 0 --max-instances 2
Kommentar
Du debiteras inte för beräkning just nu eftersom klustret ligger kvar på 0 noder förrän en batchslutpunkt anropas och ett batchbedömningsjobb skickas. Läs mer om att hantera och optimera kostnader för AmlCompute.
Nu ska vi skapa distributionen.
Om du vill skapa en ny distribution under den skapade slutpunkten skapar du en
YAML
konfiguration som följande. Du kan kontrollera YAML-schemat för den fullständiga batchslutpunkten för extra egenskaper.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
Skapa sedan distributionen med följande kommando:
az ml batch-deployment create --file deployment.yml --endpoint-name $ENDPOINT_NAME --set-default
Viktigt!
I den här distributionen ser du ett högt värde i
timeout
parameternretry_settings
. Anledningen till det beror på vilken typ av modell vi kör. Detta är en mycket dyr modell och slutsatsdragning på en enda rad kan ta upp till 60 sekunder. Parametrarnatimeout
styr hur lång tid Batch-distributionen ska vänta tills bedömningsskriptet har slutfört bearbetningen av varje mini-batch. Eftersom vår modell kör förutsägelser rad för rad kan det ta tid att bearbeta en lång fil. Observera också att antalet filer per batch är inställt på 1 (mini_batch_size=1
). Detta är återigen relaterat till arten av det arbete vi utför. Det är tillräckligt dyrt att bearbeta en fil i taget per batch för att motivera den. Du kommer att märka att detta är ett mönster i NLP-bearbetning.Även om du kan anropa en specifik distribution i en slutpunkt vill du vanligtvis anropa själva slutpunkten och låta slutpunkten bestämma vilken distribution som ska användas. En sådan distribution heter "standard"-distributionen. Detta ger dig möjlighet att ändra standarddistributionen och därmed ändra modellen som betjänar distributionen utan att ändra kontraktet med användaren som anropar slutpunkten. Använd följande instruktion för att uppdatera standarddistributionen:
Nu är vår batchslutpunkt redo att användas.
Testa distributionen
För att testa vår slutpunkt ska vi använda ett exempel på datamängden BillSum: A Corpus for Automatic Summarization of US Legislation. Det här exemplet ingår i lagringsplatsen i mappen data
. Observera att formatet för data är CSV och att innehållet som ska sammanfattas finns under kolumnen text
, som förväntat av modellen.
Nu ska vi anropa slutpunkten:
JOB_NAME=$(az ml batch-endpoint invoke --name $ENDPOINT_NAME --input data --input-type uri_folder --query name -o tsv)
Kommentar
Verktyget
jq
kanske inte installeras på varje installation. Du kan få instruktioner i den här länken.Dricks
Observera att genom att ange en lokal sökväg som indata laddas data upp till Azure Mašinsko učenje standardlagringskonto.
Ett batchjobb startas så snart kommandot returnerar. Du kan övervaka statusen för jobbet tills det har slutförts:
När distributionen är klar kan vi ladda ned förutsägelserna:
Överväganden vid distribution av modeller som bearbetar text
Som nämnts i några av anteckningarna i den här självstudien kan bearbetning av text ha vissa egenheter som kräver specifik konfiguration för batchdistributioner. Tänk på följande när du utformar batchdistributionen:
- Vissa NLP-modeller kan vara mycket dyra när det gäller minne och beräkningstid. Om så är fallet bör du överväga att minska antalet filer som ingår i varje mini-batch. I exemplet ovan togs talet till minst 1 fil per batch. Även om detta kanske inte är ditt fall bör du ta hänsyn till hur många filer din modell kan göra poäng på varje gång. Tänk på att relationen mellan indatastorleken och din modells minnesfotavtryck kanske inte är linjär för djupinlärningsmodeller.
- Om din modell inte ens kan hantera en fil i taget (som i det här exemplet) kan du läsa indata i rader/segment. Implementera batchbearbetning på radnivå om du behöver uppnå högre dataflöde eller maskinvaruanvändning.
- Ange värdet för distributionen
timeout
enligt överenskommelse till hur dyr din modell är och hur mycket data du förväntar dig att bearbeta. Kom ihåg atttimeout
anger den tid batchdistributionen skulle vänta på att ditt bedömningsskript skulle köras för en viss batch. Om batchen har många filer eller filer med många rader påverkar detta det rätta värdet för den här parametern.
Överväganden för MLflow-modeller som bearbetar text
Samma överväganden som nämns ovan gäller för MLflow-modeller. Men eftersom du inte behöver ange ett bedömningsskript för din MLflow-modelldistribution kan vissa av de rekommendationer som nämns kräva en annan metod.
- MLflow-modeller i Batch-slutpunkter stöder läsning av tabelldata som indata, som kan innehålla långa textsekvenser. Mer information om vilka filtyper som stöds finns i Stöd för filtyper.
- Batchdistributioner anropar MLflow-modellens förutsägelsefunktion med innehållet i en hel fil i som Pandas-dataram. Om dina indata innehåller många rader är chansen stor att körningen av en komplex modell (som den som visas i den här självstudien) resulterar i ett undantag utan minne. Om så är fallet kan du överväga:
- Anpassa hur din modell kör förutsägelser och implementera batchbearbetning. Mer information om hur du anpassar MLflow-modellens slutsatsdragning finns i Loggning av anpassade modeller.
- Skapa ett bedömningsskript och läs in din modell med hjälp av
mlflow.<flavor>.load_model()
. Mer information finns i Använda MLflow-modeller med ett bedömningsskript .