Spaces:
Menyu
/
Running on Zero

QwenImage / app.py
Menyu's picture
Update app.py
8849bc0 verified
import random
import gradio as gr
import numpy as np
import spaces
import torch
import re
from diffusers import DiffusionPipeline
from PIL import Image, PngImagePlugin
import json
import io
# Add metadata to the image
def add_metadata_to_image(image, metadata):
metadata_str = json.dumps(metadata)
# Convert PIL Image to PNG with metadata
img_with_metadata = image.copy()
# Create a PngInfo object and add metadata
png_info = PngImagePlugin.PngInfo()
png_info.add_text("parameters", metadata_str)
# Save to a byte buffer with metadata
buffer = io.BytesIO()
img_with_metadata.save(buffer, format="PNG", pnginfo=png_info)
# Reopen from buffer to get the image with metadata
buffer.seek(0)
return Image.open(buffer)
def add_comma_after_pattern_ti(text):
pattern = re.compile(r'\b\w+_\d+\b')
modified_text = pattern.sub(lambda x: x.group() + ',', text)
return modified_text
def process_prompt(prompt):
"""简单的提示词处理函数"""
return add_comma_after_pattern_ti(prompt)
DESCRIPTION = "梦羽的模型生成器 - 快速生成 Qwen-image 模型的图片"
if not torch.cuda.is_available():
DESCRIPTION += "\n<p>你现在运行在CPU上 但是此项目只支持GPU.</p>"
MAX_SEED = np.iinfo(np.int32).max
MAX_IMAGE_SIZE = 2048
if torch.cuda.is_available():
dtype = torch.bfloat16
device = "cuda"
pipe = DiffusionPipeline.from_pretrained("Qwen/Qwen-Image", torch_dtype=dtype).to(device)
def randomize_seed_fn(seed: int, randomize_seed: bool) -> int:
if randomize_seed:
seed = random.randint(0, MAX_SEED)
return seed
@spaces.GPU
def infer(
prompt: str,
negative_prompt: str = "lowres, {bad}, error, fewer, extra, missing, worst quality, jpeg artifacts, bad quality, watermark, unfinished, displeasing, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]",
use_negative_prompt: bool = True,
seed: int = 7,
width: int = 1024,
height: int = 1536,
guidance_scale: float = 4.0,
num_inference_steps: int = 50,
randomize_seed: bool = True,
):
seed = int(randomize_seed_fn(seed, randomize_seed))
generator = torch.Generator(device=device).manual_seed(seed)
if not use_negative_prompt:
negative_prompt = ""
original_prompt = prompt # Store original prompt for metadata
# 处理提示词
prompt = process_prompt(prompt)
# 为 Qwen-Image 添加质量提升词条
positive_magic_en = "Ultra HD, 4K, cinematic composition."
positive_magic_zh = "超清,4K,电影级构图"
# 简单判断是否包含中文字符
if any('\u4e00' <= char <= '\u9fff' for char in prompt):
prompt = prompt + " " + positive_magic_zh
else:
prompt = prompt + " " + positive_magic_en
# 使用 Qwen-Image 的参数格式
image = pipe(
prompt=prompt,
negative_prompt=negative_prompt,
width=width,
height=height,
true_cfg_scale=guidance_scale,
num_inference_steps=num_inference_steps,
generator=generator,
).images[0]
# Create metadata dictionary
metadata = {
"prompt": original_prompt,
"processed_prompt": prompt,
"negative_prompt": negative_prompt,
"seed": seed,
"width": width,
"height": height,
"true_cfg_scale": guidance_scale,
"num_inference_steps": num_inference_steps,
"model": "qwen-image",
"PreUrl": "https://huggingface.co/spaces/Menyu/QwenImage"
}
# Add metadata to the image
image_with_metadata = add_metadata_to_image(image, metadata)
return image_with_metadata, seed
examples = [
"nahida (genshin impact)",
"klee (genshin impact)",
]
css = '''
.gradio-container {
max-width: 560px !important;
margin-left: auto !important;
margin-right: auto !important;
}
h1{text-align:center}
'''
with gr.Blocks(css=css) as demo:
gr.Markdown("""# 梦羽的模型生成器
### 快速生成 qwen-image 模型的图片""")
with gr.Group():
with gr.Row():
prompt = gr.Text(
label="关键词",
show_label=True,
max_lines=5,
placeholder="输入你要的图片关键词",
container=False,
)
run_button = gr.Button("生成", scale=0, variant="primary")
result = gr.Image(label="Result", show_label=False, format="png")
with gr.Accordion("高级选项", open=False):
with gr.Row():
use_negative_prompt = gr.Checkbox(label="使用反向词条", value=True)
negative_prompt = gr.Text(
label="反向词条",
max_lines=5,
lines=4,
placeholder="输入你要排除的图片关键词",
value="lowres, {bad}, error, fewer, extra, missing, worst quality, jpeg artifacts, bad quality, watermark, unfinished, displeasing, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]",
visible=True,
)
seed = gr.Slider(
label="种子",
minimum=0,
maximum=MAX_SEED,
step=1,
value=0,
)
randomize_seed = gr.Checkbox(label="随机种子", value=True)
with gr.Row(visible=True):
width = gr.Slider(
label="宽度",
minimum=512,
maximum=MAX_IMAGE_SIZE,
step=64,
value=832,
)
height = gr.Slider(
label="高度",
minimum=512,
maximum=MAX_IMAGE_SIZE,
step=64,
value=1216,
)
with gr.Row():
guidance_scale = gr.Slider(
label="True CFG Scale",
minimum=1.0,
maximum=10.0,
step=0.1,
value=4.0,
)
num_inference_steps = gr.Slider(
label="生成步数",
minimum=1,
maximum=100,
step=1,
value=50,
)
gr.Examples(
examples=examples,
inputs=prompt,
outputs=[result, seed],
fn=infer
)
use_negative_prompt.change(
fn=lambda x: gr.update(visible=x),
inputs=use_negative_prompt,
outputs=negative_prompt,
)
gr.on(
triggers=[prompt.submit, run_button.click],
fn=infer,
inputs=[
prompt,
negative_prompt,
use_negative_prompt,
seed,
width,
height,
guidance_scale,
num_inference_steps,
randomize_seed,
],
outputs=[result, seed],
)
if __name__ == "__main__":
demo.launch(share=True)