Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
76c4bca
fix: Ensure invalid/corrupt audio files returns 400 error
jasonozuzu-cohere Feb 17, 2026
909e864
add unit test
jasonozuzu-cohere Feb 17, 2026
b626668
run linting
jasonozuzu-cohere Feb 18, 2026
138c0bb
Merge branch 'vllm-project:main' into jasonozuzu/pts-8824-push-vllm-v…
jasonozuzu-cohere Feb 20, 2026
1eb29d4
move test to correct file
jasonozuzu-cohere Feb 20, 2026
bf4112b
fix spacing
jasonozuzu-cohere Feb 20, 2026
0bbca7e
Merge branch 'vllm-project:main' into jasonozuzu/pts-8824-push-vllm-v…
jasonozuzu-cohere Feb 20, 2026
e258f04
Merge branch 'vllm-project:main' into jasonozuzu/pts-8824-push-vllm-v…
jasonozuzu-cohere Feb 24, 2026
f50af46
treat soundfile as guaranteed dependency and simplify exception handling
jasonozuzu-cohere Feb 24, 2026
0640bce
Merge branch 'vllm-project:main' into jasonozuzu/pts-8824-push-vllm-v…
jasonozuzu-cohere Feb 24, 2026
7bc42cd
Merge branch 'vllm-project:main' into jasonozuzu/pts-8824-push-vllm-v…
jasonozuzu-cohere Feb 24, 2026
1b90562
Merge branch 'vllm-project:main' into jasonozuzu/pts-8824-push-vllm-v…
jasonozuzu-cohere Feb 25, 2026
91ae5ee
Merge branch 'vllm-project:main' into jasonozuzu/pts-8824-push-vllm-v…
jasonozuzu-cohere Feb 25, 2026
11cf005
Merge branch 'main' into jasonozuzu/pts-8824-push-vllm-validation-upd…
NickLucche Feb 26, 2026
7b74918
Merge branch 'main' into jasonozuzu/pts-8824-push-vllm-validation-upd…
NickLucche Mar 2, 2026
fd38f56
Merge branch 'vllm-project:main' into jasonozuzu/pts-8824-push-vllm-v…
jasonozuzu-cohere Mar 3, 2026
88e1a6e
fix fixture name in test
jasonozuzu-cohere Mar 3, 2026
5849a3f
Merge branch 'vllm-project:main' into jasonozuzu/pts-8824-push-vllm-v…
jasonozuzu-cohere Mar 3, 2026
65dac67
Merge branch 'vllm-project:main' into jasonozuzu/pts-8824-push-vllm-v…
jasonozuzu-cohere Mar 3, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,23 @@ async def test_long_audio_request(mary_had_lamb, whisper_client):
assert out_usage["seconds"] == 161, out_usage["seconds"]


@pytest.mark.asyncio
async def test_invalid_audio_file(client):
"""Corrupted audio should surface as HTTP 400."""
invalid_audio = io.BytesIO(b"not a valid audio file")
invalid_audio.name = "invalid.wav"

with pytest.raises(openai.BadRequestError) as exc_info:
await client.audio.transcriptions.create(
model=MODEL_NAME,
file=invalid_audio,
language="en",
)

assert exc_info.value.status_code == 400
assert "Invalid or unsupported audio file" in exc_info.value.message


@pytest.mark.asyncio
async def test_completion_endpoints(whisper_client):
# text to text model
Expand Down
28 changes: 25 additions & 3 deletions vllm/entrypoints/openai/speech_to_text/speech_to_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@
except ImportError:
librosa = PlaceholderModule("librosa") # type: ignore[assignment]

try:
import soundfile as sf
except ImportError:
sf = None
Comment thread
jasonozuzu-cohere marked this conversation as resolved.
Outdated

# Public libsndfile error codes exposed via `soundfile.LibsndfileError.code`, soundfile
# being librosa's main backend. Used to validate if an audio loading error is due to a
# server error vs a client error (invalid audio file).
# 1 = unrecognised format (file is not a supported audio container)
# 3 = malformed file (corrupt or structurally invalid audio)
# 4 = unsupported encoding (codec not supported by this libsndfile build)
_BAD_SF_CODES = {1, 3, 4}

SpeechToTextResponse: TypeAlias = TranscriptionResponse | TranslationResponse
SpeechToTextResponseVerbose: TypeAlias = (
TranscriptionResponseVerbose | TranslationResponseVerbose
Expand Down Expand Up @@ -264,9 +277,18 @@ async def _preprocess_speech_to_text(
)

with io.BytesIO(audio_data) as bytes_:
# NOTE resample to model SR here for efficiency. This is also a
# pre-requisite for chunking, as it assumes Whisper SR.
y, sr = librosa.load(bytes_, sr=self.asr_config.sample_rate)
try:
# NOTE resample to model SR here for efficiency. This is also a
# pre-requisite for chunking, as it assumes Whisper SR.
y, sr = librosa.load(bytes_, sr=self.asr_config.sample_rate)
except Exception as exc:
if (
sf is not None
and isinstance(exc, sf.LibsndfileError)
Comment thread
jasonozuzu-cohere marked this conversation as resolved.
Outdated
and exc.code in _BAD_SF_CODES
):
raise ValueError("Invalid or unsupported audio file.") from exc
raise

duration = librosa.get_duration(y=y, sr=sr)
do_split_audio = (
Expand Down