voice-changer/server/voice_changer/RVC/RVC.py

465 lines
19 KiB
Python
Raw Normal View History

2023-04-05 20:31:10 +03:00
import sys
import os
2023-04-21 23:42:24 +03:00
import json
2023-04-05 20:49:16 +03:00
import resampy
2023-04-07 21:11:37 +03:00
from voice_changer.RVC.ModelWrapper import ModelWrapper
2023-04-17 03:45:12 +03:00
from Exceptions import NoModeLoadedException
2023-04-13 02:00:28 +03:00
2023-04-05 20:38:50 +03:00
# avoiding parse arg error in RVC
2023-04-05 20:31:10 +03:00
sys.argv = ["MMVCServerSIO.py"]
if sys.platform.startswith('darwin'):
baseDir = [x for x in sys.path if x.endswith("Contents/MacOS")]
if len(baseDir) != 1:
print("baseDir should be only one ", baseDir)
sys.exit()
modulePath = os.path.join(baseDir[0], "RVC")
sys.path.append(modulePath)
else:
sys.path.append("RVC")
import io
from dataclasses import dataclass, asdict, field
from functools import reduce
import numpy as np
import torch
import onnxruntime
# onnxruntime.set_default_logger_severity(3)
2023-04-13 02:00:28 +03:00
from const import HUBERT_ONNX_MODEL_PATH, TMP_DIR
2023-04-05 20:31:10 +03:00
import pyworld as pw
from voice_changer.RVC.custom_vc_infer_pipeline import VC
2023-04-22 23:09:19 +03:00
from infer_pack.models import SynthesizerTrnMs256NSFsid, SynthesizerTrnMs256NSFsid_nono
2023-04-23 00:19:48 +03:00
from .models import SynthesizerTrnMsNSFsid as SynthesizerTrnMs768NSFsid
from .const import RVC_MODEL_TYPE_NORMAL, RVC_MODEL_TYPE_PITCHLESS, RVC_MODEL_TYPE_WEBUI_256_NORMAL, RVC_MODEL_TYPE_WEBUI_768_NORMAL, RVC_MODEL_TYPE_WEBUI_256_PITCHLESS, RVC_MODEL_TYPE_WEBUI_768_PITCHLESS, RVC_MODEL_TYPE_UNKNOWN
2023-04-05 20:31:10 +03:00
from fairseq import checkpoint_utils
providers = ['OpenVINOExecutionProvider', "CUDAExecutionProvider", "DmlExecutionProvider", "CPUExecutionProvider"]
2023-04-21 09:48:12 +03:00
@dataclass
class ModelSlot():
pyTorchModelFile: str = ""
onnxModelFile: str = ""
featureFile: str = ""
indexFile: str = ""
2023-04-21 23:42:24 +03:00
defaultTrans: int = ""
2023-04-23 00:19:48 +03:00
modelType: int = RVC_MODEL_TYPE_UNKNOWN
2023-04-21 09:48:12 +03:00
2023-04-05 20:31:10 +03:00
@dataclass
class RVCSettings():
gpu: int = 0
dstId: int = 0
2023-04-18 06:00:49 +03:00
f0Detector: str = "pm" # pm or harvest
2023-04-05 20:31:10 +03:00
tran: int = 20
silentThreshold: float = 0.00001
extraConvertSize: int = 1024 * 32
clusterInferRatio: float = 0.1
framework: str = "PyTorch" # PyTorch or ONNX
pyTorchModelFile: str = ""
onnxModelFile: str = ""
configFile: str = ""
2023-04-21 09:48:12 +03:00
modelSlots: list[ModelSlot] = field(
default_factory=lambda: [
ModelSlot(), ModelSlot(), ModelSlot()
]
)
2023-04-07 21:11:37 +03:00
indexRatio: float = 0
2023-04-07 22:39:04 +03:00
rvcQuality: int = 0
2023-04-19 01:57:19 +03:00
silenceFront: int = 1 # 0:off, 1:on
2023-04-07 22:39:04 +03:00
modelSamplingRate: int = 48000
2023-04-21 09:48:12 +03:00
modelSlotIndex: int = 0
2023-04-07 21:11:37 +03:00
2023-04-05 20:31:10 +03:00
speakers: dict[str, int] = field(
default_factory=lambda: {}
)
# ↓mutableな物だけ列挙
2023-04-21 09:48:12 +03:00
intData = ["gpu", "dstId", "tran", "extraConvertSize", "rvcQuality", "modelSamplingRate", "silenceFront", "modelSlotIndex"]
2023-04-20 11:17:43 +03:00
floatData = ["silentThreshold", "indexRatio"]
2023-04-05 20:31:10 +03:00
strData = ["framework", "f0Detector"]
class RVC:
def __init__(self, params):
2023-04-22 01:57:51 +03:00
self.initialLoad = True
2023-04-05 20:31:10 +03:00
self.settings = RVCSettings()
2023-04-21 20:37:38 +03:00
2023-04-21 23:42:24 +03:00
self.inferenceing: bool = False
2023-04-05 20:31:10 +03:00
self.net_g = None
self.onnx_session = None
2023-04-21 20:37:38 +03:00
self.feature_file = None
self.index_file = None
# self.net_g2 = None
# self.onnx_session2 = None
# self.feature_file2 = None
# self.index_file2 = None
2023-04-05 20:31:10 +03:00
self.gpu_num = torch.cuda.device_count()
self.prevVol = 0
self.params = params
2023-04-17 21:06:31 +03:00
self.mps_enabled: bool = getattr(torch.backends, "mps", None) is not None and torch.backends.mps.is_available()
2023-04-21 13:20:46 +03:00
self.currentSlot = -1
2023-04-05 20:31:10 +03:00
print("RVC initialization: ", params)
2023-04-17 21:06:31 +03:00
print("mps: ", self.mps_enabled)
2023-04-05 20:31:10 +03:00
2023-04-16 03:56:12 +03:00
def loadModel(self, props):
self.is_half = props["isHalf"]
2023-04-21 13:20:46 +03:00
self.tmp_slot = props["slot"]
2023-04-21 23:42:24 +03:00
params_str = props["params"]
params = json.loads(params_str)
2023-04-16 03:56:12 +03:00
2023-04-21 13:20:46 +03:00
self.settings.modelSlots[self.tmp_slot] = ModelSlot(
2023-04-21 09:48:12 +03:00
pyTorchModelFile=props["files"]["pyTorchModelFilename"],
onnxModelFile=props["files"]["onnxModelFilename"],
featureFile=props["files"]["featureFilename"],
2023-04-21 23:42:24 +03:00
indexFile=props["files"]["indexFilename"],
2023-04-23 00:19:48 +03:00
defaultTrans=params["trans"],
modelType=RVC_MODEL_TYPE_UNKNOWN
2023-04-21 09:48:12 +03:00
)
2023-04-21 13:20:46 +03:00
print("[Voice Changer] RVC loading... slot:", self.tmp_slot)
2023-04-05 20:31:10 +03:00
try:
2023-04-18 21:06:45 +03:00
hubert_path = self.params["hubert_base"]
2023-04-05 21:14:37 +03:00
models, saved_cfg, task = checkpoint_utils.load_model_ensemble_and_task([hubert_path], suffix="",)
2023-04-05 20:31:10 +03:00
model = models[0]
model.eval()
2023-04-07 21:56:40 +03:00
if self.is_half:
2023-04-07 21:11:37 +03:00
model = model.half()
2023-04-05 20:31:10 +03:00
self.hubert_model = model
except Exception as e:
print("EXCEPTION during loading hubert/contentvec model", e)
2023-04-21 13:20:46 +03:00
# self.switchModel(self.slot)
2023-04-22 01:57:51 +03:00
if self.initialLoad:
self.prepareModel(self.tmp_slot)
self.slot = self.tmp_slot
self.currentSlot = self.slot
self.switchModel()
self.initialLoad = False
2023-04-21 09:48:12 +03:00
return self.get_info()
2023-04-21 13:20:46 +03:00
def prepareModel(self, slot: int):
print("[Voice Changer] Prepare Model of slot:", slot)
2023-04-21 09:48:12 +03:00
pyTorchModelFile = self.settings.modelSlots[slot].pyTorchModelFile
onnxModelFile = self.settings.modelSlots[slot].onnxModelFile
2023-04-05 20:31:10 +03:00
# PyTorchモデル生成
2023-04-21 10:51:03 +03:00
if pyTorchModelFile != None and pyTorchModelFile != "":
2023-04-21 09:48:12 +03:00
cpt = torch.load(pyTorchModelFile, map_location="cpu")
2023-04-23 00:19:48 +03:00
'''
2023-04-23 13:36:41 +03:00
(1) オリジナルとrvc-webuiのモデル判定 config全体の形状
ーマル256
[1025, 32, 192, 192, 768, 2, 6, 3, 0, '1', [3, 7, 11], [[1, 3, 5], [1, 3, 5], [1, 3, 5]], [10, 6, 2, 2, 2], 512, [16, 16, 4, 4, 4], 109, 256, 48000]
ノーマル 768対応
[1025, 32, 192, 192, 768, 2, 6, 3, 0, '1', [3, 7, 11], [[1, 3, 5], [1, 3, 5], [1, 3, 5]], [10, 6, 2, 2, 2], 512, [16, 16, 4, 4, 4], 109, 256, 768, 48000]
18: オリジナル, 19: rvc-webui
(2-1) オリジナルのーマルorPitchレス判定 ckp["f0"]で判定
0: ピッチレス, 1:ノーマル
(2-2) rvc-webuiの(256 or 768) x (ーマルor pitchレス)判定 256, or 768 は17番目の要素で判定, ーマルor pitchレスはckp["f0"]で判定
2023-04-23 00:19:48 +03:00
'''
# print("config shape:1::::", cpt["config"], cpt["f0"])
# print("config shape:2::::", (cpt).keys)
2023-04-23 00:19:48 +03:00
config_len = len(cpt["config"])
upsamplingRateDims = len(cpt["config"][12])
if config_len == 18 and cpt["f0"] == 0:
print("[Voice Changer] RVC Model Type: RVC_MODEL_TYPE_PITCHLESS")
self.settings.modelSlots[slot].modelType = RVC_MODEL_TYPE_PITCHLESS
elif config_len == 18 and cpt["f0"] == 1:
2023-04-23 13:36:41 +03:00
print("[Voice Changer] RVC Model Type: RVC_MODEL_TYPE_NORMAL")
2023-04-23 00:19:48 +03:00
self.settings.modelSlots[slot].modelType = RVC_MODEL_TYPE_NORMAL
elif config_len == 19:
print("PARAMS:::::::::", cpt["params"])
2023-04-23 13:36:41 +03:00
embedding = cpt["config"][17]
if embedding == 256 and cpt["f0"] == 0:
print("[Voice Changer] RVC Model Type: RVC_MODEL_TYPE_WEBUI_256_PITCHLESS")
self.settings.modelSlots[slot].modelType = RVC_MODEL_TYPE_WEBUI_256_PITCHLESS
elif embedding == 256 and cpt["f0"] == 1:
2023-04-23 13:36:41 +03:00
print("[Voice Changer] RVC Model Type: RVC_MODEL_TYPE_WEBUI_256_NORMAL")
self.settings.modelSlots[slot].modelType = RVC_MODEL_TYPE_WEBUI_256_NORMAL
elif embedding == 768 and cpt["f0"] == 0:
print("[Voice Changer] RVC Model Type: RVC_MODEL_TYPE_WEBUI_768_PITCHLESS")
self.settings.modelSlots[slot].modelType = RVC_MODEL_TYPE_WEBUI_768_PITCHLESS
2023-04-23 13:36:41 +03:00
else:
print("[Voice Changer] RVC Model Type: RVC_MODEL_TYPE_WEBUI_768_NORMAL")
self.settings.modelSlots[slot].modelType = RVC_MODEL_TYPE_WEBUI_768_NORMAL
2023-04-23 00:19:48 +03:00
else:
print("[Voice Changer] RVC Model Type: UNKNOWN")
self.settings.modelSlots[slot].modelType = RVC_MODEL_TYPE_UNKNOWN
self.settings.modelSamplingRate = cpt["config"][-1]
2023-04-23 00:19:48 +03:00
if self.settings.modelSlots[slot].modelType == RVC_MODEL_TYPE_NORMAL:
net_g = SynthesizerTrnMs256NSFsid(*cpt["config"], is_half=self.is_half)
elif self.settings.modelSlots[slot].modelType == RVC_MODEL_TYPE_PITCHLESS:
2023-04-23 00:19:48 +03:00
net_g = SynthesizerTrnMs256NSFsid_nono(*cpt["config"])
2023-04-23 13:36:41 +03:00
elif self.settings.modelSlots[slot].modelType == RVC_MODEL_TYPE_WEBUI_256_NORMAL or self.settings.modelSlots[slot].modelType == RVC_MODEL_TYPE_WEBUI_768_NORMAL:
2023-04-23 00:19:48 +03:00
net_g = SynthesizerTrnMs768NSFsid(**cpt["params"], is_half=self.is_half)
elif self.settings.modelSlots[slot].modelType == RVC_MODEL_TYPE_WEBUI_256_PITCHLESS or self.settings.modelSlots[slot].modelType == RVC_MODEL_TYPE_WEBUI_768_PITCHLESS:
net_g = SynthesizerTrnMs768NSFsid(**cpt["params"], is_half=self.is_half)
2023-04-23 00:19:48 +03:00
else:
print("unknwon")
2023-04-05 20:31:10 +03:00
net_g.eval()
net_g.load_state_dict(cpt["weight"], strict=False)
2023-04-07 21:56:40 +03:00
if self.is_half:
2023-04-07 21:11:37 +03:00
net_g = net_g.half()
2023-04-21 13:20:46 +03:00
self.next_net_g = net_g
2023-04-21 09:48:12 +03:00
else:
2023-04-21 13:20:46 +03:00
self.next_net_g = None
2023-04-05 20:31:10 +03:00
# ONNXモデル生成
2023-04-21 10:51:03 +03:00
if onnxModelFile != None and onnxModelFile != "":
2023-04-21 13:20:46 +03:00
self.next_onnx_session = ModelWrapper(onnxModelFile)
2023-04-21 09:48:12 +03:00
else:
2023-04-21 13:20:46 +03:00
self.next_onnx_session = None
2023-04-21 09:48:12 +03:00
2023-04-21 13:20:46 +03:00
self.next_feature_file = self.settings.modelSlots[slot].featureFile
self.next_index_file = self.settings.modelSlots[slot].indexFile
2023-04-21 23:42:24 +03:00
self.next_trans = self.settings.modelSlots[slot].defaultTrans
2023-04-21 09:48:12 +03:00
2023-04-05 20:31:10 +03:00
return self.get_info()
2023-04-21 13:20:46 +03:00
def switchModel(self):
2023-04-21 23:42:24 +03:00
# del self.net_g
# del self.onnx_session
2023-04-21 13:20:46 +03:00
self.net_g = self.next_net_g
self.onnx_session = self.next_onnx_session
self.feature_file = self.next_feature_file
self.index_file = self.next_index_file
2023-04-21 23:42:24 +03:00
self.settings.tran = self.next_trans
2023-04-21 13:20:46 +03:00
self.next_net_g = None
self.next_onnx_session = None
def update_settings(self, key: str, val: any):
2023-04-05 20:31:10 +03:00
if key == "onnxExecutionProvider" and self.onnx_session != None:
if val == "CUDAExecutionProvider":
if self.settings.gpu < 0 or self.settings.gpu >= self.gpu_num:
self.settings.gpu = 0
provider_options = [{'device_id': self.settings.gpu}]
self.onnx_session.set_providers(providers=[val], provider_options=provider_options)
if hasattr(self, "hubert_onnx"):
self.hubert_onnx.set_providers(providers=[val], provider_options=provider_options)
else:
self.onnx_session.set_providers(providers=[val])
if hasattr(self, "hubert_onnx"):
self.hubert_onnx.set_providers(providers=[val])
elif key == "onnxExecutionProvider" and self.onnx_session == None:
print("Onnx is not enabled. Please load model.")
return False
elif key in self.settings.intData:
setattr(self.settings, key, int(val))
if key == "gpu" and val >= 0 and val < self.gpu_num and self.onnx_session != None:
providers = self.onnx_session.get_providers()
print("Providers:", providers)
if "CUDAExecutionProvider" in providers:
provider_options = [{'device_id': self.settings.gpu}]
self.onnx_session.set_providers(providers=["CUDAExecutionProvider"], provider_options=provider_options)
2023-04-21 09:48:12 +03:00
if key == "modelSlotIndex":
2023-04-21 13:20:46 +03:00
# self.switchModel(int(val))
self.tmp_slot = int(val)
self.prepareModel(self.tmp_slot)
self.slot = self.tmp_slot
2023-04-05 20:31:10 +03:00
elif key in self.settings.floatData:
setattr(self.settings, key, float(val))
elif key in self.settings.strData:
setattr(self.settings, key, str(val))
else:
return False
return True
def get_info(self):
data = asdict(self.settings)
data["onnxExecutionProviders"] = self.onnx_session.get_providers() if self.onnx_session != None else []
files = ["configFile", "pyTorchModelFile", "onnxModelFile"]
for f in files:
if data[f] != None and os.path.exists(data[f]):
data[f] = os.path.basename(data[f])
else:
data[f] = ""
return data
def get_processing_sampling_rate(self):
return self.settings.modelSamplingRate
2023-04-05 20:31:10 +03:00
2023-04-14 22:58:56 +03:00
def generate_input(self, newData: any, inputSize: int, crossfadeSize: int, solaSearchFrame: int = 0):
2023-04-14 03:18:34 +03:00
newData = newData.astype(np.float32) / 32768.0
if hasattr(self, "audio_buffer"):
self.audio_buffer = np.concatenate([self.audio_buffer, newData], 0) # 過去のデータに連結
else:
self.audio_buffer = newData
2023-04-14 22:58:56 +03:00
convertSize = inputSize + crossfadeSize + solaSearchFrame + self.settings.extraConvertSize
2023-04-14 03:18:34 +03:00
if convertSize % 128 != 0: # モデルの出力のホップサイズで切り捨てが発生するので補う。
convertSize = convertSize + (128 - (convertSize % 128))
self.audio_buffer = self.audio_buffer[-1 * convertSize:] # 変換対象の部分だけ抽出
crop = self.audio_buffer[-1 * (inputSize + crossfadeSize):-1 * (crossfadeSize)] # 出力部分だけ切り出して音量を確認。(solaとの関係性について、現状は無考慮)
rms = np.sqrt(np.square(crop).mean(axis=0))
vol = max(rms, self.prevVol * 0.0)
self.prevVol = vol
2023-04-05 20:31:10 +03:00
return (self.audio_buffer, convertSize, vol)
def _onnx_inference(self, data):
2023-04-07 21:11:37 +03:00
if hasattr(self, "onnx_session") == False or self.onnx_session == None:
print("[Voice Changer] No onnx session.")
2023-04-17 03:45:12 +03:00
raise NoModeLoadedException("ONNX")
2023-04-07 21:11:37 +03:00
if self.settings.gpu < 0 or self.gpu_num == 0:
dev = torch.device("cpu")
else:
dev = torch.device("cuda", index=self.settings.gpu)
self.hubert_model = self.hubert_model.to(dev)
audio = data[0]
convertSize = data[1]
vol = data[2]
audio = resampy.resample(audio, self.settings.modelSamplingRate, 16000)
2023-04-07 21:11:37 +03:00
if vol < self.settings.silentThreshold:
return np.zeros(convertSize).astype(np.int16)
with torch.no_grad():
2023-04-07 23:34:26 +03:00
repeat = 3 if self.is_half else 1
repeat *= self.settings.rvcQuality # 0 or 3
vc = VC(self.settings.modelSamplingRate, dev, self.is_half, repeat)
2023-04-07 21:11:37 +03:00
sid = 0
times = [0, 0, 0]
f0_up_key = self.settings.tran
2023-04-18 05:53:44 +03:00
f0_method = self.settings.f0Detector
2023-04-07 21:11:37 +03:00
file_index = self.index_file if self.index_file != None else ""
file_big_npy = self.feature_file if self.feature_file != None else ""
index_rate = self.settings.indexRatio
if_f0 = 1
f0_file = None
audio_out = vc.pipeline(self.hubert_model, self.onnx_session, sid, audio, times, f0_up_key, f0_method,
file_index, file_big_npy, index_rate, if_f0, f0_file=f0_file)
result = audio_out * np.sqrt(vol)
return result
2023-04-05 20:31:10 +03:00
def _pyTorch_inference(self, data):
if hasattr(self, "net_g") == False or self.net_g == None:
print("[Voice Changer] No pyTorch session.")
2023-04-17 03:45:12 +03:00
raise NoModeLoadedException("pytorch")
2023-04-05 20:31:10 +03:00
2023-04-17 21:06:31 +03:00
if self.settings.gpu < 0 or (self.gpu_num == 0 and self.mps_enabled == False):
2023-04-05 20:31:10 +03:00
dev = torch.device("cpu")
2023-04-17 21:06:31 +03:00
elif self.mps_enabled:
dev = torch.device("mps")
2023-04-05 20:31:10 +03:00
else:
dev = torch.device("cuda", index=self.settings.gpu)
2023-04-17 22:32:43 +03:00
# print("device:", dev)
2023-04-17 21:06:31 +03:00
2023-04-07 21:11:37 +03:00
self.hubert_model = self.hubert_model.to(dev)
2023-04-21 23:42:24 +03:00
self.net_g = self.net_g.to(dev)
2023-04-07 21:11:37 +03:00
2023-04-05 20:31:10 +03:00
audio = data[0]
convertSize = data[1]
vol = data[2]
audio = resampy.resample(audio, self.settings.modelSamplingRate, 16000)
2023-04-05 20:31:10 +03:00
if vol < self.settings.silentThreshold:
return np.zeros(convertSize).astype(np.int16)
with torch.no_grad():
repeat = 3 if self.is_half else 1
repeat *= self.settings.rvcQuality # 0 or 3
vc = VC(self.settings.modelSamplingRate, dev, self.is_half, repeat)
2023-04-05 20:31:10 +03:00
sid = 0
times = [0, 0, 0]
2023-04-05 21:07:45 +03:00
f0_up_key = self.settings.tran
2023-04-18 06:00:49 +03:00
f0_method = self.settings.f0Detector
2023-04-07 21:11:37 +03:00
file_index = self.index_file if self.index_file != None else ""
file_big_npy = self.feature_file if self.feature_file != None else ""
index_rate = self.settings.indexRatio
2023-04-05 20:31:10 +03:00
if_f0 = 1
f0_file = None
2023-04-23 00:19:48 +03:00
modelType = self.settings.modelSlots[self.currentSlot].modelType
audio_out = vc.pipeline(self.hubert_model, self.net_g, sid, audio, times, f0_up_key, f0_method,
file_index, file_big_npy, index_rate, if_f0, f0_file=f0_file, silence_front=self.settings.extraConvertSize / self.settings.modelSamplingRate, modelType=modelType)
2023-04-19 01:57:19 +03:00
2023-04-05 21:07:45 +03:00
result = audio_out * np.sqrt(vol)
2023-04-05 20:49:16 +03:00
2023-04-05 20:31:10 +03:00
return result
def inference(self, data):
2023-04-22 23:09:19 +03:00
if hasattr(self, "slot") == False:
print("[Voice Changer] No model uploaded.")
raise NoModeLoadedException("model_common")
2023-04-22 01:57:51 +03:00
if self.currentSlot != self.slot:
self.currentSlot = self.slot
self.switchModel()
2023-04-21 13:20:46 +03:00
2023-04-22 01:57:51 +03:00
if self.settings.framework == "ONNX":
audio = self._onnx_inference(data)
else:
audio = self._pyTorch_inference(data)
2023-04-21 23:42:24 +03:00
2023-04-22 01:57:51 +03:00
return audio
2023-04-05 20:31:10 +03:00
2023-04-10 18:21:17 +03:00
def __del__(self):
2023-04-05 20:31:10 +03:00
del self.net_g
del self.onnx_session
2023-04-10 18:21:17 +03:00
remove_path = os.path.join("RVC")
sys.path = [x for x in sys.path if x.endswith(remove_path) == False]
for key in list(sys.modules):
val = sys.modules.get(key)
try:
file_path = val.__file__
2023-04-11 01:37:39 +03:00
if file_path.find("RVC" + os.path.sep) >= 0:
2023-04-10 18:21:17 +03:00
print("remove", key, file_path)
sys.modules.pop(key)
except Exception as e:
pass
2023-04-13 02:00:28 +03:00
def export2onnx(self):
if hasattr(self, "net_g") == False or self.net_g == None:
print("[Voice Changer] export2onnx, No pyTorch session.")
return {"status": "ng", "path": f""}
2023-04-22 09:12:10 +03:00
2023-04-22 10:19:21 +03:00
pyTorchModelFile = self.settings.modelSlots[self.slot].pyTorchModelFile # inference前にexportできるようにcurrentSlotではなくslot
2023-04-22 09:12:10 +03:00
if pyTorchModelFile == None:
2023-04-13 02:00:28 +03:00
print("[Voice Changer] export2onnx, No pyTorch filepath.")
return {"status": "ng", "path": f""}
import voice_changer.RVC.export2onnx as onnxExporter
2023-04-22 09:12:10 +03:00
output_file = os.path.splitext(os.path.basename(pyTorchModelFile))[0] + ".onnx"
output_file_simple = os.path.splitext(os.path.basename(pyTorchModelFile))[0] + "_simple.onnx"
2023-04-13 02:00:28 +03:00
output_path = os.path.join(TMP_DIR, output_file)
output_path_simple = os.path.join(TMP_DIR, output_file_simple)
2023-04-14 09:48:38 +03:00
if torch.cuda.device_count() > 0:
2023-04-22 09:12:10 +03:00
onnxExporter.export2onnx(pyTorchModelFile, output_path, output_path_simple, True)
2023-04-14 09:48:38 +03:00
else:
print("[Voice Changer] Warning!!! onnx export with float32. maybe size is doubled.")
2023-04-22 09:12:10 +03:00
onnxExporter.export2onnx(pyTorchModelFile, output_path, output_path_simple, False)
2023-04-14 09:48:38 +03:00
2023-04-13 02:00:28 +03:00
return {"status": "ok", "path": f"/tmp/{output_file_simple}", "filename": output_file_simple}