Invoquez des modèles pour une inférence en temps réel - Amazon SageMaker

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Invoquez des modèles pour une inférence en temps réel

Après avoir déployé votre modèle à l'aide des services SageMaker d'hébergement, vous pouvez le tester sur ce point de terminaison en lui envoyant des données de test. Vous pouvez tester vos points de terminaison à l'aide d'Amazon SageMaker Studio, AWS des SDK ou du. AWS CLI

Appelez votre point de terminaison à l'aide d'Amazon SageMaker Studio

Après avoir déployé votre modèle sur un point de terminaison, vous pouvez consulter le point de terminaison via Amazon SageMaker Studio et tester votre point de terminaison en envoyant des demandes d'inférence uniques.

Note

SageMaker prend uniquement en charge les tests de points de terminaison dans Studio pour les points de terminaison en temps réel.

Pour envoyer une demande d'inférence de test à votre point de terminaison
  1. Lancez Amazon SageMaker Studio.

  2. Dans le volet de navigation de gauche, choisissez Deployments.

  3. Dans le menu déroulant, sélectionnez Endpoints (Points de terminaison).

  4. Recherchez votre point de terminaison par son nom, puis choisissez-le dans le tableau. Les noms de point de terminaison répertoriés dans le panneau Points de terminaison sont définis lorsque vous déployez un modèle. L'espace de travail Studio ouvre la page Endpoint dans un nouvel onglet.

  5. Choisissez l'onglet Tester l'inférence.

  6. Pour les options de test, sélectionnez l'une des options suivantes :

    1. Sélectionnez Tester l'exemple de demande pour envoyer immédiatement une demande à votre terminal. Utilisez l'éditeur JSON pour fournir des exemples de données au format JSON, puis choisissez Send Request pour envoyer la demande à votre point de terminaison. Après avoir soumis votre demande, Studio affiche le résultat de l'inférence sur une carte située à droite de l'éditeur JSON.

    2. Sélectionnez Utiliser un exemple de code du SDK Python pour afficher le code permettant d'envoyer une demande au point de terminaison. Copiez ensuite l'exemple de code depuis la section Exemple de demande d'inférence et exécutez le code depuis votre environnement de test.

Le haut de la carte affiche le type de demande qui a été envoyée au point de terminaison (seul JSON est accepté). La carte affiche les champs suivants :

  • Statut : affiche l'un des types de statut suivants :

    • Success : la demande a réussi.

    • Failed : la demande a échoué. Une réponse apparaît sous Motif de l'échec.

    • Pending : une icône circulaire et en rotation apparaît pendant que la demande d'inférence est en attente.

  • Longueur d'exécution : durée de l'invocation (heure de fin moins l'heure de début) en millisecondes.

  • Durée de la demande : nombre de minutes qui se sont écoulées depuis l'envoi de la demande.

  • Durée du résultat : nombre de minutes qui se sont écoulées depuis le renvoi du résultat.

Invocation de votre point de terminaison à l'aide du kit AWS SDK for Python (Boto3)

Après avoir déployé votre modèle sur un point de terminaison, vous pouvez vérifier votre point de terminaison à l'aide de l'un des AWS SDK, notamment en tant que. AWS SDK for Python (Boto3) Pour tester votre point de terminaison à l'aide de ce kit SDK, vous devez utiliser l'une des méthodes suivantes :

  • invoke_endpoint : envoie une demande d'inférence à un point de terminaison du modèle et renvoie la réponse générée par le modèle. Cette méthode renvoie la charge utile d'inférence sous forme d'une réponse une fois que le modèle a fini de la générer. Pour plus d'informations, consultez invoke_endpoint dans la Référence des API du kit AWS SDK pour Python (Boto).

  • invoke_endpoint_with_response_stream : envoie une demande d'inférence à un point de terminaison du modèle et diffuse la réponse par étapes incrémentielles pendant que le modèle génère l'inférence. Avec cette méthode, votre application client commence immédiatement à recevoir des parties de la réponse dès qu'elles sont disponibles. Votre client n'a pas besoin d'attendre que le modèle génère l'intégralité de la charge utile de réponse. Vous pouvez mettre en œuvre le streaming pour prendre en charge des expériences interactives rapides, telles que les chatbots, les assistants virtuels et les générateurs de musique.

    Utilisez cette méthode uniquement pour invoquer des modèles qui prennent en charge le streaming d'inférence.

    Lorsqu'un conteneur gère une demande d'inférence en streaming, il renvoie l'inférence du modèle sous la forme d'une série de pièces au fur et à mesure que le modèle les génère. Les applications clientes commencent à recevoir des réponses dès qu'elles sont disponibles. Elles n'ont pas besoin d'attendre que le modèle génère la réponse complète. Vous pouvez mettre en œuvre le streaming pour prendre en charge des expériences interactives rapides, telles que les chatbots, les assistants virtuels et les générateurs de musique.

Avant de pouvoir utiliser ces méthodes dans votre code client, vous devez créer un client SageMaker Runtime et spécifier le nom de votre point de terminaison. L'exemple suivant configure le client et le point de terminaison pour les autres exemples suivants :

import boto3 # Create a low-level client representing Amazon SageMaker Runtime sagemaker_runtime = boto3.client( "sagemaker-runtime", region_name='aws_region') # The endpoint name must be unique within # an AWS Region in your AWS account. endpoint_name='endpoint-name'

Invocation pour obtenir une réponse d'inférence

L'exemple suivant utilise la méthode invoke_endpoint pour invoquer un point de terminaison avec le kit AWS SDK for Python (Boto3) :

# Gets inference from the model hosted at the specified endpoint: response = sagemaker_runtime.invoke_endpoint( EndpointName=endpoint_name, Body=bytes('{"features": ["This is great!"]}', 'utf-8') ) # Decodes and prints the response body: print(response['Body'].read().decode('utf-8'))

Cet exemple fournit des données d'entrée dans le Body champ SageMaker à transmettre au modèle. Ces données doivent être dans le même format que celui utilisé pour l'entraînement. L'exemple stocke la réponse dans la variable response.

La variable response permet d'accéder au statut HTTP, au nom du modèle déployé et à d'autres champs. L'extrait de code suivant imprime le HTTPStatusCode :

print(response["HTTPStatusCode"])

Invoquer pour diffuser une réponse d'inférence

Si vous avez déployé un modèle qui prend en charge le streaming d'inférence, vous pouvez invoquer le modèle pour recevoir sa charge utile d'inférence sous forme de flux de pièces. Le modèle fournit ces pièces progressivement au fur et à mesure qu'il les génère. Lorsqu'une application reçoit un flux d'inférence, elle n'a pas besoin d'attendre que le modèle génère la totalité de la charge utile de réponse. Au lieu de cela, l'application commence immédiatement à recevoir des parties de la réponse dès qu'elles sont disponibles.

En consommant un flux d'inférence dans votre application, vous pouvez créer des interactions dans lesquelles vos utilisateurs perçoivent l'inférence comme étant rapide, car ils obtiennent immédiatement la première partie. Par exemple, vous pouvez créer un chatbot qui affiche progressivement le texte généré par un grand modèle de langage (LLM).

Pour obtenir un flux d'inférence, vous pouvez utiliser la méthode invoke_endpoint_with_response_stream du kit SDK pour Python (Boto3). Dans le corps de la réponse, le kit SDK fournit un objet EventStream, qui donne l'inférence sous la forme d'une série d'objets PayloadPart.

Exemple Flux d'inférence

L'exemple suivant est un flux d'objets PayloadPart :

{'PayloadPart': {'Bytes': b'{"outputs": [" a"]}\n'}} {'PayloadPart': {'Bytes': b'{"outputs": [" challenging"]}\n'}} {'PayloadPart': {'Bytes': b'{"outputs": [" problem"]}\n'}} . . .

Dans chaque partie de la charge utile, le champ Bytes fournit une partie de la réponse d'inférence du modèle. Cette partie peut être n'importe quel type de contenu généré par un modèle, tel que du texte, des images ou des données audio. Dans cet exemple, les parties sont des objets JSON contenant du texte généré à partir d'un LLM.

En général, la partie de la charge utile contient un fragment discret de données du modèle. Dans cet exemple, les fragments discrets sont des objets JSON entiers. Parfois, la réponse de streaming divise les fragments sur plusieurs parties de la charge utile, ou elle combine plusieurs fragments en une seule partie de charge utile. L'exemple suivant montre un fragment de données au format JSON divisé en deux parties de charge utile :

{'PayloadPart': {'Bytes': b'{"outputs": '}} {'PayloadPart': {'Bytes': b'[" problem"]}\n'}}

Lorsque vous écrivez du code d'application qui traite un flux d'inférence, incluez une logique qui gère ces divisions et combinaisons de données occasionnelles. Une stratégie consisterait à écrire du code qui concatène le contenu d'Bytes pendant que votre application reçoit les parties de la charge utile. En concaténant les données JSON d'exemple ici, vous combineriez les données dans un corps JSON délimité par de nouvelles lignes. Ensuite, votre code pourrait traiter le flux en analysant l'ensemble de l'objet JSON sur chaque ligne.

L'exemple suivant montre le JSON délimité par de nouvelles lignes que vous créeriez lorsque vous concaténez le contenu de l'exemple d'Bytes :

{"outputs": [" a"]} {"outputs": [" challenging"]} {"outputs": [" problem"]} . . .
Exemple Code pour traiter un flux d'inférence

L'exemple de classe Python suivant, SmrInferenceStream, montre comment traiter un flux d'inférence qui envoie des données texte au format JSON :

import io import json # Example class that processes an inference stream: class SmrInferenceStream: def __init__(self, sagemaker_runtime, endpoint_name): self.sagemaker_runtime = sagemaker_runtime self.endpoint_name = endpoint_name # A buffered I/O stream to combine the payload parts: self.buff = io.BytesIO() self.read_pos = 0 def stream_inference(self, request_body): # Gets a streaming inference response # from the specified model endpoint: response = self.sagemaker_runtime\ .invoke_endpoint_with_response_stream( EndpointName=self.endpoint_name, Body=json.dumps(request_body), ContentType="application/json" ) # Gets the EventStream object returned by the SDK: event_stream = response['Body'] for event in event_stream: # Passes the contents of each payload part # to be concatenated: self._write(event['PayloadPart']['Bytes']) # Iterates over lines to parse whole JSON objects: for line in self._readlines(): resp = json.loads(line) part = resp.get("outputs")[0] # Returns parts incrementally: yield part # Writes to the buffer to concatenate the contents of the parts: def _write(self, content): self.buff.seek(0, io.SEEK_END) self.buff.write(content) # The JSON objects in buffer end with '\n'. # This method reads lines to yield a series of JSON objects: def _readlines(self): self.buff.seek(self.read_pos) for line in self.buff.readlines(): self.read_pos += len(line) yield line[:-1]

Cet exemple traite le flux d'inférence en procédant comme suit :

  • S'initialise avec un client SageMaker Runtime et le nom d'un point de terminaison du modèle. Avant de pouvoir obtenir un flux d'inférence, le modèle que le point de terminaison héberge doit prendre en charge le streaming d'inférence.

  • Dans l'exemple de méthode stream_inference, il reçoit le corps d'une demande et le transmet à la méthode invoke_endpoint_with_response_stream du kit SDK.

  • Il itère sur chaque événement de l'objet EventStream renvoyé par le kit SDK.

  • À partir de chaque événement, il obtient le contenu de l'objet Bytes dans l'objet PayloadPart.

  • Dans l'exemple de méthode _write, il écrit dans un tampon pour concaténer le contenu des objets Bytes. Le contenu combiné forme un corps JSON délimité par de nouvelles lignes.

  • Il utilise l'exemple de méthode _readlines pour obtenir une série itérable d'objets JSON.

  • Dans chaque objet JSON, il obtient une partie de l'inférence.

  • Avec l'expression yield, il renvoie les pièces de manière incrémentielle.

L'exemple suivant crée et utilise un objet SmrInferenceStream :

request_body = {"inputs": ["Large model inference is"], "parameters": {"max_new_tokens": 100, "enable_sampling": "true"}} smr_inference_stream = SmrInferenceStream( sagemaker_runtime, endpoint_name) stream = smr_inference_stream.stream_inference(request_body) for part in stream: print(part, end='')

Cet exemple transmet un corps de demande à la méthode stream_inference. Il itère la réponse pour imprimer chaque élément renvoyé par le flux d'inférence.

L'exemple suppose que le modèle au point de terminaison spécifié est un LLM qui génère du texte. Le résultat de cet exemple est un corps de texte généré qui s'imprime de manière incrémentielle :

a challenging problem in machine learning. The goal is to . . .

Appelez votre point de terminaison en utilisant le AWS CLI

Vous pouvez tester votre point de terminaison en exécutant des commandes avec le AWS Command Line Interface (AWS CLI). L' AWS CLI prend en charge les demandes d'inférence standard avec la commande invoke-endpoint et prend en charge les demandes d'inférence asynchrones avec la commande invoke-endpoint-async.

Note

Le AWS CLI ne prend pas en charge les demandes d'inférence en streaming.

L'exemple suivant utilise la commande invoke-endpoint pour envoyer une demande d'inférence à un point de terminaison du modèle :

aws sagemaker-runtime invoke-endpoint \ --endpoint-name endpoint_name \ --body fileb://$file_name \ output_file.txt

Pour le paramètre --endpoint-name, indiquez le nom que vous avez spécifié pour EndpointName lors de la création de votre point de terminaison avec CreateEndpoint. Pour le --body paramètre, fournissez les données d'entrée SageMaker à transmettre au modèle. Les données doivent être dans le même format que celui utilisé pour l'entraînement. Cet exemple montre comment envoyer des données binaires à votre point de terminaison.

Pour plus d'informations sur les circonstances dans lesquelles utiliser le file:// over fileb:// lors du transfert du contenu d'un fichier à un paramètre du AWS CLI, consultez la section Meilleures pratiques relatives aux paramètres de fichiers locaux.

Pour plus d'informations et pour voir les paramètres supplémentaires que vous pouvez transmettre, consultez invoke-endpoint dans la Référence des commandes de l'AWS CLI .

Si la commande invoke-endpoint réussit, elle renvoie une réponse telle que la suivante :

{ "ContentType": "<content_type>; charset=utf-8", "InvokedProductionVariant": "<Variant>" }

Si la commande échoue, vérifiez si le format de la charge utile d'entrée est correct.

Affichez la sortie de l'appel en vérifiant le fichier de sortie du fichier (output_file.txt dans cet exemple).

more output_file.txt