作成日:2024年11月30日(土)、2024年12月1日(日)
1.はじめに
これまで音声データからの文字起こしや話者分離、議事録作成は、WhisperとGPT-4を組み合わせて実現してきました。しかし、2024年10月17日(木)にOpenAIが公開したGPT-4-audio-previewと、2024年11月25日(月)にDify v0.12.0で実装されたマルチモーダル機能により、これらの機能が1つのモデルに統合されました。これにより、ローコードツールのDifyを使用して感情分析や音声ファイルの入出力が可能になりました。
DifyはRealtime API(Web Socket)には対応できていませんが、REST APIによりどの程度のことができるかを実験してみたいと思いこの記事をまとめています。
上図のように、従来は音声データをWhisperで文字起こしした後にGPT-4で議事録を作成する2段階のプロセスが必要でしたが、GPT-4-audio-previewでは1つのモデルで音声認識から議事録作成までを一括して処理できるようになりました。
2.OpenAI gpt-4o-audio-previewとは
OpenAI gpt-4o-audio-previewは、2024年10月17日(木)にOpenAIが公開したgpt-4oをベースとしたマルチモーダルモデルです。
従来のgpt-4oの機能に加え、オーディオ入力、オーディオ出力、感情分析が特徴です。
OpenAIのAudio generationページによると、gpt-4o-audio-previewは複数の機能を搭載しています。特に注目すべき点は、トーン、抑揚、その他のニュアンスを検出して感情分析ができる機能です。
また、gpt-4o-audio-previewはgpt-4oをベースモデルとしているため、従来通りの画像理解機能も備えているはずですが、Difyからは「ビジョン」が有効にできず、同時利用はできないようです。
gpt-4o-audio-previewは、音声アシスタント、会議の文字起こし、多言語音声翻訳など、幅広いアプリケーションでの活用が期待されています。音声インターフェースを通じたAIとのやり取りが、より自然で効果的なものになることが期待されています。
- テキストを音声オーディオ要約を生成する (テキスト入力、オーディオ出力)
- 録音に対して感情分析を実行する(オーディオ入力、テキスト出力)
- モデルとの非同期音声合成インタラクション (オーディオ入力、オーディオ出力)
Audio generationページの入出力の関係を以下の表にまとめました。
テキストとオーディオの両方を入力する場合、ユーザープロンプトはどちらでも指定できますが、オーディオの処理コストを考慮すると、プロンプトはテキストで入力することをお勧めします。
No | 入力 | 出力 | 説明 |
---|---|---|---|
1 | テキスト | テキスト+オーディオ | テキストを入力すると、テキストと音声の両方で応答を返します |
2 | オーディオ | テキスト+オーディオ | 音声を入力すると、テキストと音声の両方で応答を返します |
3 | オーディオ | テキスト | 音声を入力すると、テキストのみで応答を返します |
4 | テキスト+オーディオ | テキスト+オーディオ | テキストと音声の両方を入力すると、テキストと音声の両方で応答を返します |
5 | テキスト+オーディオ | テキスト | テキストと音声の両方を入力すると、テキストのみで応答を返します |
3.Azure OpenAIとの違い
OpenAI gpt-4o-audio-previewとAzure OpenAI gpt-4o-realtime-previewは、名前が類似しているため区別が難しいです。
OpenAI gpt-4o-audio-previewは感情分析などもできるため、結論としてOpenAI gpt-4o-audio-previewとAzure OpenAI gpt-4o-realtime-previewは同一モデルと思われます。
主な違いとして、OpenAI gpt-4o-audio-previewは従来のAPIでChat CompletionsとReadtime API(Web Socket)をサポートしているのに対し、Azure OpenAI gpt-4o-realtime-previewはWeb Socket APのみのサポートいう点です。
Web Socket APIは低レイテンシー(リアルタイム応答)を実現する通信インターフェースです。
OpenAI gpt-4o-audio-previewはOpenAIのChangelogによれば2024年10月17日(木)にAPIのChat Completionsをサポートし2024年10月30日(水)にReamtime APIのChat Completionsをサポートしています。
No | 比較項目 | OpenAI gpt-4o-audio-preview | OpenAI gpt-4o-audio-preview(Web Socket) | Azure OpenAI gpt-4o-realtime-preview |
---|---|---|---|---|
1 | 提供元 | OpenAI | OpenAI | Microsoft Azure |
2 | モデル基盤 | GPT-4 | GPT-4 | GPT-4 |
3 | 主な特徴 | 音声認識と生成に特化 | 低レイテンシーの音声処理 | リアルタイム処理に最適化 |
4 | 通信I/F | REST API | Web Socket | Web Socket |
4 | レイテンシー | 標準的 | 低レイテンシー(リアルタイム応答) | 低レイテンシー(リアルタイム応答) |
5 | 利用環境 | OpenAIプラットフォーム | OpenAIプラットフォーム | Azureクラウド環境 |
6 | セキュリティ | OpenAIの標準セキュリティ | OpenAIの標準セキュリティ | エンタープライズレベルのセキュリティ |
7 | コスト構造 | APIコール単位の課金 | APIコール単位の課金 | Azure従量課金制 |
8 | サポート | OpenAIコミュニティサポート | OpenAIコミュニティサポート | Microsoftエンタープライズサポート |
4.Difyのサポート状況
OpenAI gpt-4o-audio-previewは、通信インターフェースがgpt-4oと同一であったため、Dify v0.6.8のローンチ時点(2024年5月14日)からすでにサポートされていました。
しかし、Dify自体が画像以外のマルチモーダルファイルに対応したのは2024年11月25日からであり、実質的にはこの日からOpenAI gpt-4o-audio-previewの機能を利用できるようになりました。
私はDifyのRelease Noteを毎回確認していますが、OpenAI gpt-4o-audio-previewのサポートに関する記載を見つけることができませんでした。
おそらく、モデルとしてはgpt-4oなので、Difyとしては2024年11月25日のREST APIによるオーディオ入出力の対応が最初の対応となるようです。
Azure OpenAI gpt-4o-realtime-previewは、通信インターフェースが根本的に異なるため、Difyでのサポート対応には相当な時間がかかると予想されます。
No | 項目 | OpenAI gpt-4o-audio-preview | Azure OpenAI gpt-4o-realtime-preview |
---|---|---|---|
1 | サポート状況 | サポート済み | 未サポート |
2 | サポート開始バージョン |
Dify v0.6.8 (テキストと画像) … 2024/5/14 Dify v0.12.0 (Audioファイル) … 2024/11/25 |
ー |
3 | 実装形態 | 音声認識モデルとして統合 | リアルタイム処理モデルとして統合 |
4 | 設定方法 | APIキー設定で利用可能 | Azure認証情報の設定が必要 |
5 | 利用制限 | OpenAIの利用制限に準拠 | Azureの利用制限に準拠 |
Dify v0.12.1のOpenAIのモデルプロバイダー設定画面
Dify-v0.12.1のAzure OpenAI Servicreのモデルプロバイダー追加の画面
→まだWebSocketを用いる低レイテンシー(リアルタイム応答)のgpt-4o-realtime-previewモデルはありません。
5.Difyの設定
5.1. OpenAI APIの契約とAPIキーの発行
[OpenAI API Login]⇒[⚙]⇒[API key]で「Ceate new secret key」で発行します。
5.2. モデルプロバイダーの設定
[Dify]⇒[左上のプルダウンメニュー]⇒[設定]⇒[モデルプロバイダー]⇒[OpenAI]
5.3. チャットフローの作成
Difyで以下のようなシンプルなチャットフローを作成します。
以下のデータを「【音声処理】[CF]GPT Audio Processing.yml」というファイルにしてDifyでインポートしてください。
app:
description: 'OpenAI gpt-4o-audio-previewの検証用のプロジェクトです。以下の検証を実現できるチャットフローとしています。
・テキストで質問しテキスト+オーディオで回答
・オーディオで質問しテキスト+オーディオで回答
・オーディオファイルの会話内容を要約しテキストとオーディオで回答
・オーディオファイルからの文字起こし
・オーディオファイルの感情分析'
icon: 🤖
icon_background: '#FFEAD5'
mode: advanced-chat
name: 【音声処理】[CF]GPT Audio Processing
use_icon_as_answer_icon: true
kind: app
version: 0.1.3
workflow:
conversation_variables: []
environment_variables: []
features:
file_upload:
allowed_file_extensions: []
allowed_file_types:
- audio
- video
allowed_file_upload_methods:
- remote_url
- local_file
enabled: true
fileUploadConfig:
audio_file_size_limit: 50
batch_count_limit: 5
file_size_limit: 15
image_file_size_limit: 10
video_file_size_limit: 100
workflow_file_upload_limit: 10
image:
enabled: false
number_limits: 3
transfer_methods:
- local_file
- remote_url
number_limits: 1
opening_statement: 'オーディオファイルを添付して、ユーザプロンプトで様々な指示が可能です。
オーディオファイルを添付後に以下の指示をコピペで入力してみましょう。
・そのままの言語で文字起こしをしてください。
・感情分析をしてください。
・質問に答えてください。
・質問に日本語で答えてください。
・話しているひとごとに名前を特定して話している内容を整理してください。名前が分からない場合は「担当A」などと、としてください。
・打ち合わせ内容の要旨毎に要約してください。'
retriever_resource:
enabled: true
sensitive_word_avoidance:
enabled: false
speech_to_text:
enabled: true
suggested_questions: []
suggested_questions_after_answer:
enabled: true
text_to_speech:
autoPlay: enabled
enabled: true
language: ja-JP
voice: ''
graph:
edges:
- data:
sourceType: start
targetType: llm
id: 1733003745279-llm
selected: false
source: '1733003745279'
sourceHandle: source
target: llm
targetHandle: target
type: custom
- data:
sourceType: llm
targetType: answer
id: llm-answer
selected: false
source: llm
sourceHandle: source
target: answer
targetHandle: target
type: custom
nodes:
- data:
desc: 開始ノードはデフォルトのままです。
selected: false
title: 開始
type: start
variables: []
height: 82
id: '1733003745279'
position:
x: 80
y: 282
positionAbsolute:
x: 80
y: 282
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 244
- data:
context:
enabled: false
variable_selector: []
desc: オーディオでの質問、文字起こし、感情分析などを行うようにシステムプロンプトを設定し、ユーザプロンプトにはsys.queryとsys.filesを設定しています。この他、チャットフローの機能で音声系やアップロードを有効にしています。
memory:
query_prompt_template: '{{#sys.query#}}
{{#sys.files#}}'
role_prefix:
assistant: ''
user: ''
window:
enabled: false
size: 10
model:
completion_params:
temperature: 0.7
mode: chat
name: gpt-4o-audio-preview
provider: openai
prompt_template:
- id: 6d0b532f-3688-462f-a848-e5772c34da3d
role: system
text: 'あなたは優秀なオーディオ機能を備えたAIエージェントです。
ユーザからのオーディオでの質問、文字起こし、感情分析などの様々な要求を的確に処理します。'
selected: false
title: LLM
type: llm
variables: []
vision:
enabled: false
height: 190
id: llm
position:
x: 379
y: 282
positionAbsolute:
x: 379
y: 282
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 244
- data:
answer: '{{#llm.text#}}'
desc: 回答ノードはデフォルトのままです。
selected: false
title: 回答
type: answer
variables: []
height: 130
id: answer
position:
x: 680
y: 282
positionAbsolute:
x: 680
y: 282
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 244
- data:
author: Dify
desc: ''
height: 373
selected: false
showAuthor: true
text: '{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"■LLMノードについて","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"・LLMノードでオーディオファイルを扱えるようにgpt-4o-audio-previewを選択しています。","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"・システムプロンプトは無くても動きそうですが以下を設定しています。","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"・ユーザプロンプトにsys.queryとsys.filesを設定しています。","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":" sys.query:開始ノードで作られるユーザからの質問","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":" sys.files:プロンプトのクリップマークで添付するファイル","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"■機能","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"以下の設定を有効にしています。","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"・会話の開始:オープナーを設定しています。","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"・テキストから音声へ(tts)","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"
","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"・音声からテキストへ(Whisper)","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"・ファイルアップロード:音声・映像を有効","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}'
theme: blue
title: ''
type: ''
width: 837
height: 373
id: '1733003755785'
position:
x: 89
y: 502
positionAbsolute:
x: 89
y: 502
selected: true
sourcePosition: right
targetPosition: left
type: custom-note
width: 837
- data:
author: Dify
desc: ''
height: 123
selected: false
showAuthor: true
text: '{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Difyでgpt-4o-audio-previewを試す(Qiita)でのサンプルチャットフロー","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"https://qiita.com/potofo/items/f6a423836b57931bfeb0","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0},{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}'
theme: blue
title: ''
type: ''
width: 839
height: 123
id: '1733005697129'
position:
x: 80
y: 103.5
positionAbsolute:
x: 80
y: 103.5
selected: false
sourcePosition: right
targetPosition: left
type: custom-note
width: 839
viewport:
x: 187.5
y: 235.5
zoom: 1.0000000000000002
6.Difyのgpt-4o-audio-previewで出来たこと
OpenAIのAudio generationページの冒頭及び、「FAQ」に記載がある機能をいくつか試してみました。
Whisperと比較すると音楽ファイルの文字起こし機能は劣りますが、全体的な性能は十分に実用的なレベルです。
※Difyはv0.12.1を利用する前提です。
No | 項目 | 入力 | 出力 | 実際に試したこと | 実施結果 |
---|---|---|---|---|---|
1 | テキストで質問 | テキスト | テキスト | テキストで「日本の総理大臣はだれですか?」 | ○ |
2 | オーディオで質問 | オーディオ | テキスト | オーディオで「Question, "Which would most help pollinators find flowers that are pollinated at night? Option A, Shape, Option B, Color, Option C, Size, Option D, Fragrance.”」 | ○ |
3 | オーディオファイルの会話内容を要約 | テキスト+オーディオ | テキスト | テキストで「「打ち合わせ内容の要旨毎に要約してください。」 オーディオで実データ |
○ |
4 | オーディオファイルからの文字起こし | テキスト+オーディオ | テキスト | テキストで「そのままの言語で文字起こしをしてください。」 オーディオは「arc-easy-q237-tts.mp3」として文字起こし |
○ |
5 | オーディオファイルの感情分析 | テキスト+オーディオ | テキスト | テキストで「打ち合わせ内容の感情分析を担当者毎に実施して説明してください。」 オーディオは実データ |
○ |
6 | 音楽ファイルの文字起こし | テキスト+オーディオ | テキスト | テキストで「そのままの言語で文字起こしをしてください。」 オーディオは「魔王魂」さんの「シャイニングスター.mp3」 |
× |
7 | 話者分離 | テキスト+オーディオ | テキスト | テキストで「話しているひとごとに名前を特定して話している内容を整理してください。名前が分からない場合は「担当A」などと、としてください。 オーディオで実データ |
○ |
5.1. テキストで質問
「日本の総理大臣はだれですか?」とgpt-4o-audio-previewに問い合わせてみるとカットオフデートの2021年10月(gpt-4oのカットオフデートは2023年10月のはずですが)時点の総理大臣を答えました。
5.2. オーディオで質問
ここでは「aoai-realtime-audio-sdk」のPythonフォルダに含まれる「arc-easy-q237-tts.flac」を使用させていただきました。
そのままのflac拡張子はDifyでuploadできなかったので、arc-easy-q237-tts.mp3を使用して以下のプロンプトで試しました。
arc-easy-q237-tts.mp3は男性の声で以下のような文章を読み上げているオーディオファイルです。
「Question, "Which would most help pollinators find flowers that are pollinated at night? Option A, Shape, Option B, Color, Option C, Size, Option D, Fragrance.”」
プロンプトを「質問に日本語で答えてください。」に変更すると、英語の質問に対して日本語で回答することができました。
但しDifyはgpt-4o-audio-previewに対して、音声ファイルの送付を指示できていなくて、機能でTTSを有効にすると読み上げをしてくれますが、OpenAIのTTSモデルを
使用したものになりました。(TTSをオフにすると読み上げなかったため)
ただ、TTSも感情が少しこもっているように感じました。
5.3. オーディオファイルの会話内容を要約
大学の面談データoutput_54.mp3(1分58秒)を使用して試してみたところ、良好な要約結果が得られました。
プロンプト:「打ち合わせ内容の要旨毎に要約してください。」
5.4. オーディオファイルからの文字起こし
以下のプロンプトと「aoai-realtime-audio-sdk」のPythonフォルダに含まれる「arc-easy-q237-tts.mp3」
プロンプト:「そのままの言語で文字起こしをしてください。」
5.5. オーディオファイルの感情分析
大学の面談データoutput_86.mp3(00:01:54)を使用して試してみたところ、少し残念な結果ですが、感情分析の結果は得ることができました。
プロンプト:「打ち合わせ内容の感情分析を担当者毎に実施して説明してください。」
5..6 音楽ファイルの文字起こし
環境音の中で文字起こしができるか、テンポが異なる発話を正しく文字起こしできるかという観点で、potofo/whisper-azureでWhisperを使用した文字起こしでは成功していた「魔王魂」さんの「シャイニングスター.mp3」で試してみましたが、残念ながらこちらはできませんでした。Whisperに比べるとノイズ処理が弱いようです。
念のためwavファイルでも試しましたが結果は同じでした。
5.6. 話者分離
以下のプロンプトで大学の面談データoutput_86.mp3(00:01:54)で試してみました
プロンプト:「話しているひとごとに名前を特定して話している内容を整理してください。名前が分からない場合は「担当A」などと、としてください。」
結果は見事に話者分離できています。
6.まとめ
今回の検証ではRealtime APIを利用していないため、カットイン(会話の中断)やリアルタイム文字起こしの実現可能性は不明ですが、OpenAI gpt-4o-audio-previewを使用して文字起こし、話者分離、感情分析などが実行可能であることが確認できました。
No | 項目 | 評価 | 説明 |
---|---|---|---|
1 | 文字起こし | ○ | Teamsなどで使用されているSTT(Speach To Text)に比べると精度よく文字起こしが可能でした 但し、音楽のような周囲に音があるようなものではうまく文字起こしできませんでした。 会議室などで周囲がザワついているとうまく文字起こしできないかもしれません。 |
2 | 話者分離 | ○ | 複数の話者を正確に区別し、個別の発言として分離可能であることが分かりました。 このページには掲載していませんが、名前を名前を名乗ると名乗った名前で表示(例:担当者A(鈴木)」のような表記にしてくれました。 |
3 | 感情分析 | △ | 会話の内容から話者の感情を適切に分析し説明可能であることが分かりましたが、複数の話者がいる場合、話者毎の感情分析などはできないことが分かりました。 話者分離しながら感情分析はすこし厳しいという印象です。 |
7.気になった点
- Difyのアップロードは100MB制限
Difyのコミュニティ版の場合.envファイルに以下のような設定を加えることでこの上限を拡張可能です。
以下の例では500MBに拡張しています。
NGINX_CLIENT_MAX_BODY_SIZE: ${NGINX_CLIENT_MAX_BODY_SIZE:-500M}
UPLOAD_FILE_SIZE_LIMIT: ${UPLOAD_FILE_SIZE_LIMIT:-500}
UPLOAD_VIDEO_FILE_SIZE_LIMIT: ${UPLOAD_VIDEO_FILE_SIZE_LIMIT:-500}
UPLOAD_AUDIO_FILE_SIZE_LIMIT: ${UPLOAD_AUDIO_FILE_SIZE_LIMIT:-500}
- 料金
OpenAIに約$10をチャージして検証を行いましたが、1~2分程度の音声ファイルを30回ほど利用したところ、約$8を消費しました。
会社での人件費としては安価ですが、個人で遊ぶには高価だという印象です。
8.参考URL