Spaces:
Sleeping
Sleeping
Download server.py from nanye/diffusion_models: direct link, hf CLI and curl.
- Browser
- Download file 5.44 kB
-
https://huggingface.co/spaces/nanye/diffusion_models/resolve/main/server.py
- Command line
-
hf download hf://spaces/nanye/diffusion_models/server.py
-
curl -L -o server.py https://huggingface.co/spaces/nanye/diffusion_models/resolve/main/server.py
5.44 kB
| import base64 | |
| import binascii | |
| import json | |
| import mimetypes | |
| import secrets | |
| from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer | |
| from io import BytesIO | |
| from pathlib import Path | |
| from urllib.parse import urlparse | |
| from generate import CHECKPOINTS, MODEL_ID, MODEL_SIZES, generate_images, is_model_loaded, load_model | |
| ROOT = Path(__file__).resolve().parent | |
| def encode_frame(image): | |
| buffer = BytesIO() | |
| image.save(buffer, format="JPEG", quality=86) | |
| return base64.b64encode(buffer.getvalue()).decode("ascii") | |
| def generate_frames(seed, checkpoints=CHECKPOINTS, initial_image=None, model_id=MODEL_ID): | |
| yield {"type": "status", "status": "loading", "model": model_id} | |
| try: | |
| for step, image in generate_images(seed, checkpoints=checkpoints, initial_image=initial_image, model_id=model_id): | |
| yield {"type": "progress", "step": step, "total": 1000} | |
| if image is not None: | |
| yield {"type": "frame", "step": step, "image": encode_frame(image)} | |
| _, _, device = load_model(model_id=model_id) | |
| yield {"type": "complete", "seed": seed, "device": device, "model": model_id} | |
| except Exception as error: | |
| yield {"type": "error", "message": str(error)} | |
| class DiffusionHandler(BaseHTTPRequestHandler): | |
| def send_bytes(self, status, content_type, body): | |
| self.send_response(status) | |
| self.send_header("Content-Type", content_type) | |
| self.send_header("Content-Length", str(len(body))) | |
| self.send_header("Cache-Control", "no-store") | |
| self.end_headers() | |
| self.wfile.write(body) | |
| def do_GET(self): | |
| path = urlparse(self.path).path | |
| if path == "/api/health": | |
| body = json.dumps({"model": MODEL_ID, "models": list(MODEL_SIZES), "loaded": is_model_loaded()}).encode() | |
| self.send_bytes(200, "application/json", body) | |
| return | |
| relative_path = "index.html" if path == "/" else path.lstrip("/") | |
| if relative_path not in { | |
| "index.html", | |
| "app.js", | |
| "styles.css", | |
| "assets/celeba_hq_validation_91_256.png", | |
| "assets/cifar10_train_23_32.png", | |
| }: | |
| self.send_error(404) | |
| return | |
| file_path = ROOT / relative_path | |
| content_type = mimetypes.guess_type(file_path.name)[0] or "application/octet-stream" | |
| self.send_bytes(200, content_type, file_path.read_bytes()) | |
| def do_POST(self): | |
| if urlparse(self.path).path != "/api/generate": | |
| self.send_error(404) | |
| return | |
| try: | |
| length = int(self.headers.get("Content-Length", "0")) | |
| request = json.loads(self.rfile.read(length) or b"{}") | |
| model_id = request.get("model", MODEL_ID) | |
| if not isinstance(model_id, str) or model_id not in MODEL_SIZES: | |
| raise ValueError("Unsupported model.") | |
| seed = int(request.get("seed", secrets.randbelow(2**31))) | |
| if seed < 0 or seed >= 2**63: | |
| raise ValueError("Seed must be between 0 and 2^63 - 1.") | |
| checkpoints = request.get("checkpoints", CHECKPOINTS) | |
| if ( | |
| not isinstance(checkpoints, list) | |
| or not 2 <= len(checkpoints) <= 12 | |
| or any(type(step) is not int or step < 0 or step > 1000 for step in checkpoints) | |
| ): | |
| raise ValueError("Checkpoints must be a list of 2 to 12 integers from 0 to 1000.") | |
| checkpoints = tuple(sorted(set(checkpoints))) | |
| if checkpoints[0] != 0 or checkpoints[-1] != 1000: | |
| raise ValueError("Checkpoints must include 0 and 1000.") | |
| initial_image = None | |
| encoded_image = request.get("initial_image") | |
| if encoded_image is not None: | |
| if not isinstance(encoded_image, str) or len(encoded_image) > 3_000_000: | |
| raise ValueError("The forward-noise image is invalid or too large.") | |
| from PIL import Image | |
| encoded_image = encoded_image.partition(",")[2] | |
| initial_image = Image.open(BytesIO(base64.b64decode(encoded_image, validate=True))) | |
| initial_image.load() | |
| except (ValueError, TypeError, json.JSONDecodeError, binascii.Error, OSError) as error: | |
| self.send_bytes(400, "application/json", json.dumps({"error": str(error)}).encode()) | |
| return | |
| self.send_response(200) | |
| self.send_header("Content-Type", "application/x-ndjson; charset=utf-8") | |
| self.send_header("Cache-Control", "no-store") | |
| self.send_header("X-Accel-Buffering", "no") | |
| self.end_headers() | |
| try: | |
| for event in generate_frames(seed, checkpoints, initial_image, model_id): | |
| self.wfile.write((json.dumps(event) + "\n").encode()) | |
| self.wfile.flush() | |
| except (BrokenPipeError, ConnectionResetError): | |
| pass | |
| def log_message(self, format_string, *args): | |
| print(f"{self.address_string()} - {format_string % args}") | |
| class DiffusionServer(ThreadingHTTPServer): | |
| daemon_threads = True | |
| if __name__ == "__main__": | |
| server = DiffusionServer(("0.0.0.0", 8000), DiffusionHandler) | |
| print(f"Diffusion Lab: http://{server.server_address[0]}:{server.server_address[1]}") | |
| print(f"Model: {MODEL_ID} (loaded on first generation request)") | |
| server.serve_forever() | |