Skip to content
This repository was archived by the owner on Oct 19, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@ python train.py -c configs/config.json -m 44k

```shell
# 例
python inference_main.py -m "logs/44k/G_30400.pth" -c "configs/config.json" -n "君の知らない物語-src.wav" -t 0 -s "nen"
python inference_main.py -m "logs/44k/G_30400.pth" -c "configs/config.json" -f "raw/君の知らない物語-src.wav" -t 0 -s "nen"
```
必填项部分
+ -m, --model_path:模型路径。
+ -c, --config_path:配置文件路径。
+ -n, --clean_names:wav 文件名列表,放在 raw 文件夹下
+ -f, --input_files:wav 文件名列表,相对/绝对路径均可
+ -t, --trans:音高调整,支持正负(半音)。
+ -s, --spk_list:合成目标说话人名称。

Expand Down
24 changes: 15 additions & 9 deletions inference/infer_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@
import torchaudio

import cluster
from hubert import hubert_model
import utils
from models import SynthesizerTrn
from pathlib import Path


logging.getLogger('matplotlib').setLevel(logging.WARNING)


def read_temp(file_name):
if not os.path.exists(file_name):
with open(file_name, "w") as f:
path = Path(file_name)
if not path.exists():
path.parent.mkdir(exist_ok=True)
with open(path, "w") as f:
f.write(json.dumps({"info": "temp_dict"}))
return {}
else:
Expand Down Expand Up @@ -61,11 +64,13 @@ def run(*args, **kwargs):
return run


def format_wav(audio_path):
if Path(audio_path).suffix == '.wav':
return
def format_wav(audio_path: Path):
if audio_path.suffix == '.wav':
return audio_path
audio_path = audio_path.with_suffix(".wav")
raw_audio, raw_sample_rate = librosa.load(audio_path, mono=True, sr=None)
soundfile.write(Path(audio_path).with_suffix(".wav"), raw_audio, raw_sample_rate)
soundfile.write(audio_path, raw_audio, raw_sample_rate)
return audio_path


def get_end_file(dir_path, end):
Expand Down Expand Up @@ -107,7 +112,8 @@ def pad_array(arr, target_length):
class Svc(object):
def __init__(self, net_g_path, config_path,
device=None,
cluster_model_path="logs/44k/kmeans_10000.pt"):
cluster_model_path="logs/44k/kmeans_10000.pt",
hubert_model_path="hubert/checkpoint_best_legacy_500.pt"):
self.net_g_path = net_g_path
if device is None:
self.dev = torch.device("cuda" if torch.cuda.is_available() else "cpu")
Expand All @@ -119,7 +125,7 @@ def __init__(self, net_g_path, config_path,
self.hop_size = self.hps_ms.data.hop_length
self.spk2id = self.hps_ms.spk
# 加载hubert
self.hubert_model = utils.get_hubert_model().to(self.dev)
self.hubert_model = utils.get_hubert_model(hubert_model_path).to(self.dev)
self.load_model()
if os.path.exists(cluster_model_path):
self.cluster_model = cluster.get_cluster_model(cluster_model_path)
Expand Down
41 changes: 21 additions & 20 deletions inference_main.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import io
import logging
import time
from pathlib import Path

import librosa
import matplotlib.pyplot as plt
import numpy as np
import soundfile
import platform

from inference import infer_tool
from inference import slicer
Expand All @@ -25,7 +23,7 @@ def main():
# 一定要设置的部分
parser.add_argument('-m', '--model_path', type=str, default="logs/44k/G_0.pth", help='模型路径')
parser.add_argument('-c', '--config_path', type=str, default="configs/config.json", help='配置文件路径')
parser.add_argument('-n', '--clean_names', type=str, nargs='+', default=["君の知らない物語-src.wav"], help='wav文件名列表,放在raw文件夹下')
parser.add_argument('-f', '--input_files', type=str, nargs='+', default=["raw/君の知らない物語-src.wav"], help='wav文件名列表,放在raw文件夹下')
parser.add_argument('-t', '--trans', type=int, nargs='+', default=[0], help='音高调整,支持正负(半音)')
parser.add_argument('-s', '--spk_list', type=str, nargs='+', default=['nen'], help='合成目标说话人名称')

Expand All @@ -41,12 +39,14 @@ def main():
parser.add_argument('-ns', '--noice_scale', type=float, default=0.4, help='噪音级别,会影响咬字和音质,较为玄学')
parser.add_argument('-p', '--pad_seconds', type=float, default=0.5, help='推理音频pad秒数,由于未知原因开头结尾会有异响,pad一小段静音段后就不会出现')
parser.add_argument('-wf', '--wav_format', type=str, default='flac', help='音频输出格式')
parser.add_argument('-hb', '--hubert_path', type=str, default='hubert/checkpoint_best_legacy_500.pt', help='hubert模型路径')
parser.add_argument('-o', '--output_path', type=str, default="results", help='输出路径(文件夹)')

args = parser.parse_args()

svc_model = Svc(args.model_path, args.config_path, args.device, args.cluster_model_path)
infer_tool.mkdir(["raw", "results"])
clean_names = args.clean_names
svc_model = Svc(args.model_path, args.config_path,
args.device, args.cluster_model_path, hubert_model_path=args.hubert_path)
input_list = args.input_files
trans = args.trans
spk_list = args.spk_list
slice_db = args.slice_db
Expand All @@ -55,14 +55,14 @@ def main():
cluster_infer_ratio = args.cluster_infer_ratio
noice_scale = args.noice_scale
pad_seconds = args.pad_seconds

infer_tool.fill_a_to_b(trans, clean_names)
for clean_name, tran in zip(clean_names, trans):
raw_audio_path = f"raw/{clean_name}"
if "." not in raw_audio_path:
raw_audio_path += ".wav"
infer_tool.format_wav(raw_audio_path)
wav_path = Path(raw_audio_path).with_suffix('.wav')
output_dir = Path(args.output_path)
output_dir.mkdir(parents=True, exist_ok=True)

infer_tool.fill_a_to_b(trans, input_list)
for input_file, tran in zip(input_list, trans):
wav_path = Path(input_file)
if not wav_path.suffix or platform.system() == "Windows":
wav_path = infer_tool.format_wav(wav_path)
chunks = slicer.cut(wav_path, db_thresh=slice_db)
audio_data, audio_sr = slicer.chunks2audio(wav_path, chunks)

Expand All @@ -79,10 +79,10 @@ def main():
# padd
pad_len = int(audio_sr * pad_seconds)
data = np.concatenate([np.zeros([pad_len]), data, np.zeros([pad_len])])
raw_path = io.BytesIO()
soundfile.write(raw_path, data, audio_sr, format="wav")
raw_path.seek(0)
out_audio, out_sr = svc_model.infer(spk, tran, raw_path,
data_with_pad = io.BytesIO()
soundfile.write(data_with_pad, data, audio_sr, format="wav")
data_with_pad.seek(0)
out_audio, out_sr = svc_model.infer(spk, tran, data_with_pad,
cluster_infer_ratio=cluster_infer_ratio,
auto_predict_f0=auto_predict_f0,
noice_scale=noice_scale
Expand All @@ -94,7 +94,8 @@ def main():
audio.extend(list(infer_tool.pad_array(_audio, length)))
key = "auto" if auto_predict_f0 else f"{tran}key"
cluster_name = "" if cluster_infer_ratio == 0 else f"_{cluster_infer_ratio}"
res_path = f'./results/{clean_name}_{key}_{spk}{cluster_name}.{wav_format}'
clean_name = Path(input_file).stem
res_path = output_dir / f'{clean_name}_{key}_{spk}{cluster_name}.{wav_format}'
soundfile.write(res_path, audio, svc_model.target_sample, format=wav_format)

if __name__ == '__main__':
Expand Down
11 changes: 0 additions & 11 deletions onnx_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,6 @@
from onnxexport.model_onnx import SynthesizerTrn
import utils

def get_hubert_model():
vec_path = "hubert/checkpoint_best_legacy_500.pt"
print("load model(s) from {}".format(vec_path))
models, saved_cfg, task = checkpoint_utils.load_model_ensemble_and_task(
[vec_path],
suffix="",
)
model = models[0]
model.eval()
return model


def main(HubertExport, NetExport):
path = "SoVits4.0"
Expand Down
3 changes: 1 addition & 2 deletions utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,7 @@ def f0_to_coarse(f0):
return f0_coarse


def get_hubert_model():
vec_path = "hubert/checkpoint_best_legacy_500.pt"
def get_hubert_model(vec_path: str = "hubert/checkpoint_best_legacy_500.pt"):
print("load model(s) from {}".format(vec_path))
from fairseq import checkpoint_utils
models, saved_cfg, task = checkpoint_utils.load_model_ensemble_and_task(
Expand Down