🎉

ローカル環境で音声・立ち絵付きのAIと会話できるソフトウェア ez-chat-llm を作りました。

2023/12/27に公開


つくよみちゃんイラスト素材:花兎*さん

概要(忙しい人向け)

  • 手軽にローカル LLM (音声・立ち絵付き) と会話できるソフトウェア ez-chat-llm を開発しました。動作の様子は動画 (https://www.nicovideo.jp/watch/sm43196446) からご覧いただけます。

  • ez-chat-llm は、GitHub のリポジトリ (https://github.com/offtoung/ez-chat-llm) から利用できます。また、Google Colab Pro をお使いの方は、ノートブックから簡単に試せます。

  • 副産物として、Pythonから簡単に利用できる音声合成ライブラリ eztts ができました。なんと、このために音声合成モデルをフルスクラッチで学習するという手の込みようです。 上記の GitHubリポジトリをクローンしたディレクトリに入り、次のようなコードを実行すると音声合成が実行できます (音声保存のために pip install soundfile が必要です)。

from modules import ezttsModel
import soundfile as sf

model = ezttsModel("configs/voice/tsukuyomi-chan-vits.json")
text = "メロスは激怒した。必ず、かの邪智暴虐の王を除かなければならぬと決意した。"

wav = model.tts(text)
sf.write("out.mp3", data=wav, samplerate=16000)

謝辞

  • 本ソフトウェアを開発するモチベーションには、夢前黎さんが企画されているつくよみちゃんプロジェクトの存在が非常に大きかったです。最初は LLM をファインチューニングするコーパスを使いたかっただけなのに、せっかく高品質な音声コーパスがあるのなら音声合成モデルを作ろうかと思い、さらに、せっかく花兎*さんが描かれた魅力的な立ち絵素材が豊富にあるのなら WebUI で動かしてみようかと思うなど、どんどん沼にはまってしまいました。このような素晴らしいコンテンツを無料で公開いただいていることに深く感謝いたします。さらに、音声合成モデルの事前学習において、みんなで作るJSUTコーパスbasic5000の夢前黎さんの音声を使用させていただきました。大変貴重なデータセットをありがとうございます。
  • 今回、既定の音声モデルとして黄琴海月さんルナイトネイルさんの音声を学習したモデルをそれぞれ作成させていただきました。とても素敵なお声の音声コーパスを寛大な利用規約で公開していただいたこと、心より感謝いたします。
  • 音声合成モデル開発にあたっては、大規模な音声コーパスである Reazon Speech データセットを使用させていただきました。膨大な労力が注ぎ込まれたと思われるこのデータセットがなければ、私のような素人には到底、音声合成モデルの開発はできませんでした。厚く御礼申し上げます。

開発の背景と経緯

最近、AI 界隈でもっとも熱いトピックの一つに ローカルLLM が挙げられます。これは、ChatGPT のような対話 AI モデルをローカル環境 (自宅の PC) にインストールして動作させるという夢の技術です。ローカル LLM については、Sald ra さんの記事に詳しいです。

ローカル LLM を動かすときのインターフェースとしては、oobaboogaさんのtext-generation-webuiが有名です。これは非常に多機能で素晴らしいのですが、一方で、見た目があんまり可愛くないという問題点が存在します。もちろん、見た目がややこしくなるのは多機能であることの裏返しなので仕方がないことですし、ベースとなっている Gradio というフレームワーク自体、見栄えはあまり重視されていないようです。

そこで、機能はシンプルなものに抑えつつ、もっと目に馴染みやすい見た目のソフトウェアがあっても良いだろうと思い立ちました。また、前述の「つくよみちゃん」との遭遇も合わさって、せっかくなので音声合成や動く立ち絵と組み合わせて、楽しくAIと会話できるツールが作りたいと考えるようになりました。

ある程度 Python と JavaScript での開発の経験があれば、このようなソフトウェアの UI やバックエンドをコーディングすることは比較的容易です (※時間をかければなんとかなるの意)。

また、対話モデルについてはオープンなモデルがたくさん出てきていますし、QLoRA (https://github.com/artidoro/qlora) を使えばファインチューニングも難しくありません。
特に、CyberAgent 社が公開された calm2-7b-chat を素体としてファインチューニングすると、元のデータセットへの忠実度の高いモデルが簡単に得られます。今回は、ez-chat-llm 向けに、つくよみちゃんデータセットを用いて calm2-7b-chat をファインチューニングしたモデル tsukuyomi-chan-calm2-7b を公開しました。

ということで、UI 部分と LLM 部分についてはまあ何とかなります。

問題は、音声合成モデルの部分です。

現在、日本語向けに利用できる無料の音声合成ツールとして、VOICEVOXCOEIROINK などの素晴らしいソフトウェアが既に存在しています。しかし、これらのソフトウェアは、ユーザがアクセントを細やかに調整して自然な発話をさせる機能を充実させることに主眼が置かれていて、ローカルLLM と会話するという目的で使うにはちょっと大掛かりすぎる感じがあります。また、これらのソフトウェアをインストールするのにもひと手間必要ですし、さらには音声合成モデルのライセンス上、他のアプリケーションに組み込んで配布することは難しいです。

そこで、開発の目標として

という要件を満たす音声合成ライブラリの作成を据えました。

まず、後者については、いろいろ調べ物をしてみれば道筋がつけられました。具体的には、ローカルLLM 愛好家にはお馴染みの Hugging Face Transformers に今年、音声合成モデルの VITS が追加され、VITS 公式リポジトリで学習したモデルからの変換スクリプトも公開されました。Hugging Face Transformers はかなり使いやすいので、これに乗っかればなんとでもなりそうです。

一方、前者のライセンス問題はかなり厄介です。実は日本語の音声合成向けデータセットは非常に限定的であるというのが現状です。
東大の高道慎之介先生がJSUTコーパスを始めとする高品質な音声合成コーパスを多数公開されていますが、これらの多くは商用利用に制限があり、つくよみちゃんキャラクターライセンスならびにつくよみちゃんコーパスライセンスを継承させることができません。
例えば、有名な学習フレームワークである ESPnet にはつくよみちゃんの学習済みモデルが存在しますが、これは事前学習に JSUT コーパスを利用しているのでつくよみちゃんキャラクターライセンスならびにつくよみちゃんコーパスライセンスを継承できません。

なお、現状もっとも有名なつくよみちゃんボイスは COEIROINK のモデルだと思いますが、こちらは開発者のシロワニさんが有志に音声データ提供を呼びかけることで JSUT コーパスに依存しないモデル学習に成功された結果のようです。

2023/12/27 追記:この記述は正しくないという情報提供をいただきました。 これはシロワニさんが COEIROINK の前身である「つくよみちゃんトークソフト」を開発されていたときの話で、有志の方から集められた音声は実験に活用されたものの、最終的な音声合成モデルの学習には使用されなかったようです (https://shirowanisan.com/entry/2021/09/04/094259)。

音声合成モデル開発へのアプローチ

そこで私が今回取ったアプローチが、大規模な音声コーパスである Reazon Speech データセットを音声合成の学習に転用するというものです。このデータセットは、19,000時間にもおよぶテレビの字幕と音声データを解析し、短い時間ごとに音声を切り出して字幕文字列とのマッチングを取ったものです。このコーパスの作成法自体が面白いので一読をおすすめします。

もちろん、このデータセットは音声認識タスク向けであり、音声合成には全然向いていません。背景に BGM は流れていますし、複数の話者の音声が入っていることも多く、また、テレビの字幕は必ずしも発話音声と完全に一致していません。

ただ、とにかく大規模なデータなので、きっと事前学習には向いているだろうというのが私の見立てでした。特に、私が意識したのは、LLM 界隈で有名な表面アライメント仮説です。これは、膨大な事前学習によってAIモデルは既に知識を蓄えており、ファインチューニング (や強化学習) のステップでは蓄えた知識に基づく「好ましい出力」を学習するというものです。
音声合成においても表面アライメント仮説が成り立つのであれば、高品質でない膨大なデータからの事前学習と、高品質な少数データを用いたファインチューニングの組み合わせで、まともな音声合成モデルが作れるはずです。実際、LLM の事前学習で使われているデータはかなり雑多なものなので、それと比べれば Reazon Speech データセットはかなりクリーンな方だと言えます。

実際の学習手順

とはいえ、学習に用いるデータは高品質であるに越したことはありません。そこで、必要なのが丁寧な前処理です。私は今回、データに次の前処理を施しました。

  1. 長すぎる、または短すぎるデータを除外
  2. pyannote により話者検出を行い、複数話者の存在するデータを除外。
    ついでに無音区間も削除。
  3. Demucs により背景音を低減
  4. Resemblyzer 特徴量と話速を用いた話者クラスタリングにより、東京地方アクセントを多く含む話者群を抽出。

まず、1から3の処理と、4で使う特徴量の計算を行う必要があるのですが、これにものすごく時間がかかります。私は今回、前処理に 2 週間程度を費やすことで Reazon Speech データセット全体の 1/3 くらいの量を処理することができました。データセット全体を使うには前処理だけでさらに 1ヶ月程度必要な計算です (実際にはストレージの問題があるので当面は保留)。

さらに、4の作業はもっと泥臭いです。まず、音声特徴量と話速を使って40クラスタに分類しました。そして一旦、これらを用いて40話者音声合成モデルを学習し、生成音声を聞いてみて、東京地方アクセントがきちんと学習できていそうな話者クラスタを手作業で選別しました。そして、話速が極端に遅いあるいは速いクラスタを除外した上で女声と男声の二種類にマージすることで、最終的にアナウンサー風の喋り方の女声データと男声データを抽出しました。この作業を丁寧に行うことで、最終的な合成音声のアクセントが安定するようになりました。

こうして得られた音声データ約 79 万件を用いて女声と男声の 2 話者音声合成モデルを学習しました。学習時間は RTX3090 を用いて 3 日程度です。
多数の話者の混合になっていることもあり、この段階での生成音声はあまり美しいものではありません。そこで、次の段階として、みんなで作るJSUTコーパスbasic5000の夢前黎さんの音声で女声話者のみについて継続事前学習を行いました。このステップでは、学習が進むにつれて音声品質は改善する一方、イントネーションが平坦になってくるので、そのトレードオフを取るために2時間半程度で学習を止めました。

さらに、その結果得られたモデルをファインチューニングし、つくよみちゃん、ルナイトネイルさん、黄琴海月さんの音声合成モデルを作りました。このステップの所要時間は 15 分から 20 分程度でした。オリジナルの音声の素敵な声質には到底及ばないのは確かですが、冒頭の動画をご覧いただければ分かるように、素人が作った合成音声としてはなかなかの品質になったのではないかと思います。

また、新しい話者モデルを追加するのに意外と大した時間を要さないことも今回の発見でした。要望があれば、今後も話者モデルを追加したいと思います。

おわりに (Web UI についての補遺)

上記のような経緯で、私はローカル LLM とお話したかっただけなのに、なぜか音声合成モデルの開発を延々とやることになりました。そのため今回の記事では音声合成の解説に大きな比重を置いてしまいましたが、実は Web UI のほうにもそれなりに工夫が入っています。特に、AI の出力に合わせて立ち絵画像を切り替える仕組みは我ながら中々気が利いているのではないかと思います。

従来は、このような立ち絵の切り替えには、LLM から明示的に感情を出力させるという方法が取られてきました。しかし、現状のローカル LLM はあまり賢くないので、そんなマルチタスクをさせたくありません。そこで思いついたのが、テキスト抽出などで用いられる埋め込み (embedding) の利用です。embedding というのは、文字列をベクトル特徴量に変換したもののことで、文字列間の類似度や距離を算出することを可能にするものです。これを使って LLM の出力文字列と感情を表す語句との類似度を計算し、それに基づいて立ち絵を切り替えれば、感情判定の処理が軽量に実装できるというアイデアです。実際、今回のバージョンでは Multilingual-E5-large を利用しているのですが、なかなか自然な出力が得られているように思います。ぜひ、遊んでみてください。

Discussion