AWS SDK for Python (Boto)からAmazon Transcribeのカスタム語彙を触ってみた

AWS Summits 2018 San Francisco で文字起こしサービスAmazon Transcribeが正式リリースされました。 正式リリースに伴い追加された機能の一つがカスタム語彙です。

AWSの製品ページからカスタム語彙のメリットを引用します。

Amazon Transcribe では音声認識語彙の拡張とカスタマイズを行うことができます。特殊な用語や専門用語、固有の製品名が発話に含まれている場合でも、ベース語彙に新規単語 (発音も含む) を追加することで、特定のユースケースに合った高精度な文字起こしテキストを生成できます。

本ブログでは AWS SDK for Python (Boto) からカスタム語彙を操作する手順を解説します。

管理コンソールからの使い方やカスタム語彙を利用した文字起こし例は次のブログを参照して下さい。

文字起こしサービスAmazon Transcribeがカスタム語彙に対応しました

AWS CLI からのカスタム語彙の操作は次のブログを参照して下さい。

AWS CLIからAmazon Transcribeのカスタム語彙を触ってみた

API 一覧

2018/04/08 時点でカスタム語彙に関して以下の API が存在します。

  • list_vocabularies : 語彙の一覧表示
  • create_vocabulary : 語彙の作成
  • get_vocabulary : 語彙の詳細取得
  • update_vocabulary : 語彙の更新
  • delete_vocabulary : 語彙の削除

サービスオブジェクトの初期化

まずは Amazon Transcribe サービスを操作するためのオブジェクトを作成します。

In [1]: import boto3

In [2]: client = boto3.client('transcribe')

list-vocabularies : 語彙の一覧表示

語彙の一覧を表示します。

初期状態では語彙は登録されていません。

In [3]: client.list_vocabularies()
Out[3]:
{'Vocabularies': [],
 'ResponseMetadata': {…}}

create-vocabulary : 語彙の作成

語彙を新規に作成します。

フレーズは Phrases オプションで渡します。

In [4]: client.create_vocabulary(VocabularyName='test', LanguageCode='en-US', Phrases=['foo', 'bar', 'baz'])
Out[4]:
{'VocabularyName': 'test',
 'LanguageCode': 'en-US',
 'VocabularyState': 'PENDING',
 'ResponseMetadata': {…}}

作成した語彙が一覧表示されていることを確認します。

In [5]: client.list_vocabularies()
Out[5]:
{'Vocabularies': [{'VocabularyName': 'test',
   'LanguageCode': 'en-US',
   'VocabularyState': 'PENDING'}],
   'ResponseMetadata': {…}}

VocabularyState は語彙作成直後は PENDING で利用可能になると READY に遷移します。

get-vocabulary : 語彙の詳細取得

In [6]: client.get_vocabulary(VocabularyName='test')
Out[6]:
{'VocabularyName': 'test',
 'LanguageCode': 'en-US',
 'VocabularyState': 'PENDING',
 'LastModifiedTime': datetime.datetime(2018, 4, 6, 21, 28, 33, 534000, tzinfo=tzlocal()),
 'DownloadUri': 'https://s3.eu-west-1.amazonaws.com/aws-transcribe-dictionary-model-eu-west-1-prod/<USER_AWS_ACCOUNT_ID>/test/...',
 'ResponseMetadata': {…}}

語彙に登録されているフレーズの一覧は、レスポンス DownloadUri の URL から取得します。 登録した語彙は AWS の管理する S3 バケットから、プリサイン URL の GET リクエストで取得可能です。

  • バケット名 : aws-transcribe-dictionary-model--prod/
  • パス : USER_AWS_ACCOUNT_ID/語彙名/...

例)s3.eu-west-1.amazonaws.com/aws-transcribe-dictionary-model-eu-west-1-prod//test

この URL に対して実際に GET してみましょう。

In [8]: import requests
In [9]: print(requests.get(_['DownloadUri']).text)
bar
baz
foo
ENDOFDICTIONARYTRANSCRIBE

辞書順にソートされ、 終端を表す「NDOFDICTIONARYTRANSCRIBE」が追加されます。

update-vocabulary : 語彙の更新

部分更新には対応しておらず、一括置換です。

Phrases に対して

  • foo
  • bar
  • baz

から

  • hoge
  • bar

に変更して登録します。

In [13]: client.update_vocabulary(VocabularyName='test', LanguageCode='en-US', Phrases=['hoge', 'bar'])
Out[13]:
{'VocabularyName': 'test',
 'LanguageCode': 'en-US',
 'VocabularyState': 'PENDING',
 'ResponseMetadata': {…}}

先程とおなじく get-vocabulary の DownloadUri から語彙ファイルを取得します。

$ curl "https://s3.eu-west-1.amazonaws.com/aws-transcribe-dictionary-model-eu-west-1-prod/…"
bar
hoge
ENDOFDICTIONARYTRANSCRIBE

phases が一括置換されています。

delete-vocabulary : 語彙の削除

最後に語彙を削除します。

In [17]: client.delete_vocabulary(VocabularyName='test')
Out[17]:
{'ResponseMetadata': {…}
In [18]: client.list_vocabularies()
Out[18]:
{'Vocabularies': [],
 ' 'ResponseMetadata': {…}}

語彙の削除は状態遷移せず、即座に反映されます。

異常系

get_vocabulary API で 存在しない VocabularyName を指定すると BadRequestException エラーが発生します。

In [21]: client.get_vocabulary(VocabularyName='NotExist')
...
botocore.errorfactory.BadRequestException: An error occurred (BadRequestException) when calling the GetVocabulary operation: The requested vocabulary couldn't be found. Check the vocabulary name and try your request again.

各フレーズは 256 文字未満です。 256 文字以上になると、ValidationException エラーが発生します。

In [22]: client.create_vocabulary(VocabularyName='test', LanguageCode='en-US', Phrases=['a'*256])
...
ClientError: An error occurred (ValidationException) when calling the CreateVocabulary operation: 1 validation error detected: Value '[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]' at 'phrases' failed to satisfy constraint: Member must satisfy constraint: [Member must have length less than or equal to 256, Member must have length greater than or equal to 0]

英語の語彙の場合、Phrase に使える文字は

  • 大文字・小文字のアルファベット
  • ハイフン

だけです。

利用できない文字(今回のケースでは数字の「3」)を含めると、BadRequestException エラーが発生します。

In [23]: client.create_vocabulary(VocabularyName='test', LanguageCode='en-US', Phrases=['s3'])
…
BadRequestException: An error occurred (BadRequestException) when calling the CreateVocabulary operation: The vocabulary that you’re trying to create contains invalid characters. See the developer guide for more information.

参考

  • https://docs.aws.amazon.com/transcribe/latest/dg/custom-vocabulary-files.html
  • REST API Reference https://docs.aws.amazon.com/transcribe/latest/dg/API_Reference.html
  • CLI API Reference https://docs.aws.amazon.com/cli/latest/reference/transcribe/index.html