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, "showFeature": true,
"showIndex": true, "showIndex": true,
"showHalfPrecision": true,
"defaultEnablePyTorch": true "defaultEnablePyTorch": true
} }
}, },

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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