Amazon Transcribeを調べてみた

# Amazon Transcribeとは

Amazon Transcribeは一言で言うと”Speech to Text”と呼ばれる、音声をテキスト情報に変換するサービスです。
話されている言語を機械学習の技術で識別し、テキスト情報に変換します。

この技術は以下のような新しいサービスやプロダクトの提供に役立ちます。

- 映像ファイルから音声を認識し、クローズドキャプションを生成
- コールセンター業務などでの問い合わせ内容の分析
- 医療分野や法律分野での活用

また、”Amazon Translate”や”Amazon Polly”と連携して、生成したテキスト情報を翻訳し、再度翻訳した言語で音声に変換することなどもできます。

# 何ができるのか

Amazon Transcribeには以下の3つのオペレーションがあります。

- StartTranscriptionJob : 非同期で音声をテキストに書き起こす
- ListTranscriptionJobs :  開始された音声認識ジョブのリストを返す。 返して欲しいJobをステータスで絞り込むことができる
- GetTranscriptionJob : 音声認識の結果を返す。結果にはJSON形式に変換された結果へのリンクが含まれている

## Speech Input

インプットするファイルはS3 bucketに保管されている必要があります。
インプットファイルの仕様は以下のみ

-  FLAC、MP3、MP4、WAV
- 尺は2時間未満

言語、フォーマット、サンプリングレートを指定する必要があります。

- PCM 16ビットエンコーディングのFLACやWAVなどのロスレスフォーマットを使用。
- サンプリングレートは8000 ~ 16000Hz

Amazon TranscribeのS3とその中のファイルへのアクセスを許可する必要があります。

## Output JSON

Jobが完了するとJSONが含まれた結果が生成され、テキストファイルがS3に置かれます。
ファイルのIDはユーザー固有のURIとなっており、そのURIを利用することで結果を取得できます。

Ex)

```json
 {
      "jobName":"job ID",
      "accountId":"account ID",
      "results": {
         "transcripts":[
            {
               "transcript":" that's no answer",
               "confidence":1.0
            }
         ],
         "items":[
            {
               "start_time":"0.180",
               "end_time":"0.470",
               "alternatives":[
                  {
                     "confidence":0.84,
                     "word":"that's"
                  }
               ]
            },
            {
               "start_time":"0.470",
               "end_time":"0.710",
               "alternatives":[
                  {
                     "confidence":0.99,
                     "word":"no"
                  }
               ]
            },
            {
               "start_time":"0.710",
               "end_time":"1.080",
               "alternatives":[
                  {
                     "confidence":0.874,
                     "word":"answer"
                  }
               ]
            }
         ]
      },
      "status":"COMPLETED"
   }
　
```

# 始め方

始めるにはAWSアカウント、ID、IAMユーザーが必要です。CLIの利用も可能です。

## Step.1 AWSアカウント設定

いつも通りなので割愛

## Step.2 CLI設定

いつも通りなので割愛

## Step.3 コンソールでの利用開始
### Jobの作成

1.各種情報の入力
　- Transcription job name : AWSアカウント毎にユニークである必要がある
　- Amazon s3 input URL： 音声ファイルが格納されているS3 busket。**Transcribeと同一リージョンである必要がある**
　- Language：インプットファイルの言語を選択
　- Format：インプットファイルのフォーマットを選択
　- Media sampling rate(Hz)：インプットファイルのサンプリングレートを8000 ~ 48000Hzの間で指定。8000~16000Hzが推奨
2.「Create」を押す

### Jobの確認

Jobのリストを表示。「Availability」にサーバーに結果が保管される残り期間が表示される。**結果の保管期間は90日**。
Jobをクリックすると、詳細(Job名、残りの保管期間、I/OのファイルのS3パス)と結果の文字列が表示される。
「Code Samples」で該当JobについてのJSONファイルを取得可能

## Step.4 API
### CLI
#### Transcribeのテストをする場合
1.InputファイルをS3 バケットに配置する(Transcribeと同じリージョンに)
2. ファイル情報を含んだJSONファイルを作成する

```json
{
    "TranscriptionJobName": "request ID", 
    "LanguageCode": "en-US", 
    "MediaFormat": "wav", 
    "Media": {
        "MediaFileUri": "https://S3 endpoint/test-transcribe/answer2.wav"
    }
}
```

3.下記コマンドを実行
```json
aws transcribe start-transcription-job \
     --endpoint-url endpoint \
     --region region \
     --cli-input-json file://test-start-command.json 
```

・下記レスポンスが返れば成功
```json

{
    "TranscriptionJob": {
        "TranscriptionJobName": "request ID",
        "LanguageCode": "en-US",
        "TranscriptionJobStatus": "IN_PROGRESS",
        "Media": {
            "MediaFileUri": "https://S3 endpoint/test-transcribe/answer2.wav"
        },
        "CreationTime": timestamp,
        "MediaFormat": "wav"
    }
}
```

#### Jobのリストを取得
1.Jobが完了していた場合、下記コマンドでステータスを取得する

```json
aws transcribe get-transcription-job-results \
   --endpoint-url endpoint \
   --region endpoint \
   --request-id "DocTest-01"
```

・成功すればレスポンスは下記通り返ってくる

```json
{
    "TranscriptionJob": {
        "TranscriptionJobName": "request ID",
        "LanguageCode": "en-US",
        "TranscriptionJobStatus": "COMPLETED",
        "Media": {
            "MediaFileUri": "input URI"
        },
        "CreationTime": timestamp,
        "CompletionTime": timestamp,
        "Transcript": {
            "TranscriptFileUri": "output URI"
        }
    }
}
```json

2.Output URIを使って翻訳されたテキストを取得

```json
{
      "jobName":"job ID",
      "accountId":"account ID",
      "results": {
         "transcripts":[
            {
               "transcript":" that's no answer",
               "confidence":1.0
            }
         ],
         "items":[
            {
               "start_time":"0.180",
               "end_time":"0.470",
               "alternatives":[
                  {
                     "confidence":0.84,
                     "word":"that's"
                  }
               ]
            },
            {
               "start_time":"0.470",
               "end_time":"0.710",
               "alternatives":[
                  {
                     "confidence":0.99,
                     "word":"no"
                  }
               ]
            },
            {
               "start_time":"0.710",
               "end_time":"1.080",
               "alternatives":[
                  {
                     "confidence":0.87,
                     "word":"answer"
                  }
               ]
            }
         ]
      },
      "status":"COMPLETED"
   }
```
### SDK for Python(Boto)
・InputファイルをS3 バケットに配置する(Transcribeと同じリージョンに)。ファイル情報を含んだJSONファイルを作成する

```python
from __future__ import print_function
import time
import boto3
transcribe = boto3.client('transcribe')
job_name = "job name"
job_uri = "https://S3 endpoint/test-transcribe/answer2.wav"
transcribe.start_transcription_job(
    TranscriptionJobName=job_name,
    Media={'MediaFileUri': job_uri},
    MediaFormat='wav',
    LanguageCode='en-US'
)
while True:
    status = transcribe.get_transcription_job(TranscriptionJobName=job_name)
    if status['TranscriptionJob']['TranscriptionJobStatus'] in ['COMPLETED', 'FAILED']:
        break
	print("Not ready yet...")
    time.sleep(5)
print(status)
```

・成功すればレスポンスは下記通り返ってくる

```json
 {
      "jobName":"job ID",
      "accountId":"account ID",
      "results": {
         "transcripts":[
            {
               "transcript":" that's no answer",
               "confidence":1.0
            }
         ],
         "items":[
            {
               "start_time":"0.180",
               "end_time":"0.470",
               "alternatives":[
                  {
                     "confidence":0.84,
                     "word":"that's"
                  }
               ]
            },
            {
               "start_time":"0.470",
               "end_time":"0.710",
               "alternatives":[
                  {
                     "confidence":0.99,
                     "word":"no"
                  }
               ]
            },
            {
               "start_time":"0.710",
               "end_time":"1.080",
               "alternatives":[
                  {
                     "confidence":0.87,
                     "word":"answer"
                  }
               ]
            }
         ]
      },
      "status":"COMPLETED"
   }
```

# 認証とアクセスコントロール
・AWS Transcribeの利用にはCredentialが必要です。Credencialには認証とアクセスコントロールの設定を行う必要があります。
## 認証
・認証には以下のいずれかを使用します。
  - AWS Account ルートユーザー(非推奨)
  - IAM role
　 (1) ユーザーごとの許可
　 (2) AWSサービスのからのアクセス
　 (3) EC2からのアクセス許可

## アクセスコントロール
### TranscribeへアクアセスするためのPermissionの管理
#### アクセスとアクションの確認
・誰が何にアクセスするかはは下記方法で定義します。
　- IAMポリシー：IAMユーザーやIAM roleに権限を付加する
　- リソースベースのポリシー：各AWSのサービスにAPIでアクセスする際に要求されるポリシー主にResource,Action,Effect,Principalなど

## TranscribeのためのIAM ポリシー
・StartTranscriptionJobを実行するためのIAM roleの例

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "transcribe:StartTranscriptionJob"
             ],   
            "Resource": "*"
        }
    ]
}
        
```
・コンソールでTranscribeを使用するためのIAM roleの例

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "transcribe:*"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}
```
・音声を取得するためにIAM roleの例

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "transcribe.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::bucket name/*"
        }
    ]
}
```
・KMSを使ったS3の暗号化を行うための IAM roleの例

```json
{
      "Sid": "Allow-Transcribe",
      "Effect": "Allow",
      "Principal": {
        "Service": "transcribe.amazonaws.com”
      },
      "Action": [
        "kms:Encrypt",
        "kms:Decrypt",
        "kms:ReEncrypt*",
        "kms:GenerateDataKey*",
        "kms:DescribeKey"
      ],
      "Resource": "*"
    }

```
## APIに対する権限のリファレンス
・Amazon TranscribeのAPIは下記通り
　- GetTranscriptionJob: 
　　　API: transcribe:GetTranscriptionJob
　　　Resource:*
　- ListTranscriptionJobs: 
　　　API: transcribe:ListTranscriptionJobs
　　　Resource:*
　- StartTranscriptionJob: 
　　　API: transcribe:StartTranscriptionJob
　　　Resource:*﻿

# ベータ版のガイドラインと制限
・現在は下記リージョンのみ
　-リージョン：US East (N. Virginia)
　- Endpoint:：https://transcribe.us-east-1.amazonaws.com
　- プロトコル：HTTPS
・推奨素材は以下
　- ロスレスFLAC、ロスレスWAV、PCM(16ビット) 　- サンプリングレート 8000 ~ 16000Hz
・制限は以下の通り
　- 尺は最長2h

# APIリファレンス
・別紙参照(https://docs.aws.amazon.com/ja_jp/transcribe/latest/dg/API_GetTranscriptionJob.html)