add half-precision select to rvc

This commit is contained in:
wataru 2023-04-08 03:56:40 +09:00
parent 04b9bb1ac3
commit 60bffb61a5
12 changed files with 81 additions and 25 deletions

View File

@ -42,7 +42,7 @@
"showFeature": true,
"showIndex": true,
"showHalfPrecision": true,
"defaultEnablePyTorch": true
}
},

File diff suppressed because one or more lines are too long

View File

@ -42,7 +42,7 @@
"showFeature": true,
"showIndex": true,
"showHalfPrecision": true,
"defaultEnablePyTorch": true
}
},

View File

@ -0,0 +1,31 @@
import React, { useMemo } from "react"
import { fileSelector } from "@dannadori/voice-changer-client-js"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export const HalfPrecisionRow = () => {
const appState = useAppState()
const halfPrecisionSelectRow = useMemo(() => {
const onHalfPrecisionChanged = () => {
appState.serverSetting.setFileUploadSetting({
...appState.serverSetting.fileUploadSetting,
isHalf: !appState.serverSetting.fileUploadSetting.isHalf
})
}
return (
<div className="body-row split-3-3-4 left-padding-1 guided">
<div className="body-item-title left-padding-2">-</div>
<div className="body-item-text">
<div></div>
</div>
<div className="body-button-container">
<input type="checkbox" checked={appState.serverSetting.fileUploadSetting.isHalf} onChange={() => onHalfPrecisionChanged()} /> half-precision
</div>
</div>
)
}, [appState.serverSetting.fileUploadSetting, appState.serverSetting.setFileUploadSetting])
return halfPrecisionSelectRow
}

View File

@ -7,6 +7,7 @@ import { CorrespondenceSelectRow } from "./301-4_CorrespondenceSelectRow"
import { PyTorchClusterSelectRow } from "./301-5_PyTorchClusterSelectRow"
import { FeatureSelectRow } from "./301-6_FeatureSelectRow"
import { IndexSelectRow } from "./301-7_IndexSelectRow"
import { HalfPrecisionRow } from "./301-8_HalfPrescisionRow"
import { ModelUploadButtonRow } from "./301-9_ModelUploadButtonRow"
export type ModelUploaderRowProps = {
@ -18,6 +19,7 @@ export type ModelUploaderRowProps = {
showFeature: boolean
showIndex: boolean
showHalfPrecision: boolean
defaultEnablePyTorch: boolean
}
@ -47,6 +49,7 @@ export const ModelUploaderRow = (props: ModelUploaderRowProps) => {
{props.showConfig ? <ConfigSelectRow /> : <></>}
{props.showOnnx ? <ONNXSelectRow /> : <></>}
{props.showPyTorch && guiState.showPyTorchModelUpload ? <PyTorchSelectRow /> : <></>}
{props.showHalfPrecision ? <HalfPrecisionRow /> : <></>}
{props.showCorrespondence ? <CorrespondenceSelectRow /> : <></>}
{props.showPyTorchCluster ? <PyTorchClusterSelectRow /> : <></>}
{props.showFeature ? <FeatureSelectRow /> : <></>}

View File

@ -110,7 +110,7 @@ export class ServerConfigurator {
}
// !! 注意!! hubertTorchModelは固定値で上書きされるため、設定しても効果ない。
loadModel = async (configFilename: string, pyTorchModelFilename: string | null, onnxModelFilename: string | null, clusterTorchModelFilename: string | null, featureFilename: string | null, indexFilename: string | null) => {
loadModel = async (configFilename: string, pyTorchModelFilename: string | null, onnxModelFilename: string | null, clusterTorchModelFilename: string | null, featureFilename: string | null, indexFilename: string | null, isHalf: boolean) => {
const url = this.serverUrl + "/load_model"
const info = new Promise<ServerInfo>(async (resolve) => {
const formData = new FormData();
@ -120,6 +120,7 @@ export class ServerConfigurator {
formData.append("clusterTorchModelFilename", clusterTorchModelFilename || "-");
formData.append("featureFilename", featureFilename || "-");
formData.append("indexFilename", indexFilename || "-");
formData.append("isHalf", "" + isHalf);
const request = new Request(url, {
method: 'POST',

View File

@ -264,9 +264,10 @@ export class VoiceChangerClient {
clusterTorchModelFilename: string | null,
featureFilename: string | null,
indexFilename: string | null,
isHalf: boolean
) => {
// !! 注意!! hubertTorchModelは固定値で上書きされるため、設定しても効果ない。
return this.configurator.loadModel(configFilename, pyTorchModelFilename, onnxModelFilename, clusterTorchModelFilename, featureFilename, indexFilename)
return this.configurator.loadModel(configFilename, pyTorchModelFilename, onnxModelFilename, clusterTorchModelFilename, featureFilename, indexFilename, isHalf)
}
//## Worklet ##//

View File

@ -20,6 +20,8 @@ export type FileUploadSetting = {
feature: ModelData | null //RVC
index: ModelData | null //RVC
isHalf: boolean
}
const InitialFileUploadSetting: FileUploadSetting = {
@ -30,7 +32,9 @@ const InitialFileUploadSetting: FileUploadSetting = {
hubertTorchModel: null,
feature: null,
index: null
index: null,
isHalf: true
}
export type UseServerSettingProps = {
@ -234,13 +238,16 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
// !! 注意!! hubertTorchModelは固定値で上書きされるため、設定しても効果ない。
const configFileName = fileUploadSetting.configFile ? fileUploadSetting.configFile.filename || "-" : "-"
console.log("IS HALF", fileUploadSetting.isHalf)
const loadPromise = props.voiceChangerClient.loadModel(
configFileName,
fileUploadSetting.pyTorchModel?.filename || null,
fileUploadSetting.onnxModel?.filename || null,
fileUploadSetting.clusterTorchModel?.filename || null,
fileUploadSetting.feature?.filename || null,
fileUploadSetting.index?.filename || null
fileUploadSetting.index?.filename || null,
fileUploadSetting.isHalf
)
// サーバでロード中にキャッシュにセーブ
@ -260,7 +267,8 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
} : null,
index: fileUploadSetting.index ? {
data: fileUploadSetting.index.data, filename: fileUploadSetting.index.filename
} : null
} : null,
isHalf: fileUploadSetting.isHalf
}
setItem(INDEXEDDB_KEY_MODEL_DATA, saveData)

View File

@ -57,6 +57,7 @@ class MMVC_Rest_Fileuploader:
clusterTorchModelFilename: str = Form(...),
featureFilename: str = Form(...),
indexFilename: str = Form(...),
isHalf: bool = Form(...),
):
pyTorchModelFilePath = os.path.join(UPLOAD_DIR, pyTorchModelFilename) if pyTorchModelFilename != "-" else None
onnxModelFilePath = os.path.join(UPLOAD_DIR, onnxModelFilename) if onnxModelFilename != "-" else None
@ -66,7 +67,8 @@ class MMVC_Rest_Fileuploader:
indexFilePath = os.path.join(UPLOAD_DIR, indexFilename) if indexFilename != "-" else None
info = self.voiceChangerManager.loadModel(configFilePath, pyTorchModelFilePath, onnxModelFilePath,
clusterTorchModelFilePath, featureFilePath, indexFilePath)
clusterTorchModelFilePath, featureFilePath, indexFilePath,
isHalf)
json_compatible_item_data = jsonable_encoder(info)
return JSONResponse(content=json_compatible_item_data)
# return {"load": f"{configFilePath}, {pyTorchModelFilePath}, {onnxModelFilePath}"}

View File

@ -52,14 +52,14 @@ class RVCSettings():
configFile: str = ""
indexRatio: float = 0
isHalf: int = 0
quality: int = 0
speakers: dict[str, int] = field(
default_factory=lambda: {}
)
# ↓mutableな物だけ列挙
intData = ["gpu", "dstId", "tran", "predictF0", "extraConvertSize"]
intData = ["gpu", "dstId", "tran", "predictF0", "extraConvertSize", "quality"]
floatData = ["noiceScale", "silentThreshold", "indexRatio"]
strData = ["framework", "f0Detector"]
@ -76,12 +76,11 @@ class RVC:
self.params = params
print("RVC initialization: ", params)
def loadModel(self, config: str, pyTorch_model_file: str = None, onnx_model_file: str = None, feature_file: str = None, index_file: str = None):
def loadModel(self, config: str, pyTorch_model_file: str = None, onnx_model_file: str = None, feature_file: str = None, index_file: str = None, is_half: bool = True):
self.settings.configFile = config
self.feature_file = feature_file
self.index_file = index_file
print("featurefile", feature_file, index_file)
self.is_half = is_half
self.tgt_sr = 40000
try:
@ -89,7 +88,7 @@ class RVC:
models, saved_cfg, task = checkpoint_utils.load_model_ensemble_and_task([hubert_path], suffix="",)
model = models[0]
model.eval()
if self.settings.isHalf:
if self.is_half:
model = model.half()
self.hubert_model = model
@ -105,17 +104,17 @@ class RVC:
if pyTorch_model_file != None:
cpt = torch.load(pyTorch_model_file, map_location="cpu")
self.tgt_sr = cpt["config"][-1]
net_g = SynthesizerTrnMs256NSFsid(*cpt["config"], is_half=self.settings.isHalf)
net_g = SynthesizerTrnMs256NSFsid(*cpt["config"], is_half=self.is_half)
net_g.eval()
net_g.load_state_dict(cpt["weight"], strict=False)
if self.settings.isHalf:
if self.is_half:
net_g = net_g.half()
self.net_g = net_g
# ONNXモデル生成
if onnx_model_file != None:
# self.onnx_session = ModelWrapper(onnx_model_file, is_half=True)
self.onnx_session = ModelWrapper(onnx_model_file, is_half=self.settings.isHalf)
self.onnx_session = ModelWrapper(onnx_model_file, is_half=self.is_half)
# input_info = self.onnx_session.get_inputs()
# for i in input_info:
# print("input", i)
@ -222,7 +221,7 @@ class RVC:
return np.zeros(convertSize).astype(np.int16)
with torch.no_grad():
vc = VC(self.tgt_sr, dev, self.settings.isHalf)
vc = VC(self.tgt_sr, dev, self.is_half)
sid = 0
times = [0, 0, 0]
f0_up_key = self.settings.tran
@ -263,7 +262,7 @@ class RVC:
return np.zeros(convertSize).astype(np.int16)
with torch.no_grad():
vc = VC(self.tgt_sr, dev, self.settings.isHalf)
vc = VC(self.tgt_sr, dev, self.is_half)
sid = 0
times = [0, 0, 0]
f0_up_key = self.settings.tran

View File

@ -77,13 +77,13 @@ class VoiceChanger():
print(f"VoiceChanger Initialized (GPU_NUM:{self.gpu_num}, mps_enabled:{self.mps_enabled})")
def loadModel(self, config: str, pyTorch_model_file: str = None, onnx_model_file: str = None, clusterTorchModel: str = None, feature_file: str = None, index_file: str = None):
def loadModel(self, config: str, pyTorch_model_file: str = None, onnx_model_file: str = None, clusterTorchModel: str = None, feature_file: str = None, index_file: str = None, is_half: bool = True):
if self.modelType == "MMVCv15" or self.modelType == "MMVCv13":
return self.voiceChanger.loadModel(config, pyTorch_model_file, onnx_model_file)
elif self.modelType == "so-vits-svc-40" or self.modelType == "so-vits-svc-40_c" or self.modelType == "so-vits-svc-40v2":
return self.voiceChanger.loadModel(config, pyTorch_model_file, onnx_model_file, clusterTorchModel)
elif self.modelType == "RVC":
return self.voiceChanger.loadModel(config, pyTorch_model_file, onnx_model_file, feature_file, index_file)
return self.voiceChanger.loadModel(config, pyTorch_model_file, onnx_model_file, feature_file, index_file, is_half)
else:
return self.voiceChanger.loadModel(config, pyTorch_model_file, onnx_model_file, clusterTorchModel)

View File

@ -10,8 +10,8 @@ class VoiceChangerManager():
cls._instance.voiceChanger = VoiceChanger(params)
return cls._instance
def loadModel(self, config, model, onnx_model, clusterTorchModel, feature_file, index_file):
info = self.voiceChanger.loadModel(config, model, onnx_model, clusterTorchModel, feature_file, index_file)
def loadModel(self, config, model, onnx_model, clusterTorchModel, feature_file, index_file, is_half: bool = True):
info = self.voiceChanger.loadModel(config, model, onnx_model, clusterTorchModel, feature_file, index_file, is_half)
info["status"] = "OK"
return info