Yi Xie commited on
Commit
aa5fd42
·
1 Parent(s): b770ee6

Add 2xLexicaRRDBNet and 2xLexicaRRDBNet_Sharp

Browse files
Files changed (3) hide show
  1. app.py +2 -0
  2. converter.py +48 -7
  3. known_models.yaml +24 -0
app.py CHANGED
@@ -84,6 +84,8 @@ def convert(input_model):
84
  command += ['--num-blocks', str(model['blocks'])]
85
  if 'convs' in model:
86
  command += ['--num-convs', str(model['convs'])]
 
 
87
  command += [file]
88
  logger.debug('Command: %s', command)
89
  process = subprocess.Popen(command, stdout=subprocess.PIPE)
 
84
  command += ['--num-blocks', str(model['blocks'])]
85
  if 'convs' in model:
86
  command += ['--num-convs', str(model['convs'])]
87
+ if 'shuffle-factor' in model:
88
+ command += ['--shuffle-factor', str(model['shuffle-factor'])]
89
  command += [file]
90
  logger.debug('Command: %s', command)
91
  process = subprocess.Popen(command, stdout=subprocess.PIPE)
converter.py CHANGED
@@ -38,6 +38,7 @@ optional_args.add_argument('--has-cuda', action='store_true', help='Input model
38
  optional_args.add_argument('--num-features', type=int, help='Override number of features for (Real-)ESRGAN model')
39
  optional_args.add_argument('--num-blocks', type=int, help='Override number of blocks for (Real-)ESRGAN model')
40
  optional_args.add_argument('--num-convs', type=int, help='Override number of conv layers for Real-ESRGAN Compact model')
 
41
  optional_args.add_argument('--input-size', type=int, default=256, help='Input size (both width and height), default to 256')
42
  optional_args.add_argument('--shrink-size', type=int, default=20, help='Shrink size (applied to all 4 sides on input), default to 20')
43
  optional_args.add_argument('--description', type=str, required=False, help='Description of the model, supports Markdown')
@@ -88,13 +89,20 @@ else:
88
  logger.info('Using torch device cpu, please be patient')
89
 
90
  logger.info('Creating model architecture')
91
- channels = 3
 
 
92
  if args.monochrome:
93
- channels = 1
 
 
 
 
94
 
95
  num_features = 64
96
  num_blocks = 23
97
  num_convs = 16
 
98
 
99
  if args.type == 'esrgan_old_lite':
100
  num_features = 32
@@ -110,17 +118,17 @@ if args.num_convs is not None:
110
  if args.type == 'esrgan_old' or args.type == 'esrgan_old_lite':
111
  from esrgan_old import architecture
112
  torch_model = architecture.RRDB_Net(
113
- channels, channels, num_features, num_blocks, gc=32, upscale=args.scale, norm_type=None,
114
  act_type='leakyrelu', mode='CNA', res_scale=1, upsample_mode='upconv')
115
  elif args.type == 'real_esrgan':
116
  from basicsr.archs.rrdbnet_arch import RRDBNet
117
- torch_model = RRDBNet(num_in_ch=channels, num_out_ch=channels, num_feat=num_features, num_block=num_blocks, num_grow_ch=32, scale=args.scale)
118
  elif args.type == 'real_esrgan_compact':
119
  from basicsr.archs.srvgg_arch import SRVGGNetCompact
120
- torch_model = SRVGGNetCompact(num_in_ch=channels, num_out_ch=channels, num_feat=num_features, num_conv=num_convs, upscale=args.scale, act_type='prelu')
121
  elif args.type == 'esrgan_plus':
122
  from esrgan_plus.codes.models.modules.architecture import RRDBNet
123
- torch_model = RRDBNet(in_nc=channels, out_nc=channels, nf=num_features, nb=num_blocks, gc=32, upscale=args.scale)
124
  else:
125
  logger.fatal('Unknown model type: %s', args.type)
126
  sys.exit(-1)
@@ -151,6 +159,35 @@ if args.monochrome:
151
  return x
152
  torch_model = MonochromeWrapper(torch_model)
153
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  logger.info('Tracing model, will take a long time and a lot of RAM')
155
  torch_model.eval()
156
  torch_model = torch_model.to(device)
@@ -170,10 +207,14 @@ logger.info('Converting to Core ML')
170
  input_shape = [1, 3, args.input_size, args.input_size]
171
  output_size = args.input_size * args.scale
172
  output_shape = [1, 3, output_size, output_size]
 
 
 
173
  model = ct.convert(
174
  traced_model,
175
  convert_to="mlprogram",
176
- inputs=[ct.TensorType(shape=input_shape)]
 
177
  )
178
  model_name = args.filename.split('/')[-1].split('.')[0]
179
  mlmodel_file = args.out_dir + '/' + model_name + '.mlpackage'
 
38
  optional_args.add_argument('--num-features', type=int, help='Override number of features for (Real-)ESRGAN model')
39
  optional_args.add_argument('--num-blocks', type=int, help='Override number of blocks for (Real-)ESRGAN model')
40
  optional_args.add_argument('--num-convs', type=int, help='Override number of conv layers for Real-ESRGAN Compact model')
41
+ optional_args.add_argument('--shuffle-factor', type=int, help='Shuffle input channels in ESRGAN model')
42
  optional_args.add_argument('--input-size', type=int, default=256, help='Input size (both width and height), default to 256')
43
  optional_args.add_argument('--shrink-size', type=int, default=20, help='Shrink size (applied to all 4 sides on input), default to 20')
44
  optional_args.add_argument('--description', type=str, required=False, help='Description of the model, supports Markdown')
 
89
  logger.info('Using torch device cpu, please be patient')
90
 
91
  logger.info('Creating model architecture')
92
+ in_channels = 3
93
+ out_channels = 3
94
+ model_scale = args.scale
95
  if args.monochrome:
96
+ in_channels = 1
97
+ out_channels = 1
98
+ if args.shuffle_factor:
99
+ in_channels *= args.shuffle_factor * args.shuffle_factor
100
+ model_scale *= args.shuffle_factor
101
 
102
  num_features = 64
103
  num_blocks = 23
104
  num_convs = 16
105
+ shuffle_factor = None
106
 
107
  if args.type == 'esrgan_old_lite':
108
  num_features = 32
 
118
  if args.type == 'esrgan_old' or args.type == 'esrgan_old_lite':
119
  from esrgan_old import architecture
120
  torch_model = architecture.RRDB_Net(
121
+ in_channels, out_channels, num_features, num_blocks, gc=32, upscale=model_scale, norm_type=None,
122
  act_type='leakyrelu', mode='CNA', res_scale=1, upsample_mode='upconv')
123
  elif args.type == 'real_esrgan':
124
  from basicsr.archs.rrdbnet_arch import RRDBNet
125
+ torch_model = RRDBNet(num_in_ch=in_channels, num_out_ch=out_channels, num_feat=num_features, num_block=num_blocks, num_grow_ch=32, scale=args.scale)
126
  elif args.type == 'real_esrgan_compact':
127
  from basicsr.archs.srvgg_arch import SRVGGNetCompact
128
+ torch_model = SRVGGNetCompact(num_in_ch=in_channels, num_out_ch=out_channels, num_feat=num_features, num_conv=num_convs, upscale=args.scale, act_type='prelu')
129
  elif args.type == 'esrgan_plus':
130
  from esrgan_plus.codes.models.modules.architecture import RRDBNet
131
+ torch_model = RRDBNet(in_nc=in_channels, out_nc=out_channels, nf=num_features, nb=num_blocks, gc=32, upscale=args.scale)
132
  else:
133
  logger.fatal('Unknown model type: %s', args.type)
134
  sys.exit(-1)
 
159
  return x
160
  torch_model = MonochromeWrapper(torch_model)
161
 
162
+ if args.shuffle_factor:
163
+ from torch import nn
164
+ # Source: https://github.com/chaiNNer-org/spandrel/blob/cb2f03459819ce114c52e328b7ac9bb2812f205a/libs/spandrel/spandrel/architectures/__arch_helpers/padding.py
165
+ def pad_to_multiple(
166
+ tensor: torch.Tensor,
167
+ multiple: int,
168
+ *,
169
+ mode: str,
170
+ value: float = 0.0,
171
+ ) -> torch.Tensor:
172
+ _, _, h, w = tensor.size()
173
+ pad_h = (multiple - h % multiple) % multiple
174
+ pad_w = (multiple - w % multiple) % multiple
175
+ if pad_h or pad_w:
176
+ return nn.pad(tensor, (0, pad_w, 0, pad_h), mode, value)
177
+ return tensor
178
+
179
+ class ShuffleWrapper(nn.Module):
180
+ def __init__(self, model: nn.Module):
181
+ super(ShuffleWrapper, self).__init__()
182
+ self.model = model
183
+ def forward(self, x: torch.Tensor):
184
+ _, _, h, w = x.size()
185
+ x = pad_to_multiple(x, args.shuffle_factor, mode="reflect")
186
+ x = torch.pixel_unshuffle(x, downscale_factor=args.shuffle_factor)
187
+ x = self.model(x)
188
+ return x[:, :, : h * model_scale, : w * model_scale]
189
+ torch_model = ShuffleWrapper(torch_model)
190
+
191
  logger.info('Tracing model, will take a long time and a lot of RAM')
192
  torch_model.eval()
193
  torch_model = torch_model.to(device)
 
207
  input_shape = [1, 3, args.input_size, args.input_size]
208
  output_size = args.input_size * args.scale
209
  output_shape = [1, 3, output_size, output_size]
210
+ minimum_deployment_target = None
211
+ if args.shuffle_factor:
212
+ minimum_deployment_target = ct.target.iOS16
213
  model = ct.convert(
214
  traced_model,
215
  convert_to="mlprogram",
216
+ inputs=[ct.TensorType(shape=input_shape)],
217
+ minimum_deployment_target=minimum_deployment_target
218
  )
219
  model_name = args.filename.split('/')[-1].split('.')[0]
220
  mlmodel_file = args.out_dir + '/' + model_name + '.mlpackage'
known_models.yaml CHANGED
@@ -340,4 +340,28 @@ models:
340
  description: "Category: Oversharpening Purpose: Denoise Pretrained: 1st attempt on random sharpening with the same dataset at 200000 iterations, which was trained on non-random desharp model, total ~600000 iterations on 3 models.\n\n\n\nMade for rare particular cases when the image was destroyed by applying noise, i.e. game textures or any badly exported photos. If your image does not have any oversharpening, it won't hurt them, leaving as is. In theory, this model knows when to activate and when to skip, also can successfully remove artifacts if only some parts of the image are oversharpened, for example in image consisting of several combined images, 1 of them with sharpen noise."
341
  author: "Loinne"
342
  source: "[OpenModelDB](https://openmodeldb.info/models/1x-DeSharpen)"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343
  license: "[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/)"
 
340
  description: "Category: Oversharpening Purpose: Denoise Pretrained: 1st attempt on random sharpening with the same dataset at 200000 iterations, which was trained on non-random desharp model, total ~600000 iterations on 3 models.\n\n\n\nMade for rare particular cases when the image was destroyed by applying noise, i.e. game textures or any badly exported photos. If your image does not have any oversharpening, it won't hurt them, leaving as is. In theory, this model knows when to activate and when to skip, also can successfully remove artifacts if only some parts of the image are oversharpened, for example in image consisting of several combined images, 1 of them with sharpen noise."
341
  author: "Loinne"
342
  source: "[OpenModelDB](https://openmodeldb.info/models/1x-DeSharpen)"
343
+ license: "[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/)"
344
+ - name: "2xLexicaRRDBNet"
345
+ type: esrgan_old
346
+ file: "./torch_models/2xLexicaRRDBNet.pth"
347
+ sourceLink: https://github.com/Phhofm/models/raw/main/2xLexicaRRDBNet/2xLexicaRRDBNet.pth
348
+ sha256: 47c4ecdb06717b13e16da3000485cce72e378e18b7b7ee2e1020562283f7ac31
349
+ scale: 2
350
+ shuffle-factor: 2
351
+ cuda: true
352
+ description: "Upscaling AI generated images"
353
+ author: "[Philip Hofmann](https://github.com/Phhofm)"
354
+ source: "[GitHub Phhofm/models](https://github.com/Phhofm/models)"
355
+ license: "[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/)"
356
+ - name: "2xLexicaRRDBNet Sharp"
357
+ type: esrgan_old
358
+ file: "./torch_models/2xLexicaRRDBNet_Sharp.pth"
359
+ sourceLink: https://github.com/Phhofm/models/raw/main/2xLexicaRRDBNet/2xLexicaRRDBNet_Sharp.pth
360
+ sha256: 11e7bec714d8d15e686e336fe7095bd952e21ee8308551a00ea4df2caa374ac7
361
+ scale: 2
362
+ shuffle-factor: 2
363
+ cuda: true
364
+ description: "Upscaling AI generated images - a bit sharper then 2xLexicaRRDBNet"
365
+ author: "[Philip Hofmann](https://github.com/Phhofm)"
366
+ source: "[GitHub Phhofm/models](https://github.com/Phhofm/models)"
367
  license: "[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/)"