pixelforge-upscale / README.md
revirevyrevy's picture
Deploy PixelForge SUPIR generative upscale engine
93ef7ce verified
|
Raw
History Blame Contribute Delete
6.45 kB
---
title: PixelForge AI Generative Upscale
emoji:
colorFrom: indigo
colorTo: purple
sdk: gradio
sdk_version: 6.25.0
app_file: app.py
pinned: false
---
# PixelForge AI — generative upscale engine
This Space exposes the PixelForge AI SUPIR generative upscaling API.
See the included project README below for the API contract and runtime details.
# PixelForge AI — generative upscale engine (Hugging Face Space)
This is the **generative** upscale engine behind PixelForge AI. It accepts a
low-resolution image and returns a high-resolution version in which the model
**invents plausible new detail** (texture, grain, fine structure) via
diffusion — it is *not* an ESRGAN-style sharpener.
Two engines ship in one app:
| Engine | Model | What it is | Hardware |
|-------------|-------|------------|----------|
| `supir` (default) | [SUPIR](https://huggingface.co/papers/2404.03502) (SDXL-based generative restoration), pruned fp16 weights from [`Kijai/SUPIR_pruned`](https://huggingface.co/Kijai/SUPIR_pruned) | The quality leader. Generative detail invention + restoration. | ~16–24 GB VRAM — fits ZeroGPU |
| `sdxl_tile` | [SDXL](https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0) + [ControlNet-Tile](https://huggingface.co/xinsir/controlnet-tile-sdxl-1.0) img2img upscale | Lighter generative fallback for small-GPU hardware (e.g. a 16 GB T4). | ~12–16 GB VRAM |
The SUPIR codebase (the official `SUPIR/` + `sgm/` packages) is cloned at
first use from a verified Hugging Face mirror — the original GitHub repo
(`github.com/ciat-org/SUPIR`) is currently offline. Override the mirror with
the `SUPIR_REPO_URL` env var if it ever changes.
---
## API
### `POST /upscale`
Send **raw image bytes** (`Content-Type: image/png|jpeg|…` or
`application/octet-stream`) **or multipart** with a file part named `image`.
Query params: `scale` = `2` or `4` (default `4`).
Returns: `image/png` bytes + header `X-Upscale-Engine`.
```bash
# raw bytes
curl -X POST "https://<owner>-<space>.hf.space/upscale?scale=4" \
-H "Content-Type: image/png" \
-H "Authorization: Bearer $SPACE_ACCESS_TOKEN" \
--data-binary @input.png -o output.png
# multipart
curl -X POST "https://<owner>-<space>.hf.space/upscale?scale=4" \
-H "Authorization: Bearer $SPACE_ACCESS_TOKEN" \
-F "image=@input.png" -o output.png
```
### `GET /health`
`{"status":"ok","engine":"supir","gpu":true}` — engine and GPU availability,
no secrets.
---
## Deploy to Hugging Face Spaces (ZeroGPU, free)
1. **Account** — a free personal HF account in good standing (verified email,
older than ~30 days) can host up to 2 ZeroGPU Spaces for free. PRO accounts
get more quota and priority queues.
2. **Create the Space** — [huggingface.co/new-space](https://huggingface.co/new-space):
- Name: e.g. `pixelforge-upscale`
- License: any (MIT suggested)
- SDK: **Docker** (this repo's `Dockerfile`)
- Hardware: **ZeroGPU** (Nvidia RTX Pro 6000 Blackwell, free — the row
labeled "ZeroGPU"; do **not** pick a paid T4/L4 row)
- Visibility: private while testing (see token note below)
3. **Push the files** — upload `app.py`, `engines/`, `requirements.txt`,
`Dockerfile`, `README.md` (web UI "Files" tab, or `git clone
https://huggingface.co/spaces/<owner>/<space>` and push). The build takes
several minutes: it installs torch + diffusers (~4 GB image).
4. **Env vars** (Settings → Variables and secrets):
- `UPSCALE_ENGINE` — `supir` (default) or `sdxl_tile`.
- `SPACE_ACCESS_TOKEN` — optional gate. If set, every `/upscale` request
must send `Authorization: Bearer <this value>`. **Recommended:** set it
to a token value you control and put the same value in the site's
`HF_TOKEN` env var.
- Optional tuning: `SUPIR_STEPS`, `SUPIR_CFG`, `SDXL_TILE_STRENGTH`,
`SUPIR_REPO_URL`, `PRELOAD=1` (download weights at boot instead of on
first request).
5. **First request** — the first `/upscale` call downloads the weights
(~9.5 GB for SUPIR: SDXL base 6.9 GB + SUPIR-v0Q fp16 2.6 GB) and loads the
model, so it can take several minutes and may appear to hang. Subsequent
calls are fast while the Space is warm. Cold starts after idle are normal
on ZeroGPU (the free tier sleeps idle Spaces).
6. **Wire up the site** — set on the site server:
- `HF_SPACE_URL=https://<owner>-<space>.hf.space`
- `HF_TOKEN=<the SPACE_ACCESS_TOKEN value>`
Then `GET /api/upscale/status` on the site reports the engine configured,
and `POST /api/upscale` routes through this Space (falling back to
Replicate if configured and this fails).
> **Quota reality (verified from HF docs):** ZeroGPU is free but *queued and
> quota-limited* (free accounts: limited daily GPU-seconds; PRO: 8x more).
> That is exactly why the site treats it as the free-first provider with a
> paid Replicate fallback.
### Troubleshooting
- Space fails to build → check the build log; common causes: HF build timeout
on cold pip cache, or picking a paid hardware row by mistake.
- `/upscale` returns 401 → `SPACE_ACCESS_TOKEN` set on the Space but the
request's `Authorization` header doesn't match (check the site's `HF_TOKEN`).
- First call times out in the site → the Space is cold-starting; the site's
`hfSpace` provider retries on 503 and the queue. Keep the site
`HF_SPACE_TIMEOUT_MS` at its default (180 s) or raise it.
- Out of VRAM on 16 GB cards → use `UPSCALE_ENGINE=sdxl_tile`, or keep
`SUPIR_TILE_VAE=1` (default) and lower `SUPIR_MIN_SIZE` to `512`.
---
## What was verified here vs. what needs an HF account
**Verified in this sandbox (no GPU, ~4 GB RAM):**
- The SUPIR inference API against the real codebase (`create_SUPIR_model`,
`PIL2Tensor`/`Tensor2PIL`, `batchify_sample` signatures, `options/SUPIR_v0.yaml`
structure) and the Kijai pruned checkpoint file names.
- `xinsir/controlnet-tile-sdxl-1.0` and `stabilityai/stable-diffusion-xl-base-1.0`
exist and are public; the diffusers ControlNet img2img recipe is the
standard documented one.
- Python syntax of every module (`python -m py_compile`).
**NOT verified (needs a GPU / HF account):**
- Actual GPU inference of either engine (this box has no GPU and 4 GB RAM).
- ZeroGPU `spaces.allocate_gpu()` attach behavior (code falls back to a plain
GPU context if the `spaces` package is absent).
- First-request weight download timings and the exact VRAM footprint.