| import torch
|
| from typing import Tuple, List, Dict, Union, Optional
|
| from pprint import pformat
|
| import random
|
| import numpy
|
| import os
|
| import numpy as np
|
| import requests
|
| import io
|
| import base64
|
| from PIL import Image
|
|
|
|
|
| def compile_model(m, fast):
|
| if fast == 0:
|
| return m
|
| return (
|
| torch.compile(
|
| m,
|
| mode={
|
| 1: "reduce-overhead",
|
| 2: "max-autotune",
|
| 3: "default",
|
| }[fast],
|
| )
|
| if hasattr(torch, "compile")
|
| else m
|
| )
|
|
|
| def set_random_seed(seed: int = 42) -> None:
|
| random.seed(seed)
|
| numpy.random.seed(seed)
|
| torch.manual_seed(seed)
|
| torch.cuda.manual_seed(seed)
|
| torch.cuda.manual_seed_all(seed)
|
|
|
| def filter_params(model, ndim_dict, nowd_keys=()) -> Tuple[
|
| List[str], List[torch.nn.Parameter], List[Dict[str, Union[torch.nn.Parameter, float]]]
|
| ]:
|
| para_groups, para_groups_dbg = {}, {}
|
| names, paras = [], []
|
| names_no_grad = []
|
| count, numel = 0, 0
|
| for name, para in model.named_parameters():
|
| name = name.replace('_fsdp_wrapped_module.', '')
|
| if not para.requires_grad:
|
| names_no_grad.append(name)
|
| continue
|
| count += 1
|
| numel += para.numel()
|
| names.append(name)
|
| paras.append(para)
|
|
|
| if ndim_dict.get(name, 0) == 1 or name.endswith('bias') or any(k in name for k in nowd_keys):
|
| cur_wd_sc, group_name = 0., 'ND'
|
| else:
|
| cur_wd_sc, group_name = 1., 'D'
|
|
|
| if group_name not in para_groups:
|
| para_groups[group_name] = {'params': [], 'wd_sc': cur_wd_sc}
|
| para_groups_dbg[group_name] = {'params': [], 'wd_sc': cur_wd_sc}
|
| para_groups[group_name]['params'].append(para)
|
| para_groups_dbg[group_name]['params'].append(name)
|
|
|
| for g in para_groups_dbg.values():
|
| g['params'] = pformat(', '.join(g['params']), width=200)
|
|
|
| print(f'[get_param_groups] param_groups = \n{pformat(para_groups_dbg, indent=2, width=240)}\n')
|
|
|
| for rk in range(torch.distributed.get_world_size()):
|
| torch.distributed.barrier()
|
| if torch.distributed.get_rank() == rk:
|
| print(f'[get_param_groups][rank{torch.distributed.get_rank()}] {type(model).__name__=} {count=}, {numel=}', flush=True)
|
| print('')
|
|
|
| assert len(names_no_grad) == 0, f'[get_param_groups] names_no_grad = \n{pformat(names_no_grad, indent=2, width=240)}\n'
|
| del ndim_dict
|
| return names, paras, list(para_groups.values())
|
|
|
| def get_filter(filt_size=3):
|
| if(filt_size == 1):
|
| a = numpy.array([1., ])
|
| elif(filt_size == 2):
|
| a = numpy.array([1., 1.])
|
| elif(filt_size == 3):
|
| a = numpy.array([1., 2., 1.])
|
| elif(filt_size == 4):
|
| a = numpy.array([1., 3., 3., 1.])
|
| elif(filt_size == 5):
|
| a = numpy.array([1., 4., 6., 4., 1.])
|
| elif(filt_size == 6):
|
| a = numpy.array([1., 5., 10., 10., 5., 1.])
|
| elif(filt_size == 7):
|
| a = numpy.array([1., 6., 15., 20., 15., 6., 1.])
|
|
|
| filt = torch.Tensor(a[:, None] * a[None, :])
|
| filt = filt / torch.sum(filt)
|
|
|
| return filt
|
|
|
| def get_pad_layer(pad_type):
|
| if(pad_type in ['refl', 'reflect']):
|
| PadLayer = torch.nn.ReflectionPad2d
|
| elif(pad_type in ['repl', 'replicate']):
|
| PadLayer = torch.nn.ReplicationPad2d
|
| elif(pad_type == 'zero'):
|
| PadLayer = torch.nn.ZeroPad2d
|
| else:
|
| print('Pad type [%s] not recognized' % pad_type)
|
| return PadLayer
|
|
|
| def ensure_dir(path: str):
|
| os.makedirs(path, exist_ok=True)
|
|
|
| def pil_to_tensor(img: Image.Image) -> torch.Tensor:
|
| img = img.convert("RGB")
|
| arr = np.asarray(img).astype(np.float32) / 255.0
|
| arr = np.transpose(arr, (2, 0, 1))
|
| return torch.from_numpy(arr).unsqueeze(0)
|
|
|
| def tensor_to_pil(tensor: torch.Tensor) -> Image.Image:
|
| if tensor.dim() == 4:
|
| tensor = tensor[0]
|
| tensor = tensor.detach().float().cpu().clamp(0, 1)
|
| arr = tensor.numpy()
|
| arr = np.transpose(arr, (1, 2, 0))
|
| arr = (arr * 255.0).round().astype(np.uint8)
|
| return Image.fromarray(arr)
|
|
|
| def decode_base64_image(image_base64: str) -> Image.Image:
|
| if image_base64.startswith("data:image") and "," in image_base64:
|
| image_base64 = image_base64.split(",", 1)[1]
|
| image_bytes = base64.b64decode(image_base64)
|
| return Image.open(io.BytesIO(image_bytes)).convert("RGB")
|
|
|
| def load_image_from_url(url: str, timeout: int = 15) -> Image.Image:
|
| resp = requests.get(url, timeout=timeout)
|
| resp.raise_for_status()
|
| return Image.open(io.BytesIO(resp.content)).convert("RGB")
|
|
|
| def resize_to_multiple_of_16(img: Image.Image, max_size: Optional[int] = 1536) -> Image.Image:
|
| w, h = img.size
|
| if max_size is not None:
|
| scale = min(max_size / max(w, h), 1.0)
|
| w = int(w * scale)
|
| h = int(h * scale)
|
| w = max(16, (w // 16) * 16)
|
| h = max(16, (h // 16) * 16)
|
| return img.resize((w, h), Image.LANCZOS)
|
|
|