見出し画像

Qwen3-TTS ボイスクローンWEBアプリ&API作ってみた ~お試しから本格運用まで広くカバー~

こんにちはRcatです。
今回は先日試したQwen3-TTSによるボイスクローンを本格運用に持っていく環境整備を行います。
具体的には、事前にクローンを済ませておいて、あとはいつでも画面やAPI経由でテキストだけ渡せば音声ファイルを返せる状態にしておく感じですね。
あとはお好きにLLMと連携して…楽しさ無限大ですね!



はじめに

利用規約

情報や作品の活用時は事前に利用規約をご確認ください。

コメントについて

利用規約のガイドラインを確認の上コメントしてください。
則っていないコメントは削除します。


概要

無料ボイスクローン Qwen3-TTSって?

詳細はこちらで紹介していますが、簡単に説明すると、3秒程度の音声からその人の声を再現してしまうAIです。
再現すれば好きなセリフをしゃべらせることができます。

Qwen3-TTS WEB UIの紹介

概要

ではメインの紹介と解説行きます。
今回作成したのは、Qwen3-TTSをボイスクローンと生成を分離して利用できる環境です。

これにより、事前にクローンしておけばいつでも同じキャラクターを再現可能であったり、即時キャラ切り替えができたりと汎用性が向上します。

また、生成時も初心者向けに画面で生成を行ったり、CSVをアップロードして一括生成したりできます。
上級者は、この画面がバックエンドで使っているAPIにダイレクトアクセスすることで、ご自分のプログラムと統合することが可能です。
例えば、LLMの回答を読み上げさせることでボイスチャット化したり…。

前提

まずは本作を動かす前提です

  • Python 3.11
    Rcatの環境です。
    12、13くらいなら合わなくても動くとは思いますが、動かない場合はこのバージョンで試してください

  • FFMPEGコマンドが使える状態

    • Windowsの場合はあらかじめビルド済みバイナリを落としておき、PATHを通してCMDからffmpegと打つだけで起動する状態にします

    • Linuxの場合
      ここで紹介しています

  • OS

    • Windows11
      開発環境です

      • CUDAの場合
        VRAM 6G以上のGPU

      • CPUの場合
        16GB以上のメモリ

    • Linux (Ubuntu)
      運用環境です

      • CPUの場合
        空き10G以上のメモリ
        できるだけ強力なCPU

      • GPUの場合
        準備中

WEB画面で使う

まずはWEB画面で操作を紹介します。
起動方法などはこの後紹介しますのでご安心ください。
ちなみにログインはテンプレでくっついてるだけなので使いません。

音声プロファイルの作成(クローン)

まずはクローンから始めましょう
クローン画面にアクセスします

wavファイルを選ぶか、ドラッグ&ドロップしてリストに追加します。
この時、ファイル名をしゃべっている内容にしてください。そうすることでクローン時のテキスト入力を省いています。
素材を上げたらクローン開始ボタンを押します。

クローンはすぐ終わりますが、サンプルの合成にPC性能に応じて数秒から数分かかります。30万クラスのPCなら数秒ですね。
完了後、プレビュー音声ができていますので、一度再生してみて下さい。
気に入ったらプロファイルを保存ボタンを押すと、ダイアログが出て名前を付けられます。
これでクローンは完了です。

気に入らない場合は、素材を変更するか増やします。
本作はオリジナル機能として、複数の音声の特徴量を平均化する機能があります。
これにより、複数の短い音声を使ってより安定したプロファイルを作成することができます。
なお、素材により大きく左右される模様なので、できるだけ様々なものを用意して全組み合わせのパターンを行います。
必ずしもすべて合わせるのがいいわけではないようです。

MOMOは超ムズイ…

音声の生成(読み上げ)

プロファイルができたら生成を行いましょう。音声生成に入ります。
ゲーム内でボイスが当たっていないセリフを言わせてみます。

しゃべらせたい内容を入力したら、右側でプロファイルを選択します。今回はさっき作ったモモですね。

再生速度も変更できますが、まずは1倍で。
生成後に速度だけ変更する場合は、既に生成したキャッシュを倍速化するだけなので一瞬で終わります。

プレビューを押して満足のいく音声だったらダウンロードを押して完了です!

一括生成-バッチモード

ちっらっと見えていたかもしれませんが、一番下にCSVからバッチ生成という項目があります。
まぁ当たり前ですね。いちいち入力してから保存してたら日が暮れちゃいますし。
なので、事前にCSVファイルに言うことをまとめておいて、一括生成する機能があります。
低スぺでも放置できるのも魅力です!

まずは元となるCSVを用意します。
一番上はヘッダーで無視、その下に内容です。
左から、クローンプロファイル、発言内容、倍速値、ターゲット秒です。

倍速とターゲットは省略可能で、両方の場合はターゲットが優先されます。
ターゲット秒は、生成された音声の秒数とターゲットの秒数比率から倍速を逆算して倍速化するものです。完全には合いません。
主に吹き替えなどで、セリフの速度があっていないと困るときに使います。
なお、倍速は0.5~2までなので、この範囲で合わせられない場合は範囲内での調整になります。

オリジナルストーリー弓の練習

保存時は、BOM付きUTF-8のCSVとして保存してください。
これならExcelでも開けますし、SJISのような今どきでない文字コードを使うこともないです。

Excel2024保存画面

保存したCSVを選択してアップロードするとバッチ生成が始まります。
生成が終わると、zipファイルがダウンロードされますので、中身を見るとこんな感じ。
なお、中身が不明なzipファイルなので、chromeだと警告が出ますが、自分のPC生成したファイルなので大丈夫です

各行ごとのファイルが出来上がっています。あとはお好きにどうぞ。

一括生成-マージモード

CSV選択ボタンの隣にマージモードのチェックがあります。
これをONにしてから開始することで、zipファイルではなく単一のmp3ファイルとしてDLすることができます。
動画の素材などではなく、単純に一つの音声がほしいだけの場合は、つなげる手間がないので楽です。


APIを直に叩く

メインイベントですね。まぁWeb UIでも半分くらいの人は満足しそうですが、私的にはやはりAPIでLLM連携なんかができないとつまらないですね。
まぁWEB UIがそもそもこのAPIたたいてるので、特に専用の実装があるわけでもないんですがw

音声プロファイルの取得

プロファイルはWEB画面で作成している前提です。
ここで得たIDで次の生成を行います

  • エンドポイント
    /profile_list

  • メソッド
    GET

  • レスポンス
    JSON

応答

[
  {
    "id":プロファイルID(str),
    "name":プロファイル名
  },
  ...複数ある場合は続く
]

使用例

>>> import requests as rq
>>> import json

>>> reqp = rq.get("http://localhost:8080/profile_list")
>>> print(json.dumps(reqp.json(),indent=2,ensure_ascii=False))
[
  {
    "id": "d657fad55aef75bbe7ccad2e3885e8f3",
    "name": "ニキ"
  },
  {
    "id": "3ecd974768bea97d1d4d8189c42478f1",
    "name": "談幽"
  },
  {
    "id": "5af0730ff5e676bbc5213743970dc967",
    "name": "モモ"
  }
]

生成

上記で得たIDでキャラクターを指定し、任意のテキストやパラメータで調整します。

  • エンドポイント
    /generate

  • メソッド
    POST

  • BODY
    JSON

  • レスポンス
    JSON

リクエストボディ

{
"profile_id":使用するプロファイルのID(str),
"text":しゃべらせる内容(str),
"speed":倍速(float),
"target_length":ターゲット秒(float),
}

応答

{
"data":生成された音声バイナリ(mp3)をbase64エンコードした文字列(str),
"length":音声の実長(float)
}

使用例

>>> import base64
>>> import secrets
>>> import requests as rq

>>> def save(bin):
...   with open(f'{secrets.token_hex(4)}.mp3',"wb") as f:
...     f.write(bin)

>>> js = {"profile_id":"d4d2be398211794645ec63bf3e2871ca","text":"おかえりなさいませ。お嬢様"}
>>> resp = rq.post("http://localhost:8080/generate",json=js)
>>> save(base64.b64decode(resp.json()["data"]))

#生成パラメータをいじる場合

>>> params = {
... "temperature":0.1
... }
>>> resp = rq.post("http://localhost:8080/generate",json=js | params)
>>> save(base64.b64decode(resp.json()["data"]))

#生成パラメータをいじる場合2

>>> params = {
... "temperature":1.0,
... "top_p":0.2,
... "top_k":40
... }
>>> resp = rq.post("http://localhost:8080/generate",json=js | params)
>>> save((base64.b64decode(resp.json()["data"]))

感覚的に、temperatureを上げると声質のばらつきが大きくなる感じがします。
声質は変化されると困るので、temperatureは下げ一択ですね。

この応答をどうするかはあなた次第!いろいろ組み込んで楽しみましょう!


環境構築

ここからは本作をご利用いただくための手順解説です。

ツールのダウンロード

末尾のリンクより配布していますので、好きなところに展開してください
大体下記のような感じになるはずです。

設定関連

.envというファイルが設定ファイルです。
変更箇所はここだけです。

デバイスは、GPUがあって使える人は書き換え。
モデルパスは各自あらかじめクローンしてきたフォルダを指定。現状1.7Bの方しか参照しないので、どっちを持ってきても1.7の方に設定します。
生成パラメータはデフォルト値を設定。変えたい方はお好きに。

requirementsを選択する
Rcatの動作した環境で生成したものを格納しています。
OS違いで作ったので、使用する方を選んでrequirements.txtに名前を変えておいてください。

Windows

  • create.batを実行する
    pythonが入っていればダブルクリックでOK
    仮想環境の構築とライブラリのインストールを自動で行います
    ※GPUを使う場合はtorchを自分で入れる必要があります。

  • dbinit.batを実行する
    起動前にデータベースの初期化が要ります。
    これもダブルクリックでOK

  • start.batを実行して起動する
    ダブルクリックで起動。もう使えます。
    →次回以降はこのstart.batのクリックだけでOKです。

  • WEB UIにアクセス
    デフォルトの場合は下記URLでアクセス可能
    http://localhost:8080

Linux(通常の方法-CPU)

windowsとほぼ同じです。実行するのが*.shのシェルに変わるだけ。

  • create.shを実行する
    詳細はWindowsと同じです

  • dbinit.shを実行する
    詳細はWindowsと同じです

  • start.shを実行して起動する
    詳細はWindowsと同じです

  • WEB UIにアクセス
    詳細はWindowsと同じです
    ただしLinuxがホストマシンでない場合はufwに穴をあけておきましょう。

  • systemdに登録する
    これは任意。やっておくとLinux起動時に立ち上がります。

実行結果例

メモリは10G行きますね。RyzenAI Max+395は32Tなので、性能を生かし切れてなさそう。
ちなみにクローン用の短いサンプル生成に26秒
PASSMARK 55000越えCPUでこれとかやっぱ重いな。バッチ処理放置が現実的

GPUを使う場合

torch関連のライブラリのgpu対応バージョンをインストールすればGPUで動きます。
現在はCPU用でリストになっているので、ここは削除して先にgpu版のtorchを入れてから、手動でpip install -rをしてください。

素材の調達方法は?

基本的に個人で使う分にはコピーガードを外さない限り何をしても大丈夫なはずです。

今回のニキやモモは、ゲームの設定でボイス以外の音量を0にしたうえでイベントクエストを録画しながら進めました(やってることは実況や配信と同じ)。
その結果、純粋なボイスだけの動画が取れるわけですね。
まぁ公式の二次創作ガイドライン的には内容が微妙なので、今回サンプルは載せてないんですけど。

あとはffmpegで音声だけ動画から切り離したものをAudacityのようなオーディオ編集ソフトで必要な部分だけ切り出したwavを作れば完成。

しゃべってる内容をファイル名にするのが面倒だったので、whisperを使って自動で名付けしたりもしましたが、これはまた別のお話w

声優さんの声が欲しいなら、ラジオやテレビの音声の録音などの手段もありです。
録音はコピーではないので著作権上も問題ありません(たまたま入っちゃった体)。
さらに言えば現状の法律では、声は"知的"財産ではないので、クローン後はプロファイルを商用にしちゃっても大丈夫だったはずです(さすがにどうかと思うからやらないけどね)。

まぁ似過ぎた音声を作らないように、平均化機能を使って混ぜて、新しいミラクルボイスなんかを作ればいいんじゃないですかね。

個人ではご自由に。それ以上は自分のために最低限モラルだけ守って使いましょう。


まとめ

今回はQwen3-TTSを自分の環境で使い倒せるようにWEB UI及びAPIを構築しました。
今後はこれをLLMと組み合わせてDisocrdのボイスチャンネルに参加したり…など妄想が膨らみますね。
このAI、かなりシビアなものだと思うのでくれぐれも炎上しないように気を付けましょう。


配布情報

配布URL

以下のURLより配布しています。
利用規約に同意の上ご利用ください。

https://script.google.com/macros/s/AKfycbxdcr8pnazR7RbjaSICTtaNWfN7h_rjQrKlZ3h9CZpPRFzRILk1OGc8mZqKbF-NXNO9/exec?name=Qwen3-TTS_WEBUI

配布情報

追加のキーワードについては下記より確認可能です

リンク集

感想投稿フォーム

コメントは公開で恥ずかしい!! Rcatだけに送りたい人向け

Pythonのインストール方法

【Linux】Systemd追加支援スクリプト

LoggingBOTの導入方法

ミニPCにLinuxをインストール


いいなと思ったら応援しよう!

Rcat999 情報が役に立ったと思えば、僅かでも投げ銭していただけるとありがたいです。