Closed5

生成する音声の再生時間を指定できるZeroShot TTS「VoiceStar」を試す

kun432kun432

ここで見かけた

https://github.blog/open-source/maintainers/from-mcp-to-multi-agents-the-top-10-open-source-ai-projects-on-github-right-now-and-why-they-matter

プロジェクトで特定の時間枠内に音声を出力する必要がある場合、VoiceStar の持続時間制御可能な合成機能が役立ちます。開発者は目標の長さを設定できるため、音声出力を時間制限のあるユースケース(固定長のプロンプトやナレーションなど)に合わせることができ、追加の音声編集が不要になります。

このプロジェクトには、推論用の CLI および Gradio インターフェース、およびすぐに使用できる事前トレーニング済みモデルが含まれています。音声インターフェースがアプリでますます重要になる中、このレベルの制御が可能なオープンソースモデルは、重要な一歩前進です。

なぜ重要なのか?

これは、音声の再生時間を正確に指定できるオープンなTTSモデルです。これは、吹き替え、広告、アクセシビリティオーバーレイなど、ミリ秒単位の精度が求められるシーンで役立ちます。これは、オープンソースコミュニティから提供されるAI支援の放送品質のタイミング制御です。

kun432kun432

論文(alphaXivのまとめ)

https://www.alphaxiv.org/ja/overview/2505.19462

実際に生成された音声のデモページ

https://jasonppy.github.io/VoiceStar_web/

VoiceStar は、出力の持続時間を正確に制御し、推論中に最大トレーニング時間よりも長い音声を生成できる、自己回帰型音声クローン(ゼロショット)テキスト読み上げモデルです。

VoiceStar は、未知の声をクローンしたり、録音を編集したりするために、その声の数秒間の音声しか必要としません。30 秒間の音声でトレーニングされた VoiceStar は、40 秒間の音声を生成することができます。

YouTubeにもあった

https://www.youtube.com/watch?v=rTJeabxUxJ4

GitHubレポジトリ

https://github.com/jasonppy/VoiceStar

ライセンス

コードライセンス:MIT

モデルウェイトライセンス:CC-BY-4.0(使用したEmiliaデータセットがこのライセンスであるため)

kun432kun432

READMEに従って、Ubuntu-22.04サーバ(RTX4090)で試す。

レポジトリクローン

git clone https://github.com/jasonppy/VoiceStar && cd VoiceStar

先にPython仮想環境を作る。uvで全部やろうとしたけどパッケージインストールで詰まったので、すごい中途半端なやり方で・・・

uv venv -p 3.10
uv pip install pip
source .venv/bin/activate

g2pはespeak-ngが必要。

sudo apt-get install espeak-ng

パッケージインストール

pip install torch==2.5.1 torchaudio==2.5.1 --index-url https://download.pytorch.org/whl/cu124 
pip install numpy tqdm fire
pip install phonemizer==3.2.1
pip install torchmetrics
pip install einops
pip install omegaconf==2.3.0
pip install openai-whisper
pip install gradio

モデルをダウンロード。

wget -O ./pretrained/encodec_6f79c6a8.th https://huggingface.co/pyp1/Encodec_VoiceStar/resolve/main/encodec_4cb2048_giga.th?download=true
wget -O ./pretrained/VoiceStar_840M_30s.pth https://huggingface.co/pyp1/VoiceStar/resolve/main/VoiceStar_840M_30s.pth?download=true
wget -O ./pretrained/VoiceStar_840M_40s.pth https://huggingface.co/pyp1/VoiceStar/resolve/main/VoiceStar_840M_40s.pth?download=true

では推論。まずCLIから。デモ用のリファレンス音声を使用させてもらう。

python inference_commandline.py \
  --reference_speech "./demo/5895_34622_000026_000002.wav" \
  --target_text "I cannot believe that the same model can also do text to speech synthesis too! And you know what? this audio is 8 seconds long." \
  --target_duration 8

初回はWhisperのモデルがダウンロードされるので少し時間がかかる。

出力
(snip)
[Info] No reference_text provided, transcribing reference_speech with Whisper.
100%|█████████████████████████████████████| 1.51G/1.51G [03:00<00:00, 8.96MiB/s]
(snip)

出力された。

出力
(snip)
[Info] Running TTS inference...
WARNING:phonemizer:words count mismatch on 300.0% of the lines (3/1)
WARNING:phonemizer:words count mismatch on 400.0% of the lines (4/1)
[Success] Generated audio saved to ./generated_tts/generated.wav

生成されたもの

https://audio.com/kun432/audio/voicestar-tts-demo-1

たしかに8秒。

ffprobe  ./generated_tts/generated.wav
出力
Input #0, wav, from './generated_tts/generated.wav':
  Metadata:
    encoder         : Lavf58.76.100
  Duration: 00:00:08.00, bitrate: 256 kb/s
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 16000 Hz, 1 channels, s16, 256 kb/s

5秒にしてみるとどうなるか?

python inference_commandline.py \
  --reference_speech "./demo/5895_34622_000026_000002.wav" \
  --target_text "I cannot believe that the same model can also do text to speech synthesis too! And you know what? this audio is 8 seconds long." \
  --target_duration 5

5秒で生成されているが・・・

ffprobe  ./generated_tts/generated.wav
出力
Input #0, wav, from './generated_tts/generated.wav':
  Metadata:
    encoder         : Lavf58.76.100
  Duration: 00:00:05.00, bitrate: 256 kb/s
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 16000 Hz, 1 channels, s16, 256 kb/s

生成されたものを聞くと途中で切れてしまっている。

https://audio.com/kun432/audio/voicestar-tts-demo-2

ちなみにリファレンス音声は8秒程度だった。

ffprobe demo/5895_34622_000026_000002.wav
出力
Input #0, wav, from 'demo/5895_34622_000026_000002.wav':
  Duration: 00:00:07.87, bitrate: 512 kb/s
  Stream #0:0: Audio: pcm_f32le ([3][0][0][0] / 0x0003), 16000 Hz, 1 channels, flt, 512 kb/s

逆に伸ばしてみた。

python inference_commandline.py \
  --reference_speech "./demo/5895_34622_000026_000002.wav" \
  --target_text "I cannot believe that the same model can also do text to speech synthesis too! And you know what? this audio is 8 seconds long." \
  --target_duration 12

12秒で生成されている。

ffprobe  ./generated_tts/generated.wav
出力
Input #0, wav, from './generated_tts/generated.wav':
  Metadata:
    encoder         : Lavf58.76.100
  Duration: 00:00:12.00, bitrate: 256 kb/s
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 16000 Hz, 1 channels, s16, 256 kb/s

こちらはややゆっくりの発話になった。ただ、最後に無音が1秒ぐらいはあるかな。

https://audio.com/kun432/audio/voicestar-tts-demo-3

発話させるテキストの量によるところはありそうだし、リファレンス音声の長さとかも関係あるのかな?大幅に縮めたり伸ばしたりってのには限界はありそうかな?という印象。

kun432kun432

inference_gradio.pyでGradioのWebUIも用意されている。ただ、一部だけ修正したほうがいい。248行目辺り。

(snip)
        model_root_box = gr.Textbox(
            label="Model Root Directory",
            value="/data1/scratch/pyp/BoostedVoiceEditor/runs"
        )
(snip)

モデルディレクトリのパスなのだけど、ここまでの流れだと./pretrainedにしておくと良い。

inference_gradio.py
(snip)
        model_root_box = gr.Textbox(
            label="Model Root Directory",
            value="./pretrained"
        )
(snip)

WebUIを起動

python inference_gradio.py

ブラウザで7860番ポートにアクセスるとこんな感じ。

リファレンス音声をアップロードして文字起こし、発話させたいテキストと発話時間を入力して生成、という感じで。

一応、日本語のリファレンス音声でも試してみたけど、ところどころ発話してるけど・・・って感じでイマイチな印象。英語のリファレンス音声だと問題ない。

VRAMは起動中でこれぐらいなのだけども、

出力
Fri Jun 13 14:42:24 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 560.35.05              Driver Version: 560.35.05      CUDA Version: 12.6     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GeForce RTX 4090        Off |   00000000:01:00.0 Off |                  Off |
|  0%   50C    P8             16W /  450W |    8201MiB /  24564MiB |      0%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

推論中に跳ね上がることがあって、24GBでもたまにCUDA out of memoryになることがあった。

出力
Fri Jun 13 14:44:21 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 560.35.05              Driver Version: 560.35.05      CUDA Version: 12.6     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GeForce RTX 4090        Off |   00000000:01:00.0 Off |                  Off |
| 31%   55C    P0            160W /  450W |   21485MiB /  24564MiB |     86%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+
kun432kun432

まとめ

発話した音声のピッチを変えずに音の長さを変更するには、librosaとかpyrubberbandとかsoxを使えばできなくはない。自分も過去に試してみたことはあるけど、機械的に縮めてるわけだから口調に影響する部分はあるんじゃないかなと思うし、結構品質的に微妙だった記憶がある。(自分が試したときはsoxが一番良かった)

まあそのあたりを生成時点である程度制御できるというのはメリットといえばメリットなのかな?制御できる限界はあると思うけども。

このスクラップは3ヶ月前にクローズされました