radames commited on
Commit
9b79b03
1 Parent(s): c4a002d

add other params

Browse files
Files changed (2) hide show
  1. app-txt2img.py +9 -7
  2. txt2img/index.html +57 -28
app-txt2img.py CHANGED
@@ -76,9 +76,9 @@ pipe.unet.to(memory_format=torch.channels_last)
76
  if psutil.virtual_memory().total < 64 * 1024**3:
77
  pipe.enable_attention_slicing()
78
 
79
- if not mps_available and not xpu_available:
80
- pipe.unet = torch.compile(pipe.unet, mode="reduce-overhead", fullgraph=True)
81
- pipe(prompt="warmup", num_inference_steps=1, guidance_scale=8.0)
82
 
83
  compel_proc = Compel(
84
  tokenizer=pipe.tokenizer,
@@ -89,9 +89,12 @@ user_queue_map = {}
89
 
90
 
91
  class InputParams(BaseModel):
92
- prompt: str
93
  seed: int = 2159232
 
94
  guidance_scale: float = 8.0
 
 
 
95
  width: int = WIDTH
96
  height: int = HEIGHT
97
 
@@ -100,15 +103,14 @@ def predict(params: InputParams):
100
  generator = torch.manual_seed(params.seed)
101
  prompt_embeds = compel_proc(params.prompt)
102
  # Can be set to 1~50 steps. LCM support fast inference even <= 4 steps. Recommend: 1~8 steps.
103
- num_inference_steps = 4
104
  results = pipe(
105
  prompt_embeds=prompt_embeds,
106
  generator=generator,
107
- num_inference_steps=num_inference_steps,
108
  guidance_scale=params.guidance_scale,
109
  width=params.width,
110
  height=params.height,
111
- original_inference_steps=50,
112
  output_type="pil",
113
  )
114
  nsfw_content_detected = (
 
76
  if psutil.virtual_memory().total < 64 * 1024**3:
77
  pipe.enable_attention_slicing()
78
 
79
+ # if not mps_available and not xpu_available:
80
+ # pipe.unet = torch.compile(pipe.unet, mode="reduce-overhead", fullgraph=True)
81
+ # pipe(prompt="warmup", num_inference_steps=1, guidance_scale=8.0)
82
 
83
  compel_proc = Compel(
84
  tokenizer=pipe.tokenizer,
 
89
 
90
 
91
  class InputParams(BaseModel):
 
92
  seed: int = 2159232
93
+ prompt: str
94
  guidance_scale: float = 8.0
95
+ strength: float = 0.5
96
+ steps: int = 4
97
+ lcm_steps: int = 50
98
  width: int = WIDTH
99
  height: int = HEIGHT
100
 
 
103
  generator = torch.manual_seed(params.seed)
104
  prompt_embeds = compel_proc(params.prompt)
105
  # Can be set to 1~50 steps. LCM support fast inference even <= 4 steps. Recommend: 1~8 steps.
 
106
  results = pipe(
107
  prompt_embeds=prompt_embeds,
108
  generator=generator,
109
+ num_inference_steps=params.steps,
110
  guidance_scale=params.guidance_scale,
111
  width=params.width,
112
  height=params.height,
113
+ original_inference_steps=params.lcm_steps,
114
  output_type="pil",
115
  )
116
  nsfw_content_detected = (
txt2img/index.html CHANGED
@@ -15,10 +15,12 @@
15
  }
16
  </style>
17
  <script type="module">
18
-
19
- const seedEl = document.querySelector("#seed");
20
- const promptEl = document.querySelector("#prompt");
21
- const guidanceEl = document.querySelector("#guidance-scale");
 
 
22
  const startBtn = document.querySelector("#start");
23
  const stopBtn = document.querySelector("#stop");
24
  const videoEl = document.querySelector("#webcam");
@@ -26,8 +28,9 @@
26
  const queueSizeEl = document.querySelector("#queue_size");
27
  const errorEl = document.querySelector("#error");
28
  const snapBtn = document.querySelector("#snap");
29
-
30
- function LCMLive(promptEl, liveImage, seedEl, guidanceEl) {
 
31
  let websocket;
32
 
33
  async function start() {
@@ -69,15 +72,17 @@
69
  })
70
  }
71
 
72
- async function promptUpdateStream() {
73
- const prompt = promptEl.value;
74
- console.log(prompt);
75
- const seed = seedEl.value;
76
- const guidance_scale = guidanceEl.value;
77
  websocket.send(JSON.stringify({
78
- prompt: prompt,
79
- seed: seed,
80
- guidance_scale: guidance_scale,
 
 
 
 
81
  }));
82
  }
83
  function debouceInput(fn, delay) {
@@ -92,16 +97,12 @@
92
  const debouncedInput = debouceInput(promptUpdateStream, 200);
93
  function initPromptStream(userId) {
94
  liveImage.src = `/stream/${userId}`;
95
- promptEl.addEventListener("input", debouncedInput);
96
- seedEl.addEventListener("input", debouncedInput);
97
- guidanceEl.addEventListener("change", debouncedInput);
98
  }
99
 
100
  async function stop() {
101
  websocket.close();
102
- promptEl.removeEventListener("input", debouncedInput);
103
- seedEl.removeEventListener("input", debouncedInput);
104
- guidanceEl.removeEventListener("change", debouncedInput);
105
  }
106
  return {
107
  start,
@@ -131,7 +132,7 @@
131
  const exif = {};
132
  const gps = {};
133
  zeroth[piexif.ImageIFD.Make] = "LCM Text-to-Image";
134
- zeroth[piexif.ImageIFD.ImageDescription] = `prompt: ${promptEl.value} | seed: ${seedEl.value} | guidance: ${guidanceEl.value}`;
135
  zeroth[piexif.ImageIFD.Software] = "https://github.com/radames/Real-Time-Latent-Consistency-Model";
136
 
137
  exif[piexif.ExifIFD.DateTimeOriginal] = new Date().toISOString();
@@ -157,7 +158,7 @@
157
  }
158
 
159
 
160
- const lcmLive = LCMLive(promptEl, imageEl, seedEl, guidanceEl);
161
  startBtn.addEventListener("click", async () => {
162
  try {
163
  startBtn.disabled = true;
@@ -233,22 +234,50 @@
233
  <div class="">
234
  <details>
235
  <summary class="font-medium cursor-pointer">Advanced Options</summary>
236
- <div class="grid grid-cols-3 max-w-md items-center gap-3 py-3">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
  <label class="text-sm font-medium" for="guidance-scale">Guidance Scale
238
  </label>
239
- <input type="range" id="guidance-scale" name="guidance-scale" min="1" max="30" step="0.001"
240
  value="8.0" oninput="this.nextElementSibling.value = Number(this.value).toFixed(2)">
241
  <output class="text-xs w-[50px] text-center font-light px-1 py-1 border border-gray-700 rounded-md">
242
  8.0</output>
 
243
  <label class="text-sm font-medium" for="seed">Seed</label>
244
  <input type="number" id="seed" name="seed" value="299792458"
245
  class="font-light border border-gray-700 text-right rounded-md p-2 dark:text-black">
246
- <button
247
- onclick="document.querySelector('#seed').value = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); document.querySelector('#seed').dispatchEvent(new Event('input'));"
248
- class="button">
249
  Rand
250
  </button>
251
- </div>
 
252
  </details>
253
  </div>
254
  <div class="flex gap-3">
 
15
  }
16
  </style>
17
  <script type="module">
18
+ const getValue = (id) => {
19
+ const el = document.querySelector(`${id}`)
20
+ if (el.type === "checkbox")
21
+ return el.checked;
22
+ return el.value;
23
+ }
24
  const startBtn = document.querySelector("#start");
25
  const stopBtn = document.querySelector("#stop");
26
  const videoEl = document.querySelector("#webcam");
 
28
  const queueSizeEl = document.querySelector("#queue_size");
29
  const errorEl = document.querySelector("#error");
30
  const snapBtn = document.querySelector("#snap");
31
+ const paramsEl = document.querySelector("#params");
32
+ paramsEl.addEventListener("submit", (e) => e.preventDefault());
33
+ function LCMLive(paramsEl, liveImage) {
34
  let websocket;
35
 
36
  async function start() {
 
72
  })
73
  }
74
 
75
+ async function promptUpdateStream(e) {
76
+ const dimension = getValue("input[name=dimension]:checked");
77
+ const [WIDTH, HEIGHT] = JSON.parse(dimension);
 
 
78
  websocket.send(JSON.stringify({
79
+ "seed": getValue("#seed"),
80
+ "prompt": getValue("#prompt"),
81
+ "guidance_scale": getValue("#guidance-scale"),
82
+ "steps": getValue("#steps"),
83
+ "lcm_steps": getValue("#lcm_steps"),
84
+ "width": WIDTH,
85
+ "height": HEIGHT,
86
  }));
87
  }
88
  function debouceInput(fn, delay) {
 
97
  const debouncedInput = debouceInput(promptUpdateStream, 200);
98
  function initPromptStream(userId) {
99
  liveImage.src = `/stream/${userId}`;
100
+ paramsEl.addEventListener("change", debouncedInput);
 
 
101
  }
102
 
103
  async function stop() {
104
  websocket.close();
105
+ paramsEl.removeEventListener("change", debouncedInput);
 
 
106
  }
107
  return {
108
  start,
 
132
  const exif = {};
133
  const gps = {};
134
  zeroth[piexif.ImageIFD.Make] = "LCM Text-to-Image";
135
+ zeroth[piexif.ImageIFD.ImageDescription] = `prompt: ${getValue("#prompt")} | seed: ${getValue("#seed")} | guidance_scale: ${getValue("#guidance-scale")} | lcm_steps: ${getValue("#lcm_steps")} | steps: ${getValue("#steps")}`;
136
  zeroth[piexif.ImageIFD.Software] = "https://github.com/radames/Real-Time-Latent-Consistency-Model";
137
 
138
  exif[piexif.ExifIFD.DateTimeOriginal] = new Date().toISOString();
 
158
  }
159
 
160
 
161
+ const lcmLive = LCMLive(paramsEl, imageEl);
162
  startBtn.addEventListener("click", async () => {
163
  try {
164
  startBtn.disabled = true;
 
234
  <div class="">
235
  <details>
236
  <summary class="font-medium cursor-pointer">Advanced Options</summary>
237
+ <form class="grid grid-cols-3 items-center gap-3 py-3" id="params" action="">
238
+ <label class="text-sm font-medium" for="dimension">Image Dimensions</label>
239
+ <div class="col-span-2 flex gap-2">
240
+ <div class="flex gap-1">
241
+ <input type="radio" id="dimension512" name="dimension" value="[512,512]" checked
242
+ class="cursor-pointer">
243
+ <label for="dimension512" class="text-sm cursor-pointer">512x512</label>
244
+ </div>
245
+ <div class="flex gap-1">
246
+ <input type="radio" id="dimension768" name="dimension" value="[768,768]"
247
+ lass="cursor-pointer">
248
+ <label for="dimension768" class="text-sm cursor-pointer">768x768</label>
249
+ </div>
250
+ </div>
251
+ <!-- -->
252
+ <label class="text-sm font-medium " for="steps">Inference Steps
253
+ </label>
254
+ <input type="range" id="steps" name="steps" min="1" max="20" value="4"
255
+ oninput="this.nextElementSibling.value = Number(this.value)">
256
+ <output class="text-xs w-[50px] text-center font-light px-1 py-1 border border-gray-700 rounded-md">
257
+ 4</output>
258
+ <!-- -->
259
+ <label class="text-sm font-medium" for="lcm_steps">LCM Inference Steps
260
+ </label>
261
+ <input type="range" id="lcm_steps" name="lcm_steps" min="2" max="60" value="50"
262
+ oninput="this.nextElementSibling.value = Number(this.value)">
263
+ <output class="text-xs w-[50px] text-center font-light px-1 py-1 border border-gray-700 rounded-md">
264
+ 50</output>
265
+ <!-- -->
266
  <label class="text-sm font-medium" for="guidance-scale">Guidance Scale
267
  </label>
268
+ <input type="range" id="guidance-scale" name="guidance-scale" min="0" max="30" step="0.001"
269
  value="8.0" oninput="this.nextElementSibling.value = Number(this.value).toFixed(2)">
270
  <output class="text-xs w-[50px] text-center font-light px-1 py-1 border border-gray-700 rounded-md">
271
  8.0</output>
272
+ <!-- -->
273
  <label class="text-sm font-medium" for="seed">Seed</label>
274
  <input type="number" id="seed" name="seed" value="299792458"
275
  class="font-light border border-gray-700 text-right rounded-md p-2 dark:text-black">
276
+ <button class="button" onclick="document.querySelector('#seed').value = Math.floor(Math.random() * 1000000000); document.querySelector('#params').dispatchEvent(new Event('change'))">
 
 
277
  Rand
278
  </button>
279
+ <!-- -->
280
+ </form>
281
  </details>
282
  </div>
283
  <div class="flex gap-3">