Faster WhisperとPyAudioを使用して、マイクから音声をリアルタイムで取得し、音声をテキストに変換する
1 | pip install faster-whisper pyaudio |
でライブラリインストール
録音ファイルは
mic_rec.py
とする
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 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
で試した時には
1 | model = WhisperModel( "large-v3" , device= "cpu" , compute_type= "int8" ) |
としたので
この設定を使う
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 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() |
で実行
しかし
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 に変更してみてください
ということで
1 | CHUNK = 2048 # もしくは 4096 |
で試す
また
エラーハンドリングの追加: オーバーフローエラーが発生した場合に備え、
例外処理を追加してストリームを正しく閉じるようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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() |
これらを追加して
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 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() |
としたが
実行すると
1 | 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” とします。
ということで
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 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() |
実行すると
1 2 3 | 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+マイク録音編】
と組み合わせることにする