multimodalart's picture
multimodalart HF Staff
Upload app.py with huggingface_hub
a45bdbf verified
Raw
History Blame Contribute Delete
4.77 kB
import spaces # MUST come before torch / transformers
import torch
import gradio as gr
from transformers import AutoModelForCausalLM, AutoTokenizer
MODEL_ID = "superwhisper/s1-mini"
SYSTEM_PROMPT = (
"You are a text normalizer for speech-to-text transcripts. "
"The input begins with a control line specifying the styling, structure, "
"and context settings; clean the transcript to match those settings "
"and output only the cleaned text."
)
tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
model = AutoModelForCausalLM.from_pretrained(
MODEL_ID,
torch_dtype=torch.bfloat16,
attn_implementation="sdpa",
).to("cuda")
model.eval()
@spaces.GPU(duration=30)
def clean_transcript(
transcript: str,
styling: str = "semi-formal",
structure: str = "prose",
context: str = "general",
) -> str:
"""Clean and normalize a raw ASR transcript.
Applies punctuation, truecasing, filler removal, and formatting based on
the selected styling, structure, and context settings.
Args:
transcript: Raw ASR transcript text (disfluent, unpunctuated).
styling: Register / formality level (casual, semi-casual, semi-formal, formal).
structure: Output structure (prose or lists).
context: Context mode (general or email).
Returns:
Cleaned, normalized transcript as plain text.
"""
control = f"[Styling: {styling}] [Structure: {structure}] [Context: {context}]"
messages = [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": f"{control}\n{transcript}"},
]
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True,
enable_thinking=False,
)
inputs = tokenizer(text, return_tensors="pt").to(model.device)
input_len = inputs.input_ids.shape[1]
max_new = min(1024, int(input_len * 1.3) + 32)
with torch.no_grad():
out = model.generate(
**inputs,
max_new_tokens=max_new,
do_sample=False,
)
generated = out[0][input_len:]
result = tokenizer.decode(generated, skip_special_tokens=True).strip()
return result
CSS = """
#col-container { max-width: 900px; margin: 0 auto; }
.dark .gradio-container { color: var(--body-text-color); }
"""
with gr.Blocks() as demo:
gr.Markdown(
"# S1-mini · ASR Transcript Cleanup\n"
"A 0.6B Qwen3-based model that cleans raw speech-to-text transcripts: "
"removes fillers, resolves self-corrections, adds punctuation and truecasing, "
"and formats numbers/dates/emails — all controlled by styling and structure settings.\n\n"
"Model: [superwhisper/s1-mini](https://huggingface.co/superwhisper/s1-mini)"
)
with gr.Column(elem_id="col-container"):
with gr.Row():
transcript_input = gr.Textbox(
label="Raw ASR Transcript",
placeholder="Paste raw, unpunctuated speech-to-text output here…",
lines=6,
scale=4,
)
with gr.Row():
styling = gr.Dropdown(
choices=["casual", "semi-casual", "semi-formal", "formal"],
value="semi-formal",
label="Styling",
scale=1,
)
structure = gr.Dropdown(
choices=["prose", "lists"],
value="prose",
label="Structure",
scale=1,
)
context = gr.Dropdown(
choices=["general", "email"],
value="general",
label="Context",
scale=1,
)
run_btn = gr.Button("Clean Transcript", variant="primary")
output = gr.Textbox(
label="Cleaned Transcript",
lines=6,
)
run_btn.click(
fn=clean_transcript,
inputs=[transcript_input, styling, structure, context],
outputs=output,
api_name="clean",
)
gr.Examples(
examples=[
["so um i need to like send the the report by uh friday no wait make that thursday"],
["hey can you like um check the the numbers for q3 and also um make sure the the spreadsheet is up to date"],
["hi john um i was wondering if you could um send me the the quarterly report by end of day friday thanks"],
["so the meeting is at um three pm on tuesday and we need to like bring the the slides and also the budget numbers"],
],
inputs=transcript_input,
outputs=output,
fn=clean_transcript,
cache_examples=True,
cache_mode="lazy",
)
demo.launch(mcp_server=True, theme=gr.themes.Citrus(), css=CSS)