Snížení latence syntézy řeči s využitím sady Speech SDK
Syntéza latence je pro vaše aplikace důležitá. V tomto článku představíme osvědčené postupy pro snížení latence a dosažení nejlepšího výkonu koncovým uživatelům.
Za normálních okolností změříme latenci first byte latency
následujícím finish latency
způsobem:
Latence | Popis | SpeechSynthesisResult – klíč vlastnosti |
---|---|---|
latence prvního bajtu | Označuje časové zpoždění mezi začátkem souhrnného úkolu a příjmem prvního bloku zvukových dat. | SpeechServiceResponse_SynthesisFirstByteLatencyMs |
latence dokončení | Označuje časové zpoždění mezi začátkem souhrnného úkolu a příjmem celých syntetizovaných zvukových dat. | SpeechServiceResponse_SynthesisFinishLatencyMs |
Sada Speech SDK umístí dobu latence do kolekce Properties kolekce SpeechSynthesisResult
. Následující ukázkový kód ukazuje tyto hodnoty.
var result = await synthesizer.SpeakTextAsync(text);
Console.WriteLine($"first byte latency: \t{result.Properties.GetProperty(PropertyId.SpeechServiceResponse_SynthesisFirstByteLatencyMs)} ms");
Console.WriteLine($"finish latency: \t{result.Properties.GetProperty(PropertyId.SpeechServiceResponse_SynthesisFinishLatencyMs)} ms");
// you can also get the result id, and send to us when you need help for diagnosis
var resultId = result.ResultId;
Latence | Popis | SpeechSynthesisResult – klíč vlastnosti |
---|---|---|
first byte latency |
Označuje časové zpoždění mezi spuštěním syntézy a přijetí prvního zvukového bloku. | SpeechServiceResponse_SynthesisFirstByteLatencyMs |
finish latency |
Označuje časové zpoždění mezi zahájením syntézy a celým syntetizovaným zvukem se přijímá. | SpeechServiceResponse_SynthesisFinishLatencyMs |
Sada Speech SDK změřila latence a umístí je do kontejneru SpeechSynthesisResult
vlastností . Pokud je chcete získat, přečtěte si následující kódy.
auto result = synthesizer->SpeakTextAsync(text).get();
auto firstByteLatency = std::stoi(result->Properties.GetProperty(PropertyId::SpeechServiceResponse_SynthesisFirstByteLatencyMs));
auto finishedLatency = std::stoi(result->Properties.GetProperty(PropertyId::SpeechServiceResponse_SynthesisFinishLatencyMs));
// you can also get the result id, and send to us when you need help for diagnosis
auto resultId = result->ResultId;
Latence | Popis | SpeechSynthesisResult – klíč vlastnosti |
---|---|---|
first byte latency |
Označuje časové zpoždění mezi spuštěním syntézy a přijetí prvního zvukového bloku. | SpeechServiceResponse_SynthesisFirstByteLatencyMs |
finish latency |
Označuje časové zpoždění mezi zahájením syntézy a celým syntetizovaným zvukem se přijímá. | SpeechServiceResponse_SynthesisFinishLatencyMs |
Sada Speech SDK změřila latence a umístí je do kontejneru SpeechSynthesisResult
vlastností . Pokud je chcete získat, přečtěte si následující kódy.
SpeechSynthesisResult result = synthesizer.SpeakTextAsync(text).get();
System.out.println("first byte latency: \t" + result.getProperties().getProperty(PropertyId.SpeechServiceResponse_SynthesisFirstByteLatencyMs) + " ms.");
System.out.println("finish latency: \t" + result.getProperties().getProperty(PropertyId.SpeechServiceResponse_SynthesisFinishLatencyMs) + " ms.");
// you can also get the result id, and send to us when you need help for diagnosis
String resultId = result.getResultId();
Latence | Popis | SpeechSynthesisResult – klíč vlastnosti |
---|---|---|
first byte latency |
Označuje časové zpoždění mezi spuštěním syntézy a přijetí prvního zvukového bloku. | SpeechServiceResponse_SynthesisFirstByteLatencyMs |
finish latency |
Označuje časové zpoždění mezi zahájením syntézy a celým syntetizovaným zvukem se přijímá. | SpeechServiceResponse_SynthesisFinishLatencyMs |
Sada Speech SDK změřila latence a umístí je do kontejneru SpeechSynthesisResult
vlastností . Pokud je chcete získat, přečtěte si následující kódy.
result = synthesizer.speak_text_async(text).get()
first_byte_latency = int(result.properties.get_property(speechsdk.PropertyId.SpeechServiceResponse_SynthesisFirstByteLatencyMs))
finished_latency = int(result.properties.get_property(speechsdk.PropertyId.SpeechServiceResponse_SynthesisFinishLatencyMs))
# you can also get the result id, and send to us when you need help for diagnosis
result_id = result.result_id
Latence | Popis | SPXSpeechSynthesisResult klíč vlastnosti |
---|---|---|
first byte latency |
Označuje časové zpoždění mezi spuštěním syntézy a přijetí prvního zvukového bloku. | SPXSpeechServiceResponseSynthesisFirstByteLatencyMs |
finish latency |
Označuje časové zpoždění mezi zahájením syntézy a celým syntetizovaným zvukem se přijímá. | SPXSpeechServiceResponseSynthesisFinishLatencyMs |
Sada Speech SDK změřila latence a umístí je do kontejneru SPXSpeechSynthesisResult
vlastností . Pokud je chcete získat, přečtěte si následující kódy.
SPXSpeechSynthesisResult *speechResult = [speechSynthesizer speakText:text];
int firstByteLatency = [intString [speechResult.properties getPropertyById:SPXSpeechServiceResponseSynthesisFirstByteLatencyMs]];
int finishedLatency = [intString [speechResult.properties getPropertyById:SPXSpeechServiceResponseSynthesisFinishLatencyMs]];
// you can also get the result id, and send to us when you need help for diagnosis
NSString *resultId = result.resultId;
První latence bajtů je ve většině případů nižší než latence dokončení. První latence bajtů je nezávislá na délce textu, zatímco latence dokončení se zvyšuje s délkou textu.
V ideálním případě chceme minimalizovat uživatelskou latenci (latenci před poslechem zvuku) na jednu dobu odezvy síťové trasy a latenci prvního zvukového bloku služby syntézy řeči.
Streamování
Streamování je důležité pro snížení latence. Klientský kód může spustit přehrávání, jakmile přijme první blok zvukových dat. Ve scénáři služby můžete bloky zvukových dat okamžitě předávat klientům, aniž byste čekali na celý zvuk.
Streamování můžete povolit pomocí sady PullAudioOutputStream
Speech SDK , , PushAudioOutputStream
Synthesizing
události a AudioDataStream
sady Speech SDK.
Příklad AudioDataStream
:
using (var synthesizer = new SpeechSynthesizer(config, null as AudioConfig))
{
using (var result = await synthesizer.StartSpeakingTextAsync(text))
{
using (var audioDataStream = AudioDataStream.FromResult(result))
{
byte[] buffer = new byte[16000];
uint filledSize = 0;
while ((filledSize = audioDataStream.ReadData(buffer)) > 0)
{
Console.WriteLine($"{filledSize} bytes received.");
}
}
}
}
K povolení streamování můžete použít PullAudioOutputStream
sadu Speech SDK , PushAudioOutputStream
Synthesizing
událost a AudioDataStream
sadu Speech SDK.
Příklad AudioDataStream
:
auto synthesizer = SpeechSynthesizer::FromConfig(config, nullptr);
auto result = synthesizer->SpeakTextAsync(text).get();
auto audioDataStream = AudioDataStream::FromResult(result);
uint8_t buffer[16000];
uint32_t filledSize = 0;
while ((filledSize = audioDataStream->ReadData(buffer, sizeof(buffer))) > 0)
{
cout << filledSize << " bytes received." << endl;
}
K povolení streamování můžete použít PullAudioOutputStream
sadu Speech SDK , PushAudioOutputStream
Synthesizing
událost a AudioDataStream
sadu Speech SDK.
Příklad AudioDataStream
:
SpeechSynthesizer synthesizer = new SpeechSynthesizer(config, null);
SpeechSynthesisResult result = synthesizer.StartSpeakingTextAsync(text).get();
AudioDataStream audioDataStream = AudioDataStream.fromResult(result);
byte[] buffer = new byte[16000];
long filledSize = audioDataStream.readData(buffer);
while (filledSize > 0) {
System.out.println(filledSize + " bytes received.");
filledSize = audioDataStream.readData(buffer);
}
K povolení streamování můžete použít PullAudioOutputStream
sadu Speech SDK , PushAudioOutputStream
Synthesizing
událost a AudioDataStream
sadu Speech SDK.
Příklad AudioDataStream
:
speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=None)
result = speech_synthesizer.start_speaking_text_async(text).get()
audio_data_stream = speechsdk.AudioDataStream(result)
audio_buffer = bytes(16000)
filled_size = audio_data_stream.read_data(audio_buffer)
while filled_size > 0:
print("{} bytes received.".format(filled_size))
filled_size = audio_data_stream.read_data(audio_buffer)
K povolení streamování můžete použít SPXPullAudioOutputStream
sadu Speech SDK , SPXPushAudioOutputStream
Synthesizing
událost a SPXAudioDataStream
sadu Speech SDK.
Příklad AudioDataStream
:
SPXSpeechSynthesizer *synthesizer = [[SPXSpeechSynthesizer alloc] initWithSpeechConfiguration:speechConfig audioConfiguration:nil];
SPXSpeechSynthesisResult *speechResult = [synthesizer startSpeakingText:inputText];
SPXAudioDataStream *stream = [[SPXAudioDataStream alloc] initFromSynthesisResult:speechResult];
NSMutableData* data = [[NSMutableData alloc]initWithCapacity:16000];
while ([stream readData:data length:16000] > 0) {
// Read data here
}
Předběžné připojení a opětovné použití SpeechSynthesizer
Sada Speech SDK používá ke komunikaci se službou protokol websocket.
V ideálním případě by latence sítě měla být jedna doba odezvy trasy (RTT).
Pokud je připojení nově navázáno, latence sítě zahrnuje další čas pro navázání připojení.
Vytvoření připojení websocket vyžaduje metodu handshake protokolu TCP, handshake PROTOKOLU SSL, připojení HTTP a upgrade protokolu, což představuje časové zpoždění.
Pokud se chcete vyhnout latenci připojení, doporučujeme před připojením a opětovným spuštěním SpeechSynthesizer
zařízení .
Předběžné připojení
Pokud chcete provést předběžné připojení, vytvořte připojení ke službě Speech, pokud víte, že připojení je potřeba brzy. Pokud například vytváříte robota řeči v klientovi, můžete se předem připojit ke službě syntézy řeči, když uživatel začne mluvit, a zavolat SpeakTextAsync
, až bude text odpovědi robota připravený.
using (var synthesizer = new SpeechSynthesizer(uspConfig, null as AudioConfig))
{
using (var connection = Connection.FromSpeechSynthesizer(synthesizer))
{
connection.Open(true);
}
await synthesizer.SpeakTextAsync(text);
}
auto synthesizer = SpeechSynthesizer::FromConfig(config, nullptr);
auto connection = Connection::FromSpeechSynthesizer(synthesizer);
connection->Open(true);
SpeechSynthesizer synthesizer = new SpeechSynthesizer(speechConfig, (AudioConfig) null);
Connection connection = Connection.fromSpeechSynthesizer(synthesizer);
connection.openConnection(true);
synthesizer = speechsdk.SpeechSynthesizer(config, None)
connection = speechsdk.Connection.from_speech_synthesizer(synthesizer)
connection.open(True)
SPXSpeechSynthesizer* synthesizer = [[SPXSpeechSynthesizer alloc]initWithSpeechConfiguration:self.speechConfig audioConfiguration:nil];
SPXConnection* connection = [[SPXConnection alloc]initFromSpeechSynthesizer:synthesizer];
[connection open:true];
Poznámka:
Pokud je syntetizovaný text k dispozici, stačí zavolat SpeakTextAsync
syntetizovat zvuk. Sada SDK zpracuje připojení.
Opakované použití SpeechSynthesizer
Dalším způsobem, jak snížit latenci připojení, je znovu použít, SpeechSynthesizer
abyste nemuseli vytvářet nové SpeechSynthesizer
pro každou syntézu.
Doporučujeme použít fond objektů ve scénáři služby, viz náš ukázkový kód pro C# a Javu.
Přenos komprimovaného zvuku přes síť
Pokud je síť nestabilní nebo má omezenou šířku pásma, má velikost datové části vliv také na latenci. Mezitím komprimovaný zvukový formát pomáhá ušetřit šířku pásma sítě uživatelů, což je zvláště cenné pro mobilní uživatele.
Podporujeme mnoho komprimovaných formátů, včetně opus
, webm
mp3
, silk
a tak dále, viz úplný seznam v SpeechSynthesisOutputFormat.
Přenosová Riff24Khz16BitMonoPcm
rychlost formátu je například 384 kB/s, zatímco Audio24Khz48KBitRateMonoMp3
stojí pouze 48 kB/s.
Naše sada Speech SDK při nastavení výstupního pcm
formátu automaticky použije komprimovaný formát pro přenos.
Pro Linux a Windows GStreamer
je potřeba tuto funkci povolit.
Pokyny k instalaci a konfiguraci GStreamer
sady Speech SDK najdete v této lekci.
Pro Android, iOS a macOS není potřeba žádná další konfigurace od verze 1.20.
Další tipy
Soubory seznamu CRL mezipaměti
Sada Speech SDK používá soubory CRL ke kontrole certifikace. Ukládání do mezipaměti soubory seznamu CRL až do vypršení platnosti vám pomůže vyhnout se stahování souborů CRL pokaždé. Podrobnosti najdete v tématu věnovaném konfiguraci OpenSSL pro Linux.
Použití nejnovější sady Speech SDK
Výkon sady Speech SDK neustále zlepšujeme, takže se snažte v aplikacích používat nejnovější verzi sady Speech SDK.
Vodítko zátěžového testu
Zátěžový test můžete použít k otestování kapacity a latence služby syntézy řeči. Tady je několik pokynů:
- Služba syntézy řeči má schopnost automatického škálování, ale horizontální navýšení kapacity trvá určitou dobu. Pokud se souběžnost zvýší za krátkou dobu, klient může získat dlouhou latenci nebo
429
kód chyby (příliš mnoho požadavků). Proto doporučujeme zvýšit úroveň souběžnosti krok za krokem v zátěžových testech. Další podrobnosti najdete v tomto článku , zejména v tomto příkladu vzorů úloh. - Ukázku můžete použít pomocí fondu objektů (C# a Java) pro zátěžový test a získání čísel latence. V ukázce můžete upravit otočení testu a souběžnost tak, aby splňovala vaši cílovou souběžnost.
- Služba má omezení kvóty na základě skutečného provozu, a proto pokud chcete provést zátěžový test s vyšší souběžností než skutečný provoz, připojte se před testem.
Další kroky
- Podívejte se na ukázky na GitHubu.