mirror of
https://github.com/vladmandic/automatic
synced 2026-09-20 01:31:13 +02:00
@@ -20,6 +20,7 @@
|
||||
- **Server**
|
||||
- update handlers for all authenticated workflows
|
||||
- nunchaku-lite support for `torch==2.13`
|
||||
- remove DirectML support: latest release was over 2 years ago and is not compatible with modern frameworks
|
||||
- **Fixes**
|
||||
- init hf env variables before gradio load
|
||||
- lora skip init and rebuild offload state
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
- JSON image metadata
|
||||
- Expand custom VAE support
|
||||
- Refactor: remove obsolete code:
|
||||
- Remove `directml`
|
||||
- Remove `olive-ai`
|
||||
- Integrate natural language image search
|
||||
- [ImageDB](https://github.com/vladmandic/imagedb)
|
||||
|
||||
@@ -743,13 +743,13 @@ def fp8_failure_is_capability(detail):
|
||||
def print_environment(fp8_result, prep_status, prep_detail, weight_dequant_result=None):
|
||||
device = torch.device(torch_device)
|
||||
capability = torch_device_module.get_device_capability(device)
|
||||
# backend runtime versions (cuda/cudnn/driver, hip, ipex, openvino, directml) so a shared
|
||||
# backend runtime versions (cuda/cudnn/driver, hip, ipex, openvino) so a shared
|
||||
# report identifies the stack without inferring it from the torch version string
|
||||
try:
|
||||
gpu_info = devices.get_gpu_info() or {}
|
||||
except Exception:
|
||||
gpu_info = {}
|
||||
runtime_versions = {key: gpu_info[key] for key in ("cuda", "hip", "cudnn", "driver", "ipex", "openvino", "directml") if gpu_info.get(key)}
|
||||
runtime_versions = {key: gpu_info[key] for key in ("cuda", "hip", "cudnn", "driver", "ipex", "openvino") if gpu_info.get(key)}
|
||||
runtime_line = f"python: {sys.version.split()[0]} ({sys.platform}) backend: {getattr(devices, 'backend', 'unknown')}"
|
||||
if runtime_versions:
|
||||
runtime_line += " " + " ".join(f"{key}: {value}" for key, value in runtime_versions.items())
|
||||
|
||||
+1
-1
Submodule extensions-builtin/sdnq updated: 01bc5b460e...d840854e02
+22
-63
@@ -54,7 +54,6 @@ args = Dot({
|
||||
'skip_requirements': False,
|
||||
'skip_git': False,
|
||||
'skip_torch': False,
|
||||
'use_directml': False,
|
||||
'use_ipex': False,
|
||||
'use_cuda': False,
|
||||
'use_rocm': False,
|
||||
@@ -586,7 +585,7 @@ def check_diffusers():
|
||||
if args.skip_all:
|
||||
return
|
||||
target_commit = "6f2010e8bbe61fd2a81a659b858e298edcba8fab" # diffusers commit hash == 0.40.0.dev0 == 08-04-2026
|
||||
# if args.use_rocm or args.use_zluda or args.use_directml:
|
||||
# if args.use_rocm or args.use_zluda:
|
||||
# sha = '043ab2520f6a19fce78e6e060a68dbc947edb9f9' # lock diffusers versions for now
|
||||
pkg = package_spec('diffusers')
|
||||
parts = pkg.version.split('.') if pkg is not None else []
|
||||
@@ -616,36 +615,21 @@ def check_transformers():
|
||||
# target_commit = '753d61104116eefc8ffc977327b441ee0c8d599f' # transformers commit hash == 4.57.6
|
||||
# target_commit = "cf8572d34e39818e42dbf220701fbd3eb5b5a82a" # transformers commit hash == 5.14.0.dev0 == 08-04-2026
|
||||
target_commit = "b70d02fc724d04c916832ca4ead03ff05e8fb1ee" # transformers commit hash == 5.13.0.dev0 == 07-03-2026
|
||||
if args.use_directml:
|
||||
target_transformers = '4.52.4'
|
||||
target_tokenizers = '0.21.4'
|
||||
else:
|
||||
# target_transformers = '4.57.6'
|
||||
target_transformers = None
|
||||
target_tokenizers = '0.22.2'
|
||||
if target_transformers is not None:
|
||||
# Pinned release version (e.g. DirectML)
|
||||
if args.reinstall or (pkg_transformers is None) or ((pkg_transformers.version != target_transformers) or (pkg_tokenizers is None) or ((pkg_tokenizers.version != target_tokenizers) and (not args.experimental))):
|
||||
if pkg_transformers is None:
|
||||
log.info(f'Install: package="transformers" version={target_transformers}')
|
||||
else:
|
||||
log.info(f'Update: package="transformers" current={pkg_transformers.version} target={target_transformers}')
|
||||
pip('uninstall --yes transformers', ignore=True, quiet=True)
|
||||
pip(f'install tokenizers=={target_tokenizers}', ignore=False, quiet=True)
|
||||
pip(f'install transformers=={target_transformers}', ignore=False, quiet=True)
|
||||
else:
|
||||
# Git commit-pinned version
|
||||
current = package_commit(pkg_transformers)
|
||||
if args.reinstall or (pkg_transformers is None) or (pkg_transformers.version.startswith('4')) or (current != target_commit):
|
||||
if pkg_transformers is None:
|
||||
log.info(f'Install: package="transformers" commit={target_commit}')
|
||||
else:
|
||||
log.info(f'Update: package="transformers" current={pkg_transformers.version} commit={current} target={target_commit}')
|
||||
pip('uninstall --yes transformers', ignore=True, quiet=True)
|
||||
pip(f'install tokenizers=={target_tokenizers}', ignore=False, quiet=True)
|
||||
pip(f'install git+https://github.com/huggingface/transformers@{target_commit}', ignore=False, quiet=True)
|
||||
global transformers_commit # pylint: disable=global-statement
|
||||
transformers_commit = target_commit
|
||||
target_tokenizers = '0.22.2'
|
||||
# Git commit-pinned version
|
||||
current = package_commit(pkg_transformers)
|
||||
if args.reinstall or (pkg_transformers is None) or (pkg_transformers.version.startswith('4')) or (current != target_commit):
|
||||
if pkg_transformers is None:
|
||||
log.info(f'Install: package="transformers" commit={target_commit}')
|
||||
else:
|
||||
log.info(f'Update: package="transformers" current={pkg_transformers.version} commit={current} target={target_commit}')
|
||||
pip('uninstall --yes transformers', ignore=True, quiet=True)
|
||||
pip(f'install tokenizers=={target_tokenizers}', ignore=False, quiet=True)
|
||||
pip(f'install git+https://github.com/huggingface/transformers@{target_commit}', ignore=False, quiet=True)
|
||||
global transformers_commit # pylint: disable=global-statement
|
||||
transformers_commit = target_commit
|
||||
if args.reinstall or (pkg_tokenizers is None) or (pkg_tokenizers.version != target_tokenizers):
|
||||
pip(f'install tokenizers=={target_tokenizers}', ignore=False, quiet=True)
|
||||
ts('transformers', t_start)
|
||||
|
||||
|
||||
@@ -924,20 +908,17 @@ def check_torch():
|
||||
if args.profile:
|
||||
pr = cProfile.Profile()
|
||||
pr.enable()
|
||||
allow_cuda = not (args.use_rocm or args.use_directml or args.use_ipex or args.use_openvino)
|
||||
allow_rocm = not (args.use_cuda or args.use_directml or args.use_ipex or args.use_openvino)
|
||||
allow_ipex = not (args.use_cuda or args.use_rocm or args.use_directml or args.use_openvino)
|
||||
allow_directml = not (args.use_cuda or args.use_rocm or args.use_ipex or args.use_openvino)
|
||||
allow_openvino = not (args.use_cuda or args.use_rocm or args.use_ipex or args.use_directml)
|
||||
log.debug(f'Torch overrides: cuda={args.use_cuda} rocm={args.use_rocm} ipex={args.use_ipex} directml={args.use_directml} openvino={args.use_openvino} zluda={args.use_zluda}')
|
||||
# log.debug(f'Torch allowed: cuda={allow_cuda} rocm={allow_rocm} ipex={allow_ipex} diml={allow_directml} openvino={allow_openvino}')
|
||||
allow_cuda = not (args.use_rocm or args.use_ipex or args.use_openvino)
|
||||
allow_rocm = not (args.use_cuda or args.use_ipex or args.use_openvino)
|
||||
allow_ipex = not (args.use_cuda or args.use_rocm or args.use_openvino)
|
||||
allow_openvino = not (args.use_cuda or args.use_rocm or args.use_ipex)
|
||||
log.debug(f'Torch overrides: cuda={args.use_cuda} rocm={args.use_rocm} ipex={args.use_ipex} openvino={args.use_openvino} zluda={args.use_zluda}')
|
||||
# log.debug(f'Torch allowed: cuda={allow_cuda} rocm={allow_rocm} ipex={allow_ipex} openvino={allow_openvino}')
|
||||
torch_command = os.environ.get('TORCH_COMMAND', '')
|
||||
|
||||
if sys.platform != 'win32':
|
||||
if args.use_zluda:
|
||||
log.error('ZLUDA is only supported on Windows')
|
||||
if args.use_directml:
|
||||
log.error('DirectML is only supported on Windows')
|
||||
|
||||
if torch_command != '':
|
||||
is_cuda_available = False
|
||||
@@ -967,15 +948,8 @@ def check_torch():
|
||||
elif is_ipex_available:
|
||||
torch_command = install_ipex()
|
||||
else:
|
||||
machine = platform.machine()
|
||||
if sys.platform == 'darwin':
|
||||
torch_command = os.environ.get('TORCH_COMMAND', 'torch torchvision')
|
||||
elif allow_directml and args.use_directml and ('arm' not in machine and 'aarch' not in machine):
|
||||
log.info('DirectML: selected')
|
||||
torch_command = os.environ.get('TORCH_COMMAND', 'torch==2.4.1 torchvision torch-directml==0.2.4.dev240913')
|
||||
if 'torch' in torch_command and not args.version:
|
||||
install(torch_command, 'torch torchvision')
|
||||
install('onnxruntime-directml', 'onnxruntime-directml', ignore=True)
|
||||
else:
|
||||
log.warning('Torch: CPU-only version installed')
|
||||
torch_command = os.environ.get('TORCH_COMMAND', 'torch torchvision')
|
||||
@@ -1067,21 +1041,6 @@ def check_torch():
|
||||
except Exception as e:
|
||||
log.error(f'Torch: type=cuda/rocm {e}')
|
||||
|
||||
if args.use_directml and allow_directml:
|
||||
try:
|
||||
import torch_directml # pylint: disable=import-error
|
||||
dml_ver = package_version("torch-directml")
|
||||
log.warning(f'Torch backend: DirectML ({dml_ver})')
|
||||
log.warning('DirectML: end-of-life')
|
||||
for i in range(0, torch_directml.device_count()):
|
||||
gpu = {
|
||||
'gpu': torch_directml.device_name(i),
|
||||
}
|
||||
gpu_info.append(gpu)
|
||||
log.info(f'Torch detected: {gpu}')
|
||||
except Exception as e:
|
||||
log.warning(f"Torch: type=directml {e}")
|
||||
|
||||
except Exception as e:
|
||||
log.error(f'Torch cannot load: {e}')
|
||||
if not args.ignore:
|
||||
|
||||
@@ -37,7 +37,6 @@ def add_compute_args(p):
|
||||
p.add_argument("--use-rocm", default=env_flag("SD_USEROCM", False), action='store_true', help="Force use AMD ROCm backend, default: %(default)s")
|
||||
p.add_argument('--use-zluda', default=env_flag("SD_USEZLUDA", False), action='store_true', help="Force use ZLUDA, AMD GPUs only, default: %(default)s")
|
||||
p.add_argument("--use-openvino", default=env_flag("SD_USEOPENVINO", False), action='store_true', help="Use Intel OpenVINO backend, default: %(default)s")
|
||||
p.add_argument('--use-directml', default=env_flag("SD_USEDIRECTML", False), action='store_true', help="Use DirectML if no compatible GPU is detected, default: %(default)s")
|
||||
p.add_argument("--use-xformers", default=env_flag("SD_USEXFORMERS", False), action='store_true', help="Force use xFormers cross-optimization, default: %(default)s")
|
||||
p.add_argument("--use-nightly", default=env_flag("SD_USENIGHTLY", False), action='store_true', help="Force use nightly torch builds, default: %(default)s")
|
||||
p.add_argument("--no-half", default=env_flag("SD_NOHALF", False), action='store_true', help="Do not switch the model to 16-bit float, default: %(default)s")
|
||||
|
||||
+4
-22
@@ -79,8 +79,6 @@ def get_backend(shared_cmd_opts):
|
||||
args = shared_cmd_opts
|
||||
if args.use_openvino:
|
||||
name = 'openvino'
|
||||
elif args.use_directml:
|
||||
name = 'directml'
|
||||
elif has_xpu():
|
||||
name = 'ipex'
|
||||
elif has_zluda():
|
||||
@@ -131,11 +129,6 @@ def get_gpu_info():
|
||||
'devices': devices,
|
||||
'openvino': get_package_version("openvino"),
|
||||
}
|
||||
elif backend == 'directml':
|
||||
return {
|
||||
'device': f'{torch.cuda.get_device_name(torch.cuda.current_device())} n={torch.cuda.device_count()}',
|
||||
'directml': get_package_version("torch-directml"),
|
||||
}
|
||||
else:
|
||||
return {}
|
||||
except Exception:
|
||||
@@ -176,10 +169,6 @@ def get_cuda_device_string():
|
||||
if cmd_opts.device_id is not None:
|
||||
return f"xpu:{cmd_opts.device_id}"
|
||||
return "xpu"
|
||||
elif backend == 'directml' and torch.dml.is_available():
|
||||
if cmd_opts.device_id is not None:
|
||||
return f"privateuseone:{cmd_opts.device_id}"
|
||||
return torch.dml.get_device_string(torch.dml.default_device().index)
|
||||
else:
|
||||
if cmd_opts.device_id is not None:
|
||||
return f"cuda:{cmd_opts.device_id}"
|
||||
@@ -189,7 +178,7 @@ def get_cuda_device_string():
|
||||
def get_optimal_device_name():
|
||||
if backend == 'openvino':
|
||||
return "cpu"
|
||||
if cuda_ok or backend == 'directml':
|
||||
if cuda_ok:
|
||||
return get_cuda_device_string()
|
||||
if has_mps() and backend != 'openvino':
|
||||
return "mps"
|
||||
@@ -205,12 +194,9 @@ def torch_gc(force: bool = False, fast: bool = False, reason: str | None = None)
|
||||
mem_dict = memstats.memory_stats()
|
||||
gpu_dict = mem_dict.get('gpu', {})
|
||||
ram_dict = mem_dict.get('ram', {})
|
||||
oom = gpu_dict.get('oom', 0)
|
||||
ram = ram_dict.get('used', 0)
|
||||
if backend == "directml":
|
||||
gpu = torch.cuda.memory_allocated() / (1 << 30)
|
||||
else:
|
||||
gpu = gpu_dict.get('used', 0)
|
||||
oom = gpu_dict.get('oom', 0)
|
||||
gpu = gpu_dict.get('used', 0)
|
||||
used_gpu = round(100 * gpu / gpu_dict.get('total', 1)) if gpu_dict.get('total', 1) > 1 else 0
|
||||
used_ram = round(100 * ram / ram_dict.get('total', 1)) if ram_dict.get('total', 1) > 1 else 0
|
||||
return gpu, used_gpu, ram, used_ram, oom
|
||||
@@ -374,7 +360,7 @@ def test_bf16():
|
||||
if bf16_ok is not None:
|
||||
return bf16_ok
|
||||
if opts.cuda_dtype != 'BF16': # don't override if the user sets it
|
||||
if sys.platform == "darwin" or backend in {'directml', 'cpu'}: # override
|
||||
if sys.platform == "darwin" or backend == 'cpu': # override
|
||||
bf16_ok = False
|
||||
return bf16_ok
|
||||
elif backend == 'openvino':
|
||||
@@ -676,8 +662,6 @@ def randn_without_seed(shape):
|
||||
def autocast(disable=False):
|
||||
if disable or dtype == torch.float32:
|
||||
return contextlib.nullcontext()
|
||||
if backend == 'directml':
|
||||
return torch.dml.amp.autocast(dtype)
|
||||
if cuda_ok:
|
||||
return torch.autocast("cuda")
|
||||
else:
|
||||
@@ -687,8 +671,6 @@ def autocast(disable=False):
|
||||
def without_autocast(disable=False):
|
||||
if disable:
|
||||
return contextlib.nullcontext()
|
||||
if backend == 'directml':
|
||||
return torch.dml.amp.autocast(enabled=False) if torch.is_autocast_enabled() else contextlib.nullcontext() # pylint: disable=unexpected-keyword-arg
|
||||
if cuda_ok:
|
||||
return torch.autocast("cuda", enabled=False) if torch.is_autocast_enabled() else contextlib.nullcontext()
|
||||
else:
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
import torch
|
||||
|
||||
|
||||
class Generator(torch.Generator):
|
||||
def __init__(self, device: torch.device | None = None):
|
||||
super().__init__("cpu")
|
||||
@@ -1,116 +0,0 @@
|
||||
import platform
|
||||
from typing import NamedTuple
|
||||
from collections.abc import Callable
|
||||
import torch
|
||||
from modules.logger import log
|
||||
from modules.sd_hijack_utils import CondFunc
|
||||
|
||||
|
||||
memory_providers = ["None", "atiadlxx (AMD only)"]
|
||||
default_memory_provider = "None"
|
||||
if platform.system() == "Windows":
|
||||
memory_providers.append("Performance Counter")
|
||||
default_memory_provider = "Performance Counter"
|
||||
do_nothing = lambda: None # pylint: disable=unnecessary-lambda-assignment
|
||||
do_nothing_with_self = lambda self: None # pylint: disable=unnecessary-lambda-assignment
|
||||
|
||||
|
||||
def _set_memory_provider():
|
||||
from modules.shared import opts, cmd_opts
|
||||
if opts.directml_memory_provider == "Performance Counter":
|
||||
from .backend import pdh_mem_get_info
|
||||
from .memory import MemoryProvider
|
||||
torch.dml.mem_get_info = pdh_mem_get_info
|
||||
if torch.dml.memory_provider is not None:
|
||||
del torch.dml.memory_provider
|
||||
torch.dml.memory_provider = MemoryProvider()
|
||||
elif opts.directml_memory_provider == "atiadlxx (AMD only)":
|
||||
device_name = torch.dml.get_device_name(cmd_opts.device_id)
|
||||
if "AMD" not in device_name and "Radeon" not in device_name:
|
||||
log.warning(f"Memory stats provider is changed to None because the current device is not AMDGPU. Current Device: {device_name}")
|
||||
opts.directml_memory_provider = "None"
|
||||
_set_memory_provider()
|
||||
return
|
||||
from .backend import amd_mem_get_info
|
||||
torch.dml.mem_get_info = amd_mem_get_info
|
||||
else:
|
||||
from .backend import mem_get_info
|
||||
torch.dml.mem_get_info = mem_get_info
|
||||
torch.cuda.mem_get_info = torch.dml.mem_get_info
|
||||
|
||||
|
||||
def directml_init():
|
||||
try:
|
||||
from modules.dml.backend import DirectML # pylint: disable=ungrouped-imports
|
||||
# Alternative of torch.cuda for DirectML.
|
||||
torch.dml = DirectML
|
||||
|
||||
torch.cuda.is_available = lambda: False
|
||||
torch.cuda.device = torch.dml.device
|
||||
torch.cuda.device_count = torch.dml.device_count
|
||||
torch.cuda.current_device = torch.dml.current_device
|
||||
torch.cuda.get_device_name = torch.dml.get_device_name
|
||||
torch.cuda.get_device_properties = torch.dml.get_device_properties
|
||||
|
||||
torch.cuda.empty_cache = do_nothing
|
||||
torch.cuda.ipc_collect = do_nothing
|
||||
torch.cuda.memory_stats = torch.dml.memory_stats
|
||||
torch.cuda.mem_get_info = torch.dml.mem_get_info
|
||||
torch.cuda.memory_allocated = torch.dml.memory_allocated
|
||||
torch.cuda.max_memory_allocated = torch.dml.max_memory_allocated
|
||||
torch.cuda.reset_peak_memory_stats = torch.dml.reset_peak_memory_stats
|
||||
torch.cuda.utilization = lambda: 0
|
||||
|
||||
torch.Tensor.directml = lambda self: self.to(torch.dml.current_device())
|
||||
except Exception as e:
|
||||
log.error(f'DirectML initialization failed: {e}')
|
||||
return False, e
|
||||
return True, None
|
||||
|
||||
|
||||
def directml_do_hijack():
|
||||
import modules.dml.hijack # pylint: disable=unused-import
|
||||
from modules.devices import device
|
||||
|
||||
CondFunc('torch.Generator',
|
||||
lambda orig_func, device = None: orig_func("cpu"),
|
||||
lambda orig_func, device = None: True)
|
||||
|
||||
if not torch.dml.has_float64_support(device):
|
||||
torch.Tensor.__str__ = do_nothing_with_self
|
||||
CondFunc('torch.from_numpy',
|
||||
lambda orig_func, *args, **kwargs: orig_func(args[0].astype('float32')),
|
||||
lambda *args, **kwargs: args[1].dtype == float)
|
||||
|
||||
_set_memory_provider()
|
||||
|
||||
|
||||
class OverrideItem(NamedTuple):
|
||||
value: str
|
||||
condition: Callable | None
|
||||
message: str | None
|
||||
|
||||
|
||||
opts_override_table = {
|
||||
"diffusers_generator_device": OverrideItem("CPU", None, "DirectML does not support torch Generator API"),
|
||||
}
|
||||
|
||||
|
||||
def directml_override_opts():
|
||||
from modules import shared
|
||||
|
||||
if shared.cmd_opts.experimental:
|
||||
return
|
||||
|
||||
count = 0
|
||||
for key in opts_override_table:
|
||||
item = opts_override_table[key]
|
||||
if getattr(shared.opts, key) != item.value and (item.condition is None or item.condition(shared.opts)):
|
||||
count += 1
|
||||
setattr(shared.opts, key, item.value)
|
||||
log.warning(f'Overriding: {key}={item.value} {item.message if item.message is not None else ""}')
|
||||
|
||||
if count > 0:
|
||||
log.info(f'Options override: count={count}. If you want to keep them from overriding, run with --experimental argument.')
|
||||
|
||||
_set_memory_provider()
|
||||
@@ -1 +0,0 @@
|
||||
from .autocast_mode import autocast
|
||||
@@ -1,66 +0,0 @@
|
||||
import importlib
|
||||
from typing import Any
|
||||
import torch
|
||||
|
||||
|
||||
ops = ["torch.Tensor.__matmul__", "torch.addbmm", "torch.addmm", "torch.addmv", "torch.addr", "torch.baddbmm", "torch.bmm", "torch.chain_matmul", "torch.linalg.multi_dot", "torch.nn.functional.conv1d", "torch.nn.functional.conv2d", "torch.nn.functional.conv3d", "torch.nn.functional.conv_transpose1d", "torch.nn.functional.conv_transpose2d", "torch.nn.functional.conv_transpose3d", "torch.nn.GRUCell", "torch.nn.functional.linear", "torch.nn.LSTMCell", "torch.matmul", "torch.mm", "torch.mv", "torch.prelu", "torch.nn.RNNCell", "torch.embedding"]
|
||||
supported_cast_pairs = {
|
||||
torch.float16: (torch.float32,),
|
||||
torch.float32: (torch.float16,),
|
||||
}
|
||||
|
||||
|
||||
def forward(op, args: tuple, kwargs: dict):
|
||||
if not torch.dml.is_autocast_enabled:
|
||||
return op(*args, **kwargs)
|
||||
args = list(map(cast, args))
|
||||
for kwarg in kwargs:
|
||||
kwargs[kwarg] = cast(kwargs[kwarg])
|
||||
return op(*args, **kwargs)
|
||||
|
||||
|
||||
def cast(tensor: torch.Tensor):
|
||||
if not torch.is_tensor(tensor):
|
||||
return tensor
|
||||
dtype: torch.dtype = tensor.dtype
|
||||
if dtype not in supported_cast_pairs or (torch.dml.autocast_gpu_dtype != dtype and torch.dml.autocast_gpu_dtype not in supported_cast_pairs[dtype]):
|
||||
return tensor
|
||||
return tensor.type(torch.dml.autocast_gpu_dtype)
|
||||
|
||||
|
||||
def cond(op: str):
|
||||
if isinstance(op, str):
|
||||
func_path = op.split('.')
|
||||
for i in range(len(func_path)-1, -1, -1):
|
||||
try:
|
||||
resolved_obj = importlib.import_module('.'.join(func_path[:i]))
|
||||
break
|
||||
except ImportError:
|
||||
pass
|
||||
for attr_name in func_path[i:-1]:
|
||||
resolved_obj = getattr(resolved_obj, attr_name)
|
||||
op = getattr(resolved_obj, func_path[-1])
|
||||
setattr(resolved_obj, func_path[-1], lambda *args, **kwargs: forward(op, args, kwargs))
|
||||
|
||||
|
||||
for o in ops:
|
||||
cond(o)
|
||||
|
||||
|
||||
class autocast:
|
||||
prev: bool
|
||||
|
||||
fast_dtype: torch.dtype = torch.float16
|
||||
prev_fast_dtype: torch.dtype
|
||||
def __init__(self, dtype: torch.dtype | None = torch.float16):
|
||||
self.fast_dtype = dtype
|
||||
|
||||
def __enter__(self):
|
||||
self.prev = torch.dml.is_autocast_enabled
|
||||
self.prev_fast_dtype = torch.dml.autocast_gpu_dtype
|
||||
torch.dml.is_autocast_enabled = True
|
||||
torch.dml.autocast_gpu_dtype = self.fast_dtype
|
||||
|
||||
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any):
|
||||
torch.dml.is_autocast_enabled = self.prev
|
||||
torch.dml.autocast_gpu_dtype = self.prev_fast_dtype
|
||||
@@ -1,80 +0,0 @@
|
||||
# pylint: disable=no-member,no-self-argument,no-method-argument
|
||||
from collections.abc import Callable
|
||||
import torch
|
||||
import torch_directml # pylint: disable=import-error
|
||||
import modules.dml.amp as amp
|
||||
from .utils import rDevice, get_device
|
||||
from .device import Device
|
||||
from .Generator import Generator
|
||||
from .device_properties import DeviceProperties
|
||||
|
||||
|
||||
def amd_mem_get_info(device: rDevice | None=None) -> tuple[int, int]:
|
||||
from .memory_amd import AMDMemoryProvider
|
||||
return AMDMemoryProvider.mem_get_info(get_device(device).index)
|
||||
|
||||
|
||||
def pdh_mem_get_info(device: rDevice | None=None) -> tuple[int, int]:
|
||||
mem_info = DirectML.memory_provider.get_memory(get_device(device).index)
|
||||
return (mem_info["total_committed"] - mem_info["dedicated_usage"], mem_info["total_committed"])
|
||||
|
||||
|
||||
def mem_get_info(device: rDevice | None=None) -> tuple[int, int]: # pylint: disable=unused-argument
|
||||
return (8589934592, 8589934592)
|
||||
|
||||
|
||||
class DirectML:
|
||||
amp = amp
|
||||
device = Device
|
||||
Generator = Generator
|
||||
|
||||
context_device: torch.device | None = None
|
||||
|
||||
is_autocast_enabled = False
|
||||
autocast_gpu_dtype = torch.float16
|
||||
|
||||
memory_provider = None
|
||||
|
||||
def is_available() -> bool:
|
||||
return torch_directml.is_available()
|
||||
|
||||
def is_directml_device(device: torch.device) -> bool:
|
||||
return device.type == "privateuseone"
|
||||
|
||||
def has_float64_support(device: rDevice | None=None) -> bool:
|
||||
return torch_directml.has_float64_support(get_device(device).index)
|
||||
|
||||
def device_count() -> int:
|
||||
return torch_directml.device_count()
|
||||
|
||||
def current_device() -> torch.device:
|
||||
return DirectML.context_device or DirectML.default_device()
|
||||
|
||||
def default_device() -> torch.device:
|
||||
return torch_directml.device(torch_directml.default_device())
|
||||
|
||||
def get_device_string(device: rDevice | None=None) -> str:
|
||||
return f"privateuseone:{get_device(device).index}"
|
||||
|
||||
def get_device_name(device: rDevice | None=None) -> str:
|
||||
return torch_directml.device_name(get_device(device).index)
|
||||
|
||||
def get_device_properties(device: rDevice | None=None) -> DeviceProperties:
|
||||
return DeviceProperties(get_device(device))
|
||||
|
||||
def memory_stats(device: rDevice | None=None):
|
||||
return {
|
||||
"num_ooms": 0,
|
||||
"num_alloc_retries": 0,
|
||||
}
|
||||
|
||||
mem_get_info: Callable = mem_get_info
|
||||
|
||||
def memory_allocated(device: rDevice | None=None) -> int:
|
||||
return sum(torch_directml.gpu_memory(get_device(device).index)) * (1 << 20)
|
||||
|
||||
def max_memory_allocated(device: rDevice | None=None):
|
||||
return DirectML.memory_allocated(device) # DirectML does not empty GPU memory
|
||||
|
||||
def reset_peak_memory_stats(device: rDevice | None=None):
|
||||
return
|
||||
@@ -1,16 +0,0 @@
|
||||
import torch
|
||||
from .utils import rDevice, get_device
|
||||
|
||||
|
||||
class Device:
|
||||
idx: int
|
||||
|
||||
def __enter__(self, device: rDevice | None=None):
|
||||
torch.dml.context_device = get_device(device)
|
||||
self.idx = torch.dml.context_device.index
|
||||
|
||||
def __init__(self, device: rDevice | None=None) -> torch.device: # pylint: disable=return-in-init
|
||||
self.idx = get_device(device).index
|
||||
|
||||
def __exit__(self, t, v, tb):
|
||||
torch.dml.context_device = None
|
||||
@@ -1,20 +0,0 @@
|
||||
import torch
|
||||
|
||||
|
||||
class DeviceProperties:
|
||||
type: str = "directml"
|
||||
name: str
|
||||
major: int = 0
|
||||
minor: int = 0
|
||||
total_memory: int
|
||||
multi_processor_count: int = 1
|
||||
|
||||
def __init__(self, device: torch.device):
|
||||
self.name = torch.dml.get_device_name(device)
|
||||
self.total_memory = torch.dml.mem_get_info(device)[0]
|
||||
|
||||
def __str__(self):
|
||||
return f"DeviceProperties(name='{self.name}', total_memory='{self.total_memory}')"
|
||||
|
||||
def __repr__(self):
|
||||
return f"DeviceProperties(name='{self.name}', total_memory='{self.total_memory}')"
|
||||
@@ -1,4 +0,0 @@
|
||||
import modules.dml.hijack.torch
|
||||
import modules.dml.hijack.realesrgan_model
|
||||
import modules.dml.hijack.transformers
|
||||
import modules.dml.hijack.tomesd
|
||||
@@ -1,67 +0,0 @@
|
||||
import math
|
||||
import torch
|
||||
from modules.postprocess.realesrgan_model_arch import RealESRGANer
|
||||
from modules.logger import log
|
||||
|
||||
|
||||
# DML Solution: Some of contents of output tensor turn to 0 after Extended Slices. Move it to cpu.
|
||||
def tile_process(self):
|
||||
batch, channel, height, width = self.img.shape
|
||||
output_height = height * self.scale
|
||||
output_width = width * self.scale
|
||||
output_shape = (batch, channel, output_height, output_width)
|
||||
|
||||
# start with black image
|
||||
self.output = self.img.new_zeros(output_shape)
|
||||
tiles_x = math.ceil(width / self.tile_size)
|
||||
tiles_y = math.ceil(height / self.tile_size)
|
||||
|
||||
# loop over all tiles
|
||||
for y in range(tiles_y):
|
||||
for x in range(tiles_x):
|
||||
# extract tile from input image
|
||||
ofs_x = x * self.tile_size
|
||||
ofs_y = y * self.tile_size
|
||||
# input tile area on total image
|
||||
input_start_x = ofs_x
|
||||
input_end_x = min(ofs_x + self.tile_size, width)
|
||||
input_start_y = ofs_y
|
||||
input_end_y = min(ofs_y + self.tile_size, height)
|
||||
|
||||
# input tile area on total image with padding
|
||||
input_start_x_pad = max(input_start_x - self.tile_pad, 0)
|
||||
input_end_x_pad = min(input_end_x + self.tile_pad, width)
|
||||
input_start_y_pad = max(input_start_y - self.tile_pad, 0)
|
||||
input_end_y_pad = min(input_end_y + self.tile_pad, height)
|
||||
|
||||
# input tile dimensions
|
||||
input_tile_width = input_end_x - input_start_x
|
||||
input_tile_height = input_end_y - input_start_y
|
||||
_tile_idx = y * tiles_x + x + 1
|
||||
input_tile = self.img[0:self.img.shape[0], 0:self.img.shape[1], input_start_y_pad:input_end_y_pad, input_start_x_pad:input_end_x_pad]
|
||||
|
||||
# upscale tile
|
||||
try:
|
||||
with torch.no_grad():
|
||||
output_tile = self.model(input_tile)
|
||||
except Exception as e:
|
||||
log.error(f'Upscale error: type=R-ESRGAN {e}')
|
||||
|
||||
# output tile area on total image
|
||||
output_start_x = input_start_x * self.scale
|
||||
output_end_x = input_end_x * self.scale
|
||||
output_start_y = input_start_y * self.scale
|
||||
output_end_y = input_end_y * self.scale
|
||||
|
||||
# output tile area without padding
|
||||
output_start_x_tile = (input_start_x - input_start_x_pad) * self.scale
|
||||
output_end_x_tile = output_start_x_tile + input_tile_width * self.scale
|
||||
output_start_y_tile = (input_start_y - input_start_y_pad) * self.scale
|
||||
output_end_y_tile = output_start_y_tile + input_tile_height * self.scale
|
||||
|
||||
self.output = self.output.cpu()
|
||||
# put tile into output image
|
||||
self.output[0:self.output.shape[0], 0:self.output.shape[1], output_start_y:output_end_y, output_start_x:output_end_x] = output_tile.cpu()[0:output_tile.shape[0], 0:output_tile.shape[1], output_start_y_tile:output_end_y_tile, output_start_x_tile:output_end_x_tile]
|
||||
self.output = self.output.to(output_tile.device)
|
||||
|
||||
RealESRGANer.tile_process = tile_process
|
||||
@@ -1,26 +0,0 @@
|
||||
import torch
|
||||
from modules.dml.hijack.utils import catch_nan
|
||||
|
||||
|
||||
def make_tome_block(block_class: type[torch.nn.Module]) -> type[torch.nn.Module]:
|
||||
class ToMeBlock(block_class):
|
||||
# Save for unpatching later
|
||||
_parent = block_class
|
||||
|
||||
def _forward(self, x: torch.Tensor, context: torch.Tensor = None) -> torch.Tensor:
|
||||
m_a, m_c, m_m, u_a, u_c, u_m = tomesd.patch.compute_merge(x, self._tome_info)
|
||||
|
||||
# This is where the meat of the computation happens
|
||||
x = u_a(self.attn1(m_a(self.norm1(x)), context=context if self.disable_self_attn else None)) + x
|
||||
x = catch_nan(lambda: (u_c(self.attn2(m_c(self.norm2(x)), context=context)) + x))
|
||||
x = u_m(self.ff(m_m(self.norm3(x)))) + x
|
||||
|
||||
return x
|
||||
|
||||
return ToMeBlock
|
||||
|
||||
try:
|
||||
import tomesd
|
||||
tomesd.patch.make_tome_block = make_tome_block
|
||||
except Exception:
|
||||
pass
|
||||
@@ -1,35 +0,0 @@
|
||||
import torch
|
||||
from modules.sd_hijack_utils import CondFunc
|
||||
|
||||
|
||||
CondFunc('torchsde._brownian.brownian_interval._randn', lambda _, size, dtype, device, seed: torch.randn(size, dtype=dtype, device=torch.device("cpu"), generator=torch.Generator(torch.device("cpu")).manual_seed(int(seed))).to(device), lambda _, size, dtype, device, seed: device.type == 'privateuseone')
|
||||
# https://github.com/microsoft/DirectML/issues/400
|
||||
CondFunc('torch.Tensor.new', lambda orig, self, *args, **kwargs: orig(self.cpu(), *args, **kwargs).to(self.device), lambda orig, self, *args, **kwargs: torch.dml.is_directml_device(self.device))
|
||||
|
||||
|
||||
def cuda(self: torch.Tensor):
|
||||
return self.to(torch.dml.current_device())
|
||||
torch.Tensor.cuda = cuda
|
||||
|
||||
|
||||
# https://github.com/lshqqytiger/stable-diffusion-webui-directml/issues/436
|
||||
_pow_ = torch.Tensor.pow_
|
||||
def pow_(self: torch.Tensor, *args, **kwargs):
|
||||
if self.dtype == torch.float64:
|
||||
return _pow_(self.cpu(), *args, **kwargs).to(self.device)
|
||||
return _pow_(self, *args, **kwargs)
|
||||
torch.Tensor.pow_ = pow_
|
||||
|
||||
|
||||
_load = torch.load
|
||||
def load(f, map_location = "cpu", *args, **kwargs):
|
||||
if type(map_location) in (str, torch.device,):
|
||||
device = torch.device(map_location)
|
||||
if device.type == "privateuseone":
|
||||
data = _load(f, *args, map_location="cpu", **kwargs)
|
||||
for k in data:
|
||||
for weight in data[k]:
|
||||
data[k][weight] = data[k][weight].to(device)
|
||||
return data
|
||||
return _load(f, *args, map_location=map_location, **kwargs)
|
||||
torch.load = load
|
||||
@@ -1,43 +0,0 @@
|
||||
import torch
|
||||
import transformers.models.clip.modeling_clip
|
||||
|
||||
# Copied from transformers.models.bart.modeling_bart._make_causal_mask
|
||||
def _make_causal_mask(
|
||||
input_ids_shape: torch.Size, dtype: torch.dtype, device: torch.device, past_key_values_length: int = 0
|
||||
):
|
||||
"""
|
||||
Make causal mask used for bi-directional self-attention.
|
||||
"""
|
||||
bsz, tgt_len = input_ids_shape
|
||||
min = torch.tensor(torch.finfo(dtype).min, device="cpu")
|
||||
mask = torch.full((tgt_len, tgt_len), min, device=device) # https://discord.com/channels/1101998836328697867/1127441997184122920
|
||||
mask_cond = torch.arange(mask.size(-1), device=device)
|
||||
mask.masked_fill_(mask_cond < (mask_cond + 1).view(mask.size(-1), 1), 0)
|
||||
mask = mask.to(dtype)
|
||||
|
||||
if past_key_values_length > 0:
|
||||
mask = torch.cat([torch.zeros(tgt_len, past_key_values_length, dtype=dtype, device=device), mask], dim=-1)
|
||||
return mask[None, None, :, :].expand(bsz, 1, tgt_len, tgt_len + past_key_values_length)
|
||||
|
||||
def CLIPTextEmbeddings_forward(
|
||||
self: transformers.models.clip.modeling_clip.CLIPTextEmbeddings,
|
||||
input_ids: torch.LongTensor | None = None,
|
||||
position_ids: torch.LongTensor | None = None,
|
||||
inputs_embeds: torch.FloatTensor | None = None,
|
||||
) -> torch.Tensor:
|
||||
from modules.devices import dtype
|
||||
seq_length = input_ids.shape[-1] if input_ids is not None else inputs_embeds.shape[-2]
|
||||
|
||||
if position_ids is None:
|
||||
position_ids = self.position_ids[:, :seq_length]
|
||||
|
||||
if inputs_embeds is None:
|
||||
inputs_embeds = self.token_embedding(input_ids).type(dtype) # Type correction.
|
||||
|
||||
position_embeddings = self.position_embedding(position_ids)
|
||||
embeddings = inputs_embeds + position_embeddings
|
||||
|
||||
return embeddings
|
||||
|
||||
transformers.models.clip.modeling_clip._make_causal_mask = _make_causal_mask
|
||||
transformers.models.clip.modeling_clip.CLIPTextEmbeddings.forward = CLIPTextEmbeddings_forward
|
||||
@@ -1,19 +0,0 @@
|
||||
import torch
|
||||
from collections.abc import Callable
|
||||
from modules.shared import log, opts
|
||||
|
||||
|
||||
def catch_nan(func: Callable[[], torch.Tensor]):
|
||||
if not opts.directml_catch_nan:
|
||||
return func()
|
||||
|
||||
tries = 0
|
||||
tensor = func()
|
||||
while tensor.isnan().sum() != 0 and tries < 10:
|
||||
if tries == 0:
|
||||
log.warning("NaN is produced. Retry with same values...")
|
||||
tries += 1
|
||||
tensor = func()
|
||||
if tensor.isnan().sum() != 0:
|
||||
log.error("Failed to cover NaN.")
|
||||
return tensor
|
||||
@@ -1,31 +0,0 @@
|
||||
from os import getpid
|
||||
from collections import defaultdict
|
||||
from modules.dml.pdh import HQuery, HCounter, expand_wildcard_path
|
||||
|
||||
|
||||
class MemoryProvider:
|
||||
hQuery: HQuery
|
||||
hCounters: defaultdict[str, list[HCounter]]
|
||||
|
||||
def __init__(self):
|
||||
self.hQuery = HQuery()
|
||||
self.hCounters = defaultdict(list)
|
||||
|
||||
def get_memory(self, device_id: int) -> dict[str, int]:
|
||||
if len(self.hCounters) == 0:
|
||||
pid = getpid()
|
||||
paths_dedicated = expand_wildcard_path(f"\\GPU Process Memory(pid_{pid}_*_phys_{device_id})\\Dedicated Usage")
|
||||
paths_committed = expand_wildcard_path(f"\\GPU Process Memory(pid_{pid}_*_phys_{device_id})\\Total Committed")
|
||||
for path in paths_dedicated:
|
||||
self.hCounters["dedicated_usage"].append(self.hQuery.add_counter(path))
|
||||
for path in paths_committed:
|
||||
self.hCounters["total_committed"].append(self.hQuery.add_counter(path))
|
||||
self.hQuery.collect_data()
|
||||
result = defaultdict(int)
|
||||
for key in self.hCounters:
|
||||
for hCounter in self.hCounters[key]:
|
||||
result[key] += hCounter.get_formatted_value(int)
|
||||
return dict(result)
|
||||
|
||||
def __del__(self):
|
||||
self.hQuery.close()
|
||||
@@ -1,10 +0,0 @@
|
||||
from .driver.atiadlxx import ATIADLxx
|
||||
|
||||
|
||||
class AMDMemoryProvider:
|
||||
driver: ATIADLxx = ATIADLxx()
|
||||
|
||||
@staticmethod
|
||||
def mem_get_info(index):
|
||||
usage = AMDMemoryProvider.driver.get_dedicated_vram_usage(index) * (1 << 20)
|
||||
return (AMDMemoryProvider.driver.iHyperMemorySize - usage, AMDMemoryProvider.driver.iHyperMemorySize)
|
||||
@@ -1,47 +0,0 @@
|
||||
import ctypes as C
|
||||
from modules.dml.memory_amd.driver.atiadlxx_apis import ADL2_Main_Control_Create, ADL_Main_Memory_Alloc, ADL2_Adapter_NumberOfAdapters_Get, ADL2_Adapter_AdapterInfo_Get, ADL2_Adapter_MemoryInfo2_Get, ADL2_Adapter_DedicatedVRAMUsage_Get, ADL2_Adapter_VRAMUsage_Get
|
||||
from modules.dml.memory_amd.driver.atiadlxx_structures import ADL_CONTEXT_HANDLE, AdapterInfo, LPAdapterInfo, ADLMemoryInfo2
|
||||
from modules.dml.memory_amd.driver.atiadlxx_defines import ADL_OK
|
||||
|
||||
|
||||
class ATIADLxx:
|
||||
iHyperMemorySize = 0
|
||||
|
||||
def __init__(self):
|
||||
self.context = ADL_CONTEXT_HANDLE()
|
||||
ADL2_Main_Control_Create(ADL_Main_Memory_Alloc, 1, C.byref(self.context))
|
||||
num_adapters = C.c_int(-1)
|
||||
ADL2_Adapter_NumberOfAdapters_Get(self.context, C.byref(num_adapters))
|
||||
AdapterInfoArray = (AdapterInfo * num_adapters.value)()
|
||||
ADL2_Adapter_AdapterInfo_Get(self.context, C.cast(AdapterInfoArray, LPAdapterInfo), C.sizeof(AdapterInfoArray))
|
||||
self.devices = []
|
||||
busNumbers = []
|
||||
for adapter in AdapterInfoArray:
|
||||
if adapter.iBusNumber not in busNumbers: # filter duplicate device
|
||||
self.devices.append(adapter)
|
||||
busNumbers.append(adapter.iBusNumber)
|
||||
self.iHyperMemorySize = self.get_memory_info2(0).iHyperMemorySize
|
||||
|
||||
def get_memory_info2(self, adapterIndex: int) -> ADLMemoryInfo2:
|
||||
info = ADLMemoryInfo2()
|
||||
|
||||
if ADL2_Adapter_MemoryInfo2_Get(self.context, adapterIndex, C.byref(info)) != ADL_OK:
|
||||
raise RuntimeError("ADL2: Failed to get MemoryInfo2")
|
||||
|
||||
return info
|
||||
|
||||
def get_dedicated_vram_usage(self, index: int) -> int:
|
||||
usage = C.c_int(-1)
|
||||
|
||||
if ADL2_Adapter_DedicatedVRAMUsage_Get(self.context, self.devices[index].iAdapterIndex, C.byref(usage)) != ADL_OK:
|
||||
raise RuntimeError("ADL2: Failed to get DedicatedVRAMUsage")
|
||||
|
||||
return usage.value
|
||||
|
||||
def get_vram_usage(self, index: int) -> int:
|
||||
usage = C.c_int(-1)
|
||||
|
||||
if ADL2_Adapter_VRAMUsage_Get(self.context, self.devices[index].iAdapterIndex, C.byref(usage)) != ADL_OK:
|
||||
raise RuntimeError("ADL2: Failed to get VRAMUsage")
|
||||
|
||||
return usage.value
|
||||
@@ -1,50 +0,0 @@
|
||||
import ctypes as C
|
||||
from platform import platform
|
||||
from modules.dml.memory_amd.driver.atiadlxx_structures import ADL_CONTEXT_HANDLE, LPAdapterInfo, ADLMemoryInfo2
|
||||
|
||||
|
||||
if 'Windows' in platform():
|
||||
atiadlxx = C.WinDLL("atiadlxx.dll")
|
||||
else:
|
||||
atiadlxx = C.CDLL("libatiadlxx.so") # Not tested on Linux system. But will be supported.
|
||||
|
||||
|
||||
ADL_MAIN_MALLOC_CALLBACK = C.CFUNCTYPE(C.c_void_p, C.c_int)
|
||||
ADL_MAIN_FREE_CALLBACK = C.CFUNCTYPE(None, C.POINTER(C.c_void_p))
|
||||
|
||||
|
||||
@ADL_MAIN_MALLOC_CALLBACK
|
||||
def ADL_Main_Memory_Alloc(iSize):
|
||||
return C._malloc(iSize)
|
||||
|
||||
|
||||
@ADL_MAIN_FREE_CALLBACK
|
||||
def ADL_Main_Memory_Free(lpBuffer):
|
||||
if lpBuffer[0] is not None:
|
||||
C._free(lpBuffer[0])
|
||||
lpBuffer[0] = None
|
||||
|
||||
|
||||
ADL2_Main_Control_Create = atiadlxx.ADL2_Main_Control_Create
|
||||
ADL2_Main_Control_Create.restype = C.c_int
|
||||
ADL2_Main_Control_Create.argtypes = [ADL_MAIN_MALLOC_CALLBACK, C.c_int, ADL_CONTEXT_HANDLE]
|
||||
|
||||
ADL2_Adapter_NumberOfAdapters_Get = atiadlxx.ADL2_Adapter_NumberOfAdapters_Get
|
||||
ADL2_Adapter_NumberOfAdapters_Get.restype = C.c_int
|
||||
ADL2_Adapter_NumberOfAdapters_Get.argtypes = [ADL_CONTEXT_HANDLE, C.POINTER(C.c_int)]
|
||||
|
||||
ADL2_Adapter_AdapterInfo_Get = atiadlxx.ADL2_Adapter_AdapterInfo_Get
|
||||
ADL2_Adapter_AdapterInfo_Get.restype = C.c_int
|
||||
ADL2_Adapter_AdapterInfo_Get.argtypes = [ADL_CONTEXT_HANDLE, LPAdapterInfo, C.c_int]
|
||||
|
||||
ADL2_Adapter_MemoryInfo2_Get = atiadlxx.ADL2_Adapter_MemoryInfo2_Get
|
||||
ADL2_Adapter_MemoryInfo2_Get.restype = C.c_int
|
||||
ADL2_Adapter_MemoryInfo2_Get.argtypes = [ADL_CONTEXT_HANDLE, C.c_int, C.POINTER(ADLMemoryInfo2)]
|
||||
|
||||
ADL2_Adapter_DedicatedVRAMUsage_Get = atiadlxx.ADL2_Adapter_DedicatedVRAMUsage_Get
|
||||
ADL2_Adapter_DedicatedVRAMUsage_Get.restype = C.c_int
|
||||
ADL2_Adapter_DedicatedVRAMUsage_Get.argtypes = [ADL_CONTEXT_HANDLE, C.c_int, C.POINTER(C.c_int)]
|
||||
|
||||
ADL2_Adapter_VRAMUsage_Get = atiadlxx.ADL2_Adapter_VRAMUsage_Get
|
||||
ADL2_Adapter_VRAMUsage_Get.restype = C.c_int
|
||||
ADL2_Adapter_VRAMUsage_Get.argtypes = [ADL_CONTEXT_HANDLE, C.c_int, C.POINTER(C.c_int)]
|
||||
@@ -1 +0,0 @@
|
||||
ADL_OK = 0
|
||||
@@ -1,90 +0,0 @@
|
||||
import ctypes as C
|
||||
|
||||
|
||||
class _ADLPMActivity(C.Structure):
|
||||
__slot__ = [
|
||||
'iActivityPercent',
|
||||
'iCurrentBusLanes',
|
||||
'iCurrentBusSpeed',
|
||||
'iCurrentPerformanceLevel',
|
||||
'iEngineClock',
|
||||
'iMaximumBusLanes',
|
||||
'iMemoryClock',
|
||||
'iReserved',
|
||||
'iSize',
|
||||
'iVddc',
|
||||
]
|
||||
_ADLPMActivity._fields_ = [ # pylint: disable=protected-access
|
||||
('iActivityPercent', C.c_int),
|
||||
('iCurrentBusLanes', C.c_int),
|
||||
('iCurrentBusSpeed', C.c_int),
|
||||
('iCurrentPerformanceLevel', C.c_int),
|
||||
('iEngineClock', C.c_int),
|
||||
('iMaximumBusLanes', C.c_int),
|
||||
('iMemoryClock', C.c_int),
|
||||
('iReserved', C.c_int),
|
||||
('iSize', C.c_int),
|
||||
('iVddc', C.c_int),
|
||||
]
|
||||
ADLPMActivity = _ADLPMActivity
|
||||
|
||||
|
||||
class _ADLMemoryInfo2(C.Structure):
|
||||
__slot__ = [
|
||||
'iHyperMemorySize',
|
||||
'iInvisibleMemorySize',
|
||||
'iMemoryBandwidth',
|
||||
'iMemorySize',
|
||||
'iVisibleMemorySize',
|
||||
'strMemoryType'
|
||||
]
|
||||
_ADLMemoryInfo2._fields_ = [ # pylint: disable=protected-access
|
||||
('iHyperMemorySize', C.c_longlong),
|
||||
('iInvisibleMemorySize', C.c_longlong),
|
||||
('iMemoryBandwidth', C.c_longlong),
|
||||
('iMemorySize', C.c_longlong),
|
||||
('iVisibleMemorySize', C.c_longlong),
|
||||
('strMemoryType', C.c_char * 256)
|
||||
]
|
||||
ADLMemoryInfo2 = _ADLMemoryInfo2
|
||||
|
||||
|
||||
class _AdapterInfo(C.Structure):
|
||||
__slot__ = [
|
||||
'iSize',
|
||||
'iAdapterIndex',
|
||||
'strUDID',
|
||||
'iBusNumber',
|
||||
'iDeviceNumber',
|
||||
'iFunctionNumber',
|
||||
'iVendorID',
|
||||
'strAdapterName',
|
||||
'strDisplayName',
|
||||
'iPresent',
|
||||
'iExist',
|
||||
'strDriverPath',
|
||||
'strDriverPathExt',
|
||||
'strPNPString',
|
||||
'iOSDisplayIndex',
|
||||
]
|
||||
_AdapterInfo._fields_ = [ # pylint: disable=protected-access
|
||||
('iSize', C.c_int),
|
||||
('iAdapterIndex', C.c_int),
|
||||
('strUDID', C.c_char * 256),
|
||||
('iBusNumber', C.c_int),
|
||||
('iDeviceNumber', C.c_int),
|
||||
('iFunctionNumber', C.c_int),
|
||||
('iVendorID', C.c_int),
|
||||
('strAdapterName', C.c_char * 256),
|
||||
('strDisplayName', C.c_char * 256),
|
||||
('iPresent', C.c_int),
|
||||
('iExist', C.c_int),
|
||||
('strDriverPath', C.c_char * 256),
|
||||
('strDriverPathExt', C.c_char * 256),
|
||||
('strPNPString', C.c_char * 256),
|
||||
('iOSDisplayIndex', C.c_int)
|
||||
]
|
||||
AdapterInfo = _AdapterInfo
|
||||
LPAdapterInfo = C.POINTER(_AdapterInfo)
|
||||
|
||||
ADL_CONTEXT_HANDLE = C.c_void_p
|
||||
@@ -1,90 +0,0 @@
|
||||
from ctypes import byref, cast, c_size_t
|
||||
from ctypes.wintypes import LPCWSTR, DWORD, WCHAR
|
||||
from typing import NamedTuple, TypeVar
|
||||
from .apis import PdhExpandWildCardPathW, PdhOpenQueryW, PdhAddEnglishCounterW, PdhCollectQueryData, PdhGetFormattedCounterValue, PdhGetFormattedCounterArrayW, PdhCloseQuery
|
||||
from .structures import PDH_HQUERY, PDH_HCOUNTER, PDH_FMT_COUNTERVALUE, PPDH_FMT_COUNTERVALUE_ITEM_W
|
||||
from .defines import PDH_FMT_LARGE, PDH_FMT_DOUBLE, PDH_FMT_NOSCALE, PDH_NOEXPANDCOUNTERS, PDH_MORE_DATA, PDH_OK
|
||||
from .msvcrt import malloc
|
||||
from .errors import PDHError
|
||||
|
||||
|
||||
class __InternalAbstraction(NamedTuple):
|
||||
flag: int
|
||||
attr_name: str
|
||||
|
||||
|
||||
_type_map = {
|
||||
int: __InternalAbstraction(PDH_FMT_LARGE, "largeValue"),
|
||||
float: __InternalAbstraction(PDH_FMT_DOUBLE, "doubleValue"),
|
||||
}
|
||||
|
||||
|
||||
def expand_wildcard_path(path: str) -> list[str]:
|
||||
listLength = DWORD(0)
|
||||
if PdhExpandWildCardPathW(None, LPCWSTR(path), None, byref(listLength), PDH_NOEXPANDCOUNTERS) != PDH_MORE_DATA:
|
||||
raise PDHError("Something went wrong.")
|
||||
expanded = (WCHAR * listLength.value)()
|
||||
if PdhExpandWildCardPathW(None, LPCWSTR(path), expanded, byref(listLength), PDH_NOEXPANDCOUNTERS) != PDH_OK:
|
||||
raise PDHError(f"Couldn't expand wildcard path '{path}'")
|
||||
result = []
|
||||
cur = ""
|
||||
for c in expanded:
|
||||
if c == '\0':
|
||||
result.append(cur)
|
||||
cur = ""
|
||||
else:
|
||||
cur += c
|
||||
result.pop()
|
||||
return result
|
||||
|
||||
|
||||
T = TypeVar("T", *_type_map.keys())
|
||||
|
||||
|
||||
class HCounter(PDH_HCOUNTER):
|
||||
def get_formatted_value(self, typ: T) -> T:
|
||||
if typ not in _type_map:
|
||||
raise PDHError(f"Invalid value type: {typ}")
|
||||
flag, attr_name = _type_map[typ]
|
||||
value = PDH_FMT_COUNTERVALUE()
|
||||
if PdhGetFormattedCounterValue(self, DWORD(flag | PDH_FMT_NOSCALE), None, byref(value)) != PDH_OK:
|
||||
raise PDHError("Couldn't get formatted counter value.")
|
||||
return getattr(value.u, attr_name)
|
||||
|
||||
def get_formatted_dict(self, typ: T) -> dict[str, T]:
|
||||
if typ not in _type_map:
|
||||
raise PDHError(f"Invalid value type: {typ}")
|
||||
flag, attr_name = _type_map[typ]
|
||||
bufferSize = DWORD(0)
|
||||
itemCount = DWORD(0)
|
||||
if PdhGetFormattedCounterArrayW(self, DWORD(flag | PDH_FMT_NOSCALE), byref(bufferSize), byref(itemCount), None) != PDH_MORE_DATA:
|
||||
raise PDHError("Something went wrong.")
|
||||
itemBuffer = cast(malloc(c_size_t(bufferSize.value)), PPDH_FMT_COUNTERVALUE_ITEM_W)
|
||||
if PdhGetFormattedCounterArrayW(self, DWORD(flag | PDH_FMT_NOSCALE), byref(bufferSize), byref(itemCount), itemBuffer) != PDH_OK:
|
||||
raise PDHError("Couldn't get formatted counter array.")
|
||||
result: dict[str, T] = {}
|
||||
for i in range(0, itemCount.value):
|
||||
item = itemBuffer[i]
|
||||
result[item.szName] = getattr(item.FmtValue.u, attr_name)
|
||||
return result
|
||||
|
||||
|
||||
class HQuery(PDH_HQUERY):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
if PdhOpenQueryW(None, None, byref(self)) != PDH_OK:
|
||||
raise PDHError("Couldn't open PDH query.")
|
||||
|
||||
def add_counter(self, path: str) -> HCounter:
|
||||
hCounter = HCounter()
|
||||
if PdhAddEnglishCounterW(self, LPCWSTR(path), None, byref(hCounter)) != PDH_OK:
|
||||
raise PDHError("Couldn't add counter query.")
|
||||
return hCounter
|
||||
|
||||
def collect_data(self):
|
||||
if PdhCollectQueryData(self) != PDH_OK:
|
||||
raise PDHError("Couldn't collect query data.")
|
||||
|
||||
def close(self):
|
||||
if PdhCloseQuery(self) != PDH_OK:
|
||||
raise PDHError("Couldn't close PDH query.")
|
||||
@@ -1,37 +0,0 @@
|
||||
from ctypes import CDLL, POINTER
|
||||
from ctypes.wintypes import LPCWSTR, LPDWORD, DWORD
|
||||
from collections.abc import Callable
|
||||
from .structures import PDH_HQUERY, PDH_HCOUNTER, PPDH_FMT_COUNTERVALUE, PPDH_FMT_COUNTERVALUE_ITEM_W
|
||||
from .defines import PDH_FUNCTION, PZZWSTR, DWORD_PTR
|
||||
|
||||
|
||||
pdh = CDLL("pdh.dll")
|
||||
|
||||
|
||||
PdhExpandWildCardPathW: Callable = pdh.PdhExpandWildCardPathW
|
||||
PdhExpandWildCardPathW.restype = PDH_FUNCTION
|
||||
PdhExpandWildCardPathW.argtypes = [LPCWSTR, LPCWSTR, PZZWSTR, LPDWORD, DWORD]
|
||||
|
||||
PdhOpenQueryW: Callable = pdh.PdhOpenQueryW
|
||||
PdhOpenQueryW.restype = PDH_FUNCTION
|
||||
PdhOpenQueryW.argtypes = [LPCWSTR, DWORD_PTR, POINTER(PDH_HQUERY)]
|
||||
|
||||
PdhAddEnglishCounterW: Callable = pdh.PdhAddEnglishCounterW
|
||||
PdhAddEnglishCounterW.restype = PDH_FUNCTION
|
||||
PdhAddEnglishCounterW.argtypes = [PDH_HQUERY, LPCWSTR, DWORD_PTR, POINTER(PDH_HCOUNTER)]
|
||||
|
||||
PdhCollectQueryData: Callable = pdh.PdhCollectQueryData
|
||||
PdhCollectQueryData.restype = PDH_FUNCTION
|
||||
PdhCollectQueryData.argtypes = [PDH_HQUERY]
|
||||
|
||||
PdhGetFormattedCounterValue: Callable = pdh.PdhGetFormattedCounterValue
|
||||
PdhGetFormattedCounterValue.restype = PDH_FUNCTION
|
||||
PdhGetFormattedCounterValue.argtypes = [PDH_HCOUNTER, DWORD, LPDWORD, PPDH_FMT_COUNTERVALUE]
|
||||
|
||||
PdhGetFormattedCounterArrayW: Callable = pdh.PdhGetFormattedCounterArrayW
|
||||
PdhGetFormattedCounterArrayW.restype = PDH_FUNCTION
|
||||
PdhGetFormattedCounterArrayW.argtypes = [PDH_HCOUNTER, DWORD, LPDWORD, LPDWORD, PPDH_FMT_COUNTERVALUE_ITEM_W]
|
||||
|
||||
PdhCloseQuery: Callable = pdh.PdhCloseQuery
|
||||
PdhCloseQuery.restype = PDH_FUNCTION
|
||||
PdhCloseQuery.argtypes = [PDH_HQUERY]
|
||||
@@ -1,23 +0,0 @@
|
||||
from ctypes import c_int, POINTER
|
||||
from ctypes.wintypes import DWORD, WCHAR
|
||||
|
||||
|
||||
PDH_FUNCTION = c_int
|
||||
PDH_OK = 0x00000000
|
||||
PDH_MORE_DATA = -2147481646#0x800007D2
|
||||
|
||||
DWORD_PTR = POINTER(DWORD)
|
||||
PWSTR = POINTER(WCHAR)
|
||||
PZZWSTR = POINTER(WCHAR)
|
||||
|
||||
PDH_NOEXPANDCOUNTERS = 1
|
||||
PDH_NOEXPANDINSTANCES = 2
|
||||
PDH_REFRESHCOUNTERS = 4
|
||||
|
||||
PDH_FMT_LONG = 0x00000100
|
||||
PDH_FMT_DOUBLE = 0x00000200
|
||||
PDH_FMT_LARGE = 0x00000400
|
||||
|
||||
PDH_FMT_NOSCALE = 0x00001000
|
||||
PDH_FMT_1000 = 0x00002000
|
||||
PDH_FMT_NOCAP100 = 0x00008000
|
||||
@@ -1,3 +0,0 @@
|
||||
class PDHError(Exception):
|
||||
def __init__(self, message: str):
|
||||
super().__init__(message)
|
||||
@@ -1,13 +0,0 @@
|
||||
from ctypes import CDLL, c_void_p, c_size_t
|
||||
|
||||
|
||||
msvcrt = CDLL("msvcrt")
|
||||
|
||||
|
||||
malloc = msvcrt.malloc
|
||||
malloc.restype = c_void_p
|
||||
malloc.argtypes = [c_size_t]
|
||||
|
||||
free = msvcrt.free
|
||||
free.restype = None
|
||||
free.argtypes = [c_void_p]
|
||||
@@ -1,45 +0,0 @@
|
||||
from ctypes import Union, c_double, c_longlong, Structure, POINTER
|
||||
from ctypes.wintypes import HANDLE, LONG, LPCSTR, LPCWSTR, DWORD, LPWSTR
|
||||
|
||||
|
||||
PDH_HQUERY = HANDLE
|
||||
PDH_HCOUNTER = HANDLE
|
||||
|
||||
|
||||
class PDH_FMT_COUNTERVALUE_U(Union):
|
||||
_fields_ = [
|
||||
("longValue", LONG),
|
||||
("doubleValue", c_double),
|
||||
("largeValue", c_longlong),
|
||||
("AnsiStringValue", LPCSTR),
|
||||
("WideStringValue", LPCWSTR),
|
||||
]
|
||||
|
||||
longValue: int
|
||||
doubleValue: float
|
||||
largeValue: int
|
||||
AnsiStringValue: LPCSTR
|
||||
WideStringValue: LPCWSTR
|
||||
|
||||
|
||||
class PDH_FMT_COUNTERVALUE(Structure):
|
||||
_anonymous_ = ("u",)
|
||||
_fields_ = [
|
||||
("CStatus", DWORD),
|
||||
("u", PDH_FMT_COUNTERVALUE_U),
|
||||
]
|
||||
|
||||
CStatus: DWORD
|
||||
u: PDH_FMT_COUNTERVALUE_U
|
||||
PPDH_FMT_COUNTERVALUE = POINTER(PDH_FMT_COUNTERVALUE)
|
||||
|
||||
|
||||
class PDH_FMT_COUNTERVALUE_ITEM_W(Structure):
|
||||
_fields_ = [
|
||||
("szName", LPWSTR),
|
||||
("FmtValue", PDH_FMT_COUNTERVALUE),
|
||||
]
|
||||
|
||||
szName: str
|
||||
FmtValue: PDH_FMT_COUNTERVALUE
|
||||
PPDH_FMT_COUNTERVALUE_ITEM_W = POINTER(PDH_FMT_COUNTERVALUE_ITEM_W)
|
||||
@@ -1,9 +0,0 @@
|
||||
from typing import Union
|
||||
import torch
|
||||
|
||||
|
||||
rDevice = Union[torch.device, int]
|
||||
def get_device(device: rDevice | None=None) -> torch.device:
|
||||
if device is None:
|
||||
device = torch.dml.current_device()
|
||||
return torch.device(device)
|
||||
@@ -47,8 +47,6 @@ else:
|
||||
def get_default_execution_provider() -> ExecutionProvider:
|
||||
if devices.backend == "cpu":
|
||||
return ExecutionProvider.CPU
|
||||
elif devices.backend == "directml":
|
||||
return ExecutionProvider.DirectML
|
||||
elif devices.backend == "cuda":
|
||||
return ExecutionProvider.CUDA
|
||||
elif devices.backend == "rocm":
|
||||
|
||||
@@ -24,9 +24,7 @@ def create_ui():
|
||||
with gr.TabItem("Provider", id="onnxep"):
|
||||
gr.Markdown("Install ONNX execution provider")
|
||||
ep_default = None
|
||||
if cmd_opts.use_directml:
|
||||
ep_default = ExecutionProvider.DirectML
|
||||
elif cmd_opts.use_cuda:
|
||||
if cmd_opts.use_cuda:
|
||||
ep_default = ExecutionProvider.CUDA
|
||||
elif cmd_opts.use_rocm:
|
||||
ep_default = ExecutionProvider.ROCm
|
||||
|
||||
@@ -108,8 +108,6 @@ def dynamic_scaled_dot_product_attention(query: torch.FloatTensor, key: torch.Fl
|
||||
attn_mask=attn_mask[start_idx:end_idx, :, :, :] if attn_mask is not None else attn_mask,
|
||||
dropout_p=dropout_p, is_causal=is_causal, scale=scale, **kwargs
|
||||
)
|
||||
if devices.backend != "directml":
|
||||
getattr(torch, query.device.type).synchronize()
|
||||
else:
|
||||
hidden_states = devices.sdpa_pre_dyanmic_atten(query, key, value, attn_mask=attn_mask, dropout_p=dropout_p, is_causal=is_causal, scale=scale, **kwargs)
|
||||
if is_unsqueezed:
|
||||
@@ -252,8 +250,6 @@ class DynamicAttnProcessorBMM:
|
||||
|
||||
hidden_states[start_idx:end_idx] = attn_slice
|
||||
del attn_slice
|
||||
if devices.backend != "directml":
|
||||
getattr(torch, query.device.type).synchronize()
|
||||
else:
|
||||
attention_probs = attn.get_attention_scores(query, key, attention_mask)
|
||||
hidden_states = torch.bmm(attention_probs, value)
|
||||
|
||||
@@ -98,13 +98,7 @@ def get_fft_device():
|
||||
|
||||
def no_gpu_complex_support():
|
||||
mps_available = hasattr(torch.backends, "mps") and torch.backends.mps.is_available()
|
||||
try:
|
||||
import torch_directml
|
||||
except ImportError:
|
||||
dml_available = False
|
||||
else:
|
||||
dml_available = torch_directml.is_available()
|
||||
return mps_available or dml_available
|
||||
return mps_available
|
||||
|
||||
|
||||
def filter_skip(x, threshold, scale, scale_high):
|
||||
|
||||
@@ -129,6 +129,6 @@ def install():
|
||||
knobs.autotuning.listener = make_autotune_listener(getattr(knobs.autotuning, 'listener', None))
|
||||
knobs.compilation.listener = make_compile_listener(getattr(knobs.compilation, 'listener', None))
|
||||
Autotuner._bench = bench_hook(Autotuner._bench) # pylint: disable=protected-access
|
||||
log.debug('Kernel autotune: reporting installed')
|
||||
# log.debug('Kernel autotune: reporting installed')
|
||||
except Exception as e:
|
||||
log.warning(f'Kernel autotune: reporting install failed: {e}')
|
||||
|
||||
@@ -270,10 +270,6 @@ class OffloadHook(accelerate.hooks.ModelHook):
|
||||
clean_result=False,
|
||||
)
|
||||
offload_dir = getattr(module, "offload_dir", os.path.join(shared.opts.accelerate_offload_path, module.__class__.__name__))
|
||||
if devices.backend == "directml":
|
||||
for k, v in device_map.items():
|
||||
if isinstance(v, int):
|
||||
device_map[k] = f"{devices.device.type}:{v}" # int implies CUDA or XPU device, but it will break DirectML backend so we add type
|
||||
if debug:
|
||||
log.trace(f'Offload: type=balanced op=dispatch map={device_map}')
|
||||
if device_map is not None:
|
||||
|
||||
@@ -88,13 +88,6 @@ elif cmd_opts.use_ipex or devices.has_xpu():
|
||||
log.error(f'IPEX initialization failed: {e}')
|
||||
if os.environ.get('SD_DEVICE_DEBUG', None) is not None:
|
||||
errors.display(e, 'IPEX')
|
||||
elif cmd_opts.use_directml:
|
||||
from modules.dml import directml_init
|
||||
ok, e = directml_init()
|
||||
if not ok:
|
||||
log.error(f'DirectML initialization failed: {e}')
|
||||
if os.environ.get('SD_DEVICE_DEBUG', None) is not None:
|
||||
errors.display(e, 'DirectML')
|
||||
elif cmd_opts.use_rocm or devices.has_rocm():
|
||||
from modules.rocm import rocm_init
|
||||
ok, e = rocm_init()
|
||||
@@ -167,7 +160,6 @@ if cmd_opts.locale is not None:
|
||||
opts.data['ui_locale'] = cmd_opts.locale
|
||||
|
||||
log.debug('Initializing: backend')
|
||||
from modules.dml import directml_do_hijack
|
||||
if cmd_opts.use_xformers:
|
||||
opts.data['cross_attention_optimization'] = 'xFormers'
|
||||
opts.data['uni_pc_lower_order_final'] = opts.schedulers_use_loworder # compatibility
|
||||
@@ -191,8 +183,6 @@ device = devices.device
|
||||
parallel_processing_allowed = not cmd_opts.lowvram
|
||||
mem_mon = modules.memmon.MemUsageMonitor("MemMon", devices.device)
|
||||
history = history.History()
|
||||
if devices.backend == "directml":
|
||||
directml_do_hijack()
|
||||
log.debug('Quantization: registered=SDNQ')
|
||||
|
||||
try:
|
||||
|
||||
@@ -56,7 +56,7 @@ def get_default_modes(cmd_opts, mem_stat):
|
||||
agent = devices.get_hip_agent()
|
||||
if agent.gfx_version < 0x1100:
|
||||
default_sdp_override_options = ['Dynamic attention'] # only RDNA2 and older GPUs needs this
|
||||
elif devices.backend in {"directml", "cpu", "mps"}:
|
||||
elif devices.backend in {"cpu", "mps"}:
|
||||
default_sdp_override_options = ['Dynamic attention']
|
||||
|
||||
if devices.get_optimal_device_name() != "cpu":
|
||||
|
||||
@@ -25,14 +25,6 @@ def list_onnx_providers():
|
||||
return "CPU", []
|
||||
|
||||
|
||||
def list_dml_providers():
|
||||
try:
|
||||
from modules.dml import memory_providers, default_memory_provider
|
||||
return default_memory_provider, memory_providers
|
||||
except Exception:
|
||||
return "Performance Counter", []
|
||||
|
||||
|
||||
def list_checkpoint_titles():
|
||||
import modules.sd_models # pylint: disable=redefined-outer-name
|
||||
return modules.sd_models.checkpoint_titles()
|
||||
@@ -83,7 +75,6 @@ def create_settings(cmd_opts):
|
||||
default_xetcache_dir = os.environ.get("HF_XET_CACHE ", None) or os.path.join(paths.models_path, 'xet')
|
||||
|
||||
default_onnx_execution_provider, default_onnx_execution_providers = list_onnx_providers()
|
||||
default_dml_memory_provider, default_dml_memory_providers = list_dml_providers()
|
||||
|
||||
hide_dirs = {"visible": not cmd_opts.hide_ui_dir_config}
|
||||
|
||||
@@ -313,10 +304,6 @@ def create_settings(cmd_opts):
|
||||
"openvino_compile_backend": OptionInfo("openvino_fx", "OpenVINO compile backend", gr.Radio, {"choices": ["openvino", "openvino_fx"], "visible": cmd_opts.use_openvino}),
|
||||
"openvino_disable_model_caching": OptionInfo(True, "OpenVINO disable model caching", gr.Checkbox, {"visible": cmd_opts.use_openvino}),
|
||||
"openvino_disable_memory_cleanup": OptionInfo(True, "OpenVINO disable memory cleanup", gr.Checkbox, {"visible": cmd_opts.use_openvino}),
|
||||
|
||||
"directml_sep": OptionInfo("<h2>DirectML</h2>", "", gr.HTML, {"visible": devices.backend == "directml"}),
|
||||
"directml_memory_provider": OptionInfo(default_dml_memory_provider, "DirectML memory stats provider", gr.Radio, {"choices": default_dml_memory_providers, "visible": devices.backend == "directml"}),
|
||||
"directml_catch_nan": OptionInfo(False, "DirectML retry ops for NaN", gr.Checkbox, {"visible": devices.backend == "directml"}),
|
||||
}))
|
||||
|
||||
# --- Pipeline Modifiers ---
|
||||
|
||||
@@ -135,9 +135,6 @@ def run_settings(*args):
|
||||
from modules.onnx_impl import install_olive, initialize_onnx_pipelines
|
||||
install_olive()
|
||||
initialize_onnx_pipelines()
|
||||
if shared.cmd_opts.use_directml:
|
||||
from modules.dml import directml_override_opts
|
||||
directml_override_opts()
|
||||
if shared.cmd_opts.use_openvino:
|
||||
if "Model" not in shared.opts.cuda_compile:
|
||||
log.warning("OpenVINO: Overriding Torch Compile Model")
|
||||
@@ -196,9 +193,6 @@ def run_settings_single(value, key, progress=False, force=False):
|
||||
if key == "cuda_compile_backend" and value == "olive-ai":
|
||||
from modules.onnx_impl import install_olive
|
||||
install_olive()
|
||||
if shared.cmd_opts.use_directml:
|
||||
from modules.dml import directml_override_opts
|
||||
directml_override_opts()
|
||||
shared.opts.save(silent=True)
|
||||
if key == 'sd_text_encoder':
|
||||
sd_models.reload_text_encoder() # apply the change now; reloads the model for encoders with no in-place swap
|
||||
|
||||
@@ -109,7 +109,6 @@ main.ignore-paths=[
|
||||
"modules/schedulers/scheduler_*.py",
|
||||
"modules/apg",
|
||||
"modules/cfgzero",
|
||||
"modules/dml",
|
||||
"modules/face",
|
||||
"modules/flash_attn_triton_amd",
|
||||
"modules/ggml",
|
||||
|
||||
+1
-1
Submodule wiki updated: ee4e24dbb8...9ff9ec3bb0
Reference in New Issue
Block a user