157 lines
5.0 KiB
Python
157 lines
5.0 KiB
Python
import shutil
|
|
import subprocess
|
|
import xml.etree.ElementTree as ElementTree
|
|
from functools import lru_cache
|
|
from typing import List, Optional
|
|
|
|
from onnxruntime import get_available_providers, set_default_logger_severity
|
|
|
|
import facefusion.choices
|
|
from facefusion.types import ExecutionDevice, ExecutionProvider, InferenceSessionProvider, ValueAndUnit
|
|
|
|
set_default_logger_severity(3)
|
|
|
|
|
|
def has_execution_provider(execution_provider : ExecutionProvider) -> bool:
|
|
return execution_provider in get_available_execution_providers()
|
|
|
|
|
|
def get_available_execution_providers() -> List[ExecutionProvider]:
|
|
inference_session_providers = get_available_providers()
|
|
available_execution_providers : List[ExecutionProvider] = []
|
|
|
|
for execution_provider, execution_provider_value in facefusion.choices.execution_provider_set.items():
|
|
if execution_provider_value in inference_session_providers:
|
|
index = facefusion.choices.execution_providers.index(execution_provider)
|
|
available_execution_providers.insert(index, execution_provider)
|
|
|
|
return available_execution_providers
|
|
|
|
|
|
def create_inference_session_providers(execution_device_id : str, execution_providers : List[ExecutionProvider]) -> List[InferenceSessionProvider]:
|
|
inference_session_providers : List[InferenceSessionProvider] = []
|
|
|
|
for execution_provider in execution_providers:
|
|
if execution_provider == 'cuda':
|
|
inference_session_providers.append((facefusion.choices.execution_provider_set.get(execution_provider),
|
|
{
|
|
'device_id': execution_device_id,
|
|
'cudnn_conv_algo_search': resolve_cudnn_conv_algo_search()
|
|
}))
|
|
if execution_provider == 'tensorrt':
|
|
inference_session_providers.append((facefusion.choices.execution_provider_set.get(execution_provider),
|
|
{
|
|
'device_id': execution_device_id,
|
|
'trt_engine_cache_enable': True,
|
|
'trt_engine_cache_path': '.caches',
|
|
'trt_timing_cache_enable': True,
|
|
'trt_timing_cache_path': '.caches',
|
|
'trt_builder_optimization_level': 5
|
|
}))
|
|
if execution_provider in [ 'directml', 'rocm' ]:
|
|
inference_session_providers.append((facefusion.choices.execution_provider_set.get(execution_provider),
|
|
{
|
|
'device_id': execution_device_id
|
|
}))
|
|
if execution_provider == 'openvino':
|
|
inference_session_providers.append((facefusion.choices.execution_provider_set.get(execution_provider),
|
|
{
|
|
'device_type': resolve_openvino_device_type(execution_device_id),
|
|
'precision': 'FP32'
|
|
}))
|
|
if execution_provider == 'coreml':
|
|
inference_session_providers.append((facefusion.choices.execution_provider_set.get(execution_provider),
|
|
{
|
|
'SpecializationStrategy': 'FastPrediction',
|
|
'ModelCacheDirectory': '.caches'
|
|
}))
|
|
|
|
if 'cpu' in execution_providers:
|
|
inference_session_providers.append(facefusion.choices.execution_provider_set.get('cpu'))
|
|
|
|
return inference_session_providers
|
|
|
|
|
|
def resolve_cudnn_conv_algo_search() -> str:
|
|
execution_devices = detect_static_execution_devices()
|
|
product_names = ('GeForce GTX 1630', 'GeForce GTX 1650', 'GeForce GTX 1660')
|
|
|
|
for execution_device in execution_devices:
|
|
if execution_device.get('product').get('name').startswith(product_names):
|
|
return 'DEFAULT'
|
|
|
|
return 'EXHAUSTIVE'
|
|
|
|
|
|
def resolve_openvino_device_type(execution_device_id : str) -> str:
|
|
if execution_device_id == '0':
|
|
return 'GPU'
|
|
if execution_device_id == '∞':
|
|
return 'MULTI:GPU'
|
|
return 'GPU.' + execution_device_id
|
|
|
|
|
|
def run_nvidia_smi() -> subprocess.Popen[bytes]:
|
|
commands = [ shutil.which('nvidia-smi'), '--query', '--xml-format' ]
|
|
return subprocess.Popen(commands, stdout = subprocess.PIPE)
|
|
|
|
|
|
@lru_cache(maxsize = None)
|
|
def detect_static_execution_devices() -> List[ExecutionDevice]:
|
|
return detect_execution_devices()
|
|
|
|
|
|
def detect_execution_devices() -> List[ExecutionDevice]:
|
|
execution_devices : List[ExecutionDevice] = []
|
|
|
|
try:
|
|
output, _ = run_nvidia_smi().communicate()
|
|
root_element = ElementTree.fromstring(output)
|
|
except Exception:
|
|
root_element = ElementTree.Element('xml')
|
|
|
|
for gpu_element in root_element.findall('gpu'):
|
|
execution_devices.append(
|
|
{
|
|
'driver_version': root_element.findtext('driver_version'),
|
|
'framework':
|
|
{
|
|
'name': 'CUDA',
|
|
'version': root_element.findtext('cuda_version')
|
|
},
|
|
'product':
|
|
{
|
|
'vendor': 'NVIDIA',
|
|
'name': gpu_element.findtext('product_name').replace('NVIDIA', '').strip()
|
|
},
|
|
'video_memory':
|
|
{
|
|
'total': create_value_and_unit(gpu_element.findtext('fb_memory_usage/total')),
|
|
'free': create_value_and_unit(gpu_element.findtext('fb_memory_usage/free'))
|
|
},
|
|
'temperature':
|
|
{
|
|
'gpu': create_value_and_unit(gpu_element.findtext('temperature/gpu_temp')),
|
|
'memory': create_value_and_unit(gpu_element.findtext('temperature/memory_temp'))
|
|
},
|
|
'utilization':
|
|
{
|
|
'gpu': create_value_and_unit(gpu_element.findtext('utilization/gpu_util')),
|
|
'memory': create_value_and_unit(gpu_element.findtext('utilization/memory_util'))
|
|
}
|
|
})
|
|
|
|
return execution_devices
|
|
|
|
|
|
def create_value_and_unit(text : str) -> Optional[ValueAndUnit]:
|
|
if ' ' in text:
|
|
value, unit = text.split()
|
|
|
|
return\
|
|
{
|
|
'value': int(value),
|
|
'unit': str(unit)
|
|
}
|
|
return None
|