OpenAIのWhisper API, Llama-index, GPT-4を使って､音声データから文字起こしと要約を作成する

# はじめに

'[OpenAIのWhisper APIとGPT-4を使って､音声データから文字起こしと要約を作成する](https://qiita.com/revsystem/items/37aa4f066b63a3bb0379)' の記事では､文字起こししたテキストデータを直接GPT-4に渡してい要約を行っています｡この場合､クエリと回答のトークン数が8,192という制約があります｡文字起こしデータが長文となった場合でも対応できるよう､Llama-indexでベクトル化してインデックスを作成し､クエリを処理できるようにしてみました｡
タイトルに`要約を作成する`と書いていますが､どのような回答を得たいかはクエリ次第なので､要約以外も出力できます｡

# 参考情報

https://dev.classmethod.jp/articles/get-reference-in-query-of-llamaindex/

https://note.com/npaka/n/n94e4069f2e9c

https://recruit.gmo.jp/engineer/jisedai/blog/llamaindex-chatgpt-tuning/

https://qiita.com/remonga/items/8f8ffc1c567726a22e0d

# 環境構築

## 環境
```console
$ python3 -V
Python 3.10.12
```

事前にffmpegのインストールが必要です｡
```
$ ffmpeg -version
ffmpeg version 4.4.2-0ubuntu0.22.04.1 Copyright (c) 2000-2021 the FFmpeg developers
```

## 必要なPythonパッケージのインストール

```console
$ pip install --upgrade pip
$ pip install openai pydub sentence_transformers tiktoken llama-index==0.8.13
```

インストールされた主なライブラリは以下のとおりです｡
```console
$ pip freeze | grep -e "openai" -e "pydub" -e "sentence_transformers" -e "tiktoken" -e "llama-index" 
llama-index==0.8.13
openai==0.27.9
pydub==0.25.1
tiktoken==0.4.0
```

# Pythonコード

https://github.com/revsystem/llamaindex-with-whisper

## 実行例

Gitリポジトリをcloneします｡

```console
git clone https://github.com/revsystem/llamaindex-with-whisper.git
cd ./llamaindex-with-whisper
```

### 文字起こし
Pythonファイルと同じディレクトリ内に動画ファイル(sample.mp4)を配置し､以下の様に実行します｡
 ./data/documents 以下(ディレクトリがなければ自動作成)に文字起こし結果が出力されます｡出力ファイル名は`transcription_20230821203508.txt`という形式です｡

```console
python3 ./transcriptin.py -f ./sample.mp4
```

### ベクター化とインデックス作成
 ./data/documents以下の文字起こし結果をベクター化し､インデックスを作成します｡ ./data/indexes/index.json 以下(ディレクトリがなければ自動作成)にインデックスが作成されます｡

```console
python3 ./transcriptin.py -i
```

### クエリ実行
クエリを実行する際は引数なしで実行します｡
```console
python3 ./transcriptin.py
```

入力プロンプトが表示されるので､`レポート文章に見出しをつけたり、箇条書きにして議事録を作成して下さい｡`などクエリを入力します｡
```console
Input query: 
```

### レスポンス

`Query:`に入力したクエリ､`Answer:`に回答が出力されます｡回答は､ChatGPTのようにストリームで文字が1文字ずつ出力されます｡そのほかに､コサイン類似度や回答作成の際に参照した箇所が出力されます｡


```
==========
Query:
<QUERY_YOU_INPUTED>
Answer:
<ANSWER_FROM_AI>
==========

node.node.id_='876f8bdb-xxxx-xxxx-xxxx-xxxxxxxxxxxx', node.score=0.8484xxxxxxxxxxxxxx
----------

Cosine Similarity:
0.84xxxxxxxxxxxxxx

Reference text:
<THE_PART_AI_REFERRED_TO>
```


GTP-4が処理した結果は､Pythonファイルと同じディレクトリ内に出力されます｡出力ファイル名は`transcription_summary_20230821203603.txt`という形式です｡

### 終了

クエリを終了する場合は､`exit`と入力します｡
```
Input query: exit
```

# Setting global configuration

インデックス作成やクエリの際に都度service contextを呼び出さなくて済むように`set_global_service_context`を使用しています｡

https://gpt-index.readthedocs.io/en/stable/core_modules/supporting_modules/service_context.html#setting-global-configuration

# 多言語埋め込みモデル

デフォルトの埋め込みモデル`text-embedding-ada-002`を使用する場合､埋め込みAPI費用が発生するため､API費用がかからず且つ性能向上が見込める`Multilingual-E5-large`を使用しています｡

# Text Splitterなどの設定

Text Splitterは､Llama-indexのデフォルトのTokenTextSplitterを使用しています｡`chunk_size`や`chunk_overlap`は､日本語の文字起こし結果でインデックスを作成した際に回答の精度がよかったときの値を使用しています｡試したパターンが少ないので､PromptHelperの設定と併せて他に最適なものがあると思います｡

https://gpt-index.readthedocs.io/en/stable/core_modules/data_modules/node_parsers/usage_pattern.html#text-splitter-customization