Amazon Transcribe、Amazon Translate、Amazon Polly PlatoBlockchainDataIntelligenceで言語の壁を打ち破ります。 垂直検索。 愛。

Amazon Transcribe、Amazon Translate、AmazonPollyで言語の壁を打ち破る

人間の通訳を必要とせずに、世界中の患者とビデオ通話をしている外科医を想像してみてください。 新興の新興企業が、流動的で正確な多言語の顧客サポートと販売を提供することで、実際の人間の翻訳者を必要とせずに、国境を越えて新しい地理的市場に製品を簡単に拡大できるとしたらどうでしょうか。 言語に縛られなくなったとき、あなたのビジネスはどうなりますか?

今日では、さまざまな言語を話す国際的なチームや顧客と仮想会議を開くのが一般的です。 社内会議であろうと社外会議であろうと、複雑な話し合いでは意味が失われることが多く、言葉の壁に遭遇して、自分ができる限り効果的になることができなくなる可能性があります。

この投稿では、XNUMXつのフルマネージドAWSサービス(Amazon Transcribe, Amazon翻訳, Amazon Polly)ソーススピーカーのライブ音声入力を、機械学習(ML)の経験がまったくなくても、話された正確な翻訳済みのターゲット言語にすばやく翻訳できる、ほぼリアルタイムの音声から音声への翻訳ソリューションを作成します。

ソリューションの概要

私たちのトランスレーターは、XNUMXつのフルマネージドAWS MLサービスで構成されており、 AWS SDK for Python(Boto3) テキスト翻訳とテキスト読み上げの部分、および音声入力の文字起こし用の非同期ストリーミングSDK用。

Amazon Transcribe:音声をテキストにストリーミング

スタックで最初に使用するサービスはAmazonTranscribeです。これは、入力音声を受け取り、それをテキストに変換する、フルマネージドの音声テキストサービスです。 Amazon Transcribeは、保存されたオーディオファイルまたはストリーミングオーディオデータのいずれかを受け入れるため、バッチまたはストリーミングの柔軟な取り込み方法を備えています。 この投稿では、 Python用の非同期AmazonTranscribeストリーミングSDK、HTTP / 2ストリーミングプロトコルを使用してライブオーディオをストリーミングし、ライブトランスクリプションを受信します。

このプロトタイプを最初に作成したとき、Amazon Transcribeストリーミング取り込みは自動言語検出をサポートしていませんでしたが、2021年XNUMX月以降、これはサポートされなくなりました。バッチ取り込みとストリーミング取り込みの両方で、すべての自動言語検出がサポートされるようになりました。 サポートされている言語。 この投稿では、ストリーミング自動言語検出を使用することで、シームレスな多言語パラメーターレス設計によるパラメーターベースのソリューションがどのように可能になるかを示します。 音声文字変換された音声セグメントがテキストとして返された後、Amazon Translateにリクエストを送信して、結果を翻訳してAmazonTranscribeに返します。 EventHandler 方法。

Amazon Translate:最先端のフルマネージド翻訳API

次のスタックは、高速、高品質、手頃な価格、カスタマイズ可能な言語翻訳を提供するニューラル機械翻訳サービスであるAmazonTranslateです。 2022年75月の時点で、Amazon TranslateはXNUMXの言語にわたる翻訳をサポートしており、新しい言語ペアと改善が絶えず行われています。 Amazon Translateは、高度にスケーラブルで復元力のあるAWSクラウドアーキテクチャでホストされるディープラーニングモデルを使用して、ユースケースに応じて、リアルタイムまたはバッチで正確な翻訳を迅速に提供します。 Amazon Translateの使用は簡単で、基盤となるアーキテクチャやMLスキルを管理する必要はありません。 Amazon Translateには、作成や使用など、いくつかの機能があります。 カスタム用語 業界固有の用語間のマッピングを処理します。 Amazon Translateのサービス制限の詳細については、以下を参照してください。 ガイドラインと制限。 アプリケーションは、ターゲット言語で翻訳されたテキストを受信すると、翻訳されたテキストをAmazon Pollyに送信して、すぐに翻訳されたオーディオを再生します。

Amazon Polly:完全に管理されたテキスト読み上げAPI

最後に、翻訳されたテキストをAmazon Pollyに送信します。これは、フルマネージドのテキスト読み上げサービスであり、リアルなオーディオクリップ応答を返送してすぐにストリーミング再生するか、バッチ処理して保存することができます。 Amazon シンプル ストレージ サービス (Amazon S3)後で使用します。 標準化されたものを使用して、発音、音量、ピッチ、発話速度など、音声のさまざまな側面を制御できます。 音声合成マークアップ言語 (SSML)。

特定のAmazonPollyの音声を合成できます 神経の声 ニュースキャスタースタイルを使用して、テレビやラジオのニュースキャスターのように聞こえるようにします。 オーディオストリームに含まれるメタデータに基づいて、テキスト内の特定の単語または文がいつ話されているかを検出することもできます。 これにより、開発者は、アバターの唇の動きなど、グラフィックの強調表示やアニメーションを合成された音声と同期させることができます。

会社名、頭字語、外国語、造語などの特定の単語の発音を変更できます。たとえば、「P!nk」、「ROTFL」、「C'est lavie」(フランス語以外で話されている場合)などです。音声)、カスタムレキシコンを使用します。

アーキテクチャの概要

次の図は、ソリューションアーキテクチャを示しています。

この図は、クライアントデバイスからAmazon Transcribe、Amazon Translate、AmazonPollyへのデータフローを示しています。

ワークフローは次のとおりです。

  1. オーディオはPythonSDKによって取り込まれます。
  2. Amazon Pollyは、音声を39の可能な言語のテキストに変換します。
  3. AmazonTranslateは言語を変換します。
  4. Amazon Live Transcribeは、テキストを音声に変換します。
  5. 音声はスピーカーに出力されます。

前提条件

マイク、スピーカー、信頼性の高いインターネット接続を備えたホストマシンが必要です。 追加のハードウェアは必要ないため、最新のラップトップはこれに問題なく機能するはずです。 次に、いくつかのソフトウェアツールを使用してマシンをセットアップする必要があります。

非同期AmazonTranscribeストリーミングSDKを使用し、Pythonモジュールを使用するには、Python3.7以降がインストールされている必要があります。 pyaudio、マシンのマイクとスピーカーを制御するために使用します。 このモジュールは、と呼ばれるCライブラリに依存しています portaudio.h。 で問題が発生した場合 pyaudio エラーが発生した場合は、OSをチェックして、 portaudio.h ライブラリがインストールされています。

サービスコールの承認と認証のために、 AWS IDおよびアクセス管理 (IAM)必要なAWSサービスを呼び出す権限を持つサービスロール。 を構成することによって AWSコマンドラインインターフェイス (AWS CLI)このIAMサービスロールを使用すると、AWSライブラリは設定されたAWS CLIユーザーのクレデンシャルを使用するように作成されているため、キーやパスワードを渡さなくてもマシンでスクリプトを実行できます。 これはラピッドプロトタイピングに便利な方法であり、許可されたIDによってサービスが呼び出されていることを確認します。 いつものように、IAMユーザーまたはロールを作成するときにIAMポリシーを割り当てるときは、最小特権の原則に従ってください。

要約すると、次の前提条件が必要です。

  • マイク、スピーカー、インターネット接続を備えたPC、Mac、またはLinuxマシン
  •   portaudio.h pyaudioが機能するために必要なOS用のCライブラリ(brew、apt get、wget)
  • AWSCLIでawsconfigureを実行して設定された適切に承認されたIAMユーザーを使用したAWSCLI2.0
  • Python 3.7以降
  • 非同期のAmazonTranscribePython SDK
  • 次のPythonライブラリ:
    • boto3
    • amazon-transcribe
    • pyaudio
    • asyncio
    • concurrent

ソリューションを実装する

開始点として、Python用の非同期Amazon TranscribeストリーミングSDKに大きく依存し、その特定のSDKの上に構築します。 Python用のストリーミングSDKを試した後、次のように追加します。 ストリーミングマイク を使用して入力 pyaudio、オーディオデータの操作に使用される一般的に使用されるPythonオープンソースライブラリ。 次に、Boto3呼び出しをAmazonTranslateとAmazonPollyに追加して、翻訳とテキスト読み上げ機能を提供します。 最後に、翻訳された音声をコンピュータのスピーカーからもう一度ストリーミングします。 pyaudio。 Pythonモジュール concurrent 独自の非同期スレッドでブロッキングコードを実行して、返されたAmazonPollyスピーチをシームレスで非ブロッキングの方法で再生する機能を提供します。

必要なすべてのモジュールをインポートし、ストリーミングクラスを転写して、いくつかのグローバルをインスタンス化しましょう。

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_rate, dev_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() が呼び出されると、入力キューにマイク入力データがある限り、入力バイトが継続的に生成されます。

マイクから入力バイトを取得する方法がわかったので、AmazonPollyの出力オーディオバイトをスピーカーの出力ストリームに書き込む方法を見てみましょう。

#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トランスクリプトストリーミングSDK。 次のコードでは、を使用してエグゼキュータオブジェクトを作成します。 ThreadPoolExecutor 同時実行のXNUMX人のワーカーを持つサブクラス。 次に、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() 出力トランスクリプションストリームを引数として使用し、ハンドラオブジェクトを作成します。 次に、awaitwithを使用します asyncio.gather() そして、write_chunks()とhandlerをhandle_events()メソッドで渡して、これらのコルーチンの最終的な先物を処理します。 最後に、すべてのイベントループを収集し、 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()

上記のコードをエラーなしで一緒に実行すると、マイクに向かって話し、声が北京語に翻訳されているのをすばやく聞くことができます。 AmazonTranscribeおよびAmazonTranslateの自動言語検出機能は、サポートされている入力言語をターゲット言語に翻訳します。 あなたはかなり長い間話すことができます、そして関数呼び出しの非ブロッキングの性質のために、あなたのすべての音声入力は翻訳されて話されます、これはライブスピーチを翻訳するための優れたツールになります。

まとめ

この投稿では、これらXNUMXつのフルマネージドAWS APIがどのようにシームレスに機能するかを示しましたが、これらのサービスを他の方法で使用して、現在のコストの何分のXNUMXかで多言語のクローズドキャプションなどのサービスやメディアの多言語サポートを提供する方法を検討することをお勧めします。 医学、ビジネス、さらには外交関係さえも、常に改善され、低コストで、メンテナンスの少ない翻訳サービスの恩恵を受けることができます。

このユースケースの概念実証コードベースの詳細については、 githubの.


著者について

Amazon Transcribe、Amazon Translate、Amazon Polly PlatoBlockchainDataIntelligenceで言語の壁を打ち破ります。 垂直検索。 愛。マイケル・トラン アマゾンウェブサービスのエンビジョンエンジニアリングチームのソリューションアーキテクトです。 彼は技術的なガイダンスを提供し、AWSで可能な技術を示すことにより、顧客が革新する能力を加速するのを支援します。 彼は、AI / ML、およびお客様向けのIoTを中心に複数のプロトタイプを作成しました。 Twitterで@Mike_Trannに連絡してください。

Amazon Transcribe、Amazon Translate、Amazon Polly PlatoBlockchainDataIntelligenceで言語の壁を打ち破ります。 垂直検索。 愛。キャメロンウィルクス AWSIndustryAcceleratorチームのプロトタイピングアーキテクトです。 チームにいる間、彼はAWSでのMLの「アートオブザポッシブル」をデモンストレーションするために、いくつかのMLベースのプロトタイプを顧客に提供しました。 彼は音楽制作、オフロード、デザインを楽しんでいます。

タイムスタンプ:

より多くの AWS機械学習