tailot commited on
Commit
e4977dc
·
verified ·
1 Parent(s): 2fa0b62

Upload folder using huggingface_hub

Browse files
README.md CHANGED
@@ -19,14 +19,24 @@ tags:
19
 
20
  Benvenuto su **Universal Upscale**, l'applicazione per l'upscaling e super-resolution di immagini a qualsiasi risoluzione o fattore di scala.
21
 
 
 
 
 
22
  ## Come usare lo Space / How to use this Space
23
 
24
  1. **Carica un'immagine / Upload an image**: trascina o carica un'immagine dal tuo dispositivo.
25
  2. **Imposta la scala / Set the scale**:
26
- - **Scale Factor**: scegli un fattore di scala da **1x fino a 10x** (es. 2x, 4x, 10x).
27
  - **Target Long Side (px)**: in alternativa, specifica la dimensione in pixel del lato più lungo desiderato (es. 2048, 3000, 4096).
28
  3. **Genera / Upscale**: clicca su **Upscale Image** per ottenere l'immagine ad alta risoluzione.
29
 
 
 
 
 
 
 
30
  ## Caratteristiche principali / Features
31
  - **Scale Arbitrarie (LIIF)**: Ingrandimento continuo a qualsiasi fattore o dimensione target senza vincoli rigidi (es. solo 2x/4x).
32
  - **Tiled Inference**: Elaborazione a tasselli sovrapposti per gestire immagini ad alta risoluzione senza esaurire la memoria (OOM).
 
19
 
20
  Benvenuto su **Universal Upscale**, l'applicazione per l'upscaling e super-resolution di immagini a qualsiasi risoluzione o fattore di scala.
21
 
22
+ Questo Space esegue il checkpoint **LIIF v4 GAN** (4.60 M parametri): un unico modello a scala
23
+ arbitraria, esportato come `model.safetensors` + `model_scripted.pt` nel repo
24
+ [tailot/universal-upscale](https://huggingface.co/tailot/universal-upscale).
25
+
26
  ## Come usare lo Space / How to use this Space
27
 
28
  1. **Carica un'immagine / Upload an image**: trascina o carica un'immagine dal tuo dispositivo.
29
  2. **Imposta la scala / Set the scale**:
30
+ - **Scale Factor**: scegli un fattore di scala da **1x fino a 9.2x** (passo 0.2x, es. 2x, 3.6x, 4x, 9.2x).
31
  - **Target Long Side (px)**: in alternativa, specifica la dimensione in pixel del lato più lungo desiderato (es. 2048, 3000, 4096).
32
  3. **Genera / Upscale**: clicca su **Upscale Image** per ottenere l'immagine ad alta risoluzione.
33
 
34
+ > **Limite di scala testato / Tested scale limit**: 9.2x è il valore massimo del cursore
35
+ > ed il fattore di scala più alto raccomandato per questi pesi (la tabella completa del benchmark,
36
+ > fino a 10x, si trova nel model card del modello). Richieste oltre questo valore vengono riportate
37
+ > a 9.2x dal cursore; usando "Target Long Side" puoi comunque arrivare a 4096 px sul lato
38
+ > lungo.
39
+
40
  ## Caratteristiche principali / Features
41
  - **Scale Arbitrarie (LIIF)**: Ingrandimento continuo a qualsiasi fattore o dimensione target senza vincoli rigidi (es. solo 2x/4x).
42
  - **Tiled Inference**: Elaborazione a tasselli sovrapposti per gestire immagini ad alta risoluzione senza esaurire la memoria (OOM).
app.py CHANGED
@@ -37,6 +37,20 @@ def load_model(device: str):
37
 
38
 
39
  MAX_SIDE = 4096
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
 
42
  @gpu_decorator
@@ -46,10 +60,7 @@ def upscale(image, scale: float = 4.0, target_long_side: float = 0.0):
46
  img = image if isinstance(image, Image.Image) else Image.open(image)
47
  img = img.convert("RGB")
48
 
49
- if target_long_side is not None and float(target_long_side) > 0:
50
- factor = float(target_long_side) / float(max(img.size))
51
- else:
52
- factor = float(scale if scale is not None else 4.0)
53
 
54
  out_w, out_h = max(1, int(round(img.width * factor))), max(1, int(round(img.height * factor)))
55
  if max(out_w, out_h) > MAX_SIDE:
@@ -64,7 +75,7 @@ def upscale(image, scale: float = 4.0, target_long_side: float = 0.0):
64
  out = model(lr, out_h, out_w)
65
  arr = (out.squeeze(0).permute(1, 2, 0).cpu().numpy() * 255.0).round().astype(np.uint8)
66
  res_img = Image.fromarray(arr)
67
- status = f"Input: {img.width}x{img.height} | Output: {res_img.width}x{res_img.height} (Scale: {factor:.2f}x) | Device: {device}"
68
  return res_img, status
69
 
70
 
@@ -78,7 +89,7 @@ demo = gr.Interface(
78
  fn=upscale,
79
  inputs=[
80
  gr.Image(type="pil", label="Input Image"),
81
- gr.Slider(minimum=1.0, maximum=10.0, value=4.0, step=0.5, label="Scale Factor"),
82
  gr.Number(value=0, label="Or Target Long Side (px) [0 = use scale factor]"),
83
  ],
84
  outputs=[
@@ -87,8 +98,9 @@ demo = gr.Interface(
87
  ],
88
  title="Universal Upscale",
89
  description=(
90
- "Arbitrary-scale super-resolution: upscale images to any scale factor (1x-10x) or exact target resolution. "
91
- "Built-in tiled inference enables high-resolution upscaling without memory issues."
 
92
  ),
93
  examples=example_files if example_files else None,
94
  )
 
37
 
38
 
39
  MAX_SIDE = 4096
40
+ # Largest scale factor verified end-to-end for the published checkpoint. The slider is capped
41
+ # here; "Target Long Side" still accepts any size up to MAX_SIDE.
42
+ MAX_SCALE = 9.2
43
+
44
+
45
+ def resolve_factor(input_size, scale, target_long_side):
46
+ """Scale factor to apply: an explicit target size wins, scale requests stay under MAX_SCALE."""
47
+ target = float(target_long_side) if target_long_side is not None else 0.0
48
+ if target > 0:
49
+ return target / float(max(input_size)), ""
50
+ factor = float(scale if scale is not None else 4.0)
51
+ if factor > MAX_SCALE:
52
+ return MAX_SCALE, f" (clamped to the tested maximum {MAX_SCALE:g}x)"
53
+ return factor, ""
54
 
55
 
56
  @gpu_decorator
 
60
  img = image if isinstance(image, Image.Image) else Image.open(image)
61
  img = img.convert("RGB")
62
 
63
+ factor, clamped = resolve_factor(img.size, scale, target_long_side)
 
 
 
64
 
65
  out_w, out_h = max(1, int(round(img.width * factor))), max(1, int(round(img.height * factor)))
66
  if max(out_w, out_h) > MAX_SIDE:
 
75
  out = model(lr, out_h, out_w)
76
  arr = (out.squeeze(0).permute(1, 2, 0).cpu().numpy() * 255.0).round().astype(np.uint8)
77
  res_img = Image.fromarray(arr)
78
+ status = f"Input: {img.width}x{img.height} | Output: {res_img.width}x{res_img.height} (Scale: {factor:.2f}x) | Device: {device}{clamped}"
79
  return res_img, status
80
 
81
 
 
89
  fn=upscale,
90
  inputs=[
91
  gr.Image(type="pil", label="Input Image"),
92
+ gr.Slider(minimum=1.0, maximum=9.2, value=4.0, step=0.2, label="Scale Factor"),
93
  gr.Number(value=0, label="Or Target Long Side (px) [0 = use scale factor]"),
94
  ],
95
  outputs=[
 
98
  ],
99
  title="Universal Upscale",
100
  description=(
101
+ "Arbitrary-scale super-resolution: upscale images to any scale factor from 1x up to the tested maximum "
102
+ "9.2x, or to an exact target resolution. Built-in tiled inference enables high-resolution "
103
+ "upscaling without memory issues (outputs are capped at 4096 px on the long side)."
104
  ),
105
  examples=example_files if example_files else None,
106
  )
config.json CHANGED
@@ -11,10 +11,11 @@
11
  "arbitrary": true,
12
  "trained_range": [
13
  1.5,
14
- 10.0
15
- ]
 
16
  },
17
- "parameters": 1261955,
18
  "input": {
19
  "format": "RGB float32 tensor, shape (B, 3, H, W), values in [0, 1]"
20
  },
@@ -25,22 +26,37 @@
25
  "signature": "model(lr, target_h, target_w)",
26
  "tile_size": 256,
27
  "overlap": 16,
28
- "tiling": "overlapping tiles + feather blending, compiled inside model_scripted.pt"
 
 
29
  },
30
  "training": {
31
- "epochs": 100,
32
- "batch_size": 8,
33
- "patch_size": 128,
 
34
  "seed": 42,
35
- "amp": true,
 
 
 
 
 
36
  "losses": [
37
  "L1",
38
- "VGG perceptual",
39
- "PatchGAN"
40
  ],
 
 
 
 
 
 
 
41
  "dataset": "DIV2K train + Flickr2K (3450 HR images)",
42
  "degradation": "Real-ESRGAN-style (blur, noise, downscale, JPEG)",
43
- "checkpoint_epoch": 100
44
  },
45
  "artifacts": {
46
  "torchscript": "model_scripted.pt",
@@ -49,65 +65,82 @@
49
  },
50
  "export": {
51
  "torch_version": "2.14.1+cu130",
52
- "exported_at": "2026-10-23T14:46:57+00:00",
53
  "method": "torch.jit.script + torch.jit.freeze",
54
  "verification": {
55
  "checks": [
56
  {
57
  "input": [
58
- 128,
59
- 160
60
  ],
61
  "target": [
62
- 256,
63
- 320
64
  ],
65
  "output_shape": [
66
  1,
67
  3,
68
- 320,
69
- 256
70
  ],
71
- "max_abs_diff": 1.0132789611816406e-06
72
  },
73
  {
74
  "input": [
75
- 128,
76
- 160
77
  ],
78
  "target": [
79
- 413,
80
- 497
81
  ],
82
  "output_shape": [
83
  1,
84
  3,
85
- 497,
86
- 413
87
  ],
88
- "max_abs_diff": 1.735985279083252e-06
89
  }
90
  ],
91
- "max_abs_diff": 1.735985279083252e-06,
92
  "forward_single_shape": [
93
  1,
94
  3,
95
- 320,
96
- 256
97
  ],
98
  "forward_single_ok": true,
99
  "passed": true,
100
  "cuda_shape_check": [
101
  1,
102
  3,
103
- 320,
104
- 256
105
  ],
106
  "cuda_finite": true
107
  },
108
  "examples": {
109
- "source_image": null,
110
- "files": {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  },
112
  "demo": {
113
  "source_image": "a.png",
 
11
  "arbitrary": true,
12
  "trained_range": [
13
  1.5,
14
+ 6.0
15
+ ],
16
+ "tested_max": 9.2
17
  },
18
+ "parameters": 4603897,
19
  "input": {
20
  "format": "RGB float32 tensor, shape (B, 3, H, W), values in [0, 1]"
21
  },
 
26
  "signature": "model(lr, target_h, target_w)",
27
  "tile_size": 256,
28
  "overlap": 16,
29
+ "tiling": "overlapping tiles + feather blending, compiled inside model_scripted.pt",
30
+ "max_scale": 9.2,
31
+ "max_scale_note": "largest scale factor verified end-to-end for these weights; beyond it the model still runs but is extrapolating outside its training range"
32
  },
33
  "training": {
34
+ "stage": "2",
35
+ "iterations": 4000,
36
+ "batch_size": 2,
37
+ "patch_size": 192,
38
  "seed": 42,
39
+ "optimizer": "adam",
40
+ "lr": 4e-05,
41
+ "min_lr": 2e-05,
42
+ "scheduler": "cosine",
43
+ "grad_clip": 1.0,
44
+ "amp": false,
45
  "losses": [
46
  "L1",
47
+ "edge (Sobel gradient)",
48
+ "PatchGAN adversarial"
49
  ],
50
+ "loss_weights": {
51
+ "l1": 1.0,
52
+ "edge": 0.1,
53
+ "gan": 0.05
54
+ },
55
+ "num_buckets": 16,
56
+ "init_from": "checkpoints/liif_v4/best_liif.pth",
57
  "dataset": "DIV2K train + Flickr2K (3450 HR images)",
58
  "degradation": "Real-ESRGAN-style (blur, noise, downscale, JPEG)",
59
+ "checkpoint_step": 3500
60
  },
61
  "artifacts": {
62
  "torchscript": "model_scripted.pt",
 
65
  },
66
  "export": {
67
  "torch_version": "2.14.1+cu130",
68
+ "exported_at": "2026-10-23T20:40:12+00:00",
69
  "method": "torch.jit.script + torch.jit.freeze",
70
  "verification": {
71
  "checks": [
72
  {
73
  "input": [
74
+ 160,
75
+ 106
76
  ],
77
  "target": [
78
+ 320,
79
+ 212
80
  ],
81
  "output_shape": [
82
  1,
83
  3,
84
+ 212,
85
+ 320
86
  ],
87
+ "max_abs_diff": 1.1920928955078125e-07
88
  },
89
  {
90
  "input": [
91
+ 160,
92
+ 106
93
  ],
94
  "target": [
95
+ 509,
96
+ 335
97
  ],
98
  "output_shape": [
99
  1,
100
  3,
101
+ 335,
102
+ 509
103
  ],
104
+ "max_abs_diff": 1.1920928955078125e-07
105
  }
106
  ],
107
+ "max_abs_diff": 1.1920928955078125e-07,
108
  "forward_single_shape": [
109
  1,
110
  3,
111
+ 212,
112
+ 320
113
  ],
114
  "forward_single_ok": true,
115
  "passed": true,
116
  "cuda_shape_check": [
117
  1,
118
  3,
119
+ 212,
120
+ 320
121
  ],
122
  "cuda_finite": true
123
  },
124
  "examples": {
125
+ "source_image": "0801.png",
126
+ "files": {
127
+ "input.png": [
128
+ 320,
129
+ 240
130
+ ],
131
+ "output_4x.png": [
132
+ 1280,
133
+ 960
134
+ ],
135
+ "output_9.2x.jpg": [
136
+ 1472,
137
+ 1104
138
+ ],
139
+ "compare.jpg": [
140
+ 496,
141
+ 142
142
+ ]
143
+ }
144
  },
145
  "demo": {
146
  "source_image": "a.png",
examples/compare.jpg ADDED

Git LFS Details

  • SHA256: c3fed4ed1c1dabc71735df887f1cee1c026698968cf508761a2db4361d10a8d4
  • Pointer size: 130 Bytes
  • Size of remote file: 15.7 kB
examples/demo_compare.jpg CHANGED

Git LFS Details

  • SHA256: 2f432d975faef6211ce9d8e88982858259f1147d6aa8543e39a209c4c51b3346
  • Pointer size: 130 Bytes
  • Size of remote file: 24 kB

Git LFS Details

  • SHA256: 470e53d7583f39279d94811950d9e43308eb773ac848fab3658ca920cbe42ab6
  • Pointer size: 130 Bytes
  • Size of remote file: 24.2 kB
examples/demo_output_4x.jpg CHANGED

Git LFS Details

  • SHA256: 2e130f1c5644a5db7659b9f769194bded05cc48eb2aace64e6dc586a4ab1ffd5
  • Pointer size: 132 Bytes
  • Size of remote file: 1.42 MB

Git LFS Details

  • SHA256: 4fe0489d768d25f996e17f89c8576dc0d5b7f4a2af6932c0dd4568eeccf38423
  • Pointer size: 132 Bytes
  • Size of remote file: 1.02 MB
examples/input.png ADDED

Git LFS Details

  • SHA256: d23bf400efdbe4c922d30784b822f096157728dd2ead061538814e0542c9d16a
  • Pointer size: 131 Bytes
  • Size of remote file: 163 kB
examples/metrics.json ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "scale": 4,
3
+ "crop_size": 512,
4
+ "num_images": 5,
5
+ "per_image": [
6
+ {
7
+ "image": "0801.png",
8
+ "lr": [
9
+ 128,
10
+ 128
11
+ ],
12
+ "hr": [
13
+ 512,
14
+ 512
15
+ ],
16
+ "psnr_bicubic": 32.351,
17
+ "psnr_model": 32.632,
18
+ "ssim_bicubic": 0.8845,
19
+ "ssim_model": 0.8809,
20
+ "detail_hr": 2.1535,
21
+ "detail_bicubic": 0.1025,
22
+ "detail_model": 0.2354
23
+ },
24
+ {
25
+ "image": "0802.png",
26
+ "lr": [
27
+ 128,
28
+ 128
29
+ ],
30
+ "hr": [
31
+ 512,
32
+ 512
33
+ ],
34
+ "psnr_bicubic": 31.206,
35
+ "psnr_model": 31.042,
36
+ "ssim_bicubic": 0.8267,
37
+ "ssim_model": 0.8128,
38
+ "detail_hr": 3.0415,
39
+ "detail_bicubic": 0.0675,
40
+ "detail_model": 0.0998
41
+ },
42
+ {
43
+ "image": "0803.png",
44
+ "lr": [
45
+ 128,
46
+ 128
47
+ ],
48
+ "hr": [
49
+ 512,
50
+ 512
51
+ ],
52
+ "psnr_bicubic": 30.805,
53
+ "psnr_model": 31.34,
54
+ "ssim_bicubic": 0.8733,
55
+ "ssim_model": 0.8817,
56
+ "detail_hr": 2.3215,
57
+ "detail_bicubic": 0.1306,
58
+ "detail_model": 0.2517
59
+ },
60
+ {
61
+ "image": "0804.png",
62
+ "lr": [
63
+ 128,
64
+ 128
65
+ ],
66
+ "hr": [
67
+ 512,
68
+ 512
69
+ ],
70
+ "psnr_bicubic": 25.839,
71
+ "psnr_model": 26.072,
72
+ "ssim_bicubic": 0.7229,
73
+ "ssim_model": 0.7284,
74
+ "detail_hr": 13.3373,
75
+ "detail_bicubic": 0.199,
76
+ "detail_model": 0.4006
77
+ },
78
+ {
79
+ "image": "0805.png",
80
+ "lr": [
81
+ 128,
82
+ 128
83
+ ],
84
+ "hr": [
85
+ 512,
86
+ 512
87
+ ],
88
+ "psnr_bicubic": 27.77,
89
+ "psnr_model": 27.59,
90
+ "ssim_bicubic": 0.703,
91
+ "ssim_model": 0.6846,
92
+ "detail_hr": 8.9048,
93
+ "detail_bicubic": 0.1344,
94
+ "detail_model": 0.1757
95
+ }
96
+ ],
97
+ "average": {
98
+ "psnr_bicubic": 29.5942,
99
+ "psnr_model": 29.7352,
100
+ "ssim_bicubic": 0.8021,
101
+ "ssim_model": 0.7977,
102
+ "detail_hr": 5.9517,
103
+ "detail_bicubic": 0.1268,
104
+ "detail_model": 0.2326
105
+ }
106
+ }
examples/output_4x.png ADDED

Git LFS Details

  • SHA256: 4d3f660ad6458d145e49662258f3aac155fdc72edba6025b67cd5604ccebe99a
  • Pointer size: 132 Bytes
  • Size of remote file: 1.42 MB
examples/output_9.2x.jpg ADDED

Git LFS Details

  • SHA256: e7618d0aff2bde552248e8f1661507d8eb123cfac23e18a582289b3c66bb4110
  • Pointer size: 131 Bytes
  • Size of remote file: 254 kB
examples/verification.json CHANGED
@@ -2,53 +2,53 @@
2
  "checks": [
3
  {
4
  "input": [
5
- 128,
6
- 160
7
  ],
8
  "target": [
9
- 256,
10
- 320
11
  ],
12
  "output_shape": [
13
  1,
14
  3,
15
- 320,
16
- 256
17
  ],
18
- "max_abs_diff": 1.0132789611816406e-06
19
  },
20
  {
21
  "input": [
22
- 128,
23
- 160
24
  ],
25
  "target": [
26
- 413,
27
- 497
28
  ],
29
  "output_shape": [
30
  1,
31
  3,
32
- 497,
33
- 413
34
  ],
35
- "max_abs_diff": 1.735985279083252e-06
36
  }
37
  ],
38
- "max_abs_diff": 1.735985279083252e-06,
39
  "forward_single_shape": [
40
  1,
41
  3,
42
- 320,
43
- 256
44
  ],
45
  "forward_single_ok": true,
46
  "passed": true,
47
  "cuda_shape_check": [
48
  1,
49
  3,
50
- 320,
51
- 256
52
  ],
53
  "cuda_finite": true
54
  }
 
2
  "checks": [
3
  {
4
  "input": [
5
+ 160,
6
+ 106
7
  ],
8
  "target": [
9
+ 320,
10
+ 212
11
  ],
12
  "output_shape": [
13
  1,
14
  3,
15
+ 212,
16
+ 320
17
  ],
18
+ "max_abs_diff": 1.1920928955078125e-07
19
  },
20
  {
21
  "input": [
22
+ 160,
23
+ 106
24
  ],
25
  "target": [
26
+ 509,
27
+ 335
28
  ],
29
  "output_shape": [
30
  1,
31
  3,
32
+ 335,
33
+ 509
34
  ],
35
+ "max_abs_diff": 1.1920928955078125e-07
36
  }
37
  ],
38
+ "max_abs_diff": 1.1920928955078125e-07,
39
  "forward_single_shape": [
40
  1,
41
  3,
42
+ 212,
43
+ 320
44
  ],
45
  "forward_single_ok": true,
46
  "passed": true,
47
  "cuda_shape_check": [
48
  1,
49
  3,
50
+ 212,
51
+ 320
52
  ],
53
  "cuda_finite": true
54
  }
model.safetensors CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:d5f0b33a4448f4c936d26f05df6f2421566343b4f1abb0701582d8a200b94d4b
3
- size 5054380
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8c4781fa3375251b61aef71a6cc6c53fa3bc769f65d11e5733d4bf0d0b648c3f
3
+ size 18439020
model_scripted.pt CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:48deb75baf89d8de169be979afcf8989bb4504967af025d2a72d3e7cb54f0393
3
- size 5086206
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f20527462f30c27304a600e73f2eaa3ae0b60015312b59abbe51049ddbfce621
3
+ size 18530078