Update app.py
Browse files
app.py
CHANGED
@@ -1,12 +1,54 @@
|
|
1 |
import streamlit as st
|
2 |
from huggingface_hub import InferenceClient
|
3 |
import time
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
-
|
|
|
6 |
|
7 |
-
|
8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
generate_kwargs = {
|
11 |
"temperature": 0.7,
|
12 |
"max_new_tokens": 1000,
|
@@ -14,39 +56,53 @@ def generer_dictee(classe, longueur):
|
|
14 |
"repetition_penalty": 1.2,
|
15 |
"do_sample": True,
|
16 |
}
|
17 |
-
|
18 |
formatted_prompt = f"<s>[INST] {prompt} [/INST]"
|
19 |
-
stream =
|
20 |
dictee = ""
|
21 |
-
|
22 |
for response in stream:
|
23 |
dictee += response.token.text
|
|
|
|
|
24 |
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
|
32 |
-
|
|
|
|
|
33 |
|
|
|
34 |
st.title('Générateur de Dictée')
|
35 |
|
|
|
|
|
36 |
with st.expander("Paramètres de la dictée"):
|
37 |
classe = st.selectbox("Classe", ["CP", "CE1", "CE2", "CM1", "CM2", "6ème", "5ème", "4ème", "3ème", "Seconde", "Premiere", "Terminale"], index=2)
|
38 |
longueur = st.slider("Longueur de la dictée (nombre de mots)", 50, 500, 200)
|
39 |
-
|
40 |
-
|
41 |
if st.button('Générer la Dictée'):
|
42 |
-
# Afficher une barre de chargement pendant la génération
|
43 |
with st.spinner("Génération de la dictée en cours..."):
|
44 |
-
# Simuler un délai de chargement (facultatif)
|
45 |
-
time.sleep(1)
|
46 |
-
|
47 |
dictee = generer_dictee(classe, longueur)
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import streamlit as st
|
2 |
from huggingface_hub import InferenceClient
|
3 |
import time
|
4 |
+
import re
|
5 |
+
import edge_tts
|
6 |
+
import asyncio
|
7 |
+
from concurrent.futures import ThreadPoolExecutor
|
8 |
+
import tempfile
|
9 |
+
from pydub import AudioSegment
|
10 |
|
11 |
+
# Initialize Hugging Face InferenceClient
|
12 |
+
client_hf = InferenceClient("mistralai/Mixtral-8x7B-Instruct-v0.1")
|
13 |
|
14 |
+
# Define the async function for text-to-speech conversion using Edge TTS
|
15 |
+
async def text_to_speech_edge(text, language_code):
|
16 |
+
voice = {"fr": "fr-FR-RemyMultilingualNeural"}[language_code]
|
17 |
+
communicate = edge_tts.Communicate(text, voice)
|
18 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp_file:
|
19 |
+
tmp_path = tmp_file.name
|
20 |
+
await communicate.save(tmp_path)
|
21 |
+
return tmp_path
|
22 |
+
|
23 |
+
# Helper function to run async functions from within Streamlit (synchronous context)
|
24 |
+
def run_in_threadpool(func, *args, **kwargs):
|
25 |
+
loop = asyncio.new_event_loop()
|
26 |
+
asyncio.set_event_loop(loop)
|
27 |
+
future = asyncio.ensure_future(func(*args, **kwargs))
|
28 |
+
return loop.run_until_complete(future)
|
29 |
+
|
30 |
+
def concatenate_audio(paths):
|
31 |
+
combined = AudioSegment.empty()
|
32 |
+
for path in paths:
|
33 |
+
audio = AudioSegment.from_mp3(path)
|
34 |
+
combined += audio
|
35 |
+
combined_path = tempfile.mktemp(suffix=".mp3")
|
36 |
+
combined.export(combined_path, format="mp3")
|
37 |
+
return combined_path
|
38 |
|
39 |
+
# Modified function to work with async Edge TTS
|
40 |
+
def dictee_to_audio_segmented(dictee):
|
41 |
+
sentences = segmenter_texte(dictee)
|
42 |
+
audio_urls = []
|
43 |
+
with ThreadPoolExecutor() as executor:
|
44 |
+
for sentence in sentences:
|
45 |
+
processed_sentence = replace_punctuation(sentence)
|
46 |
+
audio_path = executor.submit(run_in_threadpool, text_to_speech_edge, processed_sentence, "fr").result()
|
47 |
+
audio_urls.append(audio_path)
|
48 |
+
return audio_urls
|
49 |
+
|
50 |
+
def generer_dictee(classe, longueur):
|
51 |
+
prompt = f"Créer une dictée pour la classe {classe} d'une longueur d'environ {longueur} mots. Il est important de créer le texte uniquement de la dictée et de ne pas ajouter de consignes ou d'indications supplémentaires."
|
52 |
generate_kwargs = {
|
53 |
"temperature": 0.7,
|
54 |
"max_new_tokens": 1000,
|
|
|
56 |
"repetition_penalty": 1.2,
|
57 |
"do_sample": True,
|
58 |
}
|
|
|
59 |
formatted_prompt = f"<s>[INST] {prompt} [/INST]"
|
60 |
+
stream = client_hf.text_generation(formatted_prompt, **generate_kwargs, stream=True, details=True, return_full_text=False)
|
61 |
dictee = ""
|
|
|
62 |
for response in stream:
|
63 |
dictee += response.token.text
|
64 |
+
dictee = dictee.replace("</s>", "").strip()
|
65 |
+
return dictee
|
66 |
|
67 |
+
def replace_punctuation(text):
|
68 |
+
replacements = {
|
69 |
+
".": " point,",
|
70 |
+
",": " virgule.",
|
71 |
+
";": " point-virgule;",
|
72 |
+
":": " deux-points:",
|
73 |
+
"!": " point d'exclamation!",
|
74 |
+
"?": " point d'interrogation?",
|
75 |
+
"-": " tiret-",
|
76 |
+
"'": " apostrophe'",
|
77 |
+
}
|
78 |
+
for key, value in replacements.items():
|
79 |
+
text = text.replace(key, value)
|
80 |
+
return text
|
81 |
|
82 |
+
def segmenter_texte(texte):
|
83 |
+
sentences = re.split(r'(?<=[.!?]) +', texte)
|
84 |
+
return sentences
|
85 |
|
86 |
+
# Streamlit App Interface
|
87 |
st.title('Générateur de Dictée')
|
88 |
|
89 |
+
mode = st.radio("Mode:", ["S'entrainer", "Entrainer"])
|
90 |
+
|
91 |
with st.expander("Paramètres de la dictée"):
|
92 |
classe = st.selectbox("Classe", ["CP", "CE1", "CE2", "CM1", "CM2", "6ème", "5ème", "4ème", "3ème", "Seconde", "Premiere", "Terminale"], index=2)
|
93 |
longueur = st.slider("Longueur de la dictée (nombre de mots)", 50, 500, 200)
|
94 |
+
|
|
|
95 |
if st.button('Générer la Dictée'):
|
|
|
96 |
with st.spinner("Génération de la dictée en cours..."):
|
|
|
|
|
|
|
97 |
dictee = generer_dictee(classe, longueur)
|
98 |
+
if mode == "S'entrainer":
|
99 |
+
audio_urls = dictee_to_audio_segmented(dictee)
|
100 |
+
concatenated_audio_path = concatenate_audio(audio_urls)
|
101 |
+
st.success("Dictée générée. Utilisez le bouton ci-dessous pour écouter la dictée entière.")
|
102 |
+
st.audio(concatenated_audio_path, format='audio/wav', start_time=0)
|
103 |
+
with st.expander("Phrases de la Dictée"):
|
104 |
+
for idx, url in enumerate(audio_urls, start=1):
|
105 |
+
st.markdown(f"**Phrase {idx}:**")
|
106 |
+
st.audio(url, format='audio/wav')
|
107 |
+
elif mode == "Entrainer":
|
108 |
+
st.text_area("Voici votre dictée :", dictee, height=300)
|