Ronaldodev commited on
Commit
ff30a18
·
1 Parent(s): 50e0de0

[ADD] app.py files

Browse files
.idea/.gitignore ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ # Default ignored files
2
+ /shelf/
3
+ /workspace.xml
4
+ # Editor-based HTTP Client requests
5
+ /httpRequests/
.idea/inspectionProfiles/Project_Default.xml ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
5
+ <option name="ignoredPackages">
6
+ <list>
7
+ <option value="aiohappyeyeballs" />
8
+ <option value="aiohttp" />
9
+ <option value="aiosignal" />
10
+ <option value="annotated-types" />
11
+ <option value="anyio" />
12
+ <option value="attrs" />
13
+ <option value="click" />
14
+ <option value="fastapi" />
15
+ <option value="frozenlist" />
16
+ <option value="h11" />
17
+ <option value="idna" />
18
+ <option value="multidict" />
19
+ <option value="propcache" />
20
+ <option value="pydantic" />
21
+ <option value="pydantic_core" />
22
+ <option value="sniffio" />
23
+ <option value="starlette" />
24
+ <option value="typing-inspection" />
25
+ <option value="typing_extensions" />
26
+ <option value="uvicorn" />
27
+ <option value="yarl" />
28
+ </list>
29
+ </option>
30
+ </inspection_tool>
31
+ </profile>
32
+ </component>
.idea/inspectionProfiles/profiles_settings.xml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <component name="InspectionProjectProfileManager">
2
+ <settings>
3
+ <option name="USE_PROJECT_PROFILE" value="false" />
4
+ <version value="1.0" />
5
+ </settings>
6
+ </component>
.idea/misc.xml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="Black">
4
+ <option name="sdkName" value="Python 3.11 (stt-fongbe)" />
5
+ </component>
6
+ <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (stt-fongbe)" project-jdk-type="Python SDK" />
7
+ </project>
.idea/modules.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/stt-fongbe.iml" filepath="$PROJECT_DIR$/.idea/stt-fongbe.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
.idea/stt-fongbe.iml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="PYTHON_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$" />
5
+ <orderEntry type="jdk" jdkName="Python 3.11 (stt-fongbe)" jdkType="Python SDK" />
6
+ <orderEntry type="sourceFolder" forTests="false" />
7
+ </component>
8
+ </module>
.idea/vcs.xml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="Git" />
5
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
6
+ </component>
7
+ </project>
app.py ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import torchaudio
4
+ import librosa
5
+ import os
6
+ from transformers import AutoProcessor, AutoModelForSpeechSeq2Seq
7
+ from huggingface_hub import login
8
+ import logging
9
+
10
+ # Configuration
11
+ MODEL_NAME = "Ronaldodev/speech-to-text-fongbe"
12
+ HF_TOKEN = os.environ.get("HF_TOKEN")
13
+
14
+ # Variables globales
15
+ model = None
16
+ processor = None
17
+
18
+ # Configuration logging
19
+ logging.basicConfig(level=logging.INFO)
20
+ logger = logging.getLogger(__name__)
21
+
22
+
23
+ def load_model():
24
+ """Charger le modèle privé au démarrage"""
25
+ global model, processor
26
+
27
+ try:
28
+ logger.info("🔄 Chargement du modèle privé...")
29
+
30
+ if not HF_TOKEN:
31
+ raise ValueError("HF_TOKEN non configuré dans les secrets")
32
+
33
+ # Login avec token privé
34
+ login(token=HF_TOKEN)
35
+ logger.info("✅ Authentification HF réussie")
36
+
37
+ # Charger le modèle et processeur
38
+ model = AutoModelForSpeechSeq2Seq.from_pretrained(MODEL_NAME)
39
+ processor = AutoProcessor.from_pretrained(MODEL_NAME)
40
+
41
+ logger.info("✅ Modèle chargé avec succès!")
42
+ return True
43
+
44
+ except Exception as e:
45
+ logger.error(f"❌ Erreur chargement: {e}")
46
+ return False
47
+
48
+
49
+ def transcribe(audio):
50
+ """Fonction principale de transcription"""
51
+
52
+ # Vérifier si le modèle est chargé
53
+ if model is None or processor is None:
54
+ return "❌ Erreur: Modèle non chargé. Vérifiez les logs."
55
+
56
+ # Vérifier si un audio est fourni
57
+ if audio is None:
58
+ return "❌ Aucun fichier audio fourni"
59
+
60
+ try:
61
+ logger.info(f"🎵 Traitement audio: {audio}")
62
+
63
+ # Charger l'audio avec fallback
64
+ try:
65
+ waveform, sample_rate = torchaudio.load(audio)
66
+ logger.info(f"✅ Audio chargé avec torchaudio: {sample_rate}Hz")
67
+ except Exception as e:
68
+ logger.warning(f"⚠️ Torchaudio échoué, essai librosa: {e}")
69
+ waveform, sample_rate = librosa.load(audio, sr=None)
70
+ waveform = torch.tensor(waveform).unsqueeze(0)
71
+ logger.info(f"✅ Audio chargé avec librosa: {sample_rate}Hz")
72
+
73
+ # Conversion mono si nécessaire
74
+ if waveform.shape[0] > 1:
75
+ waveform = waveform.mean(dim=0, keepdim=True)
76
+ logger.info("🔄 Conversion stéréo → mono")
77
+
78
+ # Resampling à 16kHz si nécessaire
79
+ if sample_rate != 16000:
80
+ logger.info(f"🔄 Resampling {sample_rate}Hz → 16000Hz")
81
+ resampler = torchaudio.transforms.Resample(sample_rate, 16000)
82
+ waveform = resampler(waveform)
83
+
84
+ # Préparation des inputs
85
+ inputs = processor(
86
+ waveform.squeeze(),
87
+ sampling_rate=16000,
88
+ return_tensors="pt"
89
+ )
90
+
91
+ # Génération de la transcription
92
+ logger.info("🔄 Génération de la transcription...")
93
+ with torch.no_grad():
94
+ result = model.generate(
95
+ **inputs,
96
+ max_length=500,
97
+ do_sample=False,
98
+ num_beams=1
99
+ )
100
+
101
+ # Décodage
102
+ transcription = processor.batch_decode(result, skip_special_tokens=True)[0]
103
+
104
+ logger.info(f"✅ Transcription réussie: '{transcription}'")
105
+ return transcription.strip()
106
+
107
+ except Exception as e:
108
+ error_msg = f"❌ Erreur de transcription: {str(e)}"
109
+ logger.error(error_msg)
110
+ return error_msg
111
+
112
+
113
+ # Charger le modèle au démarrage
114
+ print("🚀 DÉMARRAGE API STT FONGBÉ - RONALDODEV")
115
+ print("=" * 50)
116
+
117
+ if load_model():
118
+ print("✅ Modèle chargé - Interface prête!")
119
+ model_status = "✅ Modèle chargé et prêt"
120
+ else:
121
+ print("❌ Erreur de chargement du modèle")
122
+ model_status = "❌ Erreur de chargement"
123
+
124
+ # Interface Gradio simple
125
+ demo = gr.Interface(
126
+ fn=transcribe,
127
+ inputs=gr.Audio(
128
+ sources=["upload", "microphone"],
129
+ type="filepath",
130
+ label="🎤 Uploadez un fichier ou enregistrez directement"
131
+ ),
132
+ outputs=gr.Textbox(
133
+ label="📝 Transcription en Fongbé",
134
+ placeholder="La transcription apparaîtra ici...",
135
+ lines=3
136
+ ),
137
+ title="🎤 API STT Fongbé - Ronaldodev",
138
+ description=f"""
139
+ **Reconnaissance vocale pour la langue Fongbé**
140
+
141
+ Uploadez un fichier audio (WAV, MP3, M4A) ou enregistrez directement avec votre microphone.
142
+
143
+ **Statut:** {model_status}
144
+
145
+ **Modèle:** `{MODEL_NAME}`
146
+ """,
147
+ article="""
148
+ ## 🔌 API pour développeurs
149
+
150
+ Cette interface expose automatiquement une API REST :
151
+
152
+ **Endpoint:** `POST /api/predict`
153
+
154
+ **Exemple d'utilisation:**
155
+ ```python
156
+ import requests
157
+
158
+ response = requests.post(
159
+ "https://ronaldodev-stt-fongbe.hf.space/api/predict",
160
+ json={"data": [audio_file_path]}
161
+ )
162
+
163
+ transcription = response.json()["data"][0]
164
+ ```
165
+
166
+ **Pour Flutter:** Utilisez MultipartRequest avec l'endpoint ci-dessus.
167
+ """,
168
+ examples=[
169
+ # Vous pouvez ajouter des fichiers d'exemple si vous en avez
170
+ ],
171
+ theme=gr.themes.Soft(),
172
+ allow_flagging="never"
173
+ )
174
+
175
+ # Lancement de l'interface
176
+ demo.launch()