Spaces:
Sleeping
Sleeping
Commit ·
ef2120b
1
Parent(s): 33d116c
Change to playground
Browse files- README.md +15 -3
- app.py +1221 -635
- requirements.txt +7 -1
README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
emoji:
|
| 4 |
colorFrom: yellow
|
| 5 |
colorTo: yellow
|
| 6 |
sdk: gradio
|
|
@@ -9,4 +9,16 @@ app_file: app.py
|
|
| 9 |
pinned: true
|
| 10 |
---
|
| 11 |
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: HF Model Playground
|
| 3 |
+
emoji: 🤗
|
| 4 |
colorFrom: yellow
|
| 5 |
colorTo: yellow
|
| 6 |
sdk: gradio
|
|
|
|
| 9 |
pinned: true
|
| 10 |
---
|
| 11 |
|
| 12 |
+
# 🤗 HuggingFace Model Playground
|
| 13 |
+
|
| 14 |
+
Enter any HuggingFace model ID — auto-detects the task and adapts the UI.
|
| 15 |
+
|
| 16 |
+
**Supported tasks:**
|
| 17 |
+
- 💬 Text Generation (chat, completion, translate via prompt)
|
| 18 |
+
- 📝 Summarization
|
| 19 |
+
- 🌐 Translation
|
| 20 |
+
- 🎨 Image Generation (with live step preview)
|
| 21 |
+
- 🔊 Text-to-Speech
|
| 22 |
+
- 🧠 Thinking models (DeepSeek-R1, QwQ)
|
| 23 |
+
|
| 24 |
+
**Quick-select presets** for popular small models in each category.
|
app.py
CHANGED
|
@@ -1,107 +1,161 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
import
|
|
|
|
| 9 |
import gradio as gr
|
| 10 |
-
|
| 11 |
import os
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
)
|
| 21 |
-
|
| 22 |
-
pipe.to(device)
|
| 23 |
-
pipe.enable_attention_slicing()
|
| 24 |
-
print("Pipeline loaded!")
|
| 25 |
|
| 26 |
-
#
|
| 27 |
-
|
| 28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
|
|
|
|
| 30 |
|
| 31 |
-
|
| 32 |
-
"""Decode latents to a PIL image using the same recipe as the pipeline."""
|
| 33 |
-
l = latents.to(pipe.vae.dtype)
|
| 34 |
-
scaling_factor = pipe.vae.config.scaling_factor
|
| 35 |
-
shift_factor = getattr(pipe.vae.config, "shift_factor", 0)
|
| 36 |
-
l = (l / scaling_factor) + shift_factor
|
| 37 |
-
with torch.no_grad():
|
| 38 |
-
image = pipe.vae.decode(l, return_dict=False)[0]
|
| 39 |
-
return pipe.image_processor.postprocess(image, output_type="pil")[0]
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
def generate_image(prompt, height, width, num_inference_steps, seed, randomize_seed, progress=gr.Progress(track_tqdm=True)):
|
| 43 |
-
"""Generate an image from the given prompt, yielding a preview after each denoising step.
|
| 44 |
-
Cancels any previous generation automatically.
|
| 45 |
-
"""
|
| 46 |
-
global _current_interrupt
|
| 47 |
-
|
| 48 |
-
# Signal cancellation of previous generation (if any)
|
| 49 |
-
with _generation_lock:
|
| 50 |
-
if _current_interrupt is not None:
|
| 51 |
-
_current_interrupt.set() # Signal previous thread to stop
|
| 52 |
-
pipe._interrupt = True # Diffusers pipeline respects this flag
|
| 53 |
-
# Create new interrupt event for this generation
|
| 54 |
-
_current_interrupt = threading.Event()
|
| 55 |
-
pipe._interrupt = False
|
| 56 |
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
|
| 59 |
-
|
| 60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
|
| 62 |
-
generator = torch.Generator(device).manual_seed(int(seed))
|
| 63 |
|
| 64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
step_counter = {"i": 0}
|
| 66 |
|
| 67 |
-
def
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
step_counter["i"] += 1
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
|
|
|
|
|
|
| 76 |
|
| 77 |
result = {}
|
| 78 |
-
|
| 79 |
|
| 80 |
def run():
|
| 81 |
try:
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
callback_on_step_end_tensor_inputs=["latents"],
|
| 92 |
-
)
|
| 93 |
-
if not interrupt_event.is_set():
|
| 94 |
-
# Keep batch dim: out.images is [1, C, H, W], not [0] which gives [C, H, W]
|
| 95 |
-
final = decode_latents(out.images)
|
| 96 |
-
result["final"] = final
|
| 97 |
-
previews.put(None) # sentinel: done
|
| 98 |
except Exception as e:
|
| 99 |
-
|
| 100 |
previews.put(None)
|
| 101 |
|
| 102 |
-
|
| 103 |
-
thread.start()
|
| 104 |
-
|
| 105 |
last = None
|
| 106 |
while True:
|
| 107 |
item = previews.get()
|
|
@@ -109,587 +163,1119 @@ def generate_image(prompt, height, width, num_inference_steps, seed, randomize_s
|
|
| 109 |
break
|
| 110 |
img, step = item
|
| 111 |
last = img
|
| 112 |
-
yield img, seed, f"Step {step}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 113 |
|
| 114 |
-
|
| 115 |
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
|
| 120 |
-
if
|
| 121 |
-
|
|
|
|
| 122 |
yield last, seed, "Cancelled"
|
| 123 |
else:
|
| 124 |
-
yield
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
# ------
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
* a FileData dict with a `path` (uploaded)
|
| 136 |
-
* a FileData dict with an inline base64 `data:` URI (used when the
|
| 137 |
-
caller cannot reach /upload, e.g. behind a proxy)
|
| 138 |
-
* a bare `data:` URI string
|
| 139 |
-
"""
|
| 140 |
-
if isinstance(entry, str):
|
| 141 |
-
if entry.startswith("data:"):
|
| 142 |
-
_, _, payload = entry.partition(",")
|
| 143 |
-
return "upload", base64.b64decode(payload)
|
| 144 |
-
with open(entry, "rb") as fh:
|
| 145 |
-
return os.path.basename(entry), fh.read()
|
| 146 |
-
if isinstance(entry, dict):
|
| 147 |
-
name = entry.get("orig_name") or entry.get("name") or "upload"
|
| 148 |
-
path = entry.get("path")
|
| 149 |
-
if path:
|
| 150 |
-
with open(path, "rb") as fh:
|
| 151 |
-
return os.path.basename(path), fh.read()
|
| 152 |
-
url = entry.get("url") or ""
|
| 153 |
-
if url.startswith("data:"):
|
| 154 |
-
_, _, payload = url.partition(",")
|
| 155 |
-
return name, base64.b64decode(payload)
|
| 156 |
-
if url:
|
| 157 |
-
import urllib.request as _ur
|
| 158 |
-
with _ur.urlopen(url, timeout=30) as resp:
|
| 159 |
-
return name, resp.read()
|
| 160 |
-
raise ValueError(f"Unsupported file value: {entry!r}")
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
def _conflict_check_fn(files, config):
|
| 164 |
-
"""Hidden Gradio API (api_name="conflict_check"): compare uploaded files
|
| 165 |
-
for conflicts. `files` is the hidden gr.JSON input (list of FileData dicts,
|
| 166 |
-
each typically carrying an inline base64 `data:` URI, or a single dict).
|
| 167 |
-
`config` is a gr.JSON dict of generation settings (model id + params)."""
|
| 168 |
-
if not files:
|
| 169 |
-
return {
|
| 170 |
-
"conflicts_found": False,
|
| 171 |
-
"summary": "No files were uploaded.",
|
| 172 |
-
"conflicts": [],
|
| 173 |
-
}
|
| 174 |
-
if isinstance(files, (str, dict)):
|
| 175 |
-
files = [files]
|
| 176 |
-
raw_docs = []
|
| 177 |
-
for entry in files:
|
| 178 |
try:
|
| 179 |
-
|
| 180 |
except Exception as e:
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
}
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
# Example prompts
|
| 203 |
-
examples = [
|
| 204 |
-
["Young Chinese woman in red Hanfu, intricate embroidery. Impeccable makeup, red floral forehead pattern. Elaborate high bun, golden phoenix headdress, red flowers, beads. Holds round folding fan with lady, trees, bird. Neon lightning-bolt lamp, bright yellow glow, above extended left palm. Soft-lit outdoor night background, silhouetted tiered pagoda, blurred colorful distant lights."],
|
| 205 |
-
["A majestic dragon soaring through clouds at sunset, scales shimmering with iridescent colors, detailed fantasy art style"],
|
| 206 |
-
["Cozy coffee shop interior, warm lighting, rain on windows, plants on shelves, vintage aesthetic, photorealistic"],
|
| 207 |
-
["Astronaut riding a horse on Mars, cinematic lighting, sci-fi concept art, highly detailed"],
|
| 208 |
-
["Portrait of a wise old wizard with a long white beard, holding a glowing crystal staff, magical forest background"],
|
| 209 |
-
]
|
| 210 |
|
| 211 |
-
# Custom theme with modern aesthetics (Gradio 6)
|
| 212 |
-
custom_theme = gr.themes.Soft(
|
| 213 |
-
primary_hue="yellow",
|
| 214 |
-
secondary_hue="amber",
|
| 215 |
-
neutral_hue="slate",
|
| 216 |
-
font=gr.themes.GoogleFont("Inter"),
|
| 217 |
-
text_size="lg",
|
| 218 |
-
spacing_size="md",
|
| 219 |
-
radius_size="lg"
|
| 220 |
-
).set(
|
| 221 |
-
button_primary_background_fill="*primary_500",
|
| 222 |
-
button_primary_background_fill_hover="*primary_600",
|
| 223 |
-
block_title_text_weight="600",
|
| 224 |
-
)
|
| 225 |
|
| 226 |
-
#
|
| 227 |
-
with gr.Blocks(fill_height=True) as demo:
|
| 228 |
-
# Header
|
| 229 |
-
gr.Markdown(
|
| 230 |
-
"""
|
| 231 |
-
# 🎨 Z-Image-Turbo
|
| 232 |
-
**Ultra-fast AI image generation** • CPU mode • 256×256 default • live step-by-step preview
|
| 233 |
-
""",
|
| 234 |
-
elem_classes="header-text"
|
| 235 |
-
)
|
| 236 |
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
label="✨ Your Prompt",
|
| 242 |
-
placeholder="Describe the image you want to create...",
|
| 243 |
-
lines=5,
|
| 244 |
-
max_lines=10,
|
| 245 |
-
autofocus=True,
|
| 246 |
-
)
|
| 247 |
-
|
| 248 |
-
with gr.Accordion("⚙️ Advanced Settings", open=False):
|
| 249 |
-
with gr.Row():
|
| 250 |
-
height = gr.Slider(
|
| 251 |
-
minimum=32,
|
| 252 |
-
maximum=1024,
|
| 253 |
-
value=256,
|
| 254 |
-
step=32,
|
| 255 |
-
label="Height",
|
| 256 |
-
info="Image height in pixels"
|
| 257 |
-
)
|
| 258 |
-
width = gr.Slider(
|
| 259 |
-
minimum=32,
|
| 260 |
-
maximum=1024,
|
| 261 |
-
value=256,
|
| 262 |
-
step=32,
|
| 263 |
-
label="Width",
|
| 264 |
-
info="Image width in pixels"
|
| 265 |
-
)
|
| 266 |
-
|
| 267 |
-
num_inference_steps = gr.Slider(
|
| 268 |
-
minimum=1,
|
| 269 |
-
maximum=20,
|
| 270 |
-
value=9,
|
| 271 |
-
step=1,
|
| 272 |
-
label="Inference Steps",
|
| 273 |
-
info="9 steps = 8 DiT forwards (recommended)"
|
| 274 |
-
)
|
| 275 |
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
label="🎲 Random Seed",
|
| 279 |
-
value=True,
|
| 280 |
-
)
|
| 281 |
-
seed = gr.Number(
|
| 282 |
-
label="Seed",
|
| 283 |
-
value=42,
|
| 284 |
-
precision=0,
|
| 285 |
-
visible=False,
|
| 286 |
-
)
|
| 287 |
-
|
| 288 |
-
def toggle_seed(randomize):
|
| 289 |
-
return gr.Number(visible=not randomize)
|
| 290 |
-
|
| 291 |
-
randomize_seed.change(
|
| 292 |
-
toggle_seed,
|
| 293 |
-
inputs=[randomize_seed],
|
| 294 |
-
outputs=[seed]
|
| 295 |
-
)
|
| 296 |
|
| 297 |
-
|
| 298 |
-
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
scale=1
|
| 302 |
-
)
|
| 303 |
-
|
| 304 |
-
# Example prompts
|
| 305 |
-
gr.Examples(
|
| 306 |
-
examples=examples,
|
| 307 |
-
inputs=[prompt],
|
| 308 |
-
label="💡 Try these prompts",
|
| 309 |
-
examples_per_page=5,
|
| 310 |
-
)
|
| 311 |
-
|
| 312 |
-
# Right column - Output
|
| 313 |
-
with gr.Column(scale=1, min_width=320):
|
| 314 |
-
output_image = gr.Image(
|
| 315 |
-
label="Generated Image",
|
| 316 |
-
type="pil",
|
| 317 |
-
format="png",
|
| 318 |
-
show_label=False,
|
| 319 |
-
height=512,
|
| 320 |
-
buttons=["download", "share"],
|
| 321 |
-
)
|
| 322 |
-
|
| 323 |
-
status = gr.Textbox(
|
| 324 |
-
label="🔄 Progress",
|
| 325 |
-
value="Idle",
|
| 326 |
-
interactive=False,
|
| 327 |
-
)
|
| 328 |
-
|
| 329 |
-
used_seed = gr.Number(
|
| 330 |
-
label="🎲 Seed Used",
|
| 331 |
-
interactive=False,
|
| 332 |
-
container=True,
|
| 333 |
-
)
|
| 334 |
-
|
| 335 |
-
# Footer credits
|
| 336 |
-
gr.Markdown(
|
| 337 |
-
"""
|
| 338 |
-
---
|
| 339 |
-
<div style="text-align: center; opacity: 0.7; font-size: 0.9em; margin-top: 1rem;">
|
| 340 |
-
<strong>Model:</strong> <a href="https://huggingface.co/Tongyi-MAI/Z-Image-Turbo" target="_blank">Tongyi-MAI/Z-Image-Turbo</a> (Apache 2.0 License) •
|
| 341 |
-
<strong>Demo by:</strong> <a href="https://x.com/realmrfakename" target="_blank">@mrfakename</a> •
|
| 342 |
-
<strong>Redesign by:</strong> AnyCoder •
|
| 343 |
-
<strong>CPU + step-preview mod</strong>
|
| 344 |
-
</div>
|
| 345 |
-
""",
|
| 346 |
-
elem_classes="footer-text"
|
| 347 |
-
)
|
| 348 |
|
| 349 |
-
|
| 350 |
-
|
| 351 |
-
|
| 352 |
-
|
| 353 |
-
|
| 354 |
-
|
|
|
|
| 355 |
|
| 356 |
-
|
| 357 |
-
|
| 358 |
-
|
| 359 |
-
|
| 360 |
-
|
| 361 |
-
|
|
|
|
|
|
|
| 362 |
|
| 363 |
-
|
| 364 |
-
|
| 365 |
-
|
| 366 |
-
|
| 367 |
-
|
| 368 |
-
|
| 369 |
-
|
| 370 |
-
|
| 371 |
-
|
| 372 |
-
|
| 373 |
-
|
| 374 |
-
|
| 375 |
-
|
| 376 |
-
|
| 377 |
-
|
| 378 |
-
|
| 379 |
-
outputs=[conflict_out],
|
| 380 |
-
api_name="conflict_check",
|
| 381 |
-
)
|
| 382 |
|
|
|
|
|
|
|
|
|
|
| 383 |
|
| 384 |
-
|
| 385 |
-
|
| 386 |
-
|
| 387 |
-
|
| 388 |
-
|
| 389 |
-
|
| 390 |
-
|
| 391 |
-
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
|
| 396 |
-
|
| 397 |
-
|
| 398 |
-
|
| 399 |
-
|
| 400 |
-
|
| 401 |
-
|
| 402 |
-
|
| 403 |
-
|
| 404 |
-
|
| 405 |
-
|
| 406 |
-
|
| 407 |
-
|
| 408 |
-
|
| 409 |
-
|
| 410 |
-
|
| 411 |
-
|
| 412 |
-
|
| 413 |
-
|
| 414 |
-
|
| 415 |
-
|
| 416 |
-
|
| 417 |
-
|
| 418 |
-
|
| 419 |
-
|
| 420 |
-
|
| 421 |
-
|
| 422 |
-
|
| 423 |
-
|
| 424 |
-
|
| 425 |
-
|
| 426 |
-
|
| 427 |
-
|
| 428 |
-
|
| 429 |
-
|
| 430 |
-
|
| 431 |
-
|
| 432 |
-
|
| 433 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 434 |
}
|
| 435 |
-
|
| 436 |
-
|
| 437 |
-
|
| 438 |
-
|
| 439 |
-
|
| 440 |
-
|
| 441 |
-
|
| 442 |
-
|
| 443 |
-
|
| 444 |
-
|
| 445 |
-
|
| 446 |
-
|
| 447 |
-
|
| 448 |
-
|
| 449 |
-
|
| 450 |
-
|
| 451 |
-
|
| 452 |
-
if
|
| 453 |
-
|
| 454 |
-
|
| 455 |
-
|
| 456 |
-
|
| 457 |
-
|
| 458 |
-
|
| 459 |
-
|
| 460 |
-
|
| 461 |
-
|
| 462 |
-
|
| 463 |
-
|
| 464 |
-
|
| 465 |
-
|
| 466 |
-
|
| 467 |
-
|
| 468 |
-
|
| 469 |
-
|
| 470 |
-
|
| 471 |
-
|
| 472 |
-
|
| 473 |
-
|
| 474 |
-
|
| 475 |
-
|
| 476 |
-
|
| 477 |
-
|
| 478 |
-
|
| 479 |
-
|
| 480 |
-
|
| 481 |
-
|
| 482 |
-
|
| 483 |
-
|
| 484 |
-
|
| 485 |
-
|
| 486 |
-
|
| 487 |
-
|
| 488 |
-
|
| 489 |
-
|
| 490 |
-
|
| 491 |
-
|
| 492 |
-
|
| 493 |
-
|
| 494 |
-
|
| 495 |
-
|
| 496 |
-
|
| 497 |
-
|
| 498 |
-
|
| 499 |
-
|
| 500 |
-
|
| 501 |
-
|
| 502 |
-
|
| 503 |
-
|
| 504 |
-
|
| 505 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 506 |
try:
|
| 507 |
-
|
| 508 |
-
|
| 509 |
-
if isinstance(parsed, dict) and "data" in parsed:
|
| 510 |
-
parsed = parsed["data"]
|
| 511 |
-
simplified = _simplify_json(parsed)
|
| 512 |
-
return json.dumps(simplified, indent=2, ensure_ascii=False)
|
| 513 |
except Exception:
|
| 514 |
-
|
| 515 |
-
|
| 516 |
-
|
| 517 |
-
|
| 518 |
-
|
| 519 |
-
|
| 520 |
-
|
| 521 |
-
|
| 522 |
-
|
| 523 |
-
|
| 524 |
-
|
| 525 |
-
|
| 526 |
-
|
| 527 |
-
|
| 528 |
-
|
| 529 |
-
|
| 530 |
-
|
| 531 |
-
|
| 532 |
-
|
| 533 |
-
|
| 534 |
-
|
| 535 |
-
|
| 536 |
-
|
| 537 |
-
|
| 538 |
-
|
| 539 |
-
|
| 540 |
-
|
| 541 |
-
|
| 542 |
-
|
| 543 |
-
|
| 544 |
-
|
| 545 |
-
|
| 546 |
-
|
| 547 |
-
return json.loads(t[start:end + 1])
|
| 548 |
-
|
| 549 |
-
|
| 550 |
-
def _analyze_conflicts(documents, config=None):
|
| 551 |
-
"""Run the LLM conflict analysis on a list of {filename, content} dicts.
|
| 552 |
-
`config` (dict) may override the model id and any generation parameters
|
| 553 |
-
(max_new_tokens, temperature, top_p, top_k, do_sample, repetition_penalty)."""
|
| 554 |
-
config = config or {}
|
| 555 |
-
model_id = config.get("model") or CONFLICT_MODEL_ID
|
| 556 |
-
device = "cuda" if (config.get("gpu") and torch.cuda.is_available()) else "cpu"
|
| 557 |
-
tokenizer, model = _load_conflict_model(model_id, device)
|
| 558 |
-
|
| 559 |
-
gen_kwargs = {
|
| 560 |
-
"max_new_tokens": int(config.get("max_new_tokens", 4096)),
|
| 561 |
-
"do_sample": bool(config.get("do_sample", False)),
|
| 562 |
-
"temperature": float(config.get("temperature", 1.0)),
|
| 563 |
-
}
|
| 564 |
-
if config.get("top_p") is not None:
|
| 565 |
-
gen_kwargs["top_p"] = float(config["top_p"])
|
| 566 |
-
if config.get("top_k") is not None:
|
| 567 |
-
gen_kwargs["top_k"] = int(config["top_k"])
|
| 568 |
-
if config.get("repetition_penalty") is not None:
|
| 569 |
-
gen_kwargs["repetition_penalty"] = float(config["repetition_penalty"])
|
| 570 |
-
|
| 571 |
-
docs_block = "\n\n".join(
|
| 572 |
-
f"===== DOCUMENT: {d['filename']} =====\n{d['content']}" for d in documents
|
| 573 |
)
|
| 574 |
-
|
| 575 |
-
|
| 576 |
-
|
| 577 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 578 |
)
|
| 579 |
|
| 580 |
-
#
|
| 581 |
-
|
| 582 |
-
|
| 583 |
-
|
| 584 |
-
|
| 585 |
-
|
| 586 |
-
try:
|
| 587 |
-
text = tokenizer.apply_chat_template(
|
| 588 |
-
messages, tokenize=False, add_generation_prompt=True, enable_thinking=False
|
| 589 |
-
)
|
| 590 |
-
except TypeError:
|
| 591 |
-
text = tokenizer.apply_chat_template(
|
| 592 |
-
messages, tokenize=False, add_generation_prompt=True
|
| 593 |
-
)
|
| 594 |
-
inputs = tokenizer(text, return_tensors="pt").to(model.device)
|
| 595 |
|
| 596 |
-
|
| 597 |
-
|
| 598 |
-
|
| 599 |
-
|
| 600 |
-
|
| 601 |
-
|
| 602 |
-
except ValueError:
|
| 603 |
-
raise ValueError(
|
| 604 |
-
f"JSON parse failed (gen_len={generated.shape[0]}). "
|
| 605 |
-
f"tail={response_text[-300:]!r}"
|
| 606 |
-
)
|
| 607 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 608 |
|
| 609 |
-
|
| 610 |
-
|
| 611 |
-
|
| 612 |
-
|
| 613 |
-
|
|
|
|
| 614 |
|
|
|
|
|
|
|
| 615 |
|
| 616 |
-
|
| 617 |
-
|
| 618 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 619 |
|
| 620 |
|
| 621 |
-
#
|
| 622 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
| 623 |
|
| 624 |
if __name__ == "__main__":
|
| 625 |
-
demo.queue().launch(
|
| 626 |
-
|
| 627 |
-
|
| 628 |
-
|
| 629 |
-
|
| 630 |
-
|
| 631 |
-
margin-bottom: 0.5rem !important;
|
| 632 |
-
background: linear-gradient(135deg, #fbbf24 0%, #f59e0b 100%);
|
| 633 |
-
-webkit-background-clip: text;
|
| 634 |
-
-webkit-text-fill-color: transparent;
|
| 635 |
-
background-clip: text;
|
| 636 |
-
}
|
| 637 |
-
|
| 638 |
-
.header-text p {
|
| 639 |
-
font-size: 1.1rem !important;
|
| 640 |
-
color: #64748b !important;
|
| 641 |
-
margin-top: 0 !important;
|
| 642 |
-
}
|
| 643 |
-
|
| 644 |
-
.footer-text {
|
| 645 |
-
padding: 1rem 0;
|
| 646 |
-
}
|
| 647 |
-
|
| 648 |
-
.footer-text a {
|
| 649 |
-
color: #f59e0b !important;
|
| 650 |
-
text-decoration: none !important;
|
| 651 |
-
font-weight: 500;
|
| 652 |
-
}
|
| 653 |
-
|
| 654 |
-
.footer-text a:hover {
|
| 655 |
-
text-decoration: underline !important;
|
| 656 |
-
}
|
| 657 |
-
|
| 658 |
-
/* Mobile optimizations */
|
| 659 |
-
@media (max-width: 768px) {
|
| 660 |
-
.header-text h1 {
|
| 661 |
-
font-size: 1.8rem !important;
|
| 662 |
-
}
|
| 663 |
-
|
| 664 |
-
.header-text p {
|
| 665 |
-
font-size: 1rem !important;
|
| 666 |
-
}
|
| 667 |
-
}
|
| 668 |
-
|
| 669 |
-
/* Smooth transitions */
|
| 670 |
-
button, .gr-button {
|
| 671 |
-
transition: all 0.2s ease !important;
|
| 672 |
-
}
|
| 673 |
-
|
| 674 |
-
button:hover, .gr-button:hover {
|
| 675 |
-
transform: translateY(-1px);
|
| 676 |
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;
|
| 677 |
-
}
|
| 678 |
-
|
| 679 |
-
/* Better spacing */
|
| 680 |
-
.gradio-container {
|
| 681 |
-
max-width: 1400px !important;
|
| 682 |
-
margin: 0 auto !important;
|
| 683 |
-
}
|
| 684 |
-
|
| 685 |
-
/* Hide the conflict-check API components (no visible UI) */
|
| 686 |
-
.hidden_conflict {
|
| 687 |
-
display: none !important;
|
| 688 |
-
}
|
| 689 |
-
""",
|
| 690 |
-
footer_links=[
|
| 691 |
-
"api",
|
| 692 |
-
"gradio"
|
| 693 |
-
],
|
| 694 |
-
mcp_server=True
|
| 695 |
-
)
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
HuggingFace Model Playground
|
| 3 |
+
- Input any HF model ID → auto-detects task → shows suitable UI
|
| 4 |
+
- Text gen (chat/completion/translate), summarization, translation, image gen, TTS
|
| 5 |
+
- Thinking model support (DeepSeek-R1, QwQ, etc.)
|
| 6 |
+
- Quick-select presets for popular models
|
| 7 |
+
"""
|
| 8 |
+
import spaces # MUST be first — signals ZeroGPU to allocate GPU worker
|
| 9 |
+
|
| 10 |
import gradio as gr
|
| 11 |
+
import torch
|
| 12 |
import os
|
| 13 |
+
import re
|
| 14 |
+
import json
|
| 15 |
+
import threading
|
| 16 |
+
import queue
|
| 17 |
+
import time
|
| 18 |
+
import traceback
|
| 19 |
+
import numpy as np
|
| 20 |
+
import asyncio
|
| 21 |
+
import sys
|
| 22 |
+
from typing import Optional, Dict, Any, List, Tuple, Generator
|
| 23 |
+
from huggingface_hub import HfApi
|
| 24 |
+
|
| 25 |
+
from transformers import (
|
| 26 |
+
AutoConfig, AutoTokenizer, AutoModelForCausalLM, AutoModelForSeq2SeqLM,
|
| 27 |
+
pipeline as hf_pipeline, set_seed, TextIteratorStreamer
|
| 28 |
)
|
| 29 |
+
from diffusers import DiffusionPipeline
|
|
|
|
|
|
|
|
|
|
| 30 |
|
| 31 |
+
# Python 3.10 asyncio cleanup fix: suppress "Invalid file descriptor: -1" on shutdown
|
| 32 |
+
# https://bugs.python.org/issue46370
|
| 33 |
+
if sys.version_info >= (3, 10) and sys.platform == 'linux':
|
| 34 |
+
try:
|
| 35 |
+
_cls = asyncio.selector_events.BaseSelectorEventLoop
|
| 36 |
+
_orig = _cls._close_self_pipe
|
| 37 |
+
def _safe_close_self_pipe(self):
|
| 38 |
+
try:
|
| 39 |
+
_orig(self)
|
| 40 |
+
except ValueError:
|
| 41 |
+
pass
|
| 42 |
+
_cls._close_self_pipe = _safe_close_self_pipe
|
| 43 |
+
except Exception:
|
| 44 |
+
pass
|
| 45 |
|
| 46 |
+
torch.set_grad_enabled(False)
|
| 47 |
|
| 48 |
+
# ── GPU Workers (must be module-level @spaces.GPU) ──
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
|
| 50 |
+
@spaces.GPU
|
| 51 |
+
def gpu_text_generate(model_id: str, messages: list, gen_kwargs: dict):
|
| 52 |
+
"""Text generation on GPU. Model is cached in the GPU worker across calls."""
|
| 53 |
+
import torch as _torch
|
| 54 |
+
from transformers import AutoModelForCausalLM as _AutoModelForCausalLM
|
| 55 |
+
from transformers import AutoTokenizer as _AutoTokenizer
|
| 56 |
+
from transformers import TextIteratorStreamer as _TextIteratorStreamer
|
| 57 |
+
from threading import Thread as _Thread
|
| 58 |
+
|
| 59 |
+
cache = gpu_text_generate.__dict__.setdefault('_cache', {})
|
| 60 |
+
if model_id not in cache:
|
| 61 |
+
tok = _AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
|
| 62 |
+
if tok.pad_token is None:
|
| 63 |
+
tok.pad_token = tok.eos_token
|
| 64 |
+
model = _AutoModelForCausalLM.from_pretrained(
|
| 65 |
+
model_id, torch_dtype=_torch.bfloat16, device_map="auto",
|
| 66 |
+
low_cpu_mem_usage=True, trust_remote_code=True,
|
| 67 |
+
)
|
| 68 |
+
model.eval()
|
| 69 |
+
cache[model_id] = (model, tok)
|
| 70 |
|
| 71 |
+
model, tokenizer = cache[model_id]
|
| 72 |
+
prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
|
| 73 |
+
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
|
| 74 |
+
streamer = _TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
|
| 75 |
+
kw = {**gen_kwargs, "streamer": streamer}
|
| 76 |
+
_Thread(target=model.generate, args=(inputs.input_ids,), kwargs=kw).start()
|
| 77 |
+
for text in streamer:
|
| 78 |
+
yield text
|
| 79 |
|
|
|
|
| 80 |
|
| 81 |
+
@spaces.GPU
|
| 82 |
+
def gpu_image_generate(model_id: str, prompt: str, height: int, width: int, steps: int, seed: int):
|
| 83 |
+
"""Image generation on GPU."""
|
| 84 |
+
import torch as _torch
|
| 85 |
+
from diffusers import DiffusionPipeline as _DP
|
| 86 |
+
|
| 87 |
+
pipe = _DP.from_pretrained(
|
| 88 |
+
model_id, torch_dtype=_torch.bfloat16, low_cpu_mem_usage=True,
|
| 89 |
+
)
|
| 90 |
+
pipe.to("cuda")
|
| 91 |
+
if hasattr(pipe, "enable_attention_slicing"):
|
| 92 |
+
pipe.enable_attention_slicing()
|
| 93 |
+
gen = _torch.Generator("cuda").manual_seed(seed)
|
| 94 |
+
result = pipe(prompt=prompt, height=height, width=width,
|
| 95 |
+
num_inference_steps=steps, generator=gen)
|
| 96 |
+
return result.images[0]
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
@spaces.GPU
|
| 100 |
+
def gpu_image_generate_stream(model_id: str, prompt: str, height: int, width: int,
|
| 101 |
+
steps: int, seed: int):
|
| 102 |
+
"""Image generation on GPU with step-by-step preview."""
|
| 103 |
+
import torch as _torch
|
| 104 |
+
from diffusers import DiffusionPipeline as _DP
|
| 105 |
+
from PIL import Image as _Image
|
| 106 |
+
import io as _io
|
| 107 |
+
import queue as _queue
|
| 108 |
+
import threading as _threading
|
| 109 |
+
|
| 110 |
+
pipe = _DP.from_pretrained(
|
| 111 |
+
model_id, torch_dtype=_torch.bfloat16, low_cpu_mem_usage=True,
|
| 112 |
+
)
|
| 113 |
+
pipe.to("cuda")
|
| 114 |
+
if hasattr(pipe, "enable_attention_slicing"):
|
| 115 |
+
pipe.enable_attention_slicing()
|
| 116 |
+
|
| 117 |
+
has_vae = hasattr(pipe, "vae") and hasattr(pipe, "image_processor")
|
| 118 |
+
gen = _torch.Generator("cuda").manual_seed(seed)
|
| 119 |
+
previews = _queue.Queue()
|
| 120 |
step_counter = {"i": 0}
|
| 121 |
|
| 122 |
+
def decode_latents(latents):
|
| 123 |
+
l = latents.to(pipe.vae.dtype)
|
| 124 |
+
sf = pipe.vae.config.scaling_factor
|
| 125 |
+
sh = getattr(pipe.vae.config, "shift_factor", None) or 0
|
| 126 |
+
l = (l / sf) + sh
|
| 127 |
+
with _torch.no_grad():
|
| 128 |
+
img = pipe.vae.decode(l, return_dict=False)[0]
|
| 129 |
+
return pipe.image_processor.postprocess(img, output_type="pil")[0]
|
| 130 |
+
|
| 131 |
+
def cb(pipe, i, t, kw):
|
| 132 |
step_counter["i"] += 1
|
| 133 |
+
if has_vae and "latents" in kw:
|
| 134 |
+
try:
|
| 135 |
+
previews.put((decode_latents(kw["latents"]), step_counter["i"]))
|
| 136 |
+
except Exception:
|
| 137 |
+
pass
|
| 138 |
+
return kw
|
| 139 |
|
| 140 |
result = {}
|
| 141 |
+
exc = {}
|
| 142 |
|
| 143 |
def run():
|
| 144 |
try:
|
| 145 |
+
kw = dict(prompt=prompt, height=height, width=width,
|
| 146 |
+
num_inference_steps=steps, generator=gen)
|
| 147 |
+
if has_vae:
|
| 148 |
+
kw["output_type"] = "latent"
|
| 149 |
+
kw["callback_on_step_end"] = cb
|
| 150 |
+
kw["callback_on_step_end_tensor_inputs"] = ["latents"]
|
| 151 |
+
out = pipe(**kw)
|
| 152 |
+
result["img"] = decode_latents(out.images) if has_vae else out.images[0]
|
| 153 |
+
previews.put(None)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
except Exception as e:
|
| 155 |
+
exc["e"] = e
|
| 156 |
previews.put(None)
|
| 157 |
|
| 158 |
+
_threading.Thread(target=run).start()
|
|
|
|
|
|
|
| 159 |
last = None
|
| 160 |
while True:
|
| 161 |
item = previews.get()
|
|
|
|
| 163 |
break
|
| 164 |
img, step = item
|
| 165 |
last = img
|
| 166 |
+
yield img, seed, f"Step {step}/{steps}"
|
| 167 |
+
|
| 168 |
+
if "e" in exc:
|
| 169 |
+
raise exc["e"]
|
| 170 |
+
yield result.get("img", last), seed, f"Done ({steps} steps)"
|
| 171 |
+
|
| 172 |
+
|
| 173 |
+
_gpu_flag = False
|
| 174 |
+
_cancel_flag = [False]
|
| 175 |
+
|
| 176 |
+
def _use_gpu() -> bool:
|
| 177 |
+
return _gpu_flag
|
| 178 |
+
|
| 179 |
+
def _set_gpu_flag(val: bool):
|
| 180 |
+
global _gpu_flag
|
| 181 |
+
_gpu_flag = val
|
| 182 |
+
|
| 183 |
+
# ============================================================
|
| 184 |
+
# CONSTANTS
|
| 185 |
+
# ============================================================
|
| 186 |
+
|
| 187 |
+
|
| 188 |
+
ARCH_TASK_MAP: Dict[str, str] = {
|
| 189 |
+
"LlamaForCausalLM": "text-generation",
|
| 190 |
+
"GPT2LMHeadModel": "text-generation",
|
| 191 |
+
"PhiForCausalLM": "text-generation",
|
| 192 |
+
"Phi3ForCausalLM": "text-generation",
|
| 193 |
+
"Phi3SmallForCausalLM": "text-generation",
|
| 194 |
+
"GemmaForCausalLM": "text-generation",
|
| 195 |
+
"Gemma2ForCausalLM": "text-generation",
|
| 196 |
+
"Gemma3ForCausalLM": "text-generation",
|
| 197 |
+
"Qwen2ForCausalLM": "text-generation",
|
| 198 |
+
"Qwen2MoeForCausalLM": "text-generation",
|
| 199 |
+
"MistralForCausalLM": "text-generation",
|
| 200 |
+
"MixtralForCausalLM": "text-generation",
|
| 201 |
+
"OPTForCausalLM": "text-generation",
|
| 202 |
+
"BloomForCausalLM": "text-generation",
|
| 203 |
+
"StableLmForCausalLM": "text-generation",
|
| 204 |
+
"FalconForCausalLM": "text-generation",
|
| 205 |
+
"GPTNeoXForCausalLM": "text-generation",
|
| 206 |
+
"DeepseekForCausalLM": "text-generation",
|
| 207 |
+
"DeepseekV2ForCausalLM": "text-generation",
|
| 208 |
+
"DeepseekV3ForCausalLM": "text-generation",
|
| 209 |
+
"OlmoForCausalLM": "text-generation",
|
| 210 |
+
"CohereForCausalLM": "text-generation",
|
| 211 |
+
"DbrxForCausalLM": "text-generation",
|
| 212 |
+
"MptForCausalLM": "text-generation",
|
| 213 |
+
"Starcoder2ForCausalLM": "text-generation",
|
| 214 |
+
"XGLMForCausalLM": "text-generation",
|
| 215 |
+
"PhiMoEForCausalLM": "text-generation",
|
| 216 |
+
"GraniteForCausalLM": "text-generation",
|
| 217 |
+
"GraniteMoeForCausalLM": "text-generation",
|
| 218 |
+
"ExaoneForCausalLM": "text-generation",
|
| 219 |
+
"RWForCausalLM": "text-generation",
|
| 220 |
+
"LlavaForConditionalGeneration": "text-generation",
|
| 221 |
+
"Qwen2VLForConditionalGeneration": "text-generation",
|
| 222 |
+
"T5ForConditionalGeneration": "text2text-generation",
|
| 223 |
+
"FlanT5ForConditionalGeneration": "text2text-generation",
|
| 224 |
+
"BartForConditionalGeneration": "summarization",
|
| 225 |
+
"PegasusForConditionalGeneration": "summarization",
|
| 226 |
+
"LongT5ForConditionalGeneration": "summarization",
|
| 227 |
+
"LEDForConditionalGeneration": "summarization",
|
| 228 |
+
"MarianMTModel": "translation",
|
| 229 |
+
"M2M100ForConditionalGeneration": "translation",
|
| 230 |
+
"NLLBForConditionalGeneration": "translation",
|
| 231 |
+
"NLLBMoeForConditionalGeneration": "translation",
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
DIFFUSION_ARCHS = {
|
| 235 |
+
"StableDiffusionPipeline", "StableDiffusionXLPipeline", "FluxPipeline",
|
| 236 |
+
"FluxFillPipeline", "LatentConsistencyModelPipeline",
|
| 237 |
+
"StableDiffusion3Pipeline", "WuerstchenPipeline",
|
| 238 |
+
"KandinskyPipeline", "KandinskyV22Pipeline",
|
| 239 |
+
"PixArtAlphaPipeline", "PixArtSigmaPipeline",
|
| 240 |
+
"StableCascadeCombinedPipeline", "CogView4Pipeline",
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
TTS_ARCHS = {
|
| 244 |
+
"SpeechT5ForTextToSpeech", "BarkModel", "BarkCausalModel",
|
| 245 |
+
"VitsModel", "MmsTextToSpeech", "MusicgenForConditionalGeneration",
|
| 246 |
+
}
|
| 247 |
+
|
| 248 |
+
THINKING_PATTERNS = [re.compile(p) for p in [
|
| 249 |
+
r"deepseek.*r1", r"qwq", r"thinking", r"reasoning", r"r1-distill",
|
| 250 |
+
]]
|
| 251 |
+
|
| 252 |
+
PIPELINE_TAG_MAP = {
|
| 253 |
+
"text-generation": "text-generation",
|
| 254 |
+
"text2text-generation": "text2text-generation",
|
| 255 |
+
"summarization": "summarization",
|
| 256 |
+
"translation": "translation",
|
| 257 |
+
"text-to-image": "image-generation",
|
| 258 |
+
"image-to-image": "image-generation",
|
| 259 |
+
"image-segmentation": "image-generation",
|
| 260 |
+
"text-to-speech": "text-to-speech",
|
| 261 |
+
"fill-mask": "text-generation",
|
| 262 |
+
"feature-extraction": "text-generation",
|
| 263 |
+
}
|
| 264 |
+
|
| 265 |
+
TASK_UI_ORDER = ["text-generation", "text2text-generation", "summarization",
|
| 266 |
+
"translation", "image-generation", "text-to-speech"]
|
| 267 |
+
|
| 268 |
+
# ============================================================
|
| 269 |
+
# MODEL STATE
|
| 270 |
+
# ============================================================
|
| 271 |
+
|
| 272 |
+
_model_lock = threading.Lock()
|
| 273 |
+
_state = {
|
| 274 |
+
"model_id": None, "task": None, "pipeline": None,
|
| 275 |
+
"tokenizer": None, "model": None, "config": None,
|
| 276 |
+
"processor": None, "vocoder": None, "is_thinking": False,
|
| 277 |
+
"model_info": None, "device": "cpu",
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
|
| 281 |
+
def _is_thinking(model_id: str) -> bool:
|
| 282 |
+
return any(p.search(model_id.lower()) for p in THINKING_PATTERNS)
|
| 283 |
+
|
| 284 |
+
|
| 285 |
+
def _clear_state():
|
| 286 |
+
for k in list(_state.keys()):
|
| 287 |
+
v = _state[k]
|
| 288 |
+
if v is not None and hasattr(v, "__del__"):
|
| 289 |
+
try:
|
| 290 |
+
del v
|
| 291 |
+
except Exception:
|
| 292 |
+
pass
|
| 293 |
+
_state[k] = None
|
| 294 |
+
_state["model_id"] = None
|
| 295 |
+
_state["is_thinking"] = False
|
| 296 |
+
if torch.cuda.is_available():
|
| 297 |
+
torch.cuda.empty_cache()
|
| 298 |
+
|
| 299 |
+
|
| 300 |
+
# ============================================================
|
| 301 |
+
# MODEL DETECTION
|
| 302 |
+
# ============================================================
|
| 303 |
+
|
| 304 |
+
def detect_task(model_id: str) -> str:
|
| 305 |
+
try:
|
| 306 |
+
info = HfApi().model_info(model_id, timeout=10)
|
| 307 |
+
_state["model_info"] = info
|
| 308 |
+
tag = info.pipeline_tag
|
| 309 |
+
if tag and tag in PIPELINE_TAG_MAP:
|
| 310 |
+
return PIPELINE_TAG_MAP[tag]
|
| 311 |
+
except Exception:
|
| 312 |
+
pass
|
| 313 |
+
try:
|
| 314 |
+
config = AutoConfig.from_pretrained(model_id, trust_remote_code=True)
|
| 315 |
+
_state["config"] = config
|
| 316 |
+
archs = config.architectures or []
|
| 317 |
+
for arch in archs:
|
| 318 |
+
if arch in ARCH_TASK_MAP:
|
| 319 |
+
return ARCH_TASK_MAP[arch]
|
| 320 |
+
if arch in DIFFUSION_ARCHS:
|
| 321 |
+
return "image-generation"
|
| 322 |
+
if arch in TTS_ARCHS:
|
| 323 |
+
return "text-to-speech"
|
| 324 |
+
mt = getattr(config, "model_type", "")
|
| 325 |
+
if mt in ("llama", "gpt2", "phi", "phi3", "gemma", "gemma2",
|
| 326 |
+
"qwen2", "mistral", "mixtral", "opt", "bloom",
|
| 327 |
+
"falcon", "gpt_neox", "deepseek", "olmo", "cohere",
|
| 328 |
+
"stablelm", "mpt", "starcoder2", "exaone", "dbrx"):
|
| 329 |
+
return "text-generation"
|
| 330 |
+
if mt in ("t5", "mt5", "bart", "pegasus", "longt5", "led"):
|
| 331 |
+
return "text2text-generation"
|
| 332 |
+
if mt in ("marian", "m2m_100", "nllb"):
|
| 333 |
+
return "translation"
|
| 334 |
+
if mt in ("speecht5", "bark", "vits", "mms"):
|
| 335 |
+
return "text-to-speech"
|
| 336 |
+
except Exception:
|
| 337 |
+
pass
|
| 338 |
+
# Diffusers fallback: check model_index.json (hallmark of diffusers pipelines)
|
| 339 |
+
try:
|
| 340 |
+
from huggingface_hub import hf_hub_url
|
| 341 |
+
import requests as _req
|
| 342 |
+
r = _req.get(hf_hub_url(model_id, "model_index.json"), timeout=5)
|
| 343 |
+
if r.status_code == 200:
|
| 344 |
+
return "image-generation"
|
| 345 |
+
except Exception:
|
| 346 |
+
pass
|
| 347 |
+
return "text-generation"
|
| 348 |
+
|
| 349 |
+
|
| 350 |
+
# ============================================================
|
| 351 |
+
# MODEL LOADING
|
| 352 |
+
# ============================================================
|
| 353 |
+
|
| 354 |
+
def load_model(model_id: str, progress=gr.Progress()):
|
| 355 |
+
with _model_lock:
|
| 356 |
+
if _state["model_id"] == model_id and _state["model"] is not None:
|
| 357 |
+
return _build_load_result()
|
| 358 |
+
_clear_state()
|
| 359 |
+
|
| 360 |
+
progress(0, desc="Detecting model type...")
|
| 361 |
+
task = detect_task(model_id)
|
| 362 |
+
is_thinking = _is_thinking(model_id)
|
| 363 |
+
|
| 364 |
+
try:
|
| 365 |
+
if task in ("text-generation", "text2text-generation", "summarization", "translation"):
|
| 366 |
+
_load_text_model(model_id, task, progress)
|
| 367 |
+
elif task == "image-generation":
|
| 368 |
+
_load_image_model(model_id, progress)
|
| 369 |
+
elif task == "text-to-speech":
|
| 370 |
+
_load_tts_model(model_id, progress)
|
| 371 |
+
else:
|
| 372 |
+
_load_text_model(model_id, "text-generation", progress)
|
| 373 |
+
|
| 374 |
+
_state["task"] = task
|
| 375 |
+
_state["is_thinking"] = is_thinking
|
| 376 |
+
_state["model_id"] = model_id
|
| 377 |
+
except Exception as e:
|
| 378 |
+
_clear_state()
|
| 379 |
+
raise gr.Error(f"Load failed: {e}\n{traceback.format_exc()}")
|
| 380 |
+
|
| 381 |
+
return _build_load_result()
|
| 382 |
+
|
| 383 |
+
|
| 384 |
+
def _build_load_result():
|
| 385 |
+
info = _state["model_info"]
|
| 386 |
+
parts = []
|
| 387 |
+
if info:
|
| 388 |
+
if getattr(info, "author", None):
|
| 389 |
+
parts.append(f"**Author:** {info.author}")
|
| 390 |
+
if getattr(info, "pipeline_tag", None):
|
| 391 |
+
parts.append(f"**Task:** {info.pipeline_tag}")
|
| 392 |
+
parts.append(f"**Detected:** {_state['task']}")
|
| 393 |
+
if _state["is_thinking"]:
|
| 394 |
+
parts.append("🧠 **Thinking Model**")
|
| 395 |
+
return _state["task"], _state["is_thinking"], " · ".join(parts)
|
| 396 |
+
|
| 397 |
+
|
| 398 |
+
def _load_text_model(model_id: str, task: str, progress):
|
| 399 |
+
progress(0.2, desc="Loading tokenizer...")
|
| 400 |
+
tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
|
| 401 |
+
if tokenizer.pad_token is None:
|
| 402 |
+
tokenizer.pad_token = tokenizer.eos_token
|
| 403 |
+
|
| 404 |
+
progress(0.4, desc="Loading model...")
|
| 405 |
+
if task == "text-generation":
|
| 406 |
+
model = AutoModelForCausalLM.from_pretrained(
|
| 407 |
+
model_id, torch_dtype=torch.bfloat16,
|
| 408 |
+
low_cpu_mem_usage=True, trust_remote_code=True,
|
| 409 |
+
)
|
| 410 |
+
else:
|
| 411 |
+
model = AutoModelForSeq2SeqLM.from_pretrained(
|
| 412 |
+
model_id, torch_dtype=torch.bfloat16,
|
| 413 |
+
low_cpu_mem_usage=True, trust_remote_code=True,
|
| 414 |
+
)
|
| 415 |
+
|
| 416 |
+
# Always load on CPU for the fallback path.
|
| 417 |
+
# GPU inference goes through @spaces.GPU workers which handle CUDA internally.
|
| 418 |
+
model.to("cpu")
|
| 419 |
+
model.eval()
|
| 420 |
+
|
| 421 |
+
progress(0.8, desc="Ready!")
|
| 422 |
+
_state["model"] = model
|
| 423 |
+
_state["tokenizer"] = tokenizer
|
| 424 |
+
_state["device"] = "cpu"
|
| 425 |
+
|
| 426 |
+
|
| 427 |
+
def _load_image_model(model_id: str, progress):
|
| 428 |
+
progress(0.3, desc="Loading image model...")
|
| 429 |
+
pipe = DiffusionPipeline.from_pretrained(
|
| 430 |
+
model_id, torch_dtype=torch.bfloat16, low_cpu_mem_usage=True,
|
| 431 |
+
)
|
| 432 |
+
pipe.to("cpu")
|
| 433 |
+
pipe.enable_attention_slicing()
|
| 434 |
+
progress(0.8, desc="Ready!")
|
| 435 |
+
_state["pipeline"] = pipe
|
| 436 |
+
_state["device"] = "cpu"
|
| 437 |
+
|
| 438 |
+
|
| 439 |
+
def _load_tts_model(model_id: str, progress):
|
| 440 |
+
import torch as _torch
|
| 441 |
+
if "speecht5" in model_id.lower():
|
| 442 |
+
progress(0.3, desc="Loading SpeechT5 model...")
|
| 443 |
+
from transformers import AutoTokenizer as _AT
|
| 444 |
+
from transformers import SpeechT5ForTextToSpeech as _SFTTS
|
| 445 |
+
tokenizer = _AT.from_pretrained(model_id)
|
| 446 |
+
model = _SFTTS.from_pretrained(model_id)
|
| 447 |
+
model.eval()
|
| 448 |
+
progress(0.5, desc="Loading speaker embedding...")
|
| 449 |
+
speaker_embeddings = None
|
| 450 |
+
try:
|
| 451 |
+
from datasets import load_dataset as _load_ds
|
| 452 |
+
emb_ds = _load_ds("Matthijs/cmu-arctic-xvectors", split="training")
|
| 453 |
+
speaker_embeddings = _torch.tensor(emb_ds[7306]["xvector"]).unsqueeze(0)
|
| 454 |
+
except Exception:
|
| 455 |
+
speaker_embeddings = _torch.zeros((1, 512))
|
| 456 |
+
progress(0.8, desc="Ready!")
|
| 457 |
+
_state["model"] = model
|
| 458 |
+
_state["tokenizer"] = tokenizer
|
| 459 |
+
_state["speaker_embeddings"] = speaker_embeddings
|
| 460 |
+
_state["pipeline"] = None
|
| 461 |
+
_state["device"] = "cpu"
|
| 462 |
+
else:
|
| 463 |
+
progress(0.3, desc="Loading TTS model...")
|
| 464 |
+
pipe = hf_pipeline("text-to-speech", model=model_id, device=-1)
|
| 465 |
+
progress(0.8, desc="Ready!")
|
| 466 |
+
_state["pipeline"] = pipe
|
| 467 |
+
_state["device"] = "cpu"
|
| 468 |
+
|
| 469 |
+
|
| 470 |
+
# ============================================================
|
| 471 |
+
# GENERATION HELPERS
|
| 472 |
+
# ============================================================
|
| 473 |
+
|
| 474 |
+
def _gen_kwargs(max_tokens, temperature, top_p, top_k, repetition, sample):
|
| 475 |
+
return {
|
| 476 |
+
"max_new_tokens": int(max_tokens),
|
| 477 |
+
"temperature": float(temperature),
|
| 478 |
+
"top_p": float(top_p),
|
| 479 |
+
"top_k": int(top_k) if top_k > 0 else None,
|
| 480 |
+
"repetition_penalty": float(repetition),
|
| 481 |
+
"do_sample": bool(sample),
|
| 482 |
+
}
|
| 483 |
+
|
| 484 |
+
PRESET_CHOICES = [
|
| 485 |
+
("💬 gemma-3-1b-it", "google/gemma-3-1b-it"),
|
| 486 |
+
("💬 Qwen3-4B-Instruct", "Qwen/Qwen3-4B-Instruct-2507"),
|
| 487 |
+
("💬 Phi-4-mini", "microsoft/Phi-4-mini-instruct"),
|
| 488 |
+
("💬 SmolLM3-3B", "HuggingFaceTB/SmolLM3-3B"),
|
| 489 |
+
("💬 Qwen2.5-3B", "Qwen/Qwen2.5-3B-Instruct"),
|
| 490 |
+
("💬 LFM2.5-1.2B", "LiquidAI/LFM2.5-1.2B-Instruct"),
|
| 491 |
+
("🧠 DeepSeek-R1-1.5B", "deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B"),
|
| 492 |
+
("🧠 Qwen3-4B-Thinking", "Qwen/Qwen3-4B-Thinking-2507"),
|
| 493 |
+
("🧠 Gemma-2-2B", "google/gemma-2-2b-it"),
|
| 494 |
+
("🧠 LFM2.5-1.2B-Thinking", "LiquidAI/LFM2.5-1.2B-Thinking"),
|
| 495 |
+
("🔤 FLAN-T5-Small", "google/flan-t5-small"),
|
| 496 |
+
("🔤 FLAN-T5-Base", "google/flan-t5-base"),
|
| 497 |
+
("📝 BART-Large-CNN", "facebook/bart-large-cnn"),
|
| 498 |
+
("🌐 OPUS-EN→ES", "Helsinki-NLP/opus-mt-en-es"),
|
| 499 |
+
("🌐 OPUS-EN→FR", "Helsinki-NLP/opus-mt-en-fr"),
|
| 500 |
+
("🌐 NLLB-600M", "facebook/nllb-200-distilled-600M"),
|
| 501 |
+
("🎨 Z-Image-Turbo", "Tongyi-MAI/Z-Image-Turbo"),
|
| 502 |
+
("🎨 SD1.5", "runwayml/stable-diffusion-v1-5"),
|
| 503 |
+
("🎨 SDXL-Turbo", "stabilityai/sdxl-turbo"),
|
| 504 |
+
("🔊 SpeechT5", "microsoft/speecht5_tts"),
|
| 505 |
+
("🔊 Bark-Small", "suno/bark-small"),
|
| 506 |
+
("🔊 MMS-TTS-ENG", "facebook/mms-tts-eng"),
|
| 507 |
+
("🔊 Bark", "suno/bark"),
|
| 508 |
+
]
|
| 509 |
+
|
| 510 |
+
|
| 511 |
+
def _apply_template(tokenizer, messages, is_thinking=False):
|
| 512 |
+
try:
|
| 513 |
+
kwargs = {"tokenize": False, "add_generation_prompt": True}
|
| 514 |
+
if is_thinking:
|
| 515 |
+
try:
|
| 516 |
+
kwargs["enable_thinking"] = True
|
| 517 |
+
except TypeError:
|
| 518 |
+
pass
|
| 519 |
+
return tokenizer.apply_chat_template(messages, **kwargs)
|
| 520 |
+
except Exception:
|
| 521 |
+
return messages[-1]["content"]
|
| 522 |
+
|
| 523 |
+
|
| 524 |
+
def _stream(model, tokenizer, prompt, kwargs):
|
| 525 |
+
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
|
| 526 |
+
streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
|
| 527 |
+
kwargs["streamer"] = streamer
|
| 528 |
+
t = threading.Thread(target=model.generate, args=(inputs.input_ids,), kwargs=kwargs)
|
| 529 |
+
t.start()
|
| 530 |
+
for text in streamer:
|
| 531 |
+
yield text
|
| 532 |
+
|
| 533 |
+
|
| 534 |
+
# ============================================================
|
| 535 |
+
# INFERENCE FUNCTIONS
|
| 536 |
+
# ============================================================
|
| 537 |
+
|
| 538 |
+
def _build_messages(history, message, system_prompt):
|
| 539 |
+
msgs = [{"role": "system", "content": system_prompt or "You are a helpful assistant."}]
|
| 540 |
+
if history:
|
| 541 |
+
msgs.extend(history)
|
| 542 |
+
msgs.append({"role": "user", "content": message})
|
| 543 |
+
return msgs
|
| 544 |
+
|
| 545 |
+
|
| 546 |
+
def chat_respond(message, history, system_prompt, max_tokens, temperature,
|
| 547 |
+
top_p, top_k, repetition, sample, thinking):
|
| 548 |
+
s = _state
|
| 549 |
+
if s["model"] is None:
|
| 550 |
+
raise gr.Error("No model loaded.")
|
| 551 |
+
history = history or []
|
| 552 |
+
is_thinking = thinking if thinking is not None else s["is_thinking"]
|
| 553 |
+
msgs = _build_messages(history, message, system_prompt)
|
| 554 |
+
kwargs = _gen_kwargs(max_tokens, temperature, top_p, top_k, repetition, sample)
|
| 555 |
+
history.append({"role": "user", "content": message})
|
| 556 |
+
history.append({"role": "assistant", "content": ""})
|
| 557 |
+
|
| 558 |
+
if _use_gpu() and s["task"] == "text-generation":
|
| 559 |
+
for chunk in gpu_text_generate(s["model_id"], msgs, kwargs):
|
| 560 |
+
history[-1]["content"] = chunk
|
| 561 |
+
yield history, ""
|
| 562 |
+
else:
|
| 563 |
+
prompt = _apply_template(s["tokenizer"], msgs, is_thinking)
|
| 564 |
+
full = ""
|
| 565 |
+
for chunk in _stream(s["model"], s["tokenizer"], prompt, kwargs):
|
| 566 |
+
full += chunk
|
| 567 |
+
history[-1]["content"] = full
|
| 568 |
+
yield history, ""
|
| 569 |
+
yield history, ""
|
| 570 |
+
|
| 571 |
+
|
| 572 |
+
def completion_fn(prompt, max_tokens, temperature,
|
| 573 |
+
top_p, top_k, repetition, sample, thinking):
|
| 574 |
+
s = _state
|
| 575 |
+
if s["model"] is None:
|
| 576 |
+
raise gr.Error("No model loaded.")
|
| 577 |
+
kwargs = _gen_kwargs(max_tokens, temperature, top_p, top_k, repetition, sample)
|
| 578 |
+
_cancel_flag[0] = False
|
| 579 |
+
|
| 580 |
+
if _use_gpu() and s["task"] == "text-generation":
|
| 581 |
+
msgs = [{"role": "user", "content": prompt}]
|
| 582 |
+
full = prompt + "\n"
|
| 583 |
+
for chunk in gpu_text_generate(s["model_id"], msgs, kwargs):
|
| 584 |
+
if _cancel_flag[0]:
|
| 585 |
+
break
|
| 586 |
+
full += chunk
|
| 587 |
+
yield full
|
| 588 |
+
else:
|
| 589 |
+
full = prompt
|
| 590 |
+
for chunk in _stream(s["model"], s["tokenizer"], prompt, kwargs):
|
| 591 |
+
if _cancel_flag[0]:
|
| 592 |
+
break
|
| 593 |
+
full += chunk
|
| 594 |
+
yield full
|
| 595 |
+
|
| 596 |
+
|
| 597 |
+
def translate_fn(text, src_lang, tgt_lang, max_tokens, temperature,
|
| 598 |
+
top_p, top_k, repetition, sample, thinking):
|
| 599 |
+
s = _state
|
| 600 |
+
if s["model"] is None:
|
| 601 |
+
raise gr.Error("No model loaded.")
|
| 602 |
+
is_thinking = thinking if thinking is not None else s["is_thinking"]
|
| 603 |
+
kwargs = _gen_kwargs(max_tokens, temperature, top_p, top_k, repetition, sample)
|
| 604 |
+
|
| 605 |
+
if _use_gpu() and s["task"] == "text-generation":
|
| 606 |
+
sp = f"Translate {src_lang} to {tgt_lang}. Output only the translation."
|
| 607 |
+
msgs = [{"role": "system", "content": sp}, {"role": "user", "content": text}]
|
| 608 |
+
for chunk in gpu_text_generate(s["model_id"], msgs, kwargs):
|
| 609 |
+
yield chunk
|
| 610 |
+
return
|
| 611 |
+
|
| 612 |
+
if s["task"] == "translation":
|
| 613 |
+
prompt = text
|
| 614 |
+
else:
|
| 615 |
+
sp = f"Translate {src_lang} to {tgt_lang}. Output only the translation."
|
| 616 |
+
if s["tokenizer"].chat_template:
|
| 617 |
+
msgs = [{"role": "system", "content": sp}, {"role": "user", "content": text}]
|
| 618 |
+
prompt = _apply_template(s["tokenizer"], msgs, is_thinking)
|
| 619 |
+
else:
|
| 620 |
+
prompt = f"{sp}\n\n{text}"
|
| 621 |
+
full = ""
|
| 622 |
+
for chunk in _stream(s["model"], s["tokenizer"], prompt, kwargs):
|
| 623 |
+
full += chunk
|
| 624 |
+
yield full
|
| 625 |
+
|
| 626 |
+
|
| 627 |
+
def summarize_fn(text, max_tokens, temperature, top_p, top_k, repetition, sample):
|
| 628 |
+
s = _state
|
| 629 |
+
if s["model"] is None:
|
| 630 |
+
raise gr.Error("No model loaded.")
|
| 631 |
+
kwargs = _gen_kwargs(max_tokens, temperature, top_p, top_k, repetition, sample)
|
| 632 |
+
if s["tokenizer"].chat_template:
|
| 633 |
+
msgs = [{"role": "user", "content": f"Summarize:\n\n{text}"}]
|
| 634 |
+
prompt = _apply_template(s["tokenizer"], msgs)
|
| 635 |
+
else:
|
| 636 |
+
prompt = f"Summarize the following:\n\n{text}\n\nSummary:"
|
| 637 |
+
full = ""
|
| 638 |
+
for chunk in _stream(s["model"], s["tokenizer"], prompt, kwargs):
|
| 639 |
+
full += chunk
|
| 640 |
+
yield full
|
| 641 |
+
|
| 642 |
+
|
| 643 |
+
# --- Image Generation ---
|
| 644 |
+
|
| 645 |
+
_img_lock = threading.Lock()
|
| 646 |
+
_img_interrupt = None
|
| 647 |
+
|
| 648 |
+
|
| 649 |
+
def _decode_latents(latents, pipe):
|
| 650 |
+
l = latents.to(pipe.vae.dtype)
|
| 651 |
+
sf = pipe.vae.config.scaling_factor
|
| 652 |
+
sh = getattr(pipe.vae.config, "shift_factor", None) or 0
|
| 653 |
+
l = (l / sf) + sh
|
| 654 |
+
with torch.no_grad():
|
| 655 |
+
img = pipe.vae.decode(l, return_dict=False)[0]
|
| 656 |
+
return pipe.image_processor.postprocess(img, output_type="pil")[0]
|
| 657 |
+
|
| 658 |
+
|
| 659 |
+
def generate_image(prompt, height, width, steps, seed, randomize, progress=gr.Progress(track_tqdm=True)):
|
| 660 |
+
global _img_interrupt
|
| 661 |
+
s = _state
|
| 662 |
+
model_id = s["model_id"]
|
| 663 |
+
|
| 664 |
+
if _use_gpu() and model_id:
|
| 665 |
+
if randomize:
|
| 666 |
+
seed = torch.randint(0, 2**32 - 1, (1,)).item()
|
| 667 |
+
for img, used_seed, status in gpu_image_generate_stream(
|
| 668 |
+
model_id, prompt, int(height), int(width), int(steps), int(seed),
|
| 669 |
+
):
|
| 670 |
+
yield img, used_seed, status
|
| 671 |
+
return
|
| 672 |
+
|
| 673 |
+
pipe = s.get("pipeline")
|
| 674 |
+
if pipe is None:
|
| 675 |
+
raise gr.Error("No image model loaded.")
|
| 676 |
+
|
| 677 |
+
with _img_lock:
|
| 678 |
+
if _img_interrupt is not None:
|
| 679 |
+
_img_interrupt.set()
|
| 680 |
+
pipe._interrupt = True
|
| 681 |
+
_img_interrupt = threading.Event()
|
| 682 |
+
pipe._interrupt = False
|
| 683 |
+
|
| 684 |
+
ev = _img_interrupt
|
| 685 |
+
if randomize:
|
| 686 |
+
seed = torch.randint(0, 2**32 - 1, (1,)).item()
|
| 687 |
+
gen = torch.Generator(device=s["device"]).manual_seed(int(seed))
|
| 688 |
+
|
| 689 |
+
has_preview = hasattr(pipe, "vae") and hasattr(pipe, "image_processor")
|
| 690 |
+
q = queue.Queue()
|
| 691 |
+
cnt = {"i": 0}
|
| 692 |
+
|
| 693 |
+
def cb(pipe, i, t, kw):
|
| 694 |
+
if ev.is_set():
|
| 695 |
+
raise InterruptedError()
|
| 696 |
+
cnt["i"] += 1
|
| 697 |
+
if has_preview and "latents" in kw:
|
| 698 |
+
try:
|
| 699 |
+
q.put((_decode_latents(kw["latents"], pipe), cnt["i"]))
|
| 700 |
+
except Exception:
|
| 701 |
+
pass
|
| 702 |
+
return kw
|
| 703 |
+
|
| 704 |
+
res = {}
|
| 705 |
+
exc = {}
|
| 706 |
+
|
| 707 |
+
def run():
|
| 708 |
+
try:
|
| 709 |
+
kw = dict(prompt=prompt, height=int(height), width=int(width),
|
| 710 |
+
num_inference_steps=int(steps), generator=gen)
|
| 711 |
+
if has_preview:
|
| 712 |
+
kw["output_type"] = "latent"
|
| 713 |
+
kw["callback_on_step_end"] = cb
|
| 714 |
+
kw["callback_on_step_end_tensor_inputs"] = ["latents"]
|
| 715 |
+
out = pipe(**kw)
|
| 716 |
+
if not ev.is_set():
|
| 717 |
+
if has_preview:
|
| 718 |
+
res["final"] = _decode_latents(out.images, pipe)
|
| 719 |
+
else:
|
| 720 |
+
res["final"] = out.images[0]
|
| 721 |
+
q.put(None)
|
| 722 |
+
except InterruptedError:
|
| 723 |
+
q.put(None)
|
| 724 |
+
except Exception as e:
|
| 725 |
+
exc["e"] = e
|
| 726 |
+
q.put(None)
|
| 727 |
|
| 728 |
+
threading.Thread(target=run).start()
|
| 729 |
|
| 730 |
+
last = None
|
| 731 |
+
while True:
|
| 732 |
+
item = q.get()
|
| 733 |
+
if item is None:
|
| 734 |
+
break
|
| 735 |
+
img, step = item
|
| 736 |
+
last = img
|
| 737 |
+
yield img, seed, f"Step {step}/{int(steps)}"
|
| 738 |
|
| 739 |
+
if "e" in exc:
|
| 740 |
+
raise exc["e"]
|
| 741 |
+
if ev.is_set():
|
| 742 |
yield last, seed, "Cancelled"
|
| 743 |
else:
|
| 744 |
+
yield res.get("final", last), seed, f"Done ({int(steps)} steps)"
|
| 745 |
+
|
| 746 |
+
|
| 747 |
+
# --- TTS ---
|
| 748 |
+
|
| 749 |
+
def generate_speech(text):
|
| 750 |
+
pipe = _state.get("pipeline")
|
| 751 |
+
model = _state.get("model")
|
| 752 |
+
tokenizer = _state.get("tokenizer")
|
| 753 |
+
|
| 754 |
+
if pipe is not None:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 755 |
try:
|
| 756 |
+
result = pipe(text)
|
| 757 |
except Exception as e:
|
| 758 |
+
raise gr.Error(f"TTS failed: {e}")
|
| 759 |
+
sr = result.get("sampling_rate", 22050)
|
| 760 |
+
audio = result["audio"]
|
| 761 |
+
elif model is not None and tokenizer is not None:
|
| 762 |
+
speaker_embedding = _state.get("speaker_embeddings")
|
| 763 |
+
import torch as _torch
|
| 764 |
+
inputs = tokenizer(text, return_tensors="pt").to(model.device)
|
| 765 |
+
with _torch.no_grad():
|
| 766 |
+
speech = model.generate(input_ids=inputs["input_ids"], speaker_embeddings=speaker_embedding)
|
| 767 |
+
sr = 16000
|
| 768 |
+
audio = speech[0].cpu().numpy()
|
| 769 |
+
else:
|
| 770 |
+
raise gr.Error("No TTS model loaded.")
|
| 771 |
+
if isinstance(audio, list):
|
| 772 |
+
audio = audio[0]
|
| 773 |
+
if isinstance(audio, torch.Tensor):
|
| 774 |
+
audio = audio.cpu().numpy()
|
| 775 |
+
return (sr, audio)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 776 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 777 |
|
| 778 |
+
# --- Code Templates ---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 779 |
|
| 780 |
+
TEMPLATES = {
|
| 781 |
+
"Custom": "# Write any Python code here\n# Model state: model, tokenizer, pipe, device\nprint('Hello from HF Playground!')",
|
| 782 |
+
"💬 Chat": '''# Chat with the loaded model
|
| 783 |
+
import torch
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 784 |
|
| 785 |
+
messages = [{"role": "system", "content": "You are a helpful assistant."}]
|
| 786 |
+
messages.append({"role": "user", "content": "What is the capital of France?"})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 787 |
|
| 788 |
+
if tokenizer.chat_template:
|
| 789 |
+
prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
|
| 790 |
+
else:
|
| 791 |
+
prompt = messages[-1]["content"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 792 |
|
| 793 |
+
inputs = tokenizer(prompt, return_tensors="pt").to(device)
|
| 794 |
+
with torch.no_grad():
|
| 795 |
+
out = model.generate(**inputs, max_new_tokens=256, temperature=0.7, do_sample=True)
|
| 796 |
+
resp = tokenizer.decode(out[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
|
| 797 |
+
print("Response:", resp)''',
|
| 798 |
+
"✏️ Completion": '''# Raw text completion
|
| 799 |
+
import torch
|
| 800 |
|
| 801 |
+
prompt = "Once upon a time, in a land far away,"
|
| 802 |
+
inputs = tokenizer(prompt, return_tensors="pt").to(device)
|
| 803 |
+
with torch.no_grad():
|
| 804 |
+
out = model.generate(**inputs, max_new_tokens=256, temperature=0.7, do_sample=True)
|
| 805 |
+
completion = tokenizer.decode(out[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
|
| 806 |
+
print(prompt + completion)''',
|
| 807 |
+
"🧠 Reasoning": '''# Step-by-step reasoning (for thinking models)
|
| 808 |
+
import torch
|
| 809 |
|
| 810 |
+
prompt = "How many r's are in the word 'strawberry'? Think step by step."
|
| 811 |
+
messages = [{"role": "system", "content": "Please reason step by step."},
|
| 812 |
+
{"role": "user", "content": prompt}]
|
| 813 |
+
|
| 814 |
+
if tokenizer.chat_template:
|
| 815 |
+
full = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
|
| 816 |
+
else:
|
| 817 |
+
full = prompt
|
| 818 |
+
|
| 819 |
+
inputs = tokenizer(full, return_tensors="pt").to(device)
|
| 820 |
+
with torch.no_grad():
|
| 821 |
+
out = model.generate(**inputs, max_new_tokens=512, temperature=0.6, do_sample=True)
|
| 822 |
+
resp = tokenizer.decode(out[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
|
| 823 |
+
print(resp)''',
|
| 824 |
+
"🌐 Translate": '''# Translation
|
| 825 |
+
import torch
|
|
|
|
|
|
|
|
|
|
| 826 |
|
| 827 |
+
src, tgt = "English", "Spanish"
|
| 828 |
+
text = "Hello, how are you today?"
|
| 829 |
+
prompt = f"Translate {src} to {tgt}: {text}"
|
| 830 |
|
| 831 |
+
inputs = tokenizer(prompt, return_tensors="pt").to(device)
|
| 832 |
+
with torch.no_grad():
|
| 833 |
+
out = model.generate(**inputs, max_new_tokens=128, temperature=0.3)
|
| 834 |
+
result = tokenizer.decode(out[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
|
| 835 |
+
print(result)''',
|
| 836 |
+
"📝 Summarize": '''# Summarization
|
| 837 |
+
import torch
|
| 838 |
+
|
| 839 |
+
doc = """The quick brown fox jumps over the lazy dog. \
|
| 840 |
+
This sentence contains every letter of the alphabet at least once. \
|
| 841 |
+
It is commonly used for typing practice and font display."""
|
| 842 |
+
|
| 843 |
+
inputs = tokenizer(doc, return_tensors="pt", truncation=True, max_length=512).to(device)
|
| 844 |
+
with torch.no_grad():
|
| 845 |
+
out = model.generate(**inputs, max_new_tokens=128, temperature=0.3, do_sample=False)
|
| 846 |
+
summary = tokenizer.decode(out[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
|
| 847 |
+
print("Summary:", summary)''',
|
| 848 |
+
"🎨 Image Gen": '''# Generate an image using the loaded pipeline
|
| 849 |
+
import torch
|
| 850 |
+
|
| 851 |
+
prompt = "A beautiful sunset over mountains, digital art"
|
| 852 |
+
height, width, steps = 256, 256, 9
|
| 853 |
+
seed = 42
|
| 854 |
+
|
| 855 |
+
if pipe is not None:
|
| 856 |
+
gen = torch.Generator(device=device).manual_seed(seed)
|
| 857 |
+
result = pipe(prompt=prompt, height=height, width=width,
|
| 858 |
+
num_inference_steps=steps, generator=gen)
|
| 859 |
+
img = result.images[0]
|
| 860 |
+
img.save("output.png")
|
| 861 |
+
print("Saved to output.png")
|
| 862 |
+
else:
|
| 863 |
+
print("No image pipeline loaded. Load a diffusers model first.")''',
|
| 864 |
+
"🔊 TTS": '''# Generate speech
|
| 865 |
+
text = "Hello, welcome to the Hugging Face playground."
|
| 866 |
+
|
| 867 |
+
if pipe is not None:
|
| 868 |
+
result = pipe(text)
|
| 869 |
+
sr, audio = result["sampling_rate"], result["audio"]
|
| 870 |
+
import scipy.io.wavfile as wav
|
| 871 |
+
wav.write("output.wav", sr, audio)
|
| 872 |
+
print("Saved to output.wav")
|
| 873 |
+
else:
|
| 874 |
+
print("No TTS pipeline loaded. Load a TTS model first.")''',
|
| 875 |
+
"📂 Read File": '''# Read and process a file from the workspace
|
| 876 |
+
import os
|
| 877 |
+
|
| 878 |
+
path = "README.md"
|
| 879 |
+
if os.path.exists(path):
|
| 880 |
+
with open(path, "r") as f:
|
| 881 |
+
content = f.read()
|
| 882 |
+
# Process with model
|
| 883 |
+
inputs = tokenizer(f"Summarize this:\\n{content[:500]}", return_tensors="pt").to(device)
|
| 884 |
+
with torch.no_grad():
|
| 885 |
+
out = model.generate(**inputs, max_new_tokens=128)
|
| 886 |
+
result = tokenizer.decode(out[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
|
| 887 |
+
print(result)
|
| 888 |
+
else:
|
| 889 |
+
print(f"File not found: {path}")''',
|
| 890 |
+
"#! Shell": '''# Shell commands with #! prefix
|
| 891 |
+
#!ls -la
|
| 892 |
+
#!pwd
|
| 893 |
+
#!echo "Hello from shell!"
|
| 894 |
+
|
| 895 |
+
# Mix with Python
|
| 896 |
+
import os
|
| 897 |
+
print("Python says:", os.getcwd())''',
|
| 898 |
+
}
|
| 899 |
+
|
| 900 |
+
TASK_TEMPLATE_MAP = {
|
| 901 |
+
"text-generation": "💬 Chat",
|
| 902 |
+
"text2text-generation": "✏️ Completion",
|
| 903 |
+
"summarization": "📝 Summarize",
|
| 904 |
+
"translation": "🌐 Translate",
|
| 905 |
+
"image-generation": "🎨 Image Gen",
|
| 906 |
+
"text-to-speech": "🔊 TTS",
|
| 907 |
+
}
|
| 908 |
+
|
| 909 |
+
|
| 910 |
+
# --- Custom Code ---
|
| 911 |
+
|
| 912 |
+
def run_custom_code(code):
|
| 913 |
+
import io as _io, sys as _sys, subprocess as _sp, traceback as _tb, shlex as _shlex
|
| 914 |
+
s = _state
|
| 915 |
+
env = {
|
| 916 |
+
"model": s.get("model"),
|
| 917 |
+
"tokenizer": s.get("tokenizer"),
|
| 918 |
+
"pipe": s.get("pipeline"),
|
| 919 |
+
"device": s.get("device", "cpu"),
|
| 920 |
+
"state": s,
|
| 921 |
+
"__builtins__": __builtins__,
|
| 922 |
}
|
| 923 |
+
old_out, old_err = _sys.stdout, _sys.stderr
|
| 924 |
+
_sys.stdout = _io.StringIO()
|
| 925 |
+
_sys.stderr = _io.StringIO()
|
| 926 |
+
try:
|
| 927 |
+
py_blocks = []
|
| 928 |
+
for line in code.split("\n"):
|
| 929 |
+
if line.startswith("#!"):
|
| 930 |
+
if py_blocks:
|
| 931 |
+
exec("\n".join(py_blocks), env)
|
| 932 |
+
py_blocks = []
|
| 933 |
+
cmd = line[2:].strip()
|
| 934 |
+
result = _sp.run(cmd, shell=True, capture_output=True, text=True)
|
| 935 |
+
print(result.stdout, end="")
|
| 936 |
+
if result.stderr:
|
| 937 |
+
print(result.stderr, file=_sys.stderr, end="")
|
| 938 |
+
else:
|
| 939 |
+
py_blocks.append(line)
|
| 940 |
+
if py_blocks:
|
| 941 |
+
exec("\n".join(py_blocks), env)
|
| 942 |
+
except Exception:
|
| 943 |
+
print(_tb.format_exc(), file=_sys.stderr)
|
| 944 |
+
out = _sys.stdout.getvalue()
|
| 945 |
+
err = _sys.stderr.getvalue()
|
| 946 |
+
_sys.stdout, _sys.stderr = old_out, old_err
|
| 947 |
+
if err:
|
| 948 |
+
out += "\n--- stderr ---\n" + err
|
| 949 |
+
return out
|
| 950 |
+
|
| 951 |
+
|
| 952 |
+
# ============================================================
|
| 953 |
+
# UI
|
| 954 |
+
# ============================================================
|
| 955 |
+
|
| 956 |
+
CSS = """
|
| 957 |
+
.gradio-container { max-width:1400px;margin:0 auto; }
|
| 958 |
+
@media(max-width:768px){ h1{font-size:1.5rem} }
|
| 959 |
+
"""
|
| 960 |
+
|
| 961 |
+
theme = gr.themes.Soft(
|
| 962 |
+
primary_hue="yellow", secondary_hue="amber", neutral_hue="slate",
|
| 963 |
+
font=gr.themes.GoogleFont("Inter"), text_size="lg", spacing_size="md", radius_size="lg",
|
| 964 |
+
).set(button_primary_background_fill="*primary_500",
|
| 965 |
+
button_primary_background_fill_hover="*primary_600",
|
| 966 |
+
block_title_text_weight="600")
|
| 967 |
+
|
| 968 |
+
|
| 969 |
+
def build_app():
|
| 970 |
+
gr.Markdown("# 🤗 **HF Playground** — enter any model ID to test")
|
| 971 |
+
|
| 972 |
+
with gr.Row(equal_height=True):
|
| 973 |
+
model_input = gr.Dropdown(
|
| 974 |
+
label="Model ID", scale=5, container=True,
|
| 975 |
+
choices=PRESET_CHOICES, value="google/gemma-3-1b-it",
|
| 976 |
+
allow_custom_value=True,
|
| 977 |
+
)
|
| 978 |
+
load_btn = gr.Button("🚀 Load", variant="primary", scale=1, min_width=80)
|
| 979 |
+
use_gpu = gr.Checkbox(label="GPU", value=False, scale=1, show_label=False)
|
| 980 |
+
|
| 981 |
+
use_gpu.change(fn=_set_gpu_flag, inputs=[use_gpu], outputs=[])
|
| 982 |
+
|
| 983 |
+
model_info = gr.Markdown("_No model loaded_")
|
| 984 |
+
|
| 985 |
+
task_state = gr.State("text-generation")
|
| 986 |
+
thinking_state = gr.State(False)
|
| 987 |
+
|
| 988 |
+
# --- Always-visible Code + File Browser ---
|
| 989 |
+
with gr.Accordion("🐍 Python + 📁 Files", open=True):
|
| 990 |
+
with gr.Row():
|
| 991 |
+
with gr.Column(scale=1, min_width=280):
|
| 992 |
+
gr.Markdown("### 📁 Files")
|
| 993 |
+
file_list = gr.Dropdown(label="Workspace Files", choices=[], interactive=True, container=True)
|
| 994 |
+
refresh_btn = gr.Button("🔄 Refresh", scale=1)
|
| 995 |
+
gr.Markdown("---")
|
| 996 |
+
preview_img = gr.Image(label="Preview", type="filepath", visible=False, height=400)
|
| 997 |
+
preview_aud = gr.Audio(label="Preview", type="filepath", visible=False)
|
| 998 |
+
preview_vid = gr.Video(label="Preview", visible=False, height=400)
|
| 999 |
+
preview_txt = gr.Textbox(label="File Content", lines=20, visible=False)
|
| 1000 |
+
with gr.Column(scale=2):
|
| 1001 |
+
gr.Markdown("### 🐍 Python")
|
| 1002 |
+
template_dd = gr.Dropdown(
|
| 1003 |
+
label="Template", choices=list(TEMPLATES.keys()),
|
| 1004 |
+
value="Custom", container=True,
|
| 1005 |
+
)
|
| 1006 |
+
custom_code = gr.Code(label="Code", language="python", lines=12,
|
| 1007 |
+
value=TEMPLATES["Custom"])
|
| 1008 |
+
with gr.Row():
|
| 1009 |
+
custom_run = gr.Button("▶ Run", variant="primary")
|
| 1010 |
+
custom_out = gr.Textbox(label="Output", lines=8)
|
| 1011 |
+
|
| 1012 |
+
# ── Columns for each task type ──
|
| 1013 |
+
cols = {}
|
| 1014 |
+
|
| 1015 |
+
# --- TEXT GENERATION ---
|
| 1016 |
+
with gr.Column(visible=False) as c_text:
|
| 1017 |
+
cols["text-generation"] = c_text
|
| 1018 |
+
cols["text2text-generation"] = c_text
|
| 1019 |
+
gr.Markdown("### 💬 Text Generation")
|
| 1020 |
+
with gr.Tabs():
|
| 1021 |
+
with gr.TabItem("💬 Chat"):
|
| 1022 |
+
chatbot = gr.Chatbot(label="Conversation", height=400)
|
| 1023 |
+
chat_msg = gr.Textbox(label="Message", placeholder="Type...", scale=4, container=True)
|
| 1024 |
+
with gr.Row():
|
| 1025 |
+
chat_btn = gr.Button("Send", variant="primary")
|
| 1026 |
+
chat_clr = gr.Button("🗑 Clear")
|
| 1027 |
+
chat_sys = gr.Textbox(label="System Prompt", value="You are a helpful assistant.", lines=2)
|
| 1028 |
+
with gr.TabItem("✏️ Completion"):
|
| 1029 |
+
comp_in = gr.Textbox(label="Input", lines=5)
|
| 1030 |
+
comp_out = gr.Textbox(label="Output", lines=10)
|
| 1031 |
+
with gr.Row():
|
| 1032 |
+
comp_btn = gr.Button("Generate", variant="primary")
|
| 1033 |
+
comp_stop = gr.Button("⏹ Stop", variant="stop", visible=False)
|
| 1034 |
+
with gr.TabItem("🌐 Translate (prompt)"):
|
| 1035 |
+
tri_in = gr.Textbox(label="Text", lines=5)
|
| 1036 |
+
with gr.Row():
|
| 1037 |
+
tri_src = gr.Dropdown(label="Source", value="auto",
|
| 1038 |
+
choices=["auto","English","Spanish","French","German","Chinese"])
|
| 1039 |
+
tri_tgt = gr.Dropdown(label="Target", value="Spanish",
|
| 1040 |
+
choices=["English","Spanish","French","German","Chinese"])
|
| 1041 |
+
tri_out = gr.Textbox(label="Translation", lines=5)
|
| 1042 |
+
tri_btn = gr.Button("Translate", variant="primary")
|
| 1043 |
+
with gr.Accordion("⚙️ Parameters", open=False):
|
| 1044 |
+
with gr.Row():
|
| 1045 |
+
tk = gr.Slider(32, 4096, 512, 32, label="Max New Tokens")
|
| 1046 |
+
tm = gr.Slider(0, 2, 0.7, 0.05, label="Temperature")
|
| 1047 |
+
with gr.Row():
|
| 1048 |
+
tp = gr.Slider(0, 1, 0.9, 0.05, label="Top-P")
|
| 1049 |
+
tkk = gr.Slider(0, 200, 50, 1, label="Top-K (0=off)")
|
| 1050 |
+
with gr.Row():
|
| 1051 |
+
rp = gr.Slider(1, 2, 1.1, 0.05, label="Repetition Penalty")
|
| 1052 |
+
ds = gr.Checkbox(True, label="Sampling")
|
| 1053 |
+
|
| 1054 |
+
# --- SUMMARIZATION ---
|
| 1055 |
+
with gr.Column(visible=False) as c_summ:
|
| 1056 |
+
cols["summarization"] = c_summ
|
| 1057 |
+
gr.Markdown("### 📝 Summarization")
|
| 1058 |
+
sm_in = gr.Textbox(label="Document", lines=10)
|
| 1059 |
+
sm_out = gr.Textbox(label="Summary", lines=8)
|
| 1060 |
+
sm_btn = gr.Button("Summarize", variant="primary")
|
| 1061 |
+
with gr.Accordion("⚙️ Parameters", open=False):
|
| 1062 |
+
with gr.Row():
|
| 1063 |
+
sm_tk = gr.Slider(32, 1024, 150, 16, label="Max New Tokens")
|
| 1064 |
+
sm_tm = gr.Slider(0, 2, 0.7, 0.05, label="Temperature")
|
| 1065 |
+
with gr.Row():
|
| 1066 |
+
sm_tp = gr.Slider(0, 1, 0.9, 0.05, label="Top-P")
|
| 1067 |
+
sm_tkk = gr.Slider(0, 200, 50, 1, label="Top-K")
|
| 1068 |
+
with gr.Row():
|
| 1069 |
+
sm_rp = gr.Slider(1, 2, 1, 0.05, label="Repetition")
|
| 1070 |
+
sm_ds = gr.Checkbox(True, label="Sampling")
|
| 1071 |
+
|
| 1072 |
+
# --- TRANSLATION ---
|
| 1073 |
+
with gr.Column(visible=False) as c_trans:
|
| 1074 |
+
cols["translation"] = c_trans
|
| 1075 |
+
gr.Markdown("### 🌐 Translation")
|
| 1076 |
+
with gr.Row():
|
| 1077 |
+
dl_src = gr.Dropdown(label="Source", value="en",
|
| 1078 |
+
choices=["en","es","fr","de","zh","ja","ar"])
|
| 1079 |
+
dl_tgt = gr.Dropdown(label="Target", value="es",
|
| 1080 |
+
choices=["en","es","fr","de","zh","ja","ar"])
|
| 1081 |
+
dl_in = gr.Textbox(label="Text", lines=5)
|
| 1082 |
+
dl_out = gr.Textbox(label="Translation", lines=5)
|
| 1083 |
+
dl_btn = gr.Button("Translate", variant="primary")
|
| 1084 |
+
with gr.Accordion("⚙️ Parameters", open=False):
|
| 1085 |
+
with gr.Row():
|
| 1086 |
+
dl_tk = gr.Slider(32, 1024, 256, 16, label="Max New Tokens")
|
| 1087 |
+
dl_tm = gr.Slider(0, 2, 0.7, 0.05, label="Temperature")
|
| 1088 |
+
with gr.Row():
|
| 1089 |
+
dl_tp = gr.Slider(0, 1, 0.9, 0.05, label="Top-P")
|
| 1090 |
+
dl_tkk = gr.Slider(0, 200, 50, 1, label="Top-K")
|
| 1091 |
+
with gr.Row():
|
| 1092 |
+
dl_rp = gr.Slider(1, 2, 1, 0.05, label="Repetition")
|
| 1093 |
+
dl_ds = gr.Checkbox(True, label="Sampling")
|
| 1094 |
+
|
| 1095 |
+
# --- IMAGE GENERATION ---
|
| 1096 |
+
with gr.Column(visible=False) as c_img:
|
| 1097 |
+
cols["image-generation"] = c_img
|
| 1098 |
+
gr.Markdown("### 🎨 Image Generation")
|
| 1099 |
+
img_pr = gr.Textbox(label="Prompt", lines=3)
|
| 1100 |
+
with gr.Row():
|
| 1101 |
+
img_h = gr.Slider(64, 1024, 256, 32, label="Height")
|
| 1102 |
+
img_w = gr.Slider(64, 1024, 256, 32, label="Width")
|
| 1103 |
+
with gr.Row():
|
| 1104 |
+
img_st = gr.Slider(1, 50, 9, 1, label="Steps")
|
| 1105 |
+
img_rz = gr.Checkbox(True, label="Random Seed")
|
| 1106 |
+
img_sd = gr.Number(42, label="Seed", precision=0, visible=False)
|
| 1107 |
+
img_rz.change(fn=lambda r: gr.update(visible=not r), inputs=[img_rz], outputs=[img_sd])
|
| 1108 |
+
img_out = gr.Image(label="Generated Image", type="pil", height=512)
|
| 1109 |
+
img_sts = gr.Textbox(label="Status", value="Idle", interactive=False)
|
| 1110 |
+
img_used = gr.Number(label="Seed", interactive=False)
|
| 1111 |
+
img_btn = gr.Button("🎨 Generate Image", variant="primary")
|
| 1112 |
+
gr.Examples([["Young Chinese woman in red Hanfu."],
|
| 1113 |
+
["Dragon soaring through clouds at sunset."],
|
| 1114 |
+
["Astronaut riding a horse on Mars."]],
|
| 1115 |
+
inputs=[img_pr])
|
| 1116 |
+
|
| 1117 |
+
# --- TTS ---
|
| 1118 |
+
with gr.Column(visible=False) as c_tts:
|
| 1119 |
+
cols["text-to-speech"] = c_tts
|
| 1120 |
+
gr.Markdown("### 🔊 Text-to-Speech")
|
| 1121 |
+
tts_txt = gr.Textbox(label="Text", lines=3)
|
| 1122 |
+
tts_btn = gr.Button("🔊 Generate Speech", variant="primary")
|
| 1123 |
+
tts_aud = gr.Audio(label="Speech", type="numpy")
|
| 1124 |
+
|
| 1125 |
+
# ===========================
|
| 1126 |
+
# VISIBILITY MAPPING
|
| 1127 |
+
# ===========================
|
| 1128 |
+
ui_order = ["text-generation", "text2text-generation", "summarization",
|
| 1129 |
+
"translation", "image-generation", "text-to-speech"]
|
| 1130 |
+
ui_cols = [cols.get(t, c_text) for t in ui_order]
|
| 1131 |
+
# deduplicate by id
|
| 1132 |
+
seen = set()
|
| 1133 |
+
unique_cols = []
|
| 1134 |
+
for c in ui_cols:
|
| 1135 |
+
if id(c) not in seen:
|
| 1136 |
+
seen.add(id(c))
|
| 1137 |
+
unique_cols.append(c)
|
| 1138 |
+
|
| 1139 |
+
def set_visible(task):
|
| 1140 |
+
return [gr.update(visible=c == cols.get(task, c_text)) for c in unique_cols]
|
| 1141 |
+
|
| 1142 |
+
# File browser helpers
|
| 1143 |
+
import os as _os, glob as _glob
|
| 1144 |
+
|
| 1145 |
+
def _list_files():
|
| 1146 |
+
files = sorted(f for f in _glob.glob("**/*", recursive=True) if _os.path.isfile(f))
|
| 1147 |
+
return gr.update(choices=[(f, f) for f in files])
|
| 1148 |
+
|
| 1149 |
+
def _preview_file(path):
|
| 1150 |
+
if not path:
|
| 1151 |
+
return [gr.update(visible=False)] * 4
|
| 1152 |
+
ext = _os.path.splitext(path)[1].lower()
|
| 1153 |
+
img = {".png",".jpg",".jpeg",".gif",".bmp",".webp",".svg"}
|
| 1154 |
+
aud = {".mp3",".wav",".ogg",".flac",".m4a",".aac",".wma"}
|
| 1155 |
+
vid = {".mp4",".avi",".mov",".mkv",".webm",".m4v"}
|
| 1156 |
+
if ext in img:
|
| 1157 |
+
return [gr.update(visible=True, value=path), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)]
|
| 1158 |
+
if ext in aud:
|
| 1159 |
+
return [gr.update(visible=False), gr.update(visible=True, value=path), gr.update(visible=False), gr.update(visible=False)]
|
| 1160 |
+
if ext in vid:
|
| 1161 |
+
return [gr.update(visible=False), gr.update(visible=False), gr.update(visible=True, value=path), gr.update(visible=False)]
|
| 1162 |
try:
|
| 1163 |
+
with open(path, "r", encoding="utf-8") as f:
|
| 1164 |
+
content = f.read()
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1165 |
except Exception:
|
| 1166 |
+
content = f"<binary or unreadable: {path}>"
|
| 1167 |
+
return [gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=True, value=content)]
|
| 1168 |
+
|
| 1169 |
+
# ===========================
|
| 1170 |
+
# EVENT WIRING
|
| 1171 |
+
# ===========================
|
| 1172 |
+
|
| 1173 |
+
# Load model
|
| 1174 |
+
def on_load(model_id_val, progress=gr.Progress()):
|
| 1175 |
+
if not model_id_val:
|
| 1176 |
+
return [gr.update()] * (5 + n_vis)
|
| 1177 |
+
task, thinking, info = load_model(model_id_val, progress)
|
| 1178 |
+
vis_updates = set_visible(task)
|
| 1179 |
+
template_name = TASK_TEMPLATE_MAP.get(task, "Custom")
|
| 1180 |
+
template_code = TEMPLATES.get(template_name, TEMPLATES["Custom"])
|
| 1181 |
+
return [task, thinking, info] + vis_updates + [gr.update(value=template_name), gr.update(value=template_code)]
|
| 1182 |
+
|
| 1183 |
+
n_vis = len(unique_cols)
|
| 1184 |
+
load_outputs = [task_state, thinking_state, model_info] + unique_cols + [template_dd, custom_code]
|
| 1185 |
+
|
| 1186 |
+
model_input.change(fn=on_load, inputs=[model_input], outputs=load_outputs)
|
| 1187 |
+
load_btn.click(fn=on_load, inputs=[model_input], outputs=load_outputs)
|
| 1188 |
+
|
| 1189 |
+
# Chat
|
| 1190 |
+
chat_btn.click(
|
| 1191 |
+
fn=chat_respond,
|
| 1192 |
+
inputs=[chat_msg, chatbot, chat_sys, tk, tm, tp, tkk, rp, ds, thinking_state],
|
| 1193 |
+
outputs=[chatbot, chat_msg],
|
| 1194 |
+
)
|
| 1195 |
+
chat_msg.submit(
|
| 1196 |
+
fn=chat_respond,
|
| 1197 |
+
inputs=[chat_msg, chatbot, chat_sys, tk, tm, tp, tkk, rp, ds, thinking_state],
|
| 1198 |
+
outputs=[chatbot, chat_msg],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1199 |
)
|
| 1200 |
+
chat_clr.click(fn=lambda: ([], ""), outputs=[chatbot, chat_msg])
|
| 1201 |
+
|
| 1202 |
+
# Completion
|
| 1203 |
+
comp_btn.click(
|
| 1204 |
+
fn=lambda: (gr.update(visible=False), gr.update(visible=True)),
|
| 1205 |
+
outputs=[comp_btn, comp_stop],
|
| 1206 |
+
).then(
|
| 1207 |
+
fn=completion_fn,
|
| 1208 |
+
inputs=[comp_in, tk, tm, tp, tkk, rp, ds, thinking_state],
|
| 1209 |
+
outputs=[comp_out],
|
| 1210 |
+
).then(
|
| 1211 |
+
fn=lambda: (gr.update(visible=True), gr.update(visible=False)),
|
| 1212 |
+
outputs=[comp_btn, comp_stop],
|
| 1213 |
+
)
|
| 1214 |
+
comp_stop.click(
|
| 1215 |
+
fn=lambda: (_cancel_flag.__setitem__(0, True),) or (gr.update(visible=True), gr.update(visible=False)),
|
| 1216 |
+
outputs=[comp_btn, comp_stop],
|
| 1217 |
)
|
| 1218 |
|
| 1219 |
+
# Translate (text gen tab)
|
| 1220 |
+
tri_btn.click(
|
| 1221 |
+
fn=translate_fn,
|
| 1222 |
+
inputs=[tri_in, tri_src, tri_tgt, tk, tm, tp, tkk, rp, ds, thinking_state],
|
| 1223 |
+
outputs=[tri_out],
|
| 1224 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1225 |
|
| 1226 |
+
# Summarization
|
| 1227 |
+
sm_btn.click(
|
| 1228 |
+
fn=summarize_fn,
|
| 1229 |
+
inputs=[sm_in, sm_tk, sm_tm, sm_tp, sm_tkk, sm_rp, sm_ds],
|
| 1230 |
+
outputs=[sm_out],
|
| 1231 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1232 |
|
| 1233 |
+
# Translation dedicated
|
| 1234 |
+
dl_btn.click(
|
| 1235 |
+
fn=translate_fn,
|
| 1236 |
+
inputs=[dl_in, dl_src, dl_tgt, dl_tk, dl_tm, dl_tp, dl_tkk, dl_rp, dl_ds, thinking_state],
|
| 1237 |
+
outputs=[dl_out],
|
| 1238 |
+
)
|
| 1239 |
|
| 1240 |
+
# Image
|
| 1241 |
+
img_btn.click(
|
| 1242 |
+
fn=generate_image,
|
| 1243 |
+
inputs=[img_pr, img_h, img_w, img_st, img_sd, img_rz],
|
| 1244 |
+
outputs=[img_out, img_used, img_sts],
|
| 1245 |
+
)
|
| 1246 |
|
| 1247 |
+
# TTS
|
| 1248 |
+
tts_btn.click(fn=generate_speech, inputs=[tts_txt], outputs=[tts_aud])
|
| 1249 |
|
| 1250 |
+
# Custom code
|
| 1251 |
+
refresh_btn.click(fn=_list_files, outputs=[file_list])
|
| 1252 |
+
file_list.change(fn=_preview_file, inputs=[file_list], outputs=[preview_img, preview_aud, preview_vid, preview_txt])
|
| 1253 |
+
template_dd.change(
|
| 1254 |
+
fn=lambda name: gr.update(value=TEMPLATES.get(name, TEMPLATES["Custom"])),
|
| 1255 |
+
inputs=[template_dd], outputs=[custom_code],
|
| 1256 |
+
)
|
| 1257 |
+
custom_run.click(fn=run_custom_code, inputs=[custom_code], outputs=[custom_out])
|
| 1258 |
+
|
| 1259 |
+
# Footer
|
| 1260 |
+
gr.Markdown("""
|
| 1261 |
+
---
|
| 1262 |
+
<div style="text-align:center;opacity:0.7;font-size:0.85em;padding:0.5rem 0;">
|
| 1263 |
+
🤗 HuggingFace Model Playground — Enter any model ID, auto-detect, test instantly.
|
| 1264 |
+
</div>
|
| 1265 |
+
""")
|
| 1266 |
|
| 1267 |
|
| 1268 |
+
# ============================================================
|
| 1269 |
+
# LAUNCH
|
| 1270 |
+
# ============================================================
|
| 1271 |
+
|
| 1272 |
+
with gr.Blocks(title="HF Model Playground", fill_height=True) as demo:
|
| 1273 |
+
build_app()
|
| 1274 |
|
| 1275 |
if __name__ == "__main__":
|
| 1276 |
+
demo.queue(default_concurrency_limit=3).launch(
|
| 1277 |
+
server_name="0.0.0.0",
|
| 1278 |
+
theme=theme,
|
| 1279 |
+
css=CSS,
|
| 1280 |
+
footer_links=["api", "gradio"],
|
| 1281 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
requirements.txt
CHANGED
|
@@ -4,4 +4,10 @@ diffusers
|
|
| 4 |
transformers
|
| 5 |
accelerate
|
| 6 |
torch
|
| 7 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
transformers
|
| 5 |
accelerate
|
| 6 |
torch
|
| 7 |
+
huggingface_hub
|
| 8 |
+
sentencepiece
|
| 9 |
+
tiktoken
|
| 10 |
+
datasets
|
| 11 |
+
protobuf
|
| 12 |
+
soundfile
|
| 13 |
+
einops
|