vllm-project--vllm-omni
101 行
4.2 KiB
Python
101 行
4.2 KiB
Python
"""Tests for speaker metadata (created_at, consent, ref_text, ...) round-tripping
|
|
through the safetensors header.
|
|
|
|
These cover the helpers that back ``_restore_uploaded_speakers`` — the logic
|
|
that rebuilds ``uploaded_speakers`` on server start by reading the
|
|
``.safetensors`` file written during upload.
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from vllm_omni.entrypoints.openai.serving_speech import OmniOpenAIServingSpeech
|
|
|
|
pytestmark = [pytest.mark.core_model, pytest.mark.cpu]
|
|
|
|
|
|
class TestSpeakerMetadataRoundTrip:
|
|
def test_str_only_header(self):
|
|
"""The safetensors metadata dict must be ``dict[str, str]`` — every value
|
|
serialized as a string (ints and None handled)."""
|
|
data = {
|
|
"name": "Alice",
|
|
"voice_name_lower": "alice",
|
|
"consent": "xxx",
|
|
"created_at": 1712345678,
|
|
"sample_rate": 24000,
|
|
"embedding_source": "audio",
|
|
"ref_text": None, # None values must be dropped
|
|
"file_path": "/tmp/should/be/stripped.safetensors", # re-derived, not persisted
|
|
}
|
|
header = OmniOpenAIServingSpeech._speaker_metadata_to_header(data)
|
|
assert all(isinstance(k, str) and isinstance(v, str) for k, v in header.items())
|
|
assert "ref_text" not in header # None stripped
|
|
assert "file_path" not in header # never persisted
|
|
|
|
def test_int_fields_coerce_back(self):
|
|
"""Int fields (created_at, file_size, sample_rate, embedding_dim) survive
|
|
the string round-trip with their type preserved."""
|
|
data = {
|
|
"name": "Bob",
|
|
"voice_name_lower": "bob",
|
|
"consent": "yyy",
|
|
"created_at": 1712345678,
|
|
"sample_rate": 44100,
|
|
"file_size": 12345,
|
|
"embedding_dim": 1024,
|
|
"embedding_source": "direct",
|
|
}
|
|
header = OmniOpenAIServingSpeech._speaker_metadata_to_header(data)
|
|
back = OmniOpenAIServingSpeech._speaker_metadata_from_header(header, "/some/path.safetensors")
|
|
assert isinstance(back["created_at"], int)
|
|
assert back["created_at"] == 1712345678
|
|
assert isinstance(back["sample_rate"], int)
|
|
assert back["sample_rate"] == 44100
|
|
assert isinstance(back["file_size"], int)
|
|
assert isinstance(back["embedding_dim"], int)
|
|
|
|
def test_file_path_reinjected_on_load(self):
|
|
"""file_path is not persisted in the header; restore derives it from the
|
|
actual file location on disk."""
|
|
data = {
|
|
"name": "Carol",
|
|
"voice_name_lower": "carol",
|
|
"consent": "zzz",
|
|
"created_at": 1234,
|
|
"embedding_source": "audio",
|
|
}
|
|
header = OmniOpenAIServingSpeech._speaker_metadata_to_header(data)
|
|
back = OmniOpenAIServingSpeech._speaker_metadata_from_header(header, "/real/path.safetensors")
|
|
assert back["file_path"] == "/real/path.safetensors"
|
|
|
|
def test_string_fields_preserved(self):
|
|
"""ref_text, consent, speaker_description must survive unchanged."""
|
|
data = {
|
|
"name": "Dave",
|
|
"voice_name_lower": "dave",
|
|
"consent": "consent-id-42",
|
|
"created_at": 1,
|
|
"ref_text": "Hello. This is a transcript with punctuation!",
|
|
"speaker_description": "A warm baritone voice.",
|
|
"embedding_source": "audio",
|
|
}
|
|
header = OmniOpenAIServingSpeech._speaker_metadata_to_header(data)
|
|
back = OmniOpenAIServingSpeech._speaker_metadata_from_header(header, "/x.safetensors")
|
|
assert back["ref_text"] == data["ref_text"]
|
|
assert back["speaker_description"] == data["speaker_description"]
|
|
assert back["consent"] == data["consent"]
|
|
|
|
def test_malformed_int_is_left_as_string(self):
|
|
"""If an int field somehow contains non-numeric text (manual edit,
|
|
corruption), the loader does not crash; it leaves the field as-is."""
|
|
header = {
|
|
"name": "Eve",
|
|
"voice_name_lower": "eve",
|
|
"consent": "x",
|
|
"created_at": "not-a-number",
|
|
"embedding_source": "audio",
|
|
}
|
|
back = OmniOpenAIServingSpeech._speaker_metadata_from_header(header, "/p.safetensors")
|
|
# Preserved as string rather than raising.
|
|
assert back["created_at"] == "not-a-number"
|