LoginSignup
3
2

mlxのwhisperでリアルタイム文字起こしを試してみる

Last updated at Posted at 2024-01-20

Whisperでのリアルタイム文字起こしの手法は「Whisperを使ったリアルタイム音声認識と字幕描画方法の紹介」を参考にした。

mlxのwhisperセットアップは前回の記事を参考ください。

本題

ストリーミング処理を行うには音声の無音検知が必要となるので調べたところ、faster-whisperでもVAD(Voice Activity Detector)にSilero VADを使っている。
それのJS版であるricky0123/vad書かれているコードがあったのでmlx用に一部書き直して試してみた。

ファイル構成

├── server.py
├── static
│   └── jimaku.css
├── templates
│   └── index.html

コード

server.py
import os
import time
from flask import Flask, request, render_template
import whisper
import threading

UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'m4a','mp3','wav'}
CSS_TEMPLATE_PATH = 'static/jimaku.css'
WHISPER_MODEL_NAME = "mlx-community/whisper-large-v3-mlx"

with open(CSS_TEMPLATE_PATH) as f:
   CSS_TEMPLATE = f.read()

print('loading whisper model', WHISPER_MODEL_NAME)

os.makedirs(UPLOAD_FOLDER, exist_ok=True)
app = Flask(__name__, static_url_path='/')
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

lock = threading.Lock()

@app.route('/')
def index():
   return render_template('index.html')

@app.route('/api/transcribe', methods=['POST'])
def transcribe():
   time_sta = time.perf_counter()
   print('start transcribe ' + str(time_sta))
   file = request.files['file']
   ext = file.filename.rsplit('.', 1)[1].lower()
   if ext and ext in ALLOWED_EXTENSIONS:
       filename = str(int(time.time())) + '.' + ext
       saved_filename = os.path.join(app.config['UPLOAD_FOLDER'], filename)
       file.save(saved_filename)
       lock.acquire()
       result = whisper.transcribe(saved_filename, path_or_hf_repo=WHISPER_MODEL_NAME, 
                                   language='ja', fp16=True, verbose=True)

       lock.release()
       return result, 200

   result={'error':'something wrong'}
   print(result)
   return result, 400

app.run(host='localhost', port=9000)

元のコードから大きな変更はない。
mlxのwhisper.transcribeは最初の一回目だけモデルの初期化を行うので、都度呼び出しても問題ないようだ。

positiveSpeechThreshold: 0.5,
negativeSpeechThreshold: 0.5 - 0.15,
preSpeechPadFrames: 2,
redemptionFrames: 8,
frameSamples: 1536,
minSpeechFrames: 3,

元のコードのindex.htmlのパラメータ部分だけricky0123/vadのデフォルト値にした方が私の環境ではいい感じに動いた。
あとは、preSpeechPadFrames=2にした方が喋り出しの取りこぼしが少ないように感じた。

感想など

mlxもv0.10.0で少し速くなったようだが、手元のM1 Macはメモリ8GBなのでlarge-v3を読み込むとスワップしまくりもあってとても遅い。
今回、ストリーミングの方法を調べて、音声検知を組み込むと結構いい感じにかつシンプルなコードで作れることがわかったので興味のある方は試してみると良い。

3
2
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
3
2