logger, handle creating pipeline exception

This commit is contained in:
w-okada 2023-07-27 04:06:25 +09:00
parent d2a2826a82
commit f96b4c2414
23 changed files with 276 additions and 166 deletions

View File

@ -39,3 +39,13 @@ class VoiceChangerIsNotSelectedException(Exception):
class WeightDownladException(Exception): class WeightDownladException(Exception):
def __str__(self): def __str__(self):
return repr("Failed to download weight.") return repr("Failed to download weight.")
class PipelineCreateException(Exception):
def __str__(self):
return repr("Failed to create Pipeline.")
class PipelineNotInitializedException(Exception):
def __str__(self):
return repr("Pipeline is not initialized.")

View File

@ -1,4 +1,3 @@
import logging
import sys import sys
from distutils.util import strtobool from distutils.util import strtobool
@ -25,10 +24,10 @@ from const import (
) )
import subprocess import subprocess
import multiprocessing as mp import multiprocessing as mp
from mods.log_control import setup_loggers from mods.log_control import VoiceChangaerLogger
setup_loggers(f"Booting PHASE :{__name__}") logger = VoiceChangaerLogger.get_instance().getLogger()
logger = logging.getLogger("vcclient") logger.debug(f"---------------- Booting PHASE :{__name__} -----------------")
def setupArgParser(): def setupArgParser():
@ -62,22 +61,23 @@ def printMessage(message, level=0):
pf = platform.system() pf = platform.system()
if pf == "Windows": if pf == "Windows":
if level == 0: if level == 0:
print(f"{message}") message = f"{message}"
elif level == 1: elif level == 1:
print(f" {message}") message = f" {message}"
elif level == 2: elif level == 2:
print(f" {message}") message = f" {message}"
else: else:
print(f" {message}") message = f" {message}"
else: else:
if level == 0: if level == 0:
print(f"\033[17m{message}\033[0m") message = f"\033[17m{message}\033[0m"
elif level == 1: elif level == 1:
print(f"\033[34m {message}\033[0m") message = f"\033[34m {message}\033[0m"
elif level == 2: elif level == 2:
print(f"\033[32m {message}\033[0m") message = f"\033[32m {message}\033[0m"
else: else:
print(f"\033[47m {message}\033[0m") message = f"\033[47m {message}\033[0m"
logger.info(message)
parser = setupArgParser() parser = setupArgParser()
@ -112,7 +112,7 @@ def localServer(logLevel: str = "critical"):
log_level=logLevel, log_level=logLevel,
) )
except Exception as e: except Exception as e:
print("[Voice Changer] Web Server Launch Exception", e) logger.error(f"[Voice Changer] Web Server Launch Exception, {e}")
if __name__ == "MMVCServerSIO": if __name__ == "MMVCServerSIO":
@ -129,7 +129,7 @@ if __name__ == "__mp_main__":
if __name__ == "__main__": if __name__ == "__main__":
mp.freeze_support() mp.freeze_support()
logger.info(args) logger.debug(args)
printMessage(f"PYTHON:{sys.version}", level=2) printMessage(f"PYTHON:{sys.version}", level=2)
printMessage("Voice Changerを起動しています。", level=2) printMessage("Voice Changerを起動しています。", level=2)
@ -139,14 +139,12 @@ if __name__ == "__main__":
except WeightDownladException: except WeightDownladException:
printMessage("RVC用のモデルファイルのダウンロードに失敗しました。", level=2) printMessage("RVC用のモデルファイルのダウンロードに失敗しました。", level=2)
printMessage("failed to download weight for rvc", level=2) printMessage("failed to download weight for rvc", level=2)
logger.warn("failed to download weight for rvc")
# ダウンロード(Sample) # ダウンロード(Sample)
try: try:
downloadInitialSamples(args.sample_mode, args.model_dir) downloadInitialSamples(args.sample_mode, args.model_dir)
except Exception as e: except Exception as e:
print("[Voice Changer] loading sample failed", e) printMessage(f"[Voice Changer] loading sample failed {e}", level=2)
logger.warn(f"[Voice Changer] loading sample failed {e}",)
# PORT = args.p # PORT = args.p
@ -232,7 +230,7 @@ if __name__ == "__main__":
log_level=args.logLevel, log_level=args.logLevel,
) )
except Exception as e: except Exception as e:
print("[Voice Changer] Web Server Launch Exception", e) logger.error(f"[Voice Changer] Web Server(https) Launch Exception, {e}")
else: else:
p = mp.Process(name="p", target=localServer, args=(args.logLevel,)) p = mp.Process(name="p", target=localServer, args=(args.logLevel,))
@ -241,13 +239,13 @@ if __name__ == "__main__":
if sys.platform.startswith("win"): if sys.platform.startswith("win"):
process = subprocess.Popen([NATIVE_CLIENT_FILE_WIN, "--disable-gpu", "-u", f"http://localhost:{PORT}/"]) process = subprocess.Popen([NATIVE_CLIENT_FILE_WIN, "--disable-gpu", "-u", f"http://localhost:{PORT}/"])
return_code = process.wait() return_code = process.wait()
print("client closed.") logger.info("client closed.")
p.terminate() p.terminate()
elif sys.platform.startswith("darwin"): elif sys.platform.startswith("darwin"):
process = subprocess.Popen([NATIVE_CLIENT_FILE_MAC, "--disable-gpu", "-u", f"http://localhost:{PORT}/"]) process = subprocess.Popen([NATIVE_CLIENT_FILE_MAC, "--disable-gpu", "-u", f"http://localhost:{PORT}/"])
return_code = process.wait() return_code = process.wait()
print("client closed.") logger.info("client closed.")
p.terminate() p.terminate()
except Exception as e: except Exception as e:
print(e) logger.error(f"[Voice Changer] Launch Exception, {e}")

View File

@ -2,6 +2,10 @@ import requests # type: ignore
import os import os
from tqdm import tqdm from tqdm import tqdm
from mods.log_control import VoiceChangaerLogger
logger = VoiceChangaerLogger.get_instance().getLogger()
def download(params): def download(params):
url = params["url"] url = params["url"]
@ -31,7 +35,7 @@ def download(params):
f.write(chunk) f.write(chunk)
except Exception as e: except Exception as e:
print(e) logger.warning(e)
def download_no_tqdm(params): def download_no_tqdm(params):
@ -51,6 +55,6 @@ def download_no_tqdm(params):
if countToDot % 1024 == 0: if countToDot % 1024 == 0:
print(".", end="", flush=True) print(".", end="", flush=True)
print("+", end="", flush=True) logger.info(f"[Voice Changer] download sample catalog. {saveTo}")
except Exception as e: except Exception as e:
print(e) logger.warning(e)

View File

@ -6,17 +6,20 @@ from typing import Any, Tuple
from const import RVCSampleMode, getSampleJsonAndModelIds from const import RVCSampleMode, getSampleJsonAndModelIds
from data.ModelSample import ModelSamples, generateModelSample from data.ModelSample import ModelSamples, generateModelSample
from data.ModelSlot import DiffusionSVCModelSlot, ModelSlot, RVCModelSlot from data.ModelSlot import DiffusionSVCModelSlot, ModelSlot, RVCModelSlot
from mods.log_control import VoiceChangaerLogger
from voice_changer.DiffusionSVC.DiffusionSVCModelSlotGenerator import DiffusionSVCModelSlotGenerator from voice_changer.DiffusionSVC.DiffusionSVCModelSlotGenerator import DiffusionSVCModelSlotGenerator
from voice_changer.ModelSlotManager import ModelSlotManager from voice_changer.ModelSlotManager import ModelSlotManager
from voice_changer.RVC.RVCModelSlotGenerator import RVCModelSlotGenerator from voice_changer.RVC.RVCModelSlotGenerator import RVCModelSlotGenerator
from downloader.Downloader import download, download_no_tqdm from downloader.Downloader import download, download_no_tqdm
logger = VoiceChangaerLogger.get_instance().getLogger()
def downloadInitialSamples(mode: RVCSampleMode, model_dir: str): def downloadInitialSamples(mode: RVCSampleMode, model_dir: str):
sampleJsonUrls, sampleModels = getSampleJsonAndModelIds(mode) sampleJsonUrls, sampleModels = getSampleJsonAndModelIds(mode)
sampleJsons = _downloadSampleJsons(sampleJsonUrls) sampleJsons = _downloadSampleJsons(sampleJsonUrls)
if os.path.exists(model_dir): if os.path.exists(model_dir):
print("[Voice Changer] model_dir is already exists. skip download samples.") logger.info("[Voice Changer] model_dir is already exists. skip download samples.")
return return
samples = _generateSampleList(sampleJsons) samples = _generateSampleList(sampleJsons)
slotIndex = list(range(len(sampleModels))) slotIndex = list(range(len(sampleModels)))
@ -85,7 +88,7 @@ def _downloadSamples(samples: list[ModelSamples], sampleModelIds: list[Tuple[str
match = True match = True
break break
if match is False: if match is False:
print(f"[Voice Changer] initiail sample not found. {targetSampleId}") logger.warn(f"[Voice Changer] initiail sample not found. {targetSampleId}")
continue continue
# 検出されたら、、、 # 検出されたら、、、
@ -194,10 +197,10 @@ def _downloadSamples(samples: list[ModelSamples], sampleModelIds: list[Tuple[str
slotInfo.isONNX = slotInfo.modelFile.endswith(".onnx") slotInfo.isONNX = slotInfo.modelFile.endswith(".onnx")
modelSlotManager.save_model_slot(targetSlotIndex, slotInfo) modelSlotManager.save_model_slot(targetSlotIndex, slotInfo)
else: else:
print(f"[Voice Changer] {sample.voiceChangerType} is not supported.") logger.warn(f"[Voice Changer] {sample.voiceChangerType} is not supported.")
# ダウンロード # ダウンロード
print("[Voice Changer] Downloading model files...") logger.info("[Voice Changer] Downloading model files...")
if withoutTqdm: if withoutTqdm:
with ThreadPoolExecutor() as pool: with ThreadPoolExecutor() as pool:
pool.map(download_no_tqdm, downloadParams) pool.map(download_no_tqdm, downloadParams)
@ -206,7 +209,7 @@ def _downloadSamples(samples: list[ModelSamples], sampleModelIds: list[Tuple[str
pool.map(download, downloadParams) pool.map(download, downloadParams)
# メタデータ作成 # メタデータ作成
print("[Voice Changer] Generating metadata...") logger.info("[Voice Changer] Generating metadata...")
for targetSlotIndex in slotIndex: for targetSlotIndex in slotIndex:
slotInfo = modelSlotManager.get_slot_info(targetSlotIndex) slotInfo = modelSlotManager.get_slot_info(targetSlotIndex)
if slotInfo.voiceChangerType == "RVC": if slotInfo.voiceChangerType == "RVC":

View File

@ -1,12 +1,12 @@
import logging
import os import os
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
from downloader.Downloader import download from downloader.Downloader import download
from mods.log_control import VoiceChangaerLogger
from voice_changer.utils.VoiceChangerParams import VoiceChangerParams from voice_changer.utils.VoiceChangerParams import VoiceChangerParams
from Exceptions import WeightDownladException from Exceptions import WeightDownladException
logger = logging.getLogger("vcclient") logger = VoiceChangaerLogger.get_instance().getLogger()
def downloadWeight(voiceChangerParams: VoiceChangerParams): def downloadWeight(voiceChangerParams: VoiceChangerParams):
@ -120,7 +120,7 @@ def downloadWeight(voiceChangerParams: VoiceChangerParams):
for weight in weight_files: for weight in weight_files:
if os.path.exists(weight): if os.path.exists(weight):
file_size = os.path.getsize(weight) file_size = os.path.getsize(weight)
logger.info(f"weight file [{weight}]: {file_size}") logger.debug(f"weight file [{weight}]: {file_size}")
else: else:
logger.warn(f"weight file is missing. {weight}") logger.warning(f"weight file is missing. {weight}")
raise WeightDownladException() raise WeightDownladException()

View File

@ -8,40 +8,123 @@ class UvicornSuppressFilter(logging.Filter):
return False return False
class NullHandler(logging.Handler):
def emit(self, record):
pass
class VoiceChangaerLogger:
_instance = None
@classmethod
def get_instance(cls):
if cls._instance is None:
cls._instance = cls()
return cls._instance
def __init__(self):
# logger = logging.getLogger("uvicorn.error")
# logger.addFilter(UvicornSuppressFilter())
# logging.basicConfig(filename='myapp.log', level=logging.INFO)
# logging.basicConfig(level=logging.NOTSET)
logging.root.handlers = [NullHandler()]
logger = logging.getLogger("fairseq.tasks.hubert_pretraining")
logger.addFilter(UvicornSuppressFilter())
logger = logging.getLogger("fairseq.models.hubert.hubert")
logger.addFilter(UvicornSuppressFilter())
logger = logging.getLogger("fairseq.tasks.text_to_speech")
logger.addFilter(UvicornSuppressFilter())
logger = logging.getLogger("numba.core.ssa")
logger.addFilter(UvicornSuppressFilter())
logger = logging.getLogger("numba.core.interpreter")
logger.addFilter(UvicornSuppressFilter())
logger = logging.getLogger("numba.core.byteflow")
logger.addFilter(UvicornSuppressFilter())
# logger.propagate = False
logger = logging.getLogger("multipart.multipart")
logger.propagate = False
logging.getLogger("asyncio").setLevel(logging.WARNING)
logger = logging.getLogger("vcclient")
logger.setLevel(logging.DEBUG)
if not logger.handlers:
# pass
# file_handler = logging.FileHandler('vvclient.log', encoding='utf-8', mode='w')
file_handler = logging.FileHandler('vvclient.log', encoding='utf-8')
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(process)d - %(message)s')
file_handler.setFormatter(file_formatter)
file_handler.setLevel(logging.DEBUG)
logger.addHandler(file_handler)
stream_formatter = logging.Formatter('%(message)s')
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(stream_formatter)
stream_handler.setLevel(logging.INFO)
logger.addHandler(stream_handler)
self.logger = logger
def getLogger(self):
return self.logger
def setup_loggers(startMessage: str): def setup_loggers(startMessage: str):
# logger = logging.getLogger("uvicorn.error") pass
# # logger = logging.getLogger("uvicorn.error")
# # logger.addFilter(UvicornSuppressFilter())
# logger = logging.getLogger("fairseq.tasks.hubert_pretraining")
# logger.addFilter(UvicornSuppressFilter()) # logger.addFilter(UvicornSuppressFilter())
logger = logging.getLogger("fairseq.tasks.hubert_pretraining") # logger = logging.getLogger("fairseq.models.hubert.hubert")
logger.addFilter(UvicornSuppressFilter()) # logger.addFilter(UvicornSuppressFilter())
logger = logging.getLogger("fairseq.models.hubert.hubert") # logger = logging.getLogger("fairseq.tasks.text_to_speech")
logger.addFilter(UvicornSuppressFilter()) # logger.addFilter(UvicornSuppressFilter())
logger = logging.getLogger("fairseq.tasks.text_to_speech") # logger = logging.getLogger("numba.core.ssa")
logger.addFilter(UvicornSuppressFilter()) # logger.addFilter(UvicornSuppressFilter())
logger = logging.getLogger("numba.core.ssa") # logger = logging.getLogger("numba.core.interpreter")
logger.addFilter(UvicornSuppressFilter()) # logger.addFilter(UvicornSuppressFilter())
logger = logging.getLogger("numba.core.interpreter") # logger = logging.getLogger("numba.core.byteflow")
logger.addFilter(UvicornSuppressFilter()) # logger.addFilter(UvicornSuppressFilter())
logger = logging.getLogger("numba.core.byteflow") # # logger.propagate = False
logger.addFilter(UvicornSuppressFilter())
# logger = logging.getLogger("multipart.multipart")
# logger.propagate = False # logger.propagate = False
logger = logging.getLogger("multipart.multipart") # logging.getLogger("asyncio").setLevel(logging.WARNING)
logger.propagate = False
logging.getLogger("asyncio").setLevel(logging.WARNING) # logger = logging.getLogger("vcclient")
# logger.setLevel(logging.DEBUG)
logger = logging.getLogger("vcclient") # if not logger.handlers:
logger.setLevel(logging.INFO) # # file_handler = logging.FileHandler('vvclient.log', encoding='utf-8', mode='w')
fh = logging.FileHandler('vvclient.log', encoding='utf-8') # file_handler = logging.FileHandler('vvclient.log', encoding='utf-8')
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(process)d - %(message)s')
fh.setFormatter(formatter) # file_handler.setFormatter(file_formatter)
fh.setLevel(logging.INFO) # file_handler.setLevel(logging.INFO)
logger.addHandler(fh) # logger.addHandler(file_handler)
logger.info(f"Start Logging, {startMessage}")
# stream_formatter = logging.Formatter('%(message)s')
# stream_handler = logging.StreamHandler()
# stream_handler.setFormatter(stream_formatter)
# stream_handler.setLevel(logging.DEBUG)
# logger.addHandler(stream_handler)
# logger.info(f"Start Logging, {startMessage}")

View File

@ -1,6 +1,7 @@
from dataclasses import asdict from dataclasses import asdict
import numpy as np import numpy as np
from data.ModelSlot import DiffusionSVCModelSlot from data.ModelSlot import DiffusionSVCModelSlot
from mods.log_control import VoiceChangaerLogger
from voice_changer.DiffusionSVC.DiffusionSVCSettings import DiffusionSVCSettings from voice_changer.DiffusionSVC.DiffusionSVCSettings import DiffusionSVCSettings
from voice_changer.DiffusionSVC.inferencer.InferencerManager import InferencerManager from voice_changer.DiffusionSVC.inferencer.InferencerManager import InferencerManager
from voice_changer.DiffusionSVC.pipeline.Pipeline import Pipeline from voice_changer.DiffusionSVC.pipeline.Pipeline import Pipeline
@ -13,12 +14,14 @@ from voice_changer.RVC.embedder.EmbedderManager import EmbedderManager
# from voice_changer.RVC.onnxExporter.export2onnx import export2onnx # from voice_changer.RVC.onnxExporter.export2onnx import export2onnx
from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager
from Exceptions import DeviceCannotSupportHalfPrecisionException from Exceptions import DeviceCannotSupportHalfPrecisionException, PipelineCreateException
logger = VoiceChangaerLogger.get_instance().getLogger()
class DiffusionSVC(VoiceChangerModel): class DiffusionSVC(VoiceChangerModel):
def __init__(self, params: VoiceChangerParams, slotInfo: DiffusionSVCModelSlot): def __init__(self, params: VoiceChangerParams, slotInfo: DiffusionSVCModelSlot):
print("[Voice Changer] [DiffusionSVC] Creating instance ") logger.info("[Voice Changer] [DiffusionSVC] Creating instance ")
self.deviceManager = DeviceManager.get_instance() self.deviceManager = DeviceManager.get_instance()
EmbedderManager.initialize(params) EmbedderManager.initialize(params)
PitchExtractorManager.initialize(params) PitchExtractorManager.initialize(params)
@ -36,10 +39,14 @@ class DiffusionSVC(VoiceChangerModel):
self.slotInfo = slotInfo self.slotInfo = slotInfo
def initialize(self): def initialize(self):
print("[Voice Changer] [DiffusionSVC] Initializing... ") logger.info("[Voice Changer] [DiffusionSVC] Initializing... ")
# pipelineの生成 # pipelineの生成
self.pipeline = createPipeline(self.slotInfo, self.settings.gpu, self.settings.f0Detector, self.inputSampleRate, self.outputSampleRate) try:
self.pipeline = createPipeline(self.slotInfo, self.settings.gpu, self.settings.f0Detector, self.inputSampleRate, self.outputSampleRate)
except PipelineCreateException as e: # NOQA
logger.error("[Voice Changer] pipeline create failed. check your model is valid.")
return
# その他の設定 # その他の設定
self.settings.tran = self.slotInfo.defaultTune self.settings.tran = self.slotInfo.defaultTune
@ -47,7 +54,7 @@ class DiffusionSVC(VoiceChangerModel):
self.settings.kStep = self.slotInfo.defaultKstep self.settings.kStep = self.slotInfo.defaultKstep
self.settings.speedUp = self.slotInfo.defaultSpeedup self.settings.speedUp = self.slotInfo.defaultSpeedup
print("[Voice Changer] [DiffusionSVC] Initializing... done") logger.info("[Voice Changer] [DiffusionSVC] Initializing... done")
def setSamplingRate(self, inputSampleRate, outputSampleRate): def setSamplingRate(self, inputSampleRate, outputSampleRate):
self.inputSampleRate = inputSampleRate self.inputSampleRate = inputSampleRate
@ -55,7 +62,7 @@ class DiffusionSVC(VoiceChangerModel):
self.initialize() self.initialize()
def update_settings(self, key: str, val: int | float | str): def update_settings(self, key: str, val: int | float | str):
print("[Voice Changer][DiffusionSVC]: update_settings", key, val) logger.info(f"[Voice Changer][DiffusionSVC]: update_settings {key}:{val}")
if key in self.settings.intData: if key in self.settings.intData:
setattr(self.settings, key, int(val)) setattr(self.settings, key, int(val))
if key == "gpu": if key == "gpu":
@ -174,7 +181,7 @@ class DiffusionSVC(VoiceChangerModel):
result = audio_out.detach().cpu().numpy() result = audio_out.detach().cpu().numpy()
return result return result
except DeviceCannotSupportHalfPrecisionException as e: # NOQA except DeviceCannotSupportHalfPrecisionException as e: # NOQA
print("[Device Manager] Device cannot support half precision. Fallback to float....") logger.warn("[Device Manager] Device cannot support half precision. Fallback to float....")
self.deviceManager.setForceTensor(True) self.deviceManager.setForceTensor(True)
self.initialize() self.initialize()
# raise e # raise e

View File

@ -8,6 +8,7 @@ from Exceptions import (
HalfPrecisionChangingException, HalfPrecisionChangingException,
NotEnoughDataExtimateF0, NotEnoughDataExtimateF0,
) )
from mods.log_control import VoiceChangaerLogger
from voice_changer.DiffusionSVC.inferencer.Inferencer import Inferencer from voice_changer.DiffusionSVC.inferencer.Inferencer import Inferencer
from voice_changer.DiffusionSVC.pitchExtractor.PitchExtractor import PitchExtractor from voice_changer.DiffusionSVC.pitchExtractor.PitchExtractor import PitchExtractor
@ -17,9 +18,8 @@ from voice_changer.common.VolumeExtractor import VolumeExtractor
from torchaudio.transforms import Resample from torchaudio.transforms import Resample
from voice_changer.utils.Timer import Timer from voice_changer.utils.Timer import Timer
import logging
logger = logging.getLogger("vcclient") logger = VoiceChangaerLogger.get_instance().getLogger()
class Pipeline(object): class Pipeline(object):
@ -60,17 +60,11 @@ class Pipeline(object):
self.resamplerIn = resamplerIn self.resamplerIn = resamplerIn
self.resamplerOut = resamplerOut self.resamplerOut = resamplerOut
print("VOLUME EXTRACTOR", self.volumeExtractor)
print("GENERATE INFERENCER", self.inferencer)
print("GENERATE EMBEDDER", self.embedder)
print("GENERATE PITCH EXTRACTOR", self.pitchExtractor)
logger.info("VOLUME EXTRACTOR" + str(self.volumeExtractor)) logger.info("VOLUME EXTRACTOR" + str(self.volumeExtractor))
logger.info("GENERATE INFERENCER" + str(self.inferencer)) logger.info("GENERATE INFERENCER" + str(self.inferencer))
logger.info("GENERATE EMBEDDER" + str(self.embedder)) logger.info("GENERATE EMBEDDER" + str(self.embedder))
logger.info("GENERATE PITCH EXTRACTOR" + str(self.pitchExtractor)) logger.info("GENERATE PITCH EXTRACTOR" + str(self.pitchExtractor))
self.targetSR = targetSR self.targetSR = targetSR
self.device = device self.device = device
self.isHalf = False self.isHalf = False

View File

@ -1,4 +1,5 @@
import traceback import traceback
from Exceptions import PipelineCreateException
from data.ModelSlot import DiffusionSVCModelSlot from data.ModelSlot import DiffusionSVCModelSlot
from voice_changer.DiffusionSVC.inferencer.InferencerManager import InferencerManager from voice_changer.DiffusionSVC.inferencer.InferencerManager import InferencerManager
from voice_changer.DiffusionSVC.pipeline.Pipeline import Pipeline from voice_changer.DiffusionSVC.pipeline.Pipeline import Pipeline
@ -22,6 +23,7 @@ def createPipeline(modelSlot: DiffusionSVCModelSlot, gpu: int, f0Detector: str,
except Exception as e: except Exception as e:
print("[Voice Changer] exception! loading inferencer", e) print("[Voice Changer] exception! loading inferencer", e)
traceback.print_exc() traceback.print_exc()
raise PipelineCreateException("[Voice Changer] exception! loading inferencer")
# Embedder 生成 # Embedder 生成
try: try:
@ -34,6 +36,7 @@ def createPipeline(modelSlot: DiffusionSVCModelSlot, gpu: int, f0Detector: str,
except Exception as e: except Exception as e:
print("[Voice Changer] exception! loading embedder", e) print("[Voice Changer] exception! loading embedder", e)
traceback.print_exc() traceback.print_exc()
raise PipelineCreateException("[Voice Changer] exception! loading embedder")
# pitchExtractor # pitchExtractor
pitchExtractor = PitchExtractorManager.getPitchExtractor(f0Detector, gpu) pitchExtractor = PitchExtractorManager.getPitchExtractor(f0Detector, gpu)

View File

@ -1,5 +1,8 @@
import wave import wave
import os import os
from mods.log_control import VoiceChangaerLogger
logger = VoiceChangaerLogger.get_instance().getLogger()
class IORecorder: class IORecorder:
@ -19,10 +22,10 @@ class IORecorder:
def _clearFile(self, filename: str): def _clearFile(self, filename: str):
if os.path.exists(filename): if os.path.exists(filename):
print("[IORecorder] delete old analyze file.", filename) logger.info(f"[IORecorder] delete old analyze file. {filename}")
os.remove(filename) os.remove(filename)
else: else:
print("[IORecorder] old analyze file not exist.", filename) logger.info(f"[IORecorder] old analyze file not exist. {filename}")
def writeInput(self, wav): def writeInput(self, wav):
self.fi.writeframes(wav) self.fi.writeframes(wav)

View File

@ -4,8 +4,11 @@ from dataclasses import dataclass, field
import numpy as np import numpy as np
from const import ServerAudioDeviceType from const import ServerAudioDeviceType
from mods.log_control import VoiceChangaerLogger
# from const import SERVER_DEVICE_SAMPLE_RATES # from const import SERVER_DEVICE_SAMPLE_RATES
logger = VoiceChangaerLogger.get_instance().getLogger()
@dataclass @dataclass
class ServerAudioDevice: class ServerAudioDevice:
@ -56,8 +59,8 @@ def list_audio_device():
try: try:
audioDeviceList = sd.query_devices() audioDeviceList = sd.query_devices()
except Exception as e: except Exception as e:
print("[Voice Changer] ex:query_devices") logger.error("[Voice Changer] ex:query_devices")
print(e) logger.exception(e)
raise e raise e
inputAudioDeviceList = [d for d in audioDeviceList if d["max_input_channels"] > 0] inputAudioDeviceList = [d for d in audioDeviceList if d["max_input_channels"] > 0]

View File

@ -4,6 +4,7 @@ import numpy as np
from const import SERVER_DEVICE_SAMPLE_RATES from const import SERVER_DEVICE_SAMPLE_RATES
from queue import Queue from queue import Queue
from mods.log_control import VoiceChangaerLogger
from voice_changer.Local.AudioDeviceList import checkSamplingRate, list_audio_device from voice_changer.Local.AudioDeviceList import checkSamplingRate, list_audio_device
import time import time
@ -17,6 +18,8 @@ from typing import Union
from typing import Literal, TypeAlias from typing import Literal, TypeAlias
AudioDeviceKind: TypeAlias = Literal["input", "output"] AudioDeviceKind: TypeAlias = Literal["input", "output"]
logger = VoiceChangaerLogger.get_instance().getLogger()
@dataclass @dataclass
class ServerDeviceSettings: class ServerDeviceSettings:

View File

@ -4,7 +4,7 @@ import sys
import json import json
import logging import logging
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) # logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
logger = logging logger = logging
hann_window = {} hann_window = {}

View File

@ -1,11 +1,12 @@
import logging
from const import UPLOAD_DIR from const import UPLOAD_DIR
from data.ModelSlot import ModelSlots, loadAllSlotInfo, saveSlotInfo from data.ModelSlot import ModelSlots, loadAllSlotInfo, saveSlotInfo
import json import json
import os import os
import shutil import shutil
logger = logging.getLogger("vcclient") from mods.log_control import VoiceChangaerLogger
logger = VoiceChangaerLogger.get_instance().getLogger()
class ModelSlotManager: class ModelSlotManager:
@ -14,7 +15,7 @@ class ModelSlotManager:
def __init__(self, model_dir: str): def __init__(self, model_dir: str):
self.model_dir = model_dir self.model_dir = model_dir
self.modelSlots = loadAllSlotInfo(self.model_dir) self.modelSlots = loadAllSlotInfo(self.model_dir)
logger.info(f"[MODEL SLOT INFO] {self.modelSlots}") logger.debug(f"[MODEL SLOT INFO] {self.modelSlots}")
@classmethod @classmethod
def get_instance(cls, model_dir: str): def get_instance(cls, model_dir: str):
@ -41,7 +42,7 @@ class ModelSlotManager:
self._save_model_slot(slotIndex, slotInfo) self._save_model_slot(slotIndex, slotInfo)
def update_model_info(self, newData: str): def update_model_info(self, newData: str):
print("[Voice Changer] UPDATE MODEL INFO", newData) logger.info(f"[Voice Changer] UPDATE MODEL INFO, {newData}")
newDataDict = json.loads(newData) newDataDict = json.loads(newData)
slotInfo = self._load_model_slot(newDataDict["slot"]) slotInfo = self._load_model_slot(newDataDict["slot"])
if newDataDict["key"] == "speakers": if newDataDict["key"] == "speakers":
@ -64,4 +65,5 @@ class ModelSlotManager:
setattr(slotInfo, paramsDict["name"], storePath) setattr(slotInfo, paramsDict["name"], storePath)
self._save_model_slot(paramsDict["slot"], slotInfo) self._save_model_slot(paramsDict["slot"], slotInfo)
except Exception as e: except Exception as e:
print("Exception::::", e) logger.info(f"[Voice Changer] Exception: {e}")
logger.error(e)

View File

@ -1,25 +1,9 @@
# import sys
# import os
from dataclasses import asdict from dataclasses import asdict
import numpy as np import numpy as np
import torch import torch
import torchaudio import torchaudio
from data.ModelSlot import RVCModelSlot from data.ModelSlot import RVCModelSlot
from mods.log_control import VoiceChangaerLogger
# # avoiding parse arg error in RVC
# sys.argv = ["MMVCServerSIO.py"]
# if sys.platform.startswith("darwin"):
# baseDir = [x for x in sys.path if x.endswith("Contents/MacOS")]
# if len(baseDir) != 1:
# print("baseDir should be only one ", baseDir)
# sys.exit()
# modulePath = os.path.join(baseDir[0], "RVC")
# sys.path.append(modulePath)
# else:
# sys.path.append("RVC")
from voice_changer.RVC.RVCSettings import RVCSettings from voice_changer.RVC.RVCSettings import RVCSettings
from voice_changer.RVC.embedder.EmbedderManager import EmbedderManager from voice_changer.RVC.embedder.EmbedderManager import EmbedderManager
@ -31,18 +15,20 @@ from voice_changer.RVC.pipeline.PipelineGenerator import createPipeline
from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager
from voice_changer.RVC.pipeline.Pipeline import Pipeline from voice_changer.RVC.pipeline.Pipeline import Pipeline
from Exceptions import DeviceCannotSupportHalfPrecisionException from Exceptions import DeviceCannotSupportHalfPrecisionException, PipelineCreateException, PipelineNotInitializedException
logger = VoiceChangaerLogger.get_instance().getLogger()
class RVC(VoiceChangerModel): class RVC(VoiceChangerModel):
def __init__(self, params: VoiceChangerParams, slotInfo: RVCModelSlot): def __init__(self, params: VoiceChangerParams, slotInfo: RVCModelSlot):
print("[Voice Changer] [RVC] Creating instance ") logger.info("[Voice Changer] [RVC] Creating instance ")
self.deviceManager = DeviceManager.get_instance() self.deviceManager = DeviceManager.get_instance()
EmbedderManager.initialize(params) EmbedderManager.initialize(params)
PitchExtractorManager.initialize(params) PitchExtractorManager.initialize(params)
self.settings = RVCSettings() self.settings = RVCSettings()
self.params = params self.params = params
self.pitchExtractor = PitchExtractorManager.getPitchExtractor(self.settings.f0Detector, self.settings.gpu) # self.pitchExtractor = PitchExtractorManager.getPitchExtractor(self.settings.f0Detector, self.settings.gpu)
self.pipeline: Pipeline | None = None self.pipeline: Pipeline | None = None
@ -54,19 +40,23 @@ class RVC(VoiceChangerModel):
# self.initialize() # self.initialize()
def initialize(self): def initialize(self):
print("[Voice Changer] [RVC] Initializing... ") logger.info("[Voice Changer][RVC] Initializing... ")
# pipelineの生成 # pipelineの生成
self.pipeline = createPipeline(self.slotInfo, self.settings.gpu, self.settings.f0Detector) try:
self.pipeline = createPipeline(self.slotInfo, self.settings.gpu, self.settings.f0Detector)
except PipelineCreateException as e: # NOQA
logger.error("[Voice Changer] pipeline create failed. check your model is valid.")
return
# その他の設定 # その他の設定
self.settings.tran = self.slotInfo.defaultTune self.settings.tran = self.slotInfo.defaultTune
self.settings.indexRatio = self.slotInfo.defaultIndexRatio self.settings.indexRatio = self.slotInfo.defaultIndexRatio
self.settings.protect = self.slotInfo.defaultProtect self.settings.protect = self.slotInfo.defaultProtect
print("[Voice Changer] [RVC] Initializing... done") logger.info("[Voice Changer] [RVC] Initializing... done")
def update_settings(self, key: str, val: int | float | str): def update_settings(self, key: str, val: int | float | str):
print("[Voice Changer][RVC]: update_settings", key, val) logger.info(f"[Voice Changer][RVC]: update_settings {key}:{val}")
if key in self.settings.intData: if key in self.settings.intData:
setattr(self.settings, key, int(val)) setattr(self.settings, key, int(val))
if key == "gpu": if key == "gpu":
@ -88,6 +78,8 @@ class RVC(VoiceChangerModel):
if self.pipeline is not None: if self.pipeline is not None:
pipelineInfo = self.pipeline.getPipelineInfo() pipelineInfo = self.pipeline.getPipelineInfo()
data["pipelineInfo"] = pipelineInfo data["pipelineInfo"] = pipelineInfo
else:
data["pipelineInfo"] = "None"
return data return data
def get_processing_sampling_rate(self): def get_processing_sampling_rate(self):
@ -146,6 +138,9 @@ class RVC(VoiceChangerModel):
return (self.audio_buffer, self.pitchf_buffer, self.feature_buffer, convertSize, vol, outSize) return (self.audio_buffer, self.pitchf_buffer, self.feature_buffer, convertSize, vol, outSize)
def inference(self, data): def inference(self, data):
if self.pipeline is None:
logger.info("[Voice Changer] Pipeline is not initialized.111")
raise PipelineNotInitializedException()
audio = data[0] audio = data[0]
pitchf = data[1] pitchf = data[1]
feature = data[2] feature = data[2]
@ -192,7 +187,7 @@ class RVC(VoiceChangerModel):
return result return result
except DeviceCannotSupportHalfPrecisionException as e: # NOQA except DeviceCannotSupportHalfPrecisionException as e: # NOQA
print("[Device Manager] Device cannot support half precision. Fallback to float....") logger.warn("[Device Manager] Device cannot support half precision. Fallback to float....")
self.deviceManager.setForceTensor(True) self.deviceManager.setForceTensor(True)
self.initialize() self.initialize()
# raise e # raise e
@ -222,7 +217,7 @@ class RVC(VoiceChangerModel):
modelSlot = self.slotInfo modelSlot = self.slotInfo
if modelSlot.isONNX: if modelSlot.isONNX:
print("[Voice Changer] export2onnx, No pyTorch filepath.") logger.warn("[Voice Changer] export2onnx, No pyTorch filepath.")
return {"status": "ng", "path": ""} return {"status": "ng", "path": ""}
if self.pipeline is not None: if self.pipeline is not None:

View File

@ -20,7 +20,7 @@ from .config import TrainConfig
matplotlib.use("Agg") matplotlib.use("Agg")
logging.getLogger("matplotlib").setLevel(logging.WARNING) logging.getLogger("matplotlib").setLevel(logging.WARNING)
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) # logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
logger = logging logger = logging

View File

@ -10,6 +10,7 @@ from Exceptions import (
HalfPrecisionChangingException, HalfPrecisionChangingException,
NotEnoughDataExtimateF0, NotEnoughDataExtimateF0,
) )
from mods.log_control import VoiceChangaerLogger
from voice_changer.RVC.embedder.Embedder import Embedder from voice_changer.RVC.embedder.Embedder import Embedder
from voice_changer.RVC.inferencer.Inferencer import Inferencer from voice_changer.RVC.inferencer.Inferencer import Inferencer
@ -17,9 +18,8 @@ from voice_changer.RVC.inferencer.OnnxRVCInferencer import OnnxRVCInferencer
from voice_changer.RVC.inferencer.OnnxRVCInferencerNono import OnnxRVCInferencerNono from voice_changer.RVC.inferencer.OnnxRVCInferencerNono import OnnxRVCInferencerNono
from voice_changer.RVC.pitchExtractor.PitchExtractor import PitchExtractor from voice_changer.RVC.pitchExtractor.PitchExtractor import PitchExtractor
import logging
logger = logging.getLogger("vcclient") logger = VoiceChangaerLogger.get_instance().getLogger()
class Pipeline(object): class Pipeline(object):
@ -49,9 +49,6 @@ class Pipeline(object):
self.embedder = embedder self.embedder = embedder
self.inferencer = inferencer self.inferencer = inferencer
self.pitchExtractor = pitchExtractor self.pitchExtractor = pitchExtractor
print("GENERATE INFERENCER", self.inferencer)
print("GENERATE EMBEDDER", self.embedder)
print("GENERATE PITCH EXTRACTOR", self.pitchExtractor)
logger.info("GENERATE INFERENCER" + str(self.inferencer)) logger.info("GENERATE INFERENCER" + str(self.inferencer))
logger.info("GENERATE EMBEDDER" + str(self.embedder)) logger.info("GENERATE EMBEDDER" + str(self.embedder))
logger.info("GENERATE PITCH EXTRACTOR" + str(self.pitchExtractor)) logger.info("GENERATE PITCH EXTRACTOR" + str(self.pitchExtractor))

View File

@ -1,6 +1,7 @@
import os import os
import traceback import traceback
import faiss import faiss
from Exceptions import PipelineCreateException
from data.ModelSlot import RVCModelSlot from data.ModelSlot import RVCModelSlot
from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager
@ -20,6 +21,7 @@ def createPipeline(modelSlot: RVCModelSlot, gpu: int, f0Detector: str):
except Exception as e: except Exception as e:
print("[Voice Changer] exception! loading inferencer", e) print("[Voice Changer] exception! loading inferencer", e)
traceback.print_exc() traceback.print_exc()
raise PipelineCreateException("[Voice Changer] exception! loading inferencer")
# Embedder 生成 # Embedder 生成
try: try:
@ -30,8 +32,9 @@ def createPipeline(modelSlot: RVCModelSlot, gpu: int, f0Detector: str):
dev, dev,
) )
except Exception as e: except Exception as e:
print("[Voice Changer] exception! loading embedder", e, dev) print("[Voice Changer] exception! loading embedder", e, dev)
traceback.print_exc() traceback.print_exc()
raise PipelineCreateException("[Voice Changer] exception! loading embedder")
# pitchExtractor # pitchExtractor
pitchExtractor = PitchExtractorManager.getPitchExtractor(f0Detector, gpu) pitchExtractor = PitchExtractorManager.getPitchExtractor(f0Detector, gpu)

View File

@ -7,7 +7,7 @@ import numpy as np
from sklearn.cluster import KMeans, MiniBatchKMeans from sklearn.cluster import KMeans, MiniBatchKMeans
import tqdm import tqdm
logging.basicConfig(level=logging.INFO) #logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
import time import time

View File

@ -15,7 +15,7 @@ import torch
MATPLOTLIB_FLAG = False MATPLOTLIB_FLAG = False
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) # logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
logger = logging logger = logging
f0_bin = 256 f0_bin = 256

View File

@ -1,14 +1,13 @@
import logging
from typing import Any, Union, cast from typing import Any, Union, cast
from const import TMP_DIR from const import TMP_DIR
import torch import torch
import os import os
import traceback
import numpy as np import numpy as np
from dataclasses import dataclass, asdict, field from dataclasses import dataclass, asdict, field
import resampy import resampy
import onnxruntime import onnxruntime
from mods.log_control import VoiceChangaerLogger
from voice_changer.IORecorder import IORecorder from voice_changer.IORecorder import IORecorder
@ -22,13 +21,14 @@ from Exceptions import (
NoModeLoadedException, NoModeLoadedException,
NotEnoughDataExtimateF0, NotEnoughDataExtimateF0,
ONNXInputArgumentException, ONNXInputArgumentException,
PipelineNotInitializedException,
VoiceChangerIsNotSelectedException, VoiceChangerIsNotSelectedException,
) )
from voice_changer.utils.VoiceChangerParams import VoiceChangerParams from voice_changer.utils.VoiceChangerParams import VoiceChangerParams
STREAM_INPUT_FILE = os.path.join(TMP_DIR, "in.wav") STREAM_INPUT_FILE = os.path.join(TMP_DIR, "in.wav")
STREAM_OUTPUT_FILE = os.path.join(TMP_DIR, "out.wav") STREAM_OUTPUT_FILE = os.path.join(TMP_DIR, "out.wav")
logger = logging.getLogger("vcclient") logger = VoiceChangaerLogger.get_instance().getLogger()
@dataclass @dataclass
@ -81,7 +81,6 @@ class VoiceChanger(VoiceChangerIF):
self.mps_enabled: bool = getattr(torch.backends, "mps", None) is not None and torch.backends.mps.is_available() self.mps_enabled: bool = getattr(torch.backends, "mps", None) is not None and torch.backends.mps.is_available()
self.onnx_device = onnxruntime.get_device() self.onnx_device = onnxruntime.get_device()
print(f"VoiceChanger Initialized (GPU_NUM(cuda):{self.gpu_num}, mps_enabled:{self.mps_enabled}, onnx_device:{self.onnx_device})")
logger.info(f"VoiceChanger Initialized (GPU_NUM(cuda):{self.gpu_num}, mps_enabled:{self.mps_enabled}, onnx_device:{self.onnx_device})") logger.info(f"VoiceChanger Initialized (GPU_NUM(cuda):{self.gpu_num}, mps_enabled:{self.mps_enabled}, onnx_device:{self.onnx_device})")
def setModel(self, model: Any): def setModel(self, model: Any):
@ -104,7 +103,7 @@ class VoiceChanger(VoiceChangerIF):
def update_settings(self, key: str, val: Any): def update_settings(self, key: str, val: Any):
if self.voiceChanger is None: if self.voiceChanger is None:
print("[Voice Changer] Voice Changer is not selected.") logger.warn("[Voice Changer] Voice Changer is not selected.")
return self.get_info() return self.get_info()
if key == "serverAudioStated" and val == 0: if key == "serverAudioStated" and val == 0:
@ -168,8 +167,7 @@ class VoiceChanger(VoiceChangerIF):
] ]
) )
print(f"Generated Strengths: for prev:{self.np_prev_strength.shape}, for cur:{self.np_cur_strength.shape}") logger.info(f"Generated Strengths: for prev:{self.np_prev_strength.shape}, for cur:{self.np_cur_strength.shape}")
# ひとつ前の結果とサイズが変わるため、記録は消去する。 # ひとつ前の結果とサイズが変わるため、記録は消去する。
if hasattr(self, "np_prev_audio1") is True: if hasattr(self, "np_prev_audio1") is True:
delattr(self, "np_prev_audio1") delattr(self, "np_prev_audio1")
@ -247,7 +245,7 @@ class VoiceChanger(VoiceChangerIF):
result = output_wav result = output_wav
else: else:
print("[Voice Changer] warming up... generating sola buffer.") logger.info("[Voice Changer] warming up... generating sola buffer.")
result = np.zeros(4096).astype(np.int16) result = np.zeros(4096).astype(np.int16)
if hasattr(self, "sola_buffer") is True and sola_offset < sola_search_frame: if hasattr(self, "sola_buffer") is True and sola_offset < sola_search_frame:
@ -304,29 +302,31 @@ class VoiceChanger(VoiceChangerIF):
return outputData, perf return outputData, perf
except NoModeLoadedException as e: except NoModeLoadedException as e:
print("[Voice Changer] [Exception]", e) logger.warn(f"[Voice Changer] [Exception], {e}")
return np.zeros(1).astype(np.int16), [0, 0, 0] return np.zeros(1).astype(np.int16), [0, 0, 0]
except ONNXInputArgumentException as e: except ONNXInputArgumentException as e:
print("[Voice Changer] [Exception] onnx are waiting valid input.", e) logger.warn(f"[Voice Changer] [Exception] onnx are waiting valid input., {e}")
return np.zeros(1).astype(np.int16), [0, 0, 0] return np.zeros(1).astype(np.int16), [0, 0, 0]
except HalfPrecisionChangingException: except HalfPrecisionChangingException:
print("[Voice Changer] Switching model configuration....") logger.warn("[Voice Changer] Switching model configuration....")
return np.zeros(1).astype(np.int16), [0, 0, 0] return np.zeros(1).astype(np.int16), [0, 0, 0]
except NotEnoughDataExtimateF0: except NotEnoughDataExtimateF0:
print("[Voice Changer] warming up... waiting more data.") logger.warn("[Voice Changer] warming up... waiting more data.")
return np.zeros(1).astype(np.int16), [0, 0, 0] return np.zeros(1).astype(np.int16), [0, 0, 0]
except DeviceChangingException as e: except DeviceChangingException as e:
print("[Voice Changer] embedder:", e) logger.warn(f"[Voice Changer] embedder: {e}")
return np.zeros(1).astype(np.int16), [0, 0, 0] return np.zeros(1).astype(np.int16), [0, 0, 0]
except VoiceChangerIsNotSelectedException: except VoiceChangerIsNotSelectedException:
print("[Voice Changer] Voice Changer is not selected. Wait a bit and if there is no improvement, please re-select vc.") logger.warn("[Voice Changer] Voice Changer is not selected. Wait a bit and if there is no improvement, please re-select vc.")
return np.zeros(1).astype(np.int16), [0, 0, 0] return np.zeros(1).astype(np.int16), [0, 0, 0]
except DeviceCannotSupportHalfPrecisionException: except DeviceCannotSupportHalfPrecisionException:
# RVC.pyでfallback処理をするので、ここはダミーデータ返すだけ。 # RVC.pyでfallback処理をするので、ここはダミーデータ返すだけ。
return np.zeros(1).astype(np.int16), [0, 0, 0] return np.zeros(1).astype(np.int16), [0, 0, 0]
except PipelineNotInitializedException:
return np.zeros(1).astype(np.int16), [0, 0, 0]
except Exception as e: except Exception as e:
print("[Voice Changer] VC PROCESSING EXCEPTION!!!", e) logger.warn(f"[Voice Changer] VC PROCESSING EXCEPTION!!! {e}")
print(traceback.format_exc()) logger.exception(e)
return np.zeros(1).astype(np.int16), [0, 0, 0] return np.zeros(1).astype(np.int16), [0, 0, 0]
def export2onnx(self): def export2onnx(self):
@ -336,7 +336,7 @@ class VoiceChanger(VoiceChangerIF):
def merge_models(self, request: str): def merge_models(self, request: str):
if self.voiceChanger is None: if self.voiceChanger is None:
print("[Voice Changer] Voice Changer is not selected.") logger.info("[Voice Changer] Voice Changer is not selected.")
return return
self.voiceChanger.merge_models(request) self.voiceChanger.merge_models(request)
return self.get_info() return self.get_info()
@ -348,7 +348,7 @@ PRINT_CONVERT_PROCESSING: bool = False
def print_convert_processing(mess: str): def print_convert_processing(mess: str):
if PRINT_CONVERT_PROCESSING is True: if PRINT_CONVERT_PROCESSING is True:
print(mess) logger.info(mess)
def pad_array(arr: AudioInOut, target_length: int): def pad_array(arr: AudioInOut, target_length: int):

View File

@ -5,6 +5,7 @@ import shutil
import threading import threading
import numpy as np import numpy as np
from downloader.SampleDownloader import downloadSample, getSampleInfos from downloader.SampleDownloader import downloadSample, getSampleInfos
from mods.log_control import VoiceChangaerLogger
from voice_changer.Local.ServerDevice import ServerDevice, ServerDeviceCallbacks from voice_changer.Local.ServerDevice import ServerDevice, ServerDeviceCallbacks
from voice_changer.ModelSlotManager import ModelSlotManager from voice_changer.ModelSlotManager import ModelSlotManager
from voice_changer.RVC.RVCModelMerger import RVCModelMerger from voice_changer.RVC.RVCModelMerger import RVCModelMerger
@ -23,6 +24,9 @@ from typing import Callable
from typing import Any from typing import Any
logger = VoiceChangaerLogger.get_instance().getLogger()
@dataclass() @dataclass()
class GPUInfo: class GPUInfo:
id: int id: int
@ -123,7 +127,7 @@ class VoiceChangerManager(ServerDeviceCallbacks):
def loadModel(self, params: LoadModelParams): def loadModel(self, params: LoadModelParams):
if params.isSampleMode: if params.isSampleMode:
# サンプルダウンロード # サンプルダウンロード
print("[Voice Changer] sample download....", params) logger.info(f"[Voice Changer] sample download...., {params}")
downloadSample(self.params.sample_mode, params.sampleId, self.params.model_dir, params.slot, params.params) downloadSample(self.params.sample_mode, params.sampleId, self.params.model_dir, params.slot, params.params)
self.modelSlotManager.getAllSlotInfo(reload=True) self.modelSlotManager.getAllSlotInfo(reload=True)
info = {"status": "OK"} info = {"status": "OK"}
@ -132,7 +136,7 @@ class VoiceChangerManager(ServerDeviceCallbacks):
# アップローダ # アップローダ
# ファイルをslotにコピー # ファイルをslotにコピー
for file in params.files: for file in params.files:
print("FILE", file) logger.info(f"FILE: {file}")
srcPath = os.path.join(UPLOAD_DIR, file.dir, file.name) srcPath = os.path.join(UPLOAD_DIR, file.dir, file.name)
dstDir = os.path.join( dstDir = os.path.join(
self.params.model_dir, self.params.model_dir,
@ -141,7 +145,7 @@ class VoiceChangerManager(ServerDeviceCallbacks):
) )
dstPath = os.path.join(dstDir, file.name) dstPath = os.path.join(dstDir, file.name)
os.makedirs(dstDir, exist_ok=True) os.makedirs(dstDir, exist_ok=True)
print(f"move to {srcPath} -> {dstPath}") logger.info(f"move to {srcPath} -> {dstPath}")
shutil.move(srcPath, dstPath) shutil.move(srcPath, dstPath)
file.name = dstPath file.name = dstPath
@ -176,7 +180,7 @@ class VoiceChangerManager(ServerDeviceCallbacks):
slotInfo = DiffusionSVCModelSlotGenerator.loadModel(params) slotInfo = DiffusionSVCModelSlotGenerator.loadModel(params)
self.modelSlotManager.save_model_slot(params.slot, slotInfo) self.modelSlotManager.save_model_slot(params.slot, slotInfo)
print("params", params) logger.info(f"params, {params}")
def get_info(self): def get_info(self):
data = asdict(self.settings) data = asdict(self.settings)
@ -206,52 +210,52 @@ class VoiceChangerManager(ServerDeviceCallbacks):
def generateVoiceChanger(self, val: int): def generateVoiceChanger(self, val: int):
slotInfo = self.modelSlotManager.get_slot_info(val) slotInfo = self.modelSlotManager.get_slot_info(val)
if slotInfo is None: if slotInfo is None:
print(f"[Voice Changer] model slot is not found {val}") logger.info(f"[Voice Changer] model slot is not found {val}")
return return
elif slotInfo.voiceChangerType == "RVC": elif slotInfo.voiceChangerType == "RVC":
print("................RVC") logger.info("................RVC")
from voice_changer.RVC.RVC import RVC from voice_changer.RVC.RVC import RVC
self.voiceChangerModel = RVC(self.params, slotInfo) self.voiceChangerModel = RVC(self.params, slotInfo)
self.voiceChanger = VoiceChanger(self.params) self.voiceChanger = VoiceChanger(self.params)
self.voiceChanger.setModel(self.voiceChangerModel) self.voiceChanger.setModel(self.voiceChangerModel)
elif slotInfo.voiceChangerType == "MMVCv13": elif slotInfo.voiceChangerType == "MMVCv13":
print("................MMVCv13") logger.info("................MMVCv13")
from voice_changer.MMVCv13.MMVCv13 import MMVCv13 from voice_changer.MMVCv13.MMVCv13 import MMVCv13
self.voiceChangerModel = MMVCv13(slotInfo) self.voiceChangerModel = MMVCv13(slotInfo)
self.voiceChanger = VoiceChanger(self.params) self.voiceChanger = VoiceChanger(self.params)
self.voiceChanger.setModel(self.voiceChangerModel) self.voiceChanger.setModel(self.voiceChangerModel)
elif slotInfo.voiceChangerType == "MMVCv15": elif slotInfo.voiceChangerType == "MMVCv15":
print("................MMVCv15") logger.info("................MMVCv15")
from voice_changer.MMVCv15.MMVCv15 import MMVCv15 from voice_changer.MMVCv15.MMVCv15 import MMVCv15
self.voiceChangerModel = MMVCv15(slotInfo) self.voiceChangerModel = MMVCv15(slotInfo)
self.voiceChanger = VoiceChanger(self.params) self.voiceChanger = VoiceChanger(self.params)
self.voiceChanger.setModel(self.voiceChangerModel) self.voiceChanger.setModel(self.voiceChangerModel)
elif slotInfo.voiceChangerType == "so-vits-svc-40": elif slotInfo.voiceChangerType == "so-vits-svc-40":
print("................so-vits-svc-40") logger.info("................so-vits-svc-40")
from voice_changer.SoVitsSvc40.SoVitsSvc40 import SoVitsSvc40 from voice_changer.SoVitsSvc40.SoVitsSvc40 import SoVitsSvc40
self.voiceChangerModel = SoVitsSvc40(self.params, slotInfo) self.voiceChangerModel = SoVitsSvc40(self.params, slotInfo)
self.voiceChanger = VoiceChanger(self.params) self.voiceChanger = VoiceChanger(self.params)
self.voiceChanger.setModel(self.voiceChangerModel) self.voiceChanger.setModel(self.voiceChangerModel)
elif slotInfo.voiceChangerType == "DDSP-SVC": elif slotInfo.voiceChangerType == "DDSP-SVC":
print("................DDSP-SVC") logger.info("................DDSP-SVC")
from voice_changer.DDSP_SVC.DDSP_SVC import DDSP_SVC from voice_changer.DDSP_SVC.DDSP_SVC import DDSP_SVC
self.voiceChangerModel = DDSP_SVC(self.params, slotInfo) self.voiceChangerModel = DDSP_SVC(self.params, slotInfo)
self.voiceChanger = VoiceChanger(self.params) self.voiceChanger = VoiceChanger(self.params)
self.voiceChanger.setModel(self.voiceChangerModel) self.voiceChanger.setModel(self.voiceChangerModel)
elif slotInfo.voiceChangerType == "Diffusion-SVC": elif slotInfo.voiceChangerType == "Diffusion-SVC":
print("................Diffusion-SVC") logger.info("................Diffusion-SVC")
from voice_changer.DiffusionSVC.DiffusionSVC import DiffusionSVC from voice_changer.DiffusionSVC.DiffusionSVC import DiffusionSVC
self.voiceChangerModel = DiffusionSVC(self.params, slotInfo) self.voiceChangerModel = DiffusionSVC(self.params, slotInfo)
self.voiceChanger = VoiceChangerV2(self.params) self.voiceChanger = VoiceChangerV2(self.params)
self.voiceChanger.setModel(self.voiceChangerModel) self.voiceChanger.setModel(self.voiceChangerModel)
else: else:
print(f"[Voice Changer] unknown voice changer model: {slotInfo.voiceChangerType}") logger.info(f"[Voice Changer] unknown voice changer model: {slotInfo.voiceChangerType}")
if hasattr(self, "voiceChangerModel"): if hasattr(self, "voiceChangerModel"):
del self.voiceChangerModel del self.voiceChangerModel
return return
@ -263,7 +267,7 @@ class VoiceChangerManager(ServerDeviceCallbacks):
newVal = int(val) newVal = int(val)
if key == "modelSlotIndex": if key == "modelSlotIndex":
newVal = newVal % 1000 newVal = newVal % 1000
print(f"[Voice Changer] model slot is changed {self.settings.modelSlotIndex} -> {newVal}") logger.info(f"[Voice Changer] model slot is changed {self.settings.modelSlotIndex} -> {newVal}")
self.generateVoiceChanger(newVal) self.generateVoiceChanger(newVal)
# キャッシュ設定の反映 # キャッシュ設定の反映
for k, v in self.stored_setting.items(): for k, v in self.stored_setting.items():
@ -282,7 +286,7 @@ class VoiceChangerManager(ServerDeviceCallbacks):
if hasattr(self, "voiceChanger") is True: if hasattr(self, "voiceChanger") is True:
return self.voiceChanger.on_request(receivedData) return self.voiceChanger.on_request(receivedData)
else: else:
print("Voice Change is not loaded. Did you load a correct model?") logger.info("Voice Change is not loaded. Did you load a correct model?")
return np.zeros(1).astype(np.int16), [] return np.zeros(1).astype(np.int16), []
def export2onnx(self): def export2onnx(self):

View File

@ -9,16 +9,15 @@
''' '''
import logging
from typing import Any, Union from typing import Any, Union
from const import TMP_DIR from const import TMP_DIR
import torch import torch
import os import os
import traceback
import numpy as np import numpy as np
from dataclasses import dataclass, asdict, field from dataclasses import dataclass, asdict, field
import onnxruntime import onnxruntime
from mods.log_control import VoiceChangaerLogger
from voice_changer.IORecorder import IORecorder from voice_changer.IORecorder import IORecorder
@ -38,7 +37,7 @@ from voice_changer.utils.VoiceChangerParams import VoiceChangerParams
STREAM_INPUT_FILE = os.path.join(TMP_DIR, "in.wav") STREAM_INPUT_FILE = os.path.join(TMP_DIR, "in.wav")
STREAM_OUTPUT_FILE = os.path.join(TMP_DIR, "out.wav") STREAM_OUTPUT_FILE = os.path.join(TMP_DIR, "out.wav")
logger = logging.getLogger("vcclient") logger = VoiceChangaerLogger.get_instance().getLogger()
@dataclass @dataclass
@ -91,7 +90,6 @@ class VoiceChangerV2(VoiceChangerIF):
self.mps_enabled: bool = getattr(torch.backends, "mps", None) is not None and torch.backends.mps.is_available() self.mps_enabled: bool = getattr(torch.backends, "mps", None) is not None and torch.backends.mps.is_available()
self.onnx_device = onnxruntime.get_device() self.onnx_device = onnxruntime.get_device()
print(f"VoiceChangerV2 Initialized (GPU_NUM(cuda):{self.gpu_num}, mps_enabled:{self.mps_enabled}, onnx_device:{self.onnx_device})")
logger.info(f"VoiceChangerV2 Initialized (GPU_NUM(cuda):{self.gpu_num}, mps_enabled:{self.mps_enabled}, onnx_device:{self.onnx_device})") logger.info(f"VoiceChangerV2 Initialized (GPU_NUM(cuda):{self.gpu_num}, mps_enabled:{self.mps_enabled}, onnx_device:{self.onnx_device})")
def setModel(self, model: VoiceChangerModel): def setModel(self, model: VoiceChangerModel):
@ -117,7 +115,7 @@ class VoiceChangerV2(VoiceChangerIF):
def update_settings(self, key: str, val: Any): def update_settings(self, key: str, val: Any):
if self.voiceChanger is None: if self.voiceChanger is None:
print("[Voice Changer] Voice Changer is not selected.") logger.warn("[Voice Changer] Voice Changer is not selected.")
return self.get_info() return self.get_info()
if key == "serverAudioStated" and val == 0: if key == "serverAudioStated" and val == 0:
@ -183,7 +181,7 @@ class VoiceChangerV2(VoiceChangerIF):
] ]
) )
print(f"Generated Strengths: for prev:{self.np_prev_strength.shape}, for cur:{self.np_cur_strength.shape}") logger.info(f"Generated Strengths: for prev:{self.np_prev_strength.shape}, for cur:{self.np_cur_strength.shape}")
# ひとつ前の結果とサイズが変わるため、記録は消去する。 # ひとつ前の結果とサイズが変わるため、記録は消去する。
if hasattr(self, "np_prev_audio1") is True: if hasattr(self, "np_prev_audio1") is True:
@ -243,7 +241,7 @@ class VoiceChangerV2(VoiceChangerIF):
result = output_wav result = output_wav
else: else:
print("[Voice Changer] warming up... generating sola buffer.") logger.info("[Voice Changer] warming up... generating sola buffer.")
result = np.zeros(4096).astype(np.int16) result = np.zeros(4096).astype(np.int16)
if hasattr(self, "sola_buffer") is True and sola_offset < sola_search_frame: if hasattr(self, "sola_buffer") is True and sola_offset < sola_search_frame:
@ -281,29 +279,29 @@ class VoiceChangerV2(VoiceChangerIF):
return outputData, perf return outputData, perf
except NoModeLoadedException as e: except NoModeLoadedException as e:
print("[Voice Changer] [Exception]", e) logger.warn(f"[Voice Changer] [Exception], {e}")
return np.zeros(1).astype(np.int16), [0, 0, 0] return np.zeros(1).astype(np.int16), [0, 0, 0]
except ONNXInputArgumentException as e: except ONNXInputArgumentException as e:
print("[Voice Changer] [Exception] onnx are waiting valid input.", e) logger.warn(f"[Voice Changer] [Exception] onnx are waiting valid input., {e}")
return np.zeros(1).astype(np.int16), [0, 0, 0] return np.zeros(1).astype(np.int16), [0, 0, 0]
except HalfPrecisionChangingException: except HalfPrecisionChangingException:
print("[Voice Changer] Switching model configuration....") logger.warn("[Voice Changer] Switching model configuration....")
return np.zeros(1).astype(np.int16), [0, 0, 0] return np.zeros(1).astype(np.int16), [0, 0, 0]
except NotEnoughDataExtimateF0: except NotEnoughDataExtimateF0:
print("[Voice Changer] warming up... waiting more data.") logger.warn("[Voice Changer] warming up... waiting more data.")
return np.zeros(1).astype(np.int16), [0, 0, 0] return np.zeros(1).astype(np.int16), [0, 0, 0]
except DeviceChangingException as e: except DeviceChangingException as e:
print("[Voice Changer] embedder:", e) logger.warn(f"[Voice Changer] embedder: {e}")
return np.zeros(1).astype(np.int16), [0, 0, 0] return np.zeros(1).astype(np.int16), [0, 0, 0]
except VoiceChangerIsNotSelectedException: except VoiceChangerIsNotSelectedException:
print("[Voice Changer] Voice Changer is not selected. Wait a bit and if there is no improvement, please re-select vc.") logger.warn("[Voice Changer] Voice Changer is not selected. Wait a bit and if there is no improvement, please re-select vc.")
return np.zeros(1).astype(np.int16), [0, 0, 0] return np.zeros(1).astype(np.int16), [0, 0, 0]
except DeviceCannotSupportHalfPrecisionException: except DeviceCannotSupportHalfPrecisionException:
# RVC.pyでfallback処理をするので、ここはダミーデータ返すだけ。 # RVC.pyでfallback処理をするので、ここはダミーデータ返すだけ。
return np.zeros(1).astype(np.int16), [0, 0, 0] return np.zeros(1).astype(np.int16), [0, 0, 0]
except Exception as e: except Exception as e:
print("[Voice Changer] VC PROCESSING EXCEPTION!!!", e) logger.warn(f"[Voice Changer] VC PROCESSING EXCEPTION!!! {e}")
print(traceback.format_exc()) logger.exception(e)
return np.zeros(1).astype(np.int16), [0, 0, 0] return np.zeros(1).astype(np.int16), [0, 0, 0]
def export2onnx(self): def export2onnx(self):
@ -313,7 +311,7 @@ class VoiceChangerV2(VoiceChangerIF):
def merge_models(self, request: str): def merge_models(self, request: str):
if self.voiceChanger is None: if self.voiceChanger is None:
print("[Voice Changer] Voice Changer is not selected.") logger.info("[Voice Changer] Voice Changer is not selected.")
return return
self.voiceChanger.merge_models(request) self.voiceChanger.merge_models(request)
return self.get_info() return self.get_info()
@ -325,7 +323,7 @@ PRINT_CONVERT_PROCESSING: bool = False
def print_convert_processing(mess: str): def print_convert_processing(mess: str):
if PRINT_CONVERT_PROCESSING is True: if PRINT_CONVERT_PROCESSING is True:
print(mess) logger.info(mess)
def pad_array(arr: AudioInOut, target_length: int): def pad_array(arr: AudioInOut, target_length: int):