[Frontend] Implement Batched Chat Completions (#5317)

Signed-off-by: Alex Brooks <albrooks@redhat.com>
This commit is contained in:
Alex Brooks authored and GitHub committed 2026-08-07 16:12:09 -06:00
1 parent 18bf7e0ff9
commit b15d4e6a64
7 files changed
+531 -39

No files matched your search

@@ -136,3 +136,36 @@ def test_flux_2_dev(
}
openai_client.send_diffusion_request(request_config)
@pytest.mark.parametrize(
"omni_server",
_get_flux_2_dev_feature_cases(MODEL),
indirect=True,
)
def test_flux_2_dev_batched_chat_completions(
omni_server: OmniServer,
openai_client: OpenAIClientHandler,
):
"""Validate batched chat completions for diffusion models."""
messages = [
[{"role": "user", "content": PROMPT}],
[{"role": "user", "content": "A sunset over the ocean."}],
]
responses = openai_client.send_batched_chat_completions_http_request(
{
"json": {
"model": omni_server.model,
"messages": messages,
"num_inference_steps": 2,
"height": 512,
"width": 512,
"seed": 42,
},
},
)
assert responses and len(responses) == 1
resp = responses[0]
assert resp.success
choices = resp.json_body["choices"]
assert len(choices) == len(messages)
@@ -250,3 +250,101 @@ def test_completions_rejected_for_thinker_talker(omni_server, openai_client) ->
err_code=400,
)
assert not responses[0].success
@pytest.mark.advanced_model
@pytest.mark.core_model
@pytest.mark.omni
@hardware_test(res={"cuda": "H100", "rocm": "MI325"}, num_cards=2)
@pytest.mark.parametrize("omni_server", test_params, indirect=True)
def test_batched_completions_text(omni_server, openai_client) -> None:
"""Ensure that we can make a batch chat completions request (text only)."""
responses = openai_client.send_batched_chat_completions_http_request(
{
"json": {
"model": omni_server.model,
"messages": [
[{"role": "user", "content": "What color is the sky? Answer in one word."}],
[{"role": "user", "content": "What is 2+2? Answer in one word."}],
],
"modalities": ["text"],
"max_tokens": 20,
},
},
)
assert responses
resp = responses[0]
assert resp.success
body = resp.json_body
choices = body["choices"]
assert len(choices) == 2
for choice in choices:
assert choice["message"]["content"]
@pytest.mark.advanced_model
@pytest.mark.core_model
@pytest.mark.omni
@hardware_test(res={"cuda": "H100", "rocm": "MI325"}, num_cards=2)
@pytest.mark.parametrize("omni_server", test_params, indirect=True)
def test_batched_completions_audio_out(omni_server, openai_client) -> None:
"""Ensure that we can make a batch chat completions request (audio + text)."""
messages = [
[{"role": "user", "content": "Say hello."}],
[{"role": "user", "content": "Say goodbye."}],
]
num_messages = len(messages)
responses = openai_client.send_batched_chat_completions_http_request(
{
"json": {
"model": omni_server.model,
"messages": messages,
"modalities": ["text", "audio"],
"max_tokens": 200,
},
},
)
assert responses and len(responses) == 1
resp = responses[0]
assert resp.success
choices = resp.json_body["choices"]
assert len(choices) == num_messages
# Every message in the batch should contain both the audio and text content
for choice in choices:
assert choice["message"]["audio"]["data"]
assert choice["message"]["content"]
@pytest.mark.advanced_model
@pytest.mark.core_model
@pytest.mark.omni
@hardware_test(res={"cuda": "H100", "rocm": "MI325"}, num_cards=2)
@pytest.mark.parametrize("omni_server", test_params, indirect=True)
@pytest.mark.parametrize(
"sad_opts",
[
{"stream": "not-a-bool"}, # Fails validation
{"n": 2}, # vLLM Batched endpoints doesn't support n > 1
],
)
def test_batched_completions_with_bad_values(omni_server, openai_client, sad_opts) -> None:
"""Ensure that a bad values are correctly handled as 400s."""
messages = [
[{"role": "user", "content": "Say hello."}],
[{"role": "user", "content": "Say goodbye."}],
]
responses = openai_client.send_batched_chat_completions_http_request(
{
"json": {
"model": omni_server.model,
"messages": messages,
**sad_opts,
},
},
)
assert responses and len(responses) == 1
resp = responses[0]
assert not responses[0].success
assert resp.status_code == 400