Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions docs/serving/audio_generate_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Content-Type: application/json
|-----------|------|---------|-------------|
| `input` | string | **required** | Text prompt describing the audio to generate |
| `model` | string | server's model | Model to use (optional, should match server if specified) |
| `response_format` | string | "wav" | Audio format: wav, mp3, flac, pcm, aac, opus |
| `response_format` | string | "wav" | Audio format: wav, mp3, flac, pcm, opus |
| `speed` | float | 1.0 | Playback speed (0.25 - 4.0) |

#### Diffusion Parameters
Expand All @@ -90,7 +90,6 @@ Returns binary audio data with the appropriate `Content-Type` header:
| `mp3` | `audio/mpeg` |
| `flac` | `audio/flac` |
| `pcm` | `audio/pcm` |
| `aac` | `audio/aac` |
| `opus` | `audio/opus` |

## Examples
Expand Down Expand Up @@ -285,7 +284,7 @@ Pydantic validation failure (e.g. invalid `response_format`, `speed` out of rang
"detail": [
{
"type": "literal_error",
"msg": "Input should be 'wav', 'pcm', 'flac', 'mp3', 'aac' or 'opus'",
"msg": "Input should be 'wav', 'pcm', 'flac', 'mp3' or 'opus'",
...
}
]
Expand Down
2 changes: 1 addition & 1 deletion docs/serving/speech_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ Content-Type: application/json
| `input` | string | **required** | The text to synthesize into speech |
| `model` | string | server's model | Model to use (optional, should match server if specified) |
| `voice` | string | "vivian" | Speaker name (e.g., vivian, ryan, aiden) |
| `response_format` | string | "wav" | Audio format: wav, mp3, flac, pcm, aac, opus |
| `response_format` | string | "wav" | Audio format: wav, mp3, flac, pcm, opus |
| `speed` | float | 1.0 | Playback speed (0.25-4.0) |

#### vLLM-Omni Extension Parameters
Expand Down
2 changes: 1 addition & 1 deletion docs/user_guide/examples/online_serving/text_to_audio.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ Content-Type: application/json
|-----------|------|---------|-------------|
| `input` | string | **required** | Text prompt describing the audio to generate |
| `model` | string | server's model | Model to use (optional, should match server if specified) |
| `response_format` | string | "wav" | Audio format: wav, mp3, flac, pcm, aac, opus |
| `response_format` | string | "wav" | Audio format: wav, mp3, flac, pcm, opus |
| `speed` | float | 1.0 | Playback speed (0.25 - 4.0) |
| `audio_length` | float | null | Audio duration in seconds (max ~47s for `stable-audio-open-1.0`) |
| `audio_start` | float | 0.0 | Audio start time in seconds |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@

pytestmark = [pytest.mark.slow, pytest.mark.diffusion]

# https://github.com/vllm-project/vllm-omni/issues/3649 — invalid inputs still HTTP 200 / timeout / missing validation.
_SKIP_ISSUE_3649 = pytest.mark.skip(reason="https://github.com/vllm-project/vllm-omni/issues/3649")

_PARAMS = [
pytest.param(
OmniServerParams(
Expand All @@ -34,10 +31,8 @@
@pytest.mark.parametrize(
"overrides, err_message",
[
pytest.param({"input": ""}, ("cannot be empty", "input"), id="input_empty", marks=_SKIP_ISSUE_3649),
pytest.param(
{"input": " "}, ("cannot be empty", "input"), id="input_whitespace_only", marks=_SKIP_ISSUE_3649
),
pytest.param({"input": ""}, ("cannot be empty", "input"), id="input_empty"),
pytest.param({"input": " "}, ("cannot be empty", "input"), id="input_whitespace_only"),
pytest.param({"input": 123}, ("input", "a valid string"), id="input_wrong_type"),
pytest.param(
{"response_format": "mpeg"},
Expand All @@ -52,10 +47,8 @@
("sse", "stream_format", "value_error", "not a supported stream_format"),
id="stream_format_sse_blocked",
),
pytest.param(
{"audio_length": -1.0}, ("audio_end_in_s", "higher than", "audio_start_in_s"), id="audio_length_negative"
),
pytest.param({"audio_length": 0}, "audio_length", id="audio_length_zero", marks=_SKIP_ISSUE_3649),
pytest.param({"audio_length": -1.0}, ("audio_length", "greater_than", "0"), id="audio_length_negative"),
pytest.param({"audio_length": 0}, ("audio_length", "greater_than", "0"), id="audio_length_zero"),
# ``OmniOpenAIServingAudioGenerate`` only forwards ``audio_start`` when ``audio_length`` is set.
pytest.param(
{"audio_start": -0.5, "audio_length": 5.0},
Expand All @@ -65,22 +58,27 @@
pytest.param(
{"negative_prompt": ["noise"]}, ("negative_prompt", "a valid string"), id="negative_prompt_wrong_type"
),
pytest.param({"guidance_scale": -1.0}, "guidance_scale", id="guidance_scale_negative", marks=_SKIP_ISSUE_3649),
pytest.param({"guidance_scale": 0}, "guidance_scale", id="guidance_scale_zero", marks=_SKIP_ISSUE_3649),
pytest.param({"guidance_scale": -1.0}, ("guidance_scale", "greater_than", "0"), id="guidance_scale_negative"),
pytest.param({"guidance_scale": 0}, ("guidance_scale", "greater_than", "0"), id="guidance_scale_zero"),
pytest.param(
{"num_inference_steps": 0}, "num_inference_steps", id="num_inference_steps_zero", marks=_SKIP_ISSUE_3649
{"num_inference_steps": 0},
("num_inference_steps", "greater_than_equal", "1"),
id="num_inference_steps_zero",
),
pytest.param(
{"num_inference_steps": -1}, ("number of steps", "non-negative"), id="num_inference_steps_negative"
{"num_inference_steps": -1},
("num_inference_steps", "greater_than_equal", "1"),
id="num_inference_steps_negative",
),
pytest.param(
{"num_inference_steps": 6000},
"num_inference_steps",
("num_inference_steps", "less_than_equal", "1000"),
id="num_inference_steps_above_max",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
{"guidance_scale": 1001.0}, "guidance_scale", id="guidance_scale_above_max", marks=_SKIP_ISSUE_3649
{"guidance_scale": 1001.0},
("guidance_scale", "less_than_equal", "1000"),
id="guidance_scale_above_max",
),
pytest.param(
{"audio_length": 86401.0}, ("Requested audio length", "exceeds maximum"), id="audio_length_above_max"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,9 @@
# as "unset". Strip clone fields from the batch envelope before asserting CustomVoice preset errors.
_SPEECH_BATCH_NO_CLONE_FIELDS = "__speech_batch_no_clone_fields__"

_SKIP_ISSUE_3649 = pytest.mark.skip(reason="https://github.com/vllm-project/vllm-omni/issues/3649")


pytestmark = [pytest.mark.slow, pytest.mark.tts]

_SKIP_ISSUE_3649 = pytest.mark.skip(reason="https://github.com/vllm-project/vllm-omni/issues/3649")
_L4_SPEECH_HW = hardware_marks(res={"cuda": "L4"})
_SPEECH_SERVER_ARGS = ["--trust-remote-code", "--disable-log-stats"]

Expand Down Expand Up @@ -114,7 +112,7 @@ def test_speech_missing_required_fields(omni_server: OmniServer, openai_client:
[
pytest.param({"input": ""}, ("input", "empty"), id="input_empty"),
pytest.param({"input": " "}, ("input", "empty"), id="input_whitespace_only"),
pytest.param({"voice": ""}, "Invalid voice", id="voice_empty", marks=_SKIP_ISSUE_3649),
pytest.param({"voice": ""}, "Invalid voice", id="voice_empty"),
pytest.param(
{"instructions": 123}, ("instructions", "string_type", "valid string"), id="instructions_wrong_type"
),
Expand Down Expand Up @@ -273,16 +271,15 @@ def test_speech_batch_missing_items(omni_server: OmniServer, openai_client: Open
@pytest.mark.parametrize(
"loc, overrides, err_message",
[
pytest.param("item", {"input": ""}, ("input", "empty"), id="item_input_empty", marks=_SKIP_ISSUE_3649),
pytest.param("item", {"input": ""}, ("input", "empty"), id="item_input_empty"),
pytest.param(
"item",
{"input": " "},
("input", "empty"),
id="item_input_whitespace_only",
marks=_SKIP_ISSUE_3649,
),
pytest.param("batch", {"voice": ""}, "Invalid voice", id="batch_voice_empty", marks=_SKIP_ISSUE_3649),
pytest.param("item", {"voice": ""}, "Invalid voice", id="item_voice_empty", marks=_SKIP_ISSUE_3649),
pytest.param("batch", {"voice": ""}, "Invalid voice", id="batch_voice_empty"),
pytest.param("item", {"voice": ""}, "Invalid voice", id="item_voice_empty"),
pytest.param(
"batch",
{
Expand All @@ -293,7 +290,6 @@ def test_speech_batch_missing_items(omni_server: OmniServer, openai_client: Open
},
"Invalid voice",
id="batch_voice_unknown_preset",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"item",
Expand All @@ -304,7 +300,6 @@ def test_speech_batch_missing_items(omni_server: OmniServer, openai_client: Open
},
"Invalid voice",
id="item_voice_unknown_preset",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"batch",
Expand All @@ -323,14 +318,12 @@ def test_speech_batch_missing_items(omni_server: OmniServer, openai_client: Open
{"instructions": "x" * (_SPEECH_API_MAX_INSTRUCTIONS_CHARS + 1)},
("instructions", "too long"),
id="batch_instructions_exceed_api_limit",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"item",
{"instructions": "x" * (_SPEECH_API_MAX_INSTRUCTIONS_CHARS + 1)},
("instructions", "too long"),
id="item_instructions_exceed_api_limit",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"batch",
Expand Down Expand Up @@ -363,42 +356,36 @@ def test_speech_batch_missing_items(omni_server: OmniServer, openai_client: Open
{"language": ""},
("language", "invalid language", "chinese"),
id="batch_language_empty",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"item",
{"language": ""},
("language", "invalid language", "chinese"),
id="item_language_empty",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"batch",
{"ref_audio": "ftp://example.com/a.wav"},
("ref_audio", "URL"),
id="batch_ref_audio_bad_scheme",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"item",
{"ref_audio": "ftp://example.com/a.wav"},
("ref_audio", "URL"),
id="item_ref_audio_bad_scheme",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"batch",
{"ref_audio": "not_a_valid_uri"},
("ref_audio", "url"),
id="batch_ref_audio_invalid_uri",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"item",
{"ref_audio": "not_a_valid_uri"},
("ref_audio", "url"),
id="item_ref_audio_invalid_uri",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"batch",
Expand Down Expand Up @@ -429,28 +416,24 @@ def test_speech_batch_missing_items(omni_server: OmniServer, openai_client: Open
{"max_new_tokens": 0},
("max_new_tokens", "least 1"),
id="batch_max_new_tokens_below_min",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"item",
{"max_new_tokens": 0},
("max_new_tokens", "least 1"),
id="item_max_new_tokens_below_min",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"batch",
{"max_new_tokens": _SPEECH_API_MAX_NEW_TOKENS + 1},
("max_new_tokens", "exceed 4096"),
id="batch_max_new_tokens_above_max",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"item",
{"max_new_tokens": _SPEECH_API_MAX_NEW_TOKENS + 1},
("max_new_tokens", "exceed 4096"),
id="item_max_new_tokens_above_max",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"batch",
Expand All @@ -474,7 +457,6 @@ def test_speech_batch_missing_items(omni_server: OmniServer, openai_client: Open
},
("ref_text", "base task", "non-empty"),
id="batch_ref_text_whitespace_only_base_clone",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"item",
Expand All @@ -485,7 +467,6 @@ def test_speech_batch_missing_items(omni_server: OmniServer, openai_client: Open
},
("ref_text", "base task", "non-empty"),
id="item_ref_text_whitespace_only_base_clone",
marks=_SKIP_ISSUE_3649,
),
],
)
Expand Down Expand Up @@ -649,21 +630,18 @@ def _voices_upload_multipart_files(kind: str | None) -> dict[str, Any] | None:
{"consent": " ", "name": "v_ws_consent_{uuid}"},
"consent",
id="whitespace_consent",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"wav_ok",
{"consent": "bad/consent", "name": "v_bad_cons_{uuid}"},
"consent",
id="consent_path_sep",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"wav_ok",
{"consent": _VF_LONG_CONSENT, "name": "v_long_cons_{uuid}"},
("consent", "too long", "Failed to save"),
id="consent_too_long",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"wav_ok",
Expand All @@ -683,7 +661,6 @@ def _voices_upload_multipart_files(kind: str | None) -> dict[str, Any] | None:
{"consent": "consent_ok", "name": "v_long_ref_{uuid}", "ref_text": _VF_LONG_REF_TEXT},
"ref_text",
id="ref_text_too_long",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"wav_ok",
Expand All @@ -694,7 +671,6 @@ def _voices_upload_multipart_files(kind: str | None) -> dict[str, Any] | None:
},
"speaker_description",
id="speaker_description_too_long",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"wav_pdf_type",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@

pytestmark = [pytest.mark.slow, pytest.mark.diffusion]

_SKIP_ISSUE_3649 = pytest.mark.skip(reason="https://github.com/vllm-project/vllm-omni/issues/3649")

_PARAMS = [
pytest.param(
OmniServerParams(model="Qwen/Qwen-Image"),
Expand Down Expand Up @@ -45,8 +43,8 @@ def _minimal_images_gen_json(omni_server: OmniServer) -> dict[str, object]:
("model", "mismatch"),
id="model_mismatch",
),
pytest.param({"prompt": ""}, ("prompt", "empty"), id="prompt_empty", marks=_SKIP_ISSUE_3649),
pytest.param({"prompt": " "}, ("prompt", "empty"), id="prompt_whitespace_only", marks=_SKIP_ISSUE_3649),
pytest.param({"prompt": ""}, ("prompt", "empty"), id="prompt_empty"),
pytest.param({"prompt": " "}, ("prompt", "empty"), id="prompt_whitespace_only"),
pytest.param({"prompt": 123}, ("prompt", "string_type", "valid string"), id="prompt_wrong_type"),
pytest.param({"n": 0}, ("n", "greater_than_equal", "1"), id="n_below_min"),
pytest.param({"n": 11}, ("n", "less_than_equal", "10"), id="n_above_max"),
Expand Down Expand Up @@ -89,18 +87,16 @@ def _minimal_images_gen_json(omni_server: OmniServer) -> dict[str, object]:
),
pytest.param({"layers": 2}, ("layers", "value_error", "3", "10"), id="layers_below_min"),
pytest.param({"layers": 11}, ("layers", "value_error", "3", "10"), id="layers_above_max"),
pytest.param({"seed": -1}, ("seed", "greater_than_equal", "0"), id="seed_negative", marks=_SKIP_ISSUE_3649),
pytest.param({"seed": -1}, ("seed", "greater_than_equal", "0"), id="seed_negative"),
pytest.param(
{"seed": 2**32},
("seed", "less_than_equal", "4294967295"),
id="seed_above_uint32",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
{"output_format": "gif"},
("output_format", "value_error", "b64_json"),
("output_format", "value_error", "png"),
id="output_format_invalid",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
{"vae_use_slicing": "wrong_type"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@

pytestmark = [pytest.mark.slow, pytest.mark.omni]

_SKIP_ISSUE_3649 = pytest.mark.skip(reason="https://github.com/vllm-project/vllm-omni/issues/3649")


def _minimal_chat_json(omni_server: OmniServer) -> dict[str, object]:
"""Minimal valid chat body; individual tests override one offending field."""
return {
Expand Down Expand Up @@ -112,17 +109,16 @@ def _chat_completions_request_without_expectations(omni_server: OmniServer, case
pytest.param(
"modalities_list_bad",
400,
("modalities", "value_error", ""),
("modalities", "list of strings"),
id="modalities_list_bad_element",
marks=_SKIP_ISSUE_3649,
),
pytest.param(
"response_format_json_schema_incomplete",
400,
("response_format", "value_error", "json_schema"),
id="invalid_response_format_json_schema",
),
pytest.param("logprobs_wrong_type", 400, "logprobs", id="logprobs_wrong_type", marks=_SKIP_ISSUE_3649),
pytest.param("logprobs_wrong_type", 400, ("logprobs", "boolean"), id="logprobs_wrong_type"),
pytest.param(
"logprobs_top_without_enabled",
400,
Expand Down
Loading
Loading