166 lines
5.4 KiB
Python
166 lines
5.4 KiB
Python
import base64
|
|
from typing import Any
|
|
|
|
from evalscope.api.messages import ChatMessageUser, ContentAudio, ContentText
|
|
from evalscope.api.model import get_model
|
|
from evalscope.benchmarks.seed_tts_eval.seed_tts_eval_adapter import PROMPT_TEMPLATE
|
|
from evalscope.constants import EvalType
|
|
from evalscope.utils.url_utils import data_uri_to_base64
|
|
|
|
|
|
def test_text2speech_volcengine_provider_returns_audio(monkeypatch: Any) -> None:
|
|
calls: dict[str, Any] = {}
|
|
|
|
class MockRequest:
|
|
|
|
headers = {'X-Api-Request-Id': 'request-1'}
|
|
|
|
class MockResponse:
|
|
|
|
headers = {'X-Tt-Logid': 'log-1'}
|
|
request = MockRequest()
|
|
text = ''
|
|
|
|
def __init__(self, body: str):
|
|
self.body = body
|
|
self.text = body
|
|
|
|
def raise_for_status(self) -> None:
|
|
pass
|
|
|
|
def iter_content(self, chunk_size: int, decode_unicode: bool) -> list[str]:
|
|
return [self.body]
|
|
|
|
def mock_post(
|
|
self: Any,
|
|
url: str,
|
|
headers: dict[str, str],
|
|
json: dict[str, Any],
|
|
stream: bool,
|
|
timeout: float,
|
|
) -> MockResponse:
|
|
calls['url'] = url
|
|
calls['headers'] = headers
|
|
calls['json'] = json
|
|
calls['stream'] = stream
|
|
calls['timeout'] = timeout
|
|
audio = base64.b64encode(b'audio-bytes').decode('utf-8')
|
|
body = ''.join([
|
|
'{"code":0,"message":"","data":"',
|
|
audio,
|
|
'"}',
|
|
'{"code":20000000,"message":"OK","data":null,"usage":{"text_words":5}}',
|
|
])
|
|
return MockResponse(body)
|
|
|
|
monkeypatch.setattr('requests.Session.post', mock_post)
|
|
model = get_model(
|
|
model='seed-tts-2.0',
|
|
eval_type=EvalType.TEXT2SPEECH,
|
|
base_url='https://openspeech.test/api/v3/tts/unidirectional',
|
|
api_key='test-key',
|
|
model_args={
|
|
'speaker': 'en_female_dacey_uranus_bigtts',
|
|
'audio_params': {
|
|
'sample_rate': 24000,
|
|
},
|
|
},
|
|
memoize=False,
|
|
)
|
|
output = model.generate([
|
|
ChatMessageUser(
|
|
content=[
|
|
ContentAudio(audio='data:audio/wav;base64,YXVkaW8=', format='wav'),
|
|
ContentText(
|
|
text=PROMPT_TEMPLATE.format(
|
|
prompt_text='reference speech',
|
|
text='Please synthesize this sentence.',
|
|
)
|
|
),
|
|
]
|
|
)
|
|
])
|
|
|
|
assert calls['url'] == 'https://openspeech.test/api/v3/tts/unidirectional'
|
|
assert calls['headers']['X-Api-Key'] == 'test-key'
|
|
assert calls['headers']['X-Api-Resource-Id'] == 'seed-tts-2.0'
|
|
assert calls['json']['req_params']['text'] == 'Please synthesize this sentence.'
|
|
assert calls['json']['req_params']['speaker'] == 'en_female_dacey_uranus_bigtts'
|
|
assert calls['json']['req_params']['audio_params'] == {
|
|
'format': 'mp3',
|
|
'sample_rate': 24000,
|
|
}
|
|
assert calls['stream'] is True
|
|
audio_content = output.message.content[0]
|
|
assert isinstance(audio_content, ContentAudio)
|
|
assert audio_content.format == 'mp3'
|
|
assert base64.b64decode(data_uri_to_base64(audio_content.audio)) == b'audio-bytes'
|
|
assert output.metadata['usage'] == {'text_words': 5}
|
|
|
|
|
|
def test_text2speech_openai_provider_returns_audio(monkeypatch: Any) -> None:
|
|
calls: dict[str, Any] = {}
|
|
|
|
class MockResponse:
|
|
|
|
headers = {'x-request-id': 'request-2', 'Content-Type': 'audio/mpeg'}
|
|
content = b'audio-bytes'
|
|
|
|
def raise_for_status(self) -> None:
|
|
pass
|
|
|
|
def mock_post(
|
|
self: Any,
|
|
url: str,
|
|
headers: dict[str, str],
|
|
json: dict[str, Any],
|
|
timeout: float,
|
|
) -> MockResponse:
|
|
calls['url'] = url
|
|
calls['headers'] = headers
|
|
calls['json'] = json
|
|
calls['timeout'] = timeout
|
|
return MockResponse()
|
|
|
|
monkeypatch.setattr('requests.Session.post', mock_post)
|
|
model = get_model(
|
|
model='tts-1',
|
|
eval_type=EvalType.TEXT2SPEECH,
|
|
base_url='https://api.openai.com/v1',
|
|
api_key='openai-test-key',
|
|
model_args={
|
|
'provider': 'openai',
|
|
'voice': 'nova',
|
|
'speed': 1.05,
|
|
'format': 'wav',
|
|
},
|
|
memoize=False,
|
|
)
|
|
output = model.generate([
|
|
ChatMessageUser(
|
|
content=[
|
|
ContentAudio(audio='data:audio/wav;base64,YXVkaW8=', format='wav'),
|
|
ContentText(
|
|
text=PROMPT_TEMPLATE.format(
|
|
prompt_text='reference speech',
|
|
text='Please synthesize this sentence.',
|
|
)
|
|
),
|
|
]
|
|
)
|
|
])
|
|
|
|
assert calls['url'] == 'https://api.openai.com/v1/audio/speech'
|
|
assert calls['headers']['Authorization'] == 'Bearer openai-test-key'
|
|
assert calls['headers']['Content-Type'] == 'application/json'
|
|
assert calls['json']['model'] == 'tts-1'
|
|
assert calls['json']['input'] == 'Please synthesize this sentence.'
|
|
assert calls['json']['voice'] == 'nova'
|
|
assert calls['json']['response_format'] == 'wav'
|
|
assert calls['json']['speed'] == 1.05
|
|
audio_content = output.message.content[0]
|
|
assert isinstance(audio_content, ContentAudio)
|
|
assert audio_content.format == 'wav'
|
|
assert base64.b64decode(data_uri_to_base64(audio_content.audio)) == b'audio-bytes'
|
|
assert output.metadata['request_id'] == 'request-2'
|