開発環境
環境構築
以下のライブラリをインストールします
uv pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
uv pip install funasr
実行
以下のコードを実行します
import argparse import os from funasr import AutoModel def analyze_emotion_with_funasr(audio_file_path: str): """ funasrライブラリとSenseVoiceモデルを使用して音声ファイルの感情を分析する。 Args: audio_file_path (str): 分析したい音声ファイルのパス """ if not os.path.exists(audio_file_path): print(f"エラー: 指定されたファイルが見つかりません。") print(f"パスを確認してください: {audio_file_path}") return print("--- 環境・モデル情報 ---") print(f"ライブラリ: funasr") # --- 1. モデルのロード --- # funasr の公式ドキュメントに沿ったモデルのロード方法 model_dir = "iic/SenseVoiceSmall" print(f"モデル: {model_dir}") print("モデルをロードしています... (初回は時間がかかります)") try: model = AutoModel( model=model_dir, vad_model="fsmn-vad", vad_kwargs={"max_single_segment_time": 30000}, device="cuda:0", # trust_remote_code=True は funasr のバージョンによっては不要な場合があります ) except Exception as e: print(f"モデルのロード中にエラーが発生しました: {e}") return print("モデルのロードが完了しました。") print("\n音声の感情を判定しています...") # --- 2. 感情認識の実行 --- try: # ★★★ ここが重要 ★★★ # task="ser" を指定して、感情認識タスクを実行する res = model.generate( input=audio_file_path, task="ser", # Speech Emotion Recognition ) # --- 3. 結果の表示 --- print("\n" + "="*30) print(" 感情判定結果") print("="*30) # funasrのSERタスクの出力形式はリスト形式で返ってくることが多い if res and "emotion" in res[0]: emotion_label = res[0]["emotion"] print(f" ファイル: {os.path.basename(audio_file_path)}") print(f" 判定された感情: {emotion_label}") else: print(" 感情を判定できませんでした。") print(" モデルからの生データ:", res) # デバッグ用に生データを表示 print("="*30) except Exception as e: print(f"\n推論中に予期せぬエラーが発生しました: {e}") if __name__ == '__main__': parser = argparse.ArgumentParser( description="funasr と SenseVoiceモデルを使用して、音声ファイルの感情を分析します。" ) parser.add_argument( "audio_file", type=str, help="分析したい音声ファイルのパス。" ) args = parser.parse_args() analyze_emotion_with_funasr(args.audio_file)
これを以下で実行します
python .\emotion_recognition.py .\VOICEACTRESS100_090.wav
判定結果は以下のようになります
音声の感情を判定しています... rtf_avg: 0.038: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 4.29it/s] rtf_avg: 0.046: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 3.54it/s] rtf_avg: 0.047, time_speech: 6.062, time_escape: 0.286: 100%|████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 3.38it/s] ============================== 感情判定結果 ============================== 感情を判定できませんでした。 モデルからの生データ: [{'key': 'VOICEACTRESS100_090', 'text': '<|ja|><|EMO_UNKNOWN|><|Speech|><|woitn|>戦闘服は両腕を露出し両足がアンダースーツで覆われている'}] ==============================
ニュートラルの場合は、上記のように判定をします。ただしほぼ?テキストから判定をしているみたいなのでボイス側のニュアンスはあまり反映されていない感じがしています