Nasazení jazykových modelů v dávkových koncových bodech

PLATÍ PRO:Rozšíření Azure CLI ml v2 (aktuální)Python SDK azure-ai-ml v2 (aktuální)

Pomocí dávkových koncových bodů nasaďte modely náročné na prostředky, jako jsou jazykové modely, na textová data. V tomto kurzu se dozvíte, jak nasadit model, který dokáže provádět souhrny textu dlouhých sekvencí textu pomocí modelu z HuggingFace. Ukazuje také, jak optimalizovat odvozování pomocí HuggingFace optimum a accelerate knihoven.

O této ukázce

Model, se kterým pracujete v tomto kurzu, používá oblíbenou transformers knihovnu z HuggingFace spolu s předem natrénovaným modelem z Facebooku s architekturou BART. Model byl představen v dokumentu BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation. Tento model má následující omezení, která jsou důležitá pro nasazení:

  • Funguje s sekvencemi až 1 024 tokenů.
  • Je vyškolen pro shrnutí textu v angličtině.
  • Používá Torch jako back-end.

Příklad v tomto článku vychází z ukázek kódu obsažených v úložišti azureml-examples . Pokud chcete příkazy spustit místně, aniž byste museli kopírovat nebo vkládat YAML a další soubory, naklonujte úložiště pomocí následujících příkazů a přejděte do složky pro váš kódovací jazyk:

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

Soubory pro tento příklad jsou v:

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

Sledování v poznámkových blocích Jupyter

Tuto ukázku můžete sledovat v poznámkovém bloku Jupyter. V klonovaném úložišti otevřete poznámkový blok: text-summarization-batch.ipynb.

Požadavky

  • Předplatné Azure. Pokud ještě nemáte předplatné Azure, vytvořte si bezplatný účet.

  • Pracovní prostor služby Azure Machine Learning. Pokud chcete vytvořit pracovní prostor, přečtěte si téma Správa pracovních prostorů Služby Azure Machine Learning.

  • Následující oprávnění v pracovním prostoru Azure Machine Learning:

    • Pro vytvoření nebo správu dávkových koncových bodů a nasazení použijte roli vlastníka, přispěvatele nebo vlastní roli, která má oprávnění Microsoft.MachineLearningServices/workspaces/batchEndpoints/*.
    • Pro vytváření nasazení v Azure Resource Manageru ve skupině prostředků pracovního prostoru použijte roli Vlastník, Přispěvatel nebo Vlastní role, která má Microsoft.Resources/deployments/write oprávnění ve skupině prostředků, kde je pracovní prostor nasazený.
  • Azure Machine Learning CLI nebo sada Azure Machine Learning SDK pro Python:

    Spuštěním následujícího příkazu nainstalujte Azure CLI a mlrozšíření pro Azure Machine Learning:

    az extension add -n ml
    

    Nasazení komponent kanálu pro dávkové koncové body vyžadují rozšíření ml pro Azure CLI ve verzi 2.7 nebo novější (aktuální verze: 2.37.0). az extension update --name ml Pomocí příkazu získejte nejnovější verzi.


Připojení k pracovnímu prostoru

Pracovní prostor je prostředek nejvyšší úrovně pro Azure Machine Learning. Poskytuje centralizované místo pro práci se všemi artefakty, které vytvoříte při použití služby Azure Machine Learning. V této části se připojíte k pracovnímu prostoru, kde provádíte úkony související s nasazením.

V následujícím příkazu zadejte ID předplatného, název pracovního prostoru, název skupiny prostředků a umístění:

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

Registrace modelu

Vzhledem k velikosti modelu není součástí tohoto úložiště. Místo toho si můžete stáhnout kopii z úložiště modelů na HuggingFace. Budete potřebovat balíčky transformers a torch nainstalovat je v prostředí, které používáte.

%pip install transformers torch

Ke stažení modelu do složky modelpoužijte následující kód:

from transformers import pipeline

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

Tento model teď můžeme zaregistrovat v registru služby Azure Machine Learning:

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

Vytvoření koncového bodu

Vytvoříme dávkový koncový bod s názvem text-summarization-batch , kde nasadíme model HuggingFace pro spuštění sumarizace textu u textových souborů v angličtině.

  1. Rozhodněte se o názvu koncového bodu. Název koncového bodu končí v identifikátoru URI přidruženém k vašemu koncovému bodu. Z tohoto důvodu musí být názvy dávkových koncových bodů jedinečné v rámci oblasti Azure. Například může existovat pouze jeden dávkový koncový bod s názvem mybatchendpoint v westus2.

    V tomto případě umístíme název koncového bodu do proměnné, abychom na něj později mohli snadno odkazovat.

    ENDPOINT_NAME="text-summarization-batch"
    
  2. Nakonfigurujte svůj dávkový koncový bod

    Následující soubor YAML definuje dávkový koncový bod:

    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. Vytvořte koncový bod:

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

Vytvoření nasazení

Pojďme vytvořit nasazení, na kterém bude umístěn model:

  1. Musíme vytvořit bodovací skript, který může číst soubory CSV poskytnuté dávkovém nasazením a vrátit skóre modelu souhrnem. Následující skript provede tyto akce:

    • Označuje init funkci, která zjistí hardwarovou konfiguraci (cpu vs. GPU) a odpovídajícím způsobem model načte. Model i tokenizátor se načítají do globálních proměnných. Nepoužíváme objekt pipeline z HuggingFace kvůli omezení délky posloupností v modelu, který aktuálně používáme.
    • Všimněte si, že provádíme optimalizace modelů za účelem zlepšení výkonu pomocí optimum a accelerate knihoven. Pokud ho model nebo hardware nepodporuje, spustíme nasazení bez takových optimalizací.
    • Označuje run funkci, která se spustí pro každou minidávku, kterou poskytuje dávkové nasazení.
    • Funkce run přečte celou dávku pomocí datasets knihovny. Text, který potřebujeme sumarizovat, je ve sloupci text.
    • Metoda run iteruje přes každý řádek textu a spustí predikci. Vzhledem k tomu, že se jedná o velmi drahý model, spuštění předpovědi nad celými soubory způsobí výjimku z nedostatku paměti. Všimněte si, že se model nespustí s objektem pipeline z transformers. To se provádí s ohledem na dlouhé posloupnosti textu a omezení 1024 tokenů v podkladovém modelu, který používáme.
    • Vrátí souhrn zadaného textu.

    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
    

    Návod

    I když nasazení poskytuje soubory v minidávkách, tento skórovací skript zpracovává řádky jeden po druhém. Jedná se o běžný vzor při práci s drahými modely (například transformátory), protože pokus o načtení celé dávky a její odeslání do modelu najednou může vést k vysokému zatížení paměti na dávkový exekutor (výjimky OOM).

  2. Musíme naznačit, ve kterém prostředí nasazení spustíme. V našem případě náš model běží na Torch a vyžaduje knihovny transformers, accelerate a optimum z HuggingFace. Azure Machine Learning už má prostředí s podporou Torch a GPU k dispozici. Do souboru přidáme několik závislostí 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. Soubor conda uvedený výše můžeme použít následujícím způsobem:

    Definice prostředí je součástí souboru nasazení.

    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
    

    Důležité

    Prostředí torch200-transformers-gpu , které jsme vytvořili, vyžaduje hardwarové zařízení kompatibilní s CUDA 12.1 pro spuštění Torch 2.0 na Ubuntu 22.04. Ujistěte se, že výpočetní cluster GPU používá velikost virtuálního počítače, která podporuje CUDA 12.1 nebo novější, například Standard_NCasT4_v3.

  4. Každé nasazení běží na výpočetních clusterech. Podporují jak výpočetní clustery Azure Machine Learning (AmlCompute), tak clustery Kubernetes. V tomto příkladu může náš model těžit z akcelerace GPU, což je důvod, proč používáme cluster GPU.

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

    Poznámka:

    V tomto okamžiku nejsou účtovány poplatky za výpočet, protože cluster zůstává bez žádných uzlů, dokud se nevyvolá dávkový koncový bod a neodešle dávková úloha. Přečtěte si další informace o správě a optimalizaci nákladů na AmlCompute.

  5. Teď vytvoříme nasazení.

    Pokud chcete vytvořit nové nasazení v rámci vytvořeného koncového bodu, vytvořte YAML konfiguraci jako v následujícím příkladu. Můžete zkontrolovat, jestli schéma YAML celého dávkového koncového bodu obsahuje další vlastnosti.

    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
    

    Pak vytvořte nasazení pomocí následujícího příkazu:

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

    Důležité

    Všimnete si, že v tomto nasazení je vysoká hodnota v timeout u parametru retry_settings. Důvodem je povaha modelu, který používáme. Toto je nákladný model a odvozování na jednom řádku může trvat až 60 sekund. Parametr timeout určuje, kolik času má dávkové nasazení čekat, než skript bodování dokončí zpracování každé minidávkové dávky. Vzhledem k tomu, že náš model spouští řádek předpovědí po řádcích, může zpracování dlouhého souboru nějakou dobu trvat. Všimněte si také, že počet souborů na dávku je nastaven na 1 (mini_batch_size=1). To souvisí s povahou práce, které děláme. Zpracování jednoho souboru najednou pro každou dávku je dostatečně nákladné, aby bylo možné jeho odůvodnit. Všimněte si, že se jedná o vzor při zpracování NLP.

  6. I když můžete vyvolat konkrétní nasazení uvnitř koncového bodu, obvykle chcete vyvolat samotný koncový bod a nechat koncový bod rozhodnout, které nasazení použít. Toto nasazení se nazývá výchozí nasazení. To vám dává možnost změnit výchozí nasazení a tím změnit model obsluhující nasazení beze změny kontraktu s uživatelem vyvoláním koncového bodu. K aktualizaci výchozího nasazení použijte následující pokyny:

    DEPLOYMENT_NAME="text-summarization-hfbart"
    az ml batch-endpoint update --name $ENDPOINT_NAME --set defaults.deployment_name=$DEPLOYMENT_NAME
    
  7. Nyní je náš dávkový koncový bod připraven k použití.

Testování nasazení

Pro testování našeho koncového bodu použijeme vzorek datové sady BillSum: A Corpus for Automatic Summarization of US Legislation. Tato ukázka je součástí úložiště ve složce data. Všimněte si, že formát dat je CSV a obsah, který se má sumarizovat, je pod sloupcem text, podle očekávání modelu.

  1. Pojďme vyvolat koncový bod:

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

    Poznámka:

    jq Nástroj nemusí být nainstalován v každé instalaci. Pokyny najdete na tomto odkazu.

    Návod

    Všimněte si, že když jako vstup označíte místní cestu, data se nahrají do výchozího účtu úložiště služby Azure Machine Learning.

  2. Dávkový úkol se spustí, jakmile je příkaz vrácen. Stav úlohy můžete monitorovat, dokud se nedokončí:

    az ml job show -n $JOB_NAME --web
    
  3. Po dokončení nasazení si můžeme stáhnout předpovědi:

    K stažení předpovědí použijte následující příkaz:

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

Důležité informace o nasazení modelů, které zpracovávají text

Jak je uvedeno v některých poznámkách v tomto kurzu, zpracování textu může mít určité zvláštní vlastnosti, které vyžadují konkrétní konfiguraci pro dávkové nasazení. Při návrhu dávkového nasazení vezměte v úvahu následující skutečnosti:

  • Některé modely NLP můžou být z hlediska paměti a výpočetního času velmi nákladné. V takovém případě zvažte snížení počtu souborů zahrnutých v každé minidávce. V předchozím příkladu bylo číslo nastaveno na minimální hodnotu, 1 soubor na dávku. I když to nemusí být váš případ, vezměte v úvahu, kolik souborů může váš model najednou ohodnotit. Mějte na paměti, že vztah mezi velikostí vstupu a nároky na paměť modelu nemusí být lineární pro modely hlubokého učení.
  • Pokud váš model nedokáže zpracovat jeden soubor najednou (například v tomto příkladu), zvažte čtení vstupních dat v řádcích nebo blocích. Pokud potřebujete dosáhnout vyšší propustnosti nebo využití hardwaru, implementujte dávky na úrovni řádku.
  • timeout Nastavte hodnotu nasazení tak, aby odpovídala tomu, jak nákladný model je a kolik dat očekáváte ke zpracování. Pamatujte, že timeout označuje dobu, po kterou dávkové nasazení počká, než se váš skript bodování spustí pro danou dávku. Pokud má vaše dávka mnoho souborů nebo souborů s mnoha řádky, má to vliv na správnou hodnotu tohoto parametru.

Důležité informace o modelech MLflow, které zpracovávají text

Stejné aspekty, které jsme zmínili dříve, platí pro modely MLflow. Vzhledem k tomu, že pro nasazení modelu MLflow nepotřebujete bodovací skript, můžou některá uvedená doporučení vyžadovat jiný přístup.

  • Modely MLflow v koncových bodech služby Batch podporují čtení tabulkových dat jako vstupních dat, která můžou obsahovat dlouhé sekvence textu. Podrobnosti o podporovaných typech souborů najdete v části Podpora typů souborů.
  • Nasazení služby Batch volá funkci predikce modelu MLflow s obsahem celého souboru v datovém rámci Pandas. Pokud vstupní data obsahují mnoho řádků, je pravděpodobné, že spuštění komplexního modelu (jako je tomu v tomto kurzu) způsobí výjimku mimo paměť. Pokud se jedná o váš případ, můžete zvážit:
    • Přizpůsobte si, jak model spouští předpovědi a implementuje dávkování. Informace o přizpůsobení predikce modelu MLflow najdete viz Uložení vlastních modelů.
    • Vytvořte skript pro skórování a načtěte model pomocí mlflow.<flavor>.load_model(). Podrobnosti najdete v tématu Použití modelů MLflow se skriptem bodování.