codinglabsong's picture
Update app.py
8e719f5 verified
Raw
History Blame Contribute Delete
2.03 kB
import os
import gradio as gr
import numpy as np
import torch
from diffusers import DDPMScheduler
from PIL import Image
from config import (
cfg,
device,
ema_unet_model_path,
vae_model_path,
)
from models import unet, vae
from utils import revert_images
def load_models() -> None:
"""Load pre-trained model weights."""
if not (os.path.exists(ema_unet_model_path) and os.path.exists(vae_model_path)):
msg = "Model weights not found. Train the models before running the app."
raise RuntimeError(msg)
vae.load_state_dict(torch.load(vae_model_path, map_location=device))
unet.load_state_dict(torch.load(ema_unet_model_path, map_location=device))
vae.eval()
unet.eval()
@torch.no_grad()
def generate_digit(digit: int) -> Image.Image:
"""Generate a single digit conditioned on user's requested digit class."""
noise_scheduler = DDPMScheduler(num_train_timesteps=cfg.denoising_timesteps)
latents = torch.randn((1, cfg.latent_channels, 8, 8)).to(device)
label = torch.tensor([digit]).to(device)
for t in noise_scheduler.timesteps:
noise_pred = unet(
latents, t, class_labels=label, encoder_hidden_states=None
).sample
latents = noise_scheduler.step(noise_pred, t, latents).prev_sample
recon = vae.decode(latents).sample
img_np = revert_images(recon)[0].astype(np.uint8)
img = Image.fromarray(img_np, mode="L")
return img.resize((512, 512), resample=Image.NEAREST)
def infer(digit: str) -> Image.Image:
return generate_digit(int(digit))
def build_demo() -> gr.Interface:
dropdown = gr.Dropdown(
choices=[str(i) for i in range(10)], value="0", label="Choose Digit to Generate"
)
output = gr.Image(type="pil", height=512, width=512)
return gr.Interface(
fn=infer,
inputs=dropdown,
outputs=output,
title="Digit Generator with Latent Diffuser Model",
)
if __name__ == "__main__":
load_models()
demo = build_demo()
demo.launch()