voice-changer/server/data/ModelSlot.py

174 lines
5.7 KiB
Python
Raw Normal View History

2023-06-16 10:49:55 +03:00
from typing import TypeAlias, Union
2023-07-13 21:33:04 +03:00
from const import MAX_SLOT_NUM, DiffusionSVCInferenceType, EnumInferenceTypes, EmbedderType, VoiceChangerType
2023-06-16 10:49:55 +03:00
2023-06-23 08:00:40 +03:00
from dataclasses import dataclass, asdict, field
2023-06-16 10:49:55 +03:00
import os
import json
@dataclass
class ModelSlot:
2023-08-04 21:02:43 +03:00
slotIndex: int = -1
2023-06-16 10:49:55 +03:00
voiceChangerType: VoiceChangerType | None = None
2023-06-21 01:23:13 +03:00
name: str = ""
description: str = ""
credit: str = ""
termsOfUseUrl: str = ""
iconFile: str = ""
2023-06-23 08:00:40 +03:00
speakers: dict = field(default_factory=lambda: {})
2023-06-16 10:49:55 +03:00
@dataclass
class RVCModelSlot(ModelSlot):
voiceChangerType: VoiceChangerType = "RVC"
modelFile: str = ""
indexFile: str = ""
defaultTune: int = 0
defaultIndexRatio: int = 0
2023-06-16 10:49:55 +03:00
defaultProtect: float = 0.5
isONNX: bool = False
modelType: str = EnumInferenceTypes.pyTorchRVC.value
samplingRate: int = -1
f0: bool = True
embChannels: int = 256
embOutputLayer: int = 9
useFinalProj: bool = True
deprecated: bool = False
embedder: EmbedderType = "hubert_base"
2023-06-16 10:49:55 +03:00
sampleId: str = ""
2023-06-23 08:00:40 +03:00
speakers: dict = field(default_factory=lambda: {0: "target"})
2023-06-16 10:49:55 +03:00
2023-06-20 00:39:39 +03:00
@dataclass
class MMVCv13ModelSlot(ModelSlot):
voiceChangerType: VoiceChangerType = "MMVCv13"
modelFile: str = ""
configFile: str = ""
srcId: int = 107
dstId: int = 100
isONNX: bool = False
samplingRate: int = 24000
2023-06-23 08:00:40 +03:00
speakers: dict = field(default_factory=lambda: {107: "user", 100: "zundamon", 101: "sora", 102: "methane", 103: "tsumugi"})
2023-06-20 00:39:39 +03:00
@dataclass
class MMVCv15ModelSlot(ModelSlot):
voiceChangerType: VoiceChangerType = "MMVCv15"
modelFile: str = ""
configFile: str = ""
srcId: int = 0
dstId: int = 101
2023-06-21 01:23:13 +03:00
f0Factor: float = 1.0
2023-06-20 00:39:39 +03:00
isONNX: bool = False
samplingRate: int = 24000
2023-06-25 12:02:43 +03:00
speakers: dict = field(default_factory=lambda: {})
f0: dict = field(default_factory=lambda: {})
2023-06-20 00:39:39 +03:00
@dataclass
class SoVitsSvc40ModelSlot(ModelSlot):
voiceChangerType: VoiceChangerType = "so-vits-svc-40"
modelFile: str = ""
configFile: str = ""
clusterFile: str = ""
dstId: int = 0
isONNX: bool = False
sampleId: str = ""
2023-06-21 01:23:13 +03:00
defaultTune: int = 0
defaultClusterInferRatio: float = 0.0
noiseScale: float = 0.0
2023-06-23 08:00:40 +03:00
speakers: dict = field(default_factory=lambda: {1: "user"})
2023-06-20 00:39:39 +03:00
@dataclass
class DDSPSVCModelSlot(ModelSlot):
voiceChangerType: VoiceChangerType = "DDSP-SVC"
modelFile: str = ""
configFile: str = ""
diffModelFile: str = ""
diffConfigFile: str = ""
dstId: int = 0
isONNX: bool = False
sampleId: str = ""
2023-06-21 01:23:13 +03:00
defaultTune: int = 0
enhancer: bool = False
diffusion: bool = True
acc: int = 20
kstep: int = 100
2023-06-23 08:00:40 +03:00
speakers: dict = field(default_factory=lambda: {1: "user"})
2023-06-20 00:39:39 +03:00
2023-07-12 18:59:48 +03:00
@dataclass
class DiffusionSVCModelSlot(ModelSlot):
voiceChangerType: VoiceChangerType = "Diffusion-SVC"
modelFile: str = ""
isONNX: bool = False
2023-07-13 21:33:04 +03:00
modelType: DiffusionSVCInferenceType = "combo"
2023-07-12 18:59:48 +03:00
dstId: int = 1
sampleId: str = ""
defaultTune: int = 0
2023-07-15 04:01:42 +03:00
defaultKstep: int = 20
defaultSpeedup: int = 10
kStepMax: int = 100
nLayers: int = 20
nnLayers: int = 20
2023-07-12 18:59:48 +03:00
speakers: dict = field(default_factory=lambda: {1: "user"})
embedder: EmbedderType = "hubert_base"
2023-07-13 21:33:04 +03:00
samplingRate: int = 44100
embChannels: int = 768
2023-07-12 18:59:48 +03:00
ModelSlots: TypeAlias = Union[ModelSlot, RVCModelSlot, MMVCv13ModelSlot, MMVCv15ModelSlot, SoVitsSvc40ModelSlot, DDSPSVCModelSlot, DiffusionSVCModelSlot]
2023-06-16 10:49:55 +03:00
def loadSlotInfo(model_dir: str, slotIndex: int) -> ModelSlots:
slotDir = os.path.join(model_dir, str(slotIndex))
jsonFile = os.path.join(slotDir, "params.json")
if not os.path.exists(jsonFile):
return ModelSlot()
jsonDict = json.load(open(os.path.join(slotDir, "params.json")))
2023-08-04 21:02:43 +03:00
slotInfoKey = list(ModelSlot.__annotations__.keys())
slotInfo = ModelSlot(**{k: v for k, v in jsonDict.items() if k in slotInfoKey})
2023-06-16 10:49:55 +03:00
if slotInfo.voiceChangerType == "RVC":
2023-08-04 21:02:43 +03:00
slotInfoKey.extend(list(RVCModelSlot.__annotations__.keys()))
return RVCModelSlot(**{k: v for k, v in jsonDict.items() if k in slotInfoKey})
2023-06-20 00:39:39 +03:00
elif slotInfo.voiceChangerType == "MMVCv13":
2023-08-04 21:02:43 +03:00
slotInfoKey.extend(list(MMVCv13ModelSlot.__annotations__.keys()))
return MMVCv13ModelSlot(**{k: v for k, v in jsonDict.items() if k in slotInfoKey})
2023-06-20 00:39:39 +03:00
elif slotInfo.voiceChangerType == "MMVCv15":
2023-08-04 21:02:43 +03:00
slotInfoKey.extend(list(MMVCv15ModelSlot.__annotations__.keys()))
return MMVCv15ModelSlot(**{k: v for k, v in jsonDict.items() if k in slotInfoKey})
2023-06-20 00:39:39 +03:00
elif slotInfo.voiceChangerType == "so-vits-svc-40":
2023-08-04 21:02:43 +03:00
slotInfoKey.extend(list(SoVitsSvc40ModelSlot.__annotations__.keys()))
return SoVitsSvc40ModelSlot(**{k: v for k, v in jsonDict.items() if k in slotInfoKey})
2023-06-20 00:39:39 +03:00
elif slotInfo.voiceChangerType == "DDSP-SVC":
2023-08-04 21:02:43 +03:00
slotInfoKey.extend(list(DDSPSVCModelSlot.__annotations__.keys()))
return DDSPSVCModelSlot(**{k: v for k, v in jsonDict.items() if k in slotInfoKey})
2023-07-12 18:59:48 +03:00
elif slotInfo.voiceChangerType == "Diffusion-SVC":
2023-08-04 21:02:43 +03:00
slotInfoKey.extend(list(DiffusionSVCModelSlot.__annotations__.keys()))
return DiffusionSVCModelSlot(**{k: v for k, v in jsonDict.items() if k in slotInfoKey})
2023-06-16 10:49:55 +03:00
else:
return ModelSlot()
2023-06-16 11:12:03 +03:00
def loadAllSlotInfo(model_dir: str):
slotInfos: list[ModelSlots] = []
for slotIndex in range(MAX_SLOT_NUM):
slotInfo = loadSlotInfo(model_dir, slotIndex)
2023-08-04 21:02:43 +03:00
slotInfo.slotIndex = slotIndex # スロットインデックスは動的に注入
2023-06-16 11:12:03 +03:00
slotInfos.append(slotInfo)
return slotInfos
2023-06-16 10:49:55 +03:00
def saveSlotInfo(model_dir: str, slotIndex: int, slotInfo: ModelSlots):
slotDir = os.path.join(model_dir, str(slotIndex))
2023-08-04 21:02:43 +03:00
slotInfoDict = asdict(slotInfo)
slotInfo.slotIndex = -1 # スロットインデックスは動的に注入
json.dump(slotInfoDict, open(os.path.join(slotDir, "params.json"), "w"))