メインコンテンツに移動
コミュニティ通信

Amazon Translate を使って自作音声翻訳サイトを作る

2023-07-03 | Author : 松井 英俊 (AWS Serverless HERO / JAWS-UG 浜松支部)

はじめに

こんにちは ! 株式会社スタートアップテクノロジー テックリード、 AWS Serverless HERO の松井です !

突然ですが、ビジネスや旅行などで突然外国語でコミュニケーションを取らなければならなくなり、困ったことはありませんか ? そんな問題を解決するために、今回は Amazon Translate を使ってお手軽に 自作音声翻訳サイトを作る 方法をご紹介します !


X ポスト » | Facebook シェア » | はてブ »

ご注意

本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。

*ハンズオン記事およびソースコードにおける免責事項 »

builders.flash メールメンバー登録

builders.flash メールメンバー登録で、毎月の最新アップデート情報とともに、AWS を無料でお試しいただけるクレジットコードを受け取ることができます。

今すぐ登録 »

1. 必要要件

下記サービスの有効なアカウント

  • AWS

  • GitHub

AWS CDK の動作環境 : バージョン: 2.79.1

数十〜数百円程度の AWS 利用料

2. 注意事項

今回のハンズオンで構築する Web API はインターネットにオープンになります。実際にアプリケーションに組み込む際などは、意図的にオープンにする目的がない限り Amazon CognitoAWS Amplify などを組み合わせる、または自前の認証機能を構築するなどして、トークン検証等の仕組みをセットにして使用することを推奨します。

同じくオープンな Web API である性質上、公開したままにしておくと第三者による利用等により思わぬ高額請求が発生する可能性があります。動作確認後はできるだけ速やかに API を削除することを推奨します。

3. Amazon Translate とは ?

公式ページ にもあるとおり、 AWS が提供する深層学習モデルを使用して、従来の統計ベースやルールベースの翻訳アルゴリズムよりも正確で自然な翻訳を提供する言語翻訳自動化のサービスです。

AWS マネジメントコンソールからサービスを利用できる他、 AWS SDK を通してプログラムから呼び出すことで、自前のアプリケーションに簡単に翻訳機能を組み込むこともできます。

4. アーキテクチャ

動作フロー

  1. AWS Amplify Console でホスティングした翻訳インターフェースとなる静的 Web ページ (以下、翻訳ページと呼ぶ) に、Web ブラウザからアクセスします。

  2. 翻訳ページの設定画面で翻訳元と翻訳先の言語を選択します。

  3. 翻訳ページで翻訳元に設定した言語で話すと、ブラウザの SpeechRecognition API で話した内容が文字起こしされます。

  4. 文字起こししたテキストと翻訳元と翻訳先の言語コードを、 Amazon API Gateway 経由で AWS Lambda 関数に送信します。

  5. Lambda 関数は受け取ったパラメータから、 Amazon Translate を使って翻訳し、翻訳ページに結果を返します。

  6. Web ブラウザが結果を受け取り、翻訳結果を表示します。

この 3~6 の動作を、 SpeechRecognition API の continuous パラメータを true とすることで繰り返し実行するため、短い文章ごとに区切って話せば、続けて喋りながらリアルタイムに翻訳結果を受け取ることができます。

全体図

5. 構築手順

5-1. 環境セットアップ

AWS CDK (Cloud Development Kit) が動作する環境を構築しましょう。
すでにお手元に CDK が動作する環境がある場合は必要ありませんが、 AWS Cloud9 を使ってローカル環境に依存しないハンズオン環境を構築していただくことも可能です。
その場合、 こちらの記事 を参考にしていただくとスムーズかと思います。

同記事にて ディスクサイズ拡張 の方法も記載しておりますので、こちらも忘れず実施しましょう。

AWS Cloud9 が利用できない場合、こちらのブログ をご参考に AWS IDE Toolkits または AWS CloudShell をご利用ください。

AWS Cloud9 から AWS IDE Toolkits または AWS CloudShell に移行する方法 »

5-2. API の構築

まずは、今回の機能の根幹になる Web API を構築していきます。
併せて、ソースコードも解説していきます。

リポジトリをクローン

下記コマンドを実行し、リポジトリをクローンします。

bash
git clone git@github.com:matsuihidetoshi/translate-function.git

lib/translate-function-stack.ts について

Web API リソース構築スクリプトの、 lib/translate-function-stack.ts から解説していきます。

typescript
import { Stack, StackProps, Duration } from 'aws-cdk-lib'
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'
import { RestApi, Model, JsonSchemaType, Cors } from 'aws-cdk-lib/aws-apigateway'
import { LambdaIntegration } from 'aws-cdk-lib/aws-apigateway'
import { Runtime } from 'aws-cdk-lib/aws-lambda'
import { Construct } from 'constructs'
import { PolicyStatement } from 'aws-cdk-lib/aws-iam'

export class TranslateFunctionStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props)

    // ① Lambda 関数の作成
    const translateFunction = new NodejsFunction(this, 'translate-function', {
      runtime: Runtime.NODEJS_18_X,
      functionName: 'translateFunction',
      entry: 'src/translate-function.handler.ts',
      timeout: Duration.seconds(60),
      logRetention: 30,
    })

    // ② Amazon Translate を操作するためのポリシーをアタッチ
    translateFunction.addToRolePolicy(
      new PolicyStatement({
        resources: ['*'],
        actions: ['translate:TranslateText'],
      })
    )

    // ③ API Gateway の REST API を作成
    const restApi = new RestApi(this, 'translate-function-rest-api', {
      restApiName: 'RestApiForTranslateFunction',
      deployOptions: {
        stageName: 'v1',
      },
    })

    // ④ リソースの追加と CORS の設定
    const restApiTranslateResource = restApi.root.addResource('translate', {
      defaultCorsPreflightOptions: {
        allowOrigins: Cors.ALL_ORIGINS,
        allowMethods: Cors.ALL_METHODS,
        allowHeaders: Cors.DEFAULT_HEADERS,
        statusCode: 200,
      },
    })

    // ⑤リクエストパラメータのモデルの作成
    const translateModel: Model = restApi.addModel('translateModel', {
      schema: {
        type: JsonSchemaType.OBJECT,
        properties: {
          text: {
            type: JsonSchemaType.STRING,
          },
          translateFrom: {
            type: JsonSchemaType.STRING,
          },
          translateTo: {
            type: JsonSchemaType.STRING,
          },
        },
        required: ['text', 'translateFrom', 'translateTo'],
      },
    })

    // ⑥ REST API と Lambda 関数の統合
    restApiTranslateResource.addMethod('POST', new LambdaIntegration(translateFunction), {
      requestModels: { 'application/json': translateModel },
    })
  }
}

lib/translate-function-stack.ts 内の解説

①で、Lambda 関数を作成しています。

  • NodejsFunction クラスを使用して、 Lambda の関数コード src/ivs-viewers-count-function.handler.tsentry に指定しています。これにより、 TypeScript のコードをデプロイ時に自動的にトランスパイルしてくれます。

②で、Amazon Translate を操作するためのポリシーをアタッチしています。

③で、Lambda 関数を外部からのリクエストをトリガーに呼び出すための REST API を作成しています。

④で、/translate というパスのリソースの追加と CORS の設定をしています。

  • CORS の設定をしないと、後に構築する Web ページ側からのリクエストに失敗します。

  • 今回はデモのため全ての Origin からのリクエストを許可していますが実際にアプリケーションに組み込む場合は必要に応じて Origin を制限するようにしましょう。

⑤で、リクエストパラメータのモデルを作成しています。

  • ここでの text, translateFrom, translateTo といったプロパティが、 Web API リクエスト時の POST メソッドのパラメータと対応します。

⑥で、REST API と Lambda 関数を統合しています。

  • 翻訳文字数が多くなる可能性もあるので、文字数制限の厳しい GET メソッドではなく POST メソッドを受け付けるようにしています。

src/translate-function.handler.ts について

続いて、Lambda 関数コード src/translate-function.handler.ts を解説していきます。

typescript
import { Translate } from 'aws-sdk'
import { APIGatewayProxyEvent } from 'aws-lambda'

const translate = new Translate()

export const handler = async (event: APIGatewayProxyEvent) => {
  try {

    // ①リクエストパラメータの受け取りと翻訳パラメータの組み立て
    const requestBody = JSON.parse(event.body || '{"text": "", "translateFrom": "", "translateTo": ""}') as {
      text: string
      translateFrom: string
      translateTo: string
    }
    const Text = requestBody.text
    const SourceLanguageCode = requestBody.translateFrom
    const TargetLanguageCode = requestBody.translateTo

    const translateParams = {
      Text,
      SourceLanguageCode,
      TargetLanguageCode,
    }

    // ②翻訳
    const translatedText = await translate.translateText(translateParams).promise()

    // ③クライアントへレスポンス
    return {
      statusCode: 200,
      headers: {
        'Access-Control-Allow-Headers': 'Content-Type',
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'POST',
      },
      body: JSON.stringify({ translatedText }),
    }
  } catch (error) {
    return {
      statusCode: 500,
      body: JSON.stringify({ error }),
    }
  }
}

src/translate-function.handler.ts 内の解説

①で、REST API から受け取ったパラメータを使用して、 Amazon Translate に渡すパラメータを組み立てています。

②で、実際に Amazon Translate で翻訳しています。

③で、翻訳ページにレスポンスします。

デプロイ

実際に Web API をデプロイします。

bash
cdk bootstrap #AWS アカウント内で一度も CDK を使用していない場合、実行します。
cdk deploy

y を選択

下記の通り質問されるので、y を入力して Enter を押下してください。

bash
Do you wish to deploy these changes (y/n)? y

出力内容を保存

デプロイが成功したら下記のように出力されるので、= に続く REST API のエンドポイントを控えます (後から AWS マネジメントコンソールで確認することもできます)。

bash
Outputs:
TranslateFunctionStack.translatefunctionrestapiEndpoint******** = https://**********.execute-api.ap-northeast-1.amazonaws.com/v1/

5-3. 翻訳ページの作成

続いて、翻訳ページを作成していきます。
こちらもソースコードの解説も併せてしていきます。

リポジトリをクローン

下記コマンドを実行し、リポジトリをクローンします。

bash
git clone git@github.com:matsuihidetoshi/voice-transcript.git

リポジトリをクローン

ソースコードを解説します。

ソースコードの解説

①で、翻訳元、翻訳先の言語を選択するプルダウンを作成しています。

  • SpeechRecognition API は ar-SA のような形式で言語コードを受け付ける一方で、 Amazon Translate は ar のような形式と ar-SA のような形式が混在した形で言語コードを受け取るので、今回は value 属性に ar, ar-SA のようなカンマ区切りの形式でそれぞれの言語コードを記述しています。

②の箇所に翻訳結果が表示されます。

③で、ボタンの押下と共に文字起こしと翻訳がスタートします。

  • プルダウンで選択した翻訳元の言語コードを受け取って SpeechRecognition API に文字起こしする言語を渡しています。

  • 設定画面と翻訳画面の表示切り替えも行なっています。

④で、文字起こしをトリガーにして逐次翻訳 API にリクエストを送信しています。

⑤で、実際に翻訳 API にリクエストを送信しています。

  • option 要素の value 属性の形式が先ほどの①の通りの形式になっているので , で分割して取得したものを API にリクエストするパラメータに含めています。

⑥で翻訳 API にリクエストを送信しますが、ここに先ほど 5-2. API の構築 の一番最後に控えた API のエンドポイントを記述します。

解説にもあった通り、ソースコード上の REST API エンドポイントを書き換えます。


新しいリポジトリを作成します。
こちら の手順に従って新たなリポジトリを作成しましょう。

ソースコードを push

変更をコミットして新しいリポジトリにソースコードを push します。

bash
git add .
git commit -m 'Set REST API endpoint'
git remote set-url origin [新しいリポジトリのURL]
git push origin main

5-4. 翻訳ページのデプロイ

今回はフレームワークやライブラリを使用しない非常にシンプルな HTML + JavaScript の単一ファイルの Web ページですが、こちらを AWS Amplify を使ってホスティングします。

AWS マネジメントコンソールにログインします。

AWS Amplify を選択

AWS Amplify を選択します。

AWSコンソールのホーム画面を表示し、上部の検索バーでサービス名を検索、またはクリックしてAWS Amplifyなどのサービスを選択する手順を示した日本語の案内画像。

AWS Amplify の使用を開始

使用を開始する をクリックします。

Screenshot of a Japanese AWS Amplify documentation page, showing instructions for quickly and easily starting to develop scalable mobile or web applications, with a highlighted button and technology logos.

Amplify ホスティングの使用を開始

再度 Amplify ホスティング の 使用を開始する をクリックします。

Japanese-language visual guide describing how to get started with AWS Amplify Studio for application building and Amplify Hosting for web app hosting, featuring icons for JavaScript, Apple, and Android platforms, and instructions to click the '使用を開始する' (Start using) button.

GitHub を選択

GitHub を選択し 続行 をクリックします。

AWS Amplifyホスティングの開始方法を示す画面。既存のコードリポジトリからGitHubを選択し、右下の「続行」ボタンをクリックする手順が図示されている。

認証

このような画面が表示された場合、Authorize AWS Amplify をクリックします。

Screenshot showing the AWS Amplify (us-east-1) authorization screen on GitHub, with Japanese instructions indicating to click the green 'Authorize AWS Amplify (us-east-1)' button. This is part of the process to allow AWS Amplify Console to access a GitHub account.

GitHub アカウントを選択

自分の個人の GitHub アカウントをクリックします。

Screenshot showing the selection screen for installing AWS Amplify in the us-east-1 region, with a user account highlighted and a prompt in Japanese indicating 'click' to proceed.

インストール

Only select repositories を選択し、自分のリポジトリに push した先ほどの voice-transcript を選択し、Install & Authorize をクリックします。

Screenshot showing the process to install and authorize AWS Amplify (us-east-1) for the GitHub repository 'voice-transcript'. The interface highlights selecting only specific repositories, choosing 'voice-transcript', and clicking the 'Install & Authorize' button. Japanese annotations guide the user to select and click the appropriate options.

リポジトリを選択

先ほど選択したリポジトリをここでも選択し、他はそのままで 次へ をクリックします。

AWSのAmplifyコンソールでGitHubリポジトリ(voice-transcript)を選択し、mainブランチを指定して次に進む手順を表示した画面のスクリーンショット。

ビルドの設定

AWS Amplify がプロジェクトルートディレクトリでホストされているすべてのファイルを自動的にデプロイすることを許可 をチェックし、 次へ をクリックします。

AWSのAmplifyコンソールでGitHubリポジトリ(voice-transcript)を選択し、mainブランチを指定して次に進む手順を表示した画面のスクリーンショット。

デプロイ

保存してデプロイ をクリックします。

Screenshot showing the deployment screen for a 'voice-transcript' application setup, including repository details from GitHub and deployment button, with interface text in Japanese.

アプリケーションの URL をクリック

デプロイフローが開始されるので、 デプロイ のフェーズが完了するまで待ってから、アプリケーションの URL をクリックします。

Screenshot of the AWS Amplify console in Japanese, showing the deployment status for a voice transcription web app. Visual indicators highlight the deploy step and provide instructions to click the app URL to confirm deployment completion.

成功 !

このような画面が表示されれば成功です!

Screenshot of a voice translation website interface displaying language selection menus with options to translate from and to Arabic, and a 'Start translation' button.

5-5. 動作確認

実際に動作確認してみましょう !

言語選択して、翻訳をスタート

Translate from (翻訳元の言語)Translate to (翻訳先の言語) を選択し、 Start translation をクリックします。

Screenshot of a voice translation website showing dropdowns to choose languages from Japanese to Italian and a 'Start translation' button, with Japanese annotations highlighting 'select' and 'click'.

成功 !

翻訳元として選択した言語で話してみて、翻訳が出てきたら成功です!

Screenshot of a voice translation website displaying the Italian translation 'Voglio mangiare la pasta oggi' (I want to eat pasta today), with text prompts 'Speak!', 'translation:', and a 'Restart' button.

6. 構成の削除

そのまま残していただいても構いませんが、冒頭の注意事項の通り思わぬ請求が発生する可能性もありますので、削除手順を記載します。

先ほどの Amplify ホスティングのページにて、 アクション > アプリの削除 を選択します。

Screenshot of the AWS Amplify hosting environment page in Japanese for a voice transcript app, showing main deployment details, hosting status, and an option to delete the app.

削除

削除 を入力して、 削除 をクリックします。

アプリを削除する際の確認ダイアログ画面を示す日本語のスクリーンショットです。「削除」と入力し、削除ボタンを押す手順がハイライトされています。

Web API の削除

最後に、 CDK で管理している Web API を削除します。

bash
cdk destroy

y を入力して Enter

下記のように質問されるので、 y を入力して Enter を押下します。 これで削除も完了です !

bash
Are you sure you want to delete: TranslateFunctionStack (y/n)? y

7. まとめ

いかがでしたでしょうか ?
Amazon Translate を AWS SDK で使用した私の感想ですが、思ったよりもずっと早くレスポンスが返ってきたので、色々なアプリケーションに組み込んで応用しやすそうだなと感じました ! みなさんもぜひ活用してみてください !

Happy Coding !

筆者プロフィール

松井 英俊 (まつい ひでとし)
株式会社スタートアップテクノロジー テックリード
JAWS-UG 浜松支部 運営メンバー

JAWS DAYS 2021 re:Connect、JAWS PANKRATION 2021 -Up till Down- では実行委員を務め、配信サイトを構築した。
2021 年 6 月、 AWS Serverless HERO に選ばれる。

An outdoor portrait of a man with medium-length hair and a beard, standing near water with a red torii gate in the background. The image is bright and colorful, and the man is wearing a white t-shirt with a bold graphic design.

言語選択して、翻訳をスタート

翻訳元として選択した言語で話してみて、翻訳が出てきたら成功です!

Screenshot of a voice translation website showing dropdowns to choose languages from Japanese to Italian and a 'Start translation' button, with Japanese annotations highlighting 'select' and 'click'.