improve half precision check, and fallback(exp.)

This commit is contained in:
wataru 2023-06-03 15:29:35 +09:00
parent 38b614e88c
commit 35230d3a59
4 changed files with 42 additions and 16 deletions

View File

@ -26,3 +26,8 @@ class NotEnoughDataExtimateF0(Exception):
class ONNXInputArgumentException(Exception):
def __str__(self):
return repr("ONNX received invalid argument.")
class DeviceCannotSupportHalfPrecisionException(Exception):
def __str__(self):
return repr("Device cannot support half precision.")

View File

@ -40,7 +40,7 @@ from voice_changer.RVC.pipeline.PipelineGenerator import createPipeline
from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager
from voice_changer.RVC.pipeline.Pipeline import Pipeline
from Exceptions import NoModeLoadedException
from Exceptions import DeviceCannotSupportHalfPrecisionException, NoModeLoadedException
from const import RVC_MODEL_DIRNAME, SAMPLES_JSONS, UPLOAD_DIR
import shutil
import json
@ -209,6 +209,7 @@ class RVC:
setattr(self.settings, key, val)
if key == "gpu":
self.deviceManager.setForceTensor(False)
self.prepareModel(self.settings.modelSlotIndex)
elif key in self.settings.floatData:
@ -340,7 +341,8 @@ class RVC:
# self.switchModel()
# self.needSwitch = False
half = self.deviceManager.halfPrecisionAvailable(self.settings.gpu)
# half = self.deviceManager.halfPrecisionAvailable(self.settings.gpu)
half = self.pipeline.isHalf
audio = data[0]
convertSize = data[1]
@ -361,20 +363,26 @@ class RVC:
if_f0 = 1 if self.settings.modelSlots[self.currentSlot].f0 else 0
embOutputLayer = self.settings.modelSlots[self.currentSlot].embOutputLayer
useFinalProj = self.settings.modelSlots[self.currentSlot].useFinalProj
audio_out = self.pipeline.exec(
sid,
audio,
f0_up_key,
index_rate,
if_f0,
self.settings.extraConvertSize
/ self.settings.modelSamplingRate, # extaraDataSizeの秒数。RVCのモデルのサンプリングレートで処理(★1)。
embOutputLayer,
useFinalProj,
repeat,
protect,
)
try:
audio_out = self.pipeline.exec(
sid,
audio,
f0_up_key,
index_rate,
if_f0,
self.settings.extraConvertSize
/ self.settings.modelSamplingRate, # extaraDataSizeの秒数。RVCのモデルのサンプリングレートで処理(★1)。
embOutputLayer,
useFinalProj,
repeat,
protect,
)
except DeviceCannotSupportHalfPrecisionException:
print(
"[Device Manager] Device cannot support half precision. Fallback to float...."
)
self.deviceManager.setForceTensor(True)
self.prepareModel(self.settings.modelSlotIndex)
result = audio_out.detach().cpu().numpy() * np.sqrt(vol)

View File

@ -4,6 +4,7 @@ import onnxruntime
class DeviceManager(object):
_instance = None
forceTensor: bool = False
@classmethod
def get_instance(cls):
@ -42,11 +43,16 @@ class DeviceManager(object):
}
]
def setForceTensor(self, forceTensor: bool):
self.forceTensor = forceTensor
def halfPrecisionAvailable(self, id: int):
if self.gpu_num == 0:
return False
if id < 0:
return False
if self.forceTensor:
return False
try:
gpuName = torch.cuda.get_device_name(id).upper()
@ -61,6 +67,10 @@ class DeviceManager(object):
print(e)
return False
cap = torch.cuda.get_device_capability(id)
if cap[0] < 7: # コンピューティング機能が7以上の場合half precisionが使えるとされているが例外があるT500とか
return False
return True
def getDeviceMemory(self, id: int):

View File

@ -4,6 +4,7 @@ import math
import torch
import torch.nn.functional as F
from Exceptions import (
DeviceCannotSupportHalfPrecisionException,
DeviceChangingException,
HalfPrecisionChangingException,
NotEnoughDataExtimateF0,
@ -130,6 +131,8 @@ class Pipeline(object):
padding_mask = torch.BoolTensor(feats.shape).to(self.device).fill_(False)
try:
feats = self.embedder.extractFeatures(feats, embOutputLayer, useFinalProj)
if all(i is None for i in feats):
raise DeviceCannotSupportHalfPrecisionException()
except RuntimeError as e:
if "HALF" in e.__str__().upper():
raise HalfPrecisionChangingException()