waveshaker commited on
Commit
d2fe805
·
verified ·
1 Parent(s): 3595e0c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +44 -54
app.py CHANGED
@@ -437,7 +437,7 @@ class UnifiedProgressTqdm(tqdm_lib.tqdm):
437
  # ==========================================================================
438
  def execute_workflow(workflow: dict[str, Any]) -> list[str]:
439
  import tqdm.std
440
- global _timing_store
441
  original_tqdm = tqdm.std.tqdm
442
  tqdm.std.tqdm = UnifiedProgressTqdm
443
 
@@ -454,6 +454,7 @@ def execute_workflow(workflow: dict[str, Any]) -> list[str]:
454
  prompt_id = str(uuid.uuid4())
455
  save_id = next(k for k, v in workflow.items() if v.get("class_type") == "SaveImage")
456
 
 
457
  executor.execute(workflow, prompt_id, extra_data={}, execute_outputs=[save_id])
458
 
459
  _timing_store["T2"] = time.time()
@@ -514,8 +515,6 @@ def generate_workflow(
514
  *lora_states,
515
  ):
516
  global _terminal_html, _last_used_engine, _last_used_unet, _timing_store
517
- global _workflow_done, _workflow_error, _workflow_result
518
-
519
  _terminal_html = ""
520
  _timing_store = {}
521
 
@@ -534,13 +533,16 @@ def generate_workflow(
534
  yield None, _terminal_html
535
  _last_used_engine = engine
536
  _last_used_unet = unet_name
 
537
  elif _last_used_unet != unet_name:
538
  _append_log("SYS ", "orange", "Swapping UNet weights...")
539
  yield None, _terminal_html
540
  _last_used_unet = unet_name
 
541
  else:
542
  _append_log("SYS ", "green", "Base model cached. Fast inference.")
543
  yield None, _terminal_html
 
544
 
545
  _timing_store["T0"] = time.time()
546
 
@@ -581,35 +583,25 @@ def generate_workflow(
581
  # 初始化 loading 状态
582
  _timing_store["phase"] = "loading"
583
  _timing_store["load_start"] = time.time()
584
- _timing_store["last_elapsed"] = 0
585
- _append_log("SYS ", "blue", "📦 Loading tensors to VRAM... (Elapsed: 0s)")
586
  yield None, _terminal_html
587
 
588
  # ==========================================
589
- # 🌟 终极方案:用原生 Threading 异步执行,主线程死循环 yield
590
  # ==========================================
591
- _workflow_done = False
592
- _workflow_error = None
593
- _workflow_result = None
594
-
595
- t = threading.Thread(target=_run_comfy_background, args=(workflow,))
596
- t.daemon = True
597
- t.start()
598
-
599
- # 🌟 主线程以 0.5 秒的间隔疯狂往外吐状态,绝不卡死
600
- while not _workflow_done:
601
- time.sleep(0.5)
602
- yield None, _terminal_html
603
-
604
- # 检查后台线程是否有报错
605
- if _workflow_error:
606
- raise RuntimeError(_workflow_error)
607
 
608
- final_images = _workflow_result
 
609
 
 
610
  if "T1" not in _timing_store:
611
- _timing_store["T1"] = _timing_store["T2"] - 0.1
612
- _append_log("SYS ", "blue", "🎨 Running KSampler... (Elapsed: 0s)")
 
 
613
 
614
  dl_time = _timing_store.get("download_end", _timing_store["T0"]) - _timing_store["T0"]
615
  load_time = _timing_store["T1"] - _timing_store.get("load_start", _timing_store["T1"])
@@ -1232,11 +1224,7 @@ a:hover { opacity: 0.8 !important; text-decoration: underline !important; }
1232
  flex-wrap: nowrap !important;
1233
  width: 100% !important;
1234
  }
1235
- /* ========================================= */
1236
- /* 去掉图片输出区域gradio output标签 */
1237
- .column:nth-child(2) .html-container {
1238
- padding: 0 0 var(--block-padding) 0 !important;
1239
- }
1240
 
1241
  /* 强行破除 Gradio 默认的 1280/1536 宽度限制,让它永远占满全屏 */
1242
  .fillable {
@@ -1244,20 +1232,16 @@ a:hover { opacity: 0.8 !important; text-decoration: underline !important; }
1244
  width: 100% !important;
1245
  }
1246
 
1247
- /* 干掉右侧输出图片组件自带的标签栏和背景框 */
1248
- .column:nth-child(3) .gr-image > .label-wrap,
1249
- .column:nth-child(3) .gr-image > div:first-child {
 
 
 
1250
  display: none !important;
 
 
1251
  }
1252
-
1253
- /* 确保图片区域撑满��个组件 */
1254
- .column:nth-child(3) .gr-image {
1255
- padding: 0 !important;
1256
- background: transparent !important;
1257
- border: none !important;
1258
- overflow: hidden !important;
1259
- }
1260
-
1261
  /* ========================================= */
1262
  /* 🖥️ 极简终端框样式 */
1263
  .terminal-wrapper {
@@ -1273,26 +1257,31 @@ a:hover { opacity: 0.8 !important; text-decoration: underline !important; }
1273
  margin-bottom: 12px;
1274
  margin-top: 12px;
1275
  }
1276
- .terminal-content { color: #c9d1d9 !important; word-break: break-all !important; white-space: pre-wrap !important; }
1277
- .terminal-content .t-green { color: #3fb950 !important; }
1278
- .terminal-content .t-blue { color: #58a6ff !important; }
1279
- .terminal-content .t-orange { color: #d29922 !important; }
1280
- /* 把终端框的滚动条换成细细的半透明样式 */
1281
  .terminal-wrapper::-webkit-scrollbar {
1282
- width: 6px !important;
1283
  background: transparent !important;
1284
  }
1285
 
1286
- .terminal-wrapper::-webkit-scrollbar-thumb {
1287
- background: rgba(150, 150, 150, 0.4) !important; /* 👈 删掉了那个多余的 f */
1288
- border-radius: 10px !important;
1289
  }
1290
-
1291
  .terminal-wrapper:hover::-webkit-scrollbar-thumb {
1292
- background: rgba(150, 150, 150, 0.8) !important; /* 鼠标放上去时变亮,提示用户可以拖拽 */
 
 
 
 
1293
  }
1294
 
1295
- /* 扒掉终端内部的所有包裹层背景和边框 */
 
 
 
 
 
1296
  .terminal-wrapper .prose,
1297
  .terminal-wrapper .html-container,
1298
  .terminal-wrapper > div {
@@ -1301,6 +1290,7 @@ a:hover { opacity: 0.8 !important; text-decoration: underline !important; }
1301
  box-shadow: none !important;
1302
  padding: 0 !important;
1303
  margin: 0 !important;
 
1304
  }
1305
  """
1306
 
 
437
  # ==========================================================================
438
  def execute_workflow(workflow: dict[str, Any]) -> list[str]:
439
  import tqdm.std
440
+ global _timing_store, _terminal_html
441
  original_tqdm = tqdm.std.tqdm
442
  tqdm.std.tqdm = UnifiedProgressTqdm
443
 
 
454
  prompt_id = str(uuid.uuid4())
455
  save_id = next(k for k, v in workflow.items() if v.get("class_type") == "SaveImage")
456
 
457
+ # 直接调用,删掉不存在的 on_node_start
458
  executor.execute(workflow, prompt_id, extra_data={}, execute_outputs=[save_id])
459
 
460
  _timing_store["T2"] = time.time()
 
515
  *lora_states,
516
  ):
517
  global _terminal_html, _last_used_engine, _last_used_unet, _timing_store
 
 
518
  _terminal_html = ""
519
  _timing_store = {}
520
 
 
533
  yield None, _terminal_html
534
  _last_used_engine = engine
535
  _last_used_unet = unet_name
536
+ load_hint = "Initializing heavy weights (approx. 15-20s)..."
537
  elif _last_used_unet != unet_name:
538
  _append_log("SYS ", "orange", "Swapping UNet weights...")
539
  yield None, _terminal_html
540
  _last_used_unet = unet_name
541
+ load_hint = "Swapping model checkpoint (approx. 5-10s)..."
542
  else:
543
  _append_log("SYS ", "green", "Base model cached. Fast inference.")
544
  yield None, _terminal_html
545
+ load_hint = "Model cached. Warming up (approx. 1-2s)..."
546
 
547
  _timing_store["T0"] = time.time()
548
 
 
583
  # 初始化 loading 状态
584
  _timing_store["phase"] = "loading"
585
  _timing_store["load_start"] = time.time()
586
+ _append_log("SYS ", "blue", f"📦 Loading tensors to VRAM... {load_hint}")
 
587
  yield None, _terminal_html
588
 
589
  # ==========================================
590
+ # 🌟 核心:直接同步执行,放弃后台线程
591
  # ==========================================
592
+
593
+ # 执行(阻塞)
594
+ final_images = execute_workflow(workflow)
 
 
 
 
 
 
 
 
 
 
 
 
 
595
 
596
+ # 执行结束,补上 T2
597
+ _timing_store["T2"] = time.time()
598
 
599
+ # 如果 T1 没有被拦截器覆盖,就说明秒出图
600
  if "T1" not in _timing_store:
601
+ _timing_store["T1"] = _timing_store["T2"] - 0.1
602
+
603
+ _append_log("SYS ", "blue", "🎨 Running KSampler... (Elapsed: 0s)") # 补一行视觉
604
+ yield None, _terminal_html
605
 
606
  dl_time = _timing_store.get("download_end", _timing_store["T0"]) - _timing_store["T0"]
607
  load_time = _timing_store["T1"] - _timing_store.get("load_start", _timing_store["T1"])
 
1224
  flex-wrap: nowrap !important;
1225
  width: 100% !important;
1226
  }
1227
+
 
 
 
 
1228
 
1229
  /* 强行破除 Gradio 默认的 1280/1536 宽度限制,让它永远占满全屏 */
1230
  .fillable {
 
1232
  width: 100% !important;
1233
  }
1234
 
1235
+ /* ========================================= */
1236
+ /* 去掉图片输出区域gradio output标签 */
1237
+ .column:nth-child(3) .gr-image > div:first-child,
1238
+ .column:nth-child(3) .gr-image .label-wrap,
1239
+ .column:nth-child(3) .gr-image [data-testid="block-label"],
1240
+ .column:nth-child(3) .gr-image span[data-testid="block-info"] {
1241
  display: none !important;
1242
+ opacity: 0 !important;
1243
+ visibility: hidden !important;
1244
  }
 
 
 
 
 
 
 
 
 
1245
  /* ========================================= */
1246
  /* 🖥️ 极简终端框样式 */
1247
  .terminal-wrapper {
 
1257
  margin-bottom: 12px;
1258
  margin-top: 12px;
1259
  }
1260
+
1261
+ /* 👇 关键:默认完全隐藏滚动条,不占位置 */
 
 
 
1262
  .terminal-wrapper::-webkit-scrollbar {
1263
+ width: 0px !important;
1264
  background: transparent !important;
1265
  }
1266
 
1267
+ /* 👇 关键:只有当鼠标悬浮在终端上时,才显示 6px 的半透明滚动条 */
1268
+ .terminal-wrapper:hover::-webkit-scrollbar {
1269
+ width: 6px !important;
1270
  }
 
1271
  .terminal-wrapper:hover::-webkit-scrollbar-thumb {
1272
+ background: rgba(150, 150, 150, 0.4) !important;
1273
+ border-radius: 10px !important;
1274
+ }
1275
+ .terminal-wrapper:hover::-webkit-scrollbar-thumb:hover {
1276
+ background: rgba(150, 150, 150, 0.8) !important;
1277
  }
1278
 
1279
+ .terminal-content { color: #c9d1d9 !important; word-break: break-all !important; white-space: pre-wrap !important; }
1280
+ .terminal-content .t-green { color: #3fb950 !important; }
1281
+ .terminal-content .t-blue { color: #58a6ff !important; }
1282
+ .terminal-content .t-orange { color: #d29922 !important; }
1283
+
1284
+ /* 扒掉终端内部的所有包裹层背景和边框,并强制隐藏内部的滚动条 */
1285
  .terminal-wrapper .prose,
1286
  .terminal-wrapper .html-container,
1287
  .terminal-wrapper > div {
 
1290
  box-shadow: none !important;
1291
  padding: 0 !important;
1292
  margin: 0 !important;
1293
+ overflow: hidden !important; /* 防止内部再弹出一个滚动条 */
1294
  }
1295
  """
1296