add sample diffusion svc

This commit is contained in:
w-okada 2023-07-21 18:25:28 +09:00
parent a0e890a438
commit d3e49efd69
15 changed files with 324 additions and 105 deletions

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@dannadori/voice-changer-client-js": "^1.0.161",
"@dannadori/voice-changer-client-js": "^1.0.163",
"@fortawesome/fontawesome-svg-core": "^6.4.0",
"@fortawesome/free-brands-svg-icons": "^6.4.0",
"@fortawesome/free-regular-svg-icons": "^6.4.0",
@ -35,7 +35,7 @@
"eslint": "^8.45.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react": "^7.33.0",
"eslint-webpack-plugin": "^4.0.1",
"html-loader": "^4.2.0",
"html-webpack-plugin": "^5.5.3",
@ -48,7 +48,7 @@
"ts-loader": "^9.4.4",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.1.6",
"webpack": "^5.88.1",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
}
@ -2708,9 +2708,9 @@
}
},
"node_modules/@dannadori/voice-changer-client-js": {
"version": "1.0.161",
"resolved": "https://registry.npmjs.org/@dannadori/voice-changer-client-js/-/voice-changer-client-js-1.0.161.tgz",
"integrity": "sha512-09TncUiM+NTnU3F8FnPuVqI/OQcQ6KEvUW0ErSuZtXLWIn6M7Ol+F+tvdlIa+5/fahsZle40Ujaz+5oq1g6uXQ==",
"version": "1.0.163",
"resolved": "https://registry.npmjs.org/@dannadori/voice-changer-client-js/-/voice-changer-client-js-1.0.163.tgz",
"integrity": "sha512-ZSY+ppO96pEe6ouwBI9vCkOY7PjnWcxpGmW5ZyuHZTyhIZK4ArBrKyRs+hfo4oJIqVfkgvrv3RblFDV3BNnNow==",
"dependencies": {
"@types/readable-stream": "^2.3.15",
"amazon-chime-sdk-js": "^3.15.0",
@ -6232,9 +6232,9 @@
}
},
"node_modules/eslint-plugin-react": {
"version": "7.32.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz",
"integrity": "sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==",
"version": "7.33.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.0.tgz",
"integrity": "sha512-qewL/8P34WkY8jAqdQxsiL82pDUeT7nhs8IsuXgfgnsEloKCT4miAV9N9kGtx7/KM9NH/NCGUE7Edt9iGxLXFw==",
"dev": true,
"dependencies": {
"array-includes": "^3.1.6",
@ -6250,7 +6250,7 @@
"object.values": "^1.1.6",
"prop-types": "^15.8.1",
"resolve": "^2.0.0-next.4",
"semver": "^6.3.0",
"semver": "^6.3.1",
"string.prototype.matchall": "^4.0.8"
},
"engines": {
@ -11748,9 +11748,9 @@
}
},
"node_modules/webpack": {
"version": "5.88.1",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.1.tgz",
"integrity": "sha512-FROX3TxQnC/ox4N+3xQoWZzvGXSuscxR32rbzjpXgEzWudJFEJBpdlkkob2ylrv5yzzufD1zph1OoFsLtm6stQ==",
"version": "5.88.2",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz",
"integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==",
"dev": true,
"dependencies": {
"@types/eslint-scope": "^3.7.3",

View File

@ -36,7 +36,7 @@
"eslint": "^8.45.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react": "^7.33.0",
"eslint-webpack-plugin": "^4.0.1",
"html-loader": "^4.2.0",
"html-webpack-plugin": "^5.5.3",
@ -54,7 +54,7 @@
"webpack-dev-server": "^4.15.1"
},
"dependencies": {
"@dannadori/voice-changer-client-js": "^1.0.162",
"@dannadori/voice-changer-client-js": "^1.0.163",
"@fortawesome/fontawesome-svg-core": "^6.4.0",
"@fortawesome/free-brands-svg-icons": "^6.4.0",
"@fortawesome/free-regular-svg-icons": "^6.4.0",

View File

@ -223,7 +223,7 @@ export const MainScreen = (props: MainScreenProps) => {
iconArea = generateIconArea(index, slotInfo.iconFile, true);
nameRow = generateNameRow(index, slotInfo.name, slotInfo.termsOfUseUrl);
fileRows.push(generateFileRow("model", slotInfo.modelFile));
infoRow = generateInfoRow(`tune:${slotInfo.defaultTune},ks(max):${slotInfo.kStepMax},ks:${slotInfo.defaultKstep}, sp:${slotInfo.defaultSpeedup}, l:${slotInfo.nLayers},${slotInfo.nnLayers},`);
infoRow = generateInfoRow(`tune:${slotInfo.defaultTune},mks:${slotInfo.kStepMax},ks:${slotInfo.defaultKstep}, sp:${slotInfo.defaultSpeedup}, l:${slotInfo.nLayers},${slotInfo.nnLayers},`);
} else {
iconArea = generateIconArea(index, "/assets/icons/blank.png", false);
nameRow = generateNameRow(index, "", "");

View File

@ -1,78 +1,94 @@
import React, { useMemo, useState } from "react";
import { useAppState } from "../../001_provider/001_AppStateProvider";
import { ModelUploadSetting } from "@dannadori/voice-changer-client-js";
import { DiffusionSVCSampleModel, ModelUploadSetting, RVCSampleModel, VoiceChangerType } from "@dannadori/voice-changer-client-js";
import { useMessageBuilder } from "../../hooks/useMessageBuilder";
import { ModelSlotManagerDialogScreen } from "./904_ModelSlotManagerDialog";
export type SampleDownloaderScreenProps = {
screen: ModelSlotManagerDialogScreen
targetIndex: number
close: () => void
backToSlotManager: () => void
}
screen: ModelSlotManagerDialogScreen;
targetIndex: number;
close: () => void;
backToSlotManager: () => void;
};
export const SampleDownloaderScreen = (props: SampleDownloaderScreenProps) => {
const { serverSetting } = useAppState()
const [lang, setLang] = useState<string>("All")
const messageBuilderState = useMessageBuilder()
const { serverSetting } = useAppState();
const [lang, setLang] = useState<string>("All");
const messageBuilderState = useMessageBuilder();
useMemo(() => {
messageBuilderState.setMessage(__filename, "header_message", { "ja": "サンプルをダウンロードしてください. 対象:", "en": "Download Sample for" })
messageBuilderState.setMessage(__filename, "lang", { "ja": "言語", "en": "Lang" })
messageBuilderState.setMessage(__filename, "back", { "ja": "戻る", "en": "back" })
messageBuilderState.setMessage(__filename, "terms_of_use", { "ja": "利用規約", "en": "terms of use" })
messageBuilderState.setMessage(__filename, "download", { "ja": "ダウンロード", "en": "download" })
}, [])
messageBuilderState.setMessage(__filename, "header_message", { ja: "サンプルをダウンロードしてください. 対象:", en: "Download Sample for" });
messageBuilderState.setMessage(__filename, "lang", { ja: "言語", en: "Lang" });
messageBuilderState.setMessage(__filename, "back", { ja: "戻る", en: "back" });
messageBuilderState.setMessage(__filename, "terms_of_use", { ja: "利用規約", en: "terms of use" });
messageBuilderState.setMessage(__filename, "download", { ja: "ダウンロード", en: "download" });
}, []);
/////////////////////////////////////////
// Sample Downloader
/////////////////////////////////////////
const screen = useMemo(() => {
if (props.screen != "SampleDownloader") {
return <></>
return <></>;
}
if (!serverSetting.serverSetting.modelSlots) {
return <></>
return <></>;
}
const langs = serverSetting.serverSetting.sampleModels.reduce((prev, cur) => {
const langs = serverSetting.serverSetting.sampleModels.reduce(
(prev, cur) => {
if (prev.includes(cur.lang) == false) {
prev.push(cur.lang)
prev.push(cur.lang);
}
return prev
}, ["All"] as string[])
const langOptions = (
langs.map(x => {
return <option key={x} value={x}>{x}</option>
})
)
const onDownloadSampleClicked = async (id: string) => {
return prev;
},
["All"] as string[],
);
const langOptions = langs.map((x) => {
return (
<option key={x} value={x}>
{x}
</option>
);
});
const onDownloadSampleClicked = async (id: string, voiceChangerType: VoiceChangerType, params: any) => {
const uploadParams: ModelUploadSetting = {
voiceChangerType: "RVC",
voiceChangerType: voiceChangerType,
slot: props.targetIndex,
isSampleMode: true,
sampleId: id,
files: [],
params: {
rvcIndexDownload: true
}
}
params: params,
};
try {
await serverSetting.uploadModel(uploadParams)
await serverSetting.uploadModel(uploadParams);
} catch (e) {
alert(e)
alert(e);
}
props.backToSlotManager()
props.backToSlotManager();
// setMode("localFile")
}
const options = (
serverSetting.serverSetting.sampleModels.filter(x => { return lang == "All" ? true : x.lang == lang }).map((x, index) => {
const termOfUseUrlLink = x.termsOfUseUrl && x.termsOfUseUrl.length > 0 ? <a href={x.termsOfUseUrl} target="_blank" rel="noopener noreferrer" className="body-item-text-small">[{messageBuilderState.getMessage(__filename, "terms_of_use")}]</a> : <></>
};
const options = serverSetting.serverSetting.sampleModels
.filter((x) => {
return lang == "All" ? true : x.lang == lang;
})
.map((x, index) => {
const termOfUseUrlLink =
x.termsOfUseUrl && x.termsOfUseUrl.length > 0 ? (
<a href={x.termsOfUseUrl} target="_blank" rel="noopener noreferrer" className="body-item-text-small">
[{messageBuilderState.getMessage(__filename, "terms_of_use")}]
</a>
) : (
<></>
);
let info = ``;
if (x.voiceChangerType == "RVC") {
const sampleInfo = x as RVCSampleModel;
info = `type:${sampleInfo.modelType}, f0:${sampleInfo.f0 ? "f0" : "nof0"}, sr:${sampleInfo.sampleRate}`;
} else if (x.voiceChangerType == "Diffusion-SVC") {
const sampleInfo = x as DiffusionSVCSampleModel;
info = `native_l:${sampleInfo.numOfNativeLayers}, diff_l:${sampleInfo.numOfDiffLayers}, max_kstep:${sampleInfo.maxKStep}`;
}
return (
<div key={index} className="model-slot">
<img src={x.icon} className="model-slot-icon"></img>
@ -82,21 +98,36 @@ export const SampleDownloaderScreen = (props: SampleDownloaderScreenProps) => {
<div className="model-slot-detail-row-value">{x.name}</div>
<div className="">{termOfUseUrlLink}</div>
</div>
<div className="model-slot-detail-row">
<div className="model-slot-detail-row-label">VC Type: </div>
<div className="model-slot-detail-row-value">{x.voiceChangerType}</div>
<div className=""></div>
</div>
<div className="model-slot-detail-row">
<div className="model-slot-detail-row-label">info: </div>
<div className="model-slot-detail-row-value">{x.modelType},{x.f0 ? "f0" : "nof0"},{x.sampleRate}</div>
<div className="model-slot-detail-row-value">{info}</div>
<div className=""></div>
</div>
</div>
<div className="model-slot-buttons">
<div className="model-slot-button" onClick={() => { onDownloadSampleClicked(x.id) }}>
<div
className="model-slot-button"
onClick={() => {
if (x.voiceChangerType == "RVC") {
onDownloadSampleClicked(x.id, x.voiceChangerType, {
rvcIndexDownload: true,
});
} else if (x.voiceChangerType == "Diffusion-SVC") {
onDownloadSampleClicked(x.id, x.voiceChangerType, {});
}
}}
>
{messageBuilderState.getMessage(__filename, "download")}
</div>
</div>
</div>
)
})
)
);
});
return (
<div className="dialog-frame">
@ -104,32 +135,32 @@ export const SampleDownloaderScreen = (props: SampleDownloaderScreenProps) => {
<div className="dialog-fixed-size-content">
<div className="model-slot-header">
{messageBuilderState.getMessage(__filename, "header_message")} Slot[{props.targetIndex}]
<span onClick={() => { props.backToSlotManager() }} className="model-slot-header-button">
<span
onClick={() => {
props.backToSlotManager();
}}
className="model-slot-header-button"
>
&lt;&lt;{messageBuilderState.getMessage(__filename, "back")}
</span>
</div>
<div>{messageBuilderState.getMessage(__filename, "lang")}:
<select value={lang} onChange={(e) => { setLang(e.target.value) }}>
<div>
{messageBuilderState.getMessage(__filename, "lang")}:
<select
value={lang}
onChange={(e) => {
setLang(e.target.value);
}}
>
{langOptions}
</select>
</div>
<div className="model-slot-container">
{options}
<div className="model-slot-container">{options}</div>
</div>
</div>
</div>
)
}, [
props.screen,
props.targetIndex,
lang,
serverSetting.serverSetting
])
);
}, [props.screen, props.targetIndex, lang, serverSetting.serverSetting]);
return screen;
};

View File

@ -1,12 +1,12 @@
{
"name": "@dannadori/voice-changer-client-js",
"version": "1.0.162",
"version": "1.0.163",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@dannadori/voice-changer-client-js",
"version": "1.0.162",
"version": "1.0.163",
"license": "ISC",
"dependencies": {
"@types/readable-stream": "^2.3.15",

View File

@ -1,6 +1,6 @@
{
"name": "@dannadori/voice-changer-client-js",
"version": "1.0.162",
"version": "1.0.163",
"description": "",
"main": "dist/index.js",
"directories": {

View File

@ -296,7 +296,7 @@ export type ServerInfo = VoiceChangerServerSetting & {
modelSlots: ModelSlotUnion[]
serverAudioInputDevices: ServerAudioDevice[]
serverAudioOutputDevices: ServerAudioDevice[]
sampleModels: RVCSampleModel[]
sampleModels: (RVCSampleModel|DiffusionSVCSampleModel)[]
gpus: {
id: number,
name: string,
@ -306,24 +306,37 @@ export type ServerInfo = VoiceChangerServerSetting & {
}
export type RVCSampleModel = {
export type SampleModel = {
id: string
name: string
modelUrl: string
indexUrl: string
featureUrl: string
termsOfUseUrl: string
credit: string
description: string
voiceChangerType: VoiceChangerType
lang: string
tag: string[]
name: string
modelUrl: string
termsOfUseUrl: string
icon: string
f0: boolean
credit: string
description: string
sampleRate: number
modelType: string
f0: boolean
}
export type RVCSampleModel =SampleModel & {
indexUrl: string
featureUrl: string
}
export type DiffusionSVCSampleModel =SampleModel & {
numOfDiffLayers: number
numOfNativeLayers: number
maxKStep: number
}
export const DefaultServerSetting: ServerInfo = {
// VC Common
inputSampleRate: 48000,

View File

@ -101,11 +101,14 @@ def getSampleJsonAndModelIds(mode: RVCSampleMode):
# "https://huggingface.co/wok000/vcclient_model/raw/main/samples_0002.json",
"https://huggingface.co/wok000/vcclient_model/raw/main/samples_0003_t2.json",
"https://huggingface.co/wok000/vcclient_model/raw/main/samples_0003_o2.json",
"https://huggingface.co/wok000/vcclient_model/raw/main/samples_0003_d2.json",
], [
("Tsukuyomi-chan_o", {"useIndex": False}),
("Amitaro_o", {"useIndex": False}),
("KikotoMahiro_o", {"useIndex": False}),
("TokinaShigure_o", {"useIndex": True}),
("diffusion_combo_spk5_nl3_dl20_k50_500ep", {}),
("diffusion_combo_spk5_nl3_dl1_k50_500ep", {}),
]
elif mode == "testOfficial":
return [

View File

@ -11,6 +11,7 @@ class ModelSample:
@dataclass
class RVCModelSample(ModelSample):
id: str = ""
voiceChangerType: VoiceChangerType = "RVC"
lang: str = ""
tag: list[str] = field(default_factory=lambda: [])
@ -27,11 +28,34 @@ class RVCModelSample(ModelSample):
f0: bool = True
ModelSamples: TypeAlias = Union[ModelSample, RVCModelSample]
@dataclass
class DiffusionSVCModelSample(ModelSample):
id: str = ""
voiceChangerType: VoiceChangerType = "Diffusion-SVC"
lang: str = ""
tag: list[str] = field(default_factory=lambda: [])
name: str = ""
modelUrl: str = ""
termsOfUseUrl: str = ""
icon: str = ""
credit: str = ""
description: str = ""
sampleRate: int = 48000
modelType: str = ""
f0: bool = True
numOfDiffLayers: int = 20
numOfNativeLayers: int = 3
maxKStep: int = 50
ModelSamples: TypeAlias = Union[ModelSample, RVCModelSample, DiffusionSVCModelSample]
def generateModelSample(params: Any) -> ModelSamples:
if params["voiceChangerType"] == "RVC":
return RVCModelSample(**params)
return RVCModelSample(**{k: v for k, v in params.items() if k in RVCModelSample.__annotations__})
elif params["voiceChangerType"] == "Diffusion-SVC":
return DiffusionSVCModelSample(**{k: v for k, v in params.items() if k in DiffusionSVCModelSample.__annotations__})
else:
return ModelSample(**{k: v for k, v in params.items() if k in ModelSample.__annotations__})

View File

@ -5,21 +5,29 @@ from typing import Any, Tuple
from const import RVCSampleMode, getSampleJsonAndModelIds
from data.ModelSample import ModelSamples, generateModelSample
from data.ModelSlot import RVCModelSlot
from data.ModelSlot import DiffusionSVCModelSlot, ModelSlot, RVCModelSlot
from voice_changer.DiffusionSVC.DiffusionSVCModelSlotGenerator import DiffusionSVCModelSlotGenerator
from voice_changer.ModelSlotManager import ModelSlotManager
from voice_changer.RVC.RVCModelSlotGenerator import RVCModelSlotGenerator
from downloader.Downloader import download, download_no_tqdm
def downloadInitialSamples(mode: RVCSampleMode, model_dir: str):
print("1111111111111")
sampleJsonUrls, sampleModels = getSampleJsonAndModelIds(mode)
print("11111111111112")
sampleJsons = _downloadSampleJsons(sampleJsonUrls)
print("11111111111113")
if os.path.exists(model_dir):
print("[Voice Changer] model_dir is already exists. skip download samples.")
return
print("11111111111114")
samples = _generateSampleList(sampleJsons)
print("11111111111115")
slotIndex = list(range(len(sampleModels)))
print("11111111111116")
_downloadSamples(samples, sampleModels, model_dir, slotIndex)
print("11111111111117")
pass
@ -90,6 +98,7 @@ def _downloadSamples(samples: list[ModelSamples], sampleModelIds: list[Tuple[str
# 検出されたら、、、
slotDir = os.path.join(model_dir, str(targetSlotIndex))
slotInfo: ModelSlot = ModelSlot()
if sample.voiceChangerType == "RVC":
slotInfo: RVCModelSlot = RVCModelSlot()
@ -148,6 +157,50 @@ def _downloadSamples(samples: list[ModelSamples], sampleModelIds: list[Tuple[str
slotInfo.defaultProtect = 0.5
slotInfo.isONNX = slotInfo.modelFile.endswith(".onnx")
modelSlotManager.save_model_slot(targetSlotIndex, slotInfo)
elif sample.voiceChangerType == "Diffusion-SVC":
slotInfo: DiffusionSVCModelSlot = DiffusionSVCModelSlot()
os.makedirs(slotDir, exist_ok=True)
modelFilePath = os.path.join(
slotDir,
os.path.basename(sample.modelUrl),
)
downloadParams.append(
{
"url": sample.modelUrl,
"saveTo": modelFilePath,
"position": line_num,
}
)
slotInfo.modelFile = modelFilePath
line_num += 1
if hasattr(sample, "icon") and sample.icon != "":
iconPath = os.path.join(
slotDir,
os.path.basename(sample.icon),
)
downloadParams.append(
{
"url": sample.icon,
"saveTo": iconPath,
"position": line_num,
}
)
slotInfo.iconFile = iconPath
line_num += 1
slotInfo.sampleId = sample.id
slotInfo.credit = sample.credit
slotInfo.description = sample.description
slotInfo.name = sample.name
slotInfo.termsOfUseUrl = sample.termsOfUseUrl
slotInfo.defaultTune = 0
slotInfo.defaultKstep = 0
slotInfo.defaultSpeedup = 0
slotInfo.kStepMax = 0
slotInfo.isONNX = slotInfo.modelFile.endswith(".onnx")
modelSlotManager.save_model_slot(targetSlotIndex, slotInfo)
else:
print(f"[Voice Changer] {sample.voiceChangerType} is not supported.")
@ -171,3 +224,9 @@ def _downloadSamples(samples: list[ModelSamples], sampleModelIds: list[Tuple[str
slotInfo = RVCModelSlotGenerator._setInfoByPytorch(slotInfo)
modelSlotManager.save_model_slot(targetSlotIndex, slotInfo)
elif slotInfo.voiceChangerType == "Diffusion-SVC":
if slotInfo.isONNX:
pass
else:
slotInfo = DiffusionSVCModelSlotGenerator._setInfoByPytorch(slotInfo)
modelSlotManager.save_model_slot(targetSlotIndex, slotInfo)

View File

@ -0,0 +1,76 @@
{
"Diffusion-SVC": [
{
"id": "diffusion_combo_spk5_nl3_dl20_k50_500ep",
"voiceChangerType": "Diffusion-SVC",
"lang": "ja-JP",
"tag": ["diffsuion-svc", "torch"],
"name": "初期メン(3,20)",
"modelUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/diffusion-svc/combo_spk5_nl3_dl20_k50_500ep.ptc.bin",
"termsOfUseUrl": "https://huggingface.co/wok000/vcclient_model/raw/main/diffusion-svc/term_of_use.txt",
"icon": "https://huggingface.co/wok000/vcclient_model/resolve/main/diffusion-svc/diffusion-svc.png",
"credit": "あみたろ,つくよみちゃん,黄琴海月,黄琴まひろ,刻鳴時雨",
"description": "",
"sampleRate": 44100,
"modelType": "combo",
"f0": true,
"numOfDiffLayers":20,
"numOfNativeLayers":3,
"maxKStep":50
},
{
"id": "diffusion_combo_spk5_nl3_dl10_k50_500ep",
"voiceChangerType": "Diffusion-SVC",
"lang": "ja-JP",
"tag": ["diffsuion-svc", "torch"],
"name": "初期メン(3,10)",
"modelUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/diffusion-svc/combo_spk5_nl3_dl10_k50_500ep.ptc.bin",
"termsOfUseUrl": "https://huggingface.co/wok000/vcclient_model/raw/main/diffusion-svc/term_of_use.txt",
"icon": "https://huggingface.co/wok000/vcclient_model/resolve/main/diffusion-svc/diffusion-svc.png",
"credit": "あみたろ,つくよみちゃん,黄琴海月,黄琴まひろ,刻鳴時雨",
"description": "",
"sampleRate": 44100,
"modelType": "combo",
"f0": true,
"numOfDiffLayers":10,
"numOfNativeLayers":3,
"maxKStep":50
},
{
"id": "diffusion_combo_spk5_nl3_dl1_k50_500ep",
"voiceChangerType": "Diffusion-SVC",
"lang": "ja-JP",
"tag": ["diffsuion-svc", "torch"],
"name": "初期メン(3,1)",
"modelUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/diffusion-svc/combo_spk5_nl3_dl1_k50_500ep.ptc.bin",
"termsOfUseUrl": "https://huggingface.co/wok000/vcclient_model/raw/main/diffusion-svc/term_of_use.txt",
"icon": "https://huggingface.co/wok000/vcclient_model/resolve/main/diffusion-svc/diffusion-svc.png",
"credit": "あみたろ,つくよみちゃん,黄琴海月,黄琴まひろ,刻鳴時雨",
"description": "",
"sampleRate": 44100,
"modelType": "combo",
"f0": true,
"numOfDiffLayers":1,
"numOfNativeLayers":3,
"maxKStep":50
},
{
"id": "diffusion_combo_spk5_nl1_dl1_k50_500ep",
"voiceChangerType": "Diffusion-SVC",
"lang": "ja-JP",
"tag": ["diffsuion-svc", "torch"],
"name": "初期メン(1,1)",
"modelUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/diffusion-svc/combo_spk5_nl1_dl1_k50_500ep.ptc.bin",
"termsOfUseUrl": "https://huggingface.co/wok000/vcclient_model/raw/main/diffusion-svc/term_of_use.txt",
"icon": "https://huggingface.co/wok000/vcclient_model/resolve/main/diffusion-svc/diffusion-svc.png",
"credit": "あみたろ,つくよみちゃん,黄琴海月,黄琴まひろ,刻鳴時雨",
"description": "",
"sampleRate": 44100,
"modelType": "combo",
"f0": true,
"numOfDiffLayers":1,
"numOfNativeLayers":1,
"maxKStep":50
}
]
}

View File

@ -45,6 +45,7 @@ class DiffusionSVC(VoiceChangerModel):
self.settings.tran = self.slotInfo.defaultTune
self.settings.dstId = self.slotInfo.dstId
self.settings.kStep = self.slotInfo.defaultKstep
self.settings.speedUp = self.slotInfo.defaultSpeedup
print("[Voice Changer] [DiffusionSVC] Initializing... done")

View File

@ -9,6 +9,15 @@ from voice_changer.DiffusionSVC.inferencer.diffusion_svc_model.diffusion.unit2me
from voice_changer.utils.LoadModelParams import LoadModelParams
from voice_changer.utils.ModelSlotGenerator import ModelSlotGenerator
def get_divisors(n):
divisors = []
for i in range(1, int(n**0.5)+1):
if n % i == 0:
divisors.append(i)
if i != n // i:
divisors.append(n //i)
return sorted(divisors)
class DiffusionSVCModelSlotGenerator(ModelSlotGenerator):
@classmethod
@ -20,7 +29,7 @@ class DiffusionSVCModelSlotGenerator(ModelSlotGenerator):
slotInfo.defaultTune = 0
slotInfo.isONNX = slotInfo.modelFile.endswith(".onnx")
slotInfo.name = os.path.splitext(os.path.basename(slotInfo.modelFile))[0]
slotInfo.iconFile = "/assets/icons/noimage.png"
# slotInfo.iconFile = "/assets/icons/noimage.png"
slotInfo.embChannels = 768
if slotInfo.isONNX:
@ -35,7 +44,9 @@ class DiffusionSVCModelSlotGenerator(ModelSlotGenerator):
slot.kStepMax = diff_args.model.k_step_max
slot.nLayers = diff_args.model.n_layers
slot.nnLayers = naive_args.model.n_layers
diff_args.model.n_spk
slot.defaultKstep = slot.kStepMax
divs = get_divisors(slot.defaultKstep)
slot.defaultSpeedup = divs[-2]
slot.speakers = {(x+1): f"user{x+1}" for x in range(diff_args.model.n_spk)}
return slot

View File

@ -119,7 +119,8 @@ class VoiceChangerManager(ServerDeviceCallbacks):
def loadModel(self, params: LoadModelParams):
if params.isSampleMode:
# サンプルダウンロード
downloadSample(self.params.sample_mode, params.sampleId, self.params.model_dir, params.slot, {"useIndex": params.params["rvcIndexDownload"]})
print("[Voice Changer] sample download....", params)
downloadSample(self.params.sample_mode, params.sampleId, self.params.model_dir, params.slot, params.params)
self.modelSlotManager.getAllSlotInfo(reload=True)
info = {"status": "OK"}
return info