Spaces:
Runtime error
Runtime error
jwphantom
commited on
Commit
•
ad91ef3
1
Parent(s):
ea62a8d
structuration du code
Browse files- app.py +17 -371
- modules/chatbot.py +67 -0
- modules/config.py +7 -0
- modules/image_classification.py +91 -0
- modules/image_to_text.py +68 -0
- modules/text_to_speech.py +75 -0
- utils/helpers.py +84 -0
- utils/styles.py +20 -0
app.py
CHANGED
@@ -1,56 +1,16 @@
|
|
1 |
import streamlit as st
|
2 |
from streamlit_option_menu import option_menu
|
|
|
|
|
3 |
|
4 |
-
|
5 |
-
|
6 |
-
import google.generativeai as genai
|
7 |
-
|
8 |
-
from langdetect import detect
|
9 |
-
import pycountry
|
10 |
-
from deep_translator import GoogleTranslator
|
11 |
-
|
12 |
-
|
13 |
-
import base64
|
14 |
-
|
15 |
-
from PIL import Image
|
16 |
-
|
17 |
-
import requests
|
18 |
-
|
19 |
-
from dotenv import load_dotenv
|
20 |
-
import os
|
21 |
-
|
22 |
-
# Charger les variables d'environnement
|
23 |
-
load_dotenv()
|
24 |
-
|
25 |
-
HUGGINGFACE_API_KEY = os.getenv("HUGGINGFACE_API_KEY")
|
26 |
-
GOOGLE_GENAI_API_KEY = os.getenv("GOOGLE_GENAI_API_KEY")
|
27 |
-
|
28 |
-
headers = {"Authorization": f"Bearer {HUGGINGFACE_API_KEY}"}
|
29 |
-
|
30 |
-
genai.configure(api_key=GOOGLE_GENAI_API_KEY)
|
31 |
-
|
32 |
-
# Configuration de la page
|
33 |
st.set_page_config(page_title="Application IA", layout="wide")
|
34 |
|
|
|
|
|
35 |
|
36 |
-
st.markdown(
|
37 |
-
"""
|
38 |
-
<style>
|
39 |
-
.content{
|
40 |
-
border-radius: 8px;
|
41 |
-
box-shadow: 0 1px 3px rgba(65,65,65,.492);
|
42 |
-
background: #fbfafa;
|
43 |
-
padding : 0 10px 0 20px
|
44 |
-
}
|
45 |
-
.stChatMessage .markdown-text-container {
|
46 |
-
word-wrap: break-word;
|
47 |
-
}
|
48 |
-
</style>
|
49 |
-
""",
|
50 |
-
unsafe_allow_html=True,
|
51 |
-
)
|
52 |
|
53 |
-
#
|
54 |
with st.sidebar:
|
55 |
menu = option_menu(
|
56 |
"Onyx AI",
|
@@ -71,13 +31,12 @@ with st.sidebar:
|
|
71 |
)
|
72 |
|
73 |
|
74 |
-
#
|
75 |
if menu == "Acceuil":
|
76 |
-
# Header
|
77 |
|
78 |
# # Contenu de la navbar avec des icônes appropriées
|
79 |
selected = option_menu(
|
80 |
-
menu_title=None,
|
81 |
options=[
|
82 |
"Chatbot",
|
83 |
"TextToSpeech",
|
@@ -89,9 +48,9 @@ if menu == "Acceuil":
|
|
89 |
"volume-up",
|
90 |
"camera",
|
91 |
"file-text",
|
92 |
-
],
|
93 |
-
menu_icon="cast",
|
94 |
-
default_index=0,
|
95 |
orientation="horizontal",
|
96 |
styles={
|
97 |
"container": {"background-color": "#fafafa"},
|
@@ -103,338 +62,25 @@ if menu == "Acceuil":
|
|
103 |
},
|
104 |
"nav-link-selected": {"background-color": "#519ba7"},
|
105 |
},
|
106 |
-
)
|
107 |
|
108 |
-
# Affichage du contenu basé sur le choix de la navbar avec st.markdown pour une meilleure intégration
|
109 |
if selected == "Chatbot":
|
110 |
|
111 |
-
|
112 |
-
st.markdown(
|
113 |
-
"""
|
114 |
-
<div class='content'>
|
115 |
-
<h1>Chatbot intelligent</h1>
|
116 |
-
</div>
|
117 |
-
<br/>
|
118 |
-
<p>Bienvenue dans la section Chatbot intelligent.</p>
|
119 |
-
""",
|
120 |
-
unsafe_allow_html=True,
|
121 |
-
)
|
122 |
-
|
123 |
-
model = genai.GenerativeModel("gemini-pro")
|
124 |
-
|
125 |
-
@dataclass
|
126 |
-
class Message:
|
127 |
-
actor: str
|
128 |
-
payload: str
|
129 |
-
|
130 |
-
USER = "user"
|
131 |
-
ASSISTANT = "ai"
|
132 |
-
MESSAGES = "messages"
|
133 |
-
|
134 |
-
if MESSAGES not in st.session_state:
|
135 |
-
st.session_state[MESSAGES] = [
|
136 |
-
Message(
|
137 |
-
actor=ASSISTANT, payload="Salut! Comment puis-je vous aider ? 😎"
|
138 |
-
)
|
139 |
-
]
|
140 |
-
|
141 |
-
msg: Message
|
142 |
-
for msg in st.session_state[MESSAGES]:
|
143 |
-
st.chat_message(msg.actor).write(msg.payload)
|
144 |
-
|
145 |
-
prompt: str = st.chat_input("Enter a prompt here")
|
146 |
-
|
147 |
-
if prompt:
|
148 |
-
st.session_state[MESSAGES].append(Message(actor=USER, payload=prompt))
|
149 |
-
st.chat_message(USER).write(prompt)
|
150 |
-
generate = model.generate_content(prompt)
|
151 |
-
response: str = generate.text
|
152 |
-
st.session_state[MESSAGES].append(
|
153 |
-
Message(actor=ASSISTANT, payload=response)
|
154 |
-
)
|
155 |
-
st.chat_message(ASSISTANT).write(response)
|
156 |
|
157 |
elif selected == "TextToSpeech":
|
158 |
|
159 |
-
|
160 |
-
st.markdown(
|
161 |
-
"""
|
162 |
-
<div class='content'>
|
163 |
-
<h1>Text to speech</h1>
|
164 |
-
</div>
|
165 |
-
<br/>
|
166 |
-
<p>Bienvenue dans la section Text to speech en espagnol.</p>
|
167 |
-
|
168 |
-
""",
|
169 |
-
unsafe_allow_html=True,
|
170 |
-
)
|
171 |
-
|
172 |
-
API_URL = "https://api-inference.huggingface.co/models/facebook/mms-tts-spa"
|
173 |
-
|
174 |
-
@dataclass
|
175 |
-
class Message:
|
176 |
-
actor: str
|
177 |
-
payload: str
|
178 |
-
|
179 |
-
USER = "user"
|
180 |
-
ASSISTANT = "ai"
|
181 |
-
MESSAGES = "messages_audio"
|
182 |
-
|
183 |
-
if MESSAGES not in st.session_state:
|
184 |
-
st.session_state[MESSAGES] = [
|
185 |
-
Message(
|
186 |
-
actor=ASSISTANT,
|
187 |
-
payload="Salut! Quelle phrase (peut importe la langue) souhaitez-vous prononcer en espagnol ? 😎",
|
188 |
-
)
|
189 |
-
]
|
190 |
-
|
191 |
-
def query(payload):
|
192 |
-
response = requests.post(API_URL, headers=headers, json=payload)
|
193 |
-
return response.content
|
194 |
-
|
195 |
-
# msg: Message
|
196 |
-
for msg in st.session_state[MESSAGES]:
|
197 |
-
st.chat_message(msg.actor).write(msg.payload)
|
198 |
-
|
199 |
-
prompt: str = st.chat_input("Entrez le texte à prononcer :")
|
200 |
-
|
201 |
-
if prompt:
|
202 |
-
st.session_state[MESSAGES].append(Message(actor=USER, payload=prompt))
|
203 |
-
st.chat_message(USER).write(prompt)
|
204 |
-
|
205 |
-
lang = pycountry.languages.get(alpha_2=detect(prompt))
|
206 |
-
|
207 |
-
lang_name = lang.name if lang else "Langue inconnue"
|
208 |
-
|
209 |
-
translated = GoogleTranslator(source="auto", target="es").translate(prompt)
|
210 |
-
|
211 |
-
st.chat_message(ASSISTANT).write(
|
212 |
-
f"Langue détecté {lang_name} \n \n {translated} \n \n Génération de l'audio ..."
|
213 |
-
)
|
214 |
-
|
215 |
-
parameters = {"inputs": translated}
|
216 |
-
|
217 |
-
audio = query(parameters)
|
218 |
-
|
219 |
-
st.chat_message(ASSISTANT).audio(data=audio)
|
220 |
|
221 |
elif selected == "Classification":
|
222 |
-
st.markdown(
|
223 |
-
"""
|
224 |
-
<div class='content'>
|
225 |
-
<h1>Zero shot image classification</h1>
|
226 |
-
</div>
|
227 |
-
<br/>
|
228 |
-
<p>Découvrez la classification d'images avec zerp shot.</p>
|
229 |
-
|
230 |
-
""",
|
231 |
-
unsafe_allow_html=True,
|
232 |
-
)
|
233 |
-
|
234 |
-
API_URL = "https://api-inference.huggingface.co/models/openai/clip-vit-large-patch14-336"
|
235 |
-
|
236 |
-
def query(image_bytes, parameters):
|
237 |
-
# Encode the image bytes in base64
|
238 |
-
encoded_image = base64.b64encode(image_bytes).decode("utf-8")
|
239 |
-
payload = {"parameters": parameters, "inputs": encoded_image}
|
240 |
-
response = requests.post(API_URL, headers=headers, json=payload)
|
241 |
-
return response.json()
|
242 |
-
|
243 |
-
@dataclass
|
244 |
-
class Message:
|
245 |
-
actor: str
|
246 |
-
payload: str
|
247 |
-
|
248 |
-
USER = "user"
|
249 |
-
ASSISTANT = "ai"
|
250 |
-
|
251 |
-
if "default_label" not in st.session_state:
|
252 |
-
st.session_state["default_label"] = (
|
253 |
-
"voiture,ananas,pastèque,tomate,bouteille"
|
254 |
-
)
|
255 |
-
|
256 |
-
# Interface utilisateur pour l'entrée de l'image et du libellé
|
257 |
-
uploaded_image = st.file_uploader(
|
258 |
-
"Upload an image", type=["jpg", "png", "jpeg"]
|
259 |
-
)
|
260 |
-
|
261 |
-
st.markdown(
|
262 |
-
"Veuillez entrer les labels séparés par des virgules (exemple : voiture,ananas,pastèque,tomate,bouteille):"
|
263 |
-
)
|
264 |
-
|
265 |
-
label = st.chat_input("Entrez le label séparé des virgules")
|
266 |
-
|
267 |
-
# Bouton pour envoyer l'image et le libellé
|
268 |
-
if label:
|
269 |
-
if uploaded_image is not None and label:
|
270 |
-
# Lire et stocker l'image temporairement
|
271 |
-
image = Image.open(uploaded_image)
|
272 |
-
|
273 |
-
image_bytes = uploaded_image.getvalue()
|
274 |
|
275 |
-
|
276 |
-
|
277 |
-
st.chat_message(ASSISTANT).text("Classification en cours...")
|
278 |
-
|
279 |
-
convert_label_to_english = GoogleTranslator(
|
280 |
-
source="auto", target="en"
|
281 |
-
).translate(label)
|
282 |
-
|
283 |
-
labels = convert_label_to_english.split(
|
284 |
-
","
|
285 |
-
) # Splitting the input label string into a list
|
286 |
-
|
287 |
-
print(labels)
|
288 |
-
|
289 |
-
parameters = {"candidate_labels": labels}
|
290 |
-
|
291 |
-
response = query(image_bytes, parameters)
|
292 |
-
|
293 |
-
translated = GoogleTranslator(source="auto", target="fr").translate(
|
294 |
-
f"The highest score is {response[0]['score']:.3f} for the label {response[0]['label']}"
|
295 |
-
)
|
296 |
-
|
297 |
-
st.chat_message(ASSISTANT).text(translated)
|
298 |
-
|
299 |
-
else:
|
300 |
-
st.write("Please upload an image and enter a label.")
|
301 |
|
302 |
elif selected == "Image to text":
|
303 |
-
st.markdown(
|
304 |
-
"""
|
305 |
-
<div class='content'>
|
306 |
-
<h1>Image to text</h1>
|
307 |
-
</div>
|
308 |
-
<br/>
|
309 |
-
<p>Convertissez des images en texte grâce à notre outil.</p>
|
310 |
-
|
311 |
-
""",
|
312 |
-
unsafe_allow_html=True,
|
313 |
-
)
|
314 |
-
|
315 |
-
model_pro_vision = genai.GenerativeModel("gemini-pro-vision")
|
316 |
-
|
317 |
-
@dataclass
|
318 |
-
class Message:
|
319 |
-
actor: str
|
320 |
-
payload: str
|
321 |
|
322 |
-
|
323 |
-
ASSISTANT = "ai"
|
324 |
-
|
325 |
-
# Interface utilisateur pour l'entrée de l'image et du libellé
|
326 |
-
uploaded_image_ImgTText = st.file_uploader(
|
327 |
-
"Upload an image", type=["jpg", "png", "jpeg"]
|
328 |
-
)
|
329 |
-
|
330 |
-
# Bouton pour envoyer l'image et le libellé
|
331 |
-
if st.button("Send"):
|
332 |
-
if uploaded_image_ImgTText is not None:
|
333 |
-
# Lire et stocker l'image temporairement
|
334 |
-
image = Image.open(uploaded_image_ImgTText)
|
335 |
-
|
336 |
-
st.chat_message(USER).image(image)
|
337 |
-
|
338 |
-
st.chat_message(ASSISTANT).text("Génération en cours...")
|
339 |
-
|
340 |
-
response = model_pro_vision.generate_content(
|
341 |
-
["Write a short description of the image", image],
|
342 |
-
stream=True,
|
343 |
-
)
|
344 |
-
|
345 |
-
response.resolve()
|
346 |
-
|
347 |
-
print(response.text)
|
348 |
-
|
349 |
-
translated = GoogleTranslator(source="auto", target="fr").translate(
|
350 |
-
response.text
|
351 |
-
)
|
352 |
-
|
353 |
-
st.chat_message(ASSISTANT).text(translated)
|
354 |
-
|
355 |
-
else:
|
356 |
-
st.write("Please upload an image and enter a label.")
|
357 |
|
358 |
|
359 |
elif menu == "Documentation":
|
360 |
|
361 |
-
|
362 |
-
st.markdown(
|
363 |
-
"""
|
364 |
-
# À propos de cette application
|
365 |
-
|
366 |
-
Cette application Streamlit démontre l'utilisation avancée de l'intelligence artificielle pour fournir une variété de services, y compris un chatbot intelligent, la conversion de texte en parole, la classification d'images sans exemples préalables, et la conversion d'images en texte. Cette application est un exemple de comment les technologies de pointe peuvent être intégrées dans des applications web modernes.
|
367 |
-
|
368 |
-
## Créateur
|
369 |
-
|
370 |
-
- [James Olongo](https://jamesolongo.vercel.app/)
|
371 |
-
|
372 |
-
## Technologies utilisées
|
373 |
-
|
374 |
-
- **Streamlit**: Un framework pour la création rapide d'applications web pour la science des données et le machine learning.
|
375 |
-
- **PyTorch & Transformers**: Utilisés pour les opérations de traitement du langage naturel et de génération de texte.
|
376 |
-
- **torchaudio & gTTS**: Pour la génération de parole et le traitement audio.
|
377 |
-
- **Langdetect & Pycountry**: Pour la détection de la langue et le traitement basé sur la langue.
|
378 |
-
- **Deep Translator**: Un puissant outil de traduction, utilisé en remplacement de Googletrans.
|
379 |
-
- **Google Generative AI**: Pour le chatbot intelligent, utilisant le modèle "gemini-pro" pour générer des réponses textuelles.
|
380 |
-
- **VITS**: Un modèle de synthèse vocale de pointe de Facebook pour la conversion de texte en parole en espagnol.
|
381 |
-
- **OpenAI CLIP**: Pour la classification d'images sans exemples, utilisant le modèle "clip-vit-large-patch14-336" pour la classification d'image en zero-shot.
|
382 |
-
|
383 |
-
## Détails des Applications
|
384 |
-
|
385 |
-
### Chatbot Intelligent
|
386 |
-
Utilise le modèle "gemini-pro" de Google Generative AI pour répondre aux requêtes des utilisateurs. Ce modèle est capable de comprendre et de générer des réponses à une grande variété de questions.
|
387 |
-
```python
|
388 |
-
import google.generativeai as genai
|
389 |
-
|
390 |
-
genai.configure(api_key="API_KEY")
|
391 |
-
|
392 |
-
model = genai.GenerativeModel("gemini-pro")
|
393 |
-
|
394 |
-
generate = model.generate_content("Comment déclarer une variable python")
|
395 |
-
|
396 |
-
response = generate.text
|
397 |
-
|
398 |
-
```
|
399 |
-
|
400 |
-
|
401 |
-
### Texte en Parole
|
402 |
-
Emploie le modèle "facebook/mms-tts-spa" pour convertir du texte en parole en espagnol, démontrant la capacité de transformer le texte en un fichier audio naturel.
|
403 |
-
```python
|
404 |
-
model = VitsModel.from_pretrained("facebook/mms-tts-spa")
|
405 |
-
|
406 |
-
tokenizer = AutoTokenizer.from_pretrained("facebook/mms-tts-spa")
|
407 |
-
|
408 |
-
inputs = tokenizer(translated, return_tensors="pt")
|
409 |
-
|
410 |
-
with torch.no_grad():
|
411 |
-
output = model(**inputs).waveform
|
412 |
-
```
|
413 |
-
|
414 |
-
|
415 |
-
### Zero shot image classification
|
416 |
-
Utilise le modèle "openai/clip-vit-large-patch14-336" d'OpenAI pour classifier des images sans exemples préalables, illustrant comment une IA peut comprendre et catégoriser le contenu visuel.
|
417 |
-
```python
|
418 |
-
|
419 |
-
|
420 |
-
model_name_zero_shot_classification = "openai/clip-vit-large-patch14-336"
|
421 |
-
|
422 |
-
classifier_zero_shot_classification = pipeline(
|
423 |
-
"zero-shot-image-classification", model=model_name_zero_shot_classification
|
424 |
-
)
|
425 |
-
|
426 |
-
scores = classifier_zero_shot_classification(
|
427 |
-
image_to_classify, candidate_labels="YOUR_LABEL"
|
428 |
-
)
|
429 |
-
|
430 |
-
print f"The highest score is {scores[0]['score']:.3f} for the label {scores[0]['label']}"
|
431 |
-
|
432 |
-
```
|
433 |
-
|
434 |
-
### Conversion d'Images en Texte
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
""",
|
439 |
-
unsafe_allow_html=True,
|
440 |
-
)
|
|
|
1 |
import streamlit as st
|
2 |
from streamlit_option_menu import option_menu
|
3 |
+
from modules import chatbot, text_to_speech, image_classification, image_to_text
|
4 |
+
from utils import styles, helpers
|
5 |
|
6 |
+
# Configuration initiale de la page Streamlit avec un titre et un layout spécifié.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
st.set_page_config(page_title="Application IA", layout="wide")
|
8 |
|
9 |
+
# Application des styles CSS personnalisés pour l'application.
|
10 |
+
styles.apply_styles()
|
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
+
# Création du Menu de Navigation
|
14 |
with st.sidebar:
|
15 |
menu = option_menu(
|
16 |
"Onyx AI",
|
|
|
31 |
)
|
32 |
|
33 |
|
34 |
+
# Gestion des Sections de l'Application
|
35 |
if menu == "Acceuil":
|
|
|
36 |
|
37 |
# # Contenu de la navbar avec des icônes appropriées
|
38 |
selected = option_menu(
|
39 |
+
menu_title=None,
|
40 |
options=[
|
41 |
"Chatbot",
|
42 |
"TextToSpeech",
|
|
|
48 |
"volume-up",
|
49 |
"camera",
|
50 |
"file-text",
|
51 |
+
],
|
52 |
+
menu_icon="cast",
|
53 |
+
default_index=0,
|
54 |
orientation="horizontal",
|
55 |
styles={
|
56 |
"container": {"background-color": "#fafafa"},
|
|
|
62 |
},
|
63 |
"nav-link-selected": {"background-color": "#519ba7"},
|
64 |
},
|
65 |
+
)
|
66 |
|
|
|
67 |
if selected == "Chatbot":
|
68 |
|
69 |
+
chatbot.show()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
|
71 |
elif selected == "TextToSpeech":
|
72 |
|
73 |
+
text_to_speech.show()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
|
75 |
elif selected == "Classification":
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
|
77 |
+
image_classification.show()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
|
79 |
elif selected == "Image to text":
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
|
81 |
+
image_to_text.show()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
|
83 |
|
84 |
elif menu == "Documentation":
|
85 |
|
86 |
+
helpers.show()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
modules/chatbot.py
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Importation des bibliothèques et modules nécessaires.
|
2 |
+
from attr import dataclass # Pour définir des classes de données simples.
|
3 |
+
import streamlit as st # Pour créer l'interface utilisateur web.
|
4 |
+
import google.generativeai as genai # Pour utiliser les services d'IA générative de Google.
|
5 |
+
|
6 |
+
# Importation de la clé API depuis un fichier de configuration.
|
7 |
+
from .config import GOOGLE_GENAI_API_KEY
|
8 |
+
|
9 |
+
# Configuration de l'API de Google Generative AI avec la clé API.
|
10 |
+
genai.configure(api_key=GOOGLE_GENAI_API_KEY)
|
11 |
+
|
12 |
+
|
13 |
+
# Fonction pour afficher le contenu de la section Chatbot dans l'application Streamlit.
|
14 |
+
def show():
|
15 |
+
# Affiche un titre et un message de bienvenue en utilisant HTML pour le formatage.
|
16 |
+
st.markdown(
|
17 |
+
"""
|
18 |
+
<div class='content'>
|
19 |
+
<h1>Chatbot intelligent</h1>
|
20 |
+
</div>
|
21 |
+
<br/>
|
22 |
+
<p>Bienvenue dans la section Chatbot intelligent.</p>
|
23 |
+
""",
|
24 |
+
unsafe_allow_html=True,
|
25 |
+
)
|
26 |
+
|
27 |
+
# Initialisation du modèle de chatbot avec l'identifiant spécifique 'gemini-pro'.
|
28 |
+
model = genai.GenerativeModel("gemini-pro")
|
29 |
+
|
30 |
+
# Définition d'une classe de données pour représenter les messages échangés.
|
31 |
+
@dataclass
|
32 |
+
class Message:
|
33 |
+
actor: str # Qui envoie le message ('user' ou 'ai').
|
34 |
+
payload: str # Le contenu du message.
|
35 |
+
|
36 |
+
# Constantes pour identifier l'acteur du message.
|
37 |
+
USER = "user"
|
38 |
+
ASSISTANT = "ai"
|
39 |
+
MESSAGES = (
|
40 |
+
"messages" # Clé pour stocker les messages dans l'état de session Streamlit.
|
41 |
+
)
|
42 |
+
|
43 |
+
# Initialisation de la liste de messages dans l'état de session s'il n'existe pas déjà.
|
44 |
+
if MESSAGES not in st.session_state:
|
45 |
+
st.session_state[MESSAGES] = [
|
46 |
+
Message(actor=ASSISTANT, payload="Salut! Comment puis-je vous aider ? 😎")
|
47 |
+
]
|
48 |
+
|
49 |
+
# Affichage des messages précédents stockés dans l'état de session.
|
50 |
+
for msg in st.session_state[MESSAGES]:
|
51 |
+
st.chat_message(msg.actor).write(msg.payload)
|
52 |
+
|
53 |
+
# Création d'un champ d'entrée pour que l'utilisateur saisisse une requête.
|
54 |
+
prompt: str = st.chat_input("Enter a prompt here")
|
55 |
+
|
56 |
+
# Si l'utilisateur soumet une requête :
|
57 |
+
if prompt:
|
58 |
+
# Ajoute la requête de l'utilisateur à la liste des messages.
|
59 |
+
st.session_state[MESSAGES].append(Message(actor=USER, payload=prompt))
|
60 |
+
# Affiche la requête de l'utilisateur.
|
61 |
+
st.chat_message(USER).write(prompt)
|
62 |
+
# Génère une réponse en utilisant le modèle de chatbot.
|
63 |
+
generate = model.generate_content(prompt)
|
64 |
+
response: str = generate.text
|
65 |
+
# Ajoute la réponse du chatbot à la liste des messages et l'affiche.
|
66 |
+
st.session_state[MESSAGES].append(Message(actor=ASSISTANT, payload=response))
|
67 |
+
st.chat_message(ASSISTANT).write(response)
|
modules/config.py
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from dotenv import load_dotenv
|
2 |
+
import os
|
3 |
+
|
4 |
+
load_dotenv()
|
5 |
+
|
6 |
+
HUGGINGFACE_API_KEY = os.getenv("HUGGINGFACE_API_KEY")
|
7 |
+
GOOGLE_GENAI_API_KEY = os.getenv("GOOGLE_GENAI_API_KEY")
|
modules/image_classification.py
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from attr import dataclass
|
2 |
+
from deep_translator import GoogleTranslator
|
3 |
+
import pycountry
|
4 |
+
import requests
|
5 |
+
import streamlit as st
|
6 |
+
from langdetect import detect
|
7 |
+
|
8 |
+
from .config import HUGGINGFACE_API_KEY
|
9 |
+
|
10 |
+
|
11 |
+
headers = {"Authorization": f"Bearer {HUGGINGFACE_API_KEY}"}
|
12 |
+
|
13 |
+
|
14 |
+
def show():
|
15 |
+
st.markdown(
|
16 |
+
"""
|
17 |
+
<div class='content'>
|
18 |
+
<h1>Zero shot image classification</h1>
|
19 |
+
</div>
|
20 |
+
<br/>
|
21 |
+
<p>Découvrez la classification d'images avec zerp shot.</p>
|
22 |
+
|
23 |
+
""",
|
24 |
+
unsafe_allow_html=True,
|
25 |
+
)
|
26 |
+
|
27 |
+
API_URL = (
|
28 |
+
"https://api-inference.huggingface.co/models/openai/clip-vit-large-patch14-336"
|
29 |
+
)
|
30 |
+
|
31 |
+
def query(image_bytes, parameters):
|
32 |
+
# Encode the image bytes in base64
|
33 |
+
encoded_image = base64.b64encode(image_bytes).decode("utf-8")
|
34 |
+
payload = {"parameters": parameters, "inputs": encoded_image}
|
35 |
+
response = requests.post(API_URL, headers=headers, json=payload)
|
36 |
+
return response.json()
|
37 |
+
|
38 |
+
@dataclass
|
39 |
+
class Message:
|
40 |
+
actor: str
|
41 |
+
payload: str
|
42 |
+
|
43 |
+
USER = "user"
|
44 |
+
ASSISTANT = "ai"
|
45 |
+
|
46 |
+
if "default_label" not in st.session_state:
|
47 |
+
st.session_state["default_label"] = "voiture,ananas,pastèque,tomate,bouteille"
|
48 |
+
|
49 |
+
# Interface utilisateur pour l'entrée de l'image et du libellé
|
50 |
+
uploaded_image = st.file_uploader("Upload an image", type=["jpg", "png", "jpeg"])
|
51 |
+
|
52 |
+
st.markdown(
|
53 |
+
"Veuillez entrer les labels séparés par des virgules (exemple : voiture,ananas,pastèque,tomate,bouteille):"
|
54 |
+
)
|
55 |
+
|
56 |
+
label = st.chat_input("Entrez le label séparé des virgules")
|
57 |
+
|
58 |
+
# Bouton pour envoyer l'image et le libellé
|
59 |
+
if label:
|
60 |
+
if uploaded_image is not None and label:
|
61 |
+
# Lire et stocker l'image temporairement
|
62 |
+
image = Image.open(uploaded_image)
|
63 |
+
|
64 |
+
image_bytes = uploaded_image.getvalue()
|
65 |
+
|
66 |
+
st.chat_message(USER).image(image)
|
67 |
+
|
68 |
+
st.chat_message(ASSISTANT).text("Classification en cours...")
|
69 |
+
|
70 |
+
convert_label_to_english = GoogleTranslator(
|
71 |
+
source="auto", target="en"
|
72 |
+
).translate(label)
|
73 |
+
|
74 |
+
labels = convert_label_to_english.split(
|
75 |
+
","
|
76 |
+
) # Splitting the input label string into a list
|
77 |
+
|
78 |
+
print(labels)
|
79 |
+
|
80 |
+
parameters = {"candidate_labels": labels}
|
81 |
+
|
82 |
+
response = query(image_bytes, parameters)
|
83 |
+
|
84 |
+
translated = GoogleTranslator(source="auto", target="fr").translate(
|
85 |
+
f"The highest score is {response[0]['score']:.3f} for the label {response[0]['label']}"
|
86 |
+
)
|
87 |
+
|
88 |
+
st.chat_message(ASSISTANT).text(translated)
|
89 |
+
|
90 |
+
else:
|
91 |
+
st.write("Please upload an image and enter a label.")
|
modules/image_to_text.py
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from attr import dataclass
|
2 |
+
from deep_translator import GoogleTranslator
|
3 |
+
import streamlit as st
|
4 |
+
import google.generativeai as genai
|
5 |
+
|
6 |
+
from PIL import Image
|
7 |
+
|
8 |
+
from .config import GOOGLE_GENAI_API_KEY
|
9 |
+
|
10 |
+
|
11 |
+
genai.configure(api_key=GOOGLE_GENAI_API_KEY)
|
12 |
+
|
13 |
+
|
14 |
+
def show():
|
15 |
+
st.markdown(
|
16 |
+
"""
|
17 |
+
<div class='content'>
|
18 |
+
<h1>Image to text</h1>
|
19 |
+
</div>
|
20 |
+
<br/>
|
21 |
+
<p>Convertissez des images en texte grâce à notre outil.</p>
|
22 |
+
|
23 |
+
""",
|
24 |
+
unsafe_allow_html=True,
|
25 |
+
)
|
26 |
+
|
27 |
+
model_pro_vision = genai.GenerativeModel("gemini-pro-vision")
|
28 |
+
|
29 |
+
@dataclass
|
30 |
+
class Message:
|
31 |
+
actor: str
|
32 |
+
payload: str
|
33 |
+
|
34 |
+
USER = "user"
|
35 |
+
ASSISTANT = "ai"
|
36 |
+
|
37 |
+
# Interface utilisateur pour l'entrée de l'image et du libellé
|
38 |
+
uploaded_image_ImgTText = st.file_uploader(
|
39 |
+
"Upload an image", type=["jpg", "png", "jpeg"]
|
40 |
+
)
|
41 |
+
|
42 |
+
# Bouton pour envoyer l'image et le libellé
|
43 |
+
if st.button("Send"):
|
44 |
+
if uploaded_image_ImgTText is not None:
|
45 |
+
# Lire et stocker l'image temporairement
|
46 |
+
image = Image.open(uploaded_image_ImgTText)
|
47 |
+
|
48 |
+
st.chat_message(USER).image(image)
|
49 |
+
|
50 |
+
st.chat_message(ASSISTANT).text("Génération en cours...")
|
51 |
+
|
52 |
+
response = model_pro_vision.generate_content(
|
53 |
+
["Write a short description of the image", image],
|
54 |
+
stream=True,
|
55 |
+
)
|
56 |
+
|
57 |
+
response.resolve()
|
58 |
+
|
59 |
+
print(response.text)
|
60 |
+
|
61 |
+
translated = GoogleTranslator(source="auto", target="fr").translate(
|
62 |
+
response.text
|
63 |
+
)
|
64 |
+
|
65 |
+
st.chat_message(ASSISTANT).text(translated)
|
66 |
+
|
67 |
+
else:
|
68 |
+
st.write("Please upload an image and enter a label.")
|
modules/text_to_speech.py
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from attr import dataclass
|
2 |
+
from deep_translator import GoogleTranslator
|
3 |
+
import pycountry
|
4 |
+
import requests
|
5 |
+
import streamlit as st
|
6 |
+
from langdetect import detect
|
7 |
+
|
8 |
+
from .config import HUGGINGFACE_API_KEY
|
9 |
+
|
10 |
+
|
11 |
+
headers = {"Authorization": f"Bearer {HUGGINGFACE_API_KEY}"}
|
12 |
+
|
13 |
+
|
14 |
+
def show():
|
15 |
+
# Affichage du titre et du message de bienvenue
|
16 |
+
st.markdown(
|
17 |
+
"""
|
18 |
+
<div class='content'>
|
19 |
+
<h1>Text to speech</h1>
|
20 |
+
</div>
|
21 |
+
<br/>
|
22 |
+
<p>Bienvenue dans la section Text to speech en espagnol.</p>
|
23 |
+
|
24 |
+
""",
|
25 |
+
unsafe_allow_html=True,
|
26 |
+
)
|
27 |
+
|
28 |
+
API_URL = "https://api-inference.huggingface.co/models/facebook/mms-tts-spa"
|
29 |
+
|
30 |
+
@dataclass
|
31 |
+
class Message:
|
32 |
+
actor: str
|
33 |
+
payload: str
|
34 |
+
|
35 |
+
USER = "user"
|
36 |
+
ASSISTANT = "ai"
|
37 |
+
MESSAGES = "messages_audio"
|
38 |
+
|
39 |
+
if MESSAGES not in st.session_state:
|
40 |
+
st.session_state[MESSAGES] = [
|
41 |
+
Message(
|
42 |
+
actor=ASSISTANT,
|
43 |
+
payload="Salut! Quelle phrase (peut importe la langue) souhaitez-vous prononcer en espagnol ? 😎",
|
44 |
+
)
|
45 |
+
]
|
46 |
+
|
47 |
+
def query(payload):
|
48 |
+
response = requests.post(API_URL, headers=headers, json=payload)
|
49 |
+
return response.content
|
50 |
+
|
51 |
+
# msg: Message
|
52 |
+
for msg in st.session_state[MESSAGES]:
|
53 |
+
st.chat_message(msg.actor).write(msg.payload)
|
54 |
+
|
55 |
+
prompt: str = st.chat_input("Entrez le texte à prononcer :")
|
56 |
+
|
57 |
+
if prompt:
|
58 |
+
st.session_state[MESSAGES].append(Message(actor=USER, payload=prompt))
|
59 |
+
st.chat_message(USER).write(prompt)
|
60 |
+
|
61 |
+
lang = pycountry.languages.get(alpha_2=detect(prompt))
|
62 |
+
|
63 |
+
lang_name = lang.name if lang else "Langue inconnue"
|
64 |
+
|
65 |
+
translated = GoogleTranslator(source="auto", target="es").translate(prompt)
|
66 |
+
|
67 |
+
st.chat_message(ASSISTANT).write(
|
68 |
+
f"Langue détecté {lang_name} \n \n {translated} \n \n Génération de l'audio ..."
|
69 |
+
)
|
70 |
+
|
71 |
+
parameters = {"inputs": translated}
|
72 |
+
|
73 |
+
audio = query(parameters)
|
74 |
+
|
75 |
+
st.chat_message(ASSISTANT).audio(data=audio)
|
utils/helpers.py
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
|
3 |
+
|
4 |
+
def show():
|
5 |
+
# Lorsque "About" est sélectionné, afficher le contenu À propos dans le corps principal
|
6 |
+
st.markdown(
|
7 |
+
"""
|
8 |
+
# À propos de cette application
|
9 |
+
|
10 |
+
Cette application Streamlit démontre l'utilisation avancée de l'intelligence artificielle pour fournir une variété de services, y compris un chatbot intelligent, la conversion de texte en parole, la classification d'images sans exemples préalables, et la conversion d'images en texte. Cette application est un exemple de comment les technologies de pointe peuvent être intégrées dans des applications web modernes.
|
11 |
+
|
12 |
+
## Créateur
|
13 |
+
|
14 |
+
- [James Olongo](https://jamesolongo.vercel.app/)
|
15 |
+
|
16 |
+
## Technologies utilisées
|
17 |
+
|
18 |
+
- **Streamlit**: Un framework pour la création rapide d'applications web pour la science des données et le machine learning.
|
19 |
+
- **PyTorch & Transformers**: Utilisés pour les opérations de traitement du langage naturel et de génération de texte.
|
20 |
+
- **torchaudio & gTTS**: Pour la génération de parole et le traitement audio.
|
21 |
+
- **Langdetect & Pycountry**: Pour la détection de la langue et le traitement basé sur la langue.
|
22 |
+
- **Deep Translator**: Un puissant outil de traduction, utilisé en remplacement de Googletrans.
|
23 |
+
- **Google Generative AI**: Pour le chatbot intelligent, utilisant le modèle "gemini-pro" pour générer des réponses textuelles.
|
24 |
+
- **VITS**: Un modèle de synthèse vocale de pointe de Facebook pour la conversion de texte en parole en espagnol.
|
25 |
+
- **OpenAI CLIP**: Pour la classification d'images sans exemples, utilisant le modèle "clip-vit-large-patch14-336" pour la classification d'image en zero-shot.
|
26 |
+
|
27 |
+
## Détails des Applications
|
28 |
+
|
29 |
+
### Chatbot Intelligent
|
30 |
+
Utilise le modèle "gemini-pro" de Google Generative AI pour répondre aux requêtes des utilisateurs. Ce modèle est capable de comprendre et de générer des réponses à une grande variété de questions.
|
31 |
+
```python
|
32 |
+
import google.generativeai as genai
|
33 |
+
|
34 |
+
genai.configure(api_key="API_KEY")
|
35 |
+
|
36 |
+
model = genai.GenerativeModel("gemini-pro")
|
37 |
+
|
38 |
+
generate = model.generate_content("Comment déclarer une variable python")
|
39 |
+
|
40 |
+
response = generate.text
|
41 |
+
|
42 |
+
```
|
43 |
+
|
44 |
+
|
45 |
+
### Texte en Parole
|
46 |
+
Emploie le modèle "facebook/mms-tts-spa" pour convertir du texte en parole en espagnol, démontrant la capacité de transformer le texte en un fichier audio naturel.
|
47 |
+
```python
|
48 |
+
model = VitsModel.from_pretrained("facebook/mms-tts-spa")
|
49 |
+
|
50 |
+
tokenizer = AutoTokenizer.from_pretrained("facebook/mms-tts-spa")
|
51 |
+
|
52 |
+
inputs = tokenizer(translated, return_tensors="pt")
|
53 |
+
|
54 |
+
with torch.no_grad():
|
55 |
+
output = model(**inputs).waveform
|
56 |
+
```
|
57 |
+
|
58 |
+
|
59 |
+
### Zero shot image classification
|
60 |
+
Utilise le modèle "openai/clip-vit-large-patch14-336" d'OpenAI pour classifier des images sans exemples préalables, illustrant comment une IA peut comprendre et catégoriser le contenu visuel.
|
61 |
+
```python
|
62 |
+
|
63 |
+
|
64 |
+
model_name_zero_shot_classification = "openai/clip-vit-large-patch14-336"
|
65 |
+
|
66 |
+
classifier_zero_shot_classification = pipeline(
|
67 |
+
"zero-shot-image-classification", model=model_name_zero_shot_classification
|
68 |
+
)
|
69 |
+
|
70 |
+
scores = classifier_zero_shot_classification(
|
71 |
+
image_to_classify, candidate_labels="YOUR_LABEL"
|
72 |
+
)
|
73 |
+
|
74 |
+
print f"The highest score is {scores[0]['score']:.3f} for the label {scores[0]['label']}"
|
75 |
+
|
76 |
+
```
|
77 |
+
|
78 |
+
### Conversion d'Images en Texte
|
79 |
+
|
80 |
+
|
81 |
+
|
82 |
+
""",
|
83 |
+
unsafe_allow_html=True,
|
84 |
+
)
|
utils/styles.py
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
|
3 |
+
|
4 |
+
def apply_styles():
|
5 |
+
st.markdown(
|
6 |
+
"""
|
7 |
+
<style>
|
8 |
+
.content{
|
9 |
+
border-radius: 8px;
|
10 |
+
box-shadow: 0 1px 3px rgba(65,65,65,.492);
|
11 |
+
background: #fbfafa;
|
12 |
+
padding : 0 10px 0 20px
|
13 |
+
}
|
14 |
+
.stChatMessage .markdown-text-container {
|
15 |
+
word-wrap: break-word;
|
16 |
+
}
|
17 |
+
</style>
|
18 |
+
""",
|
19 |
+
unsafe_allow_html=True,
|
20 |
+
)
|