제퍼넷 로고

Amazon Transcribe, Amazon Translate 및 Amazon Polly로 언어 장벽을 허물다

시간

의사가 통역사 없이 전 세계의 환자들과 화상 통화를 한다고 상상해 보십시오. 신생 스타트업이 실제 번역가 없이도 유연하고 정확하며 다국어 고객 지원과 판매를 제공함으로써 국경을 넘어 새로운 지리적 시장으로 제품을 쉽게 확장할 수 있다면 어떨까요? 더 이상 언어에 얽매이지 않으면 비즈니스는 어떻게 됩니까?

오늘날에는 다양한 언어를 구사하는 국제 팀 및 고객과 가상 회의를 하는 것이 일반적입니다. 내부 회의든 외부 회의든 복잡한 토론에서 의미를 잃어버리는 경우가 많으며 가능한 한 효과적이지 못하게 하는 언어 장벽에 부딪힐 수 있습니다.

이 게시물에서는 세 가지 완전 관리형 AWS 서비스(아마존 전사, 아마존 번역아마존 폴리) 기계 학습(ML) 경험이 전혀 없는 소스 화자의 실시간 음성 입력을 정확하고 번역된 대상 언어로 신속하게 번역할 수 있는 거의 실시간 음성-음성 번역기 솔루션을 생성합니다.

솔루션 개요

번역기는 다음을 사용하여 단일 Python 스크립트에서 함께 작동하는 세 가지 완전 관리형 AWS ML 서비스로 구성됩니다. Python 용 AWS SDK (Boto3) 텍스트 번역 및 텍스트 음성 변환을 위한 부분과 오디오 입력 트랜스크립션을 위한 비동기 스트리밍 SDK.

Amazon Transcribe: 음성을 텍스트로 스트리밍

스택에서 사용하는 첫 번째 서비스는 입력 음성을 가져와 텍스트로 변환하는 완전 관리형 음성-텍스트 서비스인 Amazon Transcribe입니다. Amazon Transcribe는 저장된 오디오 파일이나 스트리밍 오디오 데이터를 허용하기 때문에 배치 또는 스트리밍과 같은 유연한 수집 방법을 제공합니다. 이 게시물에서 사용하는 Python용 비동기 Amazon Transcribe 스트리밍 SDK, HTTP/2 스트리밍 프로토콜을 사용하여 라이브 오디오를 스트리밍하고 라이브 트랜스크립션을 수신합니다.

이 프로토타입을 처음 구축했을 때 Amazon Transcribe 스트리밍 수집은 자동 언어 감지를 지원하지 않았지만 2021년 XNUMX월 현재는 더 이상 지원하지 않습니다. 이제 배치 및 스트리밍 수집은 모두 자동 언어 감지를 지원합니다. 지원되는 언어. 이 게시물에서는 스트리밍 자동 언어 감지를 사용하여 원활한 다국어 매개변수 없는 설계를 통해 매개변수 기반 솔루션이 가능한 방법을 보여줍니다. 전사된 음성 세그먼트가 텍스트로 반환된 후 Amazon Translate에 요청을 보내 번역을 요청하고 Amazon Transcribe에서 결과를 반환합니다. EventHandler 방법.

Amazon Translate: 최첨단 완전 관리형 번역 API

다음 스택은 빠르고 고품질이며 경제적이며 사용자 지정 가능한 언어 번역을 제공하는 신경 기계 번역 서비스인 Amazon Translate입니다. 2022년 75월 현재 Amazon Translate는 XNUMX개 언어에 대한 번역을 지원하며 새로운 언어 쌍과 지속적으로 개선되고 있습니다. Amazon Translate는 확장성이 뛰어나고 탄력적인 AWS 클라우드 아키텍처에서 호스팅되는 딥 러닝 모델을 사용하여 사용 사례에 따라 실시간으로 또는 일괄적으로 정확한 번역을 신속하게 제공합니다. Amazon Translate를 사용하는 것은 간단하며 기본 아키텍처나 ML 기술을 관리할 필요가 없습니다. Amazon Translate에는 생성 및 사용과 같은 여러 기능이 있습니다. 사용자 정의 용어 산업별 용어 간의 매핑을 처리합니다. Amazon Translate 서비스 제한에 대한 자세한 내용은 다음을 참조하십시오. 지침 및 제한. 애플리케이션은 대상 언어로 번역된 텍스트를 수신한 후 즉시 번역된 오디오 재생을 위해 번역된 텍스트를 Amazon Polly로 보냅니다.

Amazon Polly: 완전 관리형 텍스트 음성 변환 API

마지막으로 번역된 텍스트를 Amazon Polly로 전송합니다. 이 서비스는 즉각적인 스트리밍 재생을 위해 생생한 오디오 클립 응답을 다시 보내거나 일괄 처리하여 저장할 수 있는 완전 관리형 텍스트 음성 변환 서비스입니다. 아마존 단순 스토리지 서비스 (Amazon S3) 나중에 사용할 수 있습니다. 표준화된 기능을 사용하여 발음, 음량, 높낮이, 말 속도 등의 다양한 음성을 제어할 수 있습니다. 음성 합성 마크업 언어 (SSML).

특정 Amazon Polly에 대한 음성을 합성할 수 있습니다. 신경 음성 뉴스 캐스터 스타일을 사용하여 TV 또는 라디오 뉴스 캐스터처럼 들리도록 합니다. 또한 오디오 스트림에 포함된 메타데이터를 기반으로 텍스트의 특정 단어나 문장이 언제 말하는지 감지할 수 있습니다. 이를 통해 개발자는 합성된 음성과 함께 아바타의 입술 움직임과 같은 그래픽 강조 표시 및 애니메이션을 동기화할 수 있습니다.

회사 이름, 두문자어, 외래어 또는 신조어와 같은 특정 단어의 발음을 수정할 수 있습니다(예: "P!nk", "ROTFL" 또는 "C'est la vie"(비 프랑스어로 말할 때) 음성), 사용자 지정 어휘를 사용합니다.

아키텍처 개요

다음 다이어그램은 솔루션 아키텍처를 보여줍니다.

이 다이어그램은 클라이언트 디바이스에서 Amazon Transcribe, Amazon Translate 및 Amazon Polly로의 데이터 흐름을 보여줍니다.

워크플로는 다음과 같습니다.

  1. 오디오는 Python SDK에서 수집됩니다.
  2. Amazon Polly는 음성을 39가지 가능한 언어로 텍스트로 변환합니다.
  3. Amazon Translate는 언어를 변환합니다.
  4. Amazon Live Transcribe는 텍스트를 음성으로 변환합니다.
  5. 오디오가 스피커로 출력됩니다.

사전 조건

마이크, 스피커 및 안정적인 인터넷 연결이 설정된 호스트 시스템이 필요합니다. 추가 하드웨어가 필요하지 않기 때문에 최신 노트북은 이 작업에 적합합니다. 다음으로 몇 가지 소프트웨어 도구로 기계를 설정해야 합니다.

비동기 Amazon Transcribe 스트리밍 SDK를 사용하고 Python 모듈에 대해 Python 3.7 이상이 설치되어 있어야 합니다. pyaudio, 기기의 마이크와 스피커를 제어하는 ​​데 사용합니다. 이 모듈은 portaudio.h. 문제가 발생하면 pyaudio 오류가 있는 경우 OS를 확인하여 오류가 있는지 확인하는 것이 좋습니다. portaudio.h 라이브러리가 설치되었습니다.

서비스 호출의 권한 부여 및 인증을 위해 다음을 생성합니다. AWS 자격 증명 및 액세스 관리 (IAM) 필요한 AWS 서비스를 호출할 수 있는 권한이 있는 서비스 역할. 구성하여 AWS 명령 줄 인터페이스 (AWS CLI) 이 IAM 서비스 역할을 사용하면 AWS 라이브러리가 구성된 AWS CLI 사용자의 자격 증명을 사용하도록 작성되기 때문에 키나 암호를 전달할 필요 없이 시스템에서 스크립트를 실행할 수 있습니다. 이것은 신속한 프로토타이핑을 위한 편리한 방법이며 인증된 ID로 서비스를 호출하도록 합니다. 항상 그렇듯이 IAM 사용자 또는 역할을 생성할 때 IAM 정책을 할당할 때 최소 권한 원칙을 따르십시오.

요약하자면 다음과 같은 전제 조건이 필요합니다.

  • 마이크, 스피커 및 인터넷 연결이 가능한 PC, Mac 또는 Linux 시스템
  • XNUMXD덴탈의 portaudio.h paudio가 작동하는 데 필요한 OS용 C 라이브러리(brew, apt get, wget)
  • AWS CLI에서 aws configure를 실행하여 구성된 적절하게 승인된 IAM 사용자가 있는 AWS CLI 2.0
  • Python 3.7 이상
  • 비동기식 Amazon Transcribe Python SDK
  • 다음 Python 라이브러리:
    • boto3
    • amazon-transcribe
    • pyaudio
    • asyncio
    • concurrent

솔루션 구현

시작점으로 Python용 비동기 Amazon Transcribe 스트리밍 SDK에 크게 의존하고 해당 특정 SDK를 기반으로 구축할 것입니다. Python용 스트리밍 SDK를 실험한 후 다음을 추가합니다. 스트리밍 마이크 를 사용하여 입력 pyaudio, 오디오 데이터 조작에 사용되는 일반적으로 사용되는 Python 오픈 소스 라이브러리입니다. 그런 다음 번역 및 텍스트 음성 변환 기능을 위해 Amazon Translate 및 Amazon Polly에 Boto3 호출을 추가합니다. 마지막으로 다음을 사용하여 컴퓨터 스피커를 통해 번역된 음성을 다시 스트리밍합니다. pyaudio. 파이썬 모듈 concurrent 자체 비동기 스레드에서 차단 코드를 실행하여 반환된 Amazon Polly 음성을 끊김 없는 비차단 방식으로 재생할 수 있는 기능을 제공합니다.

필요한 모든 모듈을 가져오고 스트리밍 클래스를 변환하고 일부 전역을 인스턴스화해 보겠습니다.

import boto3
 import asyncio
 import pyaudio
 import concurrent
 from amazon_transcribe.client import TranscribeStreamingClient
 from amazon_transcribe.handlers import TranscriptResultStreamHandler
 from amazon_transcribe.model import TranscriptEvent


 polly = boto3.client('polly', region_name = 'us-west-2')
 translate = boto3.client(service_name='translate', region_name='us-west-2', use_ssl=True)
 pa = pyaudio.PyAudio()

 #for mic stream, 1024 should work fine
 default_frames = 1024

 #current params are set up for English to Mandarin, modify to your liking
 params['source_language'] = "en"
 params['target_language'] = "zh"
 params['lang_code_for_polly'] = "cmn-CN"
 params['voice_id'] = "Zhiyu"
 params['lang_code_for_transcribe'] = "en-US"

먼저 pyaudio 입력 장치의 샘플링 속도, 장치 인덱스 및 채널 수를 얻으려면:

#try grabbing the default input device and see if we get lucky
 default_indput_device = pa.get_default_input_device_info()

 # verify this is your microphone device 
 print(default_input_device)

 #if correct then set it as your input device and define some globals
 input_device = default_input_device

 input_channel_count = input_device["maxInputChannels"]
 input_sample_rate = input_device["defaultSampleRate"]
 input_dev_index = input_device["index"]

이것이 작동하지 않으면 다음 코드와 같이 장치를 반복하고 인쇄한 다음 장치 색인을 사용하여 장치 정보를 검색할 수도 있습니다. pyaudio:

print ("Available devices:n")
 for i in range(0, pa.get_device_count()):
     info = pa.get_device_info_by_index(i)
     print (str(info["index"])  + ": t %s n t %s n" % (info["name"], p.get_host_api_info_by_index(info["hostApi"])["name"]))

 # select the correct index from the above returned list of devices, for example zero
 dev_index = 0 
 input_device = pa.get_device_info_by_index(dev_index)

 #set globals for microphone stream
 input_channel_count = input_device["maxInputChannels"]
 input_sample_rate = input_device["defaultSampleRate"]
 input_dev_index = input_device["index"]

너는 사용한다 channel_count, sample_ratedev_index 마이크 스트림의 매개변수로. 해당 스트림의 콜백 함수에서 다음을 사용합니다. asyncio 마이크 스트림의 입력 바이트를 asyncio 입력 큐. 다음으로 생성된 루프 및 input_queue 객체를 기록해 두십시오. asyncio 다음 코드에서 사용되는 방법:

async def mic_stream():
     # This function wraps the raw input stream from the microphone forwarding
     # the blocks to an asyncio.Queue.
     
     loop = asyncio.get_event_loop()
     input_queue = asyncio.Queue()
     
     def callback(indata, frame_count, time_info, status):
         loop.call_soon_threadsafe(input_queue.put_nowait, indata)
         return (indata, pyaudio.paContinue)
         
     # Be sure to use the correct parameters for the audio stream that matches
     # the audio formats described for the source language you'll be using:
     # https://docs.aws.amazon.com/transcribe/latest/dg/streaming.html
     
     print(input_device)
     
     #Open stream
     stream = pa.open(format = pyaudio.paInt16,
                 channels = input_channel_count,
                 rate = int(input_sample_rate),
                 input = True,
                 frames_per_buffer = default_frames,
                 input_device_index = input_dev_index,
                 stream_callback=callback)
     # Initiate the audio stream and asynchronously yield the audio chunks
     # as they become available.
     stream.start_stream()
     print("started stream")
     while True:
         indata = await input_queue.get()
         yield indata

이제 생성기 기능이 mic_stream() 가 호출되면 입력 대기열에 마이크 입력 데이터가 있는 한 계속해서 입력 바이트를 생성합니다.

이제 마이크에서 입력 바이트를 가져오는 방법을 알았으므로 Amazon Polly 출력 오디오 바이트를 스피커 출력 스트림에 쓰는 방법을 살펴보겠습니다.

#text will come from MyEventsHandler
 def aws_polly_tts(text):

     response = polly.synthesize_speech(
         Engine = 'standard',
         LanguageCode = params['lang_code_for_polly'],
         Text=text,
         VoiceId = params['voice_id'],
         OutputFormat = "pcm",
     )
     output_bytes = response['AudioStream']
     
     #play to the speakers
     write_to_speaker_stream(output_bytes)
     
 #how to write audio bytes to speakers

 def write_to_speaker_stream(output_bytes):
     """Consumes bytes in chunks to produce the response's output'"""
     print("Streaming started...")
     chunk_len = 1024
     channels = 1
     sample_rate = 16000
     
     if output_bytes:
         polly_stream = pa.open(
                     format = pyaudio.paInt16,
                     channels = channels,
                     rate = sample_rate,
                     output = True,
                     )
         #this is a blocking call - will sort this out with concurrent later
         while True:
             data = output_bytes.read(chunk_len)
             polly_stream.write(data)
             
         #If there's no more data to read, stop streaming
             if not data:
                 output_bytes.close()
                 polly_stream.stop_stream()
                 polly_stream.close()
                 break
         print("Streaming completed.")
     else:
         print("Nothing to stream.")

이제 게시물에서 구축한 내용을 확장해 보겠습니다. Python용 비동기 Amazon Transcribe 스트리밍 SDK. 다음 코드에서는 다음을 사용하여 실행기 개체를 만듭니다. ThreadPoolExecutor 세 명의 작업자가 동시에 있는 하위 클래스. 그런 다음 EventHandler에서 최종 반환된 트랜스크립트에 Amazon Translate 호출을 추가하고 번역된 텍스트, 실행기 객체 및 aws_polly_tts() 로 기능하다 asyncio 루프 loop.run_in_executor(), 다음 반복 시작 시 Amazon Polly 함수(번역된 입력 텍스트 포함)를 비동기식으로 실행합니다. asyncio 고리.

#use concurrent package to create an executor object with 3 workers ie threads
 executor = concurrent.futures.ThreadPoolExecutor(max_workers=3)

 class MyEventHandler(TranscriptResultStreamHandler):
     async def handle_transcript_event(self, transcript_event: TranscriptEvent):

         #If the transcription is finalized, send it to translate
 
         results = transcript_event.transcript.results
         if len(results) > 0:
             if len(results[0].alternatives) > 0:
                 transcript = results[0].alternatives[0].transcript
                 print("transcript:", transcript)

                 print(results[0].channel_id)
                 if hasattr(results[0], "is_partial") and results[0].is_partial == False:
                     
                     #translate only 1 channel. the other channel is a duplicate
                     if results[0].channel_id == "ch_0":
                         trans_result = translate.translate_text(
                             Text = transcript,
                             SourceLanguageCode = params['source_language'],
                             TargetLanguageCode = params['target_language']
                         )
                         print("translated text:" + trans_result.get("TranslatedText"))
                         text = trans_result.get("TranslatedText")

                         #we run aws_polly_tts with a non-blocking executor at every loop iteration
                         await loop.run_in_executor(executor, aws_polly_tts, text)  

마지막으로, 우리는 loop_me() 기능. 그것에서 당신은 정의 write_chunks(), Amazon Transcribe 스트림을 인수로 사용하고 스트리밍 마이크 입력 청크를 비동기식으로 씁니다. 당신은 다음 사용 MyEventHandler() 출력 전사 스트림을 인수로 사용하여 처리기 개체를 만듭니다. 그런 다음 await를 사용합니다. asyncio.gather() 그리고 이러한 코루틴의 궁극적인 미래를 처리하기 위해 handle_events() 메서드를 사용하여 write_chunks() 및 핸들러를 전달합니다. 마지막으로 모든 이벤트 루프를 수집하고 루프 loop_me() 기능 run_until_complete(). 다음 코드를 참조하십시오.

async def loop_me():
 # Setup up our client with our chosen AWS region

     client = TranscribeStreamingClient(region="us-west-2")
     stream = await client.start_stream_transcription(
         language_code=params['lang_code_for_transcribe'],
         media_sample_rate_hz=int(device_info["defaultSampleRate"]),
         number_of_channels = 2,
         enable_channel_identification=True,
         media_encoding="pcm",
     )
     recorded_frames = []
     async def write_chunks(stream):
         
         # This connects the raw audio chunks generator coming from the microphone
         # and passes them along to the transcription stream.
         print("getting mic stream")
         async for chunk in mic_stream():
             t.tic()
             recorded_frames.append(chunk)
             await stream.input_stream.send_audio_event(audio_chunk=chunk)
             t.toc("chunks passed to transcribe: ")
         await stream.input_stream.end_stream()

     handler = MyEventHandler(stream.output_stream)
     await asyncio.gather(write_chunks(stream), handler.handle_events())

 #write a proper while loop here
 loop = asyncio.get_event_loop()
 loop.run_until_complete(loop_me())
 loop.close()

앞의 코드가 오류 없이 함께 실행되면 마이크에 대고 말하면서 중국어로 번역된 음성을 빠르게 들을 수 있습니다. Amazon Transcribe 및 Amazon Translate의 자동 언어 감지 기능은 지원되는 모든 입력 언어를 대상 언어로 번역합니다. 꽤 오랜 시간 동안 말할 수 있으며 함수 호출의 비차단 특성 때문에 모든 음성 입력이 번역되고 말되므로 라이브 음성을 번역하는 데 탁월한 도구입니다.

결론

이 게시물은 이 세 가지 완전 관리형 AWS API가 어떻게 원활하게 함께 작동할 수 있는지 보여주었지만 현재 비용의 일부로 다국어 자막과 같은 서비스 또는 미디어에 대한 다국어 지원을 제공하기 위해 이러한 서비스를 다른 방식으로 사용할 수 있는 방법에 대해 생각해 보는 것이 좋습니다. . 의학, 비즈니스, 심지어 외교 관계까지도 지속적으로 개선되고 있는 저비용, 저유지 관리 번역 서비스의 이점을 누릴 수 있습니다.

이 사용 사례의 개념 증명 코드 기반에 대한 자세한 내용은 다음을 확인하십시오. 깃허브.


저자에 관하여

마이클 트란 Amazon Web Services의 Envision Engineering 팀의 솔루션 설계자입니다. 그는 기술 지침을 제공하고 AWS에서 가능성의 예술을 보여줌으로써 고객이 혁신 능력을 가속화하도록 돕습니다. 그는 고객을 위해 AI/ML 및 IoT를 중심으로 여러 프로토타입을 구축했습니다. Twitter에서 @Mike_Trann에게 연락할 수 있습니다.

카메론 윌크스 AWS Industry Accelerator 팀의 프로토타입 설계자입니다. 팀에 있는 동안 그는 고객에게 여러 ML 기반 프로토타입을 제공하여 AWS에서 ML의 "가능성의 기술"을 보여주었습니다. 그는 음악 제작, 오프로드, 디자인을 즐깁니다.

spot_img

최신 인텔리전스

spot_img