Spaces:
Sleeping
Sleeping
File size: 3,459 Bytes
866375a f7ecc76 866375a f7ecc76 866375a f7ecc76 866375a f7ecc76 866375a f7ecc76 866375a f7ecc76 866375a add0255 866375a add0255 866375a 5469832 add0255 866375a 8656a89 add0255 5469832 866375a 5469832 f7ecc76 866375a f7ecc76 866375a f7ecc76 866375a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | #!/usr/bin/env python3
# ------------------------------------------------------------
# Whisper Small LS-100 Demo (local or Hugging Face Spaces)
# Author: Murali Chandran (codeninja3d)
# ------------------------------------------------------------
import torch
import torchaudio
import gradio as gr
from transformers import WhisperProcessor, WhisperForConditionalGeneration
# -------------------------------
# Config
# -------------------------------
MODEL_ID = "codeninja3d/whisper-small-ls100"
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
# print(f"β
Loading model from: {MODEL_ID}")
processor = WhisperProcessor.from_pretrained(MODEL_ID)
model = WhisperForConditionalGeneration.from_pretrained(MODEL_ID).to(DEVICE).eval()
# print(f"β
#Params: {sum(p.numel() for p in model.parameters()) / 1e6:.2f}M")
# print("β
Sample rate:", processor.feature_extractor.sampling_rate)
# -------------------------------
# Transcribe function
# -------------------------------
def transcribe(audio, language, task):
if audio is None:
return "β οΈ Please record or upload an audio clip."
# Handle tuple (mic) or file path (upload)
if isinstance(audio, tuple):
sr, waveform_np = audio
waveform = torch.tensor(waveform_np, dtype=torch.float32)
if waveform.ndim > 1: # [samples, channels] β [1, samples]
waveform = waveform.mean(dim=-1, keepdim=True).T
else:
waveform, sr = torchaudio.load(audio)
# Ensure mono and correct shape [1, samples]
if waveform.ndim > 1:
waveform = waveform.mean(dim=0, keepdim=True)
# Resample to 16 kHz
if sr != 16000:
waveform = torchaudio.functional.resample(waveform, sr, 16000)
sr = 16000
# β
Normalize amplitude to [-1, 1]
waveform = waveform / waveform.abs().max()
# β
Force 1D numpy array (no 2D padding issues)
waveform_np = waveform.squeeze().numpy().astype("float32")
# Preprocess
inputs = processor.feature_extractor(
waveform_np,
sampling_rate=sr,
return_tensors="pt"
).to(DEVICE)
# print(f"[DEBUG] waveform shape: {waveform.shape}, dtype: {waveform.dtype}, sr={sr}")
# print(f"[DEBUG] min={waveform.min().item():.3f}, max={waveform.max().item():.3f}, mean={waveform.mean().item():.3f}")
# Decoder setup
forced_decoder_ids = processor.get_decoder_prompt_ids(language="en", task="transcribe")
# print("[DEBUG] forced_decoder_ids:", forced_decoder_ids)
with torch.no_grad():
pred_ids = model.generate(
**inputs,
forced_decoder_ids=forced_decoder_ids,
max_new_tokens=256,
num_beams=5,
no_repeat_ngram_size=3,
repetition_penalty=1.2,
early_stopping=True
)
text = processor.tokenizer.batch_decode(pred_ids, skip_special_tokens=True)[0]
return text.strip()
# -------------------------------
# Gradio Interface
# -------------------------------
iface = gr.Interface(
fn=transcribe,
inputs=[
gr.Audio(type="numpy", label="ποΈ Record or Upload Audio"),
],
outputs=gr.Textbox(label="π Transcription"),
title="Whisper Small LS-100 (Fine-tuned)",
description="Upload or record audio to test Murali's fine-tuned Whisper model on LibriSpeech-100.",
theme="soft",
allow_flagging="auto"
)
iface.launch(server_name="0.0.0.0", server_port=7860)
|