Delete Hololive-Style-Bert-VITS2
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- Hololive-Style-Bert-VITS2/.gitattributes +0 -76
- Hololive-Style-Bert-VITS2/.gitignore +0 -1
- Hololive-Style-Bert-VITS2/README.md +0 -15
- Hololive-Style-Bert-VITS2/app.py +0 -386
- Hololive-Style-Bert-VITS2/attentions.py +0 -462
- Hololive-Style-Bert-VITS2/bert_gen.py +0 -84
- Hololive-Style-Bert-VITS2/common/constants.py +0 -20
- Hololive-Style-Bert-VITS2/common/log.py +0 -16
- Hololive-Style-Bert-VITS2/common/stdout_wrapper.py +0 -34
- Hololive-Style-Bert-VITS2/common/subprocess_utils.py +0 -32
- Hololive-Style-Bert-VITS2/common/tts_model.py +0 -250
- Hololive-Style-Bert-VITS2/commons.py +0 -152
- Hololive-Style-Bert-VITS2/config.py +0 -269
- Hololive-Style-Bert-VITS2/config.yml +0 -51
- Hololive-Style-Bert-VITS2/configs/config.json +0 -71
- Hololive-Style-Bert-VITS2/configs/configs_jp_extra.json +0 -78
- Hololive-Style-Bert-VITS2/configs/paths.yml +0 -8
- Hololive-Style-Bert-VITS2/data_utils.py +0 -425
- Hololive-Style-Bert-VITS2/default_config.yml +0 -81
- Hololive-Style-Bert-VITS2/images/aki.png +0 -3
- Hololive-Style-Bert-VITS2/images/ame.png +0 -0
- Hololive-Style-Bert-VITS2/images/anya.png +0 -3
- Hololive-Style-Bert-VITS2/images/aqua.png +0 -3
- Hololive-Style-Bert-VITS2/images/ayame.png +0 -3
- Hololive-Style-Bert-VITS2/images/azki.png +0 -3
- Hololive-Style-Bert-VITS2/images/bae.png +0 -3
- Hololive-Style-Bert-VITS2/images/bijou.png +0 -3
- Hololive-Style-Bert-VITS2/images/calli.png +0 -0
- Hololive-Style-Bert-VITS2/images/chloe.png +0 -3
- Hololive-Style-Bert-VITS2/images/fauna.png +0 -3
- Hololive-Style-Bert-VITS2/images/flare.png +0 -3
- Hololive-Style-Bert-VITS2/images/fubuki.png +0 -3
- Hololive-Style-Bert-VITS2/images/gura.png +0 -3
- Hololive-Style-Bert-VITS2/images/haato.png +0 -3
- Hololive-Style-Bert-VITS2/images/ina.png +0 -0
- Hololive-Style-Bert-VITS2/images/iofi.png +0 -0
- Hololive-Style-Bert-VITS2/images/irys.png +0 -3
- Hololive-Style-Bert-VITS2/images/kanata.png +0 -3
- Hololive-Style-Bert-VITS2/images/kiara.png +0 -3
- Hololive-Style-Bert-VITS2/images/koyori.png +0 -3
- Hololive-Style-Bert-VITS2/images/kronii.png +0 -3
- Hololive-Style-Bert-VITS2/images/lamy.png +0 -3
- Hololive-Style-Bert-VITS2/images/laplus.png +0 -3
- Hololive-Style-Bert-VITS2/images/lui.png +0 -3
- Hololive-Style-Bert-VITS2/images/luna.png +0 -3
- Hololive-Style-Bert-VITS2/images/marine.png +0 -0
- Hololive-Style-Bert-VITS2/images/matsuri.png +0 -3
- Hololive-Style-Bert-VITS2/images/mel.png +0 -3
- Hololive-Style-Bert-VITS2/images/miko.png +0 -3
- Hololive-Style-Bert-VITS2/images/moona.png +0 -0
Hololive-Style-Bert-VITS2/.gitattributes
DELETED
|
@@ -1,76 +0,0 @@
|
|
| 1 |
-
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
-
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
-
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
-
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
-
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
-
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
-
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
-
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
-
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
-
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
-
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
-
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
-
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
-
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
-
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
-
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
-
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
-
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
-
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
-
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
-
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
-
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
-
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
-
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
-
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
-
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
-
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
-
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
-
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
-
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
-
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
-
images/aki.png filter=lfs diff=lfs merge=lfs -text
|
| 37 |
-
images/anya.png filter=lfs diff=lfs merge=lfs -text
|
| 38 |
-
images/aqua.png filter=lfs diff=lfs merge=lfs -text
|
| 39 |
-
images/ayame.png filter=lfs diff=lfs merge=lfs -text
|
| 40 |
-
images/azki.png filter=lfs diff=lfs merge=lfs -text
|
| 41 |
-
images/bae.png filter=lfs diff=lfs merge=lfs -text
|
| 42 |
-
images/bijou.png filter=lfs diff=lfs merge=lfs -text
|
| 43 |
-
images/chloe.png filter=lfs diff=lfs merge=lfs -text
|
| 44 |
-
images/fauna.png filter=lfs diff=lfs merge=lfs -text
|
| 45 |
-
images/flare.png filter=lfs diff=lfs merge=lfs -text
|
| 46 |
-
images/fubuki.png filter=lfs diff=lfs merge=lfs -text
|
| 47 |
-
images/gura.png filter=lfs diff=lfs merge=lfs -text
|
| 48 |
-
images/haato.png filter=lfs diff=lfs merge=lfs -text
|
| 49 |
-
images/irys.png filter=lfs diff=lfs merge=lfs -text
|
| 50 |
-
images/kanata.png filter=lfs diff=lfs merge=lfs -text
|
| 51 |
-
images/kiara.png filter=lfs diff=lfs merge=lfs -text
|
| 52 |
-
images/koyori.png filter=lfs diff=lfs merge=lfs -text
|
| 53 |
-
images/kronii.png filter=lfs diff=lfs merge=lfs -text
|
| 54 |
-
images/lamy.png filter=lfs diff=lfs merge=lfs -text
|
| 55 |
-
images/laplus.png filter=lfs diff=lfs merge=lfs -text
|
| 56 |
-
images/lui.png filter=lfs diff=lfs merge=lfs -text
|
| 57 |
-
images/luna.png filter=lfs diff=lfs merge=lfs -text
|
| 58 |
-
images/matsuri.png filter=lfs diff=lfs merge=lfs -text
|
| 59 |
-
images/mel.png filter=lfs diff=lfs merge=lfs -text
|
| 60 |
-
images/miko.png filter=lfs diff=lfs merge=lfs -text
|
| 61 |
-
images/mumei.png filter=lfs diff=lfs merge=lfs -text
|
| 62 |
-
images/nene.png filter=lfs diff=lfs merge=lfs -text
|
| 63 |
-
images/nerissa.png filter=lfs diff=lfs merge=lfs -text
|
| 64 |
-
images/noel.png filter=lfs diff=lfs merge=lfs -text
|
| 65 |
-
images/okayu.png filter=lfs diff=lfs merge=lfs -text
|
| 66 |
-
images/ollie.png filter=lfs diff=lfs merge=lfs -text
|
| 67 |
-
images/pekora.png filter=lfs diff=lfs merge=lfs -text
|
| 68 |
-
images/polka.png filter=lfs diff=lfs merge=lfs -text
|
| 69 |
-
images/raden.png filter=lfs diff=lfs merge=lfs -text
|
| 70 |
-
images/ririka.png filter=lfs diff=lfs merge=lfs -text
|
| 71 |
-
images/shiori.png filter=lfs diff=lfs merge=lfs -text
|
| 72 |
-
images/subaru.png filter=lfs diff=lfs merge=lfs -text
|
| 73 |
-
images/suisei.png filter=lfs diff=lfs merge=lfs -text
|
| 74 |
-
images/towa.png filter=lfs diff=lfs merge=lfs -text
|
| 75 |
-
images/watame.png filter=lfs diff=lfs merge=lfs -text
|
| 76 |
-
images/zeta.png filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/.gitignore
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
__pycache__/
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/README.md
DELETED
|
@@ -1,15 +0,0 @@
|
|
| 1 |
-
---
|
| 2 |
-
title: Hololive Style-Bert-VITS2
|
| 3 |
-
short_description: Generate Voice VTUBER
|
| 4 |
-
emoji: 🚀
|
| 5 |
-
colorFrom: gray
|
| 6 |
-
colorTo: gray
|
| 7 |
-
sdk: gradio
|
| 8 |
-
sdk_version: 4.44.1
|
| 9 |
-
app_file: app.py
|
| 10 |
-
pinned: false
|
| 11 |
-
license: agpl-3.0
|
| 12 |
-
python_version: '3.11'
|
| 13 |
-
---
|
| 14 |
-
|
| 15 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/app.py
DELETED
|
@@ -1,386 +0,0 @@
|
|
| 1 |
-
print("Starting up. Please be patient...")
|
| 2 |
-
|
| 3 |
-
import argparse
|
| 4 |
-
import datetime
|
| 5 |
-
import os
|
| 6 |
-
import sys
|
| 7 |
-
from typing import Optional
|
| 8 |
-
import json
|
| 9 |
-
import utils
|
| 10 |
-
import shutil
|
| 11 |
-
|
| 12 |
-
import gradio as gr
|
| 13 |
-
import torch
|
| 14 |
-
import yaml
|
| 15 |
-
|
| 16 |
-
from common.constants import (
|
| 17 |
-
DEFAULT_ASSIST_TEXT_WEIGHT,
|
| 18 |
-
DEFAULT_LENGTH,
|
| 19 |
-
DEFAULT_LINE_SPLIT,
|
| 20 |
-
DEFAULT_NOISE,
|
| 21 |
-
DEFAULT_NOISEW,
|
| 22 |
-
DEFAULT_SDP_RATIO,
|
| 23 |
-
DEFAULT_SPLIT_INTERVAL,
|
| 24 |
-
DEFAULT_STYLE,
|
| 25 |
-
DEFAULT_STYLE_WEIGHT,
|
| 26 |
-
Languages,
|
| 27 |
-
)
|
| 28 |
-
from common.log import logger
|
| 29 |
-
|
| 30 |
-
# --- BAGIAN DOWNLOAD OTOMATIS & FIX STRUKTUR FOLDER ---
|
| 31 |
-
from huggingface_hub import snapshot_download
|
| 32 |
-
|
| 33 |
-
HF_TOKEN = os.getenv("HF_TOKEN")
|
| 34 |
-
REPO_ID = "Plana-Archive/Premium-Model"
|
| 35 |
-
SUBFOLDER = "Hololive-Style-Bert-VITS2"
|
| 36 |
-
TEMP_DIR = "temp_download"
|
| 37 |
-
|
| 38 |
-
def download_assets():
|
| 39 |
-
print("Checking and downloading assets from private repo...")
|
| 40 |
-
|
| 41 |
-
# 1. Download folder bert/ dari repo private
|
| 42 |
-
bert_dir = "./bert"
|
| 43 |
-
if not os.path.exists(bert_dir):
|
| 44 |
-
print(f"Downloading bert/ from {REPO_ID}/{SUBFOLDER}/bert ...")
|
| 45 |
-
try:
|
| 46 |
-
snapshot_download(
|
| 47 |
-
repo_id=REPO_ID,
|
| 48 |
-
repo_type="model",
|
| 49 |
-
allow_patterns=[f"{SUBFOLDER}/bert/**/*"],
|
| 50 |
-
local_dir=TEMP_DIR,
|
| 51 |
-
token=HF_TOKEN,
|
| 52 |
-
)
|
| 53 |
-
src_bert = os.path.join(TEMP_DIR, SUBFOLDER, "bert")
|
| 54 |
-
if os.path.exists(src_bert):
|
| 55 |
-
shutil.move(src_bert, "./bert")
|
| 56 |
-
print("✅ bert/ downloaded and moved successfully.")
|
| 57 |
-
else:
|
| 58 |
-
print("⚠️ bert/ folder not found in downloaded files.")
|
| 59 |
-
except Exception as e:
|
| 60 |
-
print(f"❌ bert/ download failed: {e}")
|
| 61 |
-
else:
|
| 62 |
-
print("✅ bert/ already exists, skipping.")
|
| 63 |
-
|
| 64 |
-
# 2. Download folder model_assets/ dari repo private
|
| 65 |
-
model_assets_dir = "./model_assets"
|
| 66 |
-
if not os.path.exists(model_assets_dir):
|
| 67 |
-
print(f"Downloading model_assets/ from {REPO_ID}/{SUBFOLDER}/model_assets ...")
|
| 68 |
-
try:
|
| 69 |
-
snapshot_download(
|
| 70 |
-
repo_id=REPO_ID,
|
| 71 |
-
repo_type="model",
|
| 72 |
-
allow_patterns=[f"{SUBFOLDER}/model_assets/**/*"],
|
| 73 |
-
local_dir=TEMP_DIR,
|
| 74 |
-
token=HF_TOKEN,
|
| 75 |
-
)
|
| 76 |
-
src_assets = os.path.join(TEMP_DIR, SUBFOLDER, "model_assets")
|
| 77 |
-
if os.path.exists(src_assets):
|
| 78 |
-
shutil.move(src_assets, "./model_assets")
|
| 79 |
-
print("✅ model_assets/ downloaded and moved successfully.")
|
| 80 |
-
else:
|
| 81 |
-
print("⚠️ model_assets/ folder not found in downloaded files.")
|
| 82 |
-
except Exception as e:
|
| 83 |
-
print(f"❌ model_assets/ download failed: {e}")
|
| 84 |
-
else:
|
| 85 |
-
print("✅ model_assets/ already exists, skipping.")
|
| 86 |
-
|
| 87 |
-
# Cleanup temp dir jika masih ada
|
| 88 |
-
if os.path.exists(TEMP_DIR):
|
| 89 |
-
shutil.rmtree(TEMP_DIR)
|
| 90 |
-
print("🧹 Temp directory cleaned up.")
|
| 91 |
-
|
| 92 |
-
download_assets()
|
| 93 |
-
|
| 94 |
-
from common.tts_model import ModelHolder
|
| 95 |
-
from infer import InvalidToneError
|
| 96 |
-
from text.japanese import g2kata_tone, kata_tone2phone_tone, text_normalize
|
| 97 |
-
|
| 98 |
-
import nltk
|
| 99 |
-
nltk.download('averaged_perceptron_tagger_eng')
|
| 100 |
-
|
| 101 |
-
is_hf_spaces = os.getenv("SYSTEM") == "spaces"
|
| 102 |
-
limit = 150
|
| 103 |
-
|
| 104 |
-
with open(os.path.join("configs", "paths.yml"), "r", encoding="utf-8") as f:
|
| 105 |
-
path_config: dict[str, str] = yaml.safe_load(f.read())
|
| 106 |
-
assets_root = path_config["assets_root"]
|
| 107 |
-
|
| 108 |
-
def tts_fn(
|
| 109 |
-
model_name,
|
| 110 |
-
model_path,
|
| 111 |
-
text,
|
| 112 |
-
language,
|
| 113 |
-
reference_audio_path,
|
| 114 |
-
sdp_ratio,
|
| 115 |
-
noise_scale,
|
| 116 |
-
noise_scale_w,
|
| 117 |
-
speed_rate,
|
| 118 |
-
line_split,
|
| 119 |
-
split_interval,
|
| 120 |
-
assist_text,
|
| 121 |
-
assist_text_weight,
|
| 122 |
-
use_assist_text,
|
| 123 |
-
style,
|
| 124 |
-
style_weight,
|
| 125 |
-
kata_tone_json_str,
|
| 126 |
-
use_tone,
|
| 127 |
-
speaker,
|
| 128 |
-
):
|
| 129 |
-
if len(text) < 2:
|
| 130 |
-
return "Please enter some text.", None, kata_tone_json_str
|
| 131 |
-
|
| 132 |
-
if is_hf_spaces and len(text) > limit:
|
| 133 |
-
return f"Too long! There is a character limit of {limit} characters.", None, kata_tone_json_str
|
| 134 |
-
|
| 135 |
-
if not model_holder.current_model:
|
| 136 |
-
model_holder.load_model_gr(model_name, model_path)
|
| 137 |
-
logger.info(f"Loaded model '{model_name}'")
|
| 138 |
-
if model_holder.current_model.model_path != model_path:
|
| 139 |
-
model_holder.load_model_gr(model_name, model_path)
|
| 140 |
-
logger.info(f"Swapped to model '{model_name}'")
|
| 141 |
-
|
| 142 |
-
speaker_id = model_holder.current_model.spk2id[speaker]
|
| 143 |
-
start_time = datetime.datetime.now()
|
| 144 |
-
|
| 145 |
-
# Logika Kecepatan: Angka lebih besar = Suara lebih cepat
|
| 146 |
-
length_scale = 1.0 / speed_rate
|
| 147 |
-
|
| 148 |
-
wrong_tone_message = ""
|
| 149 |
-
kata_tone: Optional[list[tuple[str, int]]] = None
|
| 150 |
-
if use_tone and kata_tone_json_str != "":
|
| 151 |
-
if language != "JP":
|
| 152 |
-
wrong_tone_message = "アクセント指定は現在日本語のみ対応しています。"
|
| 153 |
-
if line_split:
|
| 154 |
-
wrong_tone_message = (
|
| 155 |
-
"アクセント指定は改行で分けて生成を使わない場合のみ対応しています。"
|
| 156 |
-
)
|
| 157 |
-
try:
|
| 158 |
-
kata_tone = []
|
| 159 |
-
json_data = json.loads(kata_tone_json_str)
|
| 160 |
-
for kana, tone in json_data:
|
| 161 |
-
assert isinstance(kana, str) and tone in (0, 1), f"{kana}, {tone}"
|
| 162 |
-
kata_tone.append((kana, tone))
|
| 163 |
-
except Exception as e:
|
| 164 |
-
logger.warning(f"Error occurred when parsing kana_tone_json: {e}")
|
| 165 |
-
wrong_tone_message = f"アクセント指定が不正です: {e}"
|
| 166 |
-
kata_tone = None
|
| 167 |
-
|
| 168 |
-
tone: Optional[list[int]] = None
|
| 169 |
-
if kata_tone is not None:
|
| 170 |
-
phone_tone = kata_tone2phone_tone(kata_tone)
|
| 171 |
-
tone = [t for _, t in phone_tone]
|
| 172 |
-
|
| 173 |
-
try:
|
| 174 |
-
sr, audio = model_holder.current_model.infer(
|
| 175 |
-
text=text,
|
| 176 |
-
language=language,
|
| 177 |
-
reference_audio_path=reference_audio_path,
|
| 178 |
-
sdp_ratio=sdp_ratio,
|
| 179 |
-
noise=noise_scale,
|
| 180 |
-
noisew=noise_scale_w,
|
| 181 |
-
length=length_scale,
|
| 182 |
-
line_split=line_split,
|
| 183 |
-
split_interval=split_interval,
|
| 184 |
-
assist_text=assist_text,
|
| 185 |
-
assist_text_weight=assist_text_weight,
|
| 186 |
-
use_assist_text=use_assist_text,
|
| 187 |
-
style=style,
|
| 188 |
-
style_weight=style_weight,
|
| 189 |
-
given_tone=tone,
|
| 190 |
-
sid=speaker_id,
|
| 191 |
-
)
|
| 192 |
-
except InvalidToneError as e:
|
| 193 |
-
logger.error(f"Tone error: {e}")
|
| 194 |
-
return f"Error: アクセント指定が不正です:\n{e}", None, kata_tone_json_str
|
| 195 |
-
except ValueError as e:
|
| 196 |
-
logger.error(f"Value error: {e}")
|
| 197 |
-
return f"Error: {e}", None, kata_tone_json_str
|
| 198 |
-
|
| 199 |
-
end_time = datetime.datetime.now()
|
| 200 |
-
duration = (end_time - start_time).total_seconds()
|
| 201 |
-
|
| 202 |
-
if tone is None and language == "JP":
|
| 203 |
-
norm_text = text_normalize(text)
|
| 204 |
-
kata_tone = g2kata_tone(norm_text)
|
| 205 |
-
kata_tone_json_str = json.dumps(kata_tone, ensure_ascii=False)
|
| 206 |
-
elif tone is None:
|
| 207 |
-
kata_tone_json_str = ""
|
| 208 |
-
|
| 209 |
-
if reference_audio_path:
|
| 210 |
-
style = "External Audio"
|
| 211 |
-
logger.info(
|
| 212 |
-
f"Successful inference, took {duration}s | {speaker} | "
|
| 213 |
-
f"{language}/{sdp_ratio}/{noise_scale}/{noise_scale_w}/{length_scale}/{style}/{style_weight} | {text}"
|
| 214 |
-
)
|
| 215 |
-
message = f"Success, time: {duration} seconds."
|
| 216 |
-
if wrong_tone_message != "":
|
| 217 |
-
message = wrong_tone_message + "\n" + message
|
| 218 |
-
return message, (sr, audio), kata_tone_json_str
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
def load_voicedata():
|
| 222 |
-
print("Loading voice data...")
|
| 223 |
-
envoices = []
|
| 224 |
-
jpvoices = []
|
| 225 |
-
styledict = {}
|
| 226 |
-
with open("voicelist.json", "r", encoding="utf-8") as f:
|
| 227 |
-
voc_info = json.load(f)
|
| 228 |
-
for name, info in voc_info.items():
|
| 229 |
-
if not info['enable']:
|
| 230 |
-
continue
|
| 231 |
-
model_path = info['model_path']
|
| 232 |
-
model_path_full = f"{model_dir}/{model_path}/{model_path}.safetensors"
|
| 233 |
-
if not os.path.exists(model_path_full):
|
| 234 |
-
model_path_full = f"{model_dir}\\{model_path}\\{model_path}.safetensors"
|
| 235 |
-
voice_name = info['title']
|
| 236 |
-
speakerid = info['speakerid']
|
| 237 |
-
datasetauthor = info['datasetauthor']
|
| 238 |
-
image = info['cover']
|
| 239 |
-
if not os.path.exists(f"images/{image}"):
|
| 240 |
-
image = "none.png"
|
| 241 |
-
nospace = False
|
| 242 |
-
if 'disableonspace' in info:
|
| 243 |
-
nospace = info['disableonspace']
|
| 244 |
-
if model_path not in styledict.keys():
|
| 245 |
-
conf = f"{model_dir}/{model_path}/config.json"
|
| 246 |
-
hps = utils.get_hparams_from_file(conf)
|
| 247 |
-
s2id = hps.data.style2id
|
| 248 |
-
styledict[model_path] = s2id.keys()
|
| 249 |
-
print(f"Set up hyperparameters for model {model_path}")
|
| 250 |
-
if info['primarylang'] == "JP":
|
| 251 |
-
jpvoices.append((name, model_path, model_path_full, voice_name, speakerid, datasetauthor, image, nospace))
|
| 252 |
-
else:
|
| 253 |
-
envoices.append((name, model_path, model_path_full, voice_name, speakerid, datasetauthor, image, nospace))
|
| 254 |
-
return [envoices, jpvoices], styledict
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
initial_text = "Hello there! This is test audio of a new Hololive text to speech tool."
|
| 258 |
-
initial_md = """"""
|
| 259 |
-
style_md = """
|
| 260 |
-
- You can control things like voice tone, emotion, and reading style through presets or through voice files.
|
| 261 |
-
- Neutral acts as an average across all speakers. Styling options act as an override to Neutral.
|
| 262 |
-
- Setting the intensity too high will likely break the output.
|
| 263 |
-
"""
|
| 264 |
-
|
| 265 |
-
if __name__ == "__main__":
|
| 266 |
-
parser = argparse.ArgumentParser()
|
| 267 |
-
parser.add_argument("--cpu", action="store_true", help="Use CPU instead of GPU")
|
| 268 |
-
parser.add_argument("--dir", "-d", type=str, help="Model directory", default=assets_root)
|
| 269 |
-
parser.add_argument("--share", action="store_true", help="Share this app publicly", default=False)
|
| 270 |
-
parser.add_argument("--server-name", type=str, default=None, help="Server name for Gradio app")
|
| 271 |
-
parser.add_argument("--no-autolaunch", action="store_true", default=False, help="Do not launch app automatically")
|
| 272 |
-
args = parser.parse_args()
|
| 273 |
-
model_dir = args.dir
|
| 274 |
-
|
| 275 |
-
if args.cpu:
|
| 276 |
-
device = "cpu"
|
| 277 |
-
else:
|
| 278 |
-
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 279 |
-
|
| 280 |
-
model_holder = ModelHolder(model_dir, device)
|
| 281 |
-
languages = ["EN", "JP", "ZH"]
|
| 282 |
-
langnames = ["English", "Japanese"]
|
| 283 |
-
|
| 284 |
-
model_names = model_holder.model_names
|
| 285 |
-
if len(model_names) == 0:
|
| 286 |
-
logger.error(f"No models found. Please place the model in {model_dir}.")
|
| 287 |
-
sys.exit(1)
|
| 288 |
-
|
| 289 |
-
voicedata, styledict = load_voicedata()
|
| 290 |
-
total_characters = sum(len(lang) for lang in voicedata)
|
| 291 |
-
|
| 292 |
-
text_input = gr.TextArea(label="Text", value=initial_text)
|
| 293 |
-
line_split = gr.Checkbox(label="Divide text seperately by line breaks", value=True)
|
| 294 |
-
split_interval = gr.Slider(minimum=0.0, maximum=2, value=0.5, step=0.1, label="Length of division seperation time (in seconds)")
|
| 295 |
-
language = gr.Dropdown(choices=languages, value="EN", label="Language")
|
| 296 |
-
sdp_ratio = gr.Slider(minimum=0, maximum=1, value=0.2, step=0.1, label="SDP Ratio")
|
| 297 |
-
noise_scale = gr.Slider(minimum=0.1, maximum=2, value=0.6, step=0.1, label="Noise")
|
| 298 |
-
noise_scale_w = gr.Slider(minimum=0.1, maximum=2, value=0.8, step=0.1, label="Noise_W")
|
| 299 |
-
speed_rate = gr.Slider(minimum=0.5, maximum=2.0, value=1.0, step=0.1, label="Kecepatan Suara")
|
| 300 |
-
use_style_text = gr.Checkbox(label="Use stylization text", value=False)
|
| 301 |
-
style_text = gr.Textbox(label="Style text", placeholder="Check the box to use this option!", visible=True)
|
| 302 |
-
style_text_weight = gr.Slider(minimum=0, maximum=1, value=0.7, step=0.1, label="Text stylization strength", visible=True)
|
| 303 |
-
|
| 304 |
-
# Theme menggunakan warna Slate (Abu-abu Baby) dan Zinc (Putih Bersih)
|
| 305 |
-
with gr.Blocks(theme=gr.themes.Soft(primary_hue="slate", secondary_hue="zinc"), title="Hololive Style-Bert-VITS2") as app:
|
| 306 |
-
# --- HEADER ---
|
| 307 |
-
gr.HTML(f"""
|
| 308 |
-
<div style="font-family: 'Arial', sans-serif; max-width: 800px; margin: 20px auto 10px auto; border: 1px solid #e2e8f0; border-radius: 12px; padding: 15px; background-color: #ffffff; text-align: center; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);">
|
| 309 |
-
<h1 style="color: #475569; margin: 0; font-weight: 800;">HOLOLIVE VTUBER</h1>
|
| 310 |
-
<p style="color: #94a3b8; font-size: 14px; margin-top: 5px; font-weight: 500;">VTUBER TTS • CODE by Mutsumi</p>
|
| 311 |
-
</div>
|
| 312 |
-
|
| 313 |
-
<div style="font-family: 'Arial', sans-serif; max-width: 800px; margin: 0 auto 20px auto; border: 1px solid #e2e8f0; border-radius: 10px; padding: 15px; background-color: white; display: flex; justify-content: space-around; align-items: center; box-shadow: 0 2px 4px rgba(0,0,0,0.02);">
|
| 314 |
-
<div style="text-align: center;">
|
| 315 |
-
<p style="color: #94a3b8; font-size: 11px; font-weight: 700; margin: 0; text-transform: uppercase; letter-spacing: 1px;">System Status</p>
|
| 316 |
-
<p style="color: #64748b; font-size: 14px; font-weight: 700; margin: 0;">● ONLINE</p>
|
| 317 |
-
</div>
|
| 318 |
-
<div style="height: 30px; border-left: 1px solid #f1f5f9;"></div>
|
| 319 |
-
<div style="text-align: center;">
|
| 320 |
-
<p style="color: #94a3b8; font-size: 11px; font-weight: 700; margin: 0; text-transform: uppercase; letter-spacing: 1px;">TOTAL VTUBER</p>
|
| 321 |
-
<p style="color: #475569; font-size: 14px; font-weight: 700; margin: 0;">{total_characters} Models</p>
|
| 322 |
-
</div>
|
| 323 |
-
</div>
|
| 324 |
-
""")
|
| 325 |
-
|
| 326 |
-
gr.Markdown(initial_md)
|
| 327 |
-
tone = gr.Textbox(label="Accent adjustment", visible=False)
|
| 328 |
-
use_tone = gr.Checkbox(label="Use accent adjustment", value=False, visible=False)
|
| 329 |
-
|
| 330 |
-
for vi in range(len(voicedata)):
|
| 331 |
-
with gr.TabItem(langnames[vi]):
|
| 332 |
-
for (name, model_path, model_path_full, voice_name, speakerid, datasetauthor, image, nospace) in voicedata[vi]:
|
| 333 |
-
if nospace and is_hf_spaces:
|
| 334 |
-
continue
|
| 335 |
-
with gr.TabItem(name):
|
| 336 |
-
mn = gr.Textbox(value=model_path, visible=False, interactive=False)
|
| 337 |
-
mp = gr.Textbox(value=model_path_full, visible=False, interactive=False)
|
| 338 |
-
spk = gr.Textbox(value=speakerid, visible=False, interactive=False)
|
| 339 |
-
with gr.Row():
|
| 340 |
-
with gr.Column():
|
| 341 |
-
gr.Markdown(f"### {voice_name}")
|
| 342 |
-
gr.Image(f"images/{image}", label=None, show_label=False, width=300, show_download_button=False, container=False, show_share_button=False)
|
| 343 |
-
with gr.Column():
|
| 344 |
-
with gr.TabItem("Style using a preset"):
|
| 345 |
-
style = gr.Dropdown(label="Current style", choices=styledict[model_path], value="Neutral")
|
| 346 |
-
with gr.TabItem("Style using existing audio"):
|
| 347 |
-
ref_audio_path = gr.Audio(label="Reference Audio", type="filepath", sources=["upload"])
|
| 348 |
-
style_weight = gr.Slider(minimum=0, maximum=20, value=3, step=0.1, label="Style strength")
|
| 349 |
-
with gr.Column():
|
| 350 |
-
tts_button = gr.Button("Generate Voice", variant="primary", interactive=True)
|
| 351 |
-
text_output = gr.Textbox(label="Info")
|
| 352 |
-
audio_output = gr.Audio(label="Result")
|
| 353 |
-
|
| 354 |
-
tts_button.click(
|
| 355 |
-
tts_fn,
|
| 356 |
-
inputs=[mn, mp, text_input, language, ref_audio_path, sdp_ratio, noise_scale, noise_scale_w, speed_rate, line_split, split_interval, style_text, style_text_weight, use_style_text, style, style_weight, tone, use_tone, spk],
|
| 357 |
-
outputs=[text_output, audio_output, tone],
|
| 358 |
-
)
|
| 359 |
-
|
| 360 |
-
with gr.Row():
|
| 361 |
-
with gr.Column():
|
| 362 |
-
text_input.render()
|
| 363 |
-
line_split.render()
|
| 364 |
-
split_interval.render()
|
| 365 |
-
language.render()
|
| 366 |
-
with gr.Column():
|
| 367 |
-
sdp_ratio.render()
|
| 368 |
-
noise_scale.render()
|
| 369 |
-
noise_scale_w.render()
|
| 370 |
-
speed_rate.render()
|
| 371 |
-
use_style_text.render()
|
| 372 |
-
style_text.render()
|
| 373 |
-
style_text_weight.render()
|
| 374 |
-
|
| 375 |
-
with gr.Accordion("Styling Guide", open=False):
|
| 376 |
-
gr.Markdown(style_md)
|
| 377 |
-
|
| 378 |
-
# --- FOOTER ---
|
| 379 |
-
gr.HTML("""
|
| 380 |
-
<div style="font-family: 'Arial', sans-serif; max-width: 800px; margin: 30px auto 20px auto; border: 1px solid #e2e8f0; border-radius: 12px; padding: 20px; background-color: white; text-align: center; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);">
|
| 381 |
-
<h3 style="color: #475569; font-size: 16px; margin: 0; font-weight: 700; letter-spacing: 1px;">DESIGNED BY MUTSUMI</h3>
|
| 382 |
-
<p style="color: #94a3b8; font-size: 13px; margin-top: 4px; font-weight: 500;">Hololive TTS Implementation</p>
|
| 383 |
-
</div>
|
| 384 |
-
""")
|
| 385 |
-
|
| 386 |
-
app.launch(allowed_paths=['/file/images/'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/attentions.py
DELETED
|
@@ -1,462 +0,0 @@
|
|
| 1 |
-
import math
|
| 2 |
-
import torch
|
| 3 |
-
from torch import nn
|
| 4 |
-
from torch.nn import functional as F
|
| 5 |
-
|
| 6 |
-
import commons
|
| 7 |
-
from common.log import logger as logging
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
class LayerNorm(nn.Module):
|
| 11 |
-
def __init__(self, channels, eps=1e-5):
|
| 12 |
-
super().__init__()
|
| 13 |
-
self.channels = channels
|
| 14 |
-
self.eps = eps
|
| 15 |
-
|
| 16 |
-
self.gamma = nn.Parameter(torch.ones(channels))
|
| 17 |
-
self.beta = nn.Parameter(torch.zeros(channels))
|
| 18 |
-
|
| 19 |
-
def forward(self, x):
|
| 20 |
-
x = x.transpose(1, -1)
|
| 21 |
-
x = F.layer_norm(x, (self.channels,), self.gamma, self.beta, self.eps)
|
| 22 |
-
return x.transpose(1, -1)
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
@torch.jit.script
|
| 26 |
-
def fused_add_tanh_sigmoid_multiply(input_a, input_b, n_channels):
|
| 27 |
-
n_channels_int = n_channels[0]
|
| 28 |
-
in_act = input_a + input_b
|
| 29 |
-
t_act = torch.tanh(in_act[:, :n_channels_int, :])
|
| 30 |
-
s_act = torch.sigmoid(in_act[:, n_channels_int:, :])
|
| 31 |
-
acts = t_act * s_act
|
| 32 |
-
return acts
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
class Encoder(nn.Module):
|
| 36 |
-
def __init__(
|
| 37 |
-
self,
|
| 38 |
-
hidden_channels,
|
| 39 |
-
filter_channels,
|
| 40 |
-
n_heads,
|
| 41 |
-
n_layers,
|
| 42 |
-
kernel_size=1,
|
| 43 |
-
p_dropout=0.0,
|
| 44 |
-
window_size=4,
|
| 45 |
-
isflow=True,
|
| 46 |
-
**kwargs
|
| 47 |
-
):
|
| 48 |
-
super().__init__()
|
| 49 |
-
self.hidden_channels = hidden_channels
|
| 50 |
-
self.filter_channels = filter_channels
|
| 51 |
-
self.n_heads = n_heads
|
| 52 |
-
self.n_layers = n_layers
|
| 53 |
-
self.kernel_size = kernel_size
|
| 54 |
-
self.p_dropout = p_dropout
|
| 55 |
-
self.window_size = window_size
|
| 56 |
-
# if isflow:
|
| 57 |
-
# cond_layer = torch.nn.Conv1d(256, 2*hidden_channels*n_layers, 1)
|
| 58 |
-
# self.cond_pre = torch.nn.Conv1d(hidden_channels, 2*hidden_channels, 1)
|
| 59 |
-
# self.cond_layer = weight_norm(cond_layer, name='weight')
|
| 60 |
-
# self.gin_channels = 256
|
| 61 |
-
self.cond_layer_idx = self.n_layers
|
| 62 |
-
if "gin_channels" in kwargs:
|
| 63 |
-
self.gin_channels = kwargs["gin_channels"]
|
| 64 |
-
if self.gin_channels != 0:
|
| 65 |
-
self.spk_emb_linear = nn.Linear(self.gin_channels, self.hidden_channels)
|
| 66 |
-
# vits2 says 3rd block, so idx is 2 by default
|
| 67 |
-
self.cond_layer_idx = (
|
| 68 |
-
kwargs["cond_layer_idx"] if "cond_layer_idx" in kwargs else 2
|
| 69 |
-
)
|
| 70 |
-
# logging.debug(self.gin_channels, self.cond_layer_idx)
|
| 71 |
-
assert (
|
| 72 |
-
self.cond_layer_idx < self.n_layers
|
| 73 |
-
), "cond_layer_idx should be less than n_layers"
|
| 74 |
-
self.drop = nn.Dropout(p_dropout)
|
| 75 |
-
self.attn_layers = nn.ModuleList()
|
| 76 |
-
self.norm_layers_1 = nn.ModuleList()
|
| 77 |
-
self.ffn_layers = nn.ModuleList()
|
| 78 |
-
self.norm_layers_2 = nn.ModuleList()
|
| 79 |
-
for i in range(self.n_layers):
|
| 80 |
-
self.attn_layers.append(
|
| 81 |
-
MultiHeadAttention(
|
| 82 |
-
hidden_channels,
|
| 83 |
-
hidden_channels,
|
| 84 |
-
n_heads,
|
| 85 |
-
p_dropout=p_dropout,
|
| 86 |
-
window_size=window_size,
|
| 87 |
-
)
|
| 88 |
-
)
|
| 89 |
-
self.norm_layers_1.append(LayerNorm(hidden_channels))
|
| 90 |
-
self.ffn_layers.append(
|
| 91 |
-
FFN(
|
| 92 |
-
hidden_channels,
|
| 93 |
-
hidden_channels,
|
| 94 |
-
filter_channels,
|
| 95 |
-
kernel_size,
|
| 96 |
-
p_dropout=p_dropout,
|
| 97 |
-
)
|
| 98 |
-
)
|
| 99 |
-
self.norm_layers_2.append(LayerNorm(hidden_channels))
|
| 100 |
-
|
| 101 |
-
def forward(self, x, x_mask, g=None):
|
| 102 |
-
attn_mask = x_mask.unsqueeze(2) * x_mask.unsqueeze(-1)
|
| 103 |
-
x = x * x_mask
|
| 104 |
-
for i in range(self.n_layers):
|
| 105 |
-
if i == self.cond_layer_idx and g is not None:
|
| 106 |
-
g = self.spk_emb_linear(g.transpose(1, 2))
|
| 107 |
-
g = g.transpose(1, 2)
|
| 108 |
-
x = x + g
|
| 109 |
-
x = x * x_mask
|
| 110 |
-
y = self.attn_layers[i](x, x, attn_mask)
|
| 111 |
-
y = self.drop(y)
|
| 112 |
-
x = self.norm_layers_1[i](x + y)
|
| 113 |
-
|
| 114 |
-
y = self.ffn_layers[i](x, x_mask)
|
| 115 |
-
y = self.drop(y)
|
| 116 |
-
x = self.norm_layers_2[i](x + y)
|
| 117 |
-
x = x * x_mask
|
| 118 |
-
return x
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
class Decoder(nn.Module):
|
| 122 |
-
def __init__(
|
| 123 |
-
self,
|
| 124 |
-
hidden_channels,
|
| 125 |
-
filter_channels,
|
| 126 |
-
n_heads,
|
| 127 |
-
n_layers,
|
| 128 |
-
kernel_size=1,
|
| 129 |
-
p_dropout=0.0,
|
| 130 |
-
proximal_bias=False,
|
| 131 |
-
proximal_init=True,
|
| 132 |
-
**kwargs
|
| 133 |
-
):
|
| 134 |
-
super().__init__()
|
| 135 |
-
self.hidden_channels = hidden_channels
|
| 136 |
-
self.filter_channels = filter_channels
|
| 137 |
-
self.n_heads = n_heads
|
| 138 |
-
self.n_layers = n_layers
|
| 139 |
-
self.kernel_size = kernel_size
|
| 140 |
-
self.p_dropout = p_dropout
|
| 141 |
-
self.proximal_bias = proximal_bias
|
| 142 |
-
self.proximal_init = proximal_init
|
| 143 |
-
|
| 144 |
-
self.drop = nn.Dropout(p_dropout)
|
| 145 |
-
self.self_attn_layers = nn.ModuleList()
|
| 146 |
-
self.norm_layers_0 = nn.ModuleList()
|
| 147 |
-
self.encdec_attn_layers = nn.ModuleList()
|
| 148 |
-
self.norm_layers_1 = nn.ModuleList()
|
| 149 |
-
self.ffn_layers = nn.ModuleList()
|
| 150 |
-
self.norm_layers_2 = nn.ModuleList()
|
| 151 |
-
for i in range(self.n_layers):
|
| 152 |
-
self.self_attn_layers.append(
|
| 153 |
-
MultiHeadAttention(
|
| 154 |
-
hidden_channels,
|
| 155 |
-
hidden_channels,
|
| 156 |
-
n_heads,
|
| 157 |
-
p_dropout=p_dropout,
|
| 158 |
-
proximal_bias=proximal_bias,
|
| 159 |
-
proximal_init=proximal_init,
|
| 160 |
-
)
|
| 161 |
-
)
|
| 162 |
-
self.norm_layers_0.append(LayerNorm(hidden_channels))
|
| 163 |
-
self.encdec_attn_layers.append(
|
| 164 |
-
MultiHeadAttention(
|
| 165 |
-
hidden_channels, hidden_channels, n_heads, p_dropout=p_dropout
|
| 166 |
-
)
|
| 167 |
-
)
|
| 168 |
-
self.norm_layers_1.append(LayerNorm(hidden_channels))
|
| 169 |
-
self.ffn_layers.append(
|
| 170 |
-
FFN(
|
| 171 |
-
hidden_channels,
|
| 172 |
-
hidden_channels,
|
| 173 |
-
filter_channels,
|
| 174 |
-
kernel_size,
|
| 175 |
-
p_dropout=p_dropout,
|
| 176 |
-
causal=True,
|
| 177 |
-
)
|
| 178 |
-
)
|
| 179 |
-
self.norm_layers_2.append(LayerNorm(hidden_channels))
|
| 180 |
-
|
| 181 |
-
def forward(self, x, x_mask, h, h_mask):
|
| 182 |
-
"""
|
| 183 |
-
x: decoder input
|
| 184 |
-
h: encoder output
|
| 185 |
-
"""
|
| 186 |
-
self_attn_mask = commons.subsequent_mask(x_mask.size(2)).to(
|
| 187 |
-
device=x.device, dtype=x.dtype
|
| 188 |
-
)
|
| 189 |
-
encdec_attn_mask = h_mask.unsqueeze(2) * x_mask.unsqueeze(-1)
|
| 190 |
-
x = x * x_mask
|
| 191 |
-
for i in range(self.n_layers):
|
| 192 |
-
y = self.self_attn_layers[i](x, x, self_attn_mask)
|
| 193 |
-
y = self.drop(y)
|
| 194 |
-
x = self.norm_layers_0[i](x + y)
|
| 195 |
-
|
| 196 |
-
y = self.encdec_attn_layers[i](x, h, encdec_attn_mask)
|
| 197 |
-
y = self.drop(y)
|
| 198 |
-
x = self.norm_layers_1[i](x + y)
|
| 199 |
-
|
| 200 |
-
y = self.ffn_layers[i](x, x_mask)
|
| 201 |
-
y = self.drop(y)
|
| 202 |
-
x = self.norm_layers_2[i](x + y)
|
| 203 |
-
x = x * x_mask
|
| 204 |
-
return x
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
class MultiHeadAttention(nn.Module):
|
| 208 |
-
def __init__(
|
| 209 |
-
self,
|
| 210 |
-
channels,
|
| 211 |
-
out_channels,
|
| 212 |
-
n_heads,
|
| 213 |
-
p_dropout=0.0,
|
| 214 |
-
window_size=None,
|
| 215 |
-
heads_share=True,
|
| 216 |
-
block_length=None,
|
| 217 |
-
proximal_bias=False,
|
| 218 |
-
proximal_init=False,
|
| 219 |
-
):
|
| 220 |
-
super().__init__()
|
| 221 |
-
assert channels % n_heads == 0
|
| 222 |
-
|
| 223 |
-
self.channels = channels
|
| 224 |
-
self.out_channels = out_channels
|
| 225 |
-
self.n_heads = n_heads
|
| 226 |
-
self.p_dropout = p_dropout
|
| 227 |
-
self.window_size = window_size
|
| 228 |
-
self.heads_share = heads_share
|
| 229 |
-
self.block_length = block_length
|
| 230 |
-
self.proximal_bias = proximal_bias
|
| 231 |
-
self.proximal_init = proximal_init
|
| 232 |
-
self.attn = None
|
| 233 |
-
|
| 234 |
-
self.k_channels = channels // n_heads
|
| 235 |
-
self.conv_q = nn.Conv1d(channels, channels, 1)
|
| 236 |
-
self.conv_k = nn.Conv1d(channels, channels, 1)
|
| 237 |
-
self.conv_v = nn.Conv1d(channels, channels, 1)
|
| 238 |
-
self.conv_o = nn.Conv1d(channels, out_channels, 1)
|
| 239 |
-
self.drop = nn.Dropout(p_dropout)
|
| 240 |
-
|
| 241 |
-
if window_size is not None:
|
| 242 |
-
n_heads_rel = 1 if heads_share else n_heads
|
| 243 |
-
rel_stddev = self.k_channels**-0.5
|
| 244 |
-
self.emb_rel_k = nn.Parameter(
|
| 245 |
-
torch.randn(n_heads_rel, window_size * 2 + 1, self.k_channels)
|
| 246 |
-
* rel_stddev
|
| 247 |
-
)
|
| 248 |
-
self.emb_rel_v = nn.Parameter(
|
| 249 |
-
torch.randn(n_heads_rel, window_size * 2 + 1, self.k_channels)
|
| 250 |
-
* rel_stddev
|
| 251 |
-
)
|
| 252 |
-
|
| 253 |
-
nn.init.xavier_uniform_(self.conv_q.weight)
|
| 254 |
-
nn.init.xavier_uniform_(self.conv_k.weight)
|
| 255 |
-
nn.init.xavier_uniform_(self.conv_v.weight)
|
| 256 |
-
if proximal_init:
|
| 257 |
-
with torch.no_grad():
|
| 258 |
-
self.conv_k.weight.copy_(self.conv_q.weight)
|
| 259 |
-
self.conv_k.bias.copy_(self.conv_q.bias)
|
| 260 |
-
|
| 261 |
-
def forward(self, x, c, attn_mask=None):
|
| 262 |
-
q = self.conv_q(x)
|
| 263 |
-
k = self.conv_k(c)
|
| 264 |
-
v = self.conv_v(c)
|
| 265 |
-
|
| 266 |
-
x, self.attn = self.attention(q, k, v, mask=attn_mask)
|
| 267 |
-
|
| 268 |
-
x = self.conv_o(x)
|
| 269 |
-
return x
|
| 270 |
-
|
| 271 |
-
def attention(self, query, key, value, mask=None):
|
| 272 |
-
# reshape [b, d, t] -> [b, n_h, t, d_k]
|
| 273 |
-
b, d, t_s, t_t = (*key.size(), query.size(2))
|
| 274 |
-
query = query.view(b, self.n_heads, self.k_channels, t_t).transpose(2, 3)
|
| 275 |
-
key = key.view(b, self.n_heads, self.k_channels, t_s).transpose(2, 3)
|
| 276 |
-
value = value.view(b, self.n_heads, self.k_channels, t_s).transpose(2, 3)
|
| 277 |
-
|
| 278 |
-
scores = torch.matmul(query / math.sqrt(self.k_channels), key.transpose(-2, -1))
|
| 279 |
-
if self.window_size is not None:
|
| 280 |
-
assert (
|
| 281 |
-
t_s == t_t
|
| 282 |
-
), "Relative attention is only available for self-attention."
|
| 283 |
-
key_relative_embeddings = self._get_relative_embeddings(self.emb_rel_k, t_s)
|
| 284 |
-
rel_logits = self._matmul_with_relative_keys(
|
| 285 |
-
query / math.sqrt(self.k_channels), key_relative_embeddings
|
| 286 |
-
)
|
| 287 |
-
scores_local = self._relative_position_to_absolute_position(rel_logits)
|
| 288 |
-
scores = scores + scores_local
|
| 289 |
-
if self.proximal_bias:
|
| 290 |
-
assert t_s == t_t, "Proximal bias is only available for self-attention."
|
| 291 |
-
scores = scores + self._attention_bias_proximal(t_s).to(
|
| 292 |
-
device=scores.device, dtype=scores.dtype
|
| 293 |
-
)
|
| 294 |
-
if mask is not None:
|
| 295 |
-
scores = scores.masked_fill(mask == 0, -1e4)
|
| 296 |
-
if self.block_length is not None:
|
| 297 |
-
assert (
|
| 298 |
-
t_s == t_t
|
| 299 |
-
), "Local attention is only available for self-attention."
|
| 300 |
-
block_mask = (
|
| 301 |
-
torch.ones_like(scores)
|
| 302 |
-
.triu(-self.block_length)
|
| 303 |
-
.tril(self.block_length)
|
| 304 |
-
)
|
| 305 |
-
scores = scores.masked_fill(block_mask == 0, -1e4)
|
| 306 |
-
p_attn = F.softmax(scores, dim=-1) # [b, n_h, t_t, t_s]
|
| 307 |
-
p_attn = self.drop(p_attn)
|
| 308 |
-
output = torch.matmul(p_attn, value)
|
| 309 |
-
if self.window_size is not None:
|
| 310 |
-
relative_weights = self._absolute_position_to_relative_position(p_attn)
|
| 311 |
-
value_relative_embeddings = self._get_relative_embeddings(
|
| 312 |
-
self.emb_rel_v, t_s
|
| 313 |
-
)
|
| 314 |
-
output = output + self._matmul_with_relative_values(
|
| 315 |
-
relative_weights, value_relative_embeddings
|
| 316 |
-
)
|
| 317 |
-
output = (
|
| 318 |
-
output.transpose(2, 3).contiguous().view(b, d, t_t)
|
| 319 |
-
) # [b, n_h, t_t, d_k] -> [b, d, t_t]
|
| 320 |
-
return output, p_attn
|
| 321 |
-
|
| 322 |
-
def _matmul_with_relative_values(self, x, y):
|
| 323 |
-
"""
|
| 324 |
-
x: [b, h, l, m]
|
| 325 |
-
y: [h or 1, m, d]
|
| 326 |
-
ret: [b, h, l, d]
|
| 327 |
-
"""
|
| 328 |
-
ret = torch.matmul(x, y.unsqueeze(0))
|
| 329 |
-
return ret
|
| 330 |
-
|
| 331 |
-
def _matmul_with_relative_keys(self, x, y):
|
| 332 |
-
"""
|
| 333 |
-
x: [b, h, l, d]
|
| 334 |
-
y: [h or 1, m, d]
|
| 335 |
-
ret: [b, h, l, m]
|
| 336 |
-
"""
|
| 337 |
-
ret = torch.matmul(x, y.unsqueeze(0).transpose(-2, -1))
|
| 338 |
-
return ret
|
| 339 |
-
|
| 340 |
-
def _get_relative_embeddings(self, relative_embeddings, length):
|
| 341 |
-
2 * self.window_size + 1
|
| 342 |
-
# Pad first before slice to avoid using cond ops.
|
| 343 |
-
pad_length = max(length - (self.window_size + 1), 0)
|
| 344 |
-
slice_start_position = max((self.window_size + 1) - length, 0)
|
| 345 |
-
slice_end_position = slice_start_position + 2 * length - 1
|
| 346 |
-
if pad_length > 0:
|
| 347 |
-
padded_relative_embeddings = F.pad(
|
| 348 |
-
relative_embeddings,
|
| 349 |
-
commons.convert_pad_shape([[0, 0], [pad_length, pad_length], [0, 0]]),
|
| 350 |
-
)
|
| 351 |
-
else:
|
| 352 |
-
padded_relative_embeddings = relative_embeddings
|
| 353 |
-
used_relative_embeddings = padded_relative_embeddings[
|
| 354 |
-
:, slice_start_position:slice_end_position
|
| 355 |
-
]
|
| 356 |
-
return used_relative_embeddings
|
| 357 |
-
|
| 358 |
-
def _relative_position_to_absolute_position(self, x):
|
| 359 |
-
"""
|
| 360 |
-
x: [b, h, l, 2*l-1]
|
| 361 |
-
ret: [b, h, l, l]
|
| 362 |
-
"""
|
| 363 |
-
batch, heads, length, _ = x.size()
|
| 364 |
-
# Concat columns of pad to shift from relative to absolute indexing.
|
| 365 |
-
x = F.pad(x, commons.convert_pad_shape([[0, 0], [0, 0], [0, 0], [0, 1]]))
|
| 366 |
-
|
| 367 |
-
# Concat extra elements so to add up to shape (len+1, 2*len-1).
|
| 368 |
-
x_flat = x.view([batch, heads, length * 2 * length])
|
| 369 |
-
x_flat = F.pad(
|
| 370 |
-
x_flat, commons.convert_pad_shape([[0, 0], [0, 0], [0, length - 1]])
|
| 371 |
-
)
|
| 372 |
-
|
| 373 |
-
# Reshape and slice out the padded elements.
|
| 374 |
-
x_final = x_flat.view([batch, heads, length + 1, 2 * length - 1])[
|
| 375 |
-
:, :, :length, length - 1 :
|
| 376 |
-
]
|
| 377 |
-
return x_final
|
| 378 |
-
|
| 379 |
-
def _absolute_position_to_relative_position(self, x):
|
| 380 |
-
"""
|
| 381 |
-
x: [b, h, l, l]
|
| 382 |
-
ret: [b, h, l, 2*l-1]
|
| 383 |
-
"""
|
| 384 |
-
batch, heads, length, _ = x.size()
|
| 385 |
-
# pad along column
|
| 386 |
-
x = F.pad(
|
| 387 |
-
x, commons.convert_pad_shape([[0, 0], [0, 0], [0, 0], [0, length - 1]])
|
| 388 |
-
)
|
| 389 |
-
x_flat = x.view([batch, heads, length**2 + length * (length - 1)])
|
| 390 |
-
# add 0's in the beginning that will skew the elements after reshape
|
| 391 |
-
x_flat = F.pad(x_flat, commons.convert_pad_shape([[0, 0], [0, 0], [length, 0]]))
|
| 392 |
-
x_final = x_flat.view([batch, heads, length, 2 * length])[:, :, :, 1:]
|
| 393 |
-
return x_final
|
| 394 |
-
|
| 395 |
-
def _attention_bias_proximal(self, length):
|
| 396 |
-
"""Bias for self-attention to encourage attention to close positions.
|
| 397 |
-
Args:
|
| 398 |
-
length: an integer scalar.
|
| 399 |
-
Returns:
|
| 400 |
-
a Tensor with shape [1, 1, length, length]
|
| 401 |
-
"""
|
| 402 |
-
r = torch.arange(length, dtype=torch.float32)
|
| 403 |
-
diff = torch.unsqueeze(r, 0) - torch.unsqueeze(r, 1)
|
| 404 |
-
return torch.unsqueeze(torch.unsqueeze(-torch.log1p(torch.abs(diff)), 0), 0)
|
| 405 |
-
|
| 406 |
-
|
| 407 |
-
class FFN(nn.Module):
|
| 408 |
-
def __init__(
|
| 409 |
-
self,
|
| 410 |
-
in_channels,
|
| 411 |
-
out_channels,
|
| 412 |
-
filter_channels,
|
| 413 |
-
kernel_size,
|
| 414 |
-
p_dropout=0.0,
|
| 415 |
-
activation=None,
|
| 416 |
-
causal=False,
|
| 417 |
-
):
|
| 418 |
-
super().__init__()
|
| 419 |
-
self.in_channels = in_channels
|
| 420 |
-
self.out_channels = out_channels
|
| 421 |
-
self.filter_channels = filter_channels
|
| 422 |
-
self.kernel_size = kernel_size
|
| 423 |
-
self.p_dropout = p_dropout
|
| 424 |
-
self.activation = activation
|
| 425 |
-
self.causal = causal
|
| 426 |
-
|
| 427 |
-
if causal:
|
| 428 |
-
self.padding = self._causal_padding
|
| 429 |
-
else:
|
| 430 |
-
self.padding = self._same_padding
|
| 431 |
-
|
| 432 |
-
self.conv_1 = nn.Conv1d(in_channels, filter_channels, kernel_size)
|
| 433 |
-
self.conv_2 = nn.Conv1d(filter_channels, out_channels, kernel_size)
|
| 434 |
-
self.drop = nn.Dropout(p_dropout)
|
| 435 |
-
|
| 436 |
-
def forward(self, x, x_mask):
|
| 437 |
-
x = self.conv_1(self.padding(x * x_mask))
|
| 438 |
-
if self.activation == "gelu":
|
| 439 |
-
x = x * torch.sigmoid(1.702 * x)
|
| 440 |
-
else:
|
| 441 |
-
x = torch.relu(x)
|
| 442 |
-
x = self.drop(x)
|
| 443 |
-
x = self.conv_2(self.padding(x * x_mask))
|
| 444 |
-
return x * x_mask
|
| 445 |
-
|
| 446 |
-
def _causal_padding(self, x):
|
| 447 |
-
if self.kernel_size == 1:
|
| 448 |
-
return x
|
| 449 |
-
pad_l = self.kernel_size - 1
|
| 450 |
-
pad_r = 0
|
| 451 |
-
padding = [[0, 0], [0, 0], [pad_l, pad_r]]
|
| 452 |
-
x = F.pad(x, commons.convert_pad_shape(padding))
|
| 453 |
-
return x
|
| 454 |
-
|
| 455 |
-
def _same_padding(self, x):
|
| 456 |
-
if self.kernel_size == 1:
|
| 457 |
-
return x
|
| 458 |
-
pad_l = (self.kernel_size - 1) // 2
|
| 459 |
-
pad_r = self.kernel_size // 2
|
| 460 |
-
padding = [[0, 0], [0, 0], [pad_l, pad_r]]
|
| 461 |
-
x = F.pad(x, commons.convert_pad_shape(padding))
|
| 462 |
-
return x
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/bert_gen.py
DELETED
|
@@ -1,84 +0,0 @@
|
|
| 1 |
-
import argparse
|
| 2 |
-
import sys
|
| 3 |
-
from multiprocessing import Pool
|
| 4 |
-
|
| 5 |
-
import torch
|
| 6 |
-
import torch.multiprocessing as mp
|
| 7 |
-
from tqdm import tqdm
|
| 8 |
-
|
| 9 |
-
import commons
|
| 10 |
-
import utils
|
| 11 |
-
from config import config
|
| 12 |
-
from text import cleaned_text_to_sequence, get_bert
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
def process_line(x):
|
| 16 |
-
line, add_blank = x
|
| 17 |
-
device = config.bert_gen_config.device
|
| 18 |
-
if config.bert_gen_config.use_multi_device:
|
| 19 |
-
rank = mp.current_process()._identity
|
| 20 |
-
rank = rank[0] if len(rank) > 0 else 0
|
| 21 |
-
if torch.cuda.is_available():
|
| 22 |
-
gpu_id = rank % torch.cuda.device_count()
|
| 23 |
-
device = torch.device(f"cuda:{gpu_id}")
|
| 24 |
-
else:
|
| 25 |
-
device = torch.device("cpu")
|
| 26 |
-
wav_path, _, language_str, text, phones, tone, word2ph = line.strip().split("|")
|
| 27 |
-
phone = phones.split(" ")
|
| 28 |
-
tone = [int(i) for i in tone.split(" ")]
|
| 29 |
-
word2ph = [int(i) for i in word2ph.split(" ")]
|
| 30 |
-
word2ph = [i for i in word2ph]
|
| 31 |
-
phone, tone, language = cleaned_text_to_sequence(phone, tone, language_str)
|
| 32 |
-
|
| 33 |
-
if add_blank:
|
| 34 |
-
phone = commons.intersperse(phone, 0)
|
| 35 |
-
tone = commons.intersperse(tone, 0)
|
| 36 |
-
language = commons.intersperse(language, 0)
|
| 37 |
-
for i in range(len(word2ph)):
|
| 38 |
-
word2ph[i] = word2ph[i] * 2
|
| 39 |
-
word2ph[0] += 1
|
| 40 |
-
|
| 41 |
-
bert_path = wav_path.replace(".WAV", ".wav").replace(".wav", ".bert.pt")
|
| 42 |
-
|
| 43 |
-
try:
|
| 44 |
-
bert = torch.load(bert_path)
|
| 45 |
-
assert bert.shape[-1] == len(phone)
|
| 46 |
-
except Exception:
|
| 47 |
-
bert = get_bert(text, word2ph, language_str, device)
|
| 48 |
-
assert bert.shape[-1] == len(phone)
|
| 49 |
-
torch.save(bert, bert_path)
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
preprocess_text_config = config.preprocess_text_config
|
| 53 |
-
|
| 54 |
-
if __name__ == "__main__":
|
| 55 |
-
parser = argparse.ArgumentParser()
|
| 56 |
-
parser.add_argument(
|
| 57 |
-
"-c", "--config", type=str, default=config.bert_gen_config.config_path
|
| 58 |
-
)
|
| 59 |
-
parser.add_argument(
|
| 60 |
-
"--num_processes", type=int, default=config.bert_gen_config.num_processes
|
| 61 |
-
)
|
| 62 |
-
args, _ = parser.parse_known_args()
|
| 63 |
-
config_path = args.config
|
| 64 |
-
hps = utils.get_hparams_from_file(config_path)
|
| 65 |
-
lines = []
|
| 66 |
-
with open(hps.data.training_files, encoding="utf-8") as f:
|
| 67 |
-
lines.extend(f.readlines())
|
| 68 |
-
|
| 69 |
-
with open(hps.data.validation_files, encoding="utf-8") as f:
|
| 70 |
-
lines.extend(f.readlines())
|
| 71 |
-
add_blank = [hps.data.add_blank] * len(lines)
|
| 72 |
-
|
| 73 |
-
if len(lines) != 0:
|
| 74 |
-
num_processes = args.num_processes
|
| 75 |
-
with Pool(processes=num_processes) as pool:
|
| 76 |
-
for _ in tqdm(
|
| 77 |
-
pool.imap_unordered(process_line, zip(lines, add_blank)),
|
| 78 |
-
total=len(lines),
|
| 79 |
-
file=sys.stdout,
|
| 80 |
-
):
|
| 81 |
-
# 这里是缩进的代码块,表示循环体
|
| 82 |
-
pass # 使用pass语句作为占位符
|
| 83 |
-
|
| 84 |
-
print(f"bert.pt is generated! total: {len(lines)} bert.pt files.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/common/constants.py
DELETED
|
@@ -1,20 +0,0 @@
|
|
| 1 |
-
import enum
|
| 2 |
-
|
| 3 |
-
DEFAULT_STYLE: str = "Neutral"
|
| 4 |
-
DEFAULT_STYLE_WEIGHT: float = 5.0
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
class Languages(str, enum.Enum):
|
| 8 |
-
JP = "JP"
|
| 9 |
-
EN = "EN"
|
| 10 |
-
ZH = "ZH"
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
DEFAULT_SDP_RATIO: float = 0.2
|
| 14 |
-
DEFAULT_NOISE: float = 0.6
|
| 15 |
-
DEFAULT_NOISEW: float = 0.8
|
| 16 |
-
DEFAULT_LENGTH: float = 1.0
|
| 17 |
-
DEFAULT_LINE_SPLIT: bool = True
|
| 18 |
-
DEFAULT_SPLIT_INTERVAL: float = 0.5
|
| 19 |
-
DEFAULT_ASSIST_TEXT_WEIGHT: float = 0.7
|
| 20 |
-
DEFAULT_ASSIST_TEXT_WEIGHT: float = 1.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/common/log.py
DELETED
|
@@ -1,16 +0,0 @@
|
|
| 1 |
-
"""
|
| 2 |
-
logger封装
|
| 3 |
-
"""
|
| 4 |
-
from loguru import logger
|
| 5 |
-
|
| 6 |
-
from .stdout_wrapper import SAFE_STDOUT
|
| 7 |
-
|
| 8 |
-
# 移除所有默认的处理器
|
| 9 |
-
logger.remove()
|
| 10 |
-
|
| 11 |
-
# 自定义格式并添加到标准输出
|
| 12 |
-
log_format = (
|
| 13 |
-
"<g>{time:MM-DD HH:mm:ss}</g> |<lvl>{level:^8}</lvl>| {file}:{line} | {message}"
|
| 14 |
-
)
|
| 15 |
-
|
| 16 |
-
logger.add(SAFE_STDOUT, format=log_format, backtrace=True, diagnose=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/common/stdout_wrapper.py
DELETED
|
@@ -1,34 +0,0 @@
|
|
| 1 |
-
import sys
|
| 2 |
-
import tempfile
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
class StdoutWrapper:
|
| 6 |
-
def __init__(self):
|
| 7 |
-
self.temp_file = tempfile.NamedTemporaryFile(mode="w+", delete=False)
|
| 8 |
-
self.original_stdout = sys.stdout
|
| 9 |
-
|
| 10 |
-
def write(self, message: str):
|
| 11 |
-
self.temp_file.write(message)
|
| 12 |
-
self.temp_file.flush()
|
| 13 |
-
print(message, end="", file=self.original_stdout)
|
| 14 |
-
|
| 15 |
-
def flush(self):
|
| 16 |
-
self.temp_file.flush()
|
| 17 |
-
|
| 18 |
-
def read(self):
|
| 19 |
-
self.temp_file.seek(0)
|
| 20 |
-
return self.temp_file.read()
|
| 21 |
-
|
| 22 |
-
def close(self):
|
| 23 |
-
self.temp_file.close()
|
| 24 |
-
|
| 25 |
-
def fileno(self):
|
| 26 |
-
return self.temp_file.fileno()
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
try:
|
| 30 |
-
import google.colab
|
| 31 |
-
|
| 32 |
-
SAFE_STDOUT = StdoutWrapper()
|
| 33 |
-
except ImportError:
|
| 34 |
-
SAFE_STDOUT = sys.stdout
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/common/subprocess_utils.py
DELETED
|
@@ -1,32 +0,0 @@
|
|
| 1 |
-
import subprocess
|
| 2 |
-
import sys
|
| 3 |
-
|
| 4 |
-
from .log import logger
|
| 5 |
-
from .stdout_wrapper import SAFE_STDOUT
|
| 6 |
-
|
| 7 |
-
python = sys.executable
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
def run_script_with_log(cmd: list[str], ignore_warning=False) -> tuple[bool, str]:
|
| 11 |
-
logger.info(f"Running: {' '.join(cmd)}")
|
| 12 |
-
result = subprocess.run(
|
| 13 |
-
[python] + cmd,
|
| 14 |
-
stdout=SAFE_STDOUT, # type: ignore
|
| 15 |
-
stderr=subprocess.PIPE,
|
| 16 |
-
text=True,
|
| 17 |
-
)
|
| 18 |
-
if result.returncode != 0:
|
| 19 |
-
logger.error(f"Error: {' '.join(cmd)}\n{result.stderr}")
|
| 20 |
-
return False, result.stderr
|
| 21 |
-
elif result.stderr and not ignore_warning:
|
| 22 |
-
logger.warning(f"Warning: {' '.join(cmd)}\n{result.stderr}")
|
| 23 |
-
return True, result.stderr
|
| 24 |
-
logger.success(f"Success: {' '.join(cmd)}")
|
| 25 |
-
return True, ""
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
def second_elem_of(original_function):
|
| 29 |
-
def inner_function(*args, **kwargs):
|
| 30 |
-
return original_function(*args, **kwargs)[1]
|
| 31 |
-
|
| 32 |
-
return inner_function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/common/tts_model.py
DELETED
|
@@ -1,250 +0,0 @@
|
|
| 1 |
-
import numpy as np
|
| 2 |
-
import gradio as gr
|
| 3 |
-
import torch
|
| 4 |
-
import os
|
| 5 |
-
import warnings
|
| 6 |
-
from gradio.processing_utils import convert_to_16_bit_wav
|
| 7 |
-
from typing import Dict, List, Optional, Union
|
| 8 |
-
|
| 9 |
-
import utils
|
| 10 |
-
from infer import get_net_g, infer
|
| 11 |
-
from models import SynthesizerTrn
|
| 12 |
-
from models_jp_extra import SynthesizerTrn as SynthesizerTrnJPExtra
|
| 13 |
-
|
| 14 |
-
from .log import logger
|
| 15 |
-
from .constants import (
|
| 16 |
-
DEFAULT_ASSIST_TEXT_WEIGHT,
|
| 17 |
-
DEFAULT_LENGTH,
|
| 18 |
-
DEFAULT_LINE_SPLIT,
|
| 19 |
-
DEFAULT_NOISE,
|
| 20 |
-
DEFAULT_NOISEW,
|
| 21 |
-
DEFAULT_SDP_RATIO,
|
| 22 |
-
DEFAULT_SPLIT_INTERVAL,
|
| 23 |
-
DEFAULT_STYLE,
|
| 24 |
-
DEFAULT_STYLE_WEIGHT,
|
| 25 |
-
)
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
class Model:
|
| 29 |
-
def __init__(
|
| 30 |
-
self, model_path: str, config_path: str, style_vec_path: str, device: str
|
| 31 |
-
):
|
| 32 |
-
self.model_path: str = model_path
|
| 33 |
-
self.config_path: str = config_path
|
| 34 |
-
self.device: str = device
|
| 35 |
-
self.style_vec_path: str = style_vec_path
|
| 36 |
-
self.hps: utils.HParams = utils.get_hparams_from_file(self.config_path)
|
| 37 |
-
self.spk2id: Dict[str, int] = self.hps.data.spk2id
|
| 38 |
-
self.id2spk: Dict[int, str] = {v: k for k, v in self.spk2id.items()}
|
| 39 |
-
|
| 40 |
-
self.num_styles: int = self.hps.data.num_styles
|
| 41 |
-
if hasattr(self.hps.data, "style2id"):
|
| 42 |
-
self.style2id: Dict[str, int] = self.hps.data.style2id
|
| 43 |
-
else:
|
| 44 |
-
self.style2id: Dict[str, int] = {str(i): i for i in range(self.num_styles)}
|
| 45 |
-
if len(self.style2id) != self.num_styles:
|
| 46 |
-
raise ValueError(
|
| 47 |
-
f"Number of styles ({self.num_styles}) does not match the number of style2id ({len(self.style2id)})"
|
| 48 |
-
)
|
| 49 |
-
|
| 50 |
-
self.style_vectors: np.ndarray = np.load(self.style_vec_path)
|
| 51 |
-
if self.style_vectors.shape[0] != self.num_styles:
|
| 52 |
-
raise ValueError(
|
| 53 |
-
f"The number of styles ({self.num_styles}) does not match the number of style vectors ({self.style_vectors.shape[0]})"
|
| 54 |
-
)
|
| 55 |
-
|
| 56 |
-
self.net_g: Union[SynthesizerTrn, SynthesizerTrnJPExtra, None] = None
|
| 57 |
-
|
| 58 |
-
def load_net_g(self):
|
| 59 |
-
self.net_g = get_net_g(
|
| 60 |
-
model_path=self.model_path,
|
| 61 |
-
version=self.hps.version,
|
| 62 |
-
device=self.device,
|
| 63 |
-
hps=self.hps,
|
| 64 |
-
)
|
| 65 |
-
|
| 66 |
-
def get_style_vector(self, style_id: int, weight: float = 1.0) -> np.ndarray:
|
| 67 |
-
mean = self.style_vectors[0]
|
| 68 |
-
style_vec = self.style_vectors[style_id]
|
| 69 |
-
style_vec = mean + (style_vec - mean) * weight
|
| 70 |
-
return style_vec
|
| 71 |
-
|
| 72 |
-
def get_style_vector_from_audio(
|
| 73 |
-
self, audio_path: str, weight: float = 1.0
|
| 74 |
-
) -> np.ndarray:
|
| 75 |
-
from style_gen import get_style_vector
|
| 76 |
-
|
| 77 |
-
xvec = get_style_vector(audio_path)
|
| 78 |
-
mean = self.style_vectors[0]
|
| 79 |
-
xvec = mean + (xvec - mean) * weight
|
| 80 |
-
return xvec
|
| 81 |
-
|
| 82 |
-
def infer(
|
| 83 |
-
self,
|
| 84 |
-
text: str,
|
| 85 |
-
language: str = "JP",
|
| 86 |
-
sid: int = 0,
|
| 87 |
-
reference_audio_path: Optional[str] = None,
|
| 88 |
-
sdp_ratio: float = DEFAULT_SDP_RATIO,
|
| 89 |
-
noise: float = DEFAULT_NOISE,
|
| 90 |
-
noisew: float = DEFAULT_NOISEW,
|
| 91 |
-
length: float = DEFAULT_LENGTH,
|
| 92 |
-
line_split: bool = DEFAULT_LINE_SPLIT,
|
| 93 |
-
split_interval: float = DEFAULT_SPLIT_INTERVAL,
|
| 94 |
-
assist_text: Optional[str] = None,
|
| 95 |
-
assist_text_weight: float = DEFAULT_ASSIST_TEXT_WEIGHT,
|
| 96 |
-
use_assist_text: bool = False,
|
| 97 |
-
style: str = DEFAULT_STYLE,
|
| 98 |
-
style_weight: float = DEFAULT_STYLE_WEIGHT,
|
| 99 |
-
given_tone: Optional[list[int]] = None,
|
| 100 |
-
) -> tuple[int, np.ndarray]:
|
| 101 |
-
#logger.info(f"Start generating audio data from text:\n{text}")
|
| 102 |
-
if language != "JP" and self.hps.version.endswith("JP-Extra"):
|
| 103 |
-
raise ValueError(
|
| 104 |
-
"The model is trained with JP-Extra, but the language is not JP"
|
| 105 |
-
)
|
| 106 |
-
if reference_audio_path == "":
|
| 107 |
-
reference_audio_path = None
|
| 108 |
-
if assist_text == "" or not use_assist_text:
|
| 109 |
-
assist_text = None
|
| 110 |
-
|
| 111 |
-
if self.net_g is None:
|
| 112 |
-
self.load_net_g()
|
| 113 |
-
if reference_audio_path is None:
|
| 114 |
-
style_id = self.style2id[style]
|
| 115 |
-
style_vector = self.get_style_vector(style_id, style_weight)
|
| 116 |
-
else:
|
| 117 |
-
style_vector = self.get_style_vector_from_audio(
|
| 118 |
-
reference_audio_path, style_weight
|
| 119 |
-
)
|
| 120 |
-
if not line_split:
|
| 121 |
-
with torch.no_grad():
|
| 122 |
-
audio = infer(
|
| 123 |
-
text=text,
|
| 124 |
-
sdp_ratio=sdp_ratio,
|
| 125 |
-
noise_scale=noise,
|
| 126 |
-
noise_scale_w=noisew,
|
| 127 |
-
length_scale=length,
|
| 128 |
-
sid=sid,
|
| 129 |
-
language=language,
|
| 130 |
-
hps=self.hps,
|
| 131 |
-
net_g=self.net_g,
|
| 132 |
-
device=self.device,
|
| 133 |
-
assist_text=assist_text,
|
| 134 |
-
assist_text_weight=assist_text_weight,
|
| 135 |
-
style_vec=style_vector,
|
| 136 |
-
given_tone=given_tone,
|
| 137 |
-
)
|
| 138 |
-
else:
|
| 139 |
-
texts = text.split("\n")
|
| 140 |
-
texts = [t for t in texts if t != ""]
|
| 141 |
-
audios = []
|
| 142 |
-
with torch.no_grad():
|
| 143 |
-
for i, t in enumerate(texts):
|
| 144 |
-
audios.append(
|
| 145 |
-
infer(
|
| 146 |
-
text=t,
|
| 147 |
-
sdp_ratio=sdp_ratio,
|
| 148 |
-
noise_scale=noise,
|
| 149 |
-
noise_scale_w=noisew,
|
| 150 |
-
length_scale=length,
|
| 151 |
-
sid=sid,
|
| 152 |
-
language=language,
|
| 153 |
-
hps=self.hps,
|
| 154 |
-
net_g=self.net_g,
|
| 155 |
-
device=self.device,
|
| 156 |
-
assist_text=assist_text,
|
| 157 |
-
assist_text_weight=assist_text_weight,
|
| 158 |
-
style_vec=style_vector,
|
| 159 |
-
)
|
| 160 |
-
)
|
| 161 |
-
if i != len(texts) - 1:
|
| 162 |
-
audios.append(np.zeros(int(44100 * split_interval)))
|
| 163 |
-
audio = np.concatenate(audios)
|
| 164 |
-
with warnings.catch_warnings():
|
| 165 |
-
warnings.simplefilter("ignore")
|
| 166 |
-
audio = convert_to_16_bit_wav(audio)
|
| 167 |
-
#logger.info("Audio data generated successfully")
|
| 168 |
-
return (self.hps.data.sampling_rate, audio)
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
class ModelHolder:
|
| 172 |
-
def __init__(self, root_dir: str, device: str):
|
| 173 |
-
self.root_dir: str = root_dir
|
| 174 |
-
self.device: str = device
|
| 175 |
-
self.model_files_dict: Dict[str, List[str]] = {}
|
| 176 |
-
self.current_model: Optional[Model] = None
|
| 177 |
-
self.model_names: List[str] = []
|
| 178 |
-
self.models: List[Model] = []
|
| 179 |
-
self.refresh()
|
| 180 |
-
|
| 181 |
-
def refresh(self):
|
| 182 |
-
self.model_files_dict = {}
|
| 183 |
-
self.model_names = []
|
| 184 |
-
self.current_model = None
|
| 185 |
-
model_dirs = [
|
| 186 |
-
d
|
| 187 |
-
for d in os.listdir(self.root_dir)
|
| 188 |
-
if os.path.isdir(os.path.join(self.root_dir, d))
|
| 189 |
-
]
|
| 190 |
-
for model_name in model_dirs:
|
| 191 |
-
model_dir = os.path.join(self.root_dir, model_name)
|
| 192 |
-
model_files = [
|
| 193 |
-
os.path.join(model_dir, f)
|
| 194 |
-
for f in os.listdir(model_dir)
|
| 195 |
-
if f.endswith(".pth") or f.endswith(".pt") or f.endswith(".safetensors")
|
| 196 |
-
]
|
| 197 |
-
if len(model_files) == 0:
|
| 198 |
-
logger.warning(
|
| 199 |
-
f"No model files found in {self.root_dir}/{model_name}, so skip it"
|
| 200 |
-
)
|
| 201 |
-
continue
|
| 202 |
-
self.model_files_dict[model_name] = model_files
|
| 203 |
-
self.model_names.append(model_name)
|
| 204 |
-
|
| 205 |
-
def load_model_gr(
|
| 206 |
-
self, model_name: str, model_path: str
|
| 207 |
-
) -> tuple[gr.Dropdown, gr.Button, gr.Dropdown]:
|
| 208 |
-
if model_name not in self.model_files_dict:
|
| 209 |
-
raise ValueError(f"Model `{model_name}` is not found")
|
| 210 |
-
#if model_path not in self.model_files_dict[model_name]:
|
| 211 |
-
# raise ValueError(f"Model file `{model_path}` is not found")
|
| 212 |
-
if (
|
| 213 |
-
self.current_model is not None
|
| 214 |
-
and self.current_model.model_path == model_path
|
| 215 |
-
):
|
| 216 |
-
# Already loaded
|
| 217 |
-
speakers = list(self.current_model.spk2id.keys())
|
| 218 |
-
styles = list(self.current_model.style2id.keys())
|
| 219 |
-
return (
|
| 220 |
-
gr.Dropdown(choices=styles, value=styles[0]),
|
| 221 |
-
gr.Button(interactive=True, value="音声合成"),
|
| 222 |
-
gr.Dropdown(choices=speakers, value=speakers[0]),
|
| 223 |
-
)
|
| 224 |
-
self.current_model = Model(
|
| 225 |
-
model_path=model_path,
|
| 226 |
-
config_path=os.path.join(self.root_dir, model_name, "config.json"),
|
| 227 |
-
style_vec_path=os.path.join(self.root_dir, model_name, "style_vectors.npy"),
|
| 228 |
-
device=self.device,
|
| 229 |
-
)
|
| 230 |
-
speakers = list(self.current_model.spk2id.keys())
|
| 231 |
-
styles = list(self.current_model.style2id.keys())
|
| 232 |
-
return (
|
| 233 |
-
gr.Dropdown(choices=styles, value=styles[0]),
|
| 234 |
-
gr.Button(interactive=True, value="音声合成"),
|
| 235 |
-
gr.Dropdown(choices=speakers, value=speakers[0]),
|
| 236 |
-
)
|
| 237 |
-
|
| 238 |
-
def update_model_files_gr(self, model_name: str) -> gr.Dropdown:
|
| 239 |
-
model_files = self.model_files_dict[model_name]
|
| 240 |
-
return gr.Dropdown(choices=model_files, value=model_files[0])
|
| 241 |
-
|
| 242 |
-
def update_model_names_gr(self) -> tuple[gr.Dropdown, gr.Dropdown, gr.Button]:
|
| 243 |
-
self.refresh()
|
| 244 |
-
initial_model_name = self.model_names[0]
|
| 245 |
-
initial_model_files = self.model_files_dict[initial_model_name]
|
| 246 |
-
return (
|
| 247 |
-
gr.Dropdown(choices=self.model_names, value=initial_model_name),
|
| 248 |
-
gr.Dropdown(choices=initial_model_files, value=initial_model_files[0]),
|
| 249 |
-
gr.Button(interactive=False), # For tts_button
|
| 250 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/commons.py
DELETED
|
@@ -1,152 +0,0 @@
|
|
| 1 |
-
import math
|
| 2 |
-
import torch
|
| 3 |
-
from torch.nn import functional as F
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
def init_weights(m, mean=0.0, std=0.01):
|
| 7 |
-
classname = m.__class__.__name__
|
| 8 |
-
if classname.find("Conv") != -1:
|
| 9 |
-
m.weight.data.normal_(mean, std)
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
def get_padding(kernel_size, dilation=1):
|
| 13 |
-
return int((kernel_size * dilation - dilation) / 2)
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
def convert_pad_shape(pad_shape):
|
| 17 |
-
layer = pad_shape[::-1]
|
| 18 |
-
pad_shape = [item for sublist in layer for item in sublist]
|
| 19 |
-
return pad_shape
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
def intersperse(lst, item):
|
| 23 |
-
result = [item] * (len(lst) * 2 + 1)
|
| 24 |
-
result[1::2] = lst
|
| 25 |
-
return result
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
def kl_divergence(m_p, logs_p, m_q, logs_q):
|
| 29 |
-
"""KL(P||Q)"""
|
| 30 |
-
kl = (logs_q - logs_p) - 0.5
|
| 31 |
-
kl += (
|
| 32 |
-
0.5 * (torch.exp(2.0 * logs_p) + ((m_p - m_q) ** 2)) * torch.exp(-2.0 * logs_q)
|
| 33 |
-
)
|
| 34 |
-
return kl
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
def rand_gumbel(shape):
|
| 38 |
-
"""Sample from the Gumbel distribution, protect from overflows."""
|
| 39 |
-
uniform_samples = torch.rand(shape) * 0.99998 + 0.00001
|
| 40 |
-
return -torch.log(-torch.log(uniform_samples))
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
def rand_gumbel_like(x):
|
| 44 |
-
g = rand_gumbel(x.size()).to(dtype=x.dtype, device=x.device)
|
| 45 |
-
return g
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
def slice_segments(x, ids_str, segment_size=4):
|
| 49 |
-
gather_indices = ids_str.view(x.size(0), 1, 1).repeat(
|
| 50 |
-
1, x.size(1), 1
|
| 51 |
-
) + torch.arange(segment_size, device=x.device)
|
| 52 |
-
return torch.gather(x, 2, gather_indices)
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
def rand_slice_segments(x, x_lengths=None, segment_size=4):
|
| 56 |
-
b, d, t = x.size()
|
| 57 |
-
if x_lengths is None:
|
| 58 |
-
x_lengths = t
|
| 59 |
-
ids_str_max = torch.clamp(x_lengths - segment_size + 1, min=0)
|
| 60 |
-
ids_str = (torch.rand([b], device=x.device) * ids_str_max).to(dtype=torch.long)
|
| 61 |
-
ret = slice_segments(x, ids_str, segment_size)
|
| 62 |
-
return ret, ids_str
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
def get_timing_signal_1d(length, channels, min_timescale=1.0, max_timescale=1.0e4):
|
| 66 |
-
position = torch.arange(length, dtype=torch.float)
|
| 67 |
-
num_timescales = channels // 2
|
| 68 |
-
log_timescale_increment = math.log(float(max_timescale) / float(min_timescale)) / (
|
| 69 |
-
num_timescales - 1
|
| 70 |
-
)
|
| 71 |
-
inv_timescales = min_timescale * torch.exp(
|
| 72 |
-
torch.arange(num_timescales, dtype=torch.float) * -log_timescale_increment
|
| 73 |
-
)
|
| 74 |
-
scaled_time = position.unsqueeze(0) * inv_timescales.unsqueeze(1)
|
| 75 |
-
signal = torch.cat([torch.sin(scaled_time), torch.cos(scaled_time)], 0)
|
| 76 |
-
signal = F.pad(signal, [0, 0, 0, channels % 2])
|
| 77 |
-
signal = signal.view(1, channels, length)
|
| 78 |
-
return signal
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
def add_timing_signal_1d(x, min_timescale=1.0, max_timescale=1.0e4):
|
| 82 |
-
b, channels, length = x.size()
|
| 83 |
-
signal = get_timing_signal_1d(length, channels, min_timescale, max_timescale)
|
| 84 |
-
return x + signal.to(dtype=x.dtype, device=x.device)
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
def cat_timing_signal_1d(x, min_timescale=1.0, max_timescale=1.0e4, axis=1):
|
| 88 |
-
b, channels, length = x.size()
|
| 89 |
-
signal = get_timing_signal_1d(length, channels, min_timescale, max_timescale)
|
| 90 |
-
return torch.cat([x, signal.to(dtype=x.dtype, device=x.device)], axis)
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
def subsequent_mask(length):
|
| 94 |
-
mask = torch.tril(torch.ones(length, length)).unsqueeze(0).unsqueeze(0)
|
| 95 |
-
return mask
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
@torch.jit.script
|
| 99 |
-
def fused_add_tanh_sigmoid_multiply(input_a, input_b, n_channels):
|
| 100 |
-
n_channels_int = n_channels[0]
|
| 101 |
-
in_act = input_a + input_b
|
| 102 |
-
t_act = torch.tanh(in_act[:, :n_channels_int, :])
|
| 103 |
-
s_act = torch.sigmoid(in_act[:, n_channels_int:, :])
|
| 104 |
-
acts = t_act * s_act
|
| 105 |
-
return acts
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
def shift_1d(x):
|
| 109 |
-
x = F.pad(x, convert_pad_shape([[0, 0], [0, 0], [1, 0]]))[:, :, :-1]
|
| 110 |
-
return x
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
def sequence_mask(length, max_length=None):
|
| 114 |
-
if max_length is None:
|
| 115 |
-
max_length = length.max()
|
| 116 |
-
x = torch.arange(max_length, dtype=length.dtype, device=length.device)
|
| 117 |
-
return x.unsqueeze(0) < length.unsqueeze(1)
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
def generate_path(duration, mask):
|
| 121 |
-
"""
|
| 122 |
-
duration: [b, 1, t_x]
|
| 123 |
-
mask: [b, 1, t_y, t_x]
|
| 124 |
-
"""
|
| 125 |
-
|
| 126 |
-
b, _, t_y, t_x = mask.shape
|
| 127 |
-
cum_duration = torch.cumsum(duration, -1)
|
| 128 |
-
|
| 129 |
-
cum_duration_flat = cum_duration.view(b * t_x)
|
| 130 |
-
path = sequence_mask(cum_duration_flat, t_y).to(mask.dtype)
|
| 131 |
-
path = path.view(b, t_x, t_y)
|
| 132 |
-
path = path - F.pad(path, convert_pad_shape([[0, 0], [1, 0], [0, 0]]))[:, :-1]
|
| 133 |
-
path = path.unsqueeze(1).transpose(2, 3) * mask
|
| 134 |
-
return path
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
def clip_grad_value_(parameters, clip_value, norm_type=2):
|
| 138 |
-
if isinstance(parameters, torch.Tensor):
|
| 139 |
-
parameters = [parameters]
|
| 140 |
-
parameters = list(filter(lambda p: p.grad is not None, parameters))
|
| 141 |
-
norm_type = float(norm_type)
|
| 142 |
-
if clip_value is not None:
|
| 143 |
-
clip_value = float(clip_value)
|
| 144 |
-
|
| 145 |
-
total_norm = 0
|
| 146 |
-
for p in parameters:
|
| 147 |
-
param_norm = p.grad.data.norm(norm_type)
|
| 148 |
-
total_norm += param_norm.item() ** norm_type
|
| 149 |
-
if clip_value is not None:
|
| 150 |
-
p.grad.data.clamp_(min=-clip_value, max=clip_value)
|
| 151 |
-
total_norm = total_norm ** (1.0 / norm_type)
|
| 152 |
-
return total_norm
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/config.py
DELETED
|
@@ -1,269 +0,0 @@
|
|
| 1 |
-
"""
|
| 2 |
-
@Desc: 全局配置文件读取
|
| 3 |
-
"""
|
| 4 |
-
import argparse
|
| 5 |
-
import os
|
| 6 |
-
import shutil
|
| 7 |
-
from typing import Dict, List
|
| 8 |
-
|
| 9 |
-
import yaml
|
| 10 |
-
|
| 11 |
-
from common.log import logger
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
class Resample_config:
|
| 15 |
-
"""重采样配置"""
|
| 16 |
-
|
| 17 |
-
def __init__(self, in_dir: str, out_dir: str, sampling_rate: int = 44100):
|
| 18 |
-
self.sampling_rate: int = sampling_rate # 目标采样率
|
| 19 |
-
self.in_dir: str = in_dir # 待处理音频目录路径
|
| 20 |
-
self.out_dir: str = out_dir # 重采样输出路径
|
| 21 |
-
|
| 22 |
-
@classmethod
|
| 23 |
-
def from_dict(cls, dataset_path: str, data: Dict[str, any]):
|
| 24 |
-
"""从字典中生成实例"""
|
| 25 |
-
|
| 26 |
-
# 不检查路径是否有效,此逻辑在resample.py中处理
|
| 27 |
-
data["in_dir"] = os.path.join(dataset_path, data["in_dir"])
|
| 28 |
-
data["out_dir"] = os.path.join(dataset_path, data["out_dir"])
|
| 29 |
-
|
| 30 |
-
return cls(**data)
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
class Preprocess_text_config:
|
| 34 |
-
"""数据预处理配置"""
|
| 35 |
-
|
| 36 |
-
def __init__(
|
| 37 |
-
self,
|
| 38 |
-
transcription_path: str,
|
| 39 |
-
cleaned_path: str,
|
| 40 |
-
train_path: str,
|
| 41 |
-
val_path: str,
|
| 42 |
-
config_path: str,
|
| 43 |
-
val_per_lang: int = 5,
|
| 44 |
-
max_val_total: int = 10000,
|
| 45 |
-
clean: bool = True,
|
| 46 |
-
):
|
| 47 |
-
self.transcription_path: str = transcription_path # 原始文本文件路径,文本格式应为{wav_path}|{speaker_name}|{language}|{text}。
|
| 48 |
-
self.cleaned_path: str = cleaned_path # 数据清洗后文本路径,可以不填。不填则将在原始文本目录生成
|
| 49 |
-
self.train_path: str = train_path # 训练集路径,可以不填。不填则将在原始文本目录生成
|
| 50 |
-
self.val_path: str = val_path # 验证集路径,可以不填。不填则将在原始文本目录生成
|
| 51 |
-
self.config_path: str = config_path # 配置文件路径
|
| 52 |
-
self.val_per_lang: int = val_per_lang # 每个speaker的验证集条数
|
| 53 |
-
self.max_val_total: int = max_val_total # 验证集最大条数,多于的会被截断并放到训练集中
|
| 54 |
-
self.clean: bool = clean # 是否进行数据清洗
|
| 55 |
-
|
| 56 |
-
@classmethod
|
| 57 |
-
def from_dict(cls, dataset_path: str, data: Dict[str, any]):
|
| 58 |
-
"""从字典中生成实例"""
|
| 59 |
-
|
| 60 |
-
data["transcription_path"] = os.path.join(
|
| 61 |
-
dataset_path, data["transcription_path"]
|
| 62 |
-
)
|
| 63 |
-
if data["cleaned_path"] == "" or data["cleaned_path"] is None:
|
| 64 |
-
data["cleaned_path"] = None
|
| 65 |
-
else:
|
| 66 |
-
data["cleaned_path"] = os.path.join(dataset_path, data["cleaned_path"])
|
| 67 |
-
data["train_path"] = os.path.join(dataset_path, data["train_path"])
|
| 68 |
-
data["val_path"] = os.path.join(dataset_path, data["val_path"])
|
| 69 |
-
data["config_path"] = os.path.join(dataset_path, data["config_path"])
|
| 70 |
-
|
| 71 |
-
return cls(**data)
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
class Bert_gen_config:
|
| 75 |
-
"""bert_gen 配置"""
|
| 76 |
-
|
| 77 |
-
def __init__(
|
| 78 |
-
self,
|
| 79 |
-
config_path: str,
|
| 80 |
-
num_processes: int = 2,
|
| 81 |
-
device: str = "cuda",
|
| 82 |
-
use_multi_device: bool = False,
|
| 83 |
-
):
|
| 84 |
-
self.config_path = config_path
|
| 85 |
-
self.num_processes = num_processes
|
| 86 |
-
self.device = device
|
| 87 |
-
self.use_multi_device = use_multi_device
|
| 88 |
-
|
| 89 |
-
@classmethod
|
| 90 |
-
def from_dict(cls, dataset_path: str, data: Dict[str, any]):
|
| 91 |
-
data["config_path"] = os.path.join(dataset_path, data["config_path"])
|
| 92 |
-
|
| 93 |
-
return cls(**data)
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
class Style_gen_config:
|
| 97 |
-
"""style_gen 配置"""
|
| 98 |
-
|
| 99 |
-
def __init__(
|
| 100 |
-
self,
|
| 101 |
-
config_path: str,
|
| 102 |
-
num_processes: int = 4,
|
| 103 |
-
device: str = "cuda",
|
| 104 |
-
):
|
| 105 |
-
self.config_path = config_path
|
| 106 |
-
self.num_processes = num_processes
|
| 107 |
-
self.device = device
|
| 108 |
-
|
| 109 |
-
@classmethod
|
| 110 |
-
def from_dict(cls, dataset_path: str, data: Dict[str, any]):
|
| 111 |
-
data["config_path"] = os.path.join(dataset_path, data["config_path"])
|
| 112 |
-
|
| 113 |
-
return cls(**data)
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
class Train_ms_config:
|
| 117 |
-
"""训练配置"""
|
| 118 |
-
|
| 119 |
-
def __init__(
|
| 120 |
-
self,
|
| 121 |
-
config_path: str,
|
| 122 |
-
env: Dict[str, any],
|
| 123 |
-
# base: Dict[str, any],
|
| 124 |
-
model_dir: str,
|
| 125 |
-
num_workers: int,
|
| 126 |
-
spec_cache: bool,
|
| 127 |
-
keep_ckpts: int,
|
| 128 |
-
):
|
| 129 |
-
self.env = env # 需要加载的环境变量
|
| 130 |
-
# self.base = base # 底模配置
|
| 131 |
-
self.model_dir = model_dir # 训练模型存储目录,该路径为相对于dataset_path的路径,而非项目根目录
|
| 132 |
-
self.config_path = config_path # 配置文件路径
|
| 133 |
-
self.num_workers = num_workers # worker数量
|
| 134 |
-
self.spec_cache = spec_cache # 是否启用spec缓存
|
| 135 |
-
self.keep_ckpts = keep_ckpts # ckpt数量
|
| 136 |
-
|
| 137 |
-
@classmethod
|
| 138 |
-
def from_dict(cls, dataset_path: str, data: Dict[str, any]):
|
| 139 |
-
# data["model"] = os.path.join(dataset_path, data["model"])
|
| 140 |
-
data["config_path"] = os.path.join(dataset_path, data["config_path"])
|
| 141 |
-
|
| 142 |
-
return cls(**data)
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
class Webui_config:
|
| 146 |
-
"""webui 配置"""
|
| 147 |
-
|
| 148 |
-
def __init__(
|
| 149 |
-
self,
|
| 150 |
-
device: str,
|
| 151 |
-
model: str,
|
| 152 |
-
config_path: str,
|
| 153 |
-
language_identification_library: str,
|
| 154 |
-
port: int = 7860,
|
| 155 |
-
share: bool = False,
|
| 156 |
-
debug: bool = False,
|
| 157 |
-
):
|
| 158 |
-
self.device: str = device
|
| 159 |
-
self.model: str = model # 端口号
|
| 160 |
-
self.config_path: str = config_path # 是否公开部署,对外网开放
|
| 161 |
-
self.port: int = port # 是否开启debug模式
|
| 162 |
-
self.share: bool = share # 模型路径
|
| 163 |
-
self.debug: bool = debug # 配置文件路径
|
| 164 |
-
self.language_identification_library: str = (
|
| 165 |
-
language_identification_library # 语种识别库
|
| 166 |
-
)
|
| 167 |
-
|
| 168 |
-
@classmethod
|
| 169 |
-
def from_dict(cls, dataset_path: str, data: Dict[str, any]):
|
| 170 |
-
data["config_path"] = os.path.join(dataset_path, data["config_path"])
|
| 171 |
-
data["model"] = os.path.join(dataset_path, data["model"])
|
| 172 |
-
return cls(**data)
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
class Server_config:
|
| 176 |
-
def __init__(
|
| 177 |
-
self,
|
| 178 |
-
port: int = 5000,
|
| 179 |
-
device: str = "cuda",
|
| 180 |
-
limit: int = 100,
|
| 181 |
-
language: str = "JP",
|
| 182 |
-
origins: List[str] = None,
|
| 183 |
-
):
|
| 184 |
-
self.port: int = port
|
| 185 |
-
self.device: str = device
|
| 186 |
-
self.language: str = language
|
| 187 |
-
self.limit: int = limit
|
| 188 |
-
self.origins: List[str] = origins
|
| 189 |
-
|
| 190 |
-
@classmethod
|
| 191 |
-
def from_dict(cls, data: Dict[str, any]):
|
| 192 |
-
return cls(**data)
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
class Translate_config:
|
| 196 |
-
"""翻译api配置"""
|
| 197 |
-
|
| 198 |
-
def __init__(self, app_key: str, secret_key: str):
|
| 199 |
-
self.app_key = app_key
|
| 200 |
-
self.secret_key = secret_key
|
| 201 |
-
|
| 202 |
-
@classmethod
|
| 203 |
-
def from_dict(cls, data: Dict[str, any]):
|
| 204 |
-
return cls(**data)
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
class Config:
|
| 208 |
-
def __init__(self, config_path: str, path_config: dict[str, str]):
|
| 209 |
-
if not os.path.isfile(config_path) and os.path.isfile("default_config.yml"):
|
| 210 |
-
shutil.copy(src="default_config.yml", dst=config_path)
|
| 211 |
-
logger.info(
|
| 212 |
-
f"A configuration file {config_path} has been generated based on the default configuration file default_config.yml."
|
| 213 |
-
)
|
| 214 |
-
logger.info(
|
| 215 |
-
"If you have no special needs, please do not modify default_config.yml."
|
| 216 |
-
)
|
| 217 |
-
# sys.exit(0)
|
| 218 |
-
with open(file=config_path, mode="r", encoding="utf-8") as file:
|
| 219 |
-
yaml_config: Dict[str, any] = yaml.safe_load(file.read())
|
| 220 |
-
model_name: str = yaml_config["model_name"]
|
| 221 |
-
self.model_name: str = model_name
|
| 222 |
-
if "dataset_path" in yaml_config:
|
| 223 |
-
dataset_path = yaml_config["dataset_path"]
|
| 224 |
-
else:
|
| 225 |
-
dataset_path = os.path.join(path_config["dataset_root"], model_name)
|
| 226 |
-
self.dataset_path: str = dataset_path
|
| 227 |
-
self.assets_root: str = path_config["assets_root"]
|
| 228 |
-
self.out_dir = os.path.join(self.assets_root, model_name)
|
| 229 |
-
self.resample_config: Resample_config = Resample_config.from_dict(
|
| 230 |
-
dataset_path, yaml_config["resample"]
|
| 231 |
-
)
|
| 232 |
-
self.preprocess_text_config: Preprocess_text_config = (
|
| 233 |
-
Preprocess_text_config.from_dict(
|
| 234 |
-
dataset_path, yaml_config["preprocess_text"]
|
| 235 |
-
)
|
| 236 |
-
)
|
| 237 |
-
self.bert_gen_config: Bert_gen_config = Bert_gen_config.from_dict(
|
| 238 |
-
dataset_path, yaml_config["bert_gen"]
|
| 239 |
-
)
|
| 240 |
-
self.style_gen_config: Style_gen_config = Style_gen_config.from_dict(
|
| 241 |
-
dataset_path, yaml_config["style_gen"]
|
| 242 |
-
)
|
| 243 |
-
self.train_ms_config: Train_ms_config = Train_ms_config.from_dict(
|
| 244 |
-
dataset_path, yaml_config["train_ms"]
|
| 245 |
-
)
|
| 246 |
-
self.webui_config: Webui_config = Webui_config.from_dict(
|
| 247 |
-
dataset_path, yaml_config["webui"]
|
| 248 |
-
)
|
| 249 |
-
self.server_config: Server_config = Server_config.from_dict(
|
| 250 |
-
yaml_config["server"]
|
| 251 |
-
)
|
| 252 |
-
# self.translate_config: Translate_config = Translate_config.from_dict(
|
| 253 |
-
# yaml_config["translate"]
|
| 254 |
-
# )
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
with open(os.path.join("configs", "paths.yml"), "r", encoding="utf-8") as f:
|
| 258 |
-
path_config: dict[str, str] = yaml.safe_load(f.read())
|
| 259 |
-
# Should contain the following keys:
|
| 260 |
-
# - dataset_root: the root directory of the dataset, default to "Data"
|
| 261 |
-
# - assets_root: the root directory of the assets, default to "model_assets"
|
| 262 |
-
|
| 263 |
-
|
| 264 |
-
try:
|
| 265 |
-
config = Config("config.yml", path_config)
|
| 266 |
-
except (TypeError, KeyError):
|
| 267 |
-
logger.warning("Old config.yml found. Replace it with default_config.yml.")
|
| 268 |
-
shutil.copy(src="default_config.yml", dst="config.yml")
|
| 269 |
-
config = Config("config.yml", path_config)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/config.yml
DELETED
|
@@ -1,51 +0,0 @@
|
|
| 1 |
-
bert_gen:
|
| 2 |
-
config_path: config.json
|
| 3 |
-
device: cpu
|
| 4 |
-
num_processes: 2
|
| 5 |
-
use_multi_device: false
|
| 6 |
-
dataset_path: Data\model_name
|
| 7 |
-
model_name: model_name
|
| 8 |
-
preprocess_text:
|
| 9 |
-
clean: true
|
| 10 |
-
cleaned_path: ''
|
| 11 |
-
config_path: config.json
|
| 12 |
-
max_val_total: 12
|
| 13 |
-
train_path: train.list
|
| 14 |
-
transcription_path: esd.list
|
| 15 |
-
val_path: val.list
|
| 16 |
-
val_per_lang: 4
|
| 17 |
-
resample:
|
| 18 |
-
in_dir: raw
|
| 19 |
-
out_dir: wavs
|
| 20 |
-
sampling_rate: 44100
|
| 21 |
-
server:
|
| 22 |
-
device: cuda
|
| 23 |
-
language: JP
|
| 24 |
-
limit: 100
|
| 25 |
-
origins:
|
| 26 |
-
- '*'
|
| 27 |
-
port: 5000
|
| 28 |
-
style_gen:
|
| 29 |
-
config_path: config.json
|
| 30 |
-
device: cpu
|
| 31 |
-
num_processes: 4
|
| 32 |
-
train_ms:
|
| 33 |
-
config_path: config.json
|
| 34 |
-
env:
|
| 35 |
-
LOCAL_RANK: 0
|
| 36 |
-
MASTER_ADDR: localhost
|
| 37 |
-
MASTER_PORT: 10086
|
| 38 |
-
RANK: 0
|
| 39 |
-
WORLD_SIZE: 1
|
| 40 |
-
keep_ckpts: 1
|
| 41 |
-
model_dir: models
|
| 42 |
-
num_workers: 16
|
| 43 |
-
spec_cache: true
|
| 44 |
-
webui:
|
| 45 |
-
config_path: config.json
|
| 46 |
-
debug: false
|
| 47 |
-
device: cuda
|
| 48 |
-
language_identification_library: langid
|
| 49 |
-
model: models/G_8000.pth
|
| 50 |
-
port: 7860
|
| 51 |
-
share: false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/configs/config.json
DELETED
|
@@ -1,71 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"model_name": "your_model_name",
|
| 3 |
-
"train": {
|
| 4 |
-
"log_interval": 200,
|
| 5 |
-
"eval_interval": 1000,
|
| 6 |
-
"seed": 42,
|
| 7 |
-
"epochs": 1000,
|
| 8 |
-
"learning_rate": 0.0002,
|
| 9 |
-
"betas": [0.8, 0.99],
|
| 10 |
-
"eps": 1e-9,
|
| 11 |
-
"batch_size": 4,
|
| 12 |
-
"bf16_run": true,
|
| 13 |
-
"lr_decay": 0.99995,
|
| 14 |
-
"segment_size": 16384,
|
| 15 |
-
"init_lr_ratio": 1,
|
| 16 |
-
"warmup_epochs": 0,
|
| 17 |
-
"c_mel": 45,
|
| 18 |
-
"c_kl": 1.0,
|
| 19 |
-
"skip_optimizer": false,
|
| 20 |
-
"freeze_ZH_bert": false,
|
| 21 |
-
"freeze_JP_bert": false,
|
| 22 |
-
"freeze_EN_bert": false,
|
| 23 |
-
"freeze_style": false
|
| 24 |
-
},
|
| 25 |
-
"data": {
|
| 26 |
-
"training_files": "Data/your_model_name/filelists/train.list",
|
| 27 |
-
"validation_files": "Data/your_model_name/filelists/val.list",
|
| 28 |
-
"max_wav_value": 32768.0,
|
| 29 |
-
"sampling_rate": 44100,
|
| 30 |
-
"filter_length": 2048,
|
| 31 |
-
"hop_length": 512,
|
| 32 |
-
"win_length": 2048,
|
| 33 |
-
"n_mel_channels": 128,
|
| 34 |
-
"mel_fmin": 0.0,
|
| 35 |
-
"mel_fmax": null,
|
| 36 |
-
"add_blank": true,
|
| 37 |
-
"n_speakers": 1,
|
| 38 |
-
"cleaned_text": true,
|
| 39 |
-
"num_styles": 1,
|
| 40 |
-
"style2id": {
|
| 41 |
-
"Neutral": 0
|
| 42 |
-
}
|
| 43 |
-
},
|
| 44 |
-
"model": {
|
| 45 |
-
"use_spk_conditioned_encoder": true,
|
| 46 |
-
"use_noise_scaled_mas": true,
|
| 47 |
-
"use_mel_posterior_encoder": false,
|
| 48 |
-
"use_duration_discriminator": true,
|
| 49 |
-
"inter_channels": 192,
|
| 50 |
-
"hidden_channels": 192,
|
| 51 |
-
"filter_channels": 768,
|
| 52 |
-
"n_heads": 2,
|
| 53 |
-
"n_layers": 6,
|
| 54 |
-
"kernel_size": 3,
|
| 55 |
-
"p_dropout": 0.1,
|
| 56 |
-
"resblock": "1",
|
| 57 |
-
"resblock_kernel_sizes": [3, 7, 11],
|
| 58 |
-
"resblock_dilation_sizes": [
|
| 59 |
-
[1, 3, 5],
|
| 60 |
-
[1, 3, 5],
|
| 61 |
-
[1, 3, 5]
|
| 62 |
-
],
|
| 63 |
-
"upsample_rates": [8, 8, 2, 2, 2],
|
| 64 |
-
"upsample_initial_channel": 512,
|
| 65 |
-
"upsample_kernel_sizes": [16, 16, 8, 2, 2],
|
| 66 |
-
"n_layers_q": 3,
|
| 67 |
-
"use_spectral_norm": false,
|
| 68 |
-
"gin_channels": 256
|
| 69 |
-
},
|
| 70 |
-
"version": "2.0.1"
|
| 71 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/configs/configs_jp_extra.json
DELETED
|
@@ -1,78 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"train": {
|
| 3 |
-
"log_interval": 200,
|
| 4 |
-
"eval_interval": 1000,
|
| 5 |
-
"seed": 42,
|
| 6 |
-
"epochs": 1000,
|
| 7 |
-
"learning_rate": 0.0001,
|
| 8 |
-
"betas": [0.8, 0.99],
|
| 9 |
-
"eps": 1e-9,
|
| 10 |
-
"batch_size": 24,
|
| 11 |
-
"bf16_run": false,
|
| 12 |
-
"fp16_run": false,
|
| 13 |
-
"lr_decay": 0.99996,
|
| 14 |
-
"segment_size": 16384,
|
| 15 |
-
"init_lr_ratio": 1,
|
| 16 |
-
"warmup_epochs": 0,
|
| 17 |
-
"c_mel": 45,
|
| 18 |
-
"c_kl": 1.0,
|
| 19 |
-
"c_commit": 100,
|
| 20 |
-
"skip_optimizer": true,
|
| 21 |
-
"freeze_ZH_bert": false,
|
| 22 |
-
"freeze_JP_bert": false,
|
| 23 |
-
"freeze_EN_bert": false,
|
| 24 |
-
"freeze_emo": false,
|
| 25 |
-
"freeze_style": false
|
| 26 |
-
},
|
| 27 |
-
"data": {
|
| 28 |
-
"use_jp_extra": true,
|
| 29 |
-
"training_files": "filelists/train.list",
|
| 30 |
-
"validation_files": "filelists/val.list",
|
| 31 |
-
"max_wav_value": 32768.0,
|
| 32 |
-
"sampling_rate": 44100,
|
| 33 |
-
"filter_length": 2048,
|
| 34 |
-
"hop_length": 512,
|
| 35 |
-
"win_length": 2048,
|
| 36 |
-
"n_mel_channels": 128,
|
| 37 |
-
"mel_fmin": 0.0,
|
| 38 |
-
"mel_fmax": null,
|
| 39 |
-
"add_blank": true,
|
| 40 |
-
"n_speakers": 512,
|
| 41 |
-
"cleaned_text": true
|
| 42 |
-
},
|
| 43 |
-
"model": {
|
| 44 |
-
"use_spk_conditioned_encoder": true,
|
| 45 |
-
"use_noise_scaled_mas": true,
|
| 46 |
-
"use_mel_posterior_encoder": false,
|
| 47 |
-
"use_duration_discriminator": false,
|
| 48 |
-
"use_wavlm_discriminator": true,
|
| 49 |
-
"inter_channels": 192,
|
| 50 |
-
"hidden_channels": 192,
|
| 51 |
-
"filter_channels": 768,
|
| 52 |
-
"n_heads": 2,
|
| 53 |
-
"n_layers": 6,
|
| 54 |
-
"kernel_size": 3,
|
| 55 |
-
"p_dropout": 0.1,
|
| 56 |
-
"resblock": "1",
|
| 57 |
-
"resblock_kernel_sizes": [3, 7, 11],
|
| 58 |
-
"resblock_dilation_sizes": [
|
| 59 |
-
[1, 3, 5],
|
| 60 |
-
[1, 3, 5],
|
| 61 |
-
[1, 3, 5]
|
| 62 |
-
],
|
| 63 |
-
"upsample_rates": [8, 8, 2, 2, 2],
|
| 64 |
-
"upsample_initial_channel": 512,
|
| 65 |
-
"upsample_kernel_sizes": [16, 16, 8, 2, 2],
|
| 66 |
-
"n_layers_q": 3,
|
| 67 |
-
"use_spectral_norm": false,
|
| 68 |
-
"gin_channels": 512,
|
| 69 |
-
"slm": {
|
| 70 |
-
"model": "./slm/wavlm-base-plus",
|
| 71 |
-
"sr": 16000,
|
| 72 |
-
"hidden": 768,
|
| 73 |
-
"nlayers": 13,
|
| 74 |
-
"initial_channel": 64
|
| 75 |
-
}
|
| 76 |
-
},
|
| 77 |
-
"version": "2.0.1-JP-Extra"
|
| 78 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/configs/paths.yml
DELETED
|
@@ -1,8 +0,0 @@
|
|
| 1 |
-
# Root directory of the training dataset.
|
| 2 |
-
# The training dataset of {model_name} should be placed in {dataset_root}/{model_name}.
|
| 3 |
-
dataset_root: Data
|
| 4 |
-
|
| 5 |
-
# Root directory of the model assets (for inference).
|
| 6 |
-
# In training, the model assets will be saved to {assets_root}/{model_name},
|
| 7 |
-
# and in inference, we load all the models from {assets_root}.
|
| 8 |
-
assets_root: model_assets
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/data_utils.py
DELETED
|
@@ -1,425 +0,0 @@
|
|
| 1 |
-
import os
|
| 2 |
-
import random
|
| 3 |
-
import torch
|
| 4 |
-
import torch.utils.data
|
| 5 |
-
from tqdm import tqdm
|
| 6 |
-
import numpy as np
|
| 7 |
-
from tools.log import logger
|
| 8 |
-
import commons
|
| 9 |
-
from mel_processing import spectrogram_torch, mel_spectrogram_torch
|
| 10 |
-
from utils import load_wav_to_torch, load_filepaths_and_text
|
| 11 |
-
from text import cleaned_text_to_sequence
|
| 12 |
-
from config import config
|
| 13 |
-
|
| 14 |
-
"""Multi speaker version"""
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
class TextAudioSpeakerLoader(torch.utils.data.Dataset):
|
| 18 |
-
"""
|
| 19 |
-
1) loads audio, speaker_id, text pairs
|
| 20 |
-
2) normalizes text and converts them to sequences of integers
|
| 21 |
-
3) computes spectrograms from audio files.
|
| 22 |
-
"""
|
| 23 |
-
|
| 24 |
-
def __init__(self, audiopaths_sid_text, hparams):
|
| 25 |
-
self.audiopaths_sid_text = load_filepaths_and_text(audiopaths_sid_text)
|
| 26 |
-
self.max_wav_value = hparams.max_wav_value
|
| 27 |
-
self.sampling_rate = hparams.sampling_rate
|
| 28 |
-
self.filter_length = hparams.filter_length
|
| 29 |
-
self.hop_length = hparams.hop_length
|
| 30 |
-
self.win_length = hparams.win_length
|
| 31 |
-
self.sampling_rate = hparams.sampling_rate
|
| 32 |
-
self.spk_map = hparams.spk2id
|
| 33 |
-
self.hparams = hparams
|
| 34 |
-
|
| 35 |
-
self.use_mel_spec_posterior = getattr(
|
| 36 |
-
hparams, "use_mel_posterior_encoder", False
|
| 37 |
-
)
|
| 38 |
-
if self.use_mel_spec_posterior:
|
| 39 |
-
self.n_mel_channels = getattr(hparams, "n_mel_channels", 80)
|
| 40 |
-
|
| 41 |
-
self.cleaned_text = getattr(hparams, "cleaned_text", False)
|
| 42 |
-
|
| 43 |
-
self.add_blank = hparams.add_blank
|
| 44 |
-
self.min_text_len = getattr(hparams, "min_text_len", 1)
|
| 45 |
-
self.max_text_len = getattr(hparams, "max_text_len", 384)
|
| 46 |
-
|
| 47 |
-
random.seed(1234)
|
| 48 |
-
random.shuffle(self.audiopaths_sid_text)
|
| 49 |
-
self._filter()
|
| 50 |
-
|
| 51 |
-
def _filter(self):
|
| 52 |
-
"""
|
| 53 |
-
Filter text & store spec lengths
|
| 54 |
-
"""
|
| 55 |
-
# Store spectrogram lengths for Bucketing
|
| 56 |
-
# wav_length ~= file_size / (wav_channels * Bytes per dim) = file_size / (1 * 2)
|
| 57 |
-
# spec_length = wav_length // hop_length
|
| 58 |
-
|
| 59 |
-
audiopaths_sid_text_new = []
|
| 60 |
-
lengths = []
|
| 61 |
-
skipped = 0
|
| 62 |
-
logger.info("Init dataset...")
|
| 63 |
-
for _id, spk, language, text, phones, tone, word2ph in tqdm(
|
| 64 |
-
self.audiopaths_sid_text
|
| 65 |
-
):
|
| 66 |
-
audiopath = f"{_id}"
|
| 67 |
-
if self.min_text_len <= len(phones) and len(phones) <= self.max_text_len:
|
| 68 |
-
phones = phones.split(" ")
|
| 69 |
-
tone = [int(i) for i in tone.split(" ")]
|
| 70 |
-
word2ph = [int(i) for i in word2ph.split(" ")]
|
| 71 |
-
audiopaths_sid_text_new.append(
|
| 72 |
-
[audiopath, spk, language, text, phones, tone, word2ph]
|
| 73 |
-
)
|
| 74 |
-
lengths.append(os.path.getsize(audiopath) // (2 * self.hop_length))
|
| 75 |
-
else:
|
| 76 |
-
skipped += 1
|
| 77 |
-
logger.info(
|
| 78 |
-
"skipped: "
|
| 79 |
-
+ str(skipped)
|
| 80 |
-
+ ", total: "
|
| 81 |
-
+ str(len(self.audiopaths_sid_text))
|
| 82 |
-
)
|
| 83 |
-
self.audiopaths_sid_text = audiopaths_sid_text_new
|
| 84 |
-
self.lengths = lengths
|
| 85 |
-
|
| 86 |
-
def get_audio_text_speaker_pair(self, audiopath_sid_text):
|
| 87 |
-
# separate filename, speaker_id and text
|
| 88 |
-
audiopath, sid, language, text, phones, tone, word2ph = audiopath_sid_text
|
| 89 |
-
|
| 90 |
-
bert, ja_bert, en_bert, phones, tone, language = self.get_text(
|
| 91 |
-
text, word2ph, phones, tone, language, audiopath
|
| 92 |
-
)
|
| 93 |
-
|
| 94 |
-
spec, wav = self.get_audio(audiopath)
|
| 95 |
-
sid = torch.LongTensor([int(self.spk_map[sid])])
|
| 96 |
-
style_vec = torch.FloatTensor(np.load(f"{audiopath}.npy"))
|
| 97 |
-
return (
|
| 98 |
-
phones,
|
| 99 |
-
spec,
|
| 100 |
-
wav,
|
| 101 |
-
sid,
|
| 102 |
-
tone,
|
| 103 |
-
language,
|
| 104 |
-
bert,
|
| 105 |
-
ja_bert,
|
| 106 |
-
en_bert,
|
| 107 |
-
style_vec,
|
| 108 |
-
)
|
| 109 |
-
|
| 110 |
-
def get_audio(self, filename):
|
| 111 |
-
audio, sampling_rate = load_wav_to_torch(filename)
|
| 112 |
-
if sampling_rate != self.sampling_rate:
|
| 113 |
-
raise ValueError(
|
| 114 |
-
"{} {} SR doesn't match target {} SR".format(
|
| 115 |
-
filename, sampling_rate, self.sampling_rate
|
| 116 |
-
)
|
| 117 |
-
)
|
| 118 |
-
audio_norm = audio / self.max_wav_value
|
| 119 |
-
audio_norm = audio_norm.unsqueeze(0)
|
| 120 |
-
spec_filename = filename.replace(".wav", ".spec.pt")
|
| 121 |
-
if self.use_mel_spec_posterior:
|
| 122 |
-
spec_filename = spec_filename.replace(".spec.pt", ".mel.pt")
|
| 123 |
-
try:
|
| 124 |
-
spec = torch.load(spec_filename)
|
| 125 |
-
except:
|
| 126 |
-
if self.use_mel_spec_posterior:
|
| 127 |
-
spec = mel_spectrogram_torch(
|
| 128 |
-
audio_norm,
|
| 129 |
-
self.filter_length,
|
| 130 |
-
self.n_mel_channels,
|
| 131 |
-
self.sampling_rate,
|
| 132 |
-
self.hop_length,
|
| 133 |
-
self.win_length,
|
| 134 |
-
self.hparams.mel_fmin,
|
| 135 |
-
self.hparams.mel_fmax,
|
| 136 |
-
center=False,
|
| 137 |
-
)
|
| 138 |
-
else:
|
| 139 |
-
spec = spectrogram_torch(
|
| 140 |
-
audio_norm,
|
| 141 |
-
self.filter_length,
|
| 142 |
-
self.sampling_rate,
|
| 143 |
-
self.hop_length,
|
| 144 |
-
self.win_length,
|
| 145 |
-
center=False,
|
| 146 |
-
)
|
| 147 |
-
spec = torch.squeeze(spec, 0)
|
| 148 |
-
if config.train_ms_config.spec_cache:
|
| 149 |
-
torch.save(spec, spec_filename)
|
| 150 |
-
return spec, audio_norm
|
| 151 |
-
|
| 152 |
-
def get_text(self, text, word2ph, phone, tone, language_str, wav_path):
|
| 153 |
-
phone, tone, language = cleaned_text_to_sequence(phone, tone, language_str)
|
| 154 |
-
if self.add_blank:
|
| 155 |
-
phone = commons.intersperse(phone, 0)
|
| 156 |
-
tone = commons.intersperse(tone, 0)
|
| 157 |
-
language = commons.intersperse(language, 0)
|
| 158 |
-
for i in range(len(word2ph)):
|
| 159 |
-
word2ph[i] = word2ph[i] * 2
|
| 160 |
-
word2ph[0] += 1
|
| 161 |
-
bert_path = wav_path.replace(".wav", ".bert.pt")
|
| 162 |
-
try:
|
| 163 |
-
bert_ori = torch.load(bert_path)
|
| 164 |
-
assert bert_ori.shape[-1] == len(phone)
|
| 165 |
-
except Exception as e:
|
| 166 |
-
logger.warning("Bert load Failed")
|
| 167 |
-
logger.warning(e)
|
| 168 |
-
|
| 169 |
-
if language_str == "ZH":
|
| 170 |
-
bert = bert_ori
|
| 171 |
-
ja_bert = torch.zeros(1024, len(phone))
|
| 172 |
-
en_bert = torch.zeros(1024, len(phone))
|
| 173 |
-
elif language_str == "JP":
|
| 174 |
-
bert = torch.zeros(1024, len(phone))
|
| 175 |
-
ja_bert = bert_ori
|
| 176 |
-
en_bert = torch.zeros(1024, len(phone))
|
| 177 |
-
elif language_str == "EN":
|
| 178 |
-
bert = torch.zeros(1024, len(phone))
|
| 179 |
-
ja_bert = torch.zeros(1024, len(phone))
|
| 180 |
-
en_bert = bert_ori
|
| 181 |
-
phone = torch.LongTensor(phone)
|
| 182 |
-
tone = torch.LongTensor(tone)
|
| 183 |
-
language = torch.LongTensor(language)
|
| 184 |
-
return bert, ja_bert, en_bert, phone, tone, language
|
| 185 |
-
|
| 186 |
-
def get_sid(self, sid):
|
| 187 |
-
sid = torch.LongTensor([int(sid)])
|
| 188 |
-
return sid
|
| 189 |
-
|
| 190 |
-
def __getitem__(self, index):
|
| 191 |
-
return self.get_audio_text_speaker_pair(self.audiopaths_sid_text[index])
|
| 192 |
-
|
| 193 |
-
def __len__(self):
|
| 194 |
-
return len(self.audiopaths_sid_text)
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
class TextAudioSpeakerCollate:
|
| 198 |
-
"""Zero-pads model inputs and targets"""
|
| 199 |
-
|
| 200 |
-
def __init__(self, return_ids=False):
|
| 201 |
-
self.return_ids = return_ids
|
| 202 |
-
|
| 203 |
-
def __call__(self, batch):
|
| 204 |
-
"""Collate's training batch from normalized text, audio and speaker identities
|
| 205 |
-
PARAMS
|
| 206 |
-
------
|
| 207 |
-
batch: [text_normalized, spec_normalized, wav_normalized, sid]
|
| 208 |
-
"""
|
| 209 |
-
# Right zero-pad all one-hot text sequences to max input length
|
| 210 |
-
_, ids_sorted_decreasing = torch.sort(
|
| 211 |
-
torch.LongTensor([x[1].size(1) for x in batch]), dim=0, descending=True
|
| 212 |
-
)
|
| 213 |
-
|
| 214 |
-
max_text_len = max([len(x[0]) for x in batch])
|
| 215 |
-
max_spec_len = max([x[1].size(1) for x in batch])
|
| 216 |
-
max_wav_len = max([x[2].size(1) for x in batch])
|
| 217 |
-
|
| 218 |
-
text_lengths = torch.LongTensor(len(batch))
|
| 219 |
-
spec_lengths = torch.LongTensor(len(batch))
|
| 220 |
-
wav_lengths = torch.LongTensor(len(batch))
|
| 221 |
-
sid = torch.LongTensor(len(batch))
|
| 222 |
-
|
| 223 |
-
text_padded = torch.LongTensor(len(batch), max_text_len)
|
| 224 |
-
tone_padded = torch.LongTensor(len(batch), max_text_len)
|
| 225 |
-
language_padded = torch.LongTensor(len(batch), max_text_len)
|
| 226 |
-
bert_padded = torch.FloatTensor(len(batch), 1024, max_text_len)
|
| 227 |
-
ja_bert_padded = torch.FloatTensor(len(batch), 1024, max_text_len)
|
| 228 |
-
en_bert_padded = torch.FloatTensor(len(batch), 1024, max_text_len)
|
| 229 |
-
style_vec = torch.FloatTensor(len(batch), 256)
|
| 230 |
-
|
| 231 |
-
spec_padded = torch.FloatTensor(len(batch), batch[0][1].size(0), max_spec_len)
|
| 232 |
-
wav_padded = torch.FloatTensor(len(batch), 1, max_wav_len)
|
| 233 |
-
text_padded.zero_()
|
| 234 |
-
tone_padded.zero_()
|
| 235 |
-
language_padded.zero_()
|
| 236 |
-
spec_padded.zero_()
|
| 237 |
-
wav_padded.zero_()
|
| 238 |
-
bert_padded.zero_()
|
| 239 |
-
ja_bert_padded.zero_()
|
| 240 |
-
en_bert_padded.zero_()
|
| 241 |
-
style_vec.zero_()
|
| 242 |
-
|
| 243 |
-
for i in range(len(ids_sorted_decreasing)):
|
| 244 |
-
row = batch[ids_sorted_decreasing[i]]
|
| 245 |
-
|
| 246 |
-
text = row[0]
|
| 247 |
-
text_padded[i, : text.size(0)] = text
|
| 248 |
-
text_lengths[i] = text.size(0)
|
| 249 |
-
|
| 250 |
-
spec = row[1]
|
| 251 |
-
spec_padded[i, :, : spec.size(1)] = spec
|
| 252 |
-
spec_lengths[i] = spec.size(1)
|
| 253 |
-
|
| 254 |
-
wav = row[2]
|
| 255 |
-
wav_padded[i, :, : wav.size(1)] = wav
|
| 256 |
-
wav_lengths[i] = wav.size(1)
|
| 257 |
-
|
| 258 |
-
sid[i] = row[3]
|
| 259 |
-
|
| 260 |
-
tone = row[4]
|
| 261 |
-
tone_padded[i, : tone.size(0)] = tone
|
| 262 |
-
|
| 263 |
-
language = row[5]
|
| 264 |
-
language_padded[i, : language.size(0)] = language
|
| 265 |
-
|
| 266 |
-
bert = row[6]
|
| 267 |
-
bert_padded[i, :, : bert.size(1)] = bert
|
| 268 |
-
|
| 269 |
-
ja_bert = row[7]
|
| 270 |
-
ja_bert_padded[i, :, : ja_bert.size(1)] = ja_bert
|
| 271 |
-
|
| 272 |
-
en_bert = row[8]
|
| 273 |
-
en_bert_padded[i, :, : en_bert.size(1)] = en_bert
|
| 274 |
-
|
| 275 |
-
style_vec[i, :] = row[9]
|
| 276 |
-
|
| 277 |
-
return (
|
| 278 |
-
text_padded,
|
| 279 |
-
text_lengths,
|
| 280 |
-
spec_padded,
|
| 281 |
-
spec_lengths,
|
| 282 |
-
wav_padded,
|
| 283 |
-
wav_lengths,
|
| 284 |
-
sid,
|
| 285 |
-
tone_padded,
|
| 286 |
-
language_padded,
|
| 287 |
-
bert_padded,
|
| 288 |
-
ja_bert_padded,
|
| 289 |
-
en_bert_padded,
|
| 290 |
-
style_vec,
|
| 291 |
-
)
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
class DistributedBucketSampler(torch.utils.data.distributed.DistributedSampler):
|
| 295 |
-
"""
|
| 296 |
-
Maintain similar input lengths in a batch.
|
| 297 |
-
Length groups are specified by boundaries.
|
| 298 |
-
Ex) boundaries = [b1, b2, b3] -> any batch is included either {x | b1 < length(x) <=b2} or {x | b2 < length(x) <= b3}.
|
| 299 |
-
|
| 300 |
-
It removes samples which are not included in the boundaries.
|
| 301 |
-
Ex) boundaries = [b1, b2, b3] -> any x s.t. length(x) <= b1 or length(x) > b3 are discarded.
|
| 302 |
-
"""
|
| 303 |
-
|
| 304 |
-
def __init__(
|
| 305 |
-
self,
|
| 306 |
-
dataset,
|
| 307 |
-
batch_size,
|
| 308 |
-
boundaries,
|
| 309 |
-
num_replicas=None,
|
| 310 |
-
rank=None,
|
| 311 |
-
shuffle=True,
|
| 312 |
-
):
|
| 313 |
-
super().__init__(dataset, num_replicas=num_replicas, rank=rank, shuffle=shuffle)
|
| 314 |
-
self.lengths = dataset.lengths
|
| 315 |
-
self.batch_size = batch_size
|
| 316 |
-
self.boundaries = boundaries
|
| 317 |
-
|
| 318 |
-
self.buckets, self.num_samples_per_bucket = self._create_buckets()
|
| 319 |
-
logger.info(f"Bucket info: {self.num_samples_per_bucket}")
|
| 320 |
-
logger.info(
|
| 321 |
-
f"Unused samples: {len(self.lengths) - sum(self.num_samples_per_bucket)}"
|
| 322 |
-
)
|
| 323 |
-
self.total_size = sum(self.num_samples_per_bucket)
|
| 324 |
-
self.num_samples = self.total_size // self.num_replicas
|
| 325 |
-
|
| 326 |
-
def _create_buckets(self):
|
| 327 |
-
buckets = [[] for _ in range(len(self.boundaries) - 1)]
|
| 328 |
-
for i in range(len(self.lengths)):
|
| 329 |
-
length = self.lengths[i]
|
| 330 |
-
idx_bucket = self._bisect(length)
|
| 331 |
-
if idx_bucket != -1:
|
| 332 |
-
buckets[idx_bucket].append(i)
|
| 333 |
-
|
| 334 |
-
try:
|
| 335 |
-
for i in range(len(buckets) - 1, 0, -1):
|
| 336 |
-
if len(buckets[i]) == 0:
|
| 337 |
-
buckets.pop(i)
|
| 338 |
-
self.boundaries.pop(i + 1)
|
| 339 |
-
assert all(len(bucket) > 0 for bucket in buckets)
|
| 340 |
-
# When one bucket is not traversed
|
| 341 |
-
except Exception as e:
|
| 342 |
-
print("Bucket warning ", e)
|
| 343 |
-
for i in range(len(buckets) - 1, -1, -1):
|
| 344 |
-
if len(buckets[i]) == 0:
|
| 345 |
-
buckets.pop(i)
|
| 346 |
-
self.boundaries.pop(i + 1)
|
| 347 |
-
|
| 348 |
-
num_samples_per_bucket = []
|
| 349 |
-
for i in range(len(buckets)):
|
| 350 |
-
len_bucket = len(buckets[i])
|
| 351 |
-
total_batch_size = self.num_replicas * self.batch_size
|
| 352 |
-
rem = (
|
| 353 |
-
total_batch_size - (len_bucket % total_batch_size)
|
| 354 |
-
) % total_batch_size
|
| 355 |
-
num_samples_per_bucket.append(len_bucket + rem)
|
| 356 |
-
return buckets, num_samples_per_bucket
|
| 357 |
-
|
| 358 |
-
def __iter__(self):
|
| 359 |
-
# deterministically shuffle based on epoch
|
| 360 |
-
g = torch.Generator()
|
| 361 |
-
g.manual_seed(self.epoch)
|
| 362 |
-
|
| 363 |
-
indices = []
|
| 364 |
-
if self.shuffle:
|
| 365 |
-
for bucket in self.buckets:
|
| 366 |
-
indices.append(torch.randperm(len(bucket), generator=g).tolist())
|
| 367 |
-
else:
|
| 368 |
-
for bucket in self.buckets:
|
| 369 |
-
indices.append(list(range(len(bucket))))
|
| 370 |
-
|
| 371 |
-
batches = []
|
| 372 |
-
for i in range(len(self.buckets)):
|
| 373 |
-
bucket = self.buckets[i]
|
| 374 |
-
len_bucket = len(bucket)
|
| 375 |
-
if len_bucket == 0:
|
| 376 |
-
continue
|
| 377 |
-
ids_bucket = indices[i]
|
| 378 |
-
num_samples_bucket = self.num_samples_per_bucket[i]
|
| 379 |
-
|
| 380 |
-
# add extra samples to make it evenly divisible
|
| 381 |
-
rem = num_samples_bucket - len_bucket
|
| 382 |
-
ids_bucket = (
|
| 383 |
-
ids_bucket
|
| 384 |
-
+ ids_bucket * (rem // len_bucket)
|
| 385 |
-
+ ids_bucket[: (rem % len_bucket)]
|
| 386 |
-
)
|
| 387 |
-
|
| 388 |
-
# subsample
|
| 389 |
-
ids_bucket = ids_bucket[self.rank :: self.num_replicas]
|
| 390 |
-
|
| 391 |
-
# batching
|
| 392 |
-
for j in range(len(ids_bucket) // self.batch_size):
|
| 393 |
-
batch = [
|
| 394 |
-
bucket[idx]
|
| 395 |
-
for idx in ids_bucket[
|
| 396 |
-
j * self.batch_size : (j + 1) * self.batch_size
|
| 397 |
-
]
|
| 398 |
-
]
|
| 399 |
-
batches.append(batch)
|
| 400 |
-
|
| 401 |
-
if self.shuffle:
|
| 402 |
-
batch_ids = torch.randperm(len(batches), generator=g).tolist()
|
| 403 |
-
batches = [batches[i] for i in batch_ids]
|
| 404 |
-
self.batches = batches
|
| 405 |
-
|
| 406 |
-
assert len(self.batches) * self.batch_size == self.num_samples
|
| 407 |
-
return iter(self.batches)
|
| 408 |
-
|
| 409 |
-
def _bisect(self, x, lo=0, hi=None):
|
| 410 |
-
if hi is None:
|
| 411 |
-
hi = len(self.boundaries) - 1
|
| 412 |
-
|
| 413 |
-
if hi > lo:
|
| 414 |
-
mid = (hi + lo) // 2
|
| 415 |
-
if self.boundaries[mid] < x and x <= self.boundaries[mid + 1]:
|
| 416 |
-
return mid
|
| 417 |
-
elif x <= self.boundaries[mid]:
|
| 418 |
-
return self._bisect(x, lo, mid)
|
| 419 |
-
else:
|
| 420 |
-
return self._bisect(x, mid + 1, hi)
|
| 421 |
-
else:
|
| 422 |
-
return -1
|
| 423 |
-
|
| 424 |
-
def __len__(self):
|
| 425 |
-
return self.num_samples // self.batch_size
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/default_config.yml
DELETED
|
@@ -1,81 +0,0 @@
|
|
| 1 |
-
# Global configuration file for Bert-VITS2
|
| 2 |
-
|
| 3 |
-
model_name: "model_name"
|
| 4 |
-
|
| 5 |
-
out_dir: "model_assets"
|
| 6 |
-
|
| 7 |
-
# If you want to use a specific dataset path, uncomment the following line.
|
| 8 |
-
# Otherwise, the dataset path is `Data/{model_name}`.
|
| 9 |
-
|
| 10 |
-
# dataset_path: "your/dataset/path"
|
| 11 |
-
|
| 12 |
-
resample:
|
| 13 |
-
sampling_rate: 44100
|
| 14 |
-
in_dir: "audios/raw"
|
| 15 |
-
out_dir: "audios/wavs"
|
| 16 |
-
|
| 17 |
-
preprocess_text:
|
| 18 |
-
transcription_path: "filelists/esd.list"
|
| 19 |
-
cleaned_path: ""
|
| 20 |
-
train_path: "filelists/train.list"
|
| 21 |
-
val_path: "filelists/val.list"
|
| 22 |
-
config_path: "config.json"
|
| 23 |
-
val_per_lang: 4
|
| 24 |
-
max_val_total: 12
|
| 25 |
-
clean: true
|
| 26 |
-
|
| 27 |
-
bert_gen:
|
| 28 |
-
config_path: "config.json"
|
| 29 |
-
num_processes: 4
|
| 30 |
-
device: "cuda"
|
| 31 |
-
use_multi_device: false
|
| 32 |
-
|
| 33 |
-
style_gen:
|
| 34 |
-
config_path: "config.json"
|
| 35 |
-
num_processes: 4
|
| 36 |
-
device: "cuda"
|
| 37 |
-
|
| 38 |
-
train_ms:
|
| 39 |
-
env:
|
| 40 |
-
MASTER_ADDR: "localhost"
|
| 41 |
-
MASTER_PORT: 10086
|
| 42 |
-
WORLD_SIZE: 1
|
| 43 |
-
LOCAL_RANK: 0
|
| 44 |
-
RANK: 0
|
| 45 |
-
model: "models"
|
| 46 |
-
config_path: "config.json"
|
| 47 |
-
num_workers: 16
|
| 48 |
-
spec_cache: True
|
| 49 |
-
keep_ckpts: 1 # Set this to 0 to keep all checkpoints
|
| 50 |
-
|
| 51 |
-
webui:
|
| 52 |
-
# 推理设备
|
| 53 |
-
device: "cuda"
|
| 54 |
-
# 模型路径
|
| 55 |
-
model: "models/G_8000.pth"
|
| 56 |
-
# 配置文件路径
|
| 57 |
-
config_path: "config.json"
|
| 58 |
-
# 端口号
|
| 59 |
-
port: 7860
|
| 60 |
-
# 是否公开部署,对外网开放
|
| 61 |
-
share: false
|
| 62 |
-
# 是否开启debug模式
|
| 63 |
-
debug: false
|
| 64 |
-
# 语种识别库,可选langid, fastlid
|
| 65 |
-
language_identification_library: "langid"
|
| 66 |
-
|
| 67 |
-
# server_fastapi's config
|
| 68 |
-
# TODO: `server_fastapi.py` is not implemented yet for this version
|
| 69 |
-
server:
|
| 70 |
-
port: 5000
|
| 71 |
-
device: "cuda"
|
| 72 |
-
models:
|
| 73 |
-
- model: ""
|
| 74 |
-
config: ""
|
| 75 |
-
device: "cuda"
|
| 76 |
-
language: "ZH"
|
| 77 |
-
- model: ""
|
| 78 |
-
config: ""
|
| 79 |
-
device: "cpu"
|
| 80 |
-
language: "JP"
|
| 81 |
-
speakers: []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Hololive-Style-Bert-VITS2/images/aki.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/ame.png
DELETED
|
Binary file (50.5 kB)
|
|
|
Hololive-Style-Bert-VITS2/images/anya.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/aqua.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/ayame.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/azki.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/bae.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/bijou.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/calli.png
DELETED
|
Binary file (46.8 kB)
|
|
|
Hololive-Style-Bert-VITS2/images/chloe.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/fauna.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/flare.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/fubuki.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/gura.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/haato.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/ina.png
DELETED
|
Binary file (80.4 kB)
|
|
|
Hololive-Style-Bert-VITS2/images/iofi.png
DELETED
|
Binary file (40 kB)
|
|
|
Hololive-Style-Bert-VITS2/images/irys.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/kanata.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/kiara.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/koyori.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/kronii.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/lamy.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/laplus.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/lui.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/luna.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/marine.png
DELETED
|
Binary file (41.6 kB)
|
|
|
Hololive-Style-Bert-VITS2/images/matsuri.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/mel.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/miko.png
DELETED
Git LFS Details
|
Hololive-Style-Bert-VITS2/images/moona.png
DELETED
|
Binary file (48.9 kB)
|
|
|