Faster WhisperとPyAudioを使用して、マイクから音声をリアルタイムで取得し、音声をテキストに変換する

Faster WhisperとPyAudioを使用して、マイクから音声をリアルタイムで取得し、音声をテキストに変換する

pip install faster-whisper pyaudio

でライブラリインストール

録音ファイルは
mic_rec.py
とする

import pyaudio
import numpy as np
import faster_whisper

# Faster Whisperのモデルをロードします(モデルパスは適宜変更してください)
model = faster_whisper.WhisperModel("large-v2", device="cpu")  # または "cuda" でGPUを使用

# 音声設定
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
CHUNK = 1024

# PyAudioのインスタンスを作成
audio = pyaudio.PyAudio()

# マイクから音声を取得するストリームを開きます
stream = audio.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK)

print("Listening...")

# 音声データをバッファとして取得してリアルタイムに処理します
try:
    while True:
        # 音声データを取得
        data = stream.read(CHUNK)
        # NumPy配列に変換
        audio_data = np.frombuffer(data, dtype=np.int16)
        # Faster Whisperに音声データを渡してテキストを取得
        segments, _ = model.transcribe(audio_data)
        # 取得したセグメントを出力
        for segment in segments:
            print(f"Text: {segment.text}")
except KeyboardInterrupt:
    # 終了処理
    print("Terminating...")
finally:
    stream.stop_stream()
    stream.close()
    audio.terminate()


生成されたコードだが
モデルは
large-v3
を使い

CPUを使う

なお以前
/aw10s/whisper/test.py
で試した時には

model = WhisperModel("large-v3", device="cpu", compute_type="int8")

としたので
この設定を使う

import pyaudio
import numpy as np
from faster_whisper import WhisperModel


# Faster Whisperのモデルをロードします(モデルパスは適宜変更してください)
# model = faster_whisper.WhisperModel("large-v2", device="cpu")  # または "cuda" でGPUを使用
model = WhisperModel("large-v3", device="cpu", compute_type="int8")
# 音声設定
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
CHUNK = 1024

# PyAudioのインスタンスを作成
audio = pyaudio.PyAudio()

# マイクから音声を取得するストリームを開きます
stream = audio.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK)

print("Listening...")

# 音声データをバッファとして取得してリアルタイムに処理します
try:
    while True:
        # 音声データを取得
        data = stream.read(CHUNK)
        # NumPy配列に変換
        audio_data = np.frombuffer(data, dtype=np.int16)
        # Faster Whisperに音声データを渡してテキストを取得
        segments, _ = model.transcribe(audio_data)
        # 取得したセグメントを出力
        for segment in segments:
            print(f"Text: {segment.text}")
except KeyboardInterrupt:
    # 終了処理
    print("Terminating...")
finally:
    stream.stop_stream()
    stream.close()
    audio.terminate()

で実行

しかし

Listening...
Text:  Takk for att du så på!
Traceback (most recent call last):
  File "/Users/snowpool/aw10s/linebot/mic_rec.py", line 27, in <module>
    data = stream.read(CHUNK)
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/pyaudio/__init__.py", line 570, in read
    return pa.read_stream(self._stream, num_frames,
OSError: [Errno -9981] Input overflowed

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/snowpool/aw10s/linebot/mic_rec.py", line 39, in <module>
    stream.stop_stream()
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/pyaudio/__init__.py", line 500, in stop_stream
    pa.stop_stream(self._stream)
OSError: Stream not open

となる

OSError: [Errno -9981] Input overflowed は、
PyAudio がバッファから音声データを適切に読み取れなかったことを示しています。
この問題は、バッファサイズが小さいか、処理が遅いために発生することがあります。
とのこと

バッファサイズの調整:
CHUNK のサイズを大きくすることで、入力オーバーフローを防ぐことができます。
例えば、1024 を 2048 や 4096 に変更してみてください
ということで

CHUNK = 2048  # もしくは 4096

で試す

また
エラーハンドリングの追加: オーバーフローエラーが発生した場合に備え、
例外処理を追加してストリームを正しく閉じるようにします。

try:
    while True:
        data = stream.read(CHUNK, exception_on_overflow=False)
        audio_data = np.frombuffer(data, dtype=np.int16)
        segments, _ = model.transcribe(audio_data)
        for segment in segments:
            print(f"Text: {segment.text}")
except OSError as e:
    print(f"Error: {e}")
except KeyboardInterrupt:
    print("Terminating...")
finally:
    stream.stop_stream()
    stream.close()
    audio.terminate()

これらを追加して

import pyaudio
import numpy as np
from faster_whisper import WhisperModel

# Faster Whisperのモデルをロードします
model = WhisperModel("large-v3", device="cpu", compute_type="int8")

# 音声設定
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
CHUNK = 2048  # バッファサイズを大きく変更

# PyAudioのインスタンスを作成
audio = pyaudio.PyAudio()

# マイクから音声を取得するストリームを開きます
stream = audio.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK)

print("Listening...")

# 音声データをバッファとして取得してリアルタイムに処理します
try:
    while True:
        # 音声データを取得、オーバーフロー時に例外を発生させない
        data = stream.read(CHUNK, exception_on_overflow=False)
        # NumPy配列に変換
        audio_data = np.frombuffer(data, dtype=np.int16)
        # Faster Whisperに音声データを渡してテキストを取得
        segments, _ = model.transcribe(audio_data)
        # 取得したセグメントを出力
        for segment in segments:
            print(f"Text: {segment.text}")
except OSError as e:
    print(f"Error: {e}")
except KeyboardInterrupt:
    print("Terminating...")
finally:
    stream.stop_stream()
    stream.close()
    audio.terminate()

としたが
実行すると

Listening... Text: Takk for att du så med. Text: Teksting av Nicolai Winther Text: Teksting av Nicolai Winther Text: Продолжение следует... Text: Teksting av Nicolai Winther ^CTerminating... 

となる

Faster Whisperモデルが認識する言語が様々であるため、
期待される言語での認識がうまくいっていない可能性があります。
これを改善するために、
特定の言語を指定してモデルがその言語に焦点を当てて認識するように設定することが有効です。

Faster Whisperモデルで特定の言語を指定するためには、
transcribe メソッドに language パラメータを追加して使用します。例えば、
日本語を指定したい場合は、language=”ja” とします。

ということで

import pyaudio
import numpy as np
from faster_whisper import WhisperModel

# Faster Whisperのモデルをロードします
model = WhisperModel("large-v3", device="cpu", compute_type="int8")

# 音声設定
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
CHUNK = 2048  # バッファサイズを大きく変更

# PyAudioのインスタンスを作成
audio = pyaudio.PyAudio()

# マイクから音声を取得するストリームを開きます
stream = audio.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK)

print("Listening...")

# 音声データをバッファとして取得してリアルタイムに処理します
try:
    while True:
        # 音声データを取得、オーバーフロー時に例外を発生させない
        data = stream.read(CHUNK, exception_on_overflow=False)
        # NumPy配列に変換
        audio_data = np.frombuffer(data, dtype=np.int16)
        # Faster Whisperに音声データを渡してテキストを取得
        segments, _ = model.transcribe(audio_data, language="ja")  # 言語を日本語に指定
        # 取得したセグメントを出力
        for segment in segments:
            print(f"Text: {segment.text}")
except OSError as e:
    print(f"Error: {e}")
except KeyboardInterrupt:
    print("Terminating...")
finally:
    stream.stop_stream()
    stream.close()
    audio.terminate()

実行すると

Text: ご視聴ありがとうございました
Text: ご視聴ありがとうございました
Text: ご視聴ありがとうございました

となる

多分設定が足りていない

kotoba-whisper-v1.0

large3 より速いし日本語特化らしい
https://zenn.dev/asap/articles/ba8fcb1880165e

これと
https://zenn.dev/asap/articles/2c0d421e68ef16

生成AIをローカルで簡単に 【Part5.5 faster-whisper+マイク録音編】
と組み合わせることにする

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です