【EmotiVoice】AIがついに感情を手に入れる。感情表現ができる音声生成AIに実際に喋ってもらった
WEELメディア事業部テックリサーチャーの中田です。
11月14日、音声合成ツールのEmotiVoiceがGitHubで公開され、誰でも様々な感情の音声を作成できるようになりました。
これにより、自分の思いのままに、好きな文章を機械に読ませることができるんです…!
さらに、ただ読ませるだけでなく、喜怒哀楽を声で表現させることも可能だとか…。
本ツールのGitHubでのスターはなんと3,500を超えており、とんでもない注目を浴びていることがわかります。
この記事ではEmotiVoiceの導入方法や、有効性の検証まで行います。本記事を熟読することで、このText2SpeechAIの凄さを目の当たりにし、手放せなくなるでしょう
ぜひ、最後までご覧ください。
EmotiVoiceの概要
EmotiVoiceは、多様な声と感情を持つText2SpeechAIです。このAIは英語と中国語に対応し、2000種類以上の声を生成できます。特に、喜びや悲しみなどの、様々な感情を表現する音声を作ることができるのが特徴です。
EmotiVoiceはオープンソースで、誰でも簡単に使うことができます。使い方としては、テキストを入力するだけで、様々な声や感情を持つ音声を生成することが可能です。
EmotiVoiceの料金体系
EmotiVoiceはオープンソースであるため、誰でも無料で利用可能です。
なお、OpenAIのWhisperをアップグレートさせた音声モデルについて知りたい方はこちらの記事をご覧ください。
→【WhisperSpeech】Whisperがさらに高性能になった音声モデルを使ってエミネムにゆっくり喋らせてみた
EmotiVoiceの使い方
今回はGoogle Colabを使います。その際、ランタイムをGPUに変更しておきましょう。
まず、以下のコードを実行して、必要ライブラリのインストールなどを完了しておきましょう。
!pip install torch torchaudio numpy numba scipy transformers==4.26.1 soundfile yacs g2p_en jieba pypinyin
!git clone https://github.com/netease-youdao/EmotiVoice.git
%cd EmotiVoice
!git lfs install
!git lfs clone https://huggingface.co/WangZeJun/simbert-base-chinese WangZeJun/simbert-base-chinese
!mkdir -p WangZeJun/simbert-base-chinese
!wget https://huggingface.co/WangZeJun/simbert-base-chinese/resolve/main/config.json -P WangZeJun/simbert-base-chinese
!wget https://huggingface.co/WangZeJun/simbert-base-chinese/resolve/main/pytorch_model.bin -P WangZeJun/simbert-base-chinese
!wget https://huggingface.co/WangZeJun/simbert-base-chinese/resolve/main/vocab.txt -P WangZeJun/simbert-base-chinese
次に、以下のコードを実行して、フォルダを作ります
!mkdir -p outputs/style_encoder/ckpt
!mkdir -p outputs/prompt_tts_open_source_joint/ckpt
次に、以下のURLから以下の3つのファイルをダウンロードしてください。ファイルサイズ大きめなので、注意してください。
- g_*(outputs/style_encoder/ckptに置く)
- do_*(outputs/style_encoder/ckptに置く)
- checkpoint_*(outputs/prompt_tts_open_source_joint/ckptに置く)
「*」には何かしらの数字の羅列が入ります。
最後に、以下のコードを実行したら、音声が生成されます。生成された音声ファイルは、「outputs/prompt_tts_open_source_joint/test_audio」フォルダに保存されます。
!python inference_am_vocoder_joint.py --logdir prompt_tts_open_source_joint --config_folder config/joint --checkpoint g_00140000 --test_file data/inference/text
恐らく「data/inference/textのテキストファイルのテキストを、音声に文字起こししているのだと思われます。その際に、感情を載せて読ませられるのだとか。
このテキストファイルの中身の文章を変えれば、自分の好きな文章を読ませることが可能です。
EmotiVoiceを実際に使ってみた
まずは、「data/inference/text」のテキストファイルの中身を確認してみましょう。
Maria_Kasper|Happy|<sos/eos> [IH0] [M] [AA1] [T] engsp4 [V] [OY1] [S] engsp4 [AH0] engsp1 [M] [AH1] [L] [T] [IY0] engsp4 [V] [OY1] [S] engsp1 [AE1] [N] [D] engsp1 [P] [R] [AA1] [M] [P] [T] engsp4 [K] [AH0] [N] [T] [R] [OW1] [L] [D] engsp1 [T] [IY1] engsp4 [T] [IY1] engsp4 [EH1] [S] engsp1 [EH1] [N] [JH] [AH0] [N] . <sos/eos>|Emoti-Voice - a Multi-Voice and Prompt-Controlled T-T-S Engine
Maria_Kasper|哭唧唧|<sos/eos> uo3 sp1 l ai2 sp0 d ao4 sp1 b ei3 sp0 j ing1 sp3 q ing1 sp0 h ua2 sp0 d a4 sp0 x ve2 <sos/eos>|我来到北京,清华大学
Sylviamb|第一章|<sos/eos> d i4 sp0 i1 sp0 zh ang1 <sos/eos>|第一章
John_Van_Stan|在昏暗狭小的房间内,我父亲躺在窗前的地板上,全身素白,显得身子特别长。|<sos/eos> z ai4 sp1 h uen1 sp0 an4 sp1 x ia2 sp0 x iao3 sp0 d e5 sp1 f ang2 sp0 j ian1 sp0 n ei4 sp3 uo3 sp1 f u4 sp0 q in1 sp1 t ang3 sp0 z ai4 sp1 ch uang1 sp0 q ian2 sp0 d e5 sp1 d i4 sp0 b an3 sp0 sh ang4 sp3 q van2 sp0 sh en1 sp1 s u4 sp0 b ai2 sp3 x ian3 sp0 d e5 sp1 sh en1 sp0 z ii5 sp1 t e4 sp0 b ie2 sp0 ch ang2 <sos/eos>|在昏暗狭小的房间内,我父亲躺在窗前的地板上,全身素白,显得身子特别长。
Phil_Benson|他光着双脚,脚趾头怪模怪样地向外翻着,一双亲切的手平静地放在胸前,手指头也是弯曲的。|<sos/eos> t a1 sp1 g uang1 sp0 zh e5 sp1 sh uang1 sp0 j iao3 sp3 j iao2 sp0 zh iii3 sp0 t ou5 sp1 g uai4 sp0 m u2 sp1 g uai4 sp0 iang4 sp0 d e5 sp1 x iang4 sp0 uai4 sp1 f an1 sp0 zh e5 sp3 i4 sp0 sh uang1 sp1 q in1 sp0 q ie4 sp0 d e5 sp0 sh ou3 sp2 p ing2 sp0 j ing4 sp0 d e5 sp1 f ang4 sp0 z ai4 sp1 x iong1 sp0 q ian2 sp3 sh ou2 sp0 zh iii3 sp0 t ou5 sp1 ie3 sp0 sh iii4 sp1 uan1 sp0 q v1 sp0 d e5 <sos/eos>|他光着双脚,脚趾头怪模怪样地向外翻着,一双亲切的手平静地放在胸前,手指头也是弯曲的。
Tony_Oliva|他双目紧闭,可以看见铜钱在上面留下的黑色圆圈;和善的面孔乌青发黑,龇牙咧嘴,挺吓人的。|<sos/eos> t a1 sp1 sh uang1 sp0 m u4 sp1 j in3 sp0 b i4 sp3 k e2 sp0 i3 sp1 k an4 sp0 j ian4 sp1 t ong2 sp0 q ian2 sp1 z ai4 sp0 sh ang4 sp0 m ian4 sp1 l iou2 sp0 x ia4 sp0 d e5 sp1 h ei1 sp0 s e4 sp1 van2 sp0 q van1 sp3 h e2 sp0 sh an4 sp0 d e5 sp1 m ian4 sp0 k ong3 sp2 u1 sp0 q ing1 sp1 f a1 sp0 h ei1 sp3 z ii1 sp0 ia2 sp0 l ie2 sp0 z uei3 sp3 t ing3 sp1 x ia4 sp0 r en2 sp0 d e5 <sos/eos>|他双目紧闭,可以看见铜钱在上面留下的黑色圆圈;和善的面孔乌青发黑,龇牙咧嘴,挺吓人的。
Mike_Pelton|母亲半光着上身,穿一条红裙子,跪在地上,正在用那把我常用来锯西瓜皮的小黑梳子,将父亲那又长又软的头发从前额向脑后梳去。|<sos/eos> m u3 sp0 q in1 sp2 b an4 sp0 g uang1 sp0 zh e5 sp1 sh ang4 sp0 sh en1 sp3 ch uan1 sp0 i4 sp0 t iao2 sp1 h ong2 sp0 q vn2 sp0 z ii5 sp3 g uei4 sp0 z ai4 sp1 d i4 sp0 sh ang5 sp3 zh eng4 sp0 z ai4 sp1 iong4 sp0 n a4 sp1 b a2 sp0 uo3 sp1 ch ang2 sp0 iong4 sp0 l ai2 sp1 j v4 sp1 x i1 sp0 g ua1 sp0 p i2 sp0 d e5 sp1 x iao3 sp0 h ei1 sp1 sh u1 sp0 z ii5 sp3 j iang1 sp1 f u4 sp0 q in1 sp1 n a4 sp1 iou4 sp0 ch ang2 sp1 iou4 sp0 r uan3 sp0 d e5 sp1 t ou2 sp0 f a4 sp3 c ong2 sp1 q ian2 sp0 e2 sp1 x iang4 sp1 n ao3 sp0 h ou4 sp1 sh u1 sp0 q v4 <sos/eos>|母亲半光着上身,穿一条红裙子,跪在地上,正在用那把我常用来锯西瓜皮的小黑梳子,将父亲那又长又软的头发从前额向脑后梳去。
Helen_Taylor|母亲一直在诉说着什么,声音嘶哑而低沉,她那双浅灰色的眼睛已经浮肿,仿佛融化了似的,眼泪大滴大滴地直往下落。|<sos/eos> m u3 sp0 q in1 sp1 i4 sp0 zh iii2 sp1 z ai4 sp1 s u4 sp0 sh uo1 sp0 zh e5 sp1 sh en2 sp0 m e5 sp3 sh eng1 sp0 in1 sp1 s ii1 sp0 ia3 sp1 er2 sp1 d i1 sp0 ch en2 sp3 t a1 sp1 n a4 sp0 sh uang1 sp1 q ian3 sp0 h uei1 sp0 s e4 sp0 d e5 sp1 ian3 sp0 j ing5 sp2 i3 sp0 j ing1 sp1 f u2 sp0 zh ong3 sp3 f ang3 sp0 f u2 sp1 r ong2 sp0 h ua4 sp0 l e5 sp1 sh iii4 sp0 d e5 sp3 ian3 sp0 l ei4 sp1 d a4 sp0 d i1 sp1 d a4 sp0 d i1 sp0 d e5 sp1 zh iii2 sp0 uang3 sp0 x ia4 sp0 l uo4 <sos/eos>|母亲一直在诉说着什么,声音嘶哑而低沉,她那双浅灰色的眼睛已经浮肿,仿佛融化了似的,眼泪大滴大滴地直往下落。
Celine_Major|外婆拽着我的手;她长得圆滚滚的,大脑袋、大眼睛和一只滑稽可笑的松弛的鼻子。|<sos/eos> uai4 sp0 p o2 sp1 zh uai4 sp0 zh e5 sp1 uo3 sp0 d e5 sp0 sh ou3 sp3 t a1 sp1 zh ang3 sp0 d e5 sp1 van2 sp0 g uen2 sp0 g uen3 sp0 d e5 sp3 d a4 sp0 n ao3 sp0 d ai5 sp3 d a4 sp0 ian3 sp0 j ing5 sp3 h e2 sp1 i4 sp0 zh iii1 sp1 h ua2 sp0 j i1 sp1 k e3 sp0 x iao4 sp0 d e5 sp1 s ong1 sp0 ch iii2 sp0 d e5 sp1 b i2 sp0 z ii5 <sos/eos>|外婆拽着我的手;她长得圆滚滚的,大脑袋、大眼睛和一只滑稽可笑的松弛的鼻子。
Cori_Samuel|她穿一身黑衣服,身上软乎乎的,特别好玩。她也在哭,但哭得有些特别,和母亲的哭声交相呼应。她全身都在颤抖,而且老是把我往父亲跟前推。我扭动身子,直往她身后躲;我感到害怕,浑身不自在。|<sos/eos> t a1 sp0 ch uan1 sp1 i4 sp0 sh en1 sp1 h ei1 sp0 i1 sp0 f u2 sp3 sh en1 sp0 sh ang4 sp1 r uan3 sp0 h u1 sp0 h u1 sp0 d e5 sp3 t e4 sp0 b ie2 sp1 h ao3 sp0 uan2 sp3 t a1 sp0 ie3 sp1 z ai4 sp0 k u1 sp3 d an4 sp1 k u1 sp0 d e5 sp1 iou3 sp0 x ie1 sp1 t e4 sp0 b ie2 sp3 h e2 sp1 m u3 sp0 q in1 sp0 d e5 sp1 k u1 sp0 sh eng1 sp1 j iao1 sp0 x iang1 sp1 h u1 sp0 ing4 sp3 t a1 sp1 q van2 sp0 sh en1 sp1 d ou1 sp0 z ai4 sp1 ch an4 sp0 d ou3 sp3 er2 sp0 q ie3 sp1 l ao3 sp0 sh iii4 sp1 b a2 sp0 uo3 sp1 uang3 sp1 f u4 sp0 q in1 sp1 g en1 sp0 q ian5 sp0 t uei1 sp3 uo3 sp1 n iou3 sp0 d ong4 sp1 sh en1 sp0 z ii5 sp3 zh iii2 sp0 uang3 sp0 t a1 sp1 sh en1 sp0 h ou4 sp0 d uo3 sp3 uo3 sp1 g an3 sp0 d ao4 sp1 h ai4 sp0 p a4 sp3 h uen2 sp0 sh en1 sp1 b u2 sp0 z ii4 sp0 z ai5 <sos/eos>|她穿一身黑衣服,身上软乎乎的,特别好玩。她也在哭,但哭得有些特别,和母亲的哭声交相呼应。她全身都在颤抖,而且老是把我往父亲跟前推。我扭动身子,直往她身后躲;我感到害怕,浑身不自在。
LikeManyWaters|我还从没有见过大人们哭,而且不明白外婆老说的那些话的意思:“跟你爹告个别吧,以后你再也看不到他啦,他死了,乖孩子,还不到年纪,不是时候啊……”|<sos/eos> uo3 sp0 h ai2 sp1 c ong2 sp0 m ei2 sp0 iou3 sp1 j ian4 sp0 g uo4 sp1 d a4 sp0 r en2 sp0 m en5 sp1 k u1 sp3 er2 sp0 q ie3 sp1 b u4 sp0 m ing2 sp0 b ai2 sp1 uai4 sp0 p o2 sp1 l ao3 sp0 sh uo1 sp0 d e5 sp1 n a4 sp0 x ie1 sp0 h ua4 sp0 d e5 sp1 i4 sp0 s ii5 sp3 g en1 sp0 n i3 sp0 d ie1 sp1 g ao4 sp0 g e4 sp0 b ie2 sp0 b a5 sp3 i3 sp0 h ou4 sp3 n i3 sp1 z ai4 sp0 ie3 sp1 k an4 sp0 b u2 sp0 d ao4 sp1 t a1 sp0 l a5 sp3 t a1 sp0 s ii3 sp0 l e5 sp3 g uai1 sp0 h ai2 sp0 z ii5 sp3 h ai2 sp0 b u2 sp0 d ao4 sp1 n ian2 sp0 j i4 sp3 b u2 sp0 sh iii4 sp1 sh iii2 sp0 h ou5 sp0 a5 <sos/eos>|我还从没有见过大人们哭,而且不明白外婆老说的那些话的意思:“跟你爹告个别吧,以后你再也看不到他啦,他死了,乖孩子,还不到年纪,不是时候啊……”
1006|我得过一场大病,这时刚刚能下地。生病期间一这一点我记得很清楚——父亲照看我时显得很高兴,后来他突然就不见了,换成了外婆这个怪里怪气的人。|<sos/eos> uo3 sp1 d e2 sp0 g uo4 sp1 i4 sp0 ch ang3 sp1 d a4 sp0 b ing4 sp3 zh e4 sp0 sh iii2 sp1 g ang1 sp0 g ang1 sp1 n eng2 sp0 x ia4 sp0 d i4 sp3 sh eng1 sp0 b ing4 sp1 q i1 sp0 j ian1 sp3 i2 sp0 zh e4 sp0 i4 sp0 d ian3 sp1 uo3 sp1 j i4 sp0 d e5 sp1 h en3 sp0 q ing1 sp0 ch u5 sp3 f u4 sp0 q in1 sp1 zh ao4 sp0 k an4 sp1 uo3 sp0 sh iii2 sp2 x ian3 sp0 d e5 sp1 h en3 sp0 g ao1 sp0 x ing4 sp3 h ou4 sp0 l ai2 sp3 t a1 sp1 t u1 sp0 r an2 sp1 j iou4 sp1 b u2 sp0 j ian4 sp0 l e5 sp3 h uan4 sp0 ch eng2 sp0 l e5 sp1 uai4 sp0 p o2 sp1 zh e4 sp0 g e4 sp1 g uai4 sp0 l i3 sp1 g uai4 sp0 q i4 sp0 d e5 sp0 r en2 <sos/eos>|我得过一场大病,这时刚刚能下地。生病期间一这一点我记得很清楚——父亲照看我时显得很高兴,后来他突然就不见了,换成了外婆这个怪里怪气的人。
全部で12行あるため、12個分の「テキストに即した内容の音声」が生成されることになります。公式ページを見てみると、ここの文章は、以下のような「決まったフォーマット」で書く必要があるようです。
<speaker>|<style_prompt/emotion_prompt/content>|<phoneme>|<content>
それでは、長いので1つ分のテキストを切り取って、確認してみようと思います。
Maria_Kasper|Happy|<sos/eos> [IH0] [M] [AA1] [T] engsp4 [V] [OY1] [S] engsp4 [AH0] engsp1 [M] [AH1] [L] [T] [IY0] engsp4 [V] [OY1] [S] engsp1 [AE1] [N] [D] engsp1 [P] [R] [AA1] [M] [P] [T] engsp4 [K] [AH0] [N] [T] [R] [OW1] [L] [D] engsp1 [T] [IY1] engsp4 [T] [IY1] engsp4 [EH1] [S] engsp1 [EH1] [N] [JH] [AH0] [N] . <sos/eos>|Emoti-Voice - a Multi-Voice and Prompt-Controlled T-T-S Engine
これより推測すると、上記のフォーマットの内容は、以下のような感じでしょう。
- <speaker>:喋る人(おそらく声の種類)
- <style_prompt/emotion_prompt/content>:ここで、喋り方や感情を決める(ここではHappy)
- <phoneme>:発音・音素
- <content>:喋る内容(ここの文章を読み上げる)
喋る内容に合わせて、わざわざ音素を決めないといけないのは、かなり面倒くさいですね。
そんな時は、「EmotiVoice」フォルダの「frontend_en.py」を実行しましょう。その際に、「data/my_text.txt」に読ませたい文章を、あらかじめ書いておきます。
今回は、以下の文章を読ませてみます。(中国語は分からないので、英語オンリーでいきます。)これはことわざで、問題が小さいうちに対処すれば、後で大きな手間を省けるという意味を持っています。
A stitch in time saves nine.
次に、以下のコードを実行すると、phonemeが取得できます。
!python frontend_en.py data/my_text.txt > data/my_text_for_tts.txt
my_text.txtと同じフォルダに、「my_text_for_tts.txt」というファイルが作成され、以下のphonemeが取得できます。出力結果は以下の通りです。
<sos/eos> [AH0] engsp1 [S] [T] [IH1] [CH] engsp1 [IH0] [N] engsp1 [T] [AY1] [M] engsp1 [S] [EY1] [V] [Z] engsp1 [N] [AY1] [N] . <sos/eos>
これを上記のphonemeのところに貼り付けるだけですね。そして、「data/inference/text」の中身を、以下の様に変更しましょう。
Maria_Kasper|Happy|<sos/eos> [AH0] engsp1 [S] [T] [IH1] [CH] engsp1 [IH0] [N] engsp1 [T] [AY1] [M] engsp1 [S] [EY1] [V] [Z] engsp1 [N] [AY1] [N] . <sos/eos>|A stitch in time saves nine.
実行するコードは、以下の通りです。
!python inference_am_vocoder_joint.py --logdir prompt_tts_open_source_joint --config_folder config/joint --checkpoint g_00140000 --test_file data/inference/text
これをもとに、様々な感情で、同じ文章を読ませてみようと思います。
読ませる感情のプロンプトは、以下の通りです。
- Speaking with a happy tone
- Speaking with excitement
- Speaking sadly
- Speaking angrily
以下に、結果を順番に載せておきます。
音声の精度は高いですが、あまり違いが分からないですね。
文章が短いからでしょうか。また、中国語であれば精度が高いとかですかね。
なお、Metaが開発した音声モデルについて知りたい方はこちらの記事をご覧ください。
→【MAGNeT】Meta開発のテキストから音楽や音声を生成できるAIの使い方~実践まで
EmotiVoiceの推しポイントである感情表現は本当なのか?
EmotiVoiceの感情表現が本当に素晴らしいのかを確かめるために、他のTTSモデルと比較検証しようと思います。なおここでは、VALL EというTTSモデルを、比較対象として利用しようと思います。以下のHugging Faceページで、簡単に試すことができます。
参考記事:VALL-E X
具体的に比較する内容として、「感情を含めた音声の品質」を私の主観的な判断で評価しようと思います。
結果は以下の通りです。上からHappy、Excited、Sad、Angryです。
VALL-Eの方が良いぞ。特に、SadやAngry。
EmotiVoiceと比べて、しっかりと感情を乗せている上に、音声の精度も良いですね。
まとめ
EmotiVoiceは、多様な声と感情を持つ、オープンソースの「Text2SpeechAI」です。このAIは英語と中国語に対応し、2000種類以上の声を生成できます。特に、喜びや悲しみなどの、様々な感情を表現する音声を作ることができるのが特徴です。
本記事の使い方セクションを参考にしていただければ、簡単にテキストファイルを音声に換えることが可能です。
EmotiVoiceは音声の精度は高いですが、感情の違いあまり違いが分からなかったです。文章が短いからでしょうか。また、中国語であれば精度が高いとかですかね。
VALL-Eの方がEmotiVoiceと比べて、しっかりと感情を乗せている上に、音声の精度も良かったです。
近い将来、AIと腹を割って話せる時代が来るかもしれませんね。
生成系AIの業務活用なら!
・生成系AIを活用したPoC開発
・生成系AIのコンサルティング
・システム間API連携
最後に
いかがだったでしょうか?
弊社では
・マーケティングやエンジニアリングなどの専門知識を学習させたAI社員の開発
・要件定義・業務フロー作成を80%自動化できる自律型AIエージェントの開発
・生成AIとRPAを組み合わせた業務自動化ツールの開発
・社内人事業務を99%自動化できるAIツールの開発
・ハルシネーション対策AIツールの開発
・自社専用のAIチャットボットの開発
などの開発実績がございます。
まずは、「無料相談」にてご相談を承っておりますので、ご興味がある方はぜひご連絡ください。
➡︎生成AIを使った業務効率化、生成AIツールの開発について相談をしてみる。
「生成AIを社内で活用したい」「生成AIの事業をやっていきたい」という方に向けて、生成AI社内セミナー・勉強会をさせていただいております。
セミナー内容や料金については、ご相談ください。
また、サービス紹介資料もご用意しておりますので、併せてご確認ください。