WIP: support so-vits-svc 40v2. change policy to load hubert model from local.

This commit is contained in:
wataru 2023-03-14 09:57:52 +09:00
parent 76ddef5ee1
commit 1f33cd547d
10 changed files with 62 additions and 52 deletions

File diff suppressed because one or more lines are too long

View File

@ -65,26 +65,26 @@ export const useModelSettingArea = (): ServerSettingState => {
}) })
} }
const onHubertFileLoadClicked = async () => { // const onHubertFileLoadClicked = async () => {
const file = await fileSelector("") // const file = await fileSelector("")
if (file.name.endsWith(".pth") == false) { // if (file.name.endsWith(".pth") == false) {
alert("モデルファイルの拡張子はpthである必要があります。") // alert("モデルファイルの拡張子はpthである必要があります。")
return // return
} // }
appState.serverSetting.setFileUploadSetting({ // appState.serverSetting.setFileUploadSetting({
...appState.serverSetting.fileUploadSetting, // ...appState.serverSetting.fileUploadSetting,
hubertTorchModel: { // hubertTorchModel: {
file: file // file: file
} // }
}) // })
} // }
const onHubertFileClearClicked = () => { // const onHubertFileClearClicked = () => {
appState.serverSetting.setFileUploadSetting({ // appState.serverSetting.setFileUploadSetting({
...appState.serverSetting.fileUploadSetting, // ...appState.serverSetting.fileUploadSetting,
hubertTorchModel: null // hubertTorchModel: null
}) // })
} // }
const onClusterFileLoadClicked = async () => { const onClusterFileLoadClicked = async () => {
const file = await fileSelector("") const file = await fileSelector("")
@ -135,7 +135,7 @@ export const useModelSettingArea = (): ServerSettingState => {
const uploadButtonLabel = appState.serverSetting.isUploading ? "wait..." : "upload" const uploadButtonLabel = appState.serverSetting.isUploading ? "wait..." : "upload"
const configFilenameText = appState.serverSetting.fileUploadSetting.configFile?.filename || appState.serverSetting.fileUploadSetting.configFile?.file?.name || "" const configFilenameText = appState.serverSetting.fileUploadSetting.configFile?.filename || appState.serverSetting.fileUploadSetting.configFile?.file?.name || ""
const hubertModelFilenameText = appState.serverSetting.fileUploadSetting.hubertTorchModel?.filename || appState.serverSetting.fileUploadSetting.hubertTorchModel?.file?.name || "" // const hubertModelFilenameText = appState.serverSetting.fileUploadSetting.hubertTorchModel?.filename || appState.serverSetting.fileUploadSetting.hubertTorchModel?.file?.name || ""
const clusterModelFilenameText = appState.serverSetting.fileUploadSetting.clusterTorchModel?.filename || appState.serverSetting.fileUploadSetting.clusterTorchModel?.file?.name || "" const clusterModelFilenameText = appState.serverSetting.fileUploadSetting.clusterTorchModel?.filename || appState.serverSetting.fileUploadSetting.clusterTorchModel?.file?.name || ""
// const onnxModelFilenameText = appState.serverSetting.fileUploadSetting.onnxModel?.filename || appState.serverSetting.fileUploadSetting.onnxModel?.file?.name || "" // const onnxModelFilenameText = appState.serverSetting.fileUploadSetting.onnxModel?.filename || appState.serverSetting.fileUploadSetting.onnxModel?.file?.name || ""
@ -170,7 +170,7 @@ export const useModelSettingArea = (): ServerSettingState => {
<div className="body-button left-margin-1" onClick={onConfigFileClearClicked}>clear</div> <div className="body-button left-margin-1" onClick={onConfigFileClearClicked}>clear</div>
</div> </div>
</div> </div>
<div className="body-row split-3-3-4 left-padding-1 guided"> {/* <div className="body-row split-3-3-4 left-padding-1 guided">
<div className="body-item-title left-padding-2">hubert(.pth)</div> <div className="body-item-title left-padding-2">hubert(.pth)</div>
<div className="body-item-text"> <div className="body-item-text">
<div>{hubertModelFilenameText}</div> <div>{hubertModelFilenameText}</div>
@ -179,7 +179,7 @@ export const useModelSettingArea = (): ServerSettingState => {
<div className="body-button" onClick={onHubertFileLoadClicked}>select</div> <div className="body-button" onClick={onHubertFileLoadClicked}>select</div>
<div className="body-button left-margin-1" onClick={onHubertFileClearClicked}>clear</div> <div className="body-button left-margin-1" onClick={onHubertFileClearClicked}>clear</div>
</div> </div>
</div> </div> */}
<div className="body-row split-3-3-4 left-padding-1 guided"> <div className="body-row split-3-3-4 left-padding-1 guided">
<div className="body-item-title left-padding-2">cluster(.pth)</div> <div className="body-item-title left-padding-2">cluster(.pth)</div>
<div className="body-item-text"> <div className="body-item-text">

View File

@ -109,16 +109,16 @@ export class ServerConfigurator {
}) })
} }
loadModel = async (configFilename: string, pyTorchModelFilename: string | null, onnxModelFilename: string | null, hubertTorchModelFilename: string | null, clusterTorchModelFilename: string | null) => { // !! 注意!! hubertTorchModelは固定値で上書きされるため、設定しても効果ない。
loadModel = async (configFilename: string, pyTorchModelFilename: string | null, onnxModelFilename: string | null, clusterTorchModelFilename: string | null, hubertTorchModelFilename: string | null) => {
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();
formData.append("pyTorchModelFilename", pyTorchModelFilename || "-"); formData.append("pyTorchModelFilename", pyTorchModelFilename || "-");
formData.append("onnxModelFilename", onnxModelFilename || "-"); formData.append("onnxModelFilename", onnxModelFilename || "-");
formData.append("configFilename", configFilename); formData.append("configFilename", configFilename);
formData.append("hubertTorchModelFilename", hubertTorchModelFilename || "-");
formData.append("clusterTorchModelFilename", clusterTorchModelFilename || "-"); formData.append("clusterTorchModelFilename", clusterTorchModelFilename || "-");
formData.append("hubertTorchModelFilename", hubertTorchModelFilename || "-");
const request = new Request(url, { const request = new Request(url, {
method: 'POST', method: 'POST',

View File

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

View File

@ -14,16 +14,16 @@ export type FileUploadSetting = {
pyTorchModel: ModelData | null pyTorchModel: ModelData | null
onnxModel: ModelData | null onnxModel: ModelData | null
configFile: ModelData | null configFile: ModelData | null
hubertTorchModel: ModelData | null
clusterTorchModel: ModelData | null clusterTorchModel: ModelData | null
hubertTorchModel: ModelData | null // !! 注意!! hubertTorchModelは固定値で上書きされるため、設定しても効果ない。
} }
const InitialFileUploadSetting: FileUploadSetting = { const InitialFileUploadSetting: FileUploadSetting = {
pyTorchModel: null, pyTorchModel: null,
configFile: null, configFile: null,
onnxModel: null, onnxModel: null,
clusterTorchModel: null,
hubertTorchModel: null, hubertTorchModel: null,
clusterTorchModel: null
} }
export type UseServerSettingProps = { export type UseServerSettingProps = {
@ -148,10 +148,11 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
alert("Configファイルを指定する必要があります。") alert("Configファイルを指定する必要があります。")
return return
} }
if (props.clientType == "so_vits_svc_40v2c" && !fileUploadSetting.hubertTorchModel) {
alert("content vecのファイルを指定する必要があります。") // if (props.clientType == "so_vits_svc_40v2c" && !fileUploadSetting.hubertTorchModel) {
return // alert("content vecのファイルを指定する必要があります。")
} // return
// }
if (!props.voiceChangerClient) return if (!props.voiceChangerClient) return
setUploadProgress(0) setUploadProgress(0)
@ -170,16 +171,16 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
fileUploadSetting.configFile.data = await fileUploadSetting.configFile.file!.arrayBuffer() fileUploadSetting.configFile.data = await fileUploadSetting.configFile.file!.arrayBuffer()
fileUploadSetting.configFile.filename = await fileUploadSetting.configFile.file!.name fileUploadSetting.configFile.filename = await fileUploadSetting.configFile.file!.name
} }
if (props.clientType == "so_vits_svc_40v2c" && !fileUploadSetting.hubertTorchModel!.data) { // if (props.clientType == "so_vits_svc_40v2c" && !fileUploadSetting.hubertTorchModel!.data) {
fileUploadSetting.hubertTorchModel!.data = await fileUploadSetting.hubertTorchModel!.file!.arrayBuffer() // fileUploadSetting.hubertTorchModel!.data = await fileUploadSetting.hubertTorchModel!.file!.arrayBuffer()
fileUploadSetting.hubertTorchModel!.filename = await fileUploadSetting.hubertTorchModel!.file!.name // fileUploadSetting.hubertTorchModel!.filename = await fileUploadSetting.hubertTorchModel!.file!.name
} // }
if (props.clientType == "so_vits_svc_40v2c" && !fileUploadSetting.clusterTorchModel!.data) { if (props.clientType == "so_vits_svc_40v2c" && !fileUploadSetting.clusterTorchModel!.data) {
fileUploadSetting.clusterTorchModel!.data = await fileUploadSetting.clusterTorchModel!.file!.arrayBuffer() fileUploadSetting.clusterTorchModel!.data = await fileUploadSetting.clusterTorchModel!.file!.arrayBuffer()
fileUploadSetting.clusterTorchModel!.filename = await fileUploadSetting.clusterTorchModel!.file!.name fileUploadSetting.clusterTorchModel!.filename = await fileUploadSetting.clusterTorchModel!.file!.name
} }
// ファイルをサーバにアップロード // ファイルをサーバにアップロード
const models = [fileUploadSetting.onnxModel, fileUploadSetting.pyTorchModel, fileUploadSetting.hubertTorchModel, fileUploadSetting.clusterTorchModel].filter(x => { return x != null }) as ModelData[] const models = [fileUploadSetting.onnxModel, fileUploadSetting.pyTorchModel, fileUploadSetting.clusterTorchModel /*, fileUploadSetting.hubertTorchModel*/].filter(x => { return x != null }) as ModelData[]
for (let i = 0; i < models.length; i++) { for (let i = 0; i < models.length; i++) {
const progRate = 1 / models.length const progRate = 1 / models.length
const progOffset = 100 * i * progRate const progOffset = 100 * i * progRate
@ -193,7 +194,8 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
console.log(progress, end) console.log(progress, end)
}) })
const loadPromise = props.voiceChangerClient.loadModel(fileUploadSetting.configFile.filename!, fileUploadSetting.pyTorchModel?.filename || null, fileUploadSetting.onnxModel?.filename || null, fileUploadSetting.hubertTorchModel?.filename || null, fileUploadSetting.clusterTorchModel?.filename || null) // !! 注意!! hubertTorchModelは固定値で上書きされるため、設定しても効果ない。
const loadPromise = props.voiceChangerClient.loadModel(fileUploadSetting.configFile.filename!, fileUploadSetting.pyTorchModel?.filename || null, fileUploadSetting.onnxModel?.filename || null, fileUploadSetting.clusterTorchModel?.filename || null, fileUploadSetting.hubertTorchModel?.filename || null)
// サーバでロード中にキャッシュにセーブ // サーバでロード中にキャッシュにセーブ
try { try {

View File

@ -39,8 +39,8 @@ def setupArgParser():
default=False, help="run on colab") default=False, help="run on colab")
parser.add_argument("--modelType", type=str, parser.add_argument("--modelType", type=str,
default="MMVCv15", help="model type: MMVCv13, MMVCv15, so-vits-svc-40v2") default="MMVCv15", help="model type: MMVCv13, MMVCv15, so-vits-svc-40v2")
parser.add_argument("--hubert", type=str, help="path to hubert model")
parser.add_argument("--cluster", type=str, help="path to cluster model") parser.add_argument("--cluster", type=str, help="path to cluster model")
parser.add_argument("--hubert", type=str, help="path to hubert model, 現バージョンではhubertTorchModelは固定値で上書きされるため、設定しても効果ない。")
return parser return parser
@ -107,7 +107,8 @@ if CONFIG and (MODEL or ONNX_MODEL):
if MODEL_TYPE == "MMVCv15" or MODEL_TYPE == "MMVCv13": if MODEL_TYPE == "MMVCv15" or MODEL_TYPE == "MMVCv13":
voiceChangerManager.loadModel(CONFIG, MODEL, ONNX_MODEL, None, None) voiceChangerManager.loadModel(CONFIG, MODEL, ONNX_MODEL, None, None)
else: else:
voiceChangerManager.loadModel(CONFIG, MODEL, ONNX_MODEL, HUBERT_MODEL, CLUSTER_MODEL) # !! 注意 !! hubertTorchModelは固定値で上書きされるため、設定しても効果ない。
voiceChangerManager.loadModel(CONFIG, MODEL, ONNX_MODEL, CLUSTER_MODEL, HUBERT_MODEL)
app_fastapi = MMVC_Rest.get_instance(voiceChangerManager) app_fastapi = MMVC_Rest.get_instance(voiceChangerManager)
app_socketio = MMVC_SocketIOApp.get_instance(app_fastapi, voiceChangerManager) app_socketio = MMVC_SocketIOApp.get_instance(app_fastapi, voiceChangerManager)

View File

@ -54,18 +54,19 @@ class MMVC_Rest_Fileuploader:
pyTorchModelFilename: str = Form(...), pyTorchModelFilename: str = Form(...),
onnxModelFilename: str = Form(...), onnxModelFilename: str = Form(...),
configFilename: str = Form(...), configFilename: str = Form(...),
clusterTorchModelFilename: str = Form(...),
hubertTorchModelFilename: str = Form(...), hubertTorchModelFilename: str = Form(...),
clusterTorchModelFilename: str = Form(...)
): ):
print("Hubert:", hubertTorchModelFilename) print("Hubert:", hubertTorchModelFilename)
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
configFilePath = os.path.join(UPLOAD_DIR, configFilename) configFilePath = os.path.join(UPLOAD_DIR, configFilename)
hubertTorchModelFilePath = os.path.join(UPLOAD_DIR, hubertTorchModelFilename) if hubertTorchModelFilename != "-" else None
clusterTorchModelFilePath = os.path.join(UPLOAD_DIR, clusterTorchModelFilename) if clusterTorchModelFilename != "-" else None clusterTorchModelFilePath = os.path.join(UPLOAD_DIR, clusterTorchModelFilename) if clusterTorchModelFilename != "-" else None
hubertTorchModelFilePath = os.path.join(UPLOAD_DIR, hubertTorchModelFilename) if hubertTorchModelFilename != "-" else None
# !! 注意 !! hubertTorchModelは固定値で上書きされるため、設定しても効果ない。
info = self.voiceChangerManager.loadModel(configFilePath, pyTorchModelFilePath, onnxModelFilePath, info = self.voiceChangerManager.loadModel(configFilePath, pyTorchModelFilePath, onnxModelFilePath,
hubertTorchModelFilePath, clusterTorchModelFilePath) clusterTorchModelFilePath, hubertTorchModelFilePath)
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

@ -60,13 +60,16 @@ class SoVitsSvc40v2:
self.gpu_num = torch.cuda.device_count() self.gpu_num = torch.cuda.device_count()
self.prevVol = 0 self.prevVol = 0
def loadModel(self, config: str, pyTorch_model_file: str = None, onnx_model_file: str = None, hubertTorchModel: str = None, clusterTorchModel: str = None): def loadModel(self, config: str, pyTorch_model_file: str = None, onnx_model_file: str = None, clusterTorchModel: str = None, hubertTorchModel: str = None):
# !! 注意 !! hubertTorchModelは固定値で上書きされるため、設定しても効果ない。
self.settings.configFile = config self.settings.configFile = config
self.hps = utils.get_hparams_from_file(config) self.hps = utils.get_hparams_from_file(config)
# hubert model # hubert model
try: try:
vec_path = hubertTorchModel # vec_path = hubertTorchModel
vec_path = "hubert/checkpoint_best_legacy_500.pt"
print("hubert 1 ", hubertTorchModel) print("hubert 1 ", hubertTorchModel)
models, saved_cfg, task = checkpoint_utils.load_model_ensemble_and_task( models, saved_cfg, task = checkpoint_utils.load_model_ensemble_and_task(
[vec_path], [vec_path],

View File

@ -70,11 +70,12 @@ 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, hubertTorchModel: str = None, clusterTorchModel: str = None): def loadModel(self, config: str, pyTorch_model_file: str = None, onnx_model_file: str = None, clusterTorchModel: str = None, hubertTorchModel: str = None):
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)
else: # so-vits-svc-40v2 else: # so-vits-svc-40v2
return self.voiceChanger.loadModel(config, pyTorch_model_file, onnx_model_file, hubertTorchModel, clusterTorchModel) # !! 注意 !! hubertTorchModelは固定値で上書きされるため、設定しても効果ない。
return self.voiceChanger.loadModel(config, pyTorch_model_file, onnx_model_file, clusterTorchModel, hubertTorchModel)
def get_info(self): def get_info(self):
data = asdict(self.settings) data = asdict(self.settings)

View File

@ -10,8 +10,9 @@ class VoiceChangerManager():
cls._instance.voiceChanger = VoiceChanger() cls._instance.voiceChanger = VoiceChanger()
return cls._instance return cls._instance
def loadModel(self, config, model, onnx_model, hubertTorchModel, clusterTorchModel): def loadModel(self, config, model, onnx_model, clusterTorchModel, hubertTorchModel):
info = self.voiceChanger.loadModel(config, model, onnx_model, hubertTorchModel, clusterTorchModel) # !! 注意 !! hubertTorchModelは固定値で上書きされるため、設定しても効果ない。
info = self.voiceChanger.loadModel(config, model, onnx_model, clusterTorchModel, hubertTorchModel)
info["status"] = "OK" info["status"] = "OK"
return info return info