はじめに
最近のWebミーティングツールは標準で文字起こし機能についていたり、会議後に要約やアクションプランをまとめてくれたりするものもあります。
これは確かに便利なのですが、専門用語の認識精度や要約の詳細度など、実用面で課題があります。
そこで、今回はAWSで利用可能な文字起こしサービスであるAmazon Transcribeを使って、会議の文字起こし精度の向上に取り組んでみることにしました。
最終的にはAmazon Transcribeによる高精度文字起こし + Bedrockによる要約でWebミーティングの文字起こし・要約を超えるのが目標ですが、まずは本記事ではAmazon Transcribeによる文字起こしに取り組むことにします。
Amazon Transcribeとは
AWS上で利用可能な音声認識・分析サービスです。この記事では主にレコーディングファイルを後から文字起こしする機能を取り上げますが、リアルタイムでの文字起こしや話者の感情分析、通話内容のカテゴリ分類などの機能もあります。
機能のお試しはGUIから簡単にできるので、是非やってみてください。何もチューニングをしない状態での文字起こしでも、体感としてはWebミーティングツールの文字起こしより精度が良い結果でした。
"リアルタイムトランスクリプション"は"ストリーミングを開始"を押して話すだけですぐに文字起こしされます。
"トランスクリプションジョブ"も文字起こししたいファイルを選択してアップロードするだけでOKです。
実験環境の設定
会議の前提条件
・話者は3人~5人
・単一のマイクで複数人の発言が録音されている
・専門用語を多く含む
Transcribeの設定
初回は以下のオプションで文字起こしに挑みます。
print(f"Attempting to start job: {job_name}")
transcribe_response = transcribe.start_transcription_job(
TranscriptionJobName=job_name,
LanguageCode='ja-JP', # Japanese
MediaFormat=media_format,
Media={
'MediaFileUri': f's3://{bucket}/{key}'
},
OutputBucketName=output_bucket,
Settings={
'ShowSpeakerLabels': True,
'MaxSpeakerLabels': 5,
'ChannelIdentification': False,
'ShowAlternatives': True,
'MaxAlternatives': 3
}
)
-
ShowSpeakerLabels=True
これは後続で会議の要約を行うときに話者を特定出来ると都合が良いのでTrueとしています。 -
ChannelIdentification=False
今回は単一のマイクで録音されていることもあり、Falseとしています。オンライン会議であればTrueにするのが望ましいかもしれませんが、3チャンネル以上にするにはクォータの引き上げが必要なようです。
By default, you can transcribe audio files with two channels. You can request a quota increase if you need to transcribe files that have more than two channels. For information about requesting a quota increase, see AWS service quotas.
- ShowAlternatives=True
各単語のConfidence Scoreを取得するためにTrueにしています。これはTranscribeが単語毎の文字起こし精度を評価した0~1の値で、1に近ければ近いほど高精度です。
文字起こし結果の分析
結果の構成
Amazon Transcribeの文字起こし結果は以下のようなjsonファイルで取得可能です。
30分未満の短い会議でも数万行になります。
{
"jobName": "<jobName>",
"accountId": "<AccountId>",
"status": "COMPLETED",
"results": {
"transcripts": [
{
"transcript": "<文字起こし結果全文>
}
],
"speaker_labels": {
"segments": [
{
"start_time": "75.73",
"end_time": "76.91",
"speaker_label": "spk_0",
"items": [
{
"speaker_label": "spk_0",
"start_time": "75.739",
"end_time": "75.769"
},
{
"speaker_label": "spk_0",
"start_time": "75.769",
"end_time": "76.089"
},
{
"speaker_label": "spk_0",
"start_time": "76.089",
"end_time": "76.309"
},
{
"speaker_label": "spk_0",
"start_time": "76.309",
"end_time": "76.879"
}
]
}
]
},
"items": [
{
"id": 0,
"type": "pronunciation",
"alternatives": [
{
"confidence": "0.936",
"content": "お"
}
],
"start_time": "75.739",
"end_time": "75.769",
"speaker_label": "spk_0"
},
{
"id": 1,
"type": "pronunciation",
"alternatives": [
{
"confidence": "0.945",
"content": "疲れ"
}
],
"start_time": "75.769",
"end_time": "76.089",
"speaker_label": "spk_0"
},
{
"id": 2,
"type": "pronunciation",
"alternatives": [
{
"confidence": "0.902",
"content": "様"
}
],
"start_time": "76.089",
"end_time": "76.309",
"speaker_label": "spk_0"
},
{
"id": 3,
"type": "pronunciation",
"alternatives": [
{
"confidence": "0.88",
"content": "です。"
}
],
"start_time": "76.309",
"end_time": "76.879",
"speaker_label": "spk_0"
},
],
"segments": [
{
"start_time": "75.73",
"end_time": "76.91",
"alternatives": [
{
"transcript": "お疲れ様です。",
"items": [
{
"type": "pronunciation",
"content": "お",
"confidence": "0.936",
"start_time": "75.739",
"end_time": "75.769"
},
{
"type": "pronunciation",
"content": "疲れ",
"confidence": "0.945",
"start_time": "75.769",
"end_time": "76.089"
},
{
"type": "pronunciation",
"content": "様",
"confidence": "0.902",
"start_time": "76.089",
"end_time": "76.309"
},
{
"type": "pronunciation",
"content": "です。",
"confidence": "0.88",
"start_time": "76.309",
"end_time": "76.879"
}
]
},
]
},
],
"audio_segments": [
{
"id": 0,
"transcript": "お疲れ様です。",
"start_time": "75.73",
"end_time": "76.91",
"speaker_label": "spk_0",
"items": [
0,
1,
2,
3
]
},
]
}
}
field | 内容 |
---|---|
results.transcripts.transcript | 文字起こし結果の全文が格納される。話者関係なく、一行に全文字起こし結果が詰め込まれるのでかなり見づらいです。ただし、TranscribeのGUIで表示されるのはこの部分。 |
results.speaker_labels.segments | レコーディングの何秒から何秒まで、誰が話したかが表示されます。 |
results.items | 音節単位?でかなり細かく文字起こしされた結果が表示されます。 |
results.segments / results.audio_segments | itemsをつなげた結果、文節単位で表示されます。 |
ここでは会議冒頭の"お疲れ様です"の挨拶以外はカットしていますが、これだけでこの行数ですから1時間の会議をフルで文字起こしすると膨大な行数になります。
データの整理と課題抽出
精度を上げるためには、先程のjsonファイルのitemsからcontentとconfidenceの情報を抜き出して整理する必要がありそうです。
人間の目で見るのは大変なので、AIに情報まとめてcsvに整理してもらいました。
(想定通りではありますが)その結果、以下の課題が見えてきました。
- 専門用語は認識できていない
confidence値 | 文字起こし結果 | 期待する結果 |
---|---|---|
0.003 | スペクタクラシック | Inspector Classic |
0.201 | リラックス | Linux |
0.343 | サブラスク | サブタスク |
0.589 | ギラ | Jira |
スクラム開発用語やIT用語(AWS用語)は教えてあげる必要がありそうです。
- 会社名・人名は認識できない
これも当たり前なのですが、後続の会議要約を考えると教えてあげたほうが良さそうです。
ちなみにこの時点での文字起こしの 平均Confidence値は0.844, 中央値は0.963 でした。
カスタムボキャブラリーによる精度向上
Amazon Transcribeでは文字起こしの単語を覚えさせる方法として以下の2つがあります。
- カスタムボキャブラリーを利用する
- カスタム言語モデルを利用する
取り扱うテーマに関する技術文書を学習させたカスタム言語モデルを利用するのも良さそうですが、今回は固有名詞やAWS以外の専門用語も覚えてもらうため、カスタムボキャブラリーを利用してみます。
カスタムボキャブラリーファイルの作成
Transcribeに認識してほしい語彙を集めたカスタムボキャブラリーを用意します。txtファイル・csvファイルがサポートされていますが、今回はcsvファイルとして作成することにします。
かなり抜粋していますが、今回は以下のファイルを取り込ませます。
"Phrase"には発音される言葉を、"DisplayAs"は文字起こし時に文字にしたい言葉を記載します。
Phrase,SoundsLike,IPA,DisplayAs
スプリント,,,Sprint
プランニング,,,プランニング
サブタスク,,,サブタスク
ジラ,,,Jira
コンフルエンス,,,Confluence
リナックス,,,Linux
インスペクター,,,Inspector
クラシック,,,Classic
カスタムボキャブラリーの設定
カスタムボキャブラリーは以下のように設定可能です。
ちなみに、"みたいに聞こえる(SoundsLike)"と"IPA"は項目としては存在しますが、既にサポートされておらず何も機能しないようです。ドキュメントにも空にしておくよう書いてあります。
SoundsLike is no longer supported for Custom Vocabulary. Please leave the column empty. Any values in this column will be ignored. We will remove the support for this column in the future.
IPA is no longer supported for Custom Vocabulary. Please leave the column empty. Any values in this column will be ignored. We will remove the support for this column in the future.
検証結果
1回目の結果分析
残念ながら今回のカスタムボキャブラリーだと内容が甘く、精度はほぼ変わりませんでした。 (平均Confidence値 0.844, 中央値0.961)
"ジラ"・"リナックス"などは"ギラ"・"リラックス"と認識されてしまっており、カスタムボキャブラリーで変換されないんですね。
なので、更に追加で"ギラ"・"リラックス"などカタカナの時点で文字認識がうまくいっていない単語もまとめてカスタムボキャブラリーに登録します。
また、"リアルタイムでテスト"を選択するとこのカスタムボキャブラリーを使ったリアルタイムトランスクリプションジョブが実行されます。
2回目の結果分析
更新したカスタムボキャブラリーを使って再度文字起こしを実行します。
ちなみに文字起こしの所要時間は、約20分のレコーディングファイルに対してカスタムボキャブラリーなしで77秒、カスタムボキャブラリーありで207秒でした。
(これとは別にShowAlternativesやShowSpeakerlabelsの設定も所要時間に影響を与えるかもしれません)
気になる結果は...、今回もConfidence値はあまり変わりませんでした。 (平均値 0.844, 中央値 0.962)
ただし、今回は今までちゃんと文字起こしできていなかった単語(リラックス→Linuxなど、カタカナの時点で正しく文字起こしできていなかった単語)はほぼ全て正しく認識できていました。
そもそも全体として膨大な単語が認識されている中で、ほんの数個〜数十個の認識が改善したところでConfidence値が大きく向上することはないように思います。(今回の20分程度のミーティングでも音節数=itemsは2500個以上あります)
また、最終目標はConfidence値の向上ではなく専門用語を正しく認識させることなので、目標を達成できていると言えるでしょう。
今後の課題として今回は人力grepでカスタムボキャブラリーに登録している単語を、どう効率的に検出・登録していくかを考える必要がありそうです。
おわりに
本記事ではAmazon Transcribeのカスタムボキャブラリー機能を使った文字起こし精度の改善を実際に試してみた結果をご紹介しました。
- カスタムボキャブラリーに単語登録することで、専門用語も正しく文字起こし可能となる
- カスタムボキャブラリーの登録だけでは文字起こしの精度を表す値(Confidence値)の劇的な改善は望めない可能性が高い
- 膨大な数の単語を登録する必要がある場合は、効率的に登録する方法も検討する必要がある
次回はカスタムボキャブラリーの効率的な登録方法を考えつつ、カスタム言語モデルを試してみたいと思います。