yash184 commited on
Commit
cc2a180
·
verified ·
1 Parent(s): 016e45e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +203 -45
app.py CHANGED
@@ -1,46 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
 
2
- from fastapi import FastAPI
3
- from fastapi.responses import HTMLResponse
4
- from pydantic import BaseModel
5
- import json, requests
6
- app=FastAPI()
7
- CFG="config.json"
8
- class Config(BaseModel):
9
- base_url:str
10
- api_key:str
11
- model:str
12
- class Prompt(BaseModel):
13
- prompt:str
14
- def load():
15
- try:
16
- return json.load(open(CFG))
17
- except:
18
- return {"base_url":"https://openrouter.ai/api/v1","api_key":"","model":"google/gemma-3-27b-it"}
19
- HTML="""<!doctype html><html><body><h2>Simple AI Backend</h2>
20
- Base URL<br><input id=b size=70><br><br>
21
- API Key<br><input id=k size=70><br><br>
22
- Model<br><input id=m size=70><br><br>
23
- <button onclick='saveCfg()'>Save</button><hr>
24
- <textarea id=p rows=10 cols=100></textarea><br>
25
- <button onclick='gen()'>Generate</button><pre id=o></pre>
26
- <script>
27
- fetch('/config').then(r=>r.json()).then(c=>{b.value=c.base_url||'';k.value=c.api_key||'';m.value=c.model||'';});
28
- async function saveCfg(){await fetch('/save',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({base_url:b.value,api_key:k.value,model:m.value})});alert('Saved');}
29
- async function gen(){o.innerText='Generating...';let r=await fetch('/generate',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({prompt:p.value})});let j=await r.json();o.innerText=j.text||JSON.stringify(j);}
30
- </script></body></html>"""
31
- @app.get("/")
32
- def home(): return HTMLResponse(HTML)
33
- @app.get("/config")
34
- def config(): return load()
35
- @app.post("/save")
36
- def save(cfg:Config):
37
- json.dump(cfg.model_dump(),open(CFG,"w"),indent=2)
38
- return {"success":True}
39
- @app.post("/generate")
40
- def generate(data:Prompt):
41
- c=load()
42
- r=requests.post(c["base_url"].rstrip("/")+"/chat/completions",
43
- headers={"Authorization":"Bearer "+c["api_key"],"Content-Type":"application/json"},
44
- json={"model":c["model"],"messages":[{"role":"user","content":data.prompt}]},timeout=300)
45
- r.raise_for_status()
46
- return {"text":r.json()["choices"][0]["message"]["content"]}
 
1
+ import gradio as gr
2
+ import numpy as np
3
+ import random
4
+
5
+ # import spaces #[uncomment to use ZeroGPU]
6
+ from diffusers import DiffusionPipeline, AutoPipelineForImage2Image
7
+ import torch
8
+
9
+ device = "cuda" if torch.cuda.is_available() else "cpu"
10
+ model_repo_id = "stabilityai/sdxl-turbo" # Replace to the model you would like to use
11
+
12
+ if torch.cuda.is_available():
13
+ torch_dtype = torch.float16
14
+ else:
15
+ torch_dtype = torch.float32
16
+
17
+ # Text-to-image pipeline (same as original)
18
+ pipe = DiffusionPipeline.from_pretrained(model_repo_id, torch_dtype=torch_dtype)
19
+ pipe = pipe.to(device)
20
+
21
+ # Image-to-image pipeline — built from `pipe` via from_pipe(), so it reuses the
22
+ # same unet/vae/text-encoders already in memory. No second checkpoint load,
23
+ # no extra VRAM usage.
24
+ pipe_img2img = AutoPipelineForImage2Image.from_pipe(pipe)
25
+
26
+ MAX_SEED = np.iinfo(np.int32).max
27
+ MAX_IMAGE_SIZE = 1024
28
+
29
+
30
+ # @spaces.GPU #[uncomment to use ZeroGPU]
31
+ def infer(
32
+ prompt,
33
+ init_image,
34
+ negative_prompt,
35
+ seed,
36
+ randomize_seed,
37
+ width,
38
+ height,
39
+ guidance_scale,
40
+ num_inference_steps,
41
+ strength,
42
+ progress=gr.Progress(track_tqdm=True),
43
+ ):
44
+ if randomize_seed:
45
+ seed = random.randint(0, MAX_SEED)
46
+
47
+ generator = torch.Generator().manual_seed(seed)
48
+
49
+ if init_image is not None:
50
+ # HYBRID MODE: prompt + reference image -> image-to-image
51
+ init_image = init_image.convert("RGB").resize((width, height))
52
+
53
+ # SDXL Turbo requirement: num_inference_steps * strength must be >= 1,
54
+ # otherwise the pipeline errors out. Auto-bump steps if needed instead
55
+ # of crashing.
56
+ steps = num_inference_steps
57
+ if steps * strength < 1:
58
+ steps = max(1, int(np.ceil(1 / max(strength, 1e-3))))
59
+ gr.Warning(
60
+ f"Steps bumped to {steps} so that steps × strength ≥ 1 (SDXL Turbo requirement)."
61
+ )
62
+
63
+ image = pipe_img2img(
64
+ prompt=prompt,
65
+ negative_prompt=negative_prompt,
66
+ image=init_image,
67
+ strength=strength,
68
+ guidance_scale=guidance_scale,
69
+ num_inference_steps=steps,
70
+ generator=generator,
71
+ ).images[0]
72
+ else:
73
+ # ORIGINAL MODE: prompt only -> text-to-image
74
+ image = pipe(
75
+ prompt=prompt,
76
+ negative_prompt=negative_prompt,
77
+ guidance_scale=guidance_scale,
78
+ num_inference_steps=num_inference_steps,
79
+ width=width,
80
+ height=height,
81
+ generator=generator,
82
+ ).images[0]
83
+
84
+ return image, seed
85
+
86
+
87
+ examples = [
88
+ "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k",
89
+ "An astronaut riding a green horse",
90
+ "A delicious ceviche cheesecake slice",
91
+ ]
92
+
93
+ css = """
94
+ #col-container {
95
+ margin: 0 auto;
96
+ max-width: 640px;
97
+ }
98
+ """
99
+
100
+ with gr.Blocks(css=css) as demo:
101
+ with gr.Column(elem_id="col-container"):
102
+ gr.Markdown(" # Text-to-Image + Image-to-Image (Hybrid)")
103
+ gr.Markdown(
104
+ "Upload a reference image below to guide generation with it (image-to-image). "
105
+ "Leave it empty to generate from the prompt alone (text-to-image)."
106
+ )
107
+
108
+ with gr.Row():
109
+ prompt = gr.Text(
110
+ label="Prompt",
111
+ show_label=False,
112
+ max_lines=1,
113
+ placeholder="Enter your prompt",
114
+ container=False,
115
+ )
116
+
117
+ run_button = gr.Button("Run", scale=0, variant="primary")
118
+
119
+ with gr.Row():
120
+ init_image = gr.Image(label="Reference image (optional)", type="pil")
121
+ result = gr.Image(label="Result", show_label=False)
122
+
123
+ with gr.Accordion("Advanced Settings", open=False):
124
+ negative_prompt = gr.Text(
125
+ label="Negative prompt",
126
+ max_lines=1,
127
+ placeholder="Enter a negative prompt",
128
+ visible=False,
129
+ )
130
+
131
+ seed = gr.Slider(
132
+ label="Seed",
133
+ minimum=0,
134
+ maximum=MAX_SEED,
135
+ step=1,
136
+ value=0,
137
+ )
138
+
139
+ randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
140
+
141
+ with gr.Row():
142
+ width = gr.Slider(
143
+ label="Width",
144
+ minimum=256,
145
+ maximum=MAX_IMAGE_SIZE,
146
+ step=32,
147
+ value=1024, # Replace with defaults that work for your model
148
+ )
149
+
150
+ height = gr.Slider(
151
+ label="Height",
152
+ minimum=256,
153
+ maximum=MAX_IMAGE_SIZE,
154
+ step=32,
155
+ value=1024, # Replace with defaults that work for your model
156
+ )
157
+
158
+ with gr.Row():
159
+ guidance_scale = gr.Slider(
160
+ label="Guidance scale",
161
+ minimum=0.0,
162
+ maximum=10.0,
163
+ step=0.1,
164
+ value=0.0, # Replace with defaults that work for your model
165
+ )
166
+
167
+ num_inference_steps = gr.Slider(
168
+ label="Number of inference steps",
169
+ minimum=1,
170
+ maximum=50,
171
+ step=1,
172
+ value=2, # Replace with defaults that work for your model
173
+ )
174
+
175
+ strength = gr.Slider(
176
+ label="Strength (image-to-image only — higher = further from reference image)",
177
+ minimum=0.0,
178
+ maximum=1.0,
179
+ step=0.05,
180
+ value=0.5,
181
+ )
182
+
183
+ gr.Examples(examples=examples, inputs=[prompt])
184
+ gr.on(
185
+ triggers=[run_button.click, prompt.submit],
186
+ fn=infer,
187
+ inputs=[
188
+ prompt,
189
+ init_image,
190
+ negative_prompt,
191
+ seed,
192
+ randomize_seed,
193
+ width,
194
+ height,
195
+ guidance_scale,
196
+ num_inference_steps,
197
+ strength,
198
+ ],
199
+ outputs=[result, seed],
200
+ )
201
+
202
+ if __name__ == "__main__":
203
+ demo.launch()
204