Best practices voor het testen van real-time deductie-eindpunten van Amazon SageMaker

Best practices voor het testen van real-time deductie-eindpunten van Amazon SageMaker

Bronknooppunt: 1889926

Amazon Sage Maker is een volledig beheerde machine learning-service (ML). Met SageMaker kunnen datawetenschappers en ontwikkelaars snel en eenvoudig ML-modellen bouwen en trainen, en deze vervolgens direct implementeren in een productieklare gehoste omgeving. Het biedt een geïntegreerde Jupyter authoring notebook-instantie voor eenvoudige toegang tot uw gegevensbronnen voor verkenning en analyse, zodat u geen servers hoeft te beheren. Het biedt ook gemeenschappelijke ML-algoritmen die zijn geoptimaliseerd om efficiënt te werken tegen extreem grote gegevens in een gedistribueerde omgeving.

SageMaker real-time inferentie is ideaal voor workloads die real-time, interactieve vereisten met lage latentie hebben. Met real-time inferentie van SageMaker kunt u REST-eindpunten implementeren die worden ondersteund door een specifiek instantietype met een bepaalde hoeveelheid rekenkracht en geheugen. Het implementeren van een real-time eindpunt van SageMaker is voor veel klanten slechts de eerste stap op weg naar productie. We willen de prestaties van het eindpunt kunnen maximaliseren om doeltransacties per seconde (TPS) te bereiken terwijl we ons houden aan de latentievereisten. Een groot deel van prestatieoptimalisatie voor inferentie is ervoor zorgen dat u het juiste instantietype selecteert en telt om een ​​eindpunt te ondersteunen.

Dit bericht beschrijft de best practices voor het testen van een SageMaker-eindpunt om de juiste configuratie te vinden voor het aantal instanties en de grootte. Dit kan ons helpen de minimale vereisten voor ingerichte instanties te begrijpen om te voldoen aan onze latentie- en TPS-vereisten. Van daaruit duiken we in hoe u de statistieken en prestaties van het SageMaker-eindpunt kunt volgen en begrijpen Amazon Cloud Watch statistieken.

We benchmarken eerst de prestaties van ons model op een enkele instantie om de TPS te identificeren die het aankan volgens onze aanvaardbare latentievereisten. Vervolgens extrapoleren we de bevindingen om te beslissen over het aantal instanties dat we nodig hebben om ons productieverkeer af te handelen. Ten slotte simuleren we verkeer op productieniveau en zetten we belastingstests op voor een real-time SageMaker-eindpunt om te bevestigen dat ons eindpunt de belasting op productieniveau aankan. De volledige codeset voor het voorbeeld is hieronder beschikbaar GitHub-repository.

Overzicht van de oplossing

Voor deze functie zetten we een pre-trained Knuffelend gezicht DistilBERT model van het Knuffelen Gezicht Hub. Dit model kan een aantal taken uitvoeren, maar we sturen een payload specifiek voor sentimentanalyse en tekstclassificatie. Met deze voorbeeldlading streven we naar 1000 TPS.

Implementeer een real-time eindpunt

In dit bericht wordt ervan uitgegaan dat u bekend bent met het implementeren van een model. Verwijzen naar Maak uw eindpunt en implementeer uw model om de internals achter het hosten van een eindpunt te begrijpen. Voor nu kunnen we snel naar dit model verwijzen in de Hugging Face Hub en een realtime eindpunt implementeren met het volgende codefragment:

# Hub Model configuration. https://huggingface.co/models
hub = { 'HF_MODEL_ID':'distilbert-base-uncased', 'HF_TASK':'text-classification'
} # create Hugging Face Model Class
huggingface_model = HuggingFaceModel(
transformers_version='4.17.0',
pytorch_version='1.10.2',
py_version='py38',
env=hub,
role=role,
) # deploy model to SageMaker Inference
predictor = huggingface_model.deploy(
initial_instance_count=1, # number of instances
instance_type='ml.m5.12xlarge' # ec2 instance type
)

Laten we ons eindpunt snel testen met de voorbeeldlading die we willen gebruiken voor het testen van de belasting:


import boto3
import json
client = boto3.client('sagemaker-runtime')
content_type = "application/json"
request_body = {'inputs': "I am super happy right now."}
data = json.loads(json.dumps(request_body))
payload = json.dumps(data)
response = client.invoke_endpoint(
EndpointName=predictor.endpoint_name,
ContentType=content_type,
Body=payload)
result = response['Body'].read()
result

Merk op dat we het eindpunt ondersteunen met een single Amazon Elastic Compute-cloud (Amazon EC2) instantie van het type ml.m5.12xlarge, die 48 vCPU en 192 GiB geheugen bevat. Het aantal vCPU's is een goede indicatie van de gelijktijdigheid die de instantie aankan. Over het algemeen wordt aanbevolen om verschillende instantietypen te testen om er zeker van te zijn dat we een instantie hebben met bronnen die correct worden gebruikt. Raadpleeg voor een volledige lijst met SageMaker-instanties en hun bijbehorende rekenkracht voor real-time inferentie Amazon SageMaker-prijzen.

Statistieken om bij te houden

Voordat we kunnen beginnen met het testen van de belasting, is het essentieel om te begrijpen welke statistieken moeten worden gevolgd om inzicht te krijgen in de prestatie-uitval van uw SageMaker-eindpunt. CloudWatch is de primaire logboektool die SageMaker gebruikt om u te helpen de verschillende statistieken te begrijpen die de prestaties van uw eindpunt beschrijven. U kunt CloudWatch-logboeken gebruiken om uw eindpuntaanroepen te debuggen; alle logboek- en afdrukverklaringen die u in uw inferentiecode hebt, worden hier vastgelegd. Voor meer informatie, zie Hoe Amazon CloudWatch werkt.

Er zijn twee verschillende soorten statistieken die CloudWatch voor SageMaker behandelt: instantieniveau en aanroepstatistieken.

Statistieken op instantieniveau

De eerste set parameters waarmee rekening moet worden gehouden, zijn de statistieken op instantieniveau: CPUUtilization en MemoryUtilization (voor GPU-gebaseerde instanties, GPUUtilization). Voor CPUUtilization, ziet u mogelijk eerst percentages boven de 100% in CloudWatch. Het is belangrijk om te beseffen voor CPUUtilization, wordt de som van alle CPU-cores weergegeven. Als de instantie achter uw eindpunt bijvoorbeeld 4 vCPU's bevat, betekent dit dat het gebruiksbereik tot 400% is. MemoryUtilization, aan de andere kant, ligt in het bereik van 0–100%.

Concreet kunt u gebruiken CPUUtilization om een ​​beter inzicht te krijgen of u voldoende of zelfs een teveel aan hardware heeft. Als u een onderbenutte instantie heeft (minder dan 30%), kunt u mogelijk uw instantietype verkleinen. Omgekeerd, als u voor ongeveer 80-90% wordt gebruikt, zou het voordelig zijn om een ​​instantie te kiezen met meer rekenkracht/geheugen. Op basis van onze tests stellen we een gebruik van uw hardware voor tussen de 60 en 70%.

Aanroepstatistieken

Zoals de naam suggereert, kunnen we met aanroepstatistieken de end-to-end latentie van alle aanroepen naar uw eindpunt volgen. U kunt de aanroepstatistieken gebruiken om het aantal fouten vast te leggen en het type fouten (5xx, 4xx, enzovoort) dat uw eindpunt mogelijk ondervindt. Wat nog belangrijker is, u krijgt inzicht in de latentie-uitsplitsing van uw eindpuntoproepen. Hier kan veel mee worden vastgelegd ModelLatency en OverheadLatency metrische gegevens, zoals geïllustreerd in het volgende diagram.

latencies

De ModelLatency metric legt de tijd vast die inferentie in beslag neemt binnen de modelcontainer achter een SageMaker-eindpunt. Houd er rekening mee dat de modelcontainer ook eventuele aangepaste inferentiecode of scripts bevat die u hebt doorgegeven voor inferentie. Deze eenheid wordt vastgelegd in microseconden als een aanroepstatistiek, en over het algemeen kunt u een percentiel over CloudWatch (p99, p90, enzovoort) in een grafiek weergeven om te zien of u uw beoogde latentie haalt. Houd er rekening mee dat verschillende factoren van invloed kunnen zijn op de latentie van modellen en containers, zoals de volgende:

  • Aangepast inferentiescript – Of u nu uw eigen container heeft geïmplementeerd of een op SageMaker gebaseerde container met aangepaste inferentiehandlers heeft gebruikt, het is een goede gewoonte om uw script te profileren om bewerkingen op te vangen die specifiek veel tijd aan uw latentie toevoegen.
  • Communicatie protocol – Overweeg REST versus gRPC-verbindingen met de modelserver binnen de modelcontainer.
  • Optimalisaties van het modelraamwerk – Dit is kaderspecifiek, bijvoorbeeld met TensorFlow, zijn er een aantal omgevingsvariabelen die u kunt afstemmen en die specifiek zijn voor TF Serving. Zorg ervoor dat u controleert welke container u gebruikt en of er framework-specifieke optimalisaties zijn die u kunt toevoegen binnen het script of als omgevingsvariabelen om in de container te injecteren.

OverheadLatency wordt gemeten vanaf het moment dat SageMaker het verzoek ontvangt totdat het een antwoord naar de client retourneert, minus de modellatentie. Dit deel ligt grotendeels buiten uw controle en valt onder de tijd die SageMaker-overheadkosten in beslag nemen.

End-to-end latency als geheel hangt af van verschillende factoren en is niet noodzakelijkerwijs de som van ModelLatency plus OverheadLatency. Als uw klant bijvoorbeeld de InvokeEndpoint API-aanroep via internet, vanuit het perspectief van de klant zou de end-to-end latentie internet + zijn ModelLatency + OverheadLatency. Daarom is het raadzaam om bij het testen van uw eindpunt om het eindpunt zelf nauwkeurig te benchmarken, u te concentreren op de eindpuntstatistieken (ModelLatency, OverheadLatency en InvocationsPerInstance) om het SageMaker-eindpunt nauwkeurig te benchmarken. Eventuele problemen met end-to-end latentie kunnen vervolgens afzonderlijk worden geïsoleerd.

Een paar vragen om te overwegen voor end-to-end latency:

  • Waar is de client die uw eindpunt aanroept?
  • Zijn er tussenliggende lagen tussen uw client en de SageMaker-runtime?

Automatisch schalen

We gaan in dit bericht niet specifiek in op automatisch schalen, maar het is een belangrijke overweging om het juiste aantal instanties in te richten op basis van de werkbelasting. Afhankelijk van uw verkeerspatronen kunt u een beleid voor automatisch schalen naar uw SageMaker-eindpunt. Er zijn verschillende schaalopties, zoals TargetTrackingScaling, SimpleScaling en StepScaling. Hierdoor kan uw eindpunt automatisch in- en uitschalen op basis van uw verkeerspatroon.

Een veelgebruikte optie is het bijhouden van doelen, waarbij u een CloudWatch-statistiek of aangepaste statistiek kunt specificeren die u hebt gedefinieerd en op basis daarvan kunt uitschalen. Een veelgebruikt gebruik van automatisch schalen is het volgen van de InvocationsPerInstance metriek. Nadat u een knelpunt bij een bepaalde TPS hebt geïdentificeerd, kunt u dat vaak gebruiken als maatstaf om uit te schalen naar een groter aantal instanties om piekbelastingen van verkeer aan te kunnen. Raadpleeg voor een diepere uitsplitsing van automatisch schalende SageMaker-eindpunten Inferentie-eindpunten voor automatisch schalen configureren in Amazon SageMaker.

Load testen

Hoewel we Locust gebruiken om te laten zien hoe we testen op schaal kunnen laden, als u probeert de instantie achter uw eindpunt de juiste grootte te geven, SageMaker Inferentie Aanbeveling is een efficiëntere optie. Met loadtesttools van derden moet u endpoints handmatig implementeren in verschillende instanties. Met Inference Recommender kunt u eenvoudig een reeks instantietypen doorgeven waarmee u de test wilt laden, en SageMaker zal draaien vacatures voor elk van deze gevallen.

Sprinkhaan

Voor dit voorbeeld gebruiken we Sprinkhaan, een open-source load-testtool die u kunt implementeren met Python. Locust is vergelijkbaar met veel andere open-source belastingtesttools, maar heeft een paar specifieke voordelen:

  • Makkelijk op te zetten - Zoals we in dit bericht laten zien, geven we een eenvoudig Python-script door dat gemakkelijk kan worden aangepast voor uw specifieke eindpunt en payload.
  • Gedistribueerd en schaalbaar - Locust is op gebeurtenissen gebaseerd en maakt gebruik van geven onder de motorkap. Dit is erg handig voor het testen van zeer gelijktijdige werklasten en het simuleren van duizenden gelijktijdige gebruikers. U kunt een hoge TPS bereiken met een enkel proces met Locust, maar het heeft ook een gedistribueerde belastinggeneratie functie waarmee u kunt uitschalen naar meerdere processen en clientmachines, zoals we in dit bericht zullen onderzoeken.
  • Locust-statistieken en gebruikersinterface - Locust legt ook end-to-end latency vast als een statistiek. Dit kan helpen bij het aanvullen van uw CloudWatch-statistieken om een ​​volledig beeld van uw tests te schetsen. Dit wordt allemaal vastgelegd in de gebruikersinterface van Locust, waar u gelijktijdige gebruikers, werknemers en meer kunt volgen.

Om Locust verder te begrijpen, bekijk hun documentatie.

Amazon EC2-configuratie

U kunt Locust instellen in elke omgeving die voor u compatibel is. Voor dit bericht hebben we een EC2-instantie opgezet en Locust daar geïnstalleerd om onze tests uit te voeren. We gebruiken een c5.18xlarge EC2-instantie. De rekenkracht aan de clientzijde is ook iets om rekening mee te houden. Op momenten dat de rekenkracht aan de clientzijde opraakt, wordt dit vaak niet vastgelegd en wordt het aangezien voor een SageMaker-eindpuntfout. Het is belangrijk om uw client op een locatie te plaatsen met voldoende rekenkracht die de belasting aankan waarop u test. Voor onze EC2-instantie gebruiken we een Ubuntu Deep Learning AMI, maar u kunt elke AMI gebruiken zolang u Locust correct op de machine kunt instellen. Raadpleeg de zelfstudie voor meer informatie over het starten en verbinden met uw EC2-instantie Ga aan de slag met Amazon EC2 Linux-instanties.

De gebruikersinterface van Locust is toegankelijk via poort 8089. We kunnen dit openen door onze inkomende beveiligingsgroepregels voor de EC2-instantie aan te passen. We openen ook poort 22 zodat we via SSH naar de EC2-instantie kunnen gaan. Overweeg om de bron te beperken tot het specifieke IP-adres van waaruit u toegang krijgt tot de EC2-instantie.

Beveiligingsgroepen

Nadat u bent verbonden met uw EC2-instantie, zetten we een virtuele Python-omgeving op en installeren we de open-source Locust API via de CLI:

virtualenv venv #venv is the virtual environment name, you can change as you desire
source venv/bin/activate #activate virtual environment
pip install locust

We zijn nu klaar om met Locust te werken voor het testen van ons eindpunt.

Sprinkhaan testen

Alle Locust-belastingstests worden uitgevoerd op basis van a Locust-bestand die jij verstrekt. Dit Locust-bestand definieert een taak voor de belastingstest; hier definiëren we onze Boto3 invoke_endpoint API-aanroep. Zie de volgende code:

config = Config(
retries = { 'max_attempts': 0, 'mode': 'standard'
}
) self.sagemaker_client = boto3.client('sagemaker-runtime',config=config)
self.endpoint_name = host.split('/')[-1]
self.region = region
self.content_type = content_type
self.payload = payload

Pas in de voorgaande code de para meters voor het aanroepen van het eind punt aan zodat deze passen bij uw specifieke model aanroep. Wij gebruiken de InvokeEndpoint API met behulp van het volgende stuk code in het Locust-bestand; dit is ons laadtestpunt. Het Locust-bestand dat we gebruiken is sprinkhaan_script.py.

def send(self): request_meta = { "request_type": "InvokeEndpoint", "name": "SageMaker", "start_time": time.time(), "response_length": 0, "response": None, "context": {}, "exception": None,
}
start_perf_counter = time.perf_counter() try:
response = self.sagemaker_client.invoke_endpoint(
EndpointName=self.endpoint_name,
Body=self.payload,
ContentType=self.content_type
)
response_body = response["Body"].read()

Nu we ons Locust-script klaar hebben, willen we gedistribueerde Locust-tests uitvoeren om onze enkele instantie te stresstesten om erachter te komen hoeveel verkeer onze instantie aankan.

Locust-gedistribueerde modus is iets genuanceerder dan een Locust-test met één proces. In gedistribueerde modus hebben we één primaire en meerdere werknemers. De primaire werker instrueert de werknemers hoe ze de gelijktijdige gebruikers die een aanvraag verzenden, moeten spawnen en beheren. In onze gedistribueerd.sh script zien we standaard dat er 240 gebruikers worden verdeeld over de 60 werkers. Merk op dat de --headless vlag in de Locust CLI verwijdert de UI-functie van Locust.

#replace with your endpoint name in format https://<<endpoint-name>>
export ENDPOINT_NAME=https://$1 export REGION=us-east-1
export CONTENT_TYPE=application/json
export PAYLOAD='{"inputs": "I am super happy right now."}'
export USERS=240
export WORKERS=60
export RUN_TIME=1m
export LOCUST_UI=false # Use Locust UI .
.
. locust -f $SCRIPT -H $ENDPOINT_NAME --master --expect-workers $WORKERS -u $USERS -t $RUN_TIME --csv results &
.
.
. for (( c=1; c<=$WORKERS; c++ ))
do
locust -f $SCRIPT -H $ENDPOINT_NAME --worker --master-host=localhost &
done

./distributed.sh huggingface-pytorch-inference-2022-10-04-02-46-44-677 #to execute Distributed Locust test

We voeren eerst de gedistribueerde test uit op een enkele instantie die het eindpunt ondersteunt. Het idee hier is dat we een enkele instantie volledig willen maximaliseren om inzicht te krijgen in het aantal instanties dat we nodig hebben om onze doel-TPS te bereiken terwijl we binnen onze latentievereisten blijven. Merk op dat als u toegang wilt tot de gebruikersinterface, u de Locust_UI omgevingsvariabele op True en neem het openbare IP-adres van uw EC2-instantie en wijs poort 8089 toe aan de URL.

De volgende schermafbeelding toont onze CloudWatch-statistieken.

CloudWatch-statistieken

Uiteindelijk merken we dat, hoewel we in eerste instantie een TPS van 200 behalen, we 5xx-fouten beginnen op te merken in onze EC2-logboeken aan de clientzijde, zoals te zien is in de volgende schermafbeelding.

We kunnen dit ook verifiëren door specifiek naar onze statistieken op instantieniveau te kijken CPUUtilization.

CloudWatch-statistiekenHier merken we het op CPUUtilization op bijna 4,800%. Onze instantie ml.m5.12x.large heeft 48 vCPU's (48 * 100 = 4800~). Dit verzadigt de hele instantie, wat ook helpt bij het verklaren van onze 5xx-fouten. Ook zien we een toename van ModelLatency.

Het lijkt alsof onze enkele instantie wordt omvergeworpen en niet over de rekenkracht beschikt om een ​​belasting te ondersteunen die verder gaat dan de 200 TPS die we waarnemen. Onze doel-TPS is 1000, dus laten we proberen het aantal instanties te verhogen tot 5. Dit zou zelfs nog meer moeten zijn in een productieomgeving, omdat we fouten waarnamen bij 200 TPS na een bepaald punt.

Eindpunt instellingen

We zien in zowel de Locust UI als CloudWatch-logboeken dat we een TPS van bijna 1000 hebben met vijf instanties die het eindpunt ondersteunen.

Sprinkhaan

CloudWatch-statistiekenAls u zelfs met deze hardware-installatie fouten begint te ervaren, zorg er dan voor dat u controleert CPUUtilization om het volledige plaatje achter uw endpoint hosting te begrijpen. Het is cruciaal om uw hardwaregebruik te begrijpen om te zien of u omhoog of zelfs omlaag moet schalen. Soms leiden problemen op containerniveau tot 5xx-fouten, maar if CPUUtilization laag is, geeft dit aan dat het niet uw hardware is, maar iets op container- of modelniveau dat tot deze problemen kan leiden (bijvoorbeeld de juiste omgevingsvariabele voor het aantal werknemers is niet ingesteld). Aan de andere kant, als u merkt dat uw instantie volledig verzadigd raakt, is dit een teken dat u de huidige instantievloot moet vergroten of een grotere instantie met een kleinere vloot moet uitproberen.

Hoewel we het aantal instanties hebben verhoogd tot 5 om 100 TPS te verwerken, kunnen we zien dat de ModelLatency metrische is nog steeds hoog. Dit komt doordat de instanties verzadigd zijn. Over het algemeen raden we aan om te streven naar een gebruik van de bronnen van de instantie tussen de 60 en 70%.

Opruimen

Zorg ervoor dat u na het testen van de belasting alle bronnen opruimt die u niet zult gebruiken via de SageMaker-console of via de delete_eindpunt Boto3 API-oproep. Zorg er bovendien voor dat u uw EC2-instantie of welke clientconfiguratie dan ook stopt, om daar ook geen verdere kosten in rekening te brengen.

Samengevat

In dit bericht hebben we beschreven hoe u uw real-time eindpunt van SageMaker kunt laden. We hebben ook besproken welke statistieken u moet evalueren bij het testen van uw eindpunt om inzicht te krijgen in uw prestatie-uitval. Zorg ervoor dat u uitcheckt SageMaker Inferentie Aanbeveling om de juiste grootte van instanties en meer technieken voor prestatieoptimalisatie verder te begrijpen.


Over de auteurs

Marc Karp is een ML Architect bij het SageMaker Service-team. Hij richt zich op het helpen van klanten bij het ontwerpen, implementeren en beheren van ML-workloads op schaal. In zijn vrije tijd houdt hij van reizen en het ontdekken van nieuwe plaatsen.

Ram Vegiraju is een ML Architect bij het SageMaker Service-team. Hij richt zich op het helpen van klanten bij het bouwen en optimaliseren van hun AI/ML-oplossingen op Amazon SageMaker. In zijn vrije tijd houdt hij van reizen en schrijven.

Tijdstempel:

Meer van AWS-machine learning