get pipeline info

This commit is contained in:
wataru 2023-05-31 14:30:35 +09:00
parent c2efe5cba1
commit 9818f6ec42
35 changed files with 1959 additions and 135 deletions

View File

@ -0,0 +1 @@
+

View File

@ -1 +1,10 @@
<!doctype html><html style="width:100%;height:100%;overflow:hidden"><head><meta charset="utf-8"/><title>Voice Changer Client Demo</title><script defer="defer" src="index.js"></script></head><body style="width:100%;height:100%;margin:0"><div id="app" style="width:100%;height:100%"></div></body></html> <!DOCTYPE html>
<html style="width: 100%; height: 100%; overflow: hidden">
<head>
<meta charset="utf-8" />
<title>Voice Changer Client Demo</title>
<script defer src="index.js"></script></head>
<body style="width: 100%; height: 100%; margin: 0px">
<div id="app" style="width: 100%; height: 100%"></div>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,31 +0,0 @@
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
/**
* @license React
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

View File

@ -0,0 +1 @@
+

View File

@ -10,8 +10,8 @@ import { far } from "@fortawesome/free-regular-svg-icons";
import { fab } from "@fortawesome/free-brands-svg-icons"; import { fab } from "@fortawesome/free-brands-svg-icons";
import { AppRootProvider, useAppRoot } from "./001_provider/001_AppRootProvider"; import { AppRootProvider, useAppRoot } from "./001_provider/001_AppRootProvider";
import ErrorBoundary from "./001_provider/900_ErrorBoundary"; import ErrorBoundary from "./001_provider/900_ErrorBoundary";
import { ClientType, INDEXEDDB_KEY_CLIENT, INDEXEDDB_KEY_MODEL_DATA, INDEXEDDB_KEY_SERVER, INDEXEDDB_KEY_WORKLET, INDEXEDDB_KEY_WORKLETNODE, MAX_MODEL_SLOT_NUM, useIndexedDB } from "@dannadori/voice-changer-client-js"; import { ClientType, useIndexedDB } from "@dannadori/voice-changer-client-js";
import { INDEXEDDB_KEY_AUDIO_OUTPUT, INDEXEDDB_KEY_DEFAULT_MODEL_TYPE } from "./const"; import { INDEXEDDB_KEY_DEFAULT_MODEL_TYPE } from "./const";
import { Demo } from "./components/demo/010_Demo"; import { Demo } from "./components/demo/010_Demo";
import { ClientSelector } from "./001_ClientSelector"; import { ClientSelector } from "./001_ClientSelector";
@ -42,7 +42,6 @@ const AppStateWrapper = () => {
const { appGuiSettingState, clientType, setClientType } = useAppRoot() const { appGuiSettingState, clientType, setClientType } = useAppRoot()
// エラーバウンダリー設定 // エラーバウンダリー設定
const [error, setError] = useState<{ error: Error, errorInfo: ErrorInfo }>() const [error, setError] = useState<{ error: Error, errorInfo: ErrorInfo }>()
const { removeItem } = useIndexedDB({ clientType: clientType })
const { getItem, removeDB } = useIndexedDB({ clientType: null }) const { getItem, removeDB } = useIndexedDB({ clientType: null })
const errorComponent = useMemo(() => { const errorComponent = useMemo(() => {
const errorName = error?.error.name || "no error name" const errorName = error?.error.name || "no error name"
@ -52,22 +51,6 @@ const AppStateWrapper = () => {
const onClearCacheClicked = async () => { const onClearCacheClicked = async () => {
await removeDB() await removeDB()
location.reload(); location.reload();
// const indexedDBKeys = [
// INDEXEDDB_KEY_CLIENT,
// INDEXEDDB_KEY_SERVER,
// INDEXEDDB_KEY_WORKLETNODE,
// INDEXEDDB_KEY_WORKLET,
// INDEXEDDB_KEY_AUDIO_OUTPUT
// ]
// for (const k of indexedDBKeys) {
// await removeItem(k)
// }
// for (let i = 0; i < MAX_MODEL_SLOT_NUM; i++) {
// const modleKey = `${INDEXEDDB_KEY_MODEL_DATA}_${i}`
// await removeItem(modleKey)
// }
} }
const onReloadClicked = () => { const onReloadClicked = () => {
location.reload(); location.reload();

View File

@ -19,7 +19,7 @@ export const ClientSelector = () => {
if (ua.indexOf("mac os x") !== -1) { if (ua.indexOf("mac os x") !== -1) {
return ["MMVCv13", "MMVCv15", "so-vits-svc-40", "RVC"] as ClientType[] return ["MMVCv13", "MMVCv15", "so-vits-svc-40", "RVC"] as ClientType[]
} else { } else {
return ["MMVCv13", "MMVCv15", "so-vits-svc-40", "so-vits-svc-40v2", "RVC", "DDSP-SVC"] as ClientType[] return ["MMVCv13", "MMVCv15", "so-vits-svc-40", "DDSP-SVC", "RVC"] as ClientType[]
} }
}, []) }, [])

View File

@ -66,6 +66,7 @@ export type AppGuiSettingState = {
appGuiSetting: AppGuiSetting appGuiSetting: AppGuiSetting
guiSettingLoaded: boolean guiSettingLoaded: boolean
version: string version: string
edition: string
} }
export type AppGuiSettingStateAndMethod = AppGuiSettingState & { export type AppGuiSettingStateAndMethod = AppGuiSettingState & {
@ -77,6 +78,7 @@ export const useAppGuiSetting = (): AppGuiSettingStateAndMethod => {
const [guiSettingLoaded, setGuiSettingLoaded] = useState<boolean>(false) const [guiSettingLoaded, setGuiSettingLoaded] = useState<boolean>(false)
const [appGuiSetting, setAppGuiSetting] = useState<AppGuiSetting>(InitialAppGuiDemoSetting) const [appGuiSetting, setAppGuiSetting] = useState<AppGuiSetting>(InitialAppGuiDemoSetting)
const [version, setVersion] = useState<string>("") const [version, setVersion] = useState<string>("")
const [edition, setEdition] = useState<string>("")
const getAppGuiSetting = async (url: string) => { const getAppGuiSetting = async (url: string) => {
const res = await fetch(`${url}`, { const res = await fetch(`${url}`, {
method: "GET", method: "GET",
@ -101,10 +103,22 @@ export const useAppGuiSetting = (): AppGuiSettingStateAndMethod => {
getVersionInfo() getVersionInfo()
}, []) }, [])
useEffect(() => {
const getVersionInfo = async () => {
const res = await fetch(`/assets/gui_settings/edition.txt`, {
method: "GET",
})
const edition = await res.text()
setEdition(edition)
}
getVersionInfo()
}, [])
return { return {
appGuiSetting, appGuiSetting,
guiSettingLoaded, guiSettingLoaded,
version, version,
edition,
getAppGuiSetting, getAppGuiSetting,
clearAppGuiSetting, clearAppGuiSetting,
} }

View File

@ -140,6 +140,7 @@ export const Title = (props: TitleProps) => {
<span className="title">{props.mainTitle}</span> <span className="title">{props.mainTitle}</span>
<span className="top-title-version">{props.subTitle}</span> <span className="top-title-version">{props.subTitle}</span>
<span className="top-title-version-number">{appRootState.appGuiSettingState.version}</span> <span className="top-title-version-number">{appRootState.appGuiSettingState.version}</span>
<span className="top-title-version-number">{appRootState.appGuiSettingState.edition}</span>
<span className="belongings"> <span className="belongings">
{githubLink} {githubLink}
{manualLink} {manualLink}
@ -152,7 +153,7 @@ export const Title = (props: TitleProps) => {
</div> </div>
) )
} }
}, [props.subTitle, props.mainTitle, props.lineNum, appRootState.appGuiSettingState.version]) }, [props.subTitle, props.mainTitle, props.lineNum, appRootState.appGuiSettingState.version, appRootState.appGuiSettingState.edition])
return titleRow return titleRow
}; };

View File

@ -328,23 +328,23 @@ export const DefaultServerSetting_MMVCv13: ServerInfo = {
} }
export const DefaultServerSetting_so_vits_svc_40: ServerInfo = { export const DefaultServerSetting_so_vits_svc_40: ServerInfo = {
...DefaultServerSetting, tran: 10, noiseScale: 0.3, extraConvertSize: 1024 * 32, clusterInferRatio: 0.1, ...DefaultServerSetting, tran: 10, noiseScale: 0.3, extraConvertSize: 1024 * 8, clusterInferRatio: 0.1,
} }
export const DefaultServerSetting_so_vits_svc_40_c: ServerInfo = { export const DefaultServerSetting_so_vits_svc_40_c: ServerInfo = {
...DefaultServerSetting, tran: 10, noiseScale: 0.3, extraConvertSize: 1024 * 32, clusterInferRatio: 0.1, ...DefaultServerSetting, tran: 10, noiseScale: 0.3, extraConvertSize: 1024 * 8, clusterInferRatio: 0.1,
} }
export const DefaultServerSetting_so_vits_svc_40v2: ServerInfo = { export const DefaultServerSetting_so_vits_svc_40v2: ServerInfo = {
...DefaultServerSetting, tran: 10, noiseScale: 0.3, extraConvertSize: 1024 * 32, clusterInferRatio: 0.1, ...DefaultServerSetting, tran: 10, noiseScale: 0.3, extraConvertSize: 1024 * 8, clusterInferRatio: 0.1,
} }
export const DefaultServerSetting_DDSP_SVC: ServerInfo = { export const DefaultServerSetting_DDSP_SVC: ServerInfo = {
...DefaultServerSetting, dstId: 1, tran: 10, extraConvertSize: 1024 * 32 ...DefaultServerSetting, dstId: 1, tran: 10, extraConvertSize: 1024 * 8
} }
export const DefaultServerSetting_RVC: ServerInfo = { export const DefaultServerSetting_RVC: ServerInfo = {
...DefaultServerSetting, tran: 10, extraConvertSize: 1024 * 32, f0Detector: F0Detector.harvest ...DefaultServerSetting, tran: 10, extraConvertSize: 1024 * 8, f0Detector: F0Detector.harvest
} }
/////////////////////// ///////////////////////

View File

@ -35,6 +35,12 @@ setup_loggers()
def setupArgParser(): def setupArgParser():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument(
"--logLevel",
type=str,
default="critical",
help="Log level info|critical. (default: critical)",
)
parser.add_argument("-p", type=int, default=18888, help="port") parser.add_argument("-p", type=int, default=18888, help="port")
parser.add_argument("--https", type=strtobool, default=False, help="use https") parser.add_argument("--https", type=strtobool, default=False, help="use https")
parser.add_argument( parser.add_argument(
@ -178,13 +184,13 @@ printMessage(f"Booting PHASE :{__name__}", level=2)
PORT = args.p PORT = args.p
def localServer(): def localServer(logLevel: str = "critical"):
uvicorn.run( uvicorn.run(
f"{os.path.basename(__file__)[:-3]}:app_socketio", f"{os.path.basename(__file__)[:-3]}:app_socketio",
host="0.0.0.0", host="0.0.0.0",
port=int(PORT), port=int(PORT),
reload=False if hasattr(sys, "_MEIPASS") else True, reload=False if hasattr(sys, "_MEIPASS") else True,
log_level="warning", log_level=logLevel,
) )
@ -318,10 +324,10 @@ if __name__ == "__main__":
reload=False if hasattr(sys, "_MEIPASS") else True, reload=False if hasattr(sys, "_MEIPASS") else True,
ssl_keyfile=key_path, ssl_keyfile=key_path,
ssl_certfile=cert_path, ssl_certfile=cert_path,
# log_level="warning" log_level=args.logLevel,
) )
else: else:
p = mp.Process(name="p", target=localServer) p = mp.Process(name="p", target=localServer, args=(args.logLevel,))
p.start() p.start()
try: try:
if sys.platform.startswith("win"): if sys.platform.startswith("win"):

View File

@ -104,9 +104,41 @@ SAMPLES_JSONS = [
# "https://huggingface.co/wok000/vcclient_model/raw/main/samples_0001.json", # "https://huggingface.co/wok000/vcclient_model/raw/main/samples_0001.json",
# "https://huggingface.co/wok000/vcclient_model/raw/main/samples_0002.json", # "https://huggingface.co/wok000/vcclient_model/raw/main/samples_0002.json",
# "https://huggingface.co/wok000/vcclient_model/raw/main/samples_0003_t.json", # "https://huggingface.co/wok000/vcclient_model/raw/main/samples_0003_t.json",
# "https://huggingface.co/wok000/vcclient_model/raw/main/samples_0003_o.json", "https://huggingface.co/wok000/vcclient_model/raw/main/samples_0003_o.json",
"https://huggingface.co/wok000/vcclient_model/raw/main/test/test_official_v1_v2.jsona", # "https://huggingface.co/wok000/vcclient_model/raw/main/test/test_official_v1_v2.json",
"https://huggingface.co/wok000/vcclient_model/raw/main/test/test_ddpn_v1_v2.jsona", # "https://huggingface.co/wok000/vcclient_model/raw/main/test/test_ddpn_v1_v2.json",
] ]
SAMPLE_MODEL_IDS = [
("TokinaShigure_o", True),
("KikotoMahiro_o", False),
("Amitaro_o", False),
("Tsukuyomi-chan_o", False),
# オフィシャルモデルテスト
# ("test-official-v1-f0-48k-l9-hubert_t", True),
# ("test-official-v1-nof0-48k-l9-hubert_t", False),
# ("test-official-v2-f0-40k-l12-hubert_t", False),
# ("test-official-v2-nof0-40k-l12-hubert_t", False),
# ("test-official-v1-f0-48k-l9-hubert_o", True),
# ("test-official-v1-nof0-48k-l9-hubert_o", False),
# ("test-official-v2-f0-40k-l12-hubert_o", False),
# ("test-official-v2-nof0-40k-l12-hubert_o", False),
# DDPNモデルテスト(torch)
# ("test-ddpn-v1-f0-48k-l9-hubert_t", False),
# ("test-ddpn-v1-nof0-48k-l9-hubert_t", False),
# ("test-ddpn-v2-f0-40k-l12-hubert_t", False),
# ("test-ddpn-v2-nof0-40k-l12-hubert_t", False),
# ("test-ddpn-v2-f0-40k-l12-hubert_jp_t", False),
# ("test-ddpn-v2-nof0-40k-l12-hubert_jp_t", False),
# DDPNモデルテスト(onnx)
# ("test-ddpn-v1-f0-48k-l9-hubert_o", False),
# ("test-ddpn-v1-nof0-48k-l9-hubert_o", False),
# ("test-ddpn-v2-f0-40k-l12-hubert_o", False),
# ("test-ddpn-v2-nof0-40k-l12-hubert_o", False),
# ("test-ddpn-v2-f0-40k-l12-hubert_jp_o", False),
# ("test-ddpn-v2-nof0-40k-l12-hubert_jp_o", False),
]
RVC_MODEL_DIRNAME = "rvc" RVC_MODEL_DIRNAME = "rvc"
RVC_MAX_SLOT_NUM = 10 RVC_MAX_SLOT_NUM = 10

View File

@ -69,7 +69,7 @@ class MMVC_Rest_Fileuploader:
def post_update_settings( def post_update_settings(
self, key: str = Form(...), val: Union[int, str, float] = Form(...) self, key: str = Form(...), val: Union[int, str, float] = Form(...)
): ):
print("[Voice Changer] update configuration:", key, val) # print("[Voice Changer] update configuration:", key, val)
info = self.voiceChangerManager.update_settings(key, val) info = self.voiceChangerManager.update_settings(key, val)
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)

View File

@ -0,0 +1,74 @@
{
"RVC": [
{
"id": "KikotoKurage_o",
"lang": "ja-JP",
"tag": ["v2", "onnx"],
"name": "黄琴海月",
"modelUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/rvc_v2_alpha/kikoto_kurage/kikoto_kurage_v2_40k_e100_simple.onnx",
"indexUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/rvc_v2_alpha/kikoto_kurage/added_IVF5181_Flat_nprobe_1_v2.index.bin",
"termsOfUseUrl": "https://huggingface.co/wok000/vcclient_model/raw/main/rvc_v2_alpha/kikoto_kurage/terms_of_use.txt",
"credit": "黄琴海月",
"description": "",
"sampleRate": 40000,
"modelType": "rvc_v2",
"f0": true
},
{
"id": "KikotoMahiro_o",
"lang": "ja-JP",
"tag": ["v2", "onnx"],
"name": "黄琴まひろ",
"modelUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/rvc_v2_alpha/kikoto_mahiro/kikoto_mahiro_v2_40k_simple.onnx",
"indexUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/rvc_v2_alpha/kikoto_mahiro/added_IVF6881_Flat_nprobe_1_v2.index.bin",
"termsOfUseUrl": "https://huggingface.co/wok000/vcclient_model/raw/main/rvc_v2_alpha/kikoto_mahiro/terms_of_use.txt",
"credit": "黄琴まひろ",
"description": "",
"sampleRate": 40000,
"modelType": "rvc_v2",
"f0": true
},
{
"id": "TokinaShigure_o",
"lang": "ja-JP",
"tag": ["v2", "onnx"],
"name": "刻鳴時雨",
"modelUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/rvc_v2_alpha/tokina_shigure/tokina_shigure_v2_40k_e100_simple.onnx",
"indexUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/rvc_v2_alpha/tokina_shigure/added_IVF2736_Flat_nprobe_1_v2.index.bin",
"termsOfUseUrl": "https://huggingface.co/wok000/vcclient_model/raw/main/rvc_v2_alpha/tokina_shigure/terms_of_use.txt",
"credit": "刻鳴時雨",
"description": "",
"sampleRate": 40000,
"modelType": "rvc_v2",
"f0": true
},
{
"id": "Amitaro_o",
"lang": "ja-JP",
"tag": ["v2", "onnx"],
"name": "あみたろ",
"modelUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/rvc_v2_alpha/amitaro/amitaro_v2_40k_e100_simple.onnx",
"indexUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/rvc_v2_alpha/amitaro/added_IVF3139_Flat_nprobe_1_v2.index.bin",
"termsOfUseUrl": "https://huggingface.co/wok000/vcclient_model/raw/main/rvc_v2_alpha/amitaro/terms_of_use.txt",
"credit": "あみたろ",
"description": "",
"sampleRate": 40000,
"modelType": "rvc_v2",
"f0": true
},
{
"id": "Tsukuyomi-chan_o",
"lang": "ja-JP",
"tag": ["v2", "onnx"],
"name": "つくよみちゃん",
"modelUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/rvc_v2_alpha/tsukuyomi-chan/tsukuyomi_v2_40k_e100_simple.onnx",
"indexUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/rvc_v2_alpha/tsukuyomi-chan/added_IVF7852_Flat_nprobe_1_v2.index.bin",
"termsOfUseUrl": "https://huggingface.co/wok000/vcclient_model/blob/main/rvc_v2_alpha/tsukuyomi-chan/terms_of_use.txt",
"credit": "つくよみちゃん",
"description": "",
"sampleRate": 40000,
"modelType": "rvc_v2",
"f0": true
}
]
}

View File

@ -70,7 +70,7 @@ class DDSP_SVC:
self.params = params self.params = params
self.svc_model.setVCParams(params) self.svc_model.setVCParams(params)
EmbedderManager.initialize(params) EmbedderManager.initialize(params)
print("DDSP-SVC initialization:", params) print("[Voice Changer] DDSP-SVC initialization:", params)
def loadModel(self, props: LoadModelParams): def loadModel(self, props: LoadModelParams):
target_slot_idx = props.slot target_slot_idx = props.slot

View File

@ -67,7 +67,7 @@ class RVC:
self.params = params self.params = params
EmbedderManager.initialize(params) EmbedderManager.initialize(params)
self.loadSlots() self.loadSlots()
print("RVC initialization: ", params) print("[Voice Changer] RVC initialization: ", params)
# サンプルカタログ作成 # サンプルカタログ作成
sampleJsons: list[str] = [] sampleJsons: list[str] = []
@ -210,12 +210,6 @@ class RVC:
if key == "gpu": if key == "gpu":
self.prepareModel(self.settings.modelSlotIndex) self.prepareModel(self.settings.modelSlotIndex)
if key == "enableDirectML":
if self.pipeline is not None and val == 0:
self.pipeline.setDirectMLEnable(False)
elif self.pipeline is not None and val == 1:
self.pipeline.setDirectMLEnable(True)
elif key in self.settings.floatData: elif key in self.settings.floatData:
setattr(self.settings, key, float(val)) setattr(self.settings, key, float(val))
elif key in self.settings.strData: elif key in self.settings.strData:
@ -268,6 +262,9 @@ class RVC:
def get_info(self): def get_info(self):
data = asdict(self.settings) data = asdict(self.settings)
if self.pipeline is not None:
pipelineInfo = self.pipeline.getPipelineInfo()
data["pipelineInfo"] = pipelineInfo
return data return data
def get_processing_sampling_rate(self): def get_processing_sampling_rate(self):

View File

@ -1,7 +1,7 @@
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
from dataclasses import asdict from dataclasses import asdict
import os import os
from const import RVC_MODEL_DIRNAME, TMP_DIR from const import RVC_MODEL_DIRNAME, SAMPLE_MODEL_IDS, TMP_DIR
from Downloader import download, download_no_tqdm from Downloader import download, download_no_tqdm
from ModelSample import RVCModelSample, getModelSamples from ModelSample import RVCModelSample, getModelSamples
import json import json
@ -18,37 +18,7 @@ def checkRvcModelExist(model_dir: str):
def downloadInitialSampleModels(sampleJsons: list[str], model_dir: str): def downloadInitialSampleModels(sampleJsons: list[str], model_dir: str):
# sampleModelIds = [ sampleModelIds = SAMPLE_MODEL_IDS
# ("TokinaShigure_o", True),
# ("KikotoMahiro_o", False),
# ("Amitaro_o", False),
# ("Tsukuyomi-chan_o", False),
# ]
sampleModelIds = [
# オフィシャルモデルテスト
# ("test-official-v1-f0-48k-l9-hubert_t", True),
# ("test-official-v1-nof0-48k-l9-hubert_t", False),
# ("test-official-v2-f0-40k-l12-hubert_t", False),
# ("test-official-v2-nof0-40k-l12-hubert_t", False),
# ("test-official-v1-f0-48k-l9-hubert_o", True),
# ("test-official-v1-nof0-48k-l9-hubert_o", False),
# ("test-official-v2-f0-40k-l12-hubert_o", False),
# ("test-official-v2-nof0-40k-l12-hubert_o", False),
# DDPNモデルテスト(torch)
# ("test-ddpn-v1-f0-48k-l9-hubert_t", False),
# ("test-ddpn-v1-nof0-48k-l9-hubert_t", False),
# ("test-ddpn-v2-f0-40k-l12-hubert_t", False),
# ("test-ddpn-v2-nof0-40k-l12-hubert_t", False),
# ("test-ddpn-v2-f0-40k-l12-hubert_jp_t", False),
# ("test-ddpn-v2-nof0-40k-l12-hubert_jp_t", False),
# DDPNモデルテスト(onnx)
("test-ddpn-v1-f0-48k-l9-hubert_o", False),
("test-ddpn-v1-nof0-48k-l9-hubert_o", False),
("test-ddpn-v2-f0-40k-l12-hubert_o", False),
("test-ddpn-v2-nof0-40k-l12-hubert_o", False),
("test-ddpn-v2-f0-40k-l12-hubert_jp_o", False),
("test-ddpn-v2-nof0-40k-l12-hubert_jp_o", False),
]
sampleModels = getModelSamples(sampleJsons, "RVC") sampleModels = getModelSamples(sampleJsons, "RVC")
if sampleModels is None: if sampleModels is None:

View File

@ -22,6 +22,15 @@ class Embedder(Protocol):
) -> torch.Tensor: ) -> torch.Tensor:
... ...
def getEmbedderInfo(self):
return {
"embedderType": self.embedderType.value,
"file": self.file,
"isHalf": self.isHalf,
"devType": self.dev.type,
"devIndex": self.dev.index,
}
def setProps( def setProps(
self, self,
embedderType: EnumEmbedderTypes, embedderType: EnumEmbedderTypes,

View File

@ -2,14 +2,15 @@ from typing import Any, Protocol
import torch import torch
import onnxruntime import onnxruntime
from const import EnumInferenceTypes
class Inferencer(Protocol): class Inferencer(Protocol):
# inferencerType: EnumInferenceTypes = EnumInferenceTypes.pyTorchRVC inferencerType: EnumInferenceTypes = EnumInferenceTypes.pyTorchRVC
# file: str file: str
# isHalf: bool = True isHalf: bool = True
# dev: device | None gpu: int = 0
# onnxProviders: list[str] | None
# onnxProviderOptions: Any | None
model: onnxruntime.InferenceSession | Any | None = None model: onnxruntime.InferenceSession | Any | None = None
def loadModel(self, file: str, gpu: int): def loadModel(self, file: str, gpu: int):
@ -25,18 +26,22 @@ class Inferencer(Protocol):
) -> torch.Tensor: ) -> torch.Tensor:
... ...
# def setProps( def setProps(
# self, self,
# inferencerType: EnumInferenceTypes, inferencerType: EnumInferenceTypes,
# file: str, file: str,
# dev: device | None, isHalf: bool,
# onnxProviders: list[str] | None, gpu: int,
# onnxProviderOptions: Any | None, ):
# isHalf: bool = True, self.inferencerType = inferencerType
# ): self.file = file
# self.inferencerType = inferencerType self.isHalf = isHalf
# self.file = file self.gpu = gpu
# self.isHalf = isHalf
# self.dev = dev def getInferencerInfo(self):
# self.onnxProviders = onnxProviders return {
# self.onnxProviderOptions = onnxProviderOptions "inferencerType": self.inferencerType.value,
"file": self.file,
"isHalf": self.isHalf,
"gpu": self.gpu,
}

View File

@ -1,5 +1,6 @@
import torch import torch
import onnxruntime import onnxruntime
from const import EnumInferenceTypes
from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager
from voice_changer.RVC.inferencer.Inferencer import Inferencer from voice_changer.RVC.inferencer.Inferencer import Inferencer
import numpy as np import numpy as np
@ -7,6 +8,7 @@ import numpy as np
class OnnxRVCInferencer(Inferencer): class OnnxRVCInferencer(Inferencer):
def loadModel(self, file: str, gpu: int): def loadModel(self, file: str, gpu: int):
self.setProps(EnumInferenceTypes.onnxRVC, file, True, gpu)
( (
onnxProviders, onnxProviders,
onnxProviderOptions, onnxProviderOptions,
@ -65,3 +67,8 @@ class OnnxRVCInferencer(Inferencer):
) )
return torch.tensor(np.array(audio1)) return torch.tensor(np.array(audio1))
def getInferencerInfo(self):
inferencer = super().getInferencerInfo()
inferencer["onnxExecutionProvider"] = self.model.get_providers()
return inferencer

View File

@ -1,10 +1,15 @@
import torch import torch
import numpy as np import numpy as np
from const import EnumInferenceTypes
from voice_changer.RVC.inferencer.OnnxRVCInferencer import OnnxRVCInferencer from voice_changer.RVC.inferencer.OnnxRVCInferencer import OnnxRVCInferencer
class OnnxRVCInferencerNono(OnnxRVCInferencer): class OnnxRVCInferencerNono(OnnxRVCInferencer):
def loadModel(self, file: str, gpu: int):
super().loadModel(file, gpu)
self.setProps(EnumInferenceTypes.onnxRVCNono, file, True, gpu)
def infer( def infer(
self, self,
feats: torch.Tensor, feats: torch.Tensor,

View File

@ -1,4 +1,5 @@
import torch import torch
from const import EnumInferenceTypes
from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager
from voice_changer.RVC.inferencer.Inferencer import Inferencer from voice_changer.RVC.inferencer.Inferencer import Inferencer
@ -9,6 +10,8 @@ from infer_pack.models import ( # type:ignore
class RVCInferencer(Inferencer): class RVCInferencer(Inferencer):
def loadModel(self, file: str, gpu: int): def loadModel(self, file: str, gpu: int):
self.setProps(EnumInferenceTypes.pyTorchRVC, file, True, gpu)
dev = DeviceManager.get_instance().getDevice(gpu) dev = DeviceManager.get_instance().getDevice(gpu)
isHalf = DeviceManager.get_instance().halfPrecisionAvailable(gpu) isHalf = DeviceManager.get_instance().halfPrecisionAvailable(gpu)

View File

@ -1,4 +1,5 @@
import torch import torch
from const import EnumInferenceTypes
from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager
from voice_changer.RVC.inferencer.Inferencer import Inferencer from voice_changer.RVC.inferencer.Inferencer import Inferencer
@ -9,6 +10,8 @@ from infer_pack.models import ( # type:ignore
class RVCInferencerNono(Inferencer): class RVCInferencerNono(Inferencer):
def loadModel(self, file: str, gpu: int): def loadModel(self, file: str, gpu: int):
self.setProps(EnumInferenceTypes.pyTorchRVCNono, file, True, gpu)
dev = DeviceManager.get_instance().getDevice(gpu) dev = DeviceManager.get_instance().getDevice(gpu)
isHalf = DeviceManager.get_instance().halfPrecisionAvailable(gpu) isHalf = DeviceManager.get_instance().halfPrecisionAvailable(gpu)

View File

@ -1,4 +1,5 @@
import torch import torch
from const import EnumInferenceTypes
from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager
from voice_changer.RVC.inferencer.Inferencer import Inferencer from voice_changer.RVC.inferencer.Inferencer import Inferencer
from infer_pack.models import ( # type:ignore from infer_pack.models import ( # type:ignore
@ -8,6 +9,8 @@ from infer_pack.models import ( # type:ignore
class RVCInferencerv2(Inferencer): class RVCInferencerv2(Inferencer):
def loadModel(self, file: str, gpu: int): def loadModel(self, file: str, gpu: int):
self.setProps(EnumInferenceTypes.pyTorchRVCv2, file, True, gpu)
dev = DeviceManager.get_instance().getDevice(gpu) dev = DeviceManager.get_instance().getDevice(gpu)
isHalf = DeviceManager.get_instance().halfPrecisionAvailable(gpu) isHalf = DeviceManager.get_instance().halfPrecisionAvailable(gpu)

View File

@ -1,4 +1,5 @@
import torch import torch
from const import EnumInferenceTypes
from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager
from voice_changer.RVC.inferencer.Inferencer import Inferencer from voice_changer.RVC.inferencer.Inferencer import Inferencer
@ -9,6 +10,8 @@ from infer_pack.models import ( # type:ignore
class RVCInferencerv2Nono(Inferencer): class RVCInferencerv2Nono(Inferencer):
def loadModel(self, file: str, gpu: int): def loadModel(self, file: str, gpu: int):
self.setProps(EnumInferenceTypes.pyTorchRVCv2Nono, file, True, gpu)
dev = DeviceManager.get_instance().getDevice(gpu) dev = DeviceManager.get_instance().getDevice(gpu)
isHalf = DeviceManager.get_instance().halfPrecisionAvailable(gpu) isHalf = DeviceManager.get_instance().halfPrecisionAvailable(gpu)

View File

@ -1,4 +1,5 @@
import torch import torch
from const import EnumInferenceTypes
from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager
from voice_changer.RVC.inferencer.Inferencer import Inferencer from voice_changer.RVC.inferencer.Inferencer import Inferencer
@ -7,6 +8,8 @@ from .models import SynthesizerTrnMsNSFsid
class WebUIInferencer(Inferencer): class WebUIInferencer(Inferencer):
def loadModel(self, file: str, gpu: int): def loadModel(self, file: str, gpu: int):
self.setProps(EnumInferenceTypes.pyTorchWebUI, file, True, gpu)
dev = DeviceManager.get_instance().getDevice(gpu) dev = DeviceManager.get_instance().getDevice(gpu)
isHalf = DeviceManager.get_instance().halfPrecisionAvailable(gpu) isHalf = DeviceManager.get_instance().halfPrecisionAvailable(gpu)

View File

@ -1,4 +1,5 @@
import torch import torch
from const import EnumInferenceTypes
from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager
from voice_changer.RVC.inferencer.Inferencer import Inferencer from voice_changer.RVC.inferencer.Inferencer import Inferencer
@ -7,6 +8,8 @@ from .models import SynthesizerTrnMsNSFsidNono
class WebUIInferencerNono(Inferencer): class WebUIInferencerNono(Inferencer):
def loadModel(self, file: str, gpu: int): def loadModel(self, file: str, gpu: int):
self.setProps(EnumInferenceTypes.pyTorchWebUINono, file, True, gpu)
dev = DeviceManager.get_instance().getDevice(gpu) dev = DeviceManager.get_instance().getDevice(gpu)
isHalf = DeviceManager.get_instance().halfPrecisionAvailable(gpu) isHalf = DeviceManager.get_instance().halfPrecisionAvailable(gpu)

View File

@ -59,9 +59,15 @@ class Pipeline(object):
self.sr = 16000 self.sr = 16000
self.window = 160 self.window = 160
def setDirectMLEnable(self, enable: bool): def getPipelineInfo(self):
if hasattr(self.inferencer, "setDirectMLEnable"): inferencerInfo = self.inferencer.getInferencerInfo() if self.inferencer else {}
self.inferencer.setDirectMLEnable(enable) embedderInfo = self.embedder.getEmbedderInfo()
pitchExtractorInfo = self.pitchExtractor.getPitchExtractorInfo()
return {
"inferencer": inferencerInfo,
"embedder": embedderInfo,
"pitchExtractor": pitchExtractorInfo,
}
def setPitchExtractor(self, pitchExtractor: PitchExtractor): def setPitchExtractor(self, pitchExtractor: PitchExtractor):
self.pitchExtractor = pitchExtractor self.pitchExtractor = pitchExtractor

View File

@ -1,11 +1,14 @@
import torchcrepe import torchcrepe
import torch import torch
import numpy as np import numpy as np
from const import EnumPitchExtractorTypes
from voice_changer.RVC.pitchExtractor.PitchExtractor import PitchExtractor from voice_changer.RVC.pitchExtractor.PitchExtractor import PitchExtractor
class CrepePitchExtractor(PitchExtractor): class CrepePitchExtractor(PitchExtractor):
pitchExtractorType: EnumPitchExtractorTypes = EnumPitchExtractorTypes.crepe
def __init__(self): def __init__(self):
super().__init__() super().__init__()
if torch.cuda.is_available(): if torch.cuda.is_available():

View File

@ -1,10 +1,13 @@
import pyworld import pyworld
import numpy as np import numpy as np
from const import EnumPitchExtractorTypes
from voice_changer.RVC.pitchExtractor.PitchExtractor import PitchExtractor from voice_changer.RVC.pitchExtractor.PitchExtractor import PitchExtractor
class DioPitchExtractor(PitchExtractor): class DioPitchExtractor(PitchExtractor):
pitchExtractorType: EnumPitchExtractorTypes = EnumPitchExtractorTypes.dio
def extract(self, audio, f0_up_key, sr, window, silence_front=0): def extract(self, audio, f0_up_key, sr, window, silence_front=0):
audio = audio.detach().cpu().numpy() audio = audio.detach().cpu().numpy()
n_frames = int(len(audio) // window) + 1 n_frames = int(len(audio) // window) + 1

View File

@ -1,11 +1,14 @@
import pyworld import pyworld
import numpy as np import numpy as np
import scipy.signal as signal import scipy.signal as signal
from const import EnumPitchExtractorTypes
from voice_changer.RVC.pitchExtractor.PitchExtractor import PitchExtractor from voice_changer.RVC.pitchExtractor.PitchExtractor import PitchExtractor
class HarvestPitchExtractor(PitchExtractor): class HarvestPitchExtractor(PitchExtractor):
pitchExtractorType: EnumPitchExtractorTypes = EnumPitchExtractorTypes.harvest
def extract(self, audio, f0_up_key, sr, window, silence_front=0): def extract(self, audio, f0_up_key, sr, window, silence_front=0):
audio = audio.detach().cpu().numpy() audio = audio.detach().cpu().numpy()
n_frames = int(len(audio) // window) + 1 n_frames = int(len(audio) // window) + 1

View File

@ -7,3 +7,8 @@ class PitchExtractor(Protocol):
def extract(self, audio, f0_up_key, sr, window, silence_front=0): def extract(self, audio, f0_up_key, sr, window, silence_front=0):
... ...
def getPitchExtractorInfo(self):
return {
"pitchExtractorType": self.pitchExtractorType.value,
}

View File

@ -80,7 +80,7 @@ class SoVitsSvc40:
self.gpu_num = torch.cuda.device_count() self.gpu_num = torch.cuda.device_count()
self.prevVol = 0 self.prevVol = 0
self.params = params self.params = params
print("so-vits-svc40 initialization:", params) print("[Voice Changer] so-vits-svc40 initialization:", params)
# def loadModel(self, config: str, pyTorch_model_file: str = None, onnx_model_file: str = None, clusterTorchModel: str = None): # def loadModel(self, config: str, pyTorch_model_file: str = None, onnx_model_file: str = None, clusterTorchModel: str = None):
def loadModel(self, props: LoadModelParams): def loadModel(self, props: LoadModelParams):

View File

@ -76,7 +76,7 @@ class SoVitsSvc40v2:
self.gpu_num = torch.cuda.device_count() self.gpu_num = torch.cuda.device_count()
self.prevVol = 0 self.prevVol = 0
self.params = params self.params = params
print("so-vits-svc 40v2 initialization:", params) print("[Voice Changer] so-vits-svc 40v2 initialization:", params)
def loadModel(self, props: LoadModelParams): def loadModel(self, props: LoadModelParams):
params = props.params params = props.params

View File

@ -372,7 +372,8 @@ class VoiceChanger:
else: else:
ret = self.voiceChanger.update_settings(key, val) ret = self.voiceChanger.update_settings(key, val)
if ret is False: if ret is False:
print(f"({key} is not mutable variable or unknown variable)") pass
# print(f"({key} is not mutable variable or unknown variable)")
return self.get_info() return self.get_info()
def _generate_strength(self, crossfadeSize: int): def _generate_strength(self, crossfadeSize: int):