| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import gradio as gr |
| import spaces |
| import torch |
| import os |
| from PIL import Image |
| from diffusers.utils import load_image |
|
|
| |
| from dreamlite import DreamLitePipeline |
| from dreamlite import DreamLiteMobilePipeline |
|
|
| from huggingface_hub import snapshot_download |
|
|
| from transformers import CLIPFeatureExtractor |
| from diffusers.pipelines.stable_diffusion import StableDiffusionSafetyChecker |
| import numpy as np |
|
|
|
|
| |
| |
| |
| HF_TOKEN = os.environ.get("HF_TOKEN") |
| device = "cpu" |
| dtype = torch.bfloat16 |
|
|
| |
| safety_checker = StableDiffusionSafetyChecker.from_pretrained( |
| "CompVis/stable-diffusion-safety-checker" |
| ) |
| feature_extractor = CLIPFeatureExtractor.from_pretrained( |
| "openai/clip-vit-base-patch32" |
| ) |
|
|
| def check_safety(image): |
| """检查生成的图像是否安全,返回 (image, is_nsfw)""" |
| safety_input = feature_extractor(images=image, return_tensors="pt") |
| np_image = np.array(image) |
| _, has_nsfw = safety_checker( |
| images=[np_image], |
| clip_input=safety_input.pixel_values |
| ) |
| return has_nsfw[0] |
|
|
| base_path = snapshot_download("carlofkl/DreamLite-base", token=HF_TOKEN) |
| mobile_path = snapshot_download("carlofkl/DreamLite-mobile", token=HF_TOKEN) |
|
|
| |
| print("Loading DreamLite-base...") |
| pipe_base = DreamLitePipeline.from_pretrained(base_path, torch_dtype=dtype).to(device) |
| print("DreamLite-base Loaded Successfully!") |
|
|
| print("Loading DreamLite-mobile...") |
| pipe_mobile = DreamLiteMobilePipeline.from_pretrained(mobile_path, torch_dtype=dtype).to(device) |
| print("DreamLite-mobile Loaded Successfully!") |
|
|
| MODEL_CONFIGS = { |
| "DreamLite-base": pipe_base, |
| "DreamLite-mobile": pipe_mobile, |
| } |
|
|
| BASE_RESOLUTIONS = [ |
| "1024 × 1024 (1:1)", |
| "1152 × 896 (9:7)", |
| "896 × 1152 (7:9)", |
| "1216 × 832 (3:2)", |
| "832 × 1216 (2:3)", |
| "1344 × 768 (16:9)", |
| "768 × 1344 (9:16)", |
| ] |
|
|
| def parse_resolution(res_str): |
| """从分辨率字符串中解析宽高,例如 '1024 × 1024 (1:1)' -> (1024, 1024)""" |
| parts = res_str.split("(")[0].strip().split("×") |
| w = int(parts[0].strip()) |
| h = int(parts[1].strip()) |
| return w, h |
|
|
| |
| |
| |
| @spaces.GPU |
| def generate_image( |
| model_choice, |
| prompt, |
| image, |
| resolution, |
| num_inference_steps, |
| guidance_scale, |
| image_guidance_scale, |
| seed |
| ): |
| |
| pipe = MODEL_CONFIGS[model_choice] |
|
|
| |
| generator = torch.Generator(device="cpu").manual_seed(seed) |
| |
| |
| input_image = image if image is not None else None |
|
|
| if model_choice == "DreamLite-base": |
| width, height = parse_resolution(resolution) |
| else: |
| |
| width, height = parse_resolution(resolution) |
| |
| if image is not None: width, height = image.size |
| |
| |
| out = pipe( |
| prompt=prompt, |
| image=input_image, |
| width=width, |
| height=height, |
| guidance_scale=guidance_scale, |
| image_guidance_scale=image_guidance_scale, |
| num_inference_steps=num_inference_steps, |
| generator=generator, |
| ).images[0] |
|
|
| if out.size != (width, height): |
| out = out.resize((width, height), resample=Image.LANCZOS) |
|
|
| |
| if check_safety(out): |
| raise gr.Error("⚠️ The generated image has been blocked by our safety filter. " |
| "Please try a different prompt.") |
| |
| return out |
|
|
| |
| |
| |
| def on_model_change(model_choice): |
| """ |
| 切换模型时自动调整 UI 组件: |
| - Base: 显示分辨率选择,默认 28 步 |
| - Mobile: 隐藏分辨率选择(固定 1024×1024),默认 4 步 |
| """ |
| if model_choice == "DreamLite-base": |
| return ( |
| gr.update(visible=True, value="1024 × 1024 (1:1)"), |
| gr.update(value=28), |
| gr.update(value=3.5), |
| ) |
| else: |
| return ( |
| gr.update(visible=True, value="1024 × 1024 (1:1)"), |
| gr.update(value=4), |
| gr.update(value=1.0), |
| ) |
|
|
| |
| |
| |
| with gr.Blocks(title="DreamLite Demo") as demo: |
| gr.Markdown("# 🌟 DreamLite: Efficient On-Device Generation and Editing") |
| gr.Markdown("Select a model version, then generate images from text or upload an image to edit it based on instructions.") |
| |
| with gr.Row(): |
| with gr.Column(): |
| |
| model_dropdown = gr.Dropdown( |
| choices=list(MODEL_CONFIGS.keys()), |
| value="DreamLite-base", |
| label="Select Model Version", |
| interactive=True |
| ) |
| |
| |
| prompt_input = gr.Textbox(label="Prompt / Instruction", placeholder="e.g. A photo of a dog...", lines=3) |
| image_input = gr.Image(type="pil", label="Input Image (Optional for Editing)") |
|
|
| |
| resolution_dropdown = gr.Dropdown( |
| choices=BASE_RESOLUTIONS, |
| value="1024 × 1024 (1:1)", |
| label="Resolution (Base model only, Mobile fixed at 1024×1024)", |
| interactive=True, |
| visible=True |
| ) |
| |
| with gr.Accordion("Advanced Options", open=False): |
| steps_slider = gr.Slider(minimum=1, maximum=50, value=28, step=1, label="Inference Steps") |
| guidance_slider = gr.Slider(minimum=0.0, maximum=20.0, value=3.5, step=0.1, label="Guidance Scale") |
| img_guidance_slider = gr.Slider(minimum=0.0, maximum=5.0, value=1.0, step=0.1, label="Image Guidance Scale") |
| seed_slider = gr.Slider(minimum=0, maximum=999999, value=42, step=1, label="Seed") |
| |
| submit_btn = gr.Button("Generate / Edit", variant="primary") |
| |
| with gr.Column(): |
| |
| output_image = gr.Image(type="pil", label="Output Image") |
| |
| |
| model_dropdown.change( |
| fn=on_model_change, |
| inputs=[model_dropdown], |
| outputs=[resolution_dropdown, steps_slider, guidance_slider] |
| ) |
|
|
| |
| submit_btn.click( |
| fn=generate_image, |
| inputs=[model_dropdown, prompt_input, image_input, resolution_dropdown, steps_slider, guidance_slider, img_guidance_slider, seed_slider], |
| outputs=[output_image] |
| ) |
| |
| |
| gr.Examples( |
| examples=[ |
| ["DreamLite-base", "A close-up of a fire spitting dragon, cinematic shot.", None, "1216 × 832 (3:2)", 28, 3.5, 1.0, 123], |
| ["DreamLite-mobile", "A portrait of a young woman with flowers.", None, "1024 × 1024 (1:1)", 4, 3.5, 1.0, 42], |
| ["DreamLite-mobile", "Make it look like a pencil sketch", "assets/example.png", "1024 × 1024 (1:1)", 4, 1.0, 1.0, 42], |
| ], |
| inputs=[model_dropdown, prompt_input, image_input, resolution_dropdown, steps_slider, guidance_slider, img_guidance_slider, seed_slider] |
| ) |
|
|
| |
| |
| |
| if __name__ == "__main__": |
| demo.launch(server_name="0.0.0.0", server_port=7860) |