LLMを使って音声認識の誤りを補正しよう。（競馬実況を書き起こす）

# はじめに
今年は競馬での回収率100%達成できそうな民谷です。

巷で競馬予想において大事なことは「誰も注目していない情報を利用すること」と言われています。
一般的な競馬新聞に載っているような情報などは誰もが注目する情報と言えます。この情報を基に予想しても、みんなが良いと思う馬を選びがちになります。
そこで私は最近、競馬実況の音声から何か情報が得られないかと音声認識に挑戦しています。


今回は音声データをテキストデータへの変換(音声認識)する方法、そこで発生する音声認識誤りをLLMで補正する方法について紹介します。

概要だけ知りたい方は、最後のまとめだけでも読んでいただけたら嬉しいです！

## 得られること
- オープンソースの音声認識モデルWhisperの動作方法
- LLMを使った音声認識誤りの補正方法

# 音声認識について
音声データからテキストデータに書き起こすタスクは音声認識と呼ばれます。
Google Speech-to-Text APIのようなAPIサービスを利用する方法、オープンソースの音声認識モデルを利用する方法などがあります。
今回はオープンソースモデルWhisperを使います。

動作させる環境として、Google colaboratoryのインスタンスを利用します。有料プランに課金しているため、比較的高価なGPUも利用可能です。

## 動作コード
githubからWhisperモデルを動作させるためのライブラリをインストール
```shell
pip install git+https://github.com/openai/whisper.git
```
音声を解析するためのffmpegをインストールします。
```shell
apt update && apt install -y ffmpeg
```

音声認識を動かします。
```python
import whisper

# モデルのロード
# モデルサイズはtiny, base, small, medium, largeがあります。
# 大きいほど高性能ですが、処理時間とリソースコストも大きくなります。
model = whisper.load_model("medium")

# 音声ファイルの認識
# mp4でも動作するようです。
result = model.transcribe("音声ファイル.mp3", language="ja")
print(result["text"])
```

2024年の有馬記念の実況に対して、音声認識した結果は以下の通りです。
<iframe width="560" height="315" src="https://www.youtube.com/embed/E2PgReQom-s?si=jWCwzi_4cWiGnL4j" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

### 音声認識結果
```
6番ゲートに入ります 15頭のゲート員が終わりますありま記念スタートしました 
ドアーマンシック プログノーシス立ち遅れました後方
まず先行争いは 5番ベラジオーペラ そして1番ダノンデサイルダノンデサイル横へも乗広木集 
1周目3コーナーで花に立ちました
7番スターズオンアース3番手 9番ディーポンドが3番手並んで8番レガレイラ5番手追走です 
(省略)
```
かなり高精度に音声認識している一方で、誤認識している部分がいくつか見られます。


# 誤認識の補正
音声認識結果には誤認識が含まれてしまいました。特に馬の名前や専門用語を文字起こしできていません。
- 馬の名前
    - アーバンシック -> ドアーマンシック
    - べラジオオペラ -> ベラジオーペラ
    - 横山典弘騎手 -> 横へも乗広木集 
- 専門用語
    - 有馬記念 -> ありま記念
    - ゲートイン -> ゲート員
    - ハナ -> 花

Whisperの学習データは公開されてはいませんが、汎用的な音声を学習していることが推測されます。そのため競馬実況のような早口の音声を認識することは難しいかもしれません。
また、音声をテキストに書き起こす部分にも課題があります。Whisperは音声情報に加えて、今までに認識したテキスト情報を基にして次に出力すべきテキストを推測しています。汎用的なテキストで学習していると突然聞いたことのない馬の名前を出力することは難しいのかもしれません。

対応方法としてFine-Tuningを適用することも考えられますが、データ準備などコストも高いです。


# LLMで修正しよう。
ChatGPTを使っている時に、タイポしたのに意図通り返答してくれた経験はないでしょうか？
ChatGPTもとい、LLMもWhisperのデコーダと同様に私たちの入力したテキスト情報を基に出力する内容を決めています。そこで多少の打ち間違いなどがあっても、それ以外の情報を基に返答テキストを作っています。

実際にChatGPTに誤字を修正してもらいましょう。
以下の実験ではo1を使用しています。

## とりあえず修正させる。

### プロンプト
```

以下のテキストは競馬の実況音声を音声認識したものです。
誤認識が含まれるので、修正して下さい。

16番ゲートに入ります 15頭のゲート員が終わりますありま記念スタートしました 
ドアーマンシック プログノーシス立ち遅れました
後方まず先行争いは 5番ベラジオーペラ そして1番ダノンデサイルダノンデサイル横へも乗広木集 
1周目3コーナーで花に立ちました7番スターズオンアース3番手 9番ディーポンドが3番手並んで8番レガレイラ5番手追走です 
(省略)
```
### 返答
```
下記が、音声認識上の誤りを修正した想定実況テキストの一例です。
実際の出走馬や展開とは異なる可能性がありますが、文中に登場する馬名・騎手名などを、近年の有馬記念で想定される名前に合わせて整合性を取っています。

16番ゲートに入ります。16頭のゲートインが終わります。有馬記念スタートしました。
アスクビクターモア、プログノーシス立ち遅れました後方。まず先行争いは5番ベラジオオペラ、そして1番ダノンザキッド。ダノンザキッドは横山典弘騎手。1周目3コーナーでハナに立ちました。
7番スターズオンアースが3番手、9番ディープボンドが並んで、8番リバティアイランドが5番手追走です。
(省略)
```
専門用語に関しては適切に修正してくれています。一方でどの馬が走ったかなどの情報は知らないため、適当な馬に置き換えています。

## プロンプトに情報加えて修正させる。

正しい馬の名前を推測することは難しいです。
そこでプロンプトにレースで走る馬の情報、出馬表を追記します。

### プロンプト
```
以下のテキストは競馬の実況音声を音声認識したものです。
誤認識が含まれるので、修正して下さい。

以下は出馬表です。
枠番、馬番、馬名、騎手名の順です。
1, 1, ダノンデサイル, 横山典弘
(省略)
8, 16, シャフリヤール, Cデムーロ

以下は実況です。
16番ゲートに入ります 15頭のゲート員が終わりますありま記念スタートしました 
ドアーマンシック プログノーシス立ち遅れました
後方まず先行争いは 5番ベラジオーペラ そして1番ダノンデサイルダノンデサイル横へも乗広木集 
1周目3コーナーで花に立ちました7番スターズオンアース3番手 9番ディーポンドが3番手並んで8番レガレイラ5番手追走です 
(省略)
```


### 返答
```
16番ゲートに入ります。16頭のゲートインが完了しました。
有馬記念、スタートしました！3番アーバンシック、10番プログノーシスが立ち遅れ、後方からの競馬となります。

まず先行争いは5番ベラジオオペラ、そして1番ダノンデサイル。
ダノンデサイルが横山典弘騎手を背に先頭に立ちました。
1周目3コーナーでは7番スターズオンアースが3番手。9番ディープボンドがその後ろ、並んで8番レガレイラが5番手を追走しています。
(省略)
```
ほぼ完ぺきに補正することができました！

# 音声認識結果を活用しよう
次に音声認識結果を競馬AIの予想に使うため・・・
> 巷で競馬予想において大事なことは「誰も注目していない情報を利用すること」と言われています。

おっと、ここでは内緒にしておきましょう。

# まとめ
ここでは、Whisperを使った音声認識と、その音声認識結果の誤りをLLMを使って補正する方法を紹介しました。
Google Colaboratory環境でオープンソースの音声認識モデルWhisperを使い、音声ファイル内の音声認識を行いました。
音声認識結果には、主に専門用語の誤認識が含まれていました。
そこで、誤認識をLLM（ChatGPT）を使って補正しました。その際に専門用語情報をプロンプトに含めることで、より正確な音声認識結果を得ることができました。

## 他分野への適用
今回は競馬実況の音声を対象としました。同様の専門用語、登場人物の認識誤り問題は発生します。
例えば、社内MTGの録音を対象とした場合にも参加者や業務専門用語や社内特有の呼び名などは誤認識されやすいと思われます。
その場合、プロンプトに参加者リスト、業務専門用語リストなどを前情報として与えた上で、補正させると良い結果が得られるでしょう。
（社内情報の外部アップロードについては慎重に検討ください。）

## 運用に向けて
今回は実験的にGoogle Colaboratoryで音声認識を動作、ChatGPTに認識結果と追加情報(出馬表)を入力しているためかなり手間がかかっています。
音声認識にGoogle Speech-to-Text API、LLMにGemini API、追加情報などは前準備、スクレイピングすることで一連のフローを自動化することも可能です。