Amazon Transcribe, 음성 스트리밍에서 WebSocket 지원 활용하기
Amazon Transcribe는 다양한 언어의 음성을 실시간으로 정확하게 인식하는 AI 서비스입니다. (한국어도 지원합니다.) 지금까지 Transcribe 스트리밍 API는 HTTP/2 스트리밍 기술을 사용하여 제공되었습니다. 이제 실시간 음성 기능을 적용할 수 있는 새로운 통합 옵션으로 WebSocket을 추가합니다.
이 게시물에서는 브라우저의 클라이언트 측 JavaScript만 사용하여 실시간으로 음성을 받아쓰기 해 보겠습니다. 애플리케이션을 구축하려면 먼저 기초가 필요합니다. 데모를 전체적으로 설명하는 데 필요한 만큼만 Amazon Transcribe, WebSocket, Amazon Transcribe 스트리밍 API에 대해서 알아보겠습니다. 자세한 정보는 Amazon Transcribe 문서를 참조십시오.
실제 작동 모습을 보고 싶다면 바로 데모를 실행하면 되지만, 먼저 이 게시물을 간단히 읽어볼 것을 권장합니다.
Amazon Transcribe란?
Amazon Transcribe는 기계 학습 모델을 적용하여 오디오의 음성을 텍스트 사본으로 변환합니다. Amazon Transcribe의 가장 강력한 기능 중 하나는 오디오의 실시간 받아쓰기를 수행하는 능력입니다. 지금까지 이 기능은 HTTP/2 스트림을 통해 제공되었습니다. 오늘 Amazon은 WebSocket을 사용하여 Amazon Transcribe에 연결하는 기능을 추가로 발표합니다.
Amazon Transcribe는 현재 영국 영어(en-GB), 미국 영어(en-US), 프랑스어(fr-FR), 캐나다 프랑스어(fr-CA), 미국 스페인어(es-US)의 실시간 받아쓰기를 지원합니다.
WebSocket이란?
WebSocket은 HTTP처럼 TCP를 기반으로 구축된 프로토콜입니다. HTTP는 단기 요청에 적합하지만, 지속적인 실시간 통신이 필요한 상황에는 그다지 적합하지 않았습니다. 일반적으로 HTTP 연결은 메시지의 끝에서 닫히지만 WebSocket 연결은 열린 상태로 유지됩니다. 따라서 대역폭을 소모하거나 지연을 가중시키지 않으면서 핸드쉐이킹하고 연결을 협상하는 방법으로 메시지를 양방향으로 전송할 수 있습니다. WebSocket 연결은 서버와 클라이언트가 모두 동시에 데이터를 전송할 수 있는 전이중 방식입니다. 또한 도메인 간 사용이 가능하도록 설계되었으므로 HTTP의 경우처럼 CORS(Cross-Origin Resource Sharing)와 관련한 문제가 발생하지 않습니다.
HTTP/2 스트림은 실시간 통신 시나리오에서 HTTP를 사용할 경우 발생하던 여러 가지 문제를 해결해줍니다. 제공되는 최초의 Amazon Transcribe 스트리밍 API는 HTTP/2를 사용합니다. WebSocket은 훨씬 더 많은 청중에 대해 Amazon Transcribe 스트리밍을 열도록 지원하며, 기존에 WebSocket 기반 통합 기술 또는 지식을 보유한 고객이 손쉽게 통합할 수 있도록 지원합니다.
Amazon Transcribe 스트리밍 API의 작동 방식
권한 부여
먼저 IAM 사용자에게 Amazon Transcribe 스트리밍 WebSocket을 사용할 권한을 부여해야 합니다. AWS Management Console에서 다음 정책을 사용자에게 연결합니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "transcribestreaming",
"Effect": "Allow",
"Action": "transcribe:StartStreamTranscriptionWebSocket",
"Resource": "*"
}
]
}
인증
Transcribe는 AWS Signature Version 4를 사용하여 요청을 인증합니다. WebSocket 연결에서는 사전 서명된 URL을 사용합니다. 이 URL에는 URL에서 쿼리 파라미터로 전달되는 모든 필수 정보가 들어 있습니다. 따라서 WebSocket을 설정할 수 있는 인증된 엔드포인트가 만들어지는 셈입니다.
필수 파라미터
필수 파라미터는 모두 사전 서명된 URL에 쿼리 문자열의 일부로 포함됩니다. 이러한 파라미터는 다음과 같습니다.
- language-code: 언어 코드입니다. en-US, en-GB, fr-FR, fr-CA, es-US 중 하나입니다.
- sample-rate: 오디오의 샘플링 속도(Hz)입니다. en-US 및 es-US의 경우 최대 16000, 다른 언어의 경우 8000까지 지원됩니다.
- media-encoding: 현재 pcm만 유효합니다.
- vocabulary-name: Amazon Transcribe에서는 데이터에서 나타날 것으로 예상되는 흔하지 않거나 독특한 단어를 모은 맞춤형 용어집을 정의할 수 있습니다. 맞춤형 용어집을 사용하려면 여기를 참조하십시오.
오디오 데이터 요구 사항
데이터 전송을 시작하기 전에 몇 가지 알아야 할 사항이 있습니다. 첫째 Transcribe는 PCM 데이터로 인코딩된 오디오를 필요로 합니다. 디지털 오디오 파일의 샘플링 속도는 캡처된 오디오의 품질과 관련이 있습니다. 샘플링 속도란 디지털 신호를 생성하기 위해 아날로그 신호를 확인하는 초당 횟수(Hz)입니다. 고품질 데이터는 샘플링 속도를 16,000Hz 이상으로 설정하는 것이 좋습니다. 전화 통화와 같은 저품질 오디오에는 8,000Hz의 샘플링 속도를 사용합니다. 현재 미국 영어(en-US)와 미국 스페인어(es-US)의 경우 48,000Hz의 샘플링 속도를 지원합니다. 다른 언어는 최고 16,000Hz의 속도를 지원합니다.
데모에서 lib/audioUtils.js
파일에는 브라우저에서 들어오는 오디오 바이트의 샘플링 속도를 줄이는 downsampleBuffer()
함수와 원시 오디오 바이트를 PCM으로 변환하는 pcmEncode()
함수가 포함되어 있습니다.
요청 형식
오디오 인코딩을 적절한 샘플링 속도의 PCM 데이터로 변환한 후에는 WebSocket 연결을 통해 전송하기 전에 봉투에 래핑해야 합니다. 각 메시지는 3개의 헤더 뒤에 PCM 인코딩 오디오 바이트가 들어 있는 메시지 본문이 오는 구성입니다. 전체 메시지는 바이너리 이벤트 스트림 메시지로 인코딩되어 전송됩니다. 이전에 HTTP/2 API를 사용해보았다면, 전송하는 오디오 데이터의 각 청크에 암호화 방식으로 서명할 필요가 없다는 장점 때문에 WebSocket을 사용하기가 훨씬 쉬워졌다는 것을 알 겁니다.
응답 형식
수신되는 메시지는 동일한 일반적인 형식을 따릅니다. 즉, 헤더와 본문이 있고 바이너리로 인코딩된 이벤트 스트림 메시지입니다. 단, 메시지 본문에 오디오 바이트 대신 Transcript
객체가 들어 있다는 점이 다릅니다. 오디오에서 음성이 자연스럽게 멈추는 시점이 확인될 때까지 부분 응답이 반환됩니다. 이 응답이 어떻게 포맷되는지에 대한 자세한 내용은 문서를 참조하고 main.js
에서 handleEventStreamMessage()
함수를 살펴보십시오.
데모 보기
필요한 배경 정보를 살펴보았으니 이제 데모를 실행해보겠습니다. 이 데모는 AWS Amplify 콘솔을 사용하여 배포했습니다. 살펴보거나 버튼을 눌러 직접 배포해보십시오. 앞서 권한을 부여한 IAM 사용자의 액세스 ID와 보안 키를 입력하고 [Start Transcription] 버튼을 누른 후 마이크에 대고 말하기 시작합니다.
완성된 프로젝트는 GitHub에서 참조할 수 있습니다. 가장 중요한 파일은 lib/main.js
입니다. 이 파일은 필요한 종속 관계를 모두 정의하고, index.html
에서 버튼을 연결하고 필드를 구성하며, 마이크 스트림에 액세스하고, WebSocket을 통해 데이터를 Transcribe로 푸시합니다.
코드에는 자세하게 주석을 달았기 때문에 쉽게 이해할 수 있으리라 생각하지만, 궁금한 점이 있으면 언제든 GitHub 리포지토리에서 문의하시면 도와 드리겠습니다.
이 데모의 기초를 구성한 코드를 제공해 주신 데 대해 Transcribe 팀의 소프트웨어 개발 엔지니어 Karan Grover 께 감사를 드립니다.
– Brandan West, AWS 북미 테크에반젤리즘 매니저