はじめに
OwlWhisperは、高速な音声認識ライブラリ「Faster Whisper」と、高品質な音声合成ライブラリ「Style-Bert-VITS2」を組み合わせたプロジェクトです。初心者でも簡単に音声認識と音声合成を体験できるように設計されています。チャットボットの応答には、Google社のGemini Proモデルを使用しています。
特徴
- WSL2、Docker、Streamlit、FastAPI、PyTorch、CUDA、Style-Bert-VITS2、Faster Whisperを使用した最新の技術スタック
- Webカメラを使った音声認識APIの提供
- 音声対話型のチャットボット機能(Gemini Proモデルを使用)
必要な環境
- Windows 10以降のOS
- WSL2 (Windows Subsystem for Linux 2)
- Docker
- NVIDIA GPUとCUDAドライバー
セットアップ
- このリポジトリをクローンします。
- WSL2とDockerをインストールし、設定します。
- NVIDIA GPUとCUDAドライバーを正しくインストールします。
.env
ファイルの設定(.env.example
を参考にしてください)
GOOGLE_AI_STUDIO_API_KEY=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
CAMERA_URL=http://host.docker.internal:8100/camera
FAST_WISPER_API_URL=http://fast-wisper-api:8181/transcribe
STYLE_BERT_VITS2_API_URL=http://style-bert-vits2-api:5000/voice
Webカメラ API の起動方法
- コマンドプロンプトを開きます。
- プロジェクトのルートディレクトリに移動します。
- 以下のコマンドを実行します:
C:\Prj\OwlWhisper>camera-api.bat
- Anacondaの仮想環境 "yva" がアクティベートされ、Webカメラ APIが起動します。
チャットボットの起動方法
- WSL2のターミナルを開きます。
- プロジェクトのルートディレクトリに移動します。
- 以下のコマンドを実行します:
maki@TurtleTower:/mnt/c/Prj/OwlWhisper$ docker-compose up
- Docker Composeが各サービス(Style-Bert-VITS2 API、Faster Whisper API、Streamlitアプリケーション)を起動します。
使い方
Chatbotの起動
- Webカメラ APIは、
http://localhost:8100
でアクセスできます。 - チャットボットは、Streamlitアプリケーションとして
http://localhost:8502
で利用できます。
キャラクターの描画
Vtude Studioでキャラクターを描画してOBS Studio等で重ねてください。
Docker Compose の設定
docker-compose.yml
ファイルでは、以下の3つのサービスを定義しています:
style-bert-vits2-api
: Style-Bert-VITS2 APIサービスowl-wisper
: Streamlitアプリケーションサービスfast-wisper-api
: Faster Whisper APIサービス
各サービスの設定には、ビルドコンテキスト、Dockerfileの場所、ボリュームマウント、ポートマッピング、環境変数、GPUリソースの割り当てなどが含まれています。
version: '3.8'
services:
style-bert-vits2-api:
build:
context: .
dockerfile: Style-Bert-VITS2/Dockerfile.external
volumes:
- ./Style-Bert-VITS2:/app
- ./Style-Bert-VITS2/model_assets:/model_assets
- ./Style-Bert-VITS2/Data:/Data
ports:
- "8000:8000"
- "5000:5000"
tty: true
working_dir: /app
command: >
sh -c "python initialize.py &&
python server_fastapi.py"
owl-wisper:
build: .
volumes:
- ./streamlit:/app
- ./demo:/demo
- ./.cache:/root/.cache
- /tmp/.X11-unix:/tmp/.X11-unix
- /mnt/wslg:/mnt/wslg
- ./.streamlit:/root/.streamlit
environment:
- PULSE_SERVER=/mnt/wslg/PulseServer
- DISPLAY=$DISPLAY
- WAYLAND_DISPLAY=$WAYLAND_DISPLAY
- XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR
ports:
- 8502:8502
- 8503:8503
env_file:
- .env
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [ gpu ]
working_dir: /app
tty: true
command: streamlit run main.py --server.port 8502
fast-wisper-api:
build:
context: .
dockerfile: faster-whisper-docker/Dockerfile
volumes:
- ./faster-whisper-docker:/app
- ./faster-whisper-docker/.cache:/root/.cache
- /tmp/.X11-unix:/tmp/.X11-unix
- /mnt/wslg:/mnt/wslg
environment:
- PULSE_SERVER=/mnt/wslg/PulseServer
- DISPLAY=$DISPLAY
- WAYLAND_DISPLAY=$WAYLAND_DISPLAY
- XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR
ports:
- 8181:8181
env_file:
- .env
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [ gpu ]
working_dir: /app
tty: true
command: uvicorn faster_whisper_api_server:app --reload --host=0.0.0.0 --port=8181
Streamlitアプリケーションのソースコード解説
main.py
ファイルには、Streamlitアプリケーションのメインロジックが含まれています。以下、コードの解説です:
import streamlit as st
from audio_recorder_streamlit import audio_recorder
import requests
import base64
import time
from PIL import Image
import cv2
import io
import os
# モジュールのインポート(音声生成、GENAIユーティリティ等)
from modules.voice_generator import generate_voice
from modules.genai_utils import genai, MODEL_GENAI, SYSTEM_PROMPT, MODEL_GENAI_V
- 必要なモジュールをインポートします。
streamlit
はStreamlitアプリケーションのフレームワーク、audio_recorder_streamlit
は音声録音ウィジェット、requests
はHTTPリクエストの送信、base64
はBase64エンコーディング、PIL
とcv2
は画像処理、io
はファイルI/O、os
はシステム操作に使用します。 modules.voice_generator
とmodules.genai_utils
から、音声生成とGemini Proモデルの機能をインポートします。
# カメラURLとビデオキャプチャの設定
CAMERA_URL = os.getenv("CAMERA_URL")
cap = cv2.VideoCapture(CAMERA_URL)
FAST_WISPER_API_URL = os.getenv("FAST_WISPER_API_URL")
- カメラURLとビデオキャプチャの設定を行います。
CAMERA_URL
は環境変数から取得し、cv2.VideoCapture
を使用してビデオキャプチャを初期化します。 FAST_WISPER_API_URL
も環境変数から取得します。
# Streamlitアプリケーションのタイトル設定
st.title("Owl Wisper DEMO")
- Streamlitアプリケーションのタイトルを設定します。
# サイドバーの設定
with st.sidebar:
st.markdown("""
<img src="https://raw.githubusercontent.com/Sunwood-ai-labs/OwlWhisper/main/docs/OwlWhisper.png" height=200px align="left"/>
""", unsafe_allow_html=True)
# 音声録音ウィジェット
audio_bytes = audio_recorder(pause_threshold=30)
ret, _ = cap.read()
if(ret):
st.success("CAM OK")
else:
st.warning("CAM NG")
input_vision = st.checkbox('画像を入力', value=True)
img_scale = st.slider('画像のスケール', min_value=1, max_value=10, value=3, step=1)
- サイドバーを設定します。
st.markdown
を使用して、OwlWhisperのロゴ画像を表示します。audio_recorder
ウィジェットを使用して音声録音機能を提供します。cap.read()
を使用してカメラの状態を確認し、正常に動作している場合は"CAM OK"、そうでない場合は"CAM NG"を表示します。st.checkbox
を使用して、画像入力の有効/無効を切り替えるチェックボックスを表示します。st.slider
を使用して、画像のスケールを調整するスライダーを表示します。
# メッセージの保存用
if "messages" not in st.session_state:
st.session_state.messages = []
st.session_state
を使用して、メッセージの保存用リストを初期化します。
# 音声データが存在する場合、Wisper APIに送信してテキストに変換
if audio_bytes is not None:
files = {"audio_file": ("audio.wav", audio_bytes, "audio/wav")}
response = requests.post(FAST_WISPER_API_URL, files=files)
if response.status_code == 200:
data = response.json()
transcribed_text = "".join(segment['text'] for segment in data["transcribed_text"])
prompt = transcribed_text
else:
st.error("音声をテキストに変換する際にエラーが発生しました。")
else:
prompt = st.text_input("What is up?")
- 音声データが存在する場合、Faster Whisper APIに送信してテキストに変換します。
requests.post
を使用して、音声データをファイル形式でFaster Whisper APIに送信します。- レスポンスのステータスコードが200(成功)の場合、transcribed_textからプロンプトを抽出します。
- レスポンスのステータスコードが200以外の場合、エラーメッセージを表示します。
- 音声データが存在しない場合、
st.text_input
を使用してテキスト入力欄を表示します。
# プロンプト(テキスト入力または音声入力からのテキスト)が存在する場合
if prompt:
st.session_state.messages.append({"role": "user", "content": prompt})
# 画像データの取得と処理
ret, image_data = cap.read()
if ret and input_vision:
height, width = image_data.shape[:2]
new_height, new_width = height // img_scale, width // img_scale
image_data = cv2.resize(image_data, (new_width, new_height))
image_data_rgb = cv2.cvtColor(image_data, cv2.COLOR_BGR2RGB)
img = Image.fromarray(image_data_rgb)
buffer = io.BytesIO()
img.save(buffer, format="JPEG")
buffer.seek(0)
img = Image.open(buffer)
# GENAIモデルを使用して画像付きでレスポンス生成
assistant_message = MODEL_GENAI_V.generate_content([prompt, img])
else:
# GENAIモデルを使用してテキストのみでレスポンス生成
assistant_message = MODEL_GENAI.generate_content(prompt)
# アシスタントメッセージの表示
if ret and input_vision:
st.session_state.messages.append({"role": "assistant", "content": assistant_message.text, "image": image_data})
else:
st.session_state.messages.append({"role": "assistant", "content": assistant_message.text})
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
if "image" in message:
st.image(message["image"], use_column_width=True)
# 音声応答の生成と再生
voice_data = generate_voice(assistant_message.text)
if voice_data:
audio_str = "data:audio/ogg;base64,%s" % (base64.b64encode(voice_data).decode())
audio_html = f"""
<audio autoplay=True>
<source src="{audio_str}" type="audio/ogg" autoplay=True>
Your browser does not support the audio element.
</audio>
"""
st.markdown(audio_html, unsafe_allow_html=True)
- プロンプト(テキスト入力または音声入力からのテキスト)が存在する場合、以下の処理を行います:
- ユーザーメッセージを
st.session_state.messages
に追加します。 - 画像データを取得し、リサイズと色空間の変換を行います。
-- 画像入力が有効で、画像データが正常に取得できた場合、MODEL_GENAI_V.generate_content
を使用して画像付きでレスポンスを生成します。 - 画像入力が無効または画像データが取得できなかった場合、
MODEL_GENAI.generate_content
を使用してテキストのみでレスポンスを生成します。 - アシスタントメッセージを
st.session_state.messages
に追加します。画像データがある場合は、メッセージに画像も含めます。 st.session_state.messages
内の各メッセージを表示します。st.chat_message
を使用してメッセージの役割(ユーザーまたはアシスタント)を表示し、st.markdown
を使用してメッセージの内容を表示します。画像データがある場合は、st.image
を使用して画像を表示します。generate_voice
関数を使用して、アシスタントメッセージのテキストから音声応答を生成します。- 生成された音声データがある場合、Base64エンコードを行い、HTMLの
<audio>
タグを使用して音声を自動再生します。
- ユーザーメッセージを
まとめ
OwlWhisperは、初心者でも簡単に音声認識と音声合成を体験できるプロジェクトです。WSL2、Docker、Streamlit、FastAPI、PyTorch、CUDA、Style-Bert-VITS2、Faster Whisperを使用した最新の技術スタックを採用しており、Webカメラを使った音声認識APIと音声対話型のチャットボット機能を提供しています。
チャットボットの応答には、Google社のGemini Proモデルを使用しています。Gemini Proは、高品質な自然言語処理モデルであり、ユーザーの入力に対して適切で自然な応答を生成することができます。
このプロジェクトを通して、音声認識・合成技術の基礎を学ぶことができます。また、提供されているソースコードを参考に、自分なりのアプリケーションを開発することもできます。
main.py
ファイルでは、Streamlitアプリケーションのメインロジックを実装しています。音声録音、画像入力、テキスト入力、音声認識、画像処理、Gemini Proモデルを使用したレスポンス生成、音声合成など、様々な機能を組み合わせて、インタラクティブなチャットボットを実現しています。
ぜひOwlWhisperを試してみて、音声認識・合成の世界を体験してみてください!プロジェクトのソースコードを参考に、自分なりのアイデアを実現することもできます。音声技術の可能性を探求し、創造的なアプリケーションを開発してみましょう!
コメント