Jetson Orin Nano Whisper音声認識チュートリアル【リアルタイム字幕作成】

Jetson Orin Nano Whisper音声認識チュートリアル【リアルタイム字幕作成】

Jetson Orin NanoでWhisperを動かし、マイク入力からリアルタイムに字幕を生成する手順をまとめました。OpenAIが公開したWhisperは精度の高い音声認識モデルですが、Jetsonで実用的な速度で動かすには設定の工夫が必要です。

この記事でわかること

  • Jetson Orin NanoにWhisperをインストールする手順
  • USBマイクから音声をリアルタイムに取り込む方法
  • Whisperのモデルサイズと速度・精度のトレードオフ
  • faster-whisperを使ってJetson向けに推論を高速化する方法
  • 字幕をターミナルにリアルタイム表示するPythonスクリプトの書き方
  • 動作確認環境

    まず筆者の手元での動作確認環境を明示しておきます。

  • ハードウェア: Jetson Orin Nano Super 8GB NVIDIA Jetson Orin Nano 開発者キット(Amazon)
  • JetPack: 6.2(L4T 36.4)
  • Python: 3.10
  • マイク: USB接続の汎用マイク(LogitechのH540)
  • ストレージ: NVMe SSD Western Digital SN770 500GB NVMe(Amazon)(モデルファイルが大きいのでSSDを強く推奨)
  • Whisperのモデルファイルはlarge-v3サイズで約3GBあります。microSDカード Samsung microSDXC 128GB (Endurance)(Amazon) をルートに使っている場合はSSDへの移行を検討してください。

    Whisperのインストールと環境構築

    必要なパッケージを先にインストールする

    Whisperの動作にはPortAudio(マイク入力)とffmpegが必要です。

    
    sudo apt update
    sudo apt install -y portaudio19-dev ffmpeg
    

    Python仮想環境を作る

    システムのPython環境を汚さないように仮想環境を用意します。

    
    python3 -m venv ~/whisper_env
    source ~/whisper_env/bin/activate
    

    faster-whisperをインストールする

    オリジナルのwhisperパッケージでも動きますが、Jetsonではfaster-whisperを使うほうが実用的な速度が出ます。faster-whisperはCTranslate2をバックエンドに使い、INT8量子化に対応しているためメモリ消費と推論速度が大幅に改善されます。

    
    pip install --upgrade pip
    pip install faster-whisper==1.0.3
    pip install pyaudio numpy
    

    インストール後、CTranslate2がJetsonのCUDAを認識しているか確認します。

    
    python3 -c "import ctranslate2; print(ctranslate2.get_cuda_device_count())"
    

    1と返ってくれば問題ありません。

    モデルのサイズ選びとJetsonへの影響

    Jetson Orin Nano Superで実用になるモデルサイズの目安です。

    | モデル | ファイルサイズ | VRAM使用量 | 日本語精度 | 推論速度(目安) |

    |——–|————–|———–|———–|—————-|

    | tiny | 約75MB | 約400MB | 低め | 非常に速い |

    | base | 約145MB | 約600MB | 普通 | 速い |

    | small | 約460MB | 約1.2GB | 良い | 普通 |

    | medium | 約1.5GB | 約2.8GB | 高い | やや遅い |

    | large-v3 | 約3GB | 約5.5GB | 非常に高い | 遅い(厳しい) |

    日本語認識を重視するならsmallmediumが現実的な選択です。筆者は普段smallを使っています。8GBモデルであればmediumも動きますが、リアルタイム字幕には遅延が生じます。Orin Nano SuperではsmallでRTF 0.3程度の高速化が確認されています。

    リアルタイム字幕を生成するPythonスクリプト

    音声デバイスの確認

    まずUSBマイクのデバイスインデックスを確認します。

    
    python3 -c "
    import pyaudio
    p = pyaudio.PyAudio()
    for i in range(p.get_device_count()):
        info = p.get_device_info_by_index(i)
        if info['maxInputChannels'] > 0:
            print(i, info['name'])
    p.terminate()
    "
    

    USBマイクのインデックス番号(例: 2)をメモしておいてください。

    リアルタイム字幕スクリプト本体

    以下のスクリプトをrealtime_caption.pyとして保存します。

    
    import pyaudio
    import numpy as np
    import threading
    import queue
    from faster_whisper import WhisperModel
    
    # --- 設定 ---
    MODEL_SIZE = "small"          # tiny / base / small / medium
    DEVICE_INDEX = 2              # 上で確認したマイクのインデックス
    SAMPLE_RATE = 16000
    CHUNK_DURATION = 3            # 秒ごとに認識(短いと精度が下がる)
    LANGUAGE = "ja"
    
    # モデルの読み込み(初回はダウンロードが走る)
    print(f"モデル '{MODEL_SIZE}' を読み込んでいます...")
    model = WhisperModel(MODEL_SIZE, device="cuda", compute_type="int8")
    print("モデルの読み込み完了")
    
    audio_queue = queue.Queue()
    
    def audio_capture():
        p = pyaudio.PyAudio()
        stream = p.open(
            format=pyaudio.paInt16,
            channels=1,
            rate=SAMPLE_RATE,
            input=True,
            input_device_index=DEVICE_INDEX,
            frames_per_buffer=1024
        )
        print("録音を開始しました。Ctrl+Cで終了します。")
        while True:
            frames = []
            for _ in range(0, int(SAMPLE_RATE / 1024 * CHUNK_DURATION)):
                data = stream.read(1024, exception_on_overflow=False)
                frames.append(np.frombuffer(data, dtype=np.int16))
            audio_chunk = np.concatenate(frames).astype(np.float32) / 32768.0
            audio_queue.put(audio_chunk)
    
    def transcribe():
        while True:
            audio_chunk = audio_queue.get()
            segments, info = model.transcribe(
                audio_chunk,
                language=LANGUAGE,
                beam_size=5,
                vad_filter=True  # 無音区間をスキップして速度向上
            )
            text = "".join([seg.text for seg in segments]).strip()
            if text:
                print(f"[字幕] {text}")
    
    # スレッド起動
    capture_thread = threading.Thread(target=audio_capture, daemon=True)
    transcribe_thread = threading.Thread(target=transcribe, daemon=True)
    
    capture_thread.start()
    transcribe_thread.start()
    
    try:
        capture_thread.join()
    except KeyboardInterrupt:
        print("\n終了しました。")
    

    実行方法

    
    source ~/whisper_env/bin/activate
    python3 realtime_caption.py
    

    vad_filter=TrueはVoice Activity Detection(発話区間検出)の略で、無音部分をスキップしてくれます。これを有効にするだけで処理が体感的にかなり軽くなります。

    つまずきやすいポイントと対処法

    CUDAが使われずCPUで動いてしまう

    compute_type="int8"はGPUでも動きますが、環境によってはfloat16に変更すると安定する場合があります。

    
    model = WhisperModel(MODEL_SIZE, device="cuda", compute_type="float16")
    

    それでも遅い場合はデバイスを"cpu"に落として動作確認し、CUDA環境の問題を切り分けてください。JetPack 6.2ではcuDNN 9.xの互換性問題が稀に発生します。

    音声が途切れる・バッファオーバーフローが出る

    CHUNK_DURATIONを長くするか、frames_per_buffer2048に増やすと改善するケースが多いです。冷却が不十分だとCPUがサーマルスロットリングを起こし音声処理が追いつかないこともあるので、冷却ファン Noctua NF-A4x10 5V PWMファン(Amazon) の状態も確認しましょう。

    日本語の精度が低い

    beam_size1から5に増やすと精度が上がりますが推論時間も長くなります。また、smallよりもmediumに切り替えると日本語認識の精度は明確に改善します。Whisper large-v3-turboが利用可能なら精度向上しますがVRAMが厳しいです。

    実際に使ってみた感想

    smallモデルをCUDA + INT8で動かした場合、3秒のチャンクに対して認識に約1〜2秒かかります。つまり合計で4〜5秒の遅延が発生します。厳密なリアルタイムではありませんが、会議の補助字幕や動画のキャプション生成用途であれば十分実用的です。

    mediumモデルでは精度が上がる反面、認識に3〜4秒かかるため遅延がやや気になります。用途に応じて使い分けるのが現実的です。

    Jetson入門書 エッジAI入門 Jetson実践ガイド(Amazon) でエッジAIの基礎を固めながら、こういった音声AIアプリを組み合わせていくと応用の幅が広がります。

    まとめ

    Jetson Orin Nanoでのリアルタイム字幕作成について、インストールから動作するスクリプトまでを一通り解説しました。ポイントをまとめます。

  • faster-whisperとINT8量子化の組み合わせがJetsonには最適
  • 日本語認識の実用レベルはsmallmediumモデル
  • vad_filter=Trueは必ず有効にする
  • 遅延はチャンク時間 + 推論時間の合計になる点を把握しておく
  • モデルファイルが大きいのでNVMe SSDへの保存を推奨
  • 音声認識を起点にして、翻訳APIと組み合わせたリアルタイム翻訳字幕や、音声コマンドによるロボット制御など、応用の幅は非常に広いです。ぜひ試してみてください。

    次はこちら

    Whisperと組み合わせたAIアプリ開発に興味があれば、TensorRTによる推論高速化やローカルLLMとの連携も参考になります。

  • Jetson Orin Nano TensorRT高速化チュートリアル
  • Jetson Orin NanoでローカルLLMを動かす
  • Jetson Orin Nano 熱対策・冷却方法まとめ
  • コメント

    タイトルとURLをコピーしました