network_lokr.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import torch
  2. import lyco_helpers
  3. import network
  4. class ModuleTypeLokr(network.ModuleType):
  5. def create_module(self, net: network.Network, weights: network.NetworkWeights):
  6. has_1 = "lokr_w1" in weights.w or ("lokr_w1_a" in weights.w and "lokr_w1_b" in weights.w)
  7. has_2 = "lokr_w2" in weights.w or ("lokr_w2_a" in weights.w and "lokr_w2_b" in weights.w)
  8. if has_1 and has_2:
  9. return NetworkModuleLokr(net, weights)
  10. return None
  11. def make_kron(orig_shape, w1, w2):
  12. if len(w2.shape) == 4:
  13. w1 = w1.unsqueeze(2).unsqueeze(2)
  14. w2 = w2.contiguous()
  15. return torch.kron(w1, w2).reshape(orig_shape)
  16. class NetworkModuleLokr(network.NetworkModule):
  17. def __init__(self, net: network.Network, weights: network.NetworkWeights):
  18. super().__init__(net, weights)
  19. self.w1 = weights.w.get("lokr_w1")
  20. self.w1a = weights.w.get("lokr_w1_a")
  21. self.w1b = weights.w.get("lokr_w1_b")
  22. self.dim = self.w1b.shape[0] if self.w1b is not None else self.dim
  23. self.w2 = weights.w.get("lokr_w2")
  24. self.w2a = weights.w.get("lokr_w2_a")
  25. self.w2b = weights.w.get("lokr_w2_b")
  26. self.dim = self.w2b.shape[0] if self.w2b is not None else self.dim
  27. self.t2 = weights.w.get("lokr_t2")
  28. def calc_updown(self, orig_weight):
  29. if self.w1 is not None:
  30. w1 = self.w1.to(orig_weight.device)
  31. else:
  32. w1a = self.w1a.to(orig_weight.device)
  33. w1b = self.w1b.to(orig_weight.device)
  34. w1 = w1a @ w1b
  35. if self.w2 is not None:
  36. w2 = self.w2.to(orig_weight.device)
  37. elif self.t2 is None:
  38. w2a = self.w2a.to(orig_weight.device)
  39. w2b = self.w2b.to(orig_weight.device)
  40. w2 = w2a @ w2b
  41. else:
  42. t2 = self.t2.to(orig_weight.device)
  43. w2a = self.w2a.to(orig_weight.device)
  44. w2b = self.w2b.to(orig_weight.device)
  45. w2 = lyco_helpers.make_weight_cp(t2, w2a, w2b)
  46. output_shape = [w1.size(0) * w2.size(0), w1.size(1) * w2.size(1)]
  47. if len(orig_weight.shape) == 4:
  48. output_shape = orig_weight.shape
  49. updown = make_kron(output_shape, w1, w2)
  50. return self.finalize_updown(updown, orig_weight, output_shape)