UTAUユーザーのためのblenderでMMDモデル作る(2.環境構築)

目次

  1. 前書き
  2. 環境構築(← この記事です)
  3. 下絵を準備する
  4. blenderの準備
  5. 顔を作る1_目の縁
  6. 顔を作る2_鼻・口
  7. 顔を作る3_前面
  8. 顔を作る4_後頭部
  9. 目を作る

この記事でやること

  1. MMDを導入する
  2. blenderを導入する
  3. Blenderアドイン mmd-toolsの導入
  4. clip studio paintを導入する(任意)

概要

必要なソフトを導入していきます。

clip studio paintは下絵の準備とテクスチャの加工に使います。

  • 筆者は絵が描けないので下絵の作成にclip studio paintの3D人形を参考に使います。
  • レイヤー機能のある画像編集ソフトなら、正直なんでもいいです。

pmxeditorも後々必要になりますが、今は導入しません。 一気に環境構築すると環境構築だけで疲れると思うので、また実際使うときに説明します。

MMDの導入

  1. ダウンロードはこちらから Vocaloid Promotion Video Project
  2. MikuMikuDance(x64 Ver)をダウンロードします f:id:delta_kuro:20211101081037p:plain
  3. ダウンロードしたzipファイルをどこかわかる場所に解凍しておきます。 f:id:delta_kuro:20211101081343p:plain

Blenderの導入

  1. ダウンロードはこちらから [ Download — blender.org]f:id:delta_kuro:20211101081640p:plain
  2. ダウンロードしたファイルを起動し、インストールします。
    1. Nextをクリック

      f:id:delta_kuro:20211101081751p:plain

    2. I accept the terms in the License Agrementにチェックを付けて、Nextをクリック(利用規約への同意)

      f:id:delta_kuro:20211101082027p:plain

    3. インストール先の指定。特にこだわりがなければそのままNextをクリック

      f:id:delta_kuro:20211101082249p:plain

    4. Installをクリック

      f:id:delta_kuro:20211101082325p:plain

    5. インストールが完了しました

      f:id:delta_kuro:20211101082353p:plain

  3. 初回起動し、言語を日本語に設定します。

    f:id:delta_kuro:20211101082511p:plain

  4. 起動画面です。以降blenderを起動するたびにこの画面が出ますが、何もないところをクリックすれば消えます。

    f:id:delta_kuro:20211101082709p:plain

Blenderアドイン mmd-toolsの導入

mmd toolsを導入すると、blenderから直接pmx(MMDのモデルファイル)を出力できるようになります。

  1. ダウンロード GitHub - UuuNyaa/blender_mmd_tools: mmd_tools is a blender addon for importing Models and Motions of MikuMikuDance.

    画面上部のtagsをクリック

    f:id:delta_kuro:20211101085224p:plain

    1番新しいバージョンをダウンロード

    f:id:delta_kuro:20211101085320p:plain

  2. blenderにインストール [編集] > [プリファレンス]を開く

    f:id:delta_kuro:20211101085600p:plain

    アドオンからインストールを選択

    f:id:delta_kuro:20211101085658p:plain

    さきほどダウンロードしたmmd_toolsのzipを選択

    f:id:delta_kuro:20211101085747p:plain

  3. mmd-toolsの初期設定 アドオン画面右上の検索欄に「mmd_tools」と入力

    一覧に表示された「Object: mmd_tools」の隣のチェックを付けてアドオンを有効にする。

    共有トゥーンテクスチャフォルダに、[MMDをインストールしたフォルダ]\Data\を指定する。

    f:id:delta_kuro:20211101090059p:plain

CLIP STUDIO PAINTの導入(任意)

公式の解説が丁寧なので、導入方法は公式サイトをご覧ください。

ダウンロード | CLIP STUDIO PAINT

UTAUユーザーのためのblenderでMMDモデル作る(1.前書き)

はじめに

MMD × UTAUの投稿祭を主催します。

TLで頂いたリアクションを見てると、この機会にモデリングに挑戦したいという方が多いようです。

モデリング関係の講座はたくさんありますが、 blenderMMDモデルを作る講座記事については、先のニコニコブロマガ閉鎖で失われてしまったように思います。

そこで、できる範囲の情報をまとめようと思います。

目次

  1. 前書き(← この記事です)
  2. 環境構築
  3. 下絵を準備する
  4. blenderの準備
  5. 顔を作る1_目の縁
  6. 顔を作る2_鼻・口
  7. 顔を作る3_前面
  8. 顔を作る4_後頭部
  9. 目を作る

筆者が公開しているモデル

こういうクオリティのモデルが作れます。 3d.nicovideo.jp

筆者の属性

  • PC関係は得意なほう
  • 絵は描けない
  • UTAU歴10年、MMD歴はもうすぐ2年
  • 主に自作モデル使って遊んでるので、ガラパゴス気味かも

準備していただくもの

  • パソコン
  • ホイール付きのマウス
  • テンキー付きのキーボード

NVIDIA/tacotron2で日本語TTSする実験レポート(作成中)

実験の目的

  1. 「やろうと思えばTTSソフトを作れる」という手札の獲得する
  2. 日本語TTSするのに、どの程度の収録が必要なのか知見を得る
  3. 機械学習で遊ぶ

tacotron2とは

tacotron2は、Googleで開発されたTTS(Text To Speech)アルゴリズムである。

入力テキストをメルスペクトログラムに変換する部分と、メルスペクトログラムをwavに変換する部分で構成されている。

Googleのtacotron2では、メルスペクトラム→wav部分をwavenet*1で実現しているが、 NVIDIA実装では、waveglow*2を使用されている。

リンク類 Google のtacotron2の論文 arxiv.org

NVIDIAのtacotron2のgithub github.com

waveglowのgithub github.com

ロードマップ

以下のステップtacotron2のモデルの学習実験を行う。 実験終了後余力があれば、wavglowの学習についても実験する。

  1. NVIDIAが配布している学習済みのモデルに、日本語のコーパスを転移学習し、日本語TTSを実現する
  2. LJ speech dataset*3*4を用いて学習を行い、正しく環境構築ができていることを確認するとともに、ベースモデルの作成に必要な学習量に関する知見を深める。
  3. Japanese Single Speaker Speech Dataset*5*6を用いて学習を行い、日本語モデルの学習に必要な学習量に関する知見を深める。
  4. ITAコーパス*7*8を、上記学習量に相当するぐらい反復学習することで、TTSを実現できるか実験する。→いい成果が上がらないと予想
  5. JVSコーパス*9のparallel*10を使い、複数の話者の声を使って中間声のようなベースモデルを作成可能か実験する。→可能と予想
  6. ITAコーパスを複数話者・複数テイク繰り返して活用し、ベースモデルの作成に挑戦する。

関連リンク LJSpeech dataset keithito.com

Japanese Single Speaker Speech Dataset Japanese Single Speaker Speech Datasetwww.kaggle.com

JVSコーパス sites.google.com

ITAコーパス github.com zunko.jp

ロードマップ作成にあたり参考にした先行実験記事 シロワニさんの機械学習ブログ shirowanisan.com

NVIDIA/tacotron2 で日本語の音声合成を試す note.com


実験1 NVIDIAが配布している学習済みモデルに日本語を転移学習する。

以下の記事での先行実験にならい、転移学習を実施する。 Tacotron2を日本語で学習してみる(転移学習編) shirowanisan.com

NVIDIA/tacotron2 で日本語の音声合成を試す (2) - JSUTで学習 note.com

コーパスの選定

先行実験にならいJSUT*11を使用した。

JSUT sites.google.com

実験環境

先行実験より、12時間以内*12である程度の成果が期待できることから、 Google colabを使用した。

tacotron2のハイパラメータについて

hparams.pyで定義されている。 今後の実験に関係のありそうなパラメータは下記の通り。

パラメータ 初期値 解説
epochs 500 同じサンプルを何回学習に使うか
iters_per_checkpoint 1000 何stepごとにcheckpointを出力するか。1回のチェックポイントが380MBぐらいあるため、あまり頻度が高いとすぐ容量がいっぱいになる。頻度が低いとcolabに環境リセットされたとき大きく出戻りが発生するリスクがある。
training_files 'filelists/ljs_audio_text_train_filelist.txt' 学習に使うwavファイル一覧のパス。デフォルトではLJSpeech用のダミー
validation_files 'filelists/ljs_audio_text_val_filelist.txt' 学習がうまく行ってるか確認するのに使うwavファイル一覧のパス。デフォルトではLJSpeech用のダミー
text_cleaners ['english_cleaners'] training_filesvalidation_filesに記載されているラベルを学習前にどのように変換するかの定義。text/cleaners.pyに詳細記述
batch_size 64 1回の学習に使うサンプルの数。大きい程VRAMをたくさん使うので、一般的な環境ではほぼ変更必須

なお、hparams.pyを編集しなくても、train.py起動時に、以下のような引数を付けることで上書き可能。 google colabを使用する場合、ファイルの書き換えに手間がかかるため、引数を使う方法を採用する。

python train.py --hparams batch_size=32,epochs=100

環境構築手順

Google colabではセッションが切断されるたびに、データが初期化されるため、 学習に必要なデータと学習の成果物*13google drive上に保存するようにする。

そこで、以下の手順でDrive上にデータベースの準備を行った。

なお、無料のcolabではGPUの利用時間制限が厳しいため、この作業はCPUセッションで実施した。

Driveをマウントし作業フォルダを作る

from google.colab import drive 
drive.mount('/content/drive')
!mkdir -p /content/drive/'My Drive'/colab/
%cd /content/drive/'My Drive'/colab/

tacotron2の導入

!git clone https://github.com/NVIDIA/tacotron2.git
%cd tacotron2
!git submodule init
!git submodule update
!git clone https://github.com/NVIDIA/apex

ベースモデルのダウンロード

import gdown
gdown.download('https://drive.google.com/uc?id=1c5ZTuT7J08wLUoVZ2KkUs_VdZuJ86ZqA', 'tacotron2_statedict.pt', quiet=False)

JSUTのダウンロード

%cd /content/drive/'My Drive'/colab/
!wget http://ss-takashi.sakura.ne.jp/corpus/jsut_ver1.1.zip
!unzip jsut_ver1.1.zip

データベースの加工に必要なpython ライブラリの導入

!pip install pyopenjtalk
!pip install librosa
!pip install pysoundfile

学習用ラベルファイルの整理1_ファイルの集約 各フォルダにあるtranscript_utf8.txtをまとめる。

import os

# パス
in_paths = [
    'jsut_ver1.1/basic5000/',
    'jsut_ver1.1/countersuffix26/',
    'jsut_ver1.1/loanword128/',
    'jsut_ver1.1/onomatopee300/',
    'jsut_ver1.1/precedent130/',
    'jsut_ver1.1/repeat500/',
    'jsut_ver1.1/travel1000/',
    'jsut_ver1.1/utparaphrase512/',
    'jsut_ver1.1/voiceactress100/']
out_path = 'filelists/'

# 出力フォルダの準備
os.makedirs(out_path, exist_ok=True)

# transcriptの変換
with open(out_path+'transcript_utf8.txt', 'w') as wf:
    for in_path in in_paths:
        with open(in_path+'transcript_utf8.txt', 'r') as rf:
            wf.write(rf.read())

学習用ラベルファイルの整理2_ラベルの変換 JSUTのtranscriptは、tacotron2とフォーマットが異なるため変換する。

1つ前のステップと併せて実施することも可能であるが、ラベル集約処理と変換処理を疎結合にするため、別ノートブックで処理した。

pyopenjtalkを使って漢字をローマ字に開いた際、読み間違えが散見されたが、先行実験からも転移学習に支障がないことが伺えるため無視した。

import os
import pyopenjtalk

# transcript.txtの変換
in_path = 'filelists/transcript_utf8.txt'
out_path = 'filelists/transcript.txt'
output = []
with open(in_path) as f:
    lines = f.readlines()
    for line in lines:
        strs = line.split(':')
        strs[1] = pyopenjtalk.g2p(strs[1], kana=False)
        strs[1] = strs[1].replace('pau',',')
        strs[1] = strs[1].replace(' ','')
        strs[1] = strs[1] + '.'
        output.append('wav/'+strs[0]+'.wav|'+strs[1]+'\n')

with open(out_path, 'w') as f:
    f.writelines(output)

wavファイルの変換集約 tacotron2ではサンプリングレート22,050Hz、ビット深度16bitのwavを扱うがJSUTはサンプリングレート48,000Hzのため変換を行う。

あわせて、wavファイルのパスを1つ目のステップでtranscriptに記述したパスに保存する。

import os
import pyopenjtalk

# transcript.txtの変換
in_path = 'filelists/transcript_utf8.txt'
out_path = 'filelists/transcript.txt'
output = []
with open(in_path) as f:
    lines = f.readlines()
    for line in lines:
        strs = line.split(':')
        strs[1] = pyopenjtalk.g2p(strs[1], kana=False)
        strs[1] = strs[1].replace('pau',',')
        strs[1] = strs[1].replace(' ','')
        strs[1] = strs[1] + '.'
        output.append('wav/'+strs[0]+'.wav|'+strs[1]+'\n')

with open(out_path, 'w') as f:
    f.writelines(output)

wavファイルを、tacotron2のフォルダ内にセットする。

#最初からこのパスに書き出せばよかった
!mv wav/wav/ tacotron2/wav/

transcriptを学習用データと検証用データに分割し、tacotron2のフォルダ内にセットする。

!head -n 7000 filelists/transcript.txt > tacotron2/filelists/transcript_train.txt
!tail -n 690 filelists/transcript.txt > tacotron2/filelists/transcript_val.txt

hparams.pyの編集 前述のとおりhparamsは引数でも指定可能であるが、後述の再生評価用のスクリプトに引数での変更機能を持たせていないため、 再生時にも影響するパラメータだけsedコマンドで編集する。

ローカルで編集して再アップロードしたほうが楽

!sed -i -e "30c \        text_cleaners=['basic_cleaners']," tacotron2/hparams.py

学習

colabにGPUランタイムで接続しなおし、学習に必要な環境の構築・学習をする。

driveのマウント

from google.colab import drive 
drive.mount('/content/drive')
%cd /content/drive/'My Drive'/colab/

tensorflowのバージョンを1.x系に切り替える colabのデフォルトは2系だが、tacotorn2は1系じゃないと動かない。

%tensorflow_version 1.x

tacotron2で使用するライブラリのインストール requirements.txtが2018年に定義されており、現在そのまま使うと途中で*14依存関係の問題が生じてこける。

numpy移行のライブラリが一括インストールできないため、不足分は手動でインストールする。

%cd /content/drive/'My Drive'/colab/tacotron2
!pip install -r requirements.txt
!pip install unidecode

apexのインストール

%cd /content/drive/'My Drive'/colab/tacotron2/apex
!pip install -v --no-cache-dir ./

学習のルートフォルダに移動

%cd /content/drive/'My Drive'/colab/tacotron2

学習前の確認

#割り当てられているGPUの確認
!nvidia-smi
#現在のランタイムの使用時間の確認
#上限が切れば短い時間でも切られるけど理論上最長12時間
!cat /proc/uptime | awk '{print $1 /60 /60 "hours"}'

学習の開始 学習はtraning_filesに記載したwavファイル数 * epochs / batch_sizestep行われる。

サンプルのファイルサイズにもよるが、今回の実験中では以下のバッチサイズで動作することを確認した。

GPU VRAM 可能なbatch_size
RTX2060 6GB 8
GTX1070 8GB 16
T4 16GB 32

初回実験でよくわかっていなかったため今回はbatch_size=8で学習を実施した。

!python train.py --output_directory=outdir --log_directory=logdir  -c tacotron2_statedict.pt --warm_start --hparams epochs=100,batch_size=8,training_files='filelists/transcript_train.txt',validation_files='filelists/transcript_val.txt'

学習の再開 checkpoint_1000から再開する場合

!python train.py --output_directory=outdir --log_directory=logdir  -c checkpoint_1000 --hparams epochs=100,batch_size=8,training_files='filelists/transcript_train.txt',validation_files='filelists/transcript_val.txt'

colabの90分制限対策 ブラウザの操作が90分ない場合、colabのセッションが切断される場合があるため、 ローカルで以下のスクリプトを実行して、定期的にブラウザをリロードすることにより放置可能にする。

pip install pyautogui
#処理の収量はctrl+cで
import time
import pyautogui

def reload():
    pyautogui.hotkey("ctrl","r") #更新のショートカット
    time.sleep(5)
    pyautogui.hotkey("enter") #「このページを離れていいですか?」ダイアログのOKを押す
    time.sleep(5)

def main():
    time.sleep(10) #プログラム実行後、10秒以内に、colabのブラウザ・タブをアクティブにする。
    while True: #30分に一度reloadする無限ループ
        reload()
        time.sleep(1800)

main()

参考にしたサイト qiita.com

学習結果の評価

今回は先行実験よりうまく動作することが期待されたため、ローカル環境にて音声を再生し聴感上問題がないことを確認するのみとした。

再生用のスクリプトinference.ipynbを参考に以下のように作成した。

pythonのコード 学習環境とは別に以下のライブラリをインストールする

pip install simpleaudio

また、wavファイルを保存する場合

pip install SoundFile
import sys
sys.path.append('waveglow/')
import numpy as np
import torch

from hparams import create_hparams
from model import Tacotron2
from layers import TacotronSTFT, STFT
from audio_processing import griffin_lim
from train import load_model
from text import text_to_sequence
from denoiser import Denoiser
import simpleaudio as sa

#wavファイルを保存する場合
#import soundfile as sf


#setup hparams
hparams = create_hparams()
hparams.sampling_rate = 22050

#load model from checkpoint
checkpoint_path = sys.argv[1] #test用のプログラムなので特にことわりなく第1引数を学習したモデルのパスにした
model = load_model(hparams)
model.load_state_dict(torch.load(checkpoint_path)['state_dict'])
_ = model.cuda().eval().half()

#load waveglow model
waveglow_path = 'waveglow_256channels_universal_v5.pt'
waveglow = torch.load(waveglow_path)['model']
waveglow.cuda().eval().half()
for k in waveglow.convinv:
    k.float()
denoiser = Denoiser(waveglow)

#Prepare text input
text = sys.argv[2] #test用のプログラムなので特にことわりなく第2引数を読み上げたいテキストにした
sequence = np.array(text_to_sequence(text, ['english_cleaners']))[None, :]
sequence = torch.autograd.Variable(
    torch.from_numpy(sequence)).cuda().long()

mel_outputs, mel_outputs_postnet, _, alignments = model.inference(sequence)

with torch.no_grad():
    audio = waveglow.infer(mel_outputs_postnet, sigma=0.666)

play_obj=sa.play_buffer((audio[0].data.cpu().numpy()*32767).astype(np.int16),1,2,hparams.sampling_rate)
play_obj.wait_done()

#wavファイルを保存する場合
#sf.write('output.wav', audio[0].data.cpu().numpy().astype(np.float32), hparams.sampling_rate)

以下のコマンドで出力を確認した

python inference.py outdir/checkpoint_7000 "honjitsuwa,seitennari"

真面目に観測する場合tensorboardを使用し、以下3点を確認する。*15

  • SCALARS > training lossの収束していっている*16
    画像
    f:id:delta_kuro:20210824200046p:plain
    異常なtraning ross。learning rateを調整してわざと異常値を出した図
    f:id:delta_kuro:20210824200156p:plain
    うまく学習が進んでいるtraning ross
  • SCALARS > validation lossが上昇していない*17
  • IMAGES > alignmentが綺麗な斜線になっている。*18
    画像
    f:id:delta_kuro:20210824142042p:plain
    LJSpeech学習時、まだ人の言葉を話さないalignment
    f:id:delta_kuro:20210824141959p:plain
    LJSpeech学習時、概ね正しく発音しているalignment

実験2 LJ Speech Datasetを学習する。

2021/8/24現在実験中

実験環境

学習が長期間にわたることが予想されることから、環境構築の勉強も兼ねて自宅のPCに環境を構築した。

環境構築手順

python3.7のインストール tacotron2で使用している、tensorflow1系がpython3.8以降に対応していないため、python3.7の環境を構築する。

筆者は、visual studio同梱のpyenv機能を活用してpython3.7を導入した。

tensorflowのインストール tensorflow1系は、cpu用とgpu用でライブラリが異なるため注意する。

tacotron2を使用するためにはGPU用のインストールが必要。

pip install pip install tensorflow-gpu

筆者は、visual studio同梱のpyenv機能を活用してpython3.7を導入した。

CUDA10.2のインストール google colabと環境をあわせて、CUDA10.2を導入した。 developer.nvidia.com

tacotron2の導入 tacotron2のreadmeに記載のある通りの手順でセットアップを実施 github.com

  1. LJSpeech datasetのダウンロードし展開する。
  2. tacotron2のリポジトリをクローン git clone https://github.com/NVIDIA/tacotron2.git
  3. tacotron2のフォルダに移動 cd tacotron2
  4. サブモジュールの初期化と更新 git submodule init; git submodule update
  5. filelistsフォルダ内のテキストファイルの内、wavファイルのパスを実際のLJSpeech datasetを展開したパスに変更
  6. Pytorchをインストールする。バージョン情報無しでpip installしようとするとこけるので注意。
  7. Apexをインストールする
    1. apexのリポジトリをクローン git clone https://github.com/NVIDIA/apex
    2. apexのフォルダに移動 cd apex
    3. pip install -v --no-cache-dir ./
  8. その他必要なライブラリをインストール
    1. tacotron2のディレクトリに移動
    2. pip install -r requirements.txt numpyでこけるけど無視する。
    3. pip install Unidecode

学習の開始

python train.py --output_directory=outdir --log_directory=logdir --hparams=batch_size=8

また、別のターミナルで以下のコマンドを実行し、http://localhost:6006 にアクセスすることで、tensorboardを開きっぱなしにできる。

python --logdir=outdir/logdir

経過観察(メモ)

batch_size=8 概ね1step 3.3sぐらい

  • 13,000step 10時間 人間の声じゃない
  • 46,000step 43時間 人間の声になってきたが何を言っているかわからない
  • 130,000step 108時間 alignmentにそれらしい傾向あり。何を言っているかは全く分からないが、冒頭の母音ぐらいは音があってることがある。
  • 163,000step 120時間 発音が正しいところが増えてきた。
  • 276,000step 212時間 英語は概ね正しくしゃべる。日本語を発音させたとき、正しい発音のあとに、目いっぱい意味の分からないうめき声が入る。 2021/8/25

成果が見えてきた160,000step時点頃から、並行して実験3を開始する。


実験3 Japanese Single Speaker Speech Datasetを学習する。

2021/8/24現在実験中

実験環境

学習が長期間にわたることが予想されることに加え、自宅環境は実験2で稼働中なため、 Google colabをPro*19にアップグレードして実験を行った。 また、実験に際し、google driveの容量ひっ迫が予想されるため、Google One 100GBプラン*20にも加入した。

環境構築

ほぼ実験1に準じるため、変更点のみ記載する。

ラベルの仕様策定 今回は最終的に作成される日本語TTSソフトで使用する音韻を想定したラベルを使用する。 以下の点を考慮して、ローマ字+下表のようなラベルを考案した。

  • 日本語テキストから音韻への変換を自動変換に頼ることは困難である。*21
  • 最終的に使用するフロントエンドとしては、平仮名を入力しラベルに変換する処理をUI側に組み込む。
  • ローマ字と音韻には微妙な食い違いがあり、それらを意図的に制御できるようにするため、大文字を使ってローマ字を拡張する。*22
日本語 使用するラベル
N
しゃ行の子音 S
ちゃ行の子音 tS
それ以外 普通のヘボン式ローマ字

にゃ行とかひゃ行の例外処理忘れてた

text/cleaners.pyの改造 text/cleaners.pyには、標準で以下の3つのcleanersが定義されている。 * basic_cleaners*23 * english_cleaners*24 * transliteration_cleaners*25

今回は大小アルファベットを使用したいため、組み込みのcleanersはいずれも適さない。

そこで、何も処理しないthrough_cleanersを定義して使用し、ラベルはデータベース準備段階で完全に整備する。

def through_cleaners(text):
  return text

hparams.pyの改造 text_cleanersを先ほど定義したthrough_cleanersに差し替える。

    #text_cleaners=['english_cleaners'],
    text_cleaners=['through_cleaners'],

データベースの準備 今回はローカルに開発環境構築済みのため、ローカルで加工を行ったうえでgoogle driveにアップロードした。

コーパスをダウンロードし、展開する。 Japanese Single Speaker Speech Datasetwww.kaggle.com

ファイルリスト、ラベルの変換 JSSSDは、同梱のtranscript.txtに単語ごとに半角スペースで区切ったローマ字のラベルが入っているため、これを上記で定義した様式に加工する。

import os
import os.path
import re
import codecs

INPUT_FILE=os.path.join("JSSSD","transcript.txt")
OUTPUT_DIR=os.path.join("JSSSD","filelists")

if not os.path.isfile(INPUT_FILE):
    print(INPUT_FILE +" is not found")
    exit()

os.makedirs(OUTPUT_DIR,exist_ok=True)

with codecs.open(INPUT_FILE,"r","utf-8") as fr:
    lines=fr.read().split("\n")

n_reg=re.compile(r'n([^aiueo])')
dash_reg=re.compile(r'([aiueo])-')
sh_reg=re.compile(r'sh')
ch_reg=re.compile(r'ch')
del_reg=re.compile(r'[―?! -]')

newlines=[]
for line in lines:
    values=line.split("|")
    if(len(values)<3):
        values=[]
        continue
    if(len(values[2])==0):
        continue
    s=n_reg.findall(values[2])
    values[2]=n_reg.sub('N\\1',values[2])
    values[2]=dash_reg.sub('\\1\\1',values[2])
    values[2]=sh_reg.sub('S',values[2])
    values[2]=ch_reg.sub('tS',values[2])
    values[2]=del_reg.sub('',values[2])
    values[2]=values[2].replace("、",",")
    values[2]=values[2].replace("。",".")
    if(values[2][-1] not in [',','.']):
        values[2]+='.'
    values[0]=values[0].replace('meian/','wav/')
    newlines.append([values[0],values[2]])

with codecs.open(os.path.join(OUTPUT_DIR,"transcript.txt"),"w","utf-8") as fw:
    for newline in newlines:
        fw.write("|".join(newline)+"\n")

wavの変換 割と時間がかかるため、マルチプロセスで処理した。

import os
import os.path
import librosa
import soundfile as sf
from multiprocessing import Pool
from multiprocessing import Process

INPUT_DIR=os.path.join("JSSSD","meian")
OUTPUT_DIR=os.path.join("JSSSD","convert")

def convert(filename):
    print(filename)
    y, sr = librosa.core.load(os.path.join(INPUT_DIR,filename), sr=22050, mono=True)
    sf.write(os.path.join(OUTPUT_DIR,filename), y, sr, subtype="PCM_16")

def main():
    if not os.path.isdir(INPUT_DIR):
        print(INPUT_DIR +" is not found")
        exit()

    os.makedirs(OUTPUT_DIR,exist_ok=True)
    files=os.listdir(INPUT_DIR)
    p=Pool(10)
    p.map(convert,os.listdir(INPUT_DIR))

if __name__=="__main__":
    main()

transcriptを学習用データと検証用データに分割し、tacotron2のフォルダ内にセットする。

!head -n 6000 filelists/transcript.txt > tacotron2/filelists/transcript_train.txt
!tail -n 840 filelists/transcript.txt > tacotron2/filelists/transcript_val.txt

環境構築済みのtacotron2のフォルダを全てzipにする。*26 wavファイルを都度google driveに読みに行くより、1度colabのサーバー内に全データを移動したほうが処理が早くなる(らしい)

複数ファイルの転送はgoogle driveの制限に引っかかる恐れがあるため、zip化しておく。

学習

ほぼ実験1の手順に準じるため、変更点のみ記載する。

tacotron2のzipをcolab内で解凍する

!cp tacotron2.zip ~/tacotron2.zip
%cd ~/
!unzip tacotron2.zip

学習 今回はcolab proで利用可能になったP100 環境で学習する。

batch_sizeは学習が早くなることを期待して、メモリの許す限り最大限に設定した。

!python train.py --output_directory=/content/drive/'My Drive'/colab/tacotron2/outdir --log_directory=logdir --hparams batch_size=32,training_files='filelists/transcript_train.txt',validation_files='filelists/transcript_val.txt'

経過観察(メモ)

batch_size=32 概ね1step 4.5sぐらい

先行実験で500epochs完了時点で人間の言葉をしゃべらなかったという情報あり。

batch_sizeよりstep数のほうが重要?要検証

  • 24,000step 40時間 話者の声らしき雰囲気はある。
  • 30,000step 50時間 何を言っているのかわからない。謎のうめき声を発している。
  • 44,000 step 65時間 進展なし 2021/8/24現在

*1:google

*2:NVIDIA

*3:英語のパブリックドメインの話声データベース。おそらくNVIDIAが配布している学習済みモデルはこれを学習している

*4:12,000文、約24時間、女声

*5:日本語のパブリックドメインの話声データベース

*6:6,840文、収録時間について明記はないが同一フォーマット変換時LJ speech datasetよりファイルサイズが大きいことから、24時間以上の発声があると思われる

*7:日本語のパブリックドメインの話声コーパス

*8:emotion100文とraciation324文。無音時間も含めて40分程度

*9:日本語 CC-BY-SAのデータベース、100人の話者が150文ずつ収録

*10:100人の話者が同じ内容100文を収録、1人当たり約12.5分

*11:日本語 CC-BY-SAのデータベース、女声、7,696文

*12:google colabの無料セッションの最長時間

*13:checkpointとlog

*14:numpyのインストール

*15:IMAGESから、tacotron2で生成したメルスペクトログラムと学習データの比較画像を見ることができるが、学習初期から概ね似たような画像が出るため、あまり重視していない。

*16:step毎に記録される。学習が進むほど小さくなるのが一般的。そうでないなら何かがおかしい。

*17:checkpoint保存毎に記録される。小さいほどいい。上昇を始めると過学習

*18:入力と出力の応答が一致しているかの確認

*19:proでも占有の約束はないものの、一般的なGPUインスタンスがcolab proと同一スペックで約350円/hに対し、約1,200円/月と圧倒的安価。

*20:250円/月

*21:主に漢字を読み仮名にする部分が難しい

*22:英語でさえスペルから正しい発音を導けているため、コントロール可能にする以上の意味はない。

*23:小文字アルファベットを使用する。大文字は自動で小文字に変換される。 実験1で使用

*24:英語特有の略語や数字を自動で小文字アルファベットに展開する。大文字は小文字に変換される。実験2で使用

*25:unicode文字を自動でアルファベットに変換する。 ただし、漢字は中国語として認識されるらしい

*26:wavとtranscriptも含む

ブログの移転の進捗について

長らく使用していたブロマガがこの度閉鎖することになったため、ブログ移転することになりました。

移転に伴い、ブロマガ側の記事は削除せず、サービス終了(2021年10月7日)までは、両方のサイトで記事が閲覧できる状態にします。

以下、私が把握している、ブロマガにリンクしている箇所と修正状況です。 抜け漏れがあれば連絡いただくか、各自で差替えお願いします。


  • twitterのプロフィール → 2021/08/23 完了
  • twitterの定期ツイート → 2021/08/23 完了
  • 配布しているMMDモデルの利用規約
  • ニコニ立体に表示しているMMDモデルの利用規約
  • githubに公開しているutauPluginの導入説明リンク → 2021/08/23 完了
  • 各種UTAUプラグインの配布動画 → 2021/08/23 完了

UTAU関連タグ 集計してみた(2020年)

経緯

2016年まではうたらんまとめ(http://utauhirohiro.blog56.fc2.com/blog-entry-2665.html)で関連タグTOP30が見れたのですが,今は更新されていないので自分で集計しました.

2017年、2018年版はこちら
2019年版はこちら

2020年版 UTAU関連タグ集約・解析(xlsx)
たぶんgoogleスプレッドシートでも見れますが,フィルタとかがいい感じに動かないのでエクセルで見るのがおすすめです.

※ 22:20 まいた(utau)さんが漏れていたため修正しました

概要

集計期間:2019-12-25T00:00:00+09:00~2020-12-25T00:00:00+09:00

UTAU関連動画では,
タグ検索:「UTAU or UTAUオリジナル曲 or VOCALOID&UTAUオリジナル曲 or UTAUカバー曲 or UTAUカバー or HANASU or VOCALOID→UTAUカバー曲」を含む 全12,023件が調査対象です.

UTAUキャラタグ解析は,上記12,023件のうち10件以上該当する動画があるキャラに対象を絞り,
タグ検索:「UTAU or UTAUオリジナル曲 or VOCALOID&UTAUオリジナル曲 or UTAUカバー曲 or UTAUカバー or HANASU or VOCALOID→UTAUカバー曲 【キャラタグ】」を含む動画を調査しています.

UTAUキャラタグ解析のうちオリジナル曲は,上記該当音源のうち,
タグ検索:「UTAUオリジナル曲 or VOCALOID&UTAUオリジナル曲【キャラタグ】」を含む動画を調査しています.

全体的な推移

2018年版のブロマガにも書いた通り,2018年は参考値ですが,

2018年2019年2020年
対象動画数年間9,358件9,468件12,023件
10件以上投稿された音源数150キャラ142キャラ189キャラ
デビューして1年以内で10件以上投稿されたキャラ数17キャラ13キャラ12キャラ

2019年10件未満で、今年10件以上投稿されたキャラ数:77キャラ

投稿人数と推移







累計投稿者数でみると、2013年以来の高水準。
当時よりyoutubeのみに投稿するユーザーが増えたことを踏まえると、トータルでは当時よりユーザー数多いかも(未検証)


考察

例によって真面目にまとめるのに飽きてきたのでtwitterで垂れ流します.



UTAU超投稿祭を解析してみた

UTAU超投稿祭って何?

ネット超会議2020にあわせて開催された,ユーザー企画です.
投稿期間:2020/4/12(日) ~ 2020/4/19(日)
参加方法:UTAU超投稿祭をタグロック
参加条件:オリジナル曲、カバー、HANASU、MMD...UTAUの動画ならなんでもOK

詳細は大百科を見てください.
下記のもろもろの考察の元データはGoogleDriveに公開しています.


イベントの規模は?

対象動画数362件となり,過去に開催されたUTAU関係の投稿祭で最多となった


イベント対象動画一覧は↓


参加者数は?

ニコニコの投稿者IDを調べたところ累計投稿者数は261人
1人当たりの投稿件数は以下の画像のとおり


画像からわかる通り,
2件以上投稿した人が全体の21%を占め,9件投稿した猛者が3人いる.

また,直近のUTAU関係動画投稿からの年数は以下の画像のとおり

ここでいうUTAU関係動画とは,以下のいずれかのタグを含む動画をさす.
「UTAU」「UTAUオリジナル曲」「VOCALOID&UTAUオリジナル曲」「UTAUカバー曲」「UTAUカバー」「HANASU」「VOCALOID→UTAUカバー曲」


盛り上がりの推移は?

投稿数の推移は以下の画像のとおり


またtwitterアンケートの4/22 17:30時点のデータによると,UTAU超投稿祭を知ったタイミングと参加を決めたタイミングは以下のとおり.


主催のtwitterで取ったアンケートであり,全体より企画の告知を事前に見やすい環境であることに注意する.
全体の約40%以上の人は,イベントの盛り上がりを見て参加したものと予測できる.


どんな動画が多かった?

サブカテゴリタグのヒット数と割合は以下の画像のとおり.
複数のカテゴリに該当する動画もあるため,合計が100%にならないことは注意.
全体の68%がカバー動画であった.


使用頻度30位以上のタグは以下の画像のとおり


どの音源が使われた?

タグ検索でヒットした音源タグは254件(手作業のためミスあるかも?)
使用頻度30位以上の音源タグは以下の画像のとおり
タグ検索ベースのため、メドレー動画等の捕捉はできていないことに注意する


普段よく使われている音源のデータについては,筆者の別記事参照
2019年集約
2020年1月 2月 3月

直近のよく使われる音源集計に登場しない,穂歌ソラさんや轟栄一さんの投稿が伸びており,根強い人気を感じさせる.

また,デビューから1ヵ月である不眠の黒羊さんは,2020年3月に開催されていた,「UTAUあなたのオリジナルユニット大会」にて結成されたユニットである,「星遠からじ梅の社(式音うい,詠創鹿歌,不眠の黒羊)」で大健闘した.


次回は開催されるの?

来年もネット超会議あるらしいので,開催できたらいいね.楽しいし.

ただ,筆者は投稿祭以外にもいろいろ企画を持っているて,オンラインイベントだけをやってるわけではないので,現時点で約束はしません.

別に筆者の専売企画じゃないので,やりたい人が主催するといいと思うよ!



UTAU関連タグ集計(20200225-20200325)

3月分です

2020年1月
2020年2月

集計条件:
タグ検索:UTAU or UTAUオリジナル曲 or VOCALOID&UTAUオリジナル曲 or UTAUカバー曲 or UTAUカバー or HANASU or VOCALOID→UTAUカバー曲

投稿日が20200225-20200325の動画

今回の該当動画992件

除外条件:
タグに"人力"もしくは"ランキング"を含む
今回の該当動画は46件(人力:7、ランキング:39)

音源別投稿数:
同率含め30位までを抽出



※ 橙色は集計期間中に初出日あり
※ 順位の赤文字は先月より順位があがったもの,青文字は下がったものです.

タグのワードクラウド(重み付けなし):



タグのワードクラウド(再生数で重み付け):




タグのワードクラウド(ランキングポイントで重み付け):




ランキングポイントの計算式は2018年UTAU年間ランキング式を流用