Spaces:
Running on Zero
Running on Zero
Remove the Chat tab and Gemma: this is a graphics studio
Browse files- README.md +1 -8
- app.py +1 -119
- requirements.txt +0 -1
README.md
CHANGED
|
@@ -8,14 +8,10 @@ app_file: app.py
|
|
| 8 |
pinned: false
|
| 9 |
license: apache-2.0
|
| 10 |
short_description: FLUX image, LTX video, MusicGen music, Kokoro+Qwen narration
|
| 11 |
-
hf_oauth: true
|
| 12 |
-
hf_oauth_scopes:
|
| 13 |
-
- inference-api
|
| 14 |
tags:
|
| 15 |
- text-to-image
|
| 16 |
- image-to-video
|
| 17 |
- text-to-video
|
| 18 |
-
- text-generation
|
| 19 |
- text-to-speech
|
| 20 |
- text-to-audio
|
| 21 |
- audio-text-to-text
|
|
@@ -46,7 +42,6 @@ models:
|
|
| 46 |
- hexgrad/Kokoro-82M
|
| 47 |
- openai/whisper-large-v3-turbo
|
| 48 |
- laion/clap-htsat-unfused
|
| 49 |
-
- google/gemma-4-31B-it
|
| 50 |
- florence-community/Florence-2-large
|
| 51 |
- HuggingFaceTB/SmolVLM2-2.2B-Instruct
|
| 52 |
- Qwen/Qwen3-4B
|
|
@@ -62,8 +57,6 @@ models:
|
|
| 62 |
|
| 63 |
**Narration tab (text to speech, speech generation, machine speech):** Kokoro (hexgrad) reads your text aloud in a choice of eight voices.
|
| 64 |
|
| 65 |
-
**Chat tab:** Gemma 4 31B (google) answers questions and writes text. It runs in the Space in 8-bit, so no sign-in is needed; a reply uses your own ZeroGPU quota.
|
| 66 |
-
|
| 67 |
**Describe tab:** three ways to describe what you have.
|
| 68 |
|
| 69 |
- **Image to text (image captioning, image recognition):** Florence-2 large (microsoft, via florence-community) writes a detailed caption of an uploaded picture.
|
|
@@ -80,6 +73,6 @@ models:
|
|
| 80 |
|
| 81 |
**How it stays light on ZeroGPU quota:** each model is kept in its own pack, and a button copies only the models it needs onto the GPU, one after another where a job uses several. An image copies only the image model, and a video loads FLUX, then LTX-Video, then MusicGen in turn, so every job fits the default half-card slice.
|
| 82 |
|
| 83 |
-
**Licences:** LTX-Video, Kokoro, Whisper, CLAP, Qwen3 4B,
|
| 84 |
|
| 85 |
Runs on ZeroGPU: set the Space hardware to **ZeroGPU** in Settings.
|
|
|
|
| 8 |
pinned: false
|
| 9 |
license: apache-2.0
|
| 10 |
short_description: FLUX image, LTX video, MusicGen music, Kokoro+Qwen narration
|
|
|
|
|
|
|
|
|
|
| 11 |
tags:
|
| 12 |
- text-to-image
|
| 13 |
- image-to-video
|
| 14 |
- text-to-video
|
|
|
|
| 15 |
- text-to-speech
|
| 16 |
- text-to-audio
|
| 17 |
- audio-text-to-text
|
|
|
|
| 42 |
- hexgrad/Kokoro-82M
|
| 43 |
- openai/whisper-large-v3-turbo
|
| 44 |
- laion/clap-htsat-unfused
|
|
|
|
| 45 |
- florence-community/Florence-2-large
|
| 46 |
- HuggingFaceTB/SmolVLM2-2.2B-Instruct
|
| 47 |
- Qwen/Qwen3-4B
|
|
|
|
| 57 |
|
| 58 |
**Narration tab (text to speech, speech generation, machine speech):** Kokoro (hexgrad) reads your text aloud in a choice of eight voices.
|
| 59 |
|
|
|
|
|
|
|
| 60 |
**Describe tab:** three ways to describe what you have.
|
| 61 |
|
| 62 |
- **Image to text (image captioning, image recognition):** Florence-2 large (microsoft, via florence-community) writes a detailed caption of an uploaded picture.
|
|
|
|
| 73 |
|
| 74 |
**How it stays light on ZeroGPU quota:** each model is kept in its own pack, and a button copies only the models it needs onto the GPU, one after another where a job uses several. An image copies only the image model, and a video loads FLUX, then LTX-Video, then MusicGen in turn, so every job fits the default half-card slice.
|
| 75 |
|
| 76 |
+
**Licences:** LTX-Video, Kokoro, Whisper, CLAP, Qwen3 4B, Florence-2 large and SmolVLM2 2.2B are openly licensed. **FLUX.2 klein 9B is under the FLUX Non-Commercial License** and **MusicGen medium is CC-BY-NC 4.0**, so images, videos and music made here are for non-commercial use.
|
| 77 |
|
| 78 |
Runs on ZeroGPU: set the Space hardware to **ZeroGPU** in Settings.
|
app.py
CHANGED
|
@@ -5,7 +5,6 @@ Music tab (text to music, text to audio): MusicGen medium turns a description in
|
|
| 5 |
Transcribe tab (speech to text, speech recognition, automatic speech recognition): Whisper large v3 turbo
|
| 6 |
writes down speech from an uploaded file or the microphone, in its own language or translated to English.
|
| 7 |
Narration tab (text to speech, machine speech, speech generation): Kokoro reads your text aloud.
|
| 8 |
-
Chat tab: Gemma 4 31B answers questions, running here in 8-bit (hosted Gemma with sign-in as fallback).
|
| 9 |
Describe tab: three sub-tabs for the describing jobs the Space does.
|
| 10 |
Image to text (image captioning, image recognition): Florence-2 large writes a detailed caption for
|
| 11 |
an uploaded picture.
|
|
@@ -23,8 +22,6 @@ Each model has its own ZeroGPU pack (see zero_packs.py), and each button copies
|
|
| 23 |
needs onto the GPU, one after another where a job uses several big models. That keeps every job
|
| 24 |
inside the default half-card slice, which is not billed double. If zero_packs is switched off or
|
| 25 |
cannot work, everything is copied on every request as ZeroGPU normally does, on the full card.
|
| 26 |
-
The Chat tab uses hosted Gemma 4 31B (billed to each visitor's own HF inference credits) and no
|
| 27 |
-
ZeroGPU time at all.
|
| 28 |
"""
|
| 29 |
import os
|
| 30 |
|
|
@@ -46,7 +43,6 @@ _store = _pick_model_store()
|
|
| 46 |
if _store:
|
| 47 |
os.environ["HF_HOME"] = _store # Must be set before the Hugging Face libraries are imported
|
| 48 |
|
| 49 |
-
import gc
|
| 50 |
import json
|
| 51 |
import random
|
| 52 |
import re
|
|
@@ -67,7 +63,6 @@ import zero_packs as packs
|
|
| 67 |
from diffusers import FluxPipeline, LTXConditionPipeline
|
| 68 |
from diffusers.pipelines.ltx.pipeline_ltx_condition import LTXVideoCondition
|
| 69 |
from diffusers.utils import export_to_video
|
| 70 |
-
from huggingface_hub import InferenceClient
|
| 71 |
from PIL import Image
|
| 72 |
from transformers import (AutoModelForCausalLM, AutoModelForImageTextToText, AutoProcessor,
|
| 73 |
AutoTokenizer, MusicgenForConditionalGeneration, pipeline)
|
|
@@ -85,7 +80,6 @@ IMAGE_CAPTION_MODEL = "florence-community/Florence-2-large" # Picture to ca
|
|
| 85 |
VIDEO_CAPTION_MODEL = "HuggingFaceTB/SmolVLM2-2.2B-Instruct" # Video frames to description
|
| 86 |
LISTEN_MODEL = "laion/clap-htsat-unfused" # Recognises genre, mood, instruments and tempo
|
| 87 |
SPEECH_MODEL = "openai/whisper-large-v3-turbo" # Speech to text
|
| 88 |
-
CHAT_MODEL = "google/gemma-4-31B-it" # Runs here in 8-bit; hosted inference is the fallback
|
| 89 |
VOICE = "af_heart" # Kokoro voice
|
| 90 |
VOICE_RATE = 24000
|
| 91 |
VOICES = {"Heart (woman)": "af_heart", "Bella (woman)": "af_bella", "Nicole (woman, soft)": "af_nicole",
|
|
@@ -112,34 +106,6 @@ SPEED_SUFFIX = ", moving at natural real-time speed"
|
|
| 112 |
# Pure per-call .to('cuda') from ordinary RAM was tried on 2026-10-07: the first FLUX move took 79 s.
|
| 113 |
# The packs are read straight from disk at about 17 GB a second, like ZeroGPU's own single pack.
|
| 114 |
# Once a model is sealed, never call .to("cuda") on it again here: its weights are on disk.
|
| 115 |
-
# Chat: Gemma 4 31B with its weights squeezed to 8-bit by bitsandbytes (about 32 GB, so it fits the
|
| 116 |
-
# half card on its own). The squeezing is done here on the CPU at start-up, which takes a few minutes.
|
| 117 |
-
# If anything goes wrong the Space still starts, and the Chat tab uses hosted Gemma with sign-in.
|
| 118 |
-
# It is loaded first, while the disk is empty: on 2026-10-09 downloading Gemma (62 GB) after the other
|
| 119 |
-
# models went over the Space's 150 GB disk limit and the Space was evicted. Every model's downloaded
|
| 120 |
-
# files are now deleted as soon as its pack is sealed. Set the Space variable LOCAL_CHAT to "0" to skip it.
|
| 121 |
-
try: # Which disks there are and how full: the packs' disk and the download cache have separate limits
|
| 122 |
-
print("[disk]", subprocess.run(["df", "-h"], capture_output=True, text=True).stdout.replace("\n", " | "), flush=True)
|
| 123 |
-
except Exception as e:
|
| 124 |
-
print(f"[disk] df failed: {e}", flush=True)
|
| 125 |
-
chat_model = chat_processor = None
|
| 126 |
-
try:
|
| 127 |
-
if not packs.enabled or os.environ.get("LOCAL_CHAT", "0") != "1":
|
| 128 |
-
raise RuntimeError("switched off")
|
| 129 |
-
print("[load] Gemma 4 31B (8-bit)...", flush=True)
|
| 130 |
-
from transformers import BitsAndBytesConfig
|
| 131 |
-
_t0 = time.time()
|
| 132 |
-
chat_processor = AutoProcessor.from_pretrained(CHAT_MODEL)
|
| 133 |
-
chat_model = AutoModelForImageTextToText.from_pretrained(
|
| 134 |
-
CHAT_MODEL, quantization_config=BitsAndBytesConfig(load_in_8bit=True),
|
| 135 |
-
torch_dtype=torch.bfloat16, device_map={"": "cuda"})
|
| 136 |
-
print(f"[load] Gemma ready in {time.time() - _t0:.0f}s", flush=True)
|
| 137 |
-
packs.seal("gemma", CHAT_MODEL)
|
| 138 |
-
except Exception as e:
|
| 139 |
-
print(f"[load] no local Gemma, Chat will use hosted Gemma: {type(e).__name__}: {str(e)[:300]}", flush=True)
|
| 140 |
-
chat_model = None
|
| 141 |
-
gc.collect() # Drop any half-loaded weights, so they are not packed with the next model
|
| 142 |
-
packs.free_downloads(CHAT_MODEL) # And its downloaded files, so the disk limit is not hit later
|
| 143 |
print("[load] image model...", flush=True)
|
| 144 |
try:
|
| 145 |
from diffusers import Flux2KleinPipeline
|
|
@@ -203,15 +169,6 @@ speech_pipe = pipeline("automatic-speech-recognition", model=SPEECH_MODEL, torch
|
|
| 203 |
device="cuda", chunk_length_s=30)
|
| 204 |
packs.seal("whisper", SPEECH_MODEL)
|
| 205 |
print("[load] done.", flush=True)
|
| 206 |
-
try: # Where the downloads and packs really are, and what counts towards the disk limits
|
| 207 |
-
from huggingface_hub import constants as _hub
|
| 208 |
-
_script = ("du -xsh /root/.cache/* /root/.cache/huggingface/* /root/.zerogpu /data-nvme/* /tmp /home/* 2>/dev/null"
|
| 209 |
-
" | sort -h | tail -25; uname -r; free -g | head -2")
|
| 210 |
-
print("[where]", f"HF_HUB_CACHE={_hub.HF_HUB_CACHE} HOME={os.path.expanduser('~')} offload={packs.PACK_DIR}", "|",
|
| 211 |
-
subprocess.run(["sh", "-c", _script], capture_output=True, text=True, timeout=120).stdout.replace("\n", " | "),
|
| 212 |
-
flush=True)
|
| 213 |
-
except Exception as e:
|
| 214 |
-
print(f"[where] failed: {e}", flush=True)
|
| 215 |
|
| 216 |
# With a pack per model every job fits the default half-card slice ("large"), which is billed once.
|
| 217 |
# Without them ZeroGPU copies all the models on every call, and that needs the whole card.
|
|
@@ -529,71 +486,6 @@ def video_frames(path, count=6):
|
|
| 529 |
return frames, length
|
| 530 |
|
| 531 |
|
| 532 |
-
# ---------------------------------------------------------------- Chat (hosted Gemma; no GPU)
|
| 533 |
-
|
| 534 |
-
def as_text(content):
|
| 535 |
-
if isinstance(content, str):
|
| 536 |
-
return content
|
| 537 |
-
if isinstance(content, dict):
|
| 538 |
-
return str(content.get("text", ""))
|
| 539 |
-
if isinstance(content, (list, tuple)):
|
| 540 |
-
return " ".join(as_text(part) for part in content)
|
| 541 |
-
return str(content or "")
|
| 542 |
-
|
| 543 |
-
|
| 544 |
-
def chat_seconds(messages):
|
| 545 |
-
return gpu_seconds(60)
|
| 546 |
-
|
| 547 |
-
|
| 548 |
-
@spaces.GPU(duration=chat_seconds, size=GPU_SIZE)
|
| 549 |
-
def chat_gpu(messages):
|
| 550 |
-
"""Gemma 4 31B (8-bit) answers on the GPU."""
|
| 551 |
-
with timed("chat"):
|
| 552 |
-
packs.load("gemma")
|
| 553 |
-
turns = [{"role": m["role"], "content": [{"type": "text", "text": m["content"]}]} for m in messages]
|
| 554 |
-
inputs = chat_processor.apply_chat_template(
|
| 555 |
-
turns, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt").to("cuda")
|
| 556 |
-
start = time.time()
|
| 557 |
-
out = chat_model.generate(**inputs, max_new_tokens=300, do_sample=True, temperature=0.7, top_p=0.9)
|
| 558 |
-
new = out[0][inputs["input_ids"].shape[1]:]
|
| 559 |
-
print(f"[chat] {len(new)} tokens at {len(new) / (time.time() - start):.1f} a second", flush=True)
|
| 560 |
-
return chat_processor.decode(new, skip_special_tokens=True).strip()
|
| 561 |
-
|
| 562 |
-
|
| 563 |
-
def chat(message, history, oauth_token: gr.OAuthToken | None = None):
|
| 564 |
-
"""Gemma 4 31B. Runs here in 8-bit; if that could not be loaded, hosted Gemma with the visitor's sign-in."""
|
| 565 |
-
if chat_model is not None:
|
| 566 |
-
messages = [{"role": "system", "content": "You are a helpful, friendly assistant. Answer clearly and briefly."}]
|
| 567 |
-
for turn in history[-8:]:
|
| 568 |
-
if isinstance(turn, dict):
|
| 569 |
-
messages.append({"role": turn.get("role", "user"), "content": as_text(turn.get("content"))})
|
| 570 |
-
messages.append({"role": "user", "content": as_text(message)})
|
| 571 |
-
return chat_gpu(messages)
|
| 572 |
-
if oauth_token is None:
|
| 573 |
-
return ("Please press **Sign in with Hugging Face** above. Each visitor's chat reply is billed to their "
|
| 574 |
-
"own Hugging Face inference credits, not the owner's — so sign-in is required for this tab.")
|
| 575 |
-
messages = [{"role": "system",
|
| 576 |
-
"content": "You are a helpful, friendly assistant. Answer clearly and briefly."}]
|
| 577 |
-
for turn in history[-12:]:
|
| 578 |
-
if isinstance(turn, dict):
|
| 579 |
-
messages.append({"role": turn.get("role", "user"), "content": as_text(turn.get("content"))})
|
| 580 |
-
else:
|
| 581 |
-
messages.append({"role": "user", "content": as_text(turn[0])})
|
| 582 |
-
if turn[1]:
|
| 583 |
-
messages.append({"role": "assistant", "content": as_text(turn[1])})
|
| 584 |
-
messages.append({"role": "user", "content": as_text(message)})
|
| 585 |
-
try:
|
| 586 |
-
client = InferenceClient(token=oauth_token.token)
|
| 587 |
-
out = client.chat_completion(model=CHAT_MODEL, messages=messages, max_tokens=700)
|
| 588 |
-
return out.choices[0].message.content.strip()
|
| 589 |
-
except Exception as e:
|
| 590 |
-
name = type(e).__name__
|
| 591 |
-
msg = str(e)
|
| 592 |
-
if "credits" in msg.lower() or "quota" in msg.lower() or "402" in msg:
|
| 593 |
-
return "Your Hugging Face inference credits are used up for now. Please try again later."
|
| 594 |
-
return f"The chat service could not be reached ({name}). Please try again in a moment."
|
| 595 |
-
|
| 596 |
-
|
| 597 |
# ---------------------------------------------------------------- The buttons
|
| 598 |
|
| 599 |
@spaces.GPU(duration=gpu_seconds(7), size=GPU_SIZE)
|
|
@@ -829,7 +721,7 @@ def on_open():
|
|
| 829 |
|
| 830 |
with gr.Blocks(title="Graphics Studio") as demo:
|
| 831 |
gr.Markdown("# Graphics Studio\n**FLUX.2 klein** images, **LTX-Video** animation, **MusicGen** music, "
|
| 832 |
-
"**Qwen3** + **Kokoro** narration, **Whisper** transcription,
|
| 833 |
"**Florence-2** image captions, **SmolVLM2** video descriptions, **CLAP** music classification.")
|
| 834 |
counter = gr.Markdown(counts_text())
|
| 835 |
|
|
@@ -882,16 +774,6 @@ with gr.Blocks(title="Graphics Studio") as demo:
|
|
| 882 |
read_button = gr.Button("Read aloud", variant="primary")
|
| 883 |
read_out = gr.Audio(label="Narration", type="filepath", autoplay=False)
|
| 884 |
|
| 885 |
-
with gr.Tab("Chat"):
|
| 886 |
-
if chat_model is not None:
|
| 887 |
-
gr.Markdown("Chat with **Gemma 4 31B** (google), running here in 8-bit. No sign-in needed. "
|
| 888 |
-
"A reply takes a while and uses your own ZeroGPU quota.")
|
| 889 |
-
else:
|
| 890 |
-
gr.Markdown("Chat with hosted **Gemma 4 31B** (google). Sign in with Hugging Face first — each visitor's "
|
| 891 |
-
"reply is billed to their own Hugging Face inference credits, not the owner's.")
|
| 892 |
-
gr.LoginButton()
|
| 893 |
-
gr.ChatInterface(chat)
|
| 894 |
-
|
| 895 |
with gr.Tab("Describe"):
|
| 896 |
gr.Markdown("Three ways to describe what you have: an image (image captioning), a short video "
|
| 897 |
"(video captioning), or a piece of music (music captioning, music classification). "
|
|
|
|
| 5 |
Transcribe tab (speech to text, speech recognition, automatic speech recognition): Whisper large v3 turbo
|
| 6 |
writes down speech from an uploaded file or the microphone, in its own language or translated to English.
|
| 7 |
Narration tab (text to speech, machine speech, speech generation): Kokoro reads your text aloud.
|
|
|
|
| 8 |
Describe tab: three sub-tabs for the describing jobs the Space does.
|
| 9 |
Image to text (image captioning, image recognition): Florence-2 large writes a detailed caption for
|
| 10 |
an uploaded picture.
|
|
|
|
| 22 |
needs onto the GPU, one after another where a job uses several big models. That keeps every job
|
| 23 |
inside the default half-card slice, which is not billed double. If zero_packs is switched off or
|
| 24 |
cannot work, everything is copied on every request as ZeroGPU normally does, on the full card.
|
|
|
|
|
|
|
| 25 |
"""
|
| 26 |
import os
|
| 27 |
|
|
|
|
| 43 |
if _store:
|
| 44 |
os.environ["HF_HOME"] = _store # Must be set before the Hugging Face libraries are imported
|
| 45 |
|
|
|
|
| 46 |
import json
|
| 47 |
import random
|
| 48 |
import re
|
|
|
|
| 63 |
from diffusers import FluxPipeline, LTXConditionPipeline
|
| 64 |
from diffusers.pipelines.ltx.pipeline_ltx_condition import LTXVideoCondition
|
| 65 |
from diffusers.utils import export_to_video
|
|
|
|
| 66 |
from PIL import Image
|
| 67 |
from transformers import (AutoModelForCausalLM, AutoModelForImageTextToText, AutoProcessor,
|
| 68 |
AutoTokenizer, MusicgenForConditionalGeneration, pipeline)
|
|
|
|
| 80 |
VIDEO_CAPTION_MODEL = "HuggingFaceTB/SmolVLM2-2.2B-Instruct" # Video frames to description
|
| 81 |
LISTEN_MODEL = "laion/clap-htsat-unfused" # Recognises genre, mood, instruments and tempo
|
| 82 |
SPEECH_MODEL = "openai/whisper-large-v3-turbo" # Speech to text
|
|
|
|
| 83 |
VOICE = "af_heart" # Kokoro voice
|
| 84 |
VOICE_RATE = 24000
|
| 85 |
VOICES = {"Heart (woman)": "af_heart", "Bella (woman)": "af_bella", "Nicole (woman, soft)": "af_nicole",
|
|
|
|
| 106 |
# Pure per-call .to('cuda') from ordinary RAM was tried on 2026-10-07: the first FLUX move took 79 s.
|
| 107 |
# The packs are read straight from disk at about 17 GB a second, like ZeroGPU's own single pack.
|
| 108 |
# Once a model is sealed, never call .to("cuda") on it again here: its weights are on disk.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
print("[load] image model...", flush=True)
|
| 110 |
try:
|
| 111 |
from diffusers import Flux2KleinPipeline
|
|
|
|
| 169 |
device="cuda", chunk_length_s=30)
|
| 170 |
packs.seal("whisper", SPEECH_MODEL)
|
| 171 |
print("[load] done.", flush=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
|
| 173 |
# With a pack per model every job fits the default half-card slice ("large"), which is billed once.
|
| 174 |
# Without them ZeroGPU copies all the models on every call, and that needs the whole card.
|
|
|
|
| 486 |
return frames, length
|
| 487 |
|
| 488 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 489 |
# ---------------------------------------------------------------- The buttons
|
| 490 |
|
| 491 |
@spaces.GPU(duration=gpu_seconds(7), size=GPU_SIZE)
|
|
|
|
| 721 |
|
| 722 |
with gr.Blocks(title="Graphics Studio") as demo:
|
| 723 |
gr.Markdown("# Graphics Studio\n**FLUX.2 klein** images, **LTX-Video** animation, **MusicGen** music, "
|
| 724 |
+
"**Qwen3** + **Kokoro** narration, **Whisper** transcription, "
|
| 725 |
"**Florence-2** image captions, **SmolVLM2** video descriptions, **CLAP** music classification.")
|
| 726 |
counter = gr.Markdown(counts_text())
|
| 727 |
|
|
|
|
| 774 |
read_button = gr.Button("Read aloud", variant="primary")
|
| 775 |
read_out = gr.Audio(label="Narration", type="filepath", autoplay=False)
|
| 776 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 777 |
with gr.Tab("Describe"):
|
| 778 |
gr.Markdown("Three ways to describe what you have: an image (image captioning), a short video "
|
| 779 |
"(video captioning), or a piece of music (music captioning, music classification). "
|
requirements.txt
CHANGED
|
@@ -15,4 +15,3 @@ huggingface_hub>=0.24.0
|
|
| 15 |
timm
|
| 16 |
einops
|
| 17 |
num2words
|
| 18 |
-
bitsandbytes>=0.46.0
|
|
|
|
| 15 |
timm
|
| 16 |
einops
|
| 17 |
num2words
|
|
|