Compare commits

...
17 Commits
8 changed files with 80 additions and 36 deletions
+11 -1
View File
@@ -3,7 +3,7 @@ import shutil
import subprocess import subprocess
import xml.etree.ElementTree as ElementTree import xml.etree.ElementTree as ElementTree
from functools import lru_cache from functools import lru_cache
from typing import List, Optional from typing import List, Optional, Tuple
import onnxruntime import onnxruntime
@@ -18,6 +18,16 @@ def has_execution_provider(execution_provider : ExecutionProvider) -> bool:
return execution_provider in get_available_execution_providers() return execution_provider in get_available_execution_providers()
@lru_cache()
def get_onnxruntime_version() -> Tuple[int, int, int]:
version_split = onnxruntime.__version__.split('.')
major_version = int(version_split[0])
minor_version = int(version_split[1])
patch_version = int(version_split[2].split('+')[0])
return major_version, minor_version, patch_version
def get_available_execution_providers() -> List[ExecutionProvider]: def get_available_execution_providers() -> List[ExecutionProvider]:
inference_session_providers = onnxruntime.get_available_providers() inference_session_providers = onnxruntime.get_available_providers()
available_execution_providers : List[ExecutionProvider] = [] available_execution_providers : List[ExecutionProvider] = []
+11 -9
View File
@@ -8,8 +8,7 @@ from onnxruntime import InferenceSession
from facefusion import logger, process_manager, state_manager, translator from facefusion import logger, process_manager, state_manager, translator
from facefusion.app_context import detect_app_context from facefusion.app_context import detect_app_context
from facefusion.common_helper import is_windows from facefusion.execution import create_inference_providers, get_onnxruntime_version, has_execution_provider
from facefusion.execution import create_inference_providers, has_execution_provider
from facefusion.exit_helper import fatal_exit from facefusion.exit_helper import fatal_exit
from facefusion.filesystem import get_file_name, is_file from facefusion.filesystem import get_file_name, is_file
from facefusion.time_helper import calculate_end_time from facefusion.time_helper import calculate_end_time
@@ -25,17 +24,21 @@ INFERENCE_POOL_SET : InferencePoolSet =\
def get_inference_pool(module_name : str, model_names : List[str], model_source_set : DownloadSet) -> InferencePool: def get_inference_pool(module_name : str, model_names : List[str], model_source_set : DownloadSet) -> InferencePool:
while process_manager.is_checking(): while process_manager.is_checking():
sleep(0.5) sleep(0.5)
execution_device_ids = state_manager.get_item('execution_device_ids') execution_device_ids = state_manager.get_item('execution_device_ids')
execution_providers = state_manager.get_item('execution_providers') execution_providers = state_manager.get_item('execution_providers')
has_arena_leak = has_execution_provider('cuda') and get_onnxruntime_version() > (1, 24, 4)
app_context = detect_app_context() app_context = detect_app_context()
for execution_device_id in execution_device_ids: for execution_device_id in execution_device_ids:
inference_context = get_inference_context(module_name, model_names, execution_device_id, execution_providers) inference_context = get_inference_context(module_name, model_names, execution_device_id, execution_providers)
if app_context == 'cli' and INFERENCE_POOL_SET.get('ui').get(inference_context): if not has_arena_leak:
INFERENCE_POOL_SET['cli'][inference_context] = INFERENCE_POOL_SET.get('ui').get(inference_context) if app_context == 'cli' and INFERENCE_POOL_SET.get('ui').get(inference_context):
if app_context == 'ui' and INFERENCE_POOL_SET.get('cli').get(inference_context): INFERENCE_POOL_SET['cli'][inference_context] = INFERENCE_POOL_SET.get('ui').get(inference_context)
INFERENCE_POOL_SET['ui'][inference_context] = INFERENCE_POOL_SET.get('cli').get(inference_context) if app_context == 'ui' and INFERENCE_POOL_SET.get('cli').get(inference_context):
INFERENCE_POOL_SET['ui'][inference_context] = INFERENCE_POOL_SET.get('cli').get(inference_context)
if not INFERENCE_POOL_SET.get(app_context).get(inference_context): if not INFERENCE_POOL_SET.get(app_context).get(inference_context):
inference_providers = resolve_static_inference_providers(module_name, execution_device_id) inference_providers = resolve_static_inference_providers(module_name, execution_device_id)
INFERENCE_POOL_SET[app_context][inference_context] = create_inference_pool(model_source_set, inference_providers) INFERENCE_POOL_SET[app_context][inference_context] = create_inference_pool(model_source_set, inference_providers)
@@ -49,6 +52,7 @@ def create_inference_pool(model_source_set : DownloadSet, inference_providers :
for model_name in model_source_set.keys(): for model_name in model_source_set.keys():
model_path = model_source_set.get(model_name).get('path') model_path = model_source_set.get(model_name).get('path')
if is_file(model_path): if is_file(model_path):
inference_pool[model_name] = create_inference_session(model_path, inference_providers) inference_pool[model_name] = create_inference_session(model_path, inference_providers)
@@ -60,11 +64,9 @@ def clear_inference_pool(module_name : str, model_names : List[str]) -> None:
execution_providers = state_manager.get_item('execution_providers') execution_providers = state_manager.get_item('execution_providers')
app_context = detect_app_context() app_context = detect_app_context()
if is_windows() and has_execution_provider('directml'):
INFERENCE_POOL_SET[app_context].clear()
for execution_device_id in execution_device_ids: for execution_device_id in execution_device_ids:
inference_context = get_inference_context(module_name, model_names, execution_device_id, execution_providers) inference_context = get_inference_context(module_name, model_names, execution_device_id, execution_providers)
if INFERENCE_POOL_SET.get(app_context).get(inference_context): if INFERENCE_POOL_SET.get(app_context).get(inference_context):
del INFERENCE_POOL_SET[app_context][inference_context] del INFERENCE_POOL_SET[app_context][inference_context]
+9 -7
View File
@@ -19,16 +19,17 @@ LOCALES =\
} }
ONNXRUNTIME_SET =\ ONNXRUNTIME_SET =\
{ {
'default': ('onnxruntime', '1.26.0') 'default': ('onnxruntime', '1.28.0')
} }
if is_windows() or is_linux(): if is_windows() or is_linux():
ONNXRUNTIME_SET['cuda'] = ('onnxruntime-gpu', '1.26.0') ONNXRUNTIME_SET['cuda@12'] = ('onnxruntime-gpu', '1.24.4')
ONNXRUNTIME_SET['cuda@13'] = ('onnxruntime-gpu', '1.28.0')
ONNXRUNTIME_SET['openvino'] = ('onnxruntime-openvino', '1.24.1') ONNXRUNTIME_SET['openvino'] = ('onnxruntime-openvino', '1.24.1')
if is_windows(): if is_windows():
ONNXRUNTIME_SET['directml'] = ('onnxruntime-directml', '1.24.4') ONNXRUNTIME_SET['directml'] = ('onnxruntime-directml', '1.24.4')
ONNXRUNTIME_SET['qnn'] = ('onnxruntime-qnn', '1.24.4') ONNXRUNTIME_SET['qnn'] = ('onnxruntime-qnn', '2.4.0')
if is_linux(): if is_linux():
ONNXRUNTIME_SET['migraphx'] = ('onnxruntime-migraphx', '1.26.0') ONNXRUNTIME_SET['migraphx'] = ('onnxruntime-migraphx', '1.27.1')
ONNXRUNTIME_SET['rocm'] = ('onnxruntime-rocm', '1.22.2.post3') ONNXRUNTIME_SET['rocm'] = ('onnxruntime-rocm', '1.22.2.post3')
@@ -54,6 +55,9 @@ def run(program : ArgumentParser) -> None:
sys.stdout.write(LOCALES.get('conda_not_activated') + os.linesep) sys.stdout.write(LOCALES.get('conda_not_activated') + os.linesep)
sys.exit(1) sys.exit(1)
for onnxruntime_package, _ in ONNXRUNTIME_SET.values():
subprocess.call([ shutil.which('pip'), 'uninstall', onnxruntime_package, '-y', '-q' ], stderr = subprocess.DEVNULL)
commands = [ shutil.which('pip'), 'install' ] commands = [ shutil.which('pip'), 'install' ]
if args.force_reinstall: if args.force_reinstall:
@@ -63,12 +67,10 @@ def run(program : ArgumentParser) -> None:
for line in file.readlines(): for line in file.readlines():
__line__ = line.strip() __line__ = line.strip()
if not __line__.startswith('onnxruntime'): if not __line__.startswith('onnxruntime'):
commands.append(__line__) commands.append(__line__)
onnxruntime_name, onnxruntime_version = ONNXRUNTIME_SET.get(args.onnxruntime) onnxruntime_name, onnxruntime_version = ONNXRUNTIME_SET.get(args.onnxruntime)
commands.append(onnxruntime_name + '==' + onnxruntime_version) commands.append(onnxruntime_name + '==' + onnxruntime_version)
subprocess.call([ shutil.which('pip'), 'uninstall', 'onnxruntime', onnxruntime_name, '-y', '-q' ])
subprocess.call(commands) subprocess.call(commands)
+1 -1
View File
@@ -4,7 +4,7 @@ METADATA =\
{ {
'name': 'FaceFusion', 'name': 'FaceFusion',
'description': 'Industry leading face manipulation platform', 'description': 'Industry leading face manipulation platform',
'version': '3.8.0', 'version': '3.8.1',
'license': 'OpenRAIL-AS', 'license': 'OpenRAIL-AS',
'author': 'Henry Ruhs', 'author': 'Henry Ruhs',
'url': 'https://facefusion.io' 'url': 'https://facefusion.io'
@@ -504,15 +504,15 @@ def clear_inference_pool() -> None:
def adjust_inference_providers() -> List[InferenceProvider]: def adjust_inference_providers() -> List[InferenceProvider]:
model_precision = get_model_options().get('precision') model_precision = get_model_options().get('precision')
model_type = get_model_options().get('type')
if is_macos() and has_execution_provider('coreml'): if is_macos() and has_execution_provider('coreml') and model_precision == 'fp16':
if model_type in [ 'ghost', 'uniface' ] or model_precision == 'fp16': if state_manager.get_item('workflow_mode') == 'image-to-video':
return\ return\
[ [
(facefusion.choices.execution_provider_set.get('coreml'), (facefusion.choices.execution_provider_set.get('coreml'),
{ {
'ModelFormat': 'MLProgram' 'ModelFormat': 'MLProgram',
'MLComputeUnits': 'CPUAndGPU'
}) })
] ]
+1 -1
View File
@@ -2,7 +2,7 @@ gradio-rangeslider==0.0.8
gradio==5.50.0 gradio==5.50.0
numpy==2.4.6 numpy==2.4.6
onnx==1.22.0 onnx==1.22.0
onnxruntime==1.26.0 onnxruntime==1.28.0
opencv-python-headless==5.0.0.93 opencv-python-headless==5.0.0.93
tqdm==4.70.0 tqdm==4.70.0
scipy==1.18.0 scipy==1.18.0
+14 -2
View File
@@ -36,9 +36,21 @@ def before_each() -> None:
init_jobs(get_test_jobs_directory()) init_jobs(get_test_jobs_directory())
@pytest.mark.skip()
def test_job_list() -> None: def test_job_list() -> None:
pass commands = [ sys.executable, 'facefusion.py', 'job-list', 'drafted', '--jobs-path', get_test_jobs_directory() ]
assert subprocess.run(commands).returncode == 1
commands = [ sys.executable, 'facefusion.py', 'job-create', 'test-job-list', '--jobs-path', get_test_jobs_directory() ]
subprocess.run(commands)
commands = [ sys.executable, 'facefusion.py', 'job-list', 'drafted', '--jobs-path', get_test_jobs_directory() ]
assert subprocess.run(commands).returncode == 0
commands = [ sys.executable, 'facefusion.py', 'job-list', 'queued', '--jobs-path', get_test_jobs_directory() ]
assert subprocess.run(commands).returncode == 1
def test_job_create() -> None: def test_job_create() -> None:
+29 -11
View File
@@ -6,7 +6,7 @@ from onnxruntime import InferenceSession
from facefusion import content_analyser, state_manager from facefusion import content_analyser, state_manager
from facefusion.execution import resolve_cache_path from facefusion.execution import resolve_cache_path
from facefusion.inference_manager import INFERENCE_POOL_SET, get_inference_pool, resolve_static_inference_providers from facefusion.inference_manager import get_inference_pool, resolve_static_inference_providers
@pytest.fixture(scope = 'module', autouse = True) @pytest.fixture(scope = 'module', autouse = True)
@@ -20,17 +20,29 @@ def test_get_inference_pool() -> None:
model_names = [ 'nsfw_1', 'nsfw_2', 'nsfw_3' ] model_names = [ 'nsfw_1', 'nsfw_2', 'nsfw_3' ]
_, model_source_set = content_analyser.collect_model_downloads() _, model_source_set = content_analyser.collect_model_downloads()
with patch('facefusion.inference_manager.detect_app_context', return_value = 'cli'): with patch('facefusion.inference_manager.has_execution_provider', return_value = True):
get_inference_pool('facefusion.content_analyser', model_names, model_source_set) with patch('facefusion.inference_manager.get_onnxruntime_version', return_value = (1, 26, 0)):
assert isinstance(INFERENCE_POOL_SET.get('cli').get('facefusion.content_analyser.nsfw_1.nsfw_2.nsfw_3.0.cpu').get('nsfw_1'), InferenceSession) with patch('facefusion.inference_manager.detect_app_context', return_value = 'cli'):
cli_inference_pool = get_inference_pool('facefusion.content_analyser', model_names, model_source_set)
with patch('facefusion.inference_manager.detect_app_context', return_value = 'ui'): assert isinstance(cli_inference_pool.get('nsfw_1'), InferenceSession)
get_inference_pool('facefusion.content_analyser', model_names, model_source_set)
assert isinstance(INFERENCE_POOL_SET.get('cli').get('facefusion.content_analyser.nsfw_1.nsfw_2.nsfw_3.0.cpu').get('nsfw_1'), InferenceSession) with patch('facefusion.inference_manager.detect_app_context', return_value = 'ui'):
ui_inference_pool = get_inference_pool('facefusion.content_analyser', model_names, model_source_set)
assert INFERENCE_POOL_SET.get('cli').get('facefusion.content_analyser.nsfw_1.nsfw_2.nsfw_3.0.cpu').get('nsfw_1') == INFERENCE_POOL_SET.get('ui').get('facefusion.content_analyser.nsfw_1.nsfw_2.nsfw_3.0.cpu').get('nsfw_1') assert isinstance(ui_inference_pool.get('nsfw_1'), InferenceSession)
assert not (cli_inference_pool.get('nsfw_1') is ui_inference_pool.get('nsfw_1'))
with patch('facefusion.inference_manager.get_onnxruntime_version', return_value = (1, 24, 4)):
with patch('facefusion.inference_manager.detect_app_context', return_value = 'ui'):
ui_inference_pool = get_inference_pool('facefusion.content_analyser', model_names, model_source_set)
assert isinstance(ui_inference_pool.get('nsfw_1'), InferenceSession)
assert cli_inference_pool.get('nsfw_1') is ui_inference_pool.get('nsfw_1')
@pytest.fixture @pytest.fixture
@@ -48,9 +60,15 @@ def test_resolve_static_inference_providers(override_module : SimpleNamespace, a
resolve_static_inference_providers.cache_clear() resolve_static_inference_providers.cache_clear()
with patch('facefusion.inference_manager.importlib', Mock(import_module = Mock(return_value = override_module))): with patch('facefusion.inference_manager.importlib', Mock(import_module = Mock(return_value = override_module))):
assert resolve_static_inference_providers('override_module', 0) == [ ('CoreMLExecutionProvider', { 'ModelFormat': 'MLProgram' }) ] inference_providers = resolve_static_inference_providers('override_module', 0)
assert inference_providers == [ ('CoreMLExecutionProvider', { 'ModelFormat': 'MLProgram' }) ]
with patch('facefusion.inference_manager.importlib', Mock(import_module = Mock(return_value = adjust_module))): with patch('facefusion.inference_manager.importlib', Mock(import_module = Mock(return_value = adjust_module))):
assert resolve_static_inference_providers('adjust_module', 0) == [ ('CoreMLExecutionProvider', { 'SpecializationStrategy': 'FastPrediction', 'ModelCacheDirectory': resolve_cache_path(), 'ModelFormat': 'MLProgram' }) ] inference_providers = resolve_static_inference_providers('adjust_module', 0)
assert resolve_static_inference_providers('test', 0) == [ ('CoreMLExecutionProvider', { 'SpecializationStrategy': 'FastPrediction', 'ModelCacheDirectory': resolve_cache_path() }) ] assert inference_providers == [ ('CoreMLExecutionProvider', { 'SpecializationStrategy': 'FastPrediction', 'ModelCacheDirectory': resolve_cache_path(), 'ModelFormat': 'MLProgram' }) ]
inference_providers = resolve_static_inference_providers('test', 0)
assert inference_providers == [ ('CoreMLExecutionProvider', { 'SpecializationStrategy': 'FastPrediction', 'ModelCacheDirectory': resolve_cache_path() }) ]