diff options
author | zhaohu xing <32668889+920232796@users.noreply.github.com> | 2022-11-30 02:13:17 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-30 02:13:17 +0000 |
commit | 0831ab476c626eb796b609acf8771177692bfab7 (patch) | |
tree | ebae98ea40ecc5b34497424bee19310e9fac4068 /modules/devices.py | |
parent | ee3f5ea3eeb31f1ed72e2f0cbed2c00a782497d8 (diff) | |
parent | 4b3c5bc24bffdf429c463a465763b3077fe55eb8 (diff) | |
download | stable-diffusion-webui-gfx803-0831ab476c626eb796b609acf8771177692bfab7.tar.gz stable-diffusion-webui-gfx803-0831ab476c626eb796b609acf8771177692bfab7.tar.bz2 stable-diffusion-webui-gfx803-0831ab476c626eb796b609acf8771177692bfab7.zip |
Merge branch 'master' into master
Diffstat (limited to 'modules/devices.py')
-rw-r--r-- | modules/devices.py | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/modules/devices.py b/modules/devices.py index f30b6ebc..e69c1fe3 100644 --- a/modules/devices.py +++ b/modules/devices.py @@ -2,9 +2,10 @@ import sys, os, shlex import contextlib import torch from modules import errors +from packaging import version -# has_mps is only available in nightly pytorch (for now) and MasOS 12.3+. +# has_mps is only available in nightly pytorch (for now) and macOS 12.3+. # check `getattr` and try it for compatibility def has_mps() -> bool: if not getattr(torch, 'has_mps', False): @@ -24,17 +25,18 @@ def extract_device_id(args, name): return None -def get_optimal_device(): - if torch.cuda.is_available(): - from modules import shared +def get_cuda_device_string(): + from modules import shared - device_id = shared.cmd_opts.device_id + if shared.cmd_opts.device_id is not None: + return f"cuda:{shared.cmd_opts.device_id}" - if device_id is not None: - cuda_device = f"cuda:{device_id}" - return torch.device(cuda_device) - else: - return torch.device("cuda") + return "cuda" + + +def get_optimal_device(): + if torch.cuda.is_available(): + return torch.device(get_cuda_device_string()) # if has_mps(): # return torch.device("mps") @@ -44,8 +46,9 @@ def get_optimal_device(): def torch_gc(): if torch.cuda.is_available(): - torch.cuda.empty_cache() - torch.cuda.ipc_collect() + with torch.cuda.device(get_cuda_device_string()): + torch.cuda.empty_cache() + torch.cuda.ipc_collect() def enable_tf32(): @@ -97,9 +100,25 @@ def autocast(disable=False): # MPS workaround for https://github.com/pytorch/pytorch/issues/79383 -def mps_contiguous(input_tensor, device): - return input_tensor.contiguous() if device.type == 'mps' else input_tensor - - -def mps_contiguous_to(input_tensor, device): - return mps_contiguous(input_tensor, device).to(device) +orig_tensor_to = torch.Tensor.to +def tensor_to_fix(self, *args, **kwargs): + if self.device.type != 'mps' and \ + ((len(args) > 0 and isinstance(args[0], torch.device) and args[0].type == 'mps') or \ + (isinstance(kwargs.get('device'), torch.device) and kwargs['device'].type == 'mps')): + self = self.contiguous() + return orig_tensor_to(self, *args, **kwargs) + + +# MPS workaround for https://github.com/pytorch/pytorch/issues/80800 +orig_layer_norm = torch.nn.functional.layer_norm +def layer_norm_fix(*args, **kwargs): + if len(args) > 0 and isinstance(args[0], torch.Tensor) and args[0].device.type == 'mps': + args = list(args) + args[0] = args[0].contiguous() + return orig_layer_norm(*args, **kwargs) + + +# PyTorch 1.13 doesn't need these fixes but unfortunately is slower and has regressions that prevent training from working +if has_mps() and version.parse(torch.__version__) < version.parse("1.13"): + torch.Tensor.to = tensor_to_fix + torch.nn.functional.layer_norm = layer_norm_fix |