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í)
Koncové body služby Batch je možné použít k nasazení drahých modelů, jako jsou jazykové modely, přes 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 provést optimalizaci odvozování pomocí HuggingFace optimum
a accelerate
knihoven.
O této ukázce
Model, se kterým budeme pracovat, byl sestaven pomocí oblíbených transformátorů knihovny z HuggingFace spolu s předem natrénovaným modelem z Facebooku s architekturou BART. Byla představena 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í:
- Může pracovat s sekvencemi až 1024 tokenů.
- Vytrénuje se pro shrnutí textu v angličtině.
- Budeme používat 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 napřed 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 vytváření nebo správu dávkových koncových bodů a nasazení: Použijte roli Vlastník, Přispěvatel nebo Vlastní role, která má přiřazená
Microsoft.MachineLearningServices/workspaces/batchEndpoints/*
oprávnění. - Vytváření nasazení Azure Resource Manageru ve skupině prostředků pracovního prostoru: Použijte roli Vlastník, Přispěvatel nebo Vlastní role, která má přiřazená
Microsoft.Resources/deployments/write
oprávnění ve skupině prostředků, ve které je pracovní prostor nasazený.
- Pro vytváření nebo správu dávkových koncových bodů a nasazení: Použijte roli Vlastník, Přispěvatel nebo Vlastní role, která má přiřazená
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
ml
rozšíření pro Azure Machine Learning:az extension add -n ml
Nasazení součástí kanálu pro dávkové koncové body jsou zavedena ve verzi 2.7
ml
rozšíření pro Azure CLI.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, ve kterém provádíte úlohy nasazení.
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 ho v tomto úložišti nezahrnuli. Místo toho si můžete stáhnout kopii z centra modelu 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 model
použijte následující kód:
from transformers import pipeline
model = pipeline("summarization", model="facebook/bart-large-cnn")
model_local_path = 'model'
summarizer.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ě.
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
vwestus2
.Konfigurace dávkového koncového bodu
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
Vytvořte koncový bod:
Vytvoření nasazení
Pojďme vytvořit nasazení, které je hostitelem modelu:
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. K určení omezení v posloupnosti modelu, který aktuálně používáme, nepoužívámepipeline
objekt z HuggingFace. - Všimněte si, že provádíme optimalizace modelů za účelem zlepšení výkonu pomocí
optimum
aaccelerate
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 sloupcitext
. - 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 mimo paměť. Všimněte si, že se model nespustí s objektempipeline
ztransformers
. 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.
kód/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
I když nasazení poskytuje soubory v minidávkách, tento skript bodování zpracovává současně jeden řádek. Jedná se o běžný vzor při práci s drahými modely (například transformátory) při pokusu o načtení celé dávky a jeho odeslání do modelu najednou může vést k vysokému zatížení paměti na dávkové exekutor (exekuce OOM).
- Označuje
Musíme určit, ve kterém prostředí nasazení spustíme. V našem případě náš model běží a
Torch
vyžaduje knihovnytransformers
,accelerate
aoptimum
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]
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 11.8 pro spuštění Torch 2.0 a Ubuntu 20.04. Pokud vaše zařízení GPU tuto verzi CUDA nepodporuje, můžete zkontrolovat alternativnítorch113-conda.yaml
prostředí Conda (dostupné také v úložišti), na kterém běží Torch 1.3 přes Ubuntu 18.04 s CUDA 10.1. U této konfigurace se ale akcelerace s využitímoptimum
knihovenaccelerate
nepodporuje.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:
Za výpočetní prostředky se vám v tomto okamžiku nebudou účtovat poplatky, protože cluster zůstane na 0 uzlech, dokud se nevyvolá dávkový koncový bod a neodesílají se úloha dávkového vyhodnocování. Přečtěte si další informace o správě a optimalizaci nákladů na AmlCompute.
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 tomto nasazení si všimnete vysoké hodnoty v
timeout
parametruretry_settings
. Důvodem je povaha modelu, který používáme. Jedná se o velmi drahý model a odvozování na jednom řádku může trvat až 60 sekund. Parametrytimeout
řídí, kolik času má dávkové nasazení čekat na dokončení zpracování jednotlivých minidávkových skriptů. 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 je opět v souvislosti s povahou práce, které děláme. Zpracování jednoho souboru najednou na dávku je dostatečně nákladné, aby bylo možné ho odůvodnit. Všimněte si, že se jedná o vzor při zpracování NLP.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:
V tuto chvíli 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.
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.Tip
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.
Dávková úloha se spustí hned po vrácení příkazu. Stav úlohy můžete monitorovat, dokud se nedokončí:
Po dokončení nasazení si můžeme stáhnout předpovědi:
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é specifika, 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 převzato na minimum, 1 soubor na dávku. I když to nemusí být váš případ, vezměte v úvahu, kolik souborů může váš model pokaždé skóre. 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í. Mějte natimeout
paměti, že značí dobu, po kterou dávkové nasazení počká, než se 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 výše, platí pro modely MLflow. Vzhledem k tomu, že pro nasazení modelu MLflow nepotřebujete zadat 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á mohou 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í odvozování modelu MLflow najdete v tématu Protokolování vlastních modelů.
- Vytvořte bodovací skript a načtěte model pomocí
mlflow.<flavor>.load_model()
. Podrobnosti najdete v tématu Použití modelů MLflow se skriptem bodování.