aws / aws-sdk-js

AWS SDK for JavaScript in the browser and Node.js
https://aws.amazon.com/developer/language/javascript/
Apache License 2.0
7.6k stars 1.55k forks source link

synthesizeSpeech very slow on RPi 3 #1513

Closed matrixOperator closed 7 years ago

matrixOperator commented 7 years ago

Polly.synthesizeSpeech takes a long time on my Raspberry Pi 3 for the callback to trigger. With the benchmark below, I am getting dt ~ 300 ms on Win10 and Win7 desktops, and dt ~15000 ms on the RPi 3. This is pretty unacceptable!

// Load the SDK
const AWS = require('aws-sdk')

// Create an Polly client
const Polly = new AWS.Polly({
    signatureVersion: 'v4',
    region: 'us-east-1'
})

let params = {
    'Text': 'Hello.',
    'OutputFormat': 'mp3',
    'VoiceId': 'Kimberly'
}

speechHandler = function(err,data){
    if (err) {
        console.log(err.code)
    } else if (data) {
        if (data.AudioStream instanceof Buffer) {
            console.timeEnd('a')
            console.time('a')
            Polly.synthesizeSpeech(params,speechHandler)
        }
    }
}

console.time('a')
Polly.synthesizeSpeech(params,speechHandler)

All the machines are on the same network and have similar ping times and ul/dl rates; and this happens to the RPi regardless wired or wireless connectivity (tried both). I tried doing a fresh install of Raspbian Jessie w/ Pixel on the entire 32 GB SD card, and set up with my minimum dev config:

Same slow response. So I suspect the reason may have to do with either system or network performance - since the response looks really snappy in @anaptfox's video.

Tried:

Does anyone have any idea? I am close to throwing my network router at my RPi3 to knock out a loose screw or something. Thank you!

chrisradek commented 7 years ago

@ddwp99 Can you instantiate your polly client to include logging? Ex:

new AWS.Polly({
  logger: console
});

It will give us the total time the request took, which might not be super helpful, but also let us know if the request is being retried.

I'm not very familiar with debugging node.js on a Raspberry Pi. Is it possible to profile the code to tell if it's the response that's taking a long time to come back, or if some code is taking a long time to execute?

matrixOperator commented 7 years ago

Hey @chrisradek thanks for the question. I was able to resolve this issue, and posted an answer to my question originally posted here.

As it turns out, the script was spending most of its time re-establishing the SSL handshake on each Polly request (As confirmed by CPU profiles sampled with Chrome DevTools). To resolve this issue, the module agentkeepalive the build-in module https was used.

To use https in the context here, just do this:

const AWS = require('aws-sdk')
const httpsAgent = require('https').Agent
const keepAliveAgent = new httpsAgent({maxSockets:1, keepAlive:true})
AWS.config.update({
    httpOptions: { agent: keepAliveAgent }
});

If maxSockets is not set to 1, then Polly will still attempt to establish SSL on each available socket until they are all kept alive. Once the sockets are kept alive - the latency between callbacks are reduced to ~90 ms on the RPi 3 - this is much better than the ~15000 ms that I was getting before!

chrisradek commented 7 years ago

@ddwp99 Glad you found a solution! You should be able to use the same solution you have with a native https agent as well. Very interesting that the SSL handshake takes so much time on a Raspberry Pi!

matrixOperator commented 7 years ago

Thanks Chris! I've edited the comment above to use the build-in https module instead.

lock[bot] commented 5 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.