Spaces:
Sleeping
Sleeping
File size: 2,686 Bytes
f8f32bf edd7d5a b50ecc9 edd7d5a f8f32bf edd7d5a f8f32bf edd7d5a f8f32bf edd7d5a f8f32bf edd7d5a f8f32bf b50ecc9 f8f32bf edd7d5a f8f32bf edd7d5a b50ecc9 edd7d5a f8f32bf edd7d5a f8f32bf b50ecc9 edd7d5a f8f32bf edd7d5a f8f32bf edd7d5a f8f32bf edd7d5a f8f32bf edd7d5a f8f32bf edd7d5a f8f32bf edd7d5a 8c6189b edd7d5a f8f32bf edd7d5a | 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 | import json
import os
import gradio as gr
import spaces
import torch
import torchaudio
from huggingface_hub import hf_hub_download
from transformers import Wav2Vec2FeatureExtractor, Wav2Vec2ForSequenceClassification
MODEL_ID = os.environ.get("HF_ASR_MODEL", "masumtechnonext/wav2vec2-arabic-letter-verifier")
HF_TOKEN = os.environ.get("HF_TOKEN")
SAMPLE_RATE = 16000
feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(MODEL_ID, token=HF_TOKEN)
model = Wav2Vec2ForSequenceClassification.from_pretrained(MODEL_ID, token=HF_TOKEN)
model.eval()
id2label = {int(k): v for k, v in model.config.id2label.items()}
calibration_path = hf_hub_download(MODEL_ID, "calibration.json", token=HF_TOKEN)
with open(calibration_path) as f:
THRESHOLD = json.load(f)["confidence_threshold"]
UNKNOWN_ID = next(i for i, label in id2label.items() if label == "Unknown")
LETTERS = sorted(label for label in id2label.values() if label != "Unknown")
@spaces.GPU
def predict(audio, target_letter):
if audio is None:
return "Record or upload audio first.", ""
device = "cuda" if torch.cuda.is_available() else "cpu"
model.to(device)
sample_rate, waveform = audio
waveform = torch.tensor(waveform, dtype=torch.float32)
if waveform.ndim > 1:
waveform = waveform.mean(dim=-1)
if sample_rate != SAMPLE_RATE:
waveform = torchaudio.functional.resample(waveform, sample_rate, SAMPLE_RATE)
inputs = feature_extractor(waveform.numpy(), sampling_rate=SAMPLE_RATE, return_tensors="pt")
inputs = {k: v.to(device) for k, v in inputs.items()}
with torch.no_grad():
logits = model(**inputs).logits[0]
probs = torch.softmax(logits, dim=-1)
pred_id = int(torch.argmax(probs))
confidence = float(probs[pred_id])
accepted = confidence >= THRESHOLD and pred_id != UNKNOWN_ID
predicted_label = id2label[pred_id] if accepted else "Unrecognized"
prediction = f"{predicted_label} ({confidence:.1%} confidence)"
if not target_letter:
return prediction, "Pick an expected letter to verify."
is_correct = accepted and predicted_label == target_letter
verdict = "✅ Correct" if is_correct else "❌ Incorrect"
return prediction, verdict
demo = gr.Interface(
fn=predict,
inputs=[
gr.Audio(sources=["microphone", "upload"], type="numpy", label="Speak the letter"),
gr.Dropdown(choices=LETTERS, label="Expected letter", value=LETTERS[0]),
],
outputs=[
gr.Textbox(label="Prediction"),
gr.Textbox(label="Verification"),
],
title="Arabic Letter Verifier",
description=f"Model: {MODEL_ID}",
)
if __name__ == "__main__":
demo.launch()
|