jojonocode commited on
Commit
782ca36
·
verified ·
1 Parent(s): 7328021

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -54
app.py CHANGED
@@ -1,71 +1,72 @@
 
1
  import gradio as gr
2
- import torch
3
  import librosa
4
  import numpy as np
5
- from transformers import WhisperProcessor, WhisperForConditionalGeneration, pipeline
 
6
 
7
- # Configuration du modèle basée sur vos logs [cite: 53]
8
  MODEL_NAME = "abiyo27/whisper-small-ewe-2"
9
- device = "cuda" if torch.cuda.is_available() else "cpu"
10
- torch_dtype = torch.float16 if torch.cuda.is_available() else torch.float32
11
 
12
- # Chargement optimisé du processeur et du modèle [cite: 55, 57]
13
- processor = WhisperProcessor.from_pretrained(MODEL_NAME)
14
- model = WhisperForConditionalGeneration.from_pretrained(
15
- MODEL_NAME,
16
- torch_dtype=torch_dtype
17
- ).to(device)
 
 
18
 
19
- # Création d'une pipeline pour la rapidité et la gestion automatique du chunking
20
- pipe = pipeline(
21
- "automatic-speech-recognition",
22
- model=model,
23
- tokenizer=processor.tokenizer,
24
- feature_extractor=processor.feature_extractor,
25
- model_kwargs={"torch_dtype": torch_dtype},
26
- device=device,
27
- )
28
 
29
- def transcribe(audio, state=""):
30
- """
31
- Fonction de transcription robuste gérant les fichiers et le microphone.
32
- """
33
  if audio is None:
34
- return state
35
-
36
- # Chargement et rééchantillonnage à 16000Hz comme requis [cite: 59, 65]
37
  sr, y = audio
38
  y = y.astype(np.float32)
39
- y /= np.max(np.abs(y)) if np.max(np.abs(y)) > 0 else 1
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
- # Transcription via pipeline (plus rapide pour les longs fichiers)
42
- # On force la tâche de transcription comme spécifié dans vos logs [cite: 69]
43
- result = pipe(
44
- {"sampling_rate": sr, "raw": y},
45
- generate_kwargs={"task": "transcribe", "max_new_tokens": 256}
46
- )
47
 
48
- return result["text"]
 
 
49
 
50
  def stream_transcribe(audio, state=""):
51
- """
52
- Version optimisée pour le streaming temps réel.
53
- """
54
- if audio is None:
55
  return state
56
 
57
- # Traitement rapide par segments
58
- sr, y = audio
59
- y = y.astype(np.float32)
60
- y /= np.max(np.abs(y)) if np.max(np.abs(y)) > 0 else 1
61
 
62
- result = pipe({"sampling_rate": sr, "raw": y})
63
- return result["text"]
64
 
65
- # Interface Gradio
66
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
67
- gr.Markdown(f"# 🎙️ Ewe STT - ")
68
- gr.Markdown("Transcription automatique du français vers l'Ewe ou transcription directe de l'Ewe.")
69
 
70
  with gr.Tabs():
71
  # Onglet 1: Fichier et Enregistrement classique
@@ -75,17 +76,17 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
75
  with gr.Row():
76
  transcribe_btn = gr.Button("Transcrire", variant="primary")
77
  output_text = gr.Textbox(label="Transcription Ewe", placeholder="Le texte apparaîtra ici...")
78
-
79
  transcribe_btn.click(
80
  fn=transcribe,
81
  inputs=audio_input,
82
  outputs=output_text,
83
- api_name="predict" # Point d'accès API standard
84
  )
85
 
86
  # Onglet 2: Streaming temps réel
87
  with gr.TabItem("Temps Réel (Streaming)"):
88
- gr.Markdown("*Note: Parle et regarde *")
89
  stream_input = gr.Audio(
90
  label="Microphone",
91
  sources=["microphone"],
@@ -93,7 +94,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
93
  type="numpy"
94
  )
95
  stream_output = gr.Textbox(label="Flux de transcription direct")
96
-
97
  stream_input.stream(
98
  fn=stream_transcribe,
99
  inputs=stream_input,
@@ -102,10 +103,11 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
102
  )
103
 
104
  gr.HTML("""
105
- <div style="text-align: center; color: #666;">
106
- Modèle utilisé : <b>yawo stt-ewe-2</b> | O(FP16)
107
  </div>
108
  """)
109
 
110
  if __name__ == "__main__":
 
111
  demo.queue().launch()
 
1
+ import os
2
  import gradio as gr
 
3
  import librosa
4
  import numpy as np
5
+ import ctranslate2
6
+ from faster_whisper import WhisperModel
7
 
8
+ # --- 1. CONFIGURATION ET CONVERSION DU MODÈLE ---
9
  MODEL_NAME = "abiyo27/whisper-small-ewe-2"
10
+ CT2_MODEL_DIR = "whisper-small-ewe-2-ct2"
 
11
 
12
+ # Si le modèle n'a pas encore été converti, on le fait au démarrage
13
+ if not os.path.exists(CT2_MODEL_DIR):
14
+ print(f"⏳ Conversion de {MODEL_NAME} au format CTranslate2 (int8)...")
15
+ print("Cela prendra environ une minute au premier lancement.")
16
+ # On télécharge et on convertit ton modèle HF en int8 (optimisé CPU)
17
+ converter = ctranslate2.converters.TransformersConverter(MODEL_NAME)
18
+ converter.convert(output_dir=CT2_MODEL_DIR, quantization="int8")
19
+ print("✅ Conversion terminée !")
20
 
21
+ # --- 2. CHARGEMENT OPTIMISÉ (FASTER-WHISPER) ---
22
+ print("🚀 Chargement du modèle faster-whisper en mémoire...")
23
+ # compute_type="int8" est le secret pour une vitesse fulgurante sur CPU
24
+ model = WhisperModel(CT2_MODEL_DIR, device="cpu", compute_type="int8", cpu_threads=2)
 
 
 
 
 
25
 
26
+ # --- 3. FONCTIONS DE TRAITEMENT ---
27
+ def preprocess_audio(audio):
28
+ """Gère le rééchantillonnage strict à 16kHz de manière optimisée."""
 
29
  if audio is None:
30
+ return None
 
 
31
  sr, y = audio
32
  y = y.astype(np.float32)
33
+ # Normalisation
34
+ if np.max(np.abs(y)) > 0:
35
+ y /= np.max(np.abs(y))
36
+ # Faster-whisper exige 16000Hz
37
+ if sr != 16000:
38
+ y = librosa.resample(y, orig_sr=sr, target_sr=16000)
39
+ return y
40
+
41
+ def transcribe(audio, state=""):
42
+ """Transcription de fichier ou micro complet."""
43
+ y = preprocess_audio(audio)
44
+ if y is None:
45
+ return state
46
 
47
+ # beam_size=5 donne une bonne précision. task="transcribe" forcé.
48
+ segments, info = model.transcribe(y, beam_size=5, task="transcribe")
 
 
 
 
49
 
50
+ # On assemble les segments de texte générés
51
+ text = " ".join([segment.text for segment in segments])
52
+ return text.strip()
53
 
54
  def stream_transcribe(audio, state=""):
55
+ """Transcription pour le streaming (plus agressive sur la vitesse)."""
56
+ y = preprocess_audio(audio)
57
+ if y is None:
 
58
  return state
59
 
60
+ # beam_size=1 pour privilégier la vitesse extrême en streaming
61
+ segments, info = model.transcribe(y, beam_size=1, task="transcribe")
 
 
62
 
63
+ text = " ".join([segment.text for segment in segments])
64
+ return text.strip()
65
 
66
+ # --- 4. INTERFACE GRADIO ---
67
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
68
+ gr.Markdown(f"# 🎙️ Ewe STT - Faster Whisper CPU")
69
+ gr.Markdown("Transcription ultra-rapide optimisée pour processeur. Traduction automatique du français vers l'Ewe ou transcription directe.")
70
 
71
  with gr.Tabs():
72
  # Onglet 1: Fichier et Enregistrement classique
 
76
  with gr.Row():
77
  transcribe_btn = gr.Button("Transcrire", variant="primary")
78
  output_text = gr.Textbox(label="Transcription Ewe", placeholder="Le texte apparaîtra ici...")
79
+
80
  transcribe_btn.click(
81
  fn=transcribe,
82
  inputs=audio_input,
83
  outputs=output_text,
84
+ api_name="predict"
85
  )
86
 
87
  # Onglet 2: Streaming temps réel
88
  with gr.TabItem("Temps Réel (Streaming)"):
89
+ gr.Markdown("*Note : Le streaming sur CPU gratuit reste expérimental, parlez clairement.*")
90
  stream_input = gr.Audio(
91
  label="Microphone",
92
  sources=["microphone"],
 
94
  type="numpy"
95
  )
96
  stream_output = gr.Textbox(label="Flux de transcription direct")
97
+
98
  stream_input.stream(
99
  fn=stream_transcribe,
100
  inputs=stream_input,
 
103
  )
104
 
105
  gr.HTML("""
106
+ <div style="text-align: center; color: #666; margin-top: 20px;">
107
+ Modèle utilisé : <b>yawo stt-ewe-2</b> | Optimisation : <b>CTranslate2 (INT8)</b>
108
  </div>
109
  """)
110
 
111
  if __name__ == "__main__":
112
+ # La queue est importante pour gérer plusieurs requêtes sans planter le CPU
113
  demo.queue().launch()