Spaces:
Sleeping
Sleeping
Commit ·
7eb78e5
1
Parent(s): 2b4ba87
added upscaler
Browse files- app/upscaler/realesrgan.py +55 -1
- app/upscaler/upscaler.py +39 -0
- init_structure.py +0 -94
- requirements.txt +5 -8
app/upscaler/realesrgan.py
CHANGED
|
@@ -1 +1,55 @@
|
|
| 1 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""NCNN RealESRGAN upscaler wrapper.
|
| 2 |
+
|
| 3 |
+
This module exposes:
|
| 4 |
+
- NCNNUpscaler: provides lightweight 2x/4x super-resolution via realesrgan-ncnn-py.
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
from __future__ import annotations
|
| 8 |
+
|
| 9 |
+
from PIL import Image
|
| 10 |
+
from realesrgan_ncnn_py import Realesrgan
|
| 11 |
+
|
| 12 |
+
from app.utils.logger import get_logger
|
| 13 |
+
|
| 14 |
+
logger = get_logger(__name__)
|
| 15 |
+
|
| 16 |
+
# Supported scales mapped to internal model indices
|
| 17 |
+
SCALE_TO_MODEL = {
|
| 18 |
+
2.0: 3, # realesrgan-x2plus
|
| 19 |
+
4.0: 0, # realesrgan-x4plus
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
class NCNNUpscaler:
|
| 24 |
+
"""Lightweight NCNN RealESRGAN engine using realesrgan-ncnn-py.
|
| 25 |
+
|
| 26 |
+
Args:
|
| 27 |
+
scale (float): Supported values = 2.0 or 4.0.
|
| 28 |
+
"""
|
| 29 |
+
|
| 30 |
+
def __init__(self, scale: float = 2.0):
|
| 31 |
+
"""Initialize the NCNN upscaler."""
|
| 32 |
+
if scale not in SCALE_TO_MODEL:
|
| 33 |
+
raise ValueError("Only 2.0x and 4.0x supported for your NCNN build")
|
| 34 |
+
|
| 35 |
+
self.scale = scale
|
| 36 |
+
self.model_index = SCALE_TO_MODEL[scale]
|
| 37 |
+
|
| 38 |
+
logger.info(
|
| 39 |
+
f"[NCNN] Loading RealESRGAN model index={self.model_index} \
|
| 40 |
+
for scale={scale}x"
|
| 41 |
+
)
|
| 42 |
+
|
| 43 |
+
self.model = Realesrgan(model=self.model_index)
|
| 44 |
+
|
| 45 |
+
def upscale(self, image: Image.Image) -> Image.Image:
|
| 46 |
+
"""Upscale a PIL image using NCNN RealESRGAN."""
|
| 47 |
+
if not isinstance(image, Image.Image):
|
| 48 |
+
raise TypeError("Input must be a PIL.Image")
|
| 49 |
+
|
| 50 |
+
logger.info(
|
| 51 |
+
f"[NCNN] Upscaling ({image.width}x{image.height}) "
|
| 52 |
+
f"by {self.scale}x using model={self.model_index}"
|
| 53 |
+
)
|
| 54 |
+
|
| 55 |
+
return self.model.process_pil(image)
|
app/upscaler/upscaler.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Unified upscaler interface.
|
| 2 |
+
|
| 3 |
+
Chooses between:
|
| 4 |
+
- NCNN RealESRGAN (fastest, works on NVIDIA/AMD/Intel)
|
| 5 |
+
- Future SD-upscaler backend
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
from __future__ import annotations
|
| 9 |
+
|
| 10 |
+
from PIL import Image
|
| 11 |
+
|
| 12 |
+
from app.upscaler.realesrgan import NCNNUpscaler
|
| 13 |
+
from app.utils.logger import get_logger
|
| 14 |
+
|
| 15 |
+
logger = get_logger(__name__)
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
class Upscaler:
|
| 19 |
+
"""Unified high-level upscaling wrapper."""
|
| 20 |
+
|
| 21 |
+
def __init__(self, scale: float = 2.0, prefer: str = "ncnn"):
|
| 22 |
+
"""Initialize the upscaler with given backend preference."""
|
| 23 |
+
logger.info(f"Upscaler initializing (prefer={prefer}, scale={scale})")
|
| 24 |
+
|
| 25 |
+
self.engine = None
|
| 26 |
+
|
| 27 |
+
if prefer in ("ncnn", "auto"):
|
| 28 |
+
try:
|
| 29 |
+
self.engine = NCNNUpscaler(scale=scale)
|
| 30 |
+
logger.info("Using NCNN RealESRGAN engine.")
|
| 31 |
+
return
|
| 32 |
+
except Exception as err:
|
| 33 |
+
logger.warning(f"NCNN RealESRGAN init failed: {err}")
|
| 34 |
+
|
| 35 |
+
raise RuntimeError("No valid upscaler engine available.")
|
| 36 |
+
|
| 37 |
+
def upscale(self, image: Image.Image) -> Image.Image:
|
| 38 |
+
"""Upscale the given image."""
|
| 39 |
+
return self.engine.upscale(image)
|
init_structure.py
DELETED
|
@@ -1,94 +0,0 @@
|
|
| 1 |
-
"""
|
| 2 |
-
Project Structure Generator for Stable Diffusion Image Generator.
|
| 3 |
-
|
| 4 |
-
Creates all required directories and placeholder files with compliant
|
| 5 |
-
docstrings. Safe for repeated runs — will not overwrite existing files.
|
| 6 |
-
"""
|
| 7 |
-
|
| 8 |
-
import os
|
| 9 |
-
|
| 10 |
-
# Placeholder docstrings
|
| 11 |
-
MODULE_PLACEHOLDER = '"""Auto-generated placeholder module for Stable Diffusion Image Generator."""\n'
|
| 12 |
-
INIT_PLACEHOLDER = '"""Package initialization file for Stable Diffusion Image Generator."""\n'
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
# Utility functions
|
| 16 |
-
def create_dir(path: str):
|
| 17 |
-
"""Create directory if it doesn't already exist."""
|
| 18 |
-
os.makedirs(path, exist_ok=True)
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
def create_file(path: str, content: str = MODULE_PLACEHOLDER):
|
| 22 |
-
"""Create a file only if it does not already exist."""
|
| 23 |
-
if not os.path.exists(path):
|
| 24 |
-
with open(path, "w") as f:
|
| 25 |
-
f.write(content)
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
def init_file(path: str):
|
| 29 |
-
"""Create an __init__.py with a placeholder docstring."""
|
| 30 |
-
if not os.path.exists(path):
|
| 31 |
-
with open(path, "w") as f:
|
| 32 |
-
f.write(INIT_PLACEHOLDER)
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
# Project Directory Structure
|
| 36 |
-
|
| 37 |
-
directories = [
|
| 38 |
-
"app",
|
| 39 |
-
"app/core",
|
| 40 |
-
"app/models",
|
| 41 |
-
"app/utils",
|
| 42 |
-
"app/presets",
|
| 43 |
-
"app/upscaler",
|
| 44 |
-
"assets",
|
| 45 |
-
"assets/samples",
|
| 46 |
-
"assets/lora",
|
| 47 |
-
]
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
# File Definitions
|
| 51 |
-
|
| 52 |
-
files = {
|
| 53 |
-
# Entry
|
| 54 |
-
"main.py": MODULE_PLACEHOLDER,
|
| 55 |
-
|
| 56 |
-
# Core pipeline + generation modules
|
| 57 |
-
"app/pipeline.py": MODULE_PLACEHOLDER,
|
| 58 |
-
"app/generator.py": MODULE_PLACEHOLDER,
|
| 59 |
-
"app/img2img.py": MODULE_PLACEHOLDER,
|
| 60 |
-
|
| 61 |
-
# UI
|
| 62 |
-
"app/ui.py": MODULE_PLACEHOLDER,
|
| 63 |
-
|
| 64 |
-
# Presets
|
| 65 |
-
"app/presets/styles.py": MODULE_PLACEHOLDER,
|
| 66 |
-
|
| 67 |
-
# Upscaler
|
| 68 |
-
"app/upscaler/realesrgan.py": MODULE_PLACEHOLDER,
|
| 69 |
-
|
| 70 |
-
# Utils
|
| 71 |
-
"app/utils/history.py": MODULE_PLACEHOLDER,
|
| 72 |
-
"app/utils/seed.py": MODULE_PLACEHOLDER,
|
| 73 |
-
"app/utils/logger.py": MODULE_PLACEHOLDER,
|
| 74 |
-
|
| 75 |
-
# Models or reference files
|
| 76 |
-
"app/models/metadata.py": MODULE_PLACEHOLDER,
|
| 77 |
-
|
| 78 |
-
# Root files
|
| 79 |
-
"requirements.txt": MODULE_PLACEHOLDER,
|
| 80 |
-
"README.md": MODULE_PLACEHOLDER,
|
| 81 |
-
"LICENSE": MODULE_PLACEHOLDER,
|
| 82 |
-
}
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
# Build the structure
|
| 86 |
-
|
| 87 |
-
for d in directories:
|
| 88 |
-
create_dir(d)
|
| 89 |
-
init_file(os.path.join(d, "__init__.py"))
|
| 90 |
-
|
| 91 |
-
for path, content in files.items():
|
| 92 |
-
create_file(path, content)
|
| 93 |
-
|
| 94 |
-
print("Stable Diffusion Image Generator project structure created successfully!")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
requirements.txt
CHANGED
|
@@ -8,9 +8,9 @@ torchaudio==2.5.1
|
|
| 8 |
|
| 9 |
|
| 10 |
# HUGGINGFACE DIFFUSION ECOSYSTEM
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
accelerate==0.28.0
|
| 15 |
safetensors==0.4.2
|
| 16 |
|
|
@@ -29,13 +29,10 @@ python-dotenv==1.0.1
|
|
| 29 |
|
| 30 |
|
| 31 |
# UPSCALING / SUPER-RESOLUTION
|
| 32 |
-
realesrgan==0.
|
| 33 |
-
basicsr==1.4.2
|
| 34 |
-
facexlib==0.3.0
|
| 35 |
-
gfpgan==1.3.8
|
| 36 |
|
| 37 |
|
| 38 |
-
#
|
| 39 |
black==24.3.0
|
| 40 |
ruff==0.3.5
|
| 41 |
pre-commit==3.7.0
|
|
|
|
| 8 |
|
| 9 |
|
| 10 |
# HUGGINGFACE DIFFUSION ECOSYSTEM
|
| 11 |
+
diffusers==0.29.2
|
| 12 |
+
transformers==4.39.3
|
| 13 |
+
huggingface_hub==0.29.1
|
| 14 |
accelerate==0.28.0
|
| 15 |
safetensors==0.4.2
|
| 16 |
|
|
|
|
| 29 |
|
| 30 |
|
| 31 |
# UPSCALING / SUPER-RESOLUTION
|
| 32 |
+
realesrgan-ncnn-py==2.0.0
|
|
|
|
|
|
|
|
|
|
| 33 |
|
| 34 |
|
| 35 |
+
# DEVELOPMENT TOOLS
|
| 36 |
black==24.3.0
|
| 37 |
ruff==0.3.5
|
| 38 |
pre-commit==3.7.0
|