Spaces:
Sleeping
Sleeping
Upload 4 files
Browse files- .gitattributes +35 -35
- README.md +42 -15
- app.py +82 -69
- requirements.txt +16 -0
.gitattributes
CHANGED
|
@@ -1,35 +1,35 @@
|
|
| 1 |
-
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
-
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
-
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
-
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
-
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
-
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
-
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
-
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
-
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
-
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
-
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
-
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
-
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
-
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
-
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
-
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
-
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
-
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
-
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
-
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
-
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
-
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
-
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
-
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
-
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
-
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
-
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
-
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
-
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
-
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
-
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
README.md
CHANGED
|
@@ -1,15 +1,42 @@
|
|
| 1 |
-
---
|
| 2 |
-
title: GTROX
|
| 3 |
-
emoji: ๐ฌ
|
| 4 |
-
colorFrom: yellow
|
| 5 |
-
colorTo: purple
|
| 6 |
-
sdk: gradio
|
| 7 |
-
sdk_version: 6.5.1
|
| 8 |
-
app_file: app.py
|
| 9 |
-
pinned:
|
| 10 |
-
hf_oauth: true
|
| 11 |
-
hf_oauth_scopes:
|
| 12 |
-
- inference-api
|
| 13 |
-
---
|
| 14 |
-
|
| 15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: GTROX
|
| 3 |
+
emoji: ๐ฌ
|
| 4 |
+
colorFrom: yellow
|
| 5 |
+
colorTo: purple
|
| 6 |
+
sdk: gradio
|
| 7 |
+
sdk_version: 6.5.1
|
| 8 |
+
app_file: app.py
|
| 9 |
+
pinned: true
|
| 10 |
+
hf_oauth: true
|
| 11 |
+
hf_oauth_scopes:
|
| 12 |
+
- inference-api
|
| 13 |
+
---
|
| 14 |
+
|
| 15 |
+
# ๐๏ธ GTROX: Speech Insight Coach
|
| 16 |
+
|
| 17 |
+
**GTROX** is an AI-powered speech analysis tool designed to help you improve your fluency, pacing, and clarity. By leveraging advanced speech-to-text models and compact, high-performance Language Models (SLMs), it provides actionable, real-time coaching feedback based on your audio input.
|
| 18 |
+
|
| 19 |
+
## โจ Key Features
|
| 20 |
+
|
| 21 |
+
* **Fluency Tracking:** Instantly calculate your Words Per Minute (WPM) to master your speaking pace.
|
| 22 |
+
* **Silence Analysis:** Identify how much of your speech consists of pauses and filler time.
|
| 23 |
+
* **AI Coaching:** Get personalized, constructive tips generated by a specialized Language Model to improve your delivery.
|
| 24 |
+
* **Robust Pipeline:** Engineered for high performance, utilizing efficient audio processing without heavy external dependencies.
|
| 25 |
+
|
| 26 |
+
## ๐ ๏ธ How It Works
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
1. **Input:** The system processes your uploaded `.wav` file or live microphone recording.
|
| 31 |
+
2. **Analysis:** It calculates technical metrics like WPM and silence ratios using numerical analysis.
|
| 32 |
+
3. **Transcription:** Uses `distil-whisper` for highly accurate, low-latency speech-to-text.
|
| 33 |
+
4. **Feedback:** The `SmolLM2` language model analyzes your performance and suggests improvements.
|
| 34 |
+
|
| 35 |
+
## ๐ Deployment
|
| 36 |
+
|
| 37 |
+
This app is built with **Gradio** and hosted on **Hugging Face Spaces**. It is optimized for low-latency inference, making it suitable for quick fluency checks on the go.
|
| 38 |
+
|
| 39 |
+
## ๐ฆ Requirements
|
| 40 |
+
|
| 41 |
+
To run this application locally, ensure you have Python 3.10+ and the necessary dependencies installed:
|
| 42 |
+
|
app.py
CHANGED
|
@@ -1,69 +1,82 @@
|
|
| 1 |
-
import gradio as gr
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import librosa
|
| 3 |
+
import numpy as np
|
| 4 |
+
import torch
|
| 5 |
+
import soundfile as sf
|
| 6 |
+
from transformers import pipeline
|
| 7 |
+
import os
|
| 8 |
+
|
| 9 |
+
# 1. Model Initialization
|
| 10 |
+
# We set to 'cpu' as default for broader compatibility, but it will detect 'cuda' if available.
|
| 11 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 12 |
+
|
| 13 |
+
# Transcriber: Fast, efficient speech-to-text
|
| 14 |
+
transcriber = pipeline("automatic-speech-recognition",
|
| 15 |
+
model="distil-whisper/distil-small.en",
|
| 16 |
+
device=device,
|
| 17 |
+
return_timestamps=True
|
| 18 |
+
)
|
| 19 |
+
|
| 20 |
+
# Coach: Small Language Model for feedback
|
| 21 |
+
coach = pipeline("text-generation",
|
| 22 |
+
model="HuggingFaceTB/SmolLM2-1.7B-Instruct",
|
| 23 |
+
device=device)
|
| 24 |
+
|
| 25 |
+
def analyze_speech(audio_path):
|
| 26 |
+
if audio_path is None:
|
| 27 |
+
return "Please upload an audio file."
|
| 28 |
+
|
| 29 |
+
# 1. Load Data
|
| 30 |
+
try:
|
| 31 |
+
data, sr = sf.read(audio_path)
|
| 32 |
+
if len(data.shape) > 1: data = data.mean(axis=1)
|
| 33 |
+
if sr != 16000:
|
| 34 |
+
data = librosa.resample(data, orig_sr=sr, target_sr=16000)
|
| 35 |
+
except Exception as e:
|
| 36 |
+
return f"Error loading audio: {str(e)}"
|
| 37 |
+
|
| 38 |
+
# 2. Transcription (Using optimized chunking)
|
| 39 |
+
# This prevents the "long-form" 30s crash
|
| 40 |
+
try:
|
| 41 |
+
# Pass the array and sample rate directly
|
| 42 |
+
result = transcriber({"raw": data, "sampling_rate": 16000})
|
| 43 |
+
text = result["text"]
|
| 44 |
+
except Exception as e:
|
| 45 |
+
return f"Transcription error: {str(e)}"
|
| 46 |
+
|
| 47 |
+
# 3. Metrics
|
| 48 |
+
duration = len(data) / 16000
|
| 49 |
+
wpm = (len(text.split()) / (duration / 60)) if duration > 0 else 0
|
| 50 |
+
silence_ratio = np.sum(np.abs(data) < 0.01) / len(data)
|
| 51 |
+
|
| 52 |
+
# 4. Feedback
|
| 53 |
+
prompt = (
|
| 54 |
+
f"You are a professional speech coach. The user spoke at {wpm:.1f} WPM with {silence_ratio:.1%} silence. "
|
| 55 |
+
f"Transcript: '{text}'. "
|
| 56 |
+
"Provide exactly 2 short, constructive tips to improve their delivery, focusing on pacing and clarity."
|
| 57 |
+
)
|
| 58 |
+
try:
|
| 59 |
+
# Simplified generation call
|
| 60 |
+
feedback = coach(prompt, max_new_tokens=100)[0]['generated_text']
|
| 61 |
+
except Exception as e:
|
| 62 |
+
feedback = "Could not generate feedback."
|
| 63 |
+
|
| 64 |
+
return f"๐ Transcription: {text}\n\n๐ Metrics: {wpm:.1f} WPM, Silence: {silence_ratio:.1%}\n\n๐ก Coach Feedback:\n{feedback}"
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
# 2. UI Layout
|
| 68 |
+
with gr.Blocks() as demo:
|
| 69 |
+
gr.Markdown("# ๐๏ธ ImproveTalk: Speech Insight Coach")
|
| 70 |
+
gr.Markdown("Upload your `.wav` file to get instant feedback on your fluency.")
|
| 71 |
+
|
| 72 |
+
with gr.Row():
|
| 73 |
+
# audio_input = gr.Audio(type="filepath", label="Upload WAV Audio")
|
| 74 |
+
audio_input = gr.Audio(type="filepath", label="Record or Upload Audio",sources=["microphone", "upload"])
|
| 75 |
+
analyze_btn = gr.Button("Analyze My Speech", variant="primary")
|
| 76 |
+
|
| 77 |
+
results = gr.Textbox(label="Analysis Results", lines=10)
|
| 78 |
+
|
| 79 |
+
analyze_btn.click(analyze_speech, inputs=audio_input, outputs=results)
|
| 80 |
+
|
| 81 |
+
if __name__ == "__main__":
|
| 82 |
+
demo.launch()
|
requirements.txt
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# UI Framework
|
| 2 |
+
gradio>=5.0.0
|
| 3 |
+
|
| 4 |
+
# Core AI/ML Libraries
|
| 5 |
+
torch>=2.0.0
|
| 6 |
+
transformers>=4.40.0
|
| 7 |
+
accelerate>=0.30.0
|
| 8 |
+
|
| 9 |
+
# Audio Processing
|
| 10 |
+
librosa>=0.10.0
|
| 11 |
+
soundfile>=0.12.0
|
| 12 |
+
numpy>=1.26.0
|
| 13 |
+
|
| 14 |
+
# Inference Optimization (Crucial for Small Models)
|
| 15 |
+
bitsandbytes>=0.43.0
|
| 16 |
+
|