Ricky01anjay commited on
Commit
94561ca
·
verified ·
1 Parent(s): 41a36e7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -66
app.py CHANGED
@@ -1,80 +1,70 @@
1
- """
2
- Whisper Audio-to-Text – ZeroGPU edition
3
- Runs on 🤗 Spaces with ZeroGPU (A100) accelerator
4
- """
5
  import os
 
6
  import tempfile
7
- import gradio as gr
8
- import whisper
9
- import numpy as np
10
- from huggingface_hub import hf_hub_download
11
 
12
- # ------------------------------------------------------------------
13
- # 1. ZeroGPU decorator
14
- # ------------------------------------------------------------------
15
- import spaces # pip install huggingface-hub>=0.16
16
 
17
- # ------------------------------------------------------------------
18
- # 2. Load model once per GPU worker
19
- # ------------------------------------------------------------------
20
- MODEL_ID = "openai/whisper-base" # pick any HF whisper ckpt
21
- MODEL = None
22
 
23
- def _load_model():
24
- global MODEL
25
- if MODEL is None:
26
- # download weights from HF hub (cached)
27
- ckpt = hf_hub_download(repo_id=MODEL_ID, filename="pytorch_model.bin")
28
- MODEL = whisper.load_model("base") # still uses same weights
29
- return MODEL
30
 
31
- # ------------------------------------------------------------------
32
- # 3. GPU-decorated transcription
33
- # ------------------------------------------------------------------
34
- @spaces.GPU
35
- def transcribe(audio):
36
  """
37
- audio: filepath (upload) or (sr, data) tuple (mic)
38
- returns: transcribed text
39
  """
40
- if audio is None:
41
- return "⚠️ No audio received."
 
 
 
 
 
 
42
 
43
- # ---- handle microphone ----
44
- if isinstance(audio, tuple):
45
- sr, data = audio
46
- data = data.astype(np.float32)
47
- if np.abs(data).max() > 1.0:
48
- data /= np.abs(data).max()
49
- with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmp:
50
- import soundfile as sf
51
- sf.write(tmp.name, data, sr)
52
- audio_path = tmp.name
53
- else:
54
- audio_path = audio
55
 
56
- # ---- run Whisper on GPU ----
57
- try:
58
- model = _load_model()
59
- result = model.transcribe(audio_path, fp16=True) # fp16 OK on GPU
60
- text = result["text"].strip()
61
- return text if text else "🤷‍♂️ No speech detected."
 
 
 
 
 
 
 
 
 
 
 
62
  except Exception as e:
63
- return f" Error: {e}"
 
64
  finally:
65
- if audio_path != audio and os.path.exists(audio_path):
66
- os.unlink(audio_path)
67
-
68
- # ------------------------------------------------------------------
69
- # 4. Gradio UI (unchanged)
70
- # ------------------------------------------------------------------
71
- demo = gr.Interface(
72
- fn=transcribe,
73
- inputs=gr.Audio(sources=["upload", "microphone"], type="filepath"),
74
- outputs=gr.Textbox(label="Transcription", lines=6),
75
- title="🎙️ Whisper Audio-to-Text (ZeroGPU)",
76
- description="Upload or record audio → instant transcription on A100.",
77
- )
78
 
79
  if __name__ == "__main__":
80
- demo.launch()
 
 
 
 
 
 
1
  import os
2
+ import requests
3
  import tempfile
4
+ import uvicorn
5
+ from fastapi import FastAPI, HTTPException, Query
6
+ from faster_whisper import WhisperModel
 
7
 
8
+ # 1. Inisialisasi FastAPI
9
+ app = FastAPI(title="Open Whisper API (No Limits)")
 
 
10
 
11
+ # 2. Inisialisasi Model (Base sudah cukup akurat dan cepat)
12
+ # Gunakan device="cuda" jika server punya GPU NVIDIA
13
+ model_size = "base"
14
+ print(f"Loading Whisper model '{model_size}'...")
15
+ model = WhisperModel(model_size, device="cpu", compute_type="int8")
16
 
17
+ @app.get("/")
18
+ def home():
19
+ return {"status": "API Active", "usage": "/generate?url=YOUR_AUDIO_URL"}
 
 
 
 
20
 
21
+ @app.get("/generate")
22
+ async def generate_transcription(url: str = Query(..., description="URL file audio (mp3, wav, m4a, dll)")):
 
 
 
23
  """
24
+ Menerima URL audio, mendownloadnya, dan mengembalikan teks hasil transkripsi.
 
25
  """
26
+ tmp_path = None
27
+ try:
28
+ # 3. Download file dari URL ke folder temp
29
+ suffix = ".wav" # Default suffix
30
+ if "." in url:
31
+ potential_ext = "." + url.split(".")[-1].split("?")[0]
32
+ if len(potential_ext) <= 5:
33
+ suffix = potential_ext
34
 
35
+ with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as tmp:
36
+ response = requests.get(url, stream=True, timeout=30)
37
+ response.raise_for_status() # Cek jika download gagal
38
+
39
+ for chunk in response.iter_content(chunk_size=8192):
40
+ tmp.write(chunk)
41
+ tmp_path = tmp.name
 
 
 
 
 
42
 
43
+ # 4. Proses Transkripsi
44
+ print(f"Processing: {url}")
45
+ segments, info = model.transcribe(tmp_path, beam_size=5)
46
+
47
+ full_text = " ".join([segment.text for segment in segments]).strip()
48
+
49
+ # 5. Kembalikan Response JSON
50
+ return {
51
+ "success": True,
52
+ "language": info.language,
53
+ "language_probability": info.language_probability,
54
+ "text": full_text,
55
+ "url_processed": url
56
+ }
57
+
58
+ except requests.exceptions.RequestException as e:
59
+ raise HTTPException(status_code=400, detail=f"Gagal mendownload file: {str(e)}")
60
  except Exception as e:
61
+ raise HTTPException(status_code=500, detail=f"Internal Error: {str(e)}")
62
+
63
  finally:
64
+ # 6. Bersihkan file sementara
65
+ if tmp_path and os.path.exists(tmp_path):
66
+ os.remove(tmp_path)
 
 
 
 
 
 
 
 
 
 
67
 
68
  if __name__ == "__main__":
69
+ # Jalankan server
70
+ uvicorn.run(app, host="0.0.0.0", port=7860)