Kisebb beszédszintézis-késés a Speech SDK használatával
A szintézis késése kritikus fontosságú az alkalmazások számára. Ebben a cikkben bemutatjuk azokat az ajánlott eljárásokat, amelyek csökkentik a késést, és a legjobb teljesítményt nyújtják a végfelhasználók számára.
A késést általában az alábbiak szerint és az first byte latency
finish latency
alábbiak szerint mérjük:
Késés | Leírás | SpeechSynthesisResult tulajdonságkulcs |
---|---|---|
első bájt késése | A szintézisi feladat kezdete és a hangadatok első adattömbjének beérkezése közötti késleltetést jelzi. | SpeechServiceResponse_SynthesisFirstByteLatencyMs |
befejezési késés | A szintézisi feladat kezdete és a teljes szintetizált hangadatok fogadása közötti késleltetést jelzi. | SpeechServiceResponse_SynthesisFinishLatencyMs |
A Speech SDK a késés időtartamát a következő tulajdonságok gyűjteményében SpeechSynthesisResult
helyezi el: . Az alábbi mintakód ezeket az értékeket jeleníti meg.
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;
Késés | Leírás | SpeechSynthesisResult tulajdonságkulcs |
---|---|---|
first byte latency |
A szintézis kezdete és az első hangtömb fogadása közötti késleltetést jelzi. | SpeechServiceResponse_SynthesisFirstByteLatencyMs |
finish latency |
A szintézis kezdete és a teljes szintetizált hang fogadása közötti késleltetést jelzi. | SpeechServiceResponse_SynthesisFinishLatencyMs |
A Speech SDK megmérte a késéseket, és elhelyezte őket a tulajdonságtáska SpeechSynthesisResult
. A lekéréshez tekintse meg a következő kódokat.
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;
Késés | Leírás | SpeechSynthesisResult tulajdonságkulcs |
---|---|---|
first byte latency |
A szintézis kezdete és az első hangtömb fogadása közötti késleltetést jelzi. | SpeechServiceResponse_SynthesisFirstByteLatencyMs |
finish latency |
A szintézis kezdete és a teljes szintetizált hang fogadása közötti késleltetést jelzi. | SpeechServiceResponse_SynthesisFinishLatencyMs |
A Speech SDK megmérte a késéseket, és elhelyezte őket a tulajdonságtáska SpeechSynthesisResult
. A lekéréshez tekintse meg a következő kódokat.
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();
Késés | Leírás | SpeechSynthesisResult tulajdonságkulcs |
---|---|---|
first byte latency |
A szintézis kezdete és az első hangtömb fogadása közötti késleltetést jelzi. | SpeechServiceResponse_SynthesisFirstByteLatencyMs |
finish latency |
A szintézis kezdete és a teljes szintetizált hang fogadása közötti késleltetést jelzi. | SpeechServiceResponse_SynthesisFinishLatencyMs |
A Speech SDK megmérte a késéseket, és elhelyezte őket a tulajdonságtáska SpeechSynthesisResult
. A lekéréshez tekintse meg a következő kódokat.
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
Késés | Leírás | SPXSpeechSynthesisResult tulajdonságkulcs |
---|---|---|
first byte latency |
A szintézis kezdete és az első hangtömb fogadása közötti késleltetést jelzi. | SPXSpeechServiceResponseSynthesisFirstByteLatencyMs |
finish latency |
A szintézis kezdete és a teljes szintetizált hang fogadása közötti késleltetést jelzi. | SPXSpeechServiceResponseSynthesisFinishLatencyMs |
A Speech SDK megmérte a késéseket, és elhelyezte őket a tulajdonságtáska SPXSpeechSynthesisResult
. A lekéréshez tekintse meg a következő kódokat.
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;
Az első bájt késése a legtöbb esetben alacsonyabb, mint a befejezési késés. Az első bájt késése független a szöveg hosszától, míg a befejezési késés a szöveg hosszával növekszik.
Ideális esetben minimálisra szeretnénk csökkenteni a felhasználó által tapasztalt késést (a hang meghallgatása előtti késést) egy hálózati útvonalra, valamint a beszédszintézis szolgáltatás első hangtömb késését.
Streamelés
A streamelés kritikus fontosságú a késés csökkentéséhez. Az ügyfélkód az első hanganyagdarab fogadásakor elindíthatja a lejátszást. Szolgáltatási forgatókönyv esetén a hanganyagdarabokat azonnal továbbíthatja az ügyfeleknek ahelyett, hogy a teljes hanganyagra várna.
A streamelés engedélyezéséhez használhatja a PullAudioOutputStream
Speech PushAudioOutputStream
Synthesizing
SDK-t, az eseményt és AudioDataStream
a Speech SDK-t.
Példaként: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.");
}
}
}
}
A streamelés engedélyezéséhez használhatja az PullAudioOutputStream
, PushAudioOutputStream
azSynthesizing
eseményt és AudioDataStream
a Speech SDK-t.
Példaként: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;
}
A streamelés engedélyezéséhez használhatja az PullAudioOutputStream
, PushAudioOutputStream
azSynthesizing
eseményt és AudioDataStream
a Speech SDK-t.
Példaként: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);
}
A streamelés engedélyezéséhez használhatja az PullAudioOutputStream
, PushAudioOutputStream
azSynthesizing
eseményt és AudioDataStream
a Speech SDK-t.
Példaként: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)
A streamelés engedélyezéséhez használhatja az SPXPullAudioOutputStream
, SPXPushAudioOutputStream
azSynthesizing
eseményt és SPXAudioDataStream
a Speech SDK-t.
Példaként: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
}
A SpeechSynthesizer előzetes csatlakoztatása és újrafelhasználása
A Speech SDK egy websocket használatával kommunikál a szolgáltatással.
Ideális esetben a hálózati késésnek egy útvonal-utazási időnek (RTT) kell lennie.
Ha a kapcsolat újonnan létrejött, a hálózati késés további időt foglal magában a kapcsolat létrehozásához.
A websocket-kapcsolat létrehozásához tcp-kézfogásra, SSL-kézfogásra, HTTP-kapcsolatra és protokollfrissítésre van szükség, ami időtúllépést okoz.
A kapcsolat késésének elkerülése érdekében javasoljuk a kapcsolat előzetes csatlakoztatását és újbóli használatát SpeechSynthesizer
.
Előcsatlakozás
Az előzetes csatlakozáshoz hozzon létre egy kapcsolatot a Speech szolgáltatással, ha tudja, hogy a kapcsolatra hamarosan szükség van. Ha például egy beszédrobotot hoz létre az ügyfélben, akkor a felhasználó beszédszintézisi szolgáltatásához előre csatlakozhat, és meghívhatja SpeakTextAsync
, ha a robot válaszszövege készen áll.
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];
Feljegyzés
Ha a szintetizálási szöveg elérhető, csak hívja SpeakTextAsync
meg a hang szintetizálását. Az SDK kezeli a kapcsolatot.
A SpeechSynthesizer újrafelhasználása
A kapcsolat késésének csökkentésének másik módja, ha újra felhasználja a SpeechSynthesizer
kapcsolatot, hogy ne kelljen újat SpeechSynthesizer
létrehoznia az egyes szintézisekhez.
Javasoljuk, hogy használja az objektumkészletet a szolgáltatási forgatókönyvben, tekintse meg a C# és a Java mintakódját.
Tömörített hang átvitele a hálózaton keresztül
Ha a hálózat instabil vagy korlátozott sávszélességű, a hasznos adatok mérete a késésre is hatással van. Eközben a tömörített hangformátum segít a felhasználók hálózati sávszélességének mentésében, ami különösen hasznos a mobilfelhasználók számára.
Számos tömörített formátumot támogatunk, webm
mp3
silk
többek között opus
a SpeechSynthesisOutputFormat teljes listáját.
A formátum bitráta Riff24Khz16BitMonoPcm
például 384 kb/s, míg Audio24Khz48KBitRateMonoMp3
csak 48 kb/s.
A Speech SDK a kimeneti formátum beállításakor pcm
automatikusan tömörített formátumot használ az átvitelhez.
Linux és Windows GStreamer
esetén a funkció engedélyezéséhez szükséges.
A Speech SDK telepítéséhez és konfigurálásához tekintse meg ezt az utasítástGStreamer
.
Android, iOS és macOS esetén nincs szükség további konfigurációra az 1.20-es verziótól kezdve.
Egyéb tippek
CRL-fájlok gyorsítótárazási gyorsítótárazása
A Speech SDK CRL-fájlokat használ a minősítés ellenőrzéséhez. A CRL-fájlok lejáratig történő gyorsítótárazása segít elkerülni a CRL-fájlok minden alkalommal való letöltését. Részletekért lásd: Linuxos OpenSSL konfigurálása.
A legújabb Speech SDK használata
A Speech SDK teljesítményét folyamatosan javítjuk, ezért lehetőleg a legfrissebb Speech SDK-t használja az alkalmazásában.
A tesztelési útmutató betöltése
A beszédszintézis-szolgáltatás kapacitásának és késésének teszteléséhez terheléstesztet használhat. Íme néhány irányelv:
- A beszédszintézis szolgáltatás képes automatikus skálázásra, de időbe telik a vertikális felskálázás. Ha az egyidejűség rövid idő alatt növekszik, az ügyfél hosszú késést vagy
429
hibakódot kaphat (túl sok kérés). Ezért azt javasoljuk, hogy lépésről lépésre növelje az egyidejűséget a terheléstesztben. További részletekért tekintse meg ezt a cikket , különösen a számítási feladatok mintáinak példáját. - A minta objektumkészlet (C# és Java) használatával használható a terhelésteszthez és a késési számok lekéréséhez. A minta tesztelési fordulatait és egyidejűségét módosíthatja, hogy megfeleljen a cél egyidejűségének.
- A szolgáltatás kvótakorlátozással rendelkezik a valós forgalom alapján, ezért ha a valós forgalomnál nagyobb egyidejűséggel szeretne terheléstesztet végezni, csatlakozzon a teszt előtt.
Következő lépések
- A minták megtekintése a GitHubon