Transformers documentation
Serve CLI
Serve CLI
La CLI transformers serve est une option légère pour les serveurs locaux ou auto-hébergés. Elle évite les surcoûts d’exécution et d’exploitation supplémentaires des moteurs d’inférence dédiés comme vLLM. Utilisez-la pour l’évaluation, l’expérimentation et les déploiements à charge modérée. Des fonctionnalités comme le continuous batching augmentent le débit et réduisent la latence.
Pour les déploiements de production à grande échelle, utilisez vLLM ou SGLang avec un modèle Transformer en tant que backend. En savoir plus dans le guide Backends d'inférence.
La commande transformers serve démarre un serveur local compatible avec le OpenAI SDK. Ce serveur fonctionne avec de nombreuses applications tierces et prend en charge les API REST suivantes.
/v1/chat/completionspour les requêtes texte, image, audio et vidéo/v1/completionspour les complétions de texte héritées à partir d'un prompt libre/v1/responsesprend en charge la Responses API/v1/audio/transcriptionspour les transcriptions audio/v1/systemonerépond aux questions à choix multiples, de notation ou de type oui/non, en fournissant une probabilité pour chaque réponse autorisée/v1/modelsrépertorie les modèles disponibles pour les intégrations tierces/load_modeltransmet la progression du chargement du modèle via SSE
Installez les dépendances de service.
pip install transformers[serving]
Lancez un serveur en exécutant transformers serve. L'adresse du serveur par défaut est http://localhost:8000.
transformers serve
v1/chat/completions
L’API v1/chat/completions est basée sur l’API Chat Completions. Elle prend en charge les requêtes texte, image, audio et vidéo pour les LLM, les VLM et les modèles multimodaux. Utilisez-la avec curl, le InferenceClient ou le client OpenAI.
Complétions basées sur le texte
from huggingface_hub import InferenceClient
messages = [{"role": "user", "content": "What is the Transformers library known for?"}]
client = InferenceClient("http://localhost:8000")
result = client.chat_completion(messages, model="Qwen/Qwen2.5-0.5B-Instruct", max_tokens=256)
print(result.choices[0].message.content)InferenceClient renvoie une chaîne imprimée.
The Transformers library is primarily known for its ability to create and manipulate large-scale language models [...]
from huggingface_hub import InferenceClient
messages = [{"role": "user", "content": "What is the Transformers library known for?"}]
client = InferenceClient("http://localhost:8000")
stream = client.chat_completion(messages, model="Qwen/Qwen2.5-0.5B-Instruct", max_tokens=256, stream=True)
for chunk in stream:
token = chunk.choices[0].delta.content
if token:
print(token, end="")InferenceClient renvoie une chaîne imprimée.
The Transformers library is primarily known for its ability to create and manipulate large-scale language models [...]
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
completion = client.chat.completions.create(
model="Qwen/Qwen2.5-0.5B-Instruct",
messages=[
{
"role": "user",
"content": "What is the Transformers library known for?"
}
],
)
print(completion.choices[0].message.content)Le client OpenAI renvoie une chaîne imprimée.
The Transformers library is primarily known for its ability to create and manipulate large-scale language models [...]
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
completion = client.chat.completions.create(
model="Qwen/Qwen2.5-0.5B-Instruct",
messages=[
{
"role": "user",
"content": "What is the Transformers library known for?"
}
],
stream=True,
)
for chunk in completion:
token = chunk.choices[0].delta.content
if token:
print(token, end="")Le client OpenAI renvoie une chaîne imprimée.
The Transformers library is primarily known for its ability to create and manipulate large-scale language models [...]
curl -X POST http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-0.5B-Instruct",
"messages": [{"role": "user", "content": "What is the Transformers library known for?"}],
"temperature": 0.9,
"max_tokens": 256
}'La commande renvoie une chaîne JSON.
{
"id": "ade3578d-e2c3-47ed-b651-c014991a92f6",
"choices": [
{
"finish_reason": "length",
"index": 0,
"message": {
"content": "The Transformers library is primarily known for its ability to create and manipulate large-scale language models [...]",
"role": "assistant"
}
}
],
"created": 1776184004,
"model": "Qwen/Qwen2.5-0.5B-Instruct@main",
"object": "chat.completion",
"usage": {
"completion_tokens": 256,
"prompt_tokens": 37,
"total_tokens": 293
}
}curl -X POST http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-0.5B-Instruct",
"messages": [{"role": "user", "content": "What is the Transformers library known for?"}],
"temperature": 0.9,
"max_tokens": 256,
"stream": true
}'La commande renvoie un flux de segments.
data: {"id":"596d3941-754d-43b4-8773-9bf9940049f5","choices":[{"delta":{"role":"assistant"},"index":0}],"created":1776183469,"model":"Qwen/Qwen2.5-0.5B-Instruct@main","object":"chat.completion.chunk","system_fingerprint":""}
data: {"id":"596d3941-754d-43b4-8773-9bf9940049f5","choices":[{"delta":{"content":"The"},"index":0}],"created":1776183469,"model":"Qwen/Qwen2.5-0.5B-Instruct@main","object":"chat.completion.chunk","system_fingerprint":""}
(...)Complétions basées sur des images
from huggingface_hub import InferenceClient
messages = [
{
"role": "user",
"content": [
{"type": "text", "text": "What's in this image?"},
{
"type": "image_url",
"image_url": {
"url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/astronaut.jpg",
}
},
],
}
]
client = InferenceClient("http://localhost:8000")
result = client.chat_completion(messages, model="Qwen/Qwen2.5-VL-7B-Instruct", max_tokens=256)
print(result.choices[0].message.content)InferenceClient renvoie une chaîne imprimée.
The image depicts an astronaut in a space suit standing on what appears to be the surface of the moon, given the barren, rocky landscape and the dark sky in the background. The astronaut is holding a large egg that has cracked open, revealing a small creature inside. The scene is imaginative and playful, combining elements of space exploration with a whimsical twist involving the egg and the creature.from huggingface_hub import InferenceClient
messages = [
{
"role": "user",
"content": [
{"type": "text", "text": "What's in this image?"},
{
"type": "image_url",
"image_url": {
"url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/astronaut.jpg",
}
},
],
}
]
client = InferenceClient("http://localhost:8000")
stream = client.chat_completion(messages, model="Qwen/Qwen2.5-VL-7B-Instruct", max_tokens=256, stream=True)
for chunk in stream:
token = chunk.choices[0].delta.content
if token:
print(token, end="")InferenceClient renvoie une chaîne imprimée.
The image depicts an astronaut in a space suit standing on what appears to be the surface of the moon, given the barren, rocky landscape and the dark sky in the background. The astronaut is holding a large egg that has cracked open, revealing a small creature inside. The scene is imaginative and playful, combining elements of space exploration with a whimsical twist involving the egg and the creature.from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
completion = client.chat.completions.create(
model="Qwen/Qwen2.5-VL-7B-Instruct",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "What's in this image?"},
{
"type": "image_url",
"image_url": {
"url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/astronaut.jpg",
}
},
],
}
],
)
print(completion.choices[0].message.content)Le client OpenAI renvoie une chaîne imprimée.
The image depicts an astronaut in a space suit standing on what appears to be the surface of the moon, given the barren, rocky landscape and the dark sky in the background. The astronaut is holding a large egg that has cracked open, revealing a small creature inside. The scene is imaginative and playful, combining elements of space exploration with a whimsical twist involving the egg and the creature.from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
completion = client.chat.completions.create(
model="Qwen/Qwen2.5-VL-7B-Instruct",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "What's in this image?"},
{
"type": "image_url",
"image_url": {
"url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/astronaut.jpg",
}
},
],
}
],
stream=True,
)
for chunk in completion:
token = chunk.choices[0].delta.content
if token:
print(token, end="")Le client OpenAI renvoie une chaîne imprimée.
The image depicts an astronaut in a space suit standing on what appears to be the surface of the moon, given the barren, rocky landscape and the dark sky in the background. The astronaut is holding a large egg that has cracked open, revealing a small creature inside. The scene is imaginative and playful, combining elements of space exploration with a whimsical twist involving the egg and the creature.curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-VL-7B-Instruct",
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "What's in this image?"
},
{
"type": "image_url",
"image_url": {
"url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/astronaut.jpg"
}
}
]
}
],
"max_tokens": 256
}'La commande renvoie une chaîne JSON.
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"choices": [
{
"finish_reason": "stop",
"index": 0,
"message": {
"content": "The image depicts an astronaut in a space suit standing on what appears to be the surface of the moon [...]",
"role": "assistant"
}
}
],
"created": 1753366665,
"model": "Qwen/Qwen2.5-VL-7B-Instruct@main",
"object": "chat.completion",
"usage": {
"completion_tokens": 50,
"prompt_tokens": 120,
"total_tokens": 170
}
}curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-VL-7B-Instruct",
"stream": true,
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "What's in this image?"
},
{
"type": "image_url",
"image_url": {
"url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/astronaut.jpg"
}
}
]
}
],
"max_tokens": 256
}'La commande renvoie un flux de segments.
data: {"id":"f47ac10b-58cc-4372-a567-0e02b2c3d479","choices":[{"delta":{"role":"assistant"},"index":0}],"created":1753366665,"model":"Qwen/Qwen2.5-VL-7B-Instruct@main","object":"chat.completion.chunk","system_fingerprint":""}
data: {"id":"f47ac10b-58cc-4372-a567-0e02b2c3d479","choices":[{"delta":{"content":"The "},"index":0}],"created":1753366701,"model":"Qwen/Qwen2.5-VL-7B-Instruct@main","object":"chat.completion.chunk","system_fingerprint":""}
(...)Complétions basées sur l'audio
Les modèles multimodaux comme Gemma 4 et Qwen2.5-Omni acceptent l'entrée audio via le type de contenu input_audio d'OpenAI. Encodagez l'audio en Base64 et spécifiez le format (mp3 ou wav).
import base64
from huggingface_hub.utils import httpx
from huggingface_hub import InferenceClient
audio_url = "https://huggingface.co/datasets/hf-internal-testing/dummy-audio-samples/resolve/main/obama_first_45_secs.mp3"
audio_b64 = base64.b64encode(httpx.get(audio_url, follow_redirects=True).content).decode()
messages = [
{
"role": "user",
"content": [
{"type": "text", "text": "Transcribe this audio."},
{"type": "input_audio", "input_audio": {"data": audio_b64, "format": "mp3"}},
],
}
]
client = InferenceClient("http://localhost:8000")
result = client.chat_completion(messages, model="google/gemma-4-E2B-it", max_tokens=256)
print(result.choices[0].message.content)InferenceClient renvoie une chaîne imprimée.
This week, I traveled to Chicago to deliver my final farewell address to the nation, following in the tradition of presidents before me. It was an opportunity to say thank you. Whether we've seen eye to eye or rarely agreed at all, my conversations with you, the American people, in living rooms and schools, at farms and on factory floors, at diners, and on distant military outposts, all these conversations are what have kept me honest.import base64
from huggingface_hub.utils import httpx
from huggingface_hub import InferenceClient
audio_url = "https://huggingface.co/datasets/hf-internal-testing/dummy-audio-samples/resolve/main/obama_first_45_secs.mp3"
audio_b64 = base64.b64encode(httpx.get(audio_url, follow_redirects=True).content).decode()
messages = [
{
"role": "user",
"content": [
{"type": "text", "text": "Transcribe this audio."},
{"type": "input_audio", "input_audio": {"data": audio_b64, "format": "mp3"}},
],
}
]
client = InferenceClient("http://localhost:8000")
stream = client.chat_completion(messages, model="google/gemma-4-E2B-it", max_tokens=256, stream=True)
for chunk in stream:
token = chunk.choices[0].delta.content
if token:
print(token, end="")InferenceClient renvoie une chaîne imprimée.
This week, I traveled to Chicago to deliver my final farewell address to the nation, following in the tradition of presidents before me. It was an opportunity to say thank you. Whether we've seen eye to eye or rarely agreed at all, my conversations with you, the American people, in living rooms and schools, at farms and on factory floors, at diners, and on distant military outposts, all these conversations are what have kept me honest.import base64
from huggingface_hub.utils import httpx
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
audio_url = "https://huggingface.co/datasets/hf-internal-testing/dummy-audio-samples/resolve/main/obama_first_45_secs.mp3"
audio_b64 = base64.b64encode(httpx.get(audio_url, follow_redirects=True).content).decode()
completion = client.chat.completions.create(
model="google/gemma-4-E2B-it",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "Transcribe this audio."},
{"type": "input_audio", "input_audio": {"data": audio_b64, "format": "mp3"}},
],
}
],
)
print(completion.choices[0].message.content)Le client OpenAI renvoie une chaîne imprimée.
This week, I traveled to Chicago to deliver my final farewell address to the nation, following in the tradition of presidents before me. It was an opportunity to say thank you. Whether we've seen eye to eye or rarely agreed at all, my conversations with you, the American people, in living rooms and schools, at farms and on factory floors, at diners, and on distant military outposts, all these conversations are what have kept me honest.import base64
from huggingface_hub.utils import httpx
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
audio_url = "https://huggingface.co/datasets/hf-internal-testing/dummy-audio-samples/resolve/main/obama_first_45_secs.mp3"
audio_b64 = base64.b64encode(httpx.get(audio_url, follow_redirects=True).content).decode()
completion = client.chat.completions.create(
model="google/gemma-4-E2B-it",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "Transcribe this audio."},
{"type": "input_audio", "input_audio": {"data": audio_b64, "format": "mp3"}},
],
}
],
stream=True,
)
for chunk in completion:
token = chunk.choices[0].delta.content
if token:
print(token, end="")Le client OpenAI renvoie une chaîne imprimée.
This week, I traveled to Chicago to deliver my final farewell address to the nation, following in the tradition of presidents before me. It was an opportunity to say thank you. Whether we've seen eye to eye or rarely agreed at all, my conversations with you, the American people, in living rooms and schools, at farms and on factory floors, at diners, and on distant military outposts, all these conversations are what have kept me honest.# First, base64-encode the audio file and build the JSON payload
AUDIO_B64=$(curl -sL https://huggingface.co/datasets/hf-internal-testing/dummy-audio-samples/resolve/main/obama_first_45_secs.mp3 | base64 -w 0)
cat <<EOF > /tmp/audio_request.json
{
"model": "google/gemma-4-E2B-it",
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "Transcribe this audio."},
{"type": "input_audio", "input_audio": {"data": "$AUDIO_B64", "format": "mp3"}}
]
}
]
}
EOF
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d @/tmp/audio_request.jsonLa commande renvoie une chaîne JSON.
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"choices": [
{
"finish_reason": "stop",
"index": 0,
"message": {
"content": "This week, I traveled to Chicago to deliver my final farewell address to the nation [...]",
"role": "assistant"
}
}
],
"created": 1753366665,
"model": "google/gemma-4-E2B-it@main",
"object": "chat.completion",
"usage": {
"completion_tokens": 85,
"prompt_tokens": 200,
"total_tokens": 285
}
}# First, base64-encode the audio file and build the JSON payload
AUDIO_B64=$(curl -sL https://huggingface.co/datasets/hf-internal-testing/dummy-audio-samples/resolve/main/obama_first_45_secs.mp3 | base64 -w 0)
cat <<EOF > /tmp/audio_request.json
{
"model": "google/gemma-4-E2B-it",
"stream": true,
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "Transcribe this audio."},
{"type": "input_audio", "input_audio": {"data": "$AUDIO_B64", "format": "mp3"}}
]
}
]
}
EOF
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d @/tmp/audio_request.jsonLa commande renvoie un flux de segments.
data: {"id":"cb997e1d-98b9-414a-be89-1880288610ef","choices":[{"delta":{"role":"assistant"},"index":0}],"created":1776254856,"model":"google/gemma-4-E2B-it@main","object":"chat.completion.chunk","system_fingerprint":""}
data: {"id":"cb997e1d-98b9-414a-be89-1880288610ef","choices":[{"delta":{"content":"This"},"index":0}],"created":1776254856,"model":"google/gemma-4-E2B-it@main","object":"chat.completion.chunk","system_fingerprint":""}
(...)Le type de contenu
audio_urlest une extension qui ne fait pas partie de la norme OpenAI et peut évoluer dans les versions futures.
Vous pouvez également passer l’audio par URL avec le type de contenu audio_url pour éviter l’encodage base64.
completion = client.chat.completions.create(
model="google/gemma-4-E2B-it",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "Transcribe this audio."},
{"type": "audio_url", "audio_url": {"url": "https://huggingface.co/datasets/hf-internal-testing/dummy-audio-samples/resolve/main/obama_first_45_secs.mp3"}},
],
}
],
)Complétions basées sur la vidéo
Le type de contenu
video_urlest une extension qui ne fait pas partie de la norme OpenAI et peut évoluer dans les versions futures.
Utilisez le type de contenu video_url pour l’entrée vidéo. Si le modèle prend en charge l’audio (par ex. Gemma 4, Qwen2.5-Omni), le serveur extrait la piste audio de la vidéo et la traite avec les images visuelles.
Le traitement vidéo nécessite torchcodec. Installez-le avec
pip install torchcodec.
from huggingface_hub import InferenceClient
messages = [
{
"role": "user",
"content": [
{"type": "video_url", "video_url": {"url": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/concert.mp4"}},
{"type": "text", "text": "What is happening in the video and what is the song about?"},
],
}
]
client = InferenceClient("http://localhost:8000")
result = client.chat_completion(messages, model="google/gemma-4-E2B-it", max_tokens=256)
print(result.choices[0].message.content)InferenceClient renvoie une chaîne imprimée.
The video captures a live music performance at a music festival or a large concert. There are several musicians on stage, including a central figure playing an acoustic guitar and singing. The foreground is filled with the backs of the audience, indicating a large crowd watching the show. The stage is dramatically lit with bright spotlights and blue and white stage lighting, with haze and smoke creating an immersive atmosphere.
The lyrics of the song are: "I don't care 'bout street, from that fresh street, 'cause there's no problem, another one I want to be, in the storm..."from huggingface_hub import InferenceClient
messages = [
{
"role": "user",
"content": [
{"type": "video_url", "video_url": {"url": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/concert.mp4"}},
{"type": "text", "text": "What is happening in the video and what is the song about?"},
],
}
]
client = InferenceClient("http://localhost:8000")
stream = client.chat_completion(messages, model="google/gemma-4-E2B-it", max_tokens=256, stream=True)
for chunk in stream:
token = chunk.choices[0].delta.content
if token:
print(token, end="")InferenceClient renvoie une chaîne imprimée.
The video captures a live music performance at a music festival or a large concert. There are several musicians on stage, including a central figure playing an acoustic guitar and singing. The foreground is filled with the backs of the audience, indicating a large crowd watching the show. The stage is dramatically lit with bright spotlights and blue and white stage lighting, with haze and smoke creating an immersive atmosphere.
The lyrics of the song are: "I don't care 'bout street, from that fresh street, 'cause there's no problem, another one I want to be, in the storm..."from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
completion = client.chat.completions.create(
model="google/gemma-4-E2B-it",
messages=[
{
"role": "user",
"content": [
{"type": "video_url", "video_url": {"url": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/concert.mp4"}},
{"type": "text", "text": "What is happening in the video and what is the song about?"},
],
}
],
max_tokens=256,
)
print(completion.choices[0].message.content)Le client OpenAI renvoie une chaîne imprimée.
The video captures a live music performance at a music festival or a large concert. There are several musicians on stage, including a central figure playing an acoustic guitar and singing. The foreground is filled with the backs of the audience, indicating a large crowd watching the show. The stage is dramatically lit with bright spotlights and blue and white stage lighting, with haze and smoke creating an immersive atmosphere.
The lyrics of the song are: "I don't care 'bout street, from that fresh street, 'cause there's no problem, another one I want to be, in the storm..."from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
completion = client.chat.completions.create(
model="google/gemma-4-E2B-it",
messages=[
{
"role": "user",
"content": [
{"type": "video_url", "video_url": {"url": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/concert.mp4"}},
{"type": "text", "text": "What is happening in the video and what is the song about?"},
],
}
],
max_tokens=256,
stream=True,
)
for chunk in completion:
token = chunk.choices[0].delta.content
if token:
print(token, end="")Le client OpenAI renvoie une chaîne imprimée.
The video captures a live music performance at a music festival or a large concert. There are several musicians on stage, including a central figure playing an acoustic guitar and singing. The foreground is filled with the backs of the audience, indicating a large crowd watching the show. The stage is dramatically lit with bright spotlights and blue and white stage lighting, with haze and smoke creating an immersive atmosphere.
The lyrics of the song are: "I don't care 'bout street, from that fresh street, 'cause there's no problem, another one I want to be, in the storm..."curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "google/gemma-4-E2B-it",
"messages": [
{
"role": "user",
"content": [
{"type": "video_url", "video_url": {"url": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/concert.mp4"}},
{"type": "text", "text": "What is happening in the video and what is the song about?"}
]
}
],
"max_tokens": 256
}'La commande renvoie une chaîne JSON.
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"choices": [
{
"finish_reason": "length",
"index": 0,
"message": {
"content": "The video captures a live music performance at a music festival or a large concert [...]",
"role": "assistant"
}
}
],
"created": 1753366665,
"model": "google/gemma-4-E2B-it@main",
"object": "chat.completion",
"usage": {
"completion_tokens": 256,
"prompt_tokens": 350,
"total_tokens": 606
}
}curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "google/gemma-4-E2B-it",
"stream": true,
"messages": [
{
"role": "user",
"content": [
{"type": "video_url", "video_url": {"url": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/concert.mp4"}},
{"type": "text", "text": "What is happening in the video and what is the song about?"}
]
}
],
"max_tokens": 256
}'La commande renvoie un flux de segments.
data: {"id":"cb997e1d-98b9-414a-be89-1880288610ef","choices":[{"delta":{"role":"assistant"},"index":0}],"created":1776254856,"model":"google/gemma-4-E2B-it@main","object":"chat.completion.chunk","system_fingerprint":""}
data: {"id":"cb997e1d-98b9-414a-be89-1880288610ef","choices":[{"delta":{"content":"Based"},"index":0}],"created":1776254856,"model":"google/gemma-4-E2B-it@main","object":"chat.completion.chunk","system_fingerprint":""}
(...)Conversations multi-tours
Pour mener une conversation multi-tours, incluez l’historique complet de la conversation dans la liste messages en alternant les rôles user et assistant. Comme tous les serveurs compatibles OpenAI, l’API est sans état : chaque requête doit donc contenir l’historique complet de la conversation.
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
completion = client.chat.completions.create(
model="Qwen/Qwen2.5-0.5B-Instruct",
messages=[
{"role": "user", "content": "What is the capital of France?"},
{"role": "assistant", "content": "The capital of France is Paris."},
{"role": "user", "content": "How many people live there?"},
],
)
print(completion.choices[0].message.content)La question de suivi « Combien de personnes y vivent ? » s’appuie sur le contexte précédent, de sorte que le modèle répond en parlant de Paris.
As of 2021, the population of Paris is approximately 2.2 million people.v1/completions
L’API v1/completions est basée sur l’API Completions legacy. Contrairement à /v1/chat/completions, elle prend en entrée un prompt de texte libre plutôt que des messages de chat, et renvoie le texte généré dans choices[].text. Elle est utile pour les modèles de base (non instruct) et les tâches de complétion de texte où un gabarit de chat n’est pas nécessaire. Elle prend également en charge suffix pour l’insertion de texte en milieu de séquence (fill-in-the-middle).
curl -X POST http://localhost:8000/v1/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-0.5B",
"prompt": "The capital of France is",
"max_tokens": 20
}'La commande renvoie la réponse suivante.
{
"id": "chatcmpl-abc123",
"object": "text_completion",
"created": 1234567890,
"model": "Qwen/Qwen2.5-0.5B@main",
"choices": [
{
"text": " Paris, and the capital of the United States is Washington, D.C.",
"index": 0,
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 5,
"completion_tokens": 16,
"total_tokens": 21
}
}from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
# Non-streaming
completion = client.completions.create(
model="Qwen/Qwen2.5-0.5B",
prompt="The capital of France is",
max_tokens=20,
)
print(completion.choices[0].text)Le client OpenAI renvoie ce qui suit.
Paris, and the capital of the United States is Washington, D.C.
Le streaming est également pris en charge.
stream = client.completions.create(
model="Qwen/Qwen2.5-0.5B",
prompt="The capital of France is",
max_tokens=20,
stream=True,
)
for chunk in stream:
print(chunk.choices[0].text, end="")v1/responses
L'Responses API est le dernier point d'accès API d'OpenAI pour la génération. Il prend en charge les interactions avec état et intègre des outils intégrés pour étendre les capacités d'un modèle. OpenAI recommande d'utiliser la Responses API plutôt que la Chat Completions API pour les nouveaux projets.
L’API v1/responses prend en charge les requêtes texte, image, audio et vidéo via la commande curl et le client OpenAI.
Réponses basées sur le texte
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
response = client.responses.create(
model="Qwen/Qwen2.5-0.5B-Instruct",
input="Tell me a three sentence bedtime story about a unicorn.",
max_output_tokens=256,
stream=False,
)
print(response.output[0].content[0].text)Le client OpenAI renvoie une chaîne imprimée.
Once upon a time, in a faraway land, there lived a beautiful unicorn named Luna [...]
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
response = client.responses.create(
model="Qwen/Qwen2.5-0.5B-Instruct",
input="Tell me a three sentence bedtime story about a unicorn.",
max_output_tokens=256,
stream=True,
)
for event in response:
if hasattr(event, "delta") and event.delta:
print(event.delta, end="")Le client OpenAI renvoie une chaîne imprimée.
Once upon a time, in a faraway land, there lived a beautiful unicorn named Luna [...]
curl http://localhost:8000/v1/responses \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-0.5B-Instruct",
"input": "Tell me a three sentence bedtime story about a unicorn.",
"max_output_tokens": 256,
"stream": false
}'La commande renvoie une chaîne JSON.
{
"id": "resp_8693af9b-b561-4267-bd1a-22d1b43284cb",
"created_at": 1776258580.7114341,
"model": "Qwen/Qwen2.5-0.5B-Instruct@main",
"object": "response",
"output": [
{
"id": "msg_8693af9b-b561-4267-bd1a-22d1b43284cb",
"content": [
{
"annotations": [],
"text": "Once upon a time, in a faraway land, there lived a beautiful unicorn named Luna [...]",
"type": "output_text"
}
],
"role": "assistant",
"status": "completed",
"type": "message"
}
],
"status": "completed"
}curl http://localhost:8000/v1/responses \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-0.5B-Instruct",
"stream": true,
"input": "Tell me a three sentence bedtime story about a unicorn.",
"max_output_tokens": 256
}'La commande renvoie un flux de segments.
data: {"response":{"id":"resp_req_0","created_at":1754059817.783648,"model":"Qwen/Qwen2.5-0.5B-Instruct@main","object":"response","output":[],"status":"queued"},"sequence_number":0,"type":"response.created"}
data: {"content_index":0,"delta":"Once ","item_id":"msg_req_0","output_index":0,"sequence_number":5,"type":"response.output_text.delta"}
data: {"content_index":0,"delta":"upon ","item_id":"msg_req_0","output_index":0,"sequence_number":6,"type":"response.output_text.delta"}
(...)Réponses basées sur des images
L'API Responses prend également en charge les entrées image, audio et vidéo.
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
response = client.responses.create(
model="Qwen/Qwen2.5-VL-7B-Instruct",
input=[
{"type": "input_text", "text": "What's in this image?"},
{
"type": "input_image",
"image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/astronaut.jpg",
},
],
max_output_tokens=256,
stream=False,
)
print(response.output[0].content[0].text)Le client OpenAI renvoie une chaîne imprimée.
The image depicts an astronaut in a space suit standing on what appears to be the surface of the moon, given the barren, rocky landscape and the dark sky in the background. The astronaut is holding a large egg that has cracked open, revealing a small creature inside. The scene is imaginative and playful, combining elements of space exploration with a whimsical twist involving the egg and the creature.from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
response = client.responses.create(
model="Qwen/Qwen2.5-VL-7B-Instruct",
input=[
{"type": "input_text", "text": "What's in this image?"},
{
"type": "input_image",
"image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/astronaut.jpg",
},
],
max_output_tokens=256,
stream=True,
)
for event in response:
if hasattr(event, "delta") and event.delta:
print(event.delta, end="")Le client OpenAI renvoie une chaîne imprimée.
The image depicts an astronaut in a space suit standing on what appears to be the surface of the moon, given the barren, rocky landscape and the dark sky in the background. The astronaut is holding a large egg that has cracked open, revealing a small creature inside. The scene is imaginative and playful, combining elements of space exploration with a whimsical twist involving the egg and the creature.curl http://localhost:8000/v1/responses \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-VL-7B-Instruct",
"input": [
{"type": "input_text", "text": "What'\''s in this image?"},
{"type": "input_image", "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/astronaut.jpg"}
],
"max_output_tokens": 256,
"stream": false
}'La commande renvoie une chaîne JSON.
{
"id": "resp_f47ac10b-58cc-4372-a567-0e02b2c3d479",
"created_at": 1776258580.7114341,
"model": "Qwen/Qwen2.5-VL-7B-Instruct@main",
"object": "response",
"output": [
{
"id": "msg_f47ac10b-58cc-4372-a567-0e02b2c3d479",
"content": [
{
"annotations": [],
"text": "The image depicts an astronaut in a space suit standing on what appears to be the surface of the moon [...]",
"type": "output_text"
}
],
"role": "assistant",
"status": "completed",
"type": "message"
}
],
"status": "completed"
}curl http://localhost:8000/v1/responses \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-VL-7B-Instruct",
"stream": true,
"input": [
{"type": "input_text", "text": "What'\''s in this image?"},
{"type": "input_image", "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/astronaut.jpg"}
],
"max_output_tokens": 256
}'La commande renvoie un flux de segments.
data: {"response":{"id":"resp_f47ac10b-58cc-4372-a567-0e02b2c3d479","created_at":1776258580.7114341,"model":"Qwen/Qwen2.5-VL-7B-Instruct@main","object":"response","output":[],"status":"queued"},"sequence_number":0,"type":"response.created"}
data: {"content_index":0,"delta":"The ","item_id":"msg_f47ac10b","output_index":0,"sequence_number":5,"type":"response.output_text.delta"}
(...)Réponses basées sur l'audio
import base64
from huggingface_hub.utils import httpx
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
audio_url = "https://huggingface.co/datasets/hf-internal-testing/dummy-audio-samples/resolve/main/obama_first_45_secs.mp3"
audio_b64 = base64.b64encode(httpx.get(audio_url, follow_redirects=True).content).decode()
response = client.responses.create(
model="google/gemma-4-E2B-it",
input=[
{"type": "input_text", "text": "Transcribe this audio."},
{"type": "input_audio", "input_audio": {"data": audio_b64, "format": "mp3"}},
],
max_output_tokens=256,
stream=False,
)
print(response.output[0].content[0].text)Le client OpenAI renvoie une chaîne imprimée.
This week, I traveled to Chicago to deliver my final farewell address to the nation, following in the tradition of presidents before me. It was an opportunity to say thank you. Whether we've seen eye to eye or rarely agreed at all, my conversations with you, the American people, in living rooms and schools, at farms and on factory floors, at diners, and on distant military outposts, all these conversations are what have kept me honest.import base64
from huggingface_hub.utils import httpx
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
audio_url = "https://huggingface.co/datasets/hf-internal-testing/dummy-audio-samples/resolve/main/obama_first_45_secs.mp3"
audio_b64 = base64.b64encode(httpx.get(audio_url, follow_redirects=True).content).decode()
response = client.responses.create(
model="google/gemma-4-E2B-it",
input=[
{"type": "input_text", "text": "Transcribe this audio."},
{"type": "input_audio", "input_audio": {"data": audio_b64, "format": "mp3"}},
],
}
],
max_output_tokens=256,
stream=True,
)
for event in response:
if hasattr(event, "delta") and event.delta:
print(event.delta, end="")Le client OpenAI renvoie une chaîne imprimée.
This week, I traveled to Chicago to deliver my final farewell address to the nation, following in the tradition of presidents before me. It was an opportunity to say thank you. Whether we've seen eye to eye or rarely agreed at all, my conversations with you, the American people, in living rooms and schools, at farms and on factory floors, at diners, and on distant military outposts, all these conversations are what have kept me honest.# First, base64-encode the audio file and build the JSON payload
AUDIO_B64=$(curl -sL https://huggingface.co/datasets/hf-internal-testing/dummy-audio-samples/resolve/main/obama_first_45_secs.mp3 | base64 -w 0)
cat <<EOF > /tmp/audio_request.json
{
"model": "google/gemma-4-E2B-it",
"input": [
{"type": "input_text", "text": "Transcribe this audio."},
{"type": "input_audio", "input_audio": {"data": "$AUDIO_B64", "format": "mp3"}}
],
"max_output_tokens": 256,
"stream": false
}
EOF
curl http://localhost:8000/v1/responses \
-H "Content-Type: application/json" \
-d @/tmp/audio_request.jsonLa commande renvoie une chaîne JSON.
{
"id": "resp_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": 1776258580.7114341,
"model": "google/gemma-4-E2B-it@main",
"object": "response",
"output": [
{
"id": "msg_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"content": [
{
"annotations": [],
"text": "This week, I traveled to Chicago to deliver my final farewell address to the nation [...]",
"type": "output_text"
}
],
"role": "assistant",
"status": "completed",
"type": "message"
}
],
"status": "completed"
}# First, base64-encode the audio file and build the JSON payload
AUDIO_B64=$(curl -sL https://huggingface.co/datasets/hf-internal-testing/dummy-audio-samples/resolve/main/obama_first_45_secs.mp3 | base64 -w 0)
cat <<EOF > /tmp/audio_request.json
{
"model": "google/gemma-4-E2B-it",
"stream": true,
"input": [
{"type": "input_text", "text": "Transcribe this audio."},
{"type": "input_audio", "input_audio": {"data": "$AUDIO_B64", "format": "mp3"}}
],
"max_output_tokens": 256
}
EOF
curl http://localhost:8000/v1/responses \
-H "Content-Type: application/json" \
-d @/tmp/audio_request.jsonLa commande renvoie un flux de segments.
data: {"response":{"id":"resp_a1b2c3d4-e5f6-7890-abcd-ef1234567890","created_at":1776258580.7114341,"model":"google/gemma-4-E2B-it@main","object":"response","output":[],"status":"queued"},"sequence_number":0,"type":"response.created"}
data: {"content_index":0,"delta":"This ","item_id":"msg_a1b2c3d4","output_index":0,"sequence_number":5,"type":"response.output_text.delta"}
(...)Le type de contenu
audio_urlest une extension qui ne fait pas partie de la norme OpenAI et peut évoluer dans les versions futures.
Vous pouvez également passer l’audio par URL avec le type de contenu audio_url pour éviter l’encodage base64.
response = client.responses.create(
model="google/gemma-4-E2B-it",
input=[
{"type": "input_text", "text": "Transcribe this audio."},
{"type": "audio_url", "audio_url": {"url": "https://huggingface.co/datasets/hf-internal-testing/dummy-audio-samples/resolve/main/obama_first_45_secs.mp3"}},
],
max_output_tokens=256,
stream=False,
)Réponses basées sur la vidéo
Le type de contenu
video_urlest une extension qui ne fait pas partie de la norme OpenAI et peut évoluer dans les versions futures.
Le traitement vidéo nécessite torchcodec. Installez-le avec
pip install torchcodec.
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
response = client.responses.create(
model="google/gemma-4-E2B-it",
input=[
{"type": "input_text", "text": "What is happening in the video and what is the song about?"},
{"type": "video_url", "video_url": {"url": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/concert.mp4"}},
],
max_output_tokens=256,
stream=False,
)
print(response.output[0].content[0].text)Le client OpenAI renvoie une chaîne imprimée.
The video captures a live music performance at a music festival or a large concert. There are several musicians on stage, including a central figure playing an acoustic guitar and singing. The foreground is filled with the backs of the audience, indicating a large crowd watching the show. The stage is dramatically lit with bright spotlights and blue and white stage lighting, with haze and smoke creating an immersive atmosphere.
The lyrics of the song are: "I don't care 'bout street, from that fresh street, 'cause there's no problem, another one I want to be, in the storm..."from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
response = client.responses.create(
model="google/gemma-4-E2B-it",
input=[
{"type": "input_text", "text": "What is happening in the video and what is the song about?"},
{"type": "video_url", "video_url": {"url": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/concert.mp4"}},
],
max_output_tokens=256,
stream=True,
)
for event in response:
if hasattr(event, "delta") and event.delta:
print(event.delta, end="")Le client OpenAI renvoie une chaîne imprimée.
The video captures a live music performance at a music festival or a large concert. There are several musicians on stage, including a central figure playing an acoustic guitar and singing. The foreground is filled with the backs of the audience, indicating a large crowd watching the show. The stage is dramatically lit with bright spotlights and blue and white stage lighting, with haze and smoke creating an immersive atmosphere.
The lyrics of the song are: "I don't care 'bout street, from that fresh street, 'cause there's no problem, another one I want to be, in the storm..."curl http://localhost:8000/v1/responses \
-H "Content-Type: application/json" \
-d '{
"model": "google/gemma-4-E2B-it",
"input": [
{"type": "input_text", "text": "What is happening in the video and what is the song about?"},
{"type": "video_url", "video_url": {"url": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/concert.mp4"}}
],
"max_output_tokens": 256,
"stream": false
}'La commande renvoie une chaîne JSON.
{
"id": "resp_b2c3d4e5-f6a7-8901-bcde-f12345678901",
"created_at": 1776258580.7114341,
"model": "google/gemma-4-E2B-it@main",
"object": "response",
"output": [
{
"id": "msg_b2c3d4e5-f6a7-8901-bcde-f12345678901",
"content": [
{
"annotations": [],
"text": "The video captures a live music performance at a music festival or a large concert [...]",
"type": "output_text"
}
],
"role": "assistant",
"status": "completed",
"type": "message"
}
],
"status": "completed"
}curl http://localhost:8000/v1/responses \
-H "Content-Type: application/json" \
-d '{
"model": "google/gemma-4-E2B-it",
"stream": true,
"input": [
{"type": "input_text", "text": "What is happening in the video and what is the song about?"},
{"type": "video_url", "video_url": {"url": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/concert.mp4"}}
],
"max_output_tokens": 256
}'La commande renvoie un flux de segments.
data: {"response":{"id":"resp_b2c3d4e5-f6a7-8901-bcde-f12345678901","created_at":1776258580.7114341,"model":"google/gemma-4-E2B-it@main","object":"response","output":[],"status":"queued"},"sequence_number":0,"type":"response.created"}
data: {"content_index":0,"delta":"Based ","item_id":"msg_b2c3d4e5","output_index":0,"sequence_number":5,"type":"response.output_text.delta"}
(...)Conversations multi-tours
Pour les conversations multi-tours, passez une liste de messages avec des clés role dans le champ input. Comme tous les serveurs compatibles OpenAI, l’API est sans état, chaque requête doit donc contenir l’historique complet de la conversation.
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<random_string>")
response = client.responses.create(
model="Qwen/Qwen2.5-0.5B-Instruct",
input=[
{"role": "user", "content": "What is the capital of France?"},
{"role": "assistant", "content": "The capital of France is Paris."},
{"role": "user", "content": "How many people live there?"},
],
max_output_tokens=256,
stream=False,
)
print(response.output[0].content[0].text)La question de suivi « Combien de personnes y vivent ? » s’appuie sur le contexte précédent, de sorte que le modèle répond en parlant de Paris.
As of 2021, Paris has a population of approximately 2.8 million people.v1/systemone
Le point d'accès v1/systemone répond à des questions typées concernant un state partagé, conformément à l'API System One de TypeSafe. Utilisez-le pour des décisions telles que l'aiguillage d'un ticket de support, l'évaluation de l'urgence ou le choix d'une action.
Le modèle évalue les réponses autorisées en un seul passage avant groupé, sans générer de texte. Ce point de terminaison prend en charge les modèles autorégressifs dotés d'un modèle de discussion ;
Envoyer un modèle, l'état à évaluer et des questions indexées par nom :
curl http://localhost:8000/v1/systemone \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-1.5B-Instruct",
"state": "Our integration has been failing for 3 days and we are losing sales!",
"questions": {
"team": {
"type": "choice",
"instructions": "Which team handles this?",
"criteria": {"billing": null, "technical": "Bugs or integration problems"}
},
"urgency": {
"type": "score",
"instructions": "How urgent is this ticket?",
"criteria": ["low", "medium", "high"]
},
"upset": {"type": "noul", "instructions": "Is the customer upset?"}
}
}'Installez le TypeSafe SDK pour Node.js 20 ou plus récent :
npm install @typesafe-ai/sdk
Définissez baseURL sur la racine du serveur ; le SDK ajoute /v1/systemone. Le SDK requiert une clé API, mais un espace réservé fonctionne avec le serveur local.
import { choice, noul, score, TypeSafeClient } from "@typesafe-ai/sdk";
const client = new TypeSafeClient({
baseURL: "http://localhost:8000",
apiKey: "<random_string>",
});
const response = await client.systemOne({
model: "Qwen/Qwen2.5-1.5B-Instruct",
state: "Our integration has been failing for 3 days and we are losing sales!",
questions: {
team: choice("Which team handles this?", {
billing: null,
technical: "Bugs or integration problems",
}),
urgency: score("How urgent is this ticket?", ["low", "medium", "high"]),
upset: noul("Is the customer upset?"),
},
});
console.log(response.answers.team.choice);
console.log(response.answers.urgency.score);
console.log(response.answers.upset.noul);Le client affiche l'équipe sélectionnée, le score d'urgence et la probabilité que le client soit mécontent. Par exemple :
technical 1.6739138662815094 0.851952850818634
Les réponses utilisent les mêmes noms de questions. Par exemple :
{
"model": "Qwen/Qwen2.5-1.5B-Instruct",
"answers": {
"team": {"type": "choice", "choice": "technical", "probabilities": {"billing": 0.000006962256520637311, "technical": 0.999993085861206}, "confidence": 0.9999861717224121},
"urgency": {"type": "score", "score": 1.6739138662815094, "legend": {"0": "low", "1": "medium", "2": "high"}, "probabilities": {"0": 0.0031353600788861513, "1": 0.31981542706489563, "2": 0.6770492196083069}, "confidence": 0.5108707791659981},
"upset": {"type": "noul", "noul": 0.851952850818634}
},
"usage": {"input_tokens": 213, "output_tokens": 0}
}| Type de question | criteria | Réponse |
|---|---|---|
choice | Noms des options mappés sur des descriptions, qui peuvent être null. | L'option la plus probable, les probabilités des options et la confiance. |
score | Descriptions des niveaux, classées du plus bas au plus élevé. | L'indice de niveau pondéré par la probabilité, les probabilités, une légende et la confiance. |
noul | Descriptions facultatives pour true et false. | La probabilité de true. |
state, des instructions facultatives, et les descriptions peuvent contenir du texte ou des objets et tableaux JSON. Chaque requête accepte jusqu'à 64 questions, avec 1 à 26 choix ou niveaux de score par question.
For vision-capable models, add an images array with up to four data:image/...;base64,... URLs. Every question receives the same images. The model’s processor and chat template must support images; remote image URLs are not accepted.
Configuration de la décision
Les modèles de décision ne partagent pas encore de standard pour le stockage des prompts, des étiquettes de réponse et des paramètres de calibration. Ces éléments varient d'une implémentation de modèle à l'autre, c'est pourquoi --decision-config vous permet de les fournir explicitement. Les modèles dotés de têtes de décision personnalisées nécessitent toujours une implémentation compatible ; ce fichier ne configure que le formatage des prompts et le score du jeton suivant.
Par défaut, les questions utilisent un prompt de secours et le modèle de chat du modèle avec la réflexion désactivée. Les étiquettes de réponse sont A–Z pour les choix et les scores, et Yes/No pour les booléens. Les probabilités sont le softmax sur ces étiquettes à une température de 1.
Passer --decision-config pour remplacer ces valeurs par défaut pour un modèle :
transformers serve openjev/openjev --decision-config decision.json
Le fichier JSON prend en charge trois champs facultatifs :
| Champ | Signification |
|---|---|
labels | Étiquettes de réponse par type de question, dans l'ordre des options (true, puis false pour noul). Chacune doit être un jeton unique et connu. |
temperature | Températures positives par type de question, appliquées sous la forme softmax(label_logits / temperature). |
chat_template | Un modèle Jinja en ligne qui remplace le prompt complet, y compris le formatage de la conversation et le préfixe de l'assistant. |
Par exemple, pour modifier les étiquettes et l'étalonnage tout en conservant le prompt par défaut :
{
"labels": {"noul": ["A", "B"]},
"temperature": {"choice": 0.85, "score": 0.85, "noul": 1.5547129}
}Un modèle personnalisé reçoit les messages habituels, ainsi que les champs bruts state, images et question. Le champ question expose name, type, instructions, options, labels, descriptions et legend ; options, labels et descriptions partagent le même ordre. Utilisez ces champs pour remplacer la formulation par défaut, et tojson pour afficher les valeurs structurées. Les modèles destinés aux entrées d’image doivent inclure les espaces réservés d’image du modèle.
Le fichier est chargé au démarrage et ne s’applique qu’à /v1/systemone. Les paramètres omis conservent leurs valeurs par défaut ; aucune configuration de décision n’est lue automatiquement depuis le point de contrôle.
v1/audio/transcriptions
Le point de terminaison v1/audio/transcriptions transcrit l’audio à l’aide de modèles de conversion de la parole en texte. Il suit le format de l’API de transcription audio.
curl -X POST http://localhost:8000/v1/audio/transcriptions \ -H "Content-Type: multipart/form-data" \ -F "file=@/path/to/audio.wav" \ -F "model=openai/whisper-large-v3"
La commande renvoie la réponse suivante.
{
"text": "Transcribed text from the audio file",
}v1/models
L'endpoint v1/models analyse votre cache local Hugging Face et renvoie une liste des modèles téléchargés au format compatible OpenAI. Les outils tiers utilisent cet endpoint pour découvrir les modèles disponibles.
Téléchargez un modèle avant d’exécuter transformers serve.
transformers download Qwen/Qwen2.5-0.5B-Instruct
Une fois téléchargé, le modèle apparaît dans les réponses de /v1/models.
curl http://localhost:8000/v1/models
L'endpoint renvoie un objet JSON contenant les modèles disponibles.
Chargement des modèles
Le point de terminaison /load_model précharge un modèle et transmet la progression via Server-Sent Events (SSE). L'interface en ligne de commande transformers chat l'utilise automatiquement afin que les utilisateurs voient la progression du téléchargement et du chargement plutôt qu'un inviteur qui reste bloqué. Utilisez-le pour préchauffer un modèle avant d'envoyer des requêtes d'inférence.
Demande
curl -N -X POST http://localhost:8000/load_model \
-H "Content-Type: application/json" \
-d '{"model": "Qwen/Qwen2.5-0.5B-Instruct"}'Le champ model est un identifiant de modèle Hugging Face, facultativement suivi d'un suffixe @revision (Qwen/Qwen2.5-0.5B-Instruct@main). Si la révision est omise, la valeur par défaut est main.
Réponse
La réponse est un flux SSE (Content-Type: text/event-stream). Chaque trame est un objet JSON sur une ligne data:.
data: {"status": "loading", "model": "Qwen/Qwen2.5-0.5B-Instruct@main", "stage": "processor"}Chaque événement contient au minimum un champ status et un champ model. Les champs supplémentaires dépendent du statut.
| Champ | Présent lorsque | Description |
|---|---|---|
status | Toujours | loading, ready ou error |
model | Toujours | Identifiant de modèle canonique model_id@revision |
stage | status == "loading" | L'un des éléments suivants : processor, config, download, weights (voir les étapes ci-dessous) |
progress | étapes download et weights | Objet avec current et total (entier ou null) |
cached | status == "ready" | true si le modèle était déjà en mémoire |
message | status == "error" | Description de l'erreur |
Stages
Le chargement progresse à travers ces étapes dans l'ordre. Certaines peuvent être ignorées (download est ignoré lorsque les fichiers sont déjà en cache localement).
| Stage | Des progrès ? | Description |
|---|---|---|
processor | Non | Chargement du tokenizer/processor |
config | Non | Chargement de la configuration du modèle |
download | Oui (octets) | Téléchargement des fichiers de modèle |
weights | Oui (éléments) | Chargement des tenseurs de poids en mémoire |
Le flux se termine par exactement un événement terminal, ready (succès) ou error (échec).
Délai d'attente
transformers serve gère les requêtes pour n’importe quel modèle. Chaque modèle est chargé à la demande et reste en mémoire GPU. Les modèles sont déchargés automatiquement après 300 secondes d’inactivité afin de libérer la mémoire GPU. Définissez --model-timeout sur une autre valeur en secondes, ou sur -1 pour désactiver le déchargement.
transformers serve --model-timeout 400
Chargement des exemples
Les exemples ci-dessous montrent les réponses pour un modèle fraîchement téléchargé, un modèle chargé depuis votre cache local (qui saute l'étape de téléchargement) et un modèle déjà en mémoire.
data: {"status": "loading", "model": "org/model@main", "stage": "processor"}
data: {"status": "loading", "model": "org/model@main", "stage": "config"}
data: {"status": "loading", "model": "org/model@main", "stage": "download", "progress": {"current": 0, "total": 269100000}}
data: {"status": "loading", "model": "org/model@main", "stage": "download", "progress": {"current": 134600000, "total": 269100000}}
data: {"status": "loading", "model": "org/model@main", "stage": "download", "progress": {"current": 269100000, "total": 269100000}}
data: {"status": "loading", "model": "org/model@main", "stage": "weights", "progress": {"current": 1, "total": 272}}
data: {"status": "loading", "model": "org/model@main", "stage": "weights", "progress": {"current": 272, "total": 272}}
data: {"status": "ready", "model": "org/model@main", "cached": false}data: {"status": "loading", "model": "org/model@main", "stage": "processor"}
data: {"status": "loading", "model": "org/model@main", "stage": "config"}
data: {"status": "loading", "model": "org/model@main", "stage": "weights", "progress": {"current": 1, "total": 272}}
data: {"status": "loading", "model": "org/model@main", "stage": "weights", "progress": {"current": 272, "total": 272}}
data: {"status": "ready", "model": "org/model@main", "cached": false}data: {"status": "ready", "model": "org/model@main", "cached": true}Appel d'outils
Le serveur transformers serve prend en charge l'appel de fonctions au format OpenAI. Les modèles entraînés pour l'utilisation d'outils génèrent des appels de fonctions structurés que votre application exécute.
L'appel d'outils fonctionne avec tout modèle dont le tokenizer déclare des jetons d'appel d'outils. Qwen et Gemma 4 fonctionnent sans configuration supplémentaire. Ouvrez un issue pour demander la prise en charge d'un modèle spécifique.
Définissez les outils sous forme de liste de spécifications de fonctions suivant le format OpenAI.
import json
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<KEY>")
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather in a location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city name, e.g. San Francisco"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "temperature unit"
}
},
"required": ["location"]
}
}
}
]Personnalisez la génération en passant les paramètres de GenerationConfig à l'argument extra_body dans create.
generation_config = {
"max_new_tokens": 512,
"temperature": 0.7,
"top_p": 0.9,
"top_k": 50,
"do_sample": True,
"repetition_penalty": 1.1,
"no_repeat_ngram_size": 3,
}
response = client.responses.create(
model="Qwen/Qwen2.5-7B-Instruct",
instructions="You are a helpful weather assistant. Use the get_weather tool to answer questions.",
input="What's the weather like in San Francisco?",
tools=tools,
stream=True,
extra_body={"generation_config": json.dumps(generation_config)}
)
for event in response:
print(event)Appel d'outils multi-tours
Une fois que le modèle renvoie un appel d’outil, exécutez la fonction localement, puis renvoyez le résultat dans une requête de suivi pour obtenir la réponse finale du modèle. Le schéma varie légèrement d’une API à l’autre. Consultez le guide d’appel de fonctions OpenAI pour la spécification complète.
Les exemples ci-dessous réutilisent la liste tools définie ci-dessus.
Transmettez le résultat de l'outil en tant que message role: "tool" avec l'tool_call_id correspondant.
# Model returns a tool call
messages = [{"role": "user", "content": "What's the weather like in San Francisco?"}]
response = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct",
messages=messages,
tools=tools,
)
assistant_message = response.choices[0].message
# Execute the tool locally
tool_call = assistant_message.tool_calls[0]
result = {"temperature": 22, "condition": "sunny"} # your actual function call here
# Send the tool result back
messages.append(assistant_message)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result),
})
final_response = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct",
messages=messages,
tools=tools,
)
print(final_response.choices[0].message.content)Transmettez le résultat de l'outil en tant qu'élément function_call_output dans la liste input de la requête suivante.
user_message = {"role": "user", "content": "What's the weather like in San Francisco?"}
response = client.responses.create(
model="Qwen/Qwen2.5-7B-Instruct",
input=[user_message],
tools=tools,
stream=False,
)
tool_call = next(item for item in response.output if item.type == "function_call")
result = {"temperature": 22, "condition": "sunny"}
final_response = client.responses.create(
model="Qwen/Qwen2.5-7B-Instruct",
input=[
user_message,
tool_call.model_dump(exclude_none=True),
{"type": "function_call_output", "call_id": tool_call.call_id, "output": json.dumps(result)},
],
tools=tools,
stream=False,
)
print(final_response.output_text)Raisonnement
Les modèles de raisonnement émettent une chaîne de pensée cachée avant la réponse finale. Le serveur détecte ces segments de réflexion, supprime les délimiteurs de la réponse visible et expose le texte de raisonnement dans un champ dédié afin que les clients puissent l’afficher séparément.
- Chat Completions renvoie le raisonnement sous la forme de
reasoning_contentsur le message de l'assistant. - L’API Responses renvoie le raisonnement sous forme d’un élément de sortie
reasoningqui précède l’élémentmessage.
La détection du raisonnement repose sur un modèle de réponse, qui indique au serveur où commence et où se termine un segment de réflexion. Le serveur recherche ce modèle dans deux endroits, dans l'ordre.
- L'attribut
response_templatedu tokenizer, si le modèle en fournit un. - Un repli intégré, sélectionné en fonction de l’architecture du modèle, pour les tokenizers qui ne fournissent pas encore de modèle.
Les modèles qui ne disposent d’aucun des deux sont servis sans analyse de la réponse. Le texte brut décodé est renvoyé en tant que content et aucun champ de raisonnement n’est exposé, même si le modèle émet des balises <think>...</think>.
Activer le raisonnement sur le serveur
Utilisez --reasoning pour contrôler si le modèle de conversation émet des jetons de raisonnement.
| Valeur | Comportement |
|---|---|
auto (par défaut) | Se fier à la valeur par défaut du modèle de chat. |
on | Activez la réflexion en définissant enable_thinking=True dans les arguments du modèle de discussion. |
off | Désactivez la réflexion en définissant enable_thinking=False. |
transformers serve Qwen/Qwen3-1.7B --reasoning on
Tous les modèles ne prennent pas en charge le raisonnement.
--reasoningne fonctionne que lorsque le modèle de chat du modèle gère la variableenable_thinking(ou lorsque son tokenizer déclare des délimiteurs de réflexion). Pour les autres modèles, l’indicateur est ignoré silencieusement.
--reasoning on et --reasoning off fonctionnent en définissant la variable de gabarit de discussion enable_thinking. Certains gabarits de discussion utilisent un nom de variable différent pour activer la réflexion, ou acceptent des variables supplémentaires qui modifient la façon dont le prompt est rendu. Transmettez toute variable de gabarit de discussion directement avec --chat-template-kwargs sous forme d'objet JSON.
transformers serve Qwen/Qwen3-1.7B \
--chat-template-kwargs '{"enable_thinking": true}'Les clients peuvent également envoyer chat_template_kwargs dans le corps de la requête pour remplacer les valeurs par défaut du serveur pour une seule requête, sans redémarrer le serveur.
Chat Completions
Les réponses non en streaming incluent reasoning_content en plus de content sur le message de l'assistant.
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="<KEY>")
completion = client.chat.completions.create(
model="Qwen/Qwen3-1.7B",
messages=[{"role": "user", "content": "What is 17 * 23?"}],
)
message = completion.choices[0].message
print("reasoning:", message.reasoning_content)
print("answer:", message.content)Le streaming émet des deltas reasoning_content avant les deltas content. Concaténez chaque champ séparément.
chunks = list(
client.chat.completions.create(
model="Qwen/Qwen3-1.7B",
messages=[{"role": "user", "content": "What is 17 * 23?"}],
stream=True,
)
)
reasoning = "".join(getattr(c.choices[0].delta, "reasoning_content", None) or "" for c in chunks)
content = "".join(c.choices[0].delta.content or "" for c in chunks)curl -X POST http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen3-1.7B",
"messages": [{"role": "user", "content": "What is 17 * 23?"}],
"chat_template_kwargs": {"enable_thinking": true}
}'La réponse inclut reasoning_content dans le message de l'assistant.
{
"choices": [
{
"message": {
"role": "assistant",
"content": "17 * 23 = 391.",
"reasoning_content": "Let me compute 17 * 23. 17 * 20 = 340, 17 * 3 = 51, so 340 + 51 = 391."
},
"finish_reason": "stop",
"index": 0
}
]
}API des réponses
L’API Responses renvoie le raisonnement en tant qu’élément de sortie reasoning distinct, qui précède l’élément message.
response = client.responses.create(
model="Qwen/Qwen3-1.7B",
input="What is 17 * 23?",
stream=False,
)
reasoning_item = next(i for i in response.output if i.type == "reasoning")
message_item = next(i for i in response.output if i.type == "message")
print("reasoning:", reasoning_item.content[0].text)
print("answer:", message_item.content[0].text)Streaming ouvre d'abord l'élément de raisonnement et émet des événements response.reasoning_text.delta, puis le ferme et ouvre l'élément de message pour émettre des événements response.output_text.delta.
stream = client.responses.create(
model="Qwen/Qwen3-1.7B",
input="What is 17 * 23?",
stream=True,
)
for event in stream:
if event.type == "response.reasoning_text.delta":
print(event.delta, end="")
elif event.type == "response.output_text.delta":
print(event.delta, end="")Aller-retour multi-tours
Pour les conversations multi-tours, incluez le texte de raisonnement de la réponse précédente dans la requête suivante. Le serveur le transmet au modèle de chat, qui peut l’afficher comme faisant partie du tour précédent de l’assistant, afin que le modèle voie son propre processus de réflexion antérieur.
Joindre reasoning_content au message assistant précédent.
first = client.chat.completions.create(
model="Qwen/Qwen3-1.7B",
messages=[{"role": "user", "content": "What is 17 * 23?"}],
).choices[0].message
second = client.chat.completions.create(
model="Qwen/Qwen3-1.7B",
messages=[
{"role": "user", "content": "What is 17 * 23?"},
{
"role": "assistant",
"content": first.content,
"reasoning_content": first.reasoning_content,
},
{"role": "user", "content": "Now multiply that result by 2."},
],
)
print(second.choices[0].message.content)Transmettez l'élément reasoning précédent en tant qu'élément d'entrée avant le message de l'assistant.
first = client.responses.create(
model="Qwen/Qwen3-1.7B",
input="What is 17 * 23?",
stream=False,
)
reasoning_item = next(i for i in first.output if i.type == "reasoning")
message_item = next(i for i in first.output if i.type == "message")
second = client.responses.create(
model="Qwen/Qwen3-1.7B",
input=[
{"role": "user", "content": "What is 17 * 23?"},
reasoning_item.model_dump(exclude_none=True),
{"role": "assistant", "content": message_item.content[0].text},
{"role": "user", "content": "Now multiply that result by 2."},
],
stream=False,
)
print(second.output_text)Redirection de port
Le transfert de port vous permet de servir des modèles depuis un serveur distant. Assurez-vous d'avoir un accès SSH au serveur, puis exécutez cette commande sur votre machine locale.
ssh -N -f -L 8000:localhost:8000 your_server_account@your_server_IP -p port_to_ssh_into_your_server
Reproductibilité
Transmettez un modèle en tant qu'argument positionnel afin d'éviter les indices de modèle par requête et de produire des exécutions stables et reproductibles.
transformers serve Qwen/Qwen2.5-0.5B-Instruct \
--continuous-batching \
--dtype "bfloat16"