0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[HCI] 京大のPythonライブラリMaAIで音声会話の終端を検知する

Posted at

ターンキータイミングを予測するMaAIが話題になっているので触りました。MaAIは、大規模言語モデル(LLM)や音声合成(TTS)といったジャンルではなく、対話における非言語的行動(ノンバーバル・ビヘイビア)の生成に特化したライブラリでヒューマン・コンピューター・インタラクション(HCI)の分野と言えます。

MaAIとは

MaAIは、対話型AIにおいて、非言語的行動(ターン交代、相づち、うなずき)をリアルタイムかつ軽量に生成(予測)するためのライブラリです。京大が開発している様です。

▼Githubはこちら
https://github.com/MaAI-Kyoto/MaAI

実際に使ってみます。

from maai import Maai, MaaiInput, MaaiOutput

mic = MaaiInput.Mic()
zero = MaaiInput.Zero() 

maai = Maai(mode="vap", lang="jp", frame_rate=10, context_len_sec=5, audio_ch1=mic, audio_ch2=zero, device="cpu")
maai_output_bar = MaaiOutput.ConsoleBar(bar_type="balance")

maai.start()
while True:
    result = maai.get_result()
    maai_output_bar.update(result)

会話の終端を検知する

P_Now (話者発話中): 現在、話者が発話している確率(高いほど話し手が話している)。
P_Future (聞き手発話開始): 聞き手(相槌を打つ側)がこれから発話し始める確率(高いほど相槌に適している)。

import time
from maai import Maai, MaaiOutput, MaaiInput 
import numpy as np

# 1. 設定
# マイクを使用するため、ファイルパスはコメントアウト
# AUDIO_FILE_PATH = "sample.wav" 

# maai の初期化設定
# 安定動作が確認された "vap" モードを使用
maai = Maai(
    mode="vap", 
    lang="jp",  # 日本語設定
    frame_rate=10, 
    context_len_sec=5,
    
    # マイク入力を使用
    audio_ch1=MaaiInput.Mic(), 
    audio_ch2=MaaiInput.Zero(), 
    device="cpu"
)

# 2. 結果出力設定(ConsoleBarは使用せず、直接値を表示)
print("--- maai リアルタイム予測開始 (マイク入力) ---")
print("マイクに向かって何か話してください。予測結果が直接出力されます。Ctrl+Cで停止します。")
print("---------------------------------------------")
maai.start()

start_time = time.time() # 時間計測開始

# 3. 処理ループ
try:
    while True:
        # 結果を待機して取得
        result = maai.get_result()
        
        if result is None:
            continue
            
        # 💡 リスト型対応の処理: result の値がリストの場合、最初の要素 [0] を抽出する
        processed_result = {}
        for key, value in result.items():
            if isinstance(value, list) and value:
                # リストの最初の要素を抽出
                processed_result[key] = value[0]
            else:
                # リストではないか、空のリストの場合はそのまま使用
                processed_result[key] = value

        # 頷き/相槌の値を取得 (キーが "nod" や "aizuchi" になっていることを期待)
        nod_val = processed_result.get('nod', processed_result.get('p_nod', -1)) 
        aizuchi_val = processed_result.get('aizuchi', processed_result.get('p_aizuchi', -1)) 
        
        # ターンテイキングの値を取得
        p_now_val = processed_result.get('p_now', -1)
        p_future_val = processed_result.get('p_future', -1)
        
        output_line = f"Time: {time.time() - start_time:.2f}s | "
        
        # 頷き/相槌の予測値が含まれているか確認
        if nod_val != -1 or aizuchi_val != -1:
             # 頷き/相槌の予測がある場合の出力
            output_line += f"Nod: {nod_val:.3f} | Aizuchi: {aizuchi_val:.3f} | P_Now: {p_now_val:.3f}"
        else:
            # 含まれていない場合のデフォルト出力(ターンテイキング予測のみ)
            output_line += f"P_Now: {p_now_val:.3f} | P_Future: {p_future_val:.3f}"
            
        print(output_line)
        
        time.sleep(0.1) # 100ms ごとに結果を出力

except KeyboardInterrupt:
    print("\n処理を中断しました。")

# 4. 終了処理
maai.stop()
print("\n--- maai 処理終了 ---")

テスト結果


Time: 0.22s | P_Now: 0.649 | P_Future: 0.451
Time: 0.32s | P_Now: 0.260 | P_Future: 0.195
Time: 0.43s | P_Now: 0.174 | P_Future: 0.129
Time: 0.53s | P_Now: 0.117 | P_Future: 0.104
Time: 0.64s | P_Now: 0.092 | P_Future: 0.089
Time: 0.74s | P_Now: 0.100 | P_Future: 0.091
Time: 0.85s | P_Now: 0.082 | P_Future: 0.079
Time: 0.95s | P_Now: 0.079 | P_Future: 0.078
Time: 1.05s | P_Now: 0.084 | P_Future: 0.083
Time: 1.15s | P_Now: 0.094 | P_Future: 0.090
... 長くなるので割愛

時間帯 P_Nowの変化 P_Futureの変化
3.11秒 0.151 → 0.947 0.153 → 0.708
発話開始の瞬間。 静寂から話し手が言葉を出し始めたタイミング。

14.58秒 - 16.02秒 0.922 → 0.464 0.764 → 0.404
最も明確な区切り。 話し手が文を終えて、大きな間を取ったと予測されます。この間に「うん」「はい」などの音声相槌が最適。

23.03秒 - 23.96秒 0.585 → 0.427 0.563 → 0.406
発話継続に迷いが見える。 話し手の声の勢いが弱まり、聞き手が次の発話を期待できるタイミング。

感想

単純にユーザ入力がなくなったタイミングを検知している様にも見えるが、まぁ実用的に使えそうな感じはしなくもないですね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?