Hub Python Library documentation

Points de terminaison d'inférence

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Points de terminaison d'inférence

Inference Endpoints offre une solution de production sécurisée pour déployer facilement tout modèle transformers, sentence-transformers et diffusers sur une infrastructure dédiée et à mise à l'échelle automatique, gérée par Hugging Face. Un Inference Endpoint est construit à partir d'un modèle du Hub. Dans ce guide, nous allons apprendre à gérer les Inference Endpoints de manière programmatique avec huggingface_hub. Pour plus d'informations sur le produit Inference Endpoints lui-même, consultez sa documentation officielle.

Ce guide suppose que huggingface_hub est correctement installé et que votre machine est connectée. Consultez le guide de démarrage rapide si ce n’est pas encore le cas. La version minimale prenant en charge l’API Inference Endpoints est v0.19.0.

Nouveau : il est désormais possible de déployer un Inference Endpoint à partir du catalogue de modèles HF avec un simple appel API. Le catalogue est une liste soigneusement sélectionnée de modèles pouvant être déployés avec des paramètres optimisés. Vous n’avez rien à configurer, nous nous chargeons de toute la complexité ! Tous les modèles et paramètres sont garantis testés pour offrir le meilleur équilibre coût/performance. create_inference_endpoint_from_catalog() fonctionne de la même manière que create_inference_endpoint(), avec beaucoup moins de paramètres à transmettre. Vous pouvez utiliser list_inference_catalog() pour récupérer le catalogue de manière programmatique.

Notez qu'il s'agit toujours d'une fonctionnalité expérimentale. Faites-nous part de vos retours si vous l'utilisez !

Chaque modèle du catalogue est déployé via une recette : une combinaison de matériel et de moteur testée à cet effet. list_inference_catalog() renvoie les modèles avec leurs recettes et accepte des filtres côté serveur (accelerator, engine, license, task, search, limit) :

>>> from huggingface_hub import list_inference_catalog
>>> catalog = list_inference_catalog(task="text-generation", accelerator="neuron")
>>> catalog[0]
InferenceCatalogModel(repo_id='meta-llama/Llama-3.1-8B-Instruct', name='Llama-3.1-8B-Instruct', ...)
>>> catalog[0].recipes
[InferenceCatalogRecipe(id='sizzling-biryani-g4xsi1ac', accelerator='gpu', engine='vllm', gguf_file=None, revision=None),
 InferenceCatalogRecipe(id='artisanal-quinoa-yz9ynamx', accelerator='neuron', engine='vllmNeuron', gguf_file=None, revision=None)]

Passez un repo_id à create_inference_endpoint_from_catalog() pour déployer la recette par défaut d’un modèle, éventuellement restreinte avec accelerator ("cpu", "gpu" ou "neuron") et gguf_file, ou passez un recipe_id pour déployer une recette exacte :

>>> from huggingface_hub import create_inference_endpoint_from_catalog
>>> endpoint = create_inference_endpoint_from_catalog(repo_id="openai/gpt-oss-120b")
>>> endpoint = create_inference_endpoint_from_catalog(recipe_id="artisanal-quinoa-yz9ynamx")

Trouver du matériel pour le déploiement

Les valeurs de accelerator, vendor, region, instance_type et instance_size acceptées par create_inference_endpoint() sont interdépendantes. Utilisez list_inference_endpoints_hardware() pour lister les combinaisons valides, ainsi que leur prix par heure et le quota d'accélérateurs de votre espace de noms :

>>> from huggingface_hub import list_inference_endpoints_hardware

>>> for hw in list_inference_endpoints_hardware():
...     if hw.accelerator == "gpu" and hw.status == "available":
...         print(hw.vendor, hw.region, hw.instance_type, hw.instance_size, hw.price_per_hour)
aws us-east-1 nvidia-l4 x1 0.8
aws us-east-1 nvidia-l4 x4 3.8
...

Le quota est défini par espace de noms, passez donc le namespace dans lequel vous allez déployer (par défaut, il s’agit de votre propre compte) :

>>> list_inference_endpoints_hardware(namespace="my-org")

Ou via l'interface en ligne de commande :

hf endpoints hardware --accelerator gpu

Créer un point de terminaison d'inférence

La première étape consiste à créer un point d'inférence à l'aide de create_inference_endpoint() :

>>> from huggingface_hub import create_inference_endpoint

>>> endpoint = create_inference_endpoint(
...     "my-endpoint-name",
...     repository="gpt2",
...     framework="pytorch",
...     task="text-generation",
...     accelerator="cpu",
...     vendor="aws",
...     region="us-east-1",
...     type="authenticated",
...     instance_size="x2",
...     instance_type="intel-icl"
... )

Ou via l'interface en ligne de commande :

hf endpoints deploy my-endpoint-name --repo gpt2 --framework pytorch --accelerator cpu --vendor aws --region us-east-1 --instance-size x2 --instance-type intel-icl --task text-generation

# Deploy from the catalog with a single command
hf endpoints catalog deploy --repo openai/gpt-oss-120b

# Deploy from the catalog with a specific accelerator
hf endpoints catalog deploy --repo openai/gpt-oss-120b --accelerator gpu

# Deploy an exact catalog recipe, as listed by 'hf endpoints catalog ls'
hf endpoints catalog deploy --recipe artisanal-quinoa-yz9ynamx

Dans cet exemple, nous avons créé un Inference Endpoint authenticated nommé "my-endpoint-name", afin de servir gpt2 pour la text-generation. Un Inference Endpoint authenticated signifie que votre jeton est requis pour accéder à l'API. Nous devons également fournir des informations supplémentaires pour configurer les exigences matérielles, telles que le fournisseur, la région, l'accélérateur, le type d'instance et la taille. Vous pouvez consulter la liste des ressources disponibles ici. Alternativement, vous pouvez créer un Inference Endpoint manuellement en utilisant l'interface Web pour plus de commodité. Reportez-vous à ce guide pour plus de détails sur les paramètres avancés et leur utilisation.

La valeur renvoyée par create_inference_endpoint() est un objet InferenceEndpoint :

>>> endpoint
InferenceEndpoint(name='my-endpoint-name', namespace='Wauplin', repository='gpt2', status='pending', url=None)

Ou via l'interface en ligne de commande :

hf endpoints describe my-endpoint-name

C’est une dataclass qui contient des informations sur le point de terminaison. Vous pouvez accéder à des attributs importants tels que name, repository, status, task, created_at, updated_at, etc. Si nécessaire, vous pouvez également accéder à la réponse brute du serveur avec endpoint.raw.

Une fois votre Inference Endpoint créé, vous pouvez le trouver sur votre tableau de bord personnel.

Utiliser une image personnalisée

Par défaut, l'Inference Endpoint est construit à partir d'une image docker fournie par Hugging Face. Il est toutefois possible de spécifier n'importe quelle image docker à l'aide du paramètre custom_image. Un cas d'usage courant consiste à exécuter des LLM à l'aide du framework text-generation-inference. Voici comment procéder :

# Start an Inference Endpoint running Zephyr-7b-beta on TGI
>>> from huggingface_hub import create_inference_endpoint
>>> endpoint = create_inference_endpoint(
...     "aws-zephyr-7b-beta-0486",
...     repository="HuggingFaceH4/zephyr-7b-beta",
...     framework="pytorch",
...     task="text-generation",
...     accelerator="gpu",
...     vendor="aws",
...     region="us-east-1",
...     type="authenticated",
...     instance_size="x1",
...     instance_type="nvidia-a10g",
...     custom_image={
...         "healthRoute": "/health",
...         "env": {
...             "MAX_BATCH_PREFILL_TOKENS": "2048",
...             "MAX_INPUT_LENGTH": "1024",
...             "MAX_TOTAL_TOKENS": "1512",
...             "MODEL_ID": "/repository"
...         },
...         "url": "ghcr.io/huggingface/text-generation-inference:1.1.0",
...     },
... )

La valeur à passer en tant que custom_image est un dictionnaire contenant une URL vers le conteneur docker et la configuration pour l'exécuter. Pour plus de détails à ce sujet, consultez la documentation Swagger.

Pour une image hébergée dans un registre de conteneurs privé, passez container_registry_username et, si le registre l’exige, container_registry_password. Les identifiants ne sont pris en charge que pour un conteneur personnalisé simple :

>>> endpoint = create_inference_endpoint(
...     # Other endpoint and hardware arguments omitted for brevity.
...     custom_image={"url": "private.registry.example/my-image:latest", "port": 8080},
...     container_registry_username="user",
...     container_registry_password="password",
... )

Les options CLI équivalentes sont --container-registry-username et --container-registry-password :

hf endpoints deploy my-endpoint ... --custom-image private.registry.example/my-image:latest \
  --container-registry-username user --container-registry-password password

custom_image accepte également les types de conteneurs spécifiques à chaque moteur pris en charge par l’API, en utilisant le nom du moteur comme clé du dictionnaire (vLLM, vLLMNeuron, sGLang, tgi, tgiNeuron, tei, llamacpp, hfServe, …) au lieu de le laisser à plat. Chaque moteur prend les champs de conteneur habituels (url, port, healthRoute) ainsi que ses propres options de réglage. Tout dictionnaire sans url au niveau supérieur est transmis à l’API sans modification, de sorte que les moteurs ajoutés à l’API ultérieurement fonctionnent sans mettre à jour huggingface_hub :

# Start an Inference Endpoint running the vLLM engine image
>>> endpoint = create_inference_endpoint(
...     "llama-3-1-8b-instruct-vllm",
...     repository="meta-llama/Llama-3.1-8B-Instruct",
...     framework="pytorch",
...     task="text-generation",
...     accelerator="gpu",
...     vendor="aws",
...     region="us-east-1",
...     instance_size="x1",
...     instance_type="nvidia-l4",
...     custom_image={
...         "vLLM": {
...             "url": "vllm/vllm-openai:v0.23.0",
...             "healthRoute": "/health",
...             "port": 8000,
...             "tensorParallelSize": 1,
...         }
...     },
... )

Sans la clé du moteur, le même dictionnaire est envoyé comme un conteneur personnalisé simple, de sorte que les options spécifiques au moteur (ici tensorParallelSize) sont ignorées.

Pour les conteneurs nécessitant un point d’entrée personnalisé ou des drapeaux d’exécution, passez container_command et/ou container_args (chacun étant une liste de jetons). Ils correspondent à model.command et model.args dans la charge utile de l’API. Ils ne sont pas liés aux images personnalisées : les images de moteur gérées (par exemple vLLM, SGLang) acceptent également les drapeaux de moteur via container_args. La même fonctionnalité est disponible depuis l’interface en ligne de commande via hf endpoints deploy ... --container-command "..." --container-args "...".

Parallélisme sur des instances multi-accelerators

vLLM et SGLang utilisent par défaut un seul accélérateur, alors que le point de terminaison est alloué avec tous les accélérateurs de son instance. Ainsi, laisser le parallélisme non défini chargerait le modèle sur un seul accélérateur et laisserait les autres inactifs, tout en signalant un état sain. Vous payez donc pour tous les accélérateurs mais n’obtenez que le débit d’un seul. C’est pourquoi l’API rejette désormais ce type de déploiement. (TGI dérive son nombre de shards de l’instance et n’est pas affecté.) Définissez tensorParallelSize pour répartir une copie du modèle sur les accélérateurs, ou dataParallelSize (vLLM uniquement) pour exécuter une copie par accélérateur :

>>> endpoint = create_inference_endpoint(
...     "gpt-oss-120b-vllm",
...     repository="openai/gpt-oss-120b",
...     framework="custom",
...     accelerator="gpu",
...     instance_size="x8",
...     instance_type="nvidia-h200",
...     region="us-east-1",
...     vendor="aws",
...     custom_image={"vLLM": {"url": "vllm/vllm-openai:v0.23.0", "tensorParallelSize": 8}},
... )

Depuis l’interface en ligne de commande, --engine sélectionne l’image du moteur géré et les deux drapeaux sont écrits dans sa configuration :

hf endpoints deploy gpt-oss-120b-vllm --repo openai/gpt-oss-120b --framework custom \
  --accelerator gpu --instance-size x8 --instance-type nvidia-h200 --region us-east-1 --vendor aws \
  --engine vllm --custom-image vllm/vllm-openai:v0.23.0 --tensor-parallel-size 8

Pour retuner un point de terminaison déployé, passez tensor_parallel_size seul à update() ou hf endpoints update. model.image est envoyé en entier et nécessite url, l’image actuelle du point de terminaison est donc récupérée et mise à jour sur place :

>>> endpoint.update(tensor_parallel_size=4)

container_args (--tp 8) n’est pas équivalent : il est transmis au moteur sous forme d’option en ligne de commande, et non via la configuration model.image que l’API valide en fonction du nombre d’accélérateurs de l’instance. Utilisez-le pour les options du moteur qui ne disposent pas de champ image, ainsi que pour les conteneurs personnalisés simples, qui ne comportent aucun champ de parallélisme.

Obtenir ou lister les Inference Endpoints existants

Dans certains cas, vous devrez peut-être gérer des Inference Endpoints que vous avez créés précédemment. Si vous connaissez le nom, vous pouvez le récupérer à l'aide de get_inference_endpoint(), qui renvoie un objet InferenceEndpoint. Sinon, vous pouvez utiliser list_inference_endpoints() pour obtenir la liste de tous les Inference Endpoints. Les deux méthodes acceptent un paramètre facultatif namespace. Vous pouvez définir namespace sur n'importe quelle organisation dont vous êtes membre. Sinon, la valeur par défaut est votre nom d'utilisateur.

>>> from huggingface_hub import get_inference_endpoint, list_inference_endpoints

# Get one
>>> get_inference_endpoint("my-endpoint-name")
InferenceEndpoint(name='my-endpoint-name', namespace='Wauplin', repository='gpt2', status='pending', url=None)

# List all endpoints from an organization
>>> list_inference_endpoints(namespace="huggingface")
[InferenceEndpoint(name='aws-starchat-beta', namespace='huggingface', repository='HuggingFaceH4/starchat-beta', status='paused', url=None), ...]

# List all endpoints from all organizations the user belongs to
>>> list_inference_endpoints(namespace="*")
[InferenceEndpoint(name='aws-starchat-beta', namespace='huggingface', repository='HuggingFaceH4/starchat-beta', status='paused', url=None), ...]

Ou via l'interface en ligne de commande :

hf endpoints describe my-endpoint-name
hf endpoints ls --namespace huggingface
hf endpoints ls --namespace '*'

Vérifier l'état du déploiement

Dans la suite de ce guide, nous supposerons que nous disposons d'un objet InferenceEndpoint nommé endpoint. Vous avez peut-être remarqué que l'endpoint possède un attribut status de type InferenceEndpointStatus. Lorsque l'Inference Endpoint est déployé et accessible, le statut doit être "running" et l'attribut url est défini :

>>> endpoint
InferenceEndpoint(name='my-endpoint-name', namespace='Wauplin', repository='gpt2', status='running', url='https://jpj7k2q4j805b727.us-east-1.aws.endpoints.huggingface.cloud')

Avant d’atteindre l’état "running", l’Inference Endpoint passe généralement par une phase "initializing" ou "pending". Vous pouvez récupérer le nouvel état de l’endpoint en exécutant fetch(). Comme toutes les autres méthodes de InferenceEndpoint qui effectuent une requête vers le serveur, les attributs internes de endpoint sont modifiés sur place :

>>> endpoint.fetch()
InferenceEndpoint(name='my-endpoint-name', namespace='Wauplin', repository='gpt2', status='pending', url=None)

Ou via l'interface en ligne de commande :

hf endpoints describe my-endpoint-name

Plutôt que de récupérer l'état du point d'accès d'inférence en attendant qu'il soit en cours d'exécution, vous pouvez appeler directement wait(). Cette fonction auxiliaire prend en entrée un paramètre timeout et un paramètre fetch_every (en secondes) et bloque le thread jusqu'à ce que le point d'accès d'inférence soit déployé. Les valeurs par défaut sont respectivement None (aucun délai d'attente) et 5 secondes.

# Pending endpoint
>>> endpoint
InferenceEndpoint(name='my-endpoint-name', namespace='Wauplin', repository='gpt2', status='pending', url=None)

# Wait 10s => raises a InferenceEndpointTimeoutError
>>> endpoint.wait(timeout=10)
    raise InferenceEndpointTimeoutError("Timeout while waiting for Inference Endpoint to be deployed.")
huggingface_hub._inference_endpoints.InferenceEndpointTimeoutError: Timeout while waiting for Inference Endpoint to be deployed.

# Wait more
>>> endpoint.wait()
InferenceEndpoint(name='my-endpoint-name', namespace='Wauplin', repository='gpt2', status='running', url='https://jpj7k2q4j805b727.us-east-1.aws.endpoints.huggingface.cloud')

Si timeout est défini et que le chargement de l’Inference Endpoint prend trop de temps, une erreur de délai InferenceEndpointTimeoutError est levée.

Exécuter l'inférence

Une fois votre Inference Endpoint opérationnel, vous pouvez enfin exécuter de l'inférence dessus !

InferenceEndpoint possède deux propriétés, client et async_client, qui renvoient respectivement des objets InferenceClient et AsyncInferenceClient.

# Run text_generation task:
>>> endpoint.client.text_generation("I am")
' not a fan of the idea of a "big-budget" movie. I think it\'s a'

# Or in an asyncio context:
>>> await endpoint.async_client.text_generation("I am")

Si le point de terminaison d’inférence n’est pas en cours d’exécution, une exception InferenceEndpointError est levée :

>>> endpoint.client
huggingface_hub._inference_endpoints.InferenceEndpointError: Cannot create a client for this Inference Endpoint as it is not yet deployed. Please wait for the Inference Endpoint to be deployed using `endpoint.wait()` and try again.

Pour plus de détails sur l'utilisation de InferenceClient, consultez le guide d'inférence.

Gérer le cycle de vie

Maintenant que nous avons vu comment créer un Inference Endpoint et y exécuter une inférence, voyons comment gérer son cycle de vie.

Dans cette section, nous verrons des méthodes telles que pause(), resume(), scale_to_zero(), update() et delete(). Toutes ces méthodes sont des alias ajoutés à InferenceEndpoint pour plus de commodité. Si vous préférez, vous pouvez également utiliser les méthodes génériques définies dans HfApi : pause_inference_endpoint(), resume_inference_endpoint(), scale_to_zero_inference_endpoint(), update_inference_endpoint() et delete_inference_endpoint().

Mettre en pause ou réduire à zéro

Pour réduire les coûts lorsque votre Inference Endpoint n'est pas utilisé, vous pouvez choisir de le mettre en pause à l'aide de pause() ou de le réduire à zéro à l'aide de scale_to_zero().

Un Inference Endpoint en pause ou mis à l’échelle zéro ne coûte rien. La différence entre les deux est qu’un endpoint en pause doit être explicitement reprise à l’aide de resume(). En revanche, un endpoint mis à l’échelle zéro démarre automatiquement lorsqu’un appel d’inférence lui est adressé, avec un délai de démarrage à froid supplémentaire. Un Inference Endpoint peut également être configuré pour passer automatiquement à l’échelle zéro après une certaine période d’inactivité.

# Pause and resume endpoint
>>> endpoint.pause()
InferenceEndpoint(name='my-endpoint-name', namespace='Wauplin', repository='gpt2', status='paused', url=None)
>>> endpoint.resume()
InferenceEndpoint(name='my-endpoint-name', namespace='Wauplin', repository='gpt2', status='pending', url=None)
>>> endpoint.wait().client.text_generation(...)
...

# Scale to zero
>>> endpoint.scale_to_zero()
InferenceEndpoint(name='my-endpoint-name', namespace='Wauplin', repository='gpt2', status='scaledToZero', url='https://jpj7k2q4j805b727.us-east-1.aws.endpoints.huggingface.cloud')
# Endpoint is not 'running' but still has a URL and will restart on first call.

Ou via l'interface en ligne de commande :

hf endpoints pause my-endpoint-name
hf endpoints resume my-endpoint-name
hf endpoints scale-to-zero my-endpoint-name

Mettre à jour les exigences relatives au modèle ou au matériel

Dans certains cas, vous pouvez également mettre à jour votre Inference Endpoint sans en créer un nouveau. Vous pouvez soit mettre à jour le modèle hébergé, soit les exigences matérielles pour exécuter le modèle. Vous pouvez le faire à l'aide de update() :

# Change target model
>>> endpoint.update(repository="gpt2-large")
InferenceEndpoint(name='my-endpoint-name', namespace='Wauplin', repository='gpt2-large', status='pending', url=None)

# Update number of replicas
>>> endpoint.update(min_replica=2, max_replica=6)
InferenceEndpoint(name='my-endpoint-name', namespace='Wauplin', repository='gpt2-large', status='pending', url=None)

# Update to larger instance
>>> endpoint.update(accelerator="cpu", instance_size="x4", instance_type="intel-icl")
InferenceEndpoint(name='my-endpoint-name', namespace='Wauplin', repository='gpt2-large', status='pending', url=None)

# Update the container arguments, e.g. engine flags on an endpoint running vLLM or SGLang.
# Replaces the current value, it is not appended.
>>> endpoint.update(container_args=["--enable-auto-tool-choice", "--tool-call-parser", "lfm2"])
InferenceEndpoint(name='my-endpoint-name', namespace='Wauplin', repository='gpt2-large', status='pending', url=None)

Ou via l'interface en ligne de commande :

hf endpoints update my-endpoint-name --repo gpt2-large
hf endpoints update my-endpoint-name --min-replica 2 --max-replica 6
hf endpoints update my-endpoint-name --accelerator cpu --instance-size x4 --instance-type intel-icl
hf endpoints update my-endpoint-name --container-args "--enable-auto-tool-choice --tool-call-parser lfm2"
# Merged into the image currently configured on the endpoint.
hf endpoints update my-endpoint-name --tensor-parallel-size 8
# Or replace the image entirely, in which case pass back the settings you want to keep.
hf endpoints update my-endpoint-name --engine vllm --custom-image vllm/vllm-openai:v0.23.0 --port 8000

Supprimer le point de terminaison

Enfin, si vous n'utilisez plus le Inference Endpoint, vous pouvez simplement appeler ~InferenceEndpoint.delete().

Cette action est irréversible et supprimera complètement le point de terminaison, y compris sa configuration, ses journaux et ses métriques d'utilisation. Vous ne pouvez pas restaurer un Inference Endpoint supprimé.

Un exemple de bout en bout

Un cas d’usage typique des Inference Endpoints consiste à traiter un lot de tâches en une seule fois afin de limiter les coûts d’infrastructure. Vous pouvez automatiser ce processus à l’aide de ce que nous avons vu dans ce guide :

>>> import asyncio
>>> from huggingface_hub import create_inference_endpoint

# Start endpoint + wait until initialized
>>> endpoint = create_inference_endpoint(name="batch-endpoint",...).wait()

# Run inference
>>> client = endpoint.client
>>> results = [client.text_generation(...) for job in jobs]

# Or with asyncio
>>> async_client = endpoint.async_client
>>> results = await asyncio.gather(*[async_client.text_generation(...) for job in jobs])

# Pause endpoint
>>> endpoint.pause()

Sinon, si votre Inference Endpoint existe déjà et est en pause :

>>> import asyncio
>>> from huggingface_hub import get_inference_endpoint

# Get endpoint + wait until initialized
>>> endpoint = get_inference_endpoint("batch-endpoint").resume().wait()

# Run inference
>>> async_client = endpoint.async_client
>>> results = await asyncio.gather(*[async_client.text_generation(...) for job in jobs])

# Pause endpoint
>>> endpoint.pause()
Update on GitHub