cecilemacaire commited on
Commit
765d42b
1 Parent(s): afec4d5

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +173 -0
app.py ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
3
+ import pandas as pd
4
+ from fpdf import FPDF
5
+ import whisper
6
+ import tempfile
7
+ from st_audiorec import st_audiorec
8
+ import numpy as np
9
+
10
+
11
+ # Interface utilisateur
12
+ st.set_page_config(
13
+ page_title="Traduction de la parole en pictogrammes ARASAAC",
14
+ page_icon="📝",
15
+ layout="wide"
16
+ )
17
+
18
+ # Charger le modèle et le tokenizer
19
+ checkpoint = "Propicto/t2p-nllb-200-distilled-600M-all"
20
+ tokenizer = AutoTokenizer.from_pretrained(checkpoint)
21
+ model = AutoModelForSeq2SeqLM.from_pretrained(checkpoint)
22
+
23
+ # Charger le modèle Whisper
24
+ whisper_model = whisper.load_model("base")
25
+
26
+ # Lire le lexique
27
+ @st.cache_data
28
+ def read_lexicon(lexicon):
29
+ df = pd.read_csv(lexicon, sep='\t')
30
+ df['keyword_no_cat'] = df['lemma'].str.split(' #').str[0].str.strip().str.replace(' ', '_')
31
+ return df
32
+
33
+ lexicon = read_lexicon("lexicon.csv")
34
+
35
+ # Processus de sortie de la traduction
36
+ def process_output_trad(pred):
37
+ return pred.split()
38
+
39
+ def get_id_picto_from_predicted_lemma(df_lexicon, lemma):
40
+ if lemma.endswith("!"):
41
+ lemma = lemma[:-1]
42
+ id_picto = df_lexicon.loc[df_lexicon['keyword_no_cat'] == lemma, 'id_picto'].tolist()
43
+ return (id_picto[0], lemma) if id_picto else (0, lemma)
44
+
45
+ # Génération du contenu HTML pour afficher les pictogrammes
46
+ def generate_html(ids):
47
+ html_content = '<html><head><style>'
48
+ html_content += '''
49
+ figure {
50
+ display: inline-block;
51
+ text-align: center;
52
+ font-family: Arial, sans-serif;
53
+ margin: 0;
54
+ }
55
+ figcaption {
56
+ color: black;
57
+ background-color: white;
58
+ border-radius: 5px;
59
+ }
60
+ img {
61
+ background-color: white;
62
+ margin: 0;
63
+ padding: 0;
64
+ border-radius: 6px;
65
+ }
66
+ '''
67
+ html_content += '</style></head><body>'
68
+ for picto_id, lemma in ids:
69
+ if picto_id != 0: # ignore invalid IDs
70
+ img_url = f"https://static.arasaac.org/pictograms/{picto_id}/{picto_id}_500.png"
71
+ html_content += f'''
72
+ <figure>
73
+ <img src="{img_url}" alt="{lemma}" width="200" height="200"/>
74
+ <figcaption>{lemma}</figcaption>
75
+ </figure>
76
+ '''
77
+ html_content += '</body></html>'
78
+ return html_content
79
+
80
+ # Génération du PDF
81
+ def generate_pdf(ids):
82
+ pdf = FPDF(orientation='L', unit='mm', format='A4') # 'L' for landscape orientation
83
+ pdf.add_page()
84
+ pdf.set_auto_page_break(auto=True, margin=15)
85
+
86
+ # Start positions
87
+ x_start = 10
88
+ y_start = 10
89
+ img_width = 50
90
+ img_height = 50
91
+ spacing = 1
92
+ max_width = 297 # A4 landscape width in mm
93
+ current_x = x_start
94
+ current_y = y_start
95
+
96
+ for picto_id, lemma in ids:
97
+ if picto_id != 0: # ignore invalid IDs
98
+ img_url = f"https://static.arasaac.org/pictograms/{picto_id}/{picto_id}_500.png"
99
+ pdf.image(img_url, x=current_x, y=current_y, w=img_width, h=img_height)
100
+ pdf.set_xy(current_x, current_y + img_height + 5)
101
+ pdf.set_font("Arial", size=12)
102
+ pdf.cell(img_width, 10, txt=lemma, ln=1, align='C')
103
+
104
+ current_x += img_width + spacing
105
+
106
+ # Move to the next line if exceeds max width
107
+ if current_x + img_width > max_width:
108
+ current_x = x_start
109
+ current_y += img_height + spacing + 10 # Adjust for image height and some spacing
110
+
111
+ pdf_path = "pictograms.pdf"
112
+ pdf.output(pdf_path)
113
+ return pdf_path
114
+
115
+
116
+ # Initialiser l'état de session
117
+ if 'transcription' not in st.session_state:
118
+ st.session_state['transcription'] = None
119
+ if 'pictogram_ids' not in st.session_state:
120
+ st.session_state['pictogram_ids'] = None
121
+ if 'previous_audio_file' not in st.session_state:
122
+ st.session_state['previous_audio_file'] = None
123
+
124
+
125
+ # Interface utilisateur pour l'audio et le bouton de téléchargement
126
+ st.title("Traduction de la parole en pictogrammes ARASAAC")
127
+
128
+ col1, col2 = st.columns(2)
129
+
130
+ with col1:
131
+ audio_file = st.file_uploader("Ajouter un fichier audio :", type=["wav", "mp3"])
132
+ # Réinitialiser les informations si le fichier audio change
133
+ if audio_file is not None and audio_file != st.session_state['previous_audio_file']:
134
+ st.session_state['transcription'] = None
135
+ st.session_state['pictogram_ids'] = None
136
+ st.session_state['previous_audio_file'] = audio_file
137
+
138
+ with col2:
139
+ if audio_file is not None:
140
+ with st.spinner("Transcription de l'audio en cours..."):
141
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as temp_file:
142
+ temp_file.write(audio_file.read())
143
+ temp_file_path = temp_file.name
144
+ transcription = whisper_model.transcribe(temp_file_path, language='fr')
145
+ if 'transcription' in locals():
146
+ st.text_area("Transcription :", transcription['text'])
147
+ st.session_state['transcription'] = transcription['text']
148
+
149
+
150
+ if st.session_state['transcription'] is not None:
151
+ inputs = tokenizer(transcription['text'].lower(), return_tensors="pt").input_ids
152
+ outputs = model.generate(inputs, max_new_tokens=40, do_sample=True, top_k=30, top_p=0.95)
153
+ pred = tokenizer.decode(outputs[0], skip_special_tokens=True)
154
+
155
+ sentence_to_map = process_output_trad(pred)
156
+ pictogram_ids = [get_id_picto_from_predicted_lemma(lexicon, lemma) for lemma in sentence_to_map]
157
+ st.session_state['pictogram_ids'] = [get_id_picto_from_predicted_lemma(lexicon, lemma) for lemma in sentence_to_map]
158
+
159
+
160
+ if st.session_state['pictogram_ids'] is not None:
161
+ html = generate_html(st.session_state['pictogram_ids'])
162
+ st.components.v1.html(html, height=500, scrolling=True)
163
+
164
+ # Container to hold the download button
165
+ pdf_path = generate_pdf(st.session_state['pictogram_ids'])
166
+ with open(pdf_path, "rb") as pdf_file:
167
+ st.download_button(label="Télécharger la traduction en PDF", data=pdf_file, file_name="pictograms.pdf", mime="application/pdf")
168
+
169
+ # record_audio = st_audiorec()
170
+ # if record_audio:
171
+ # audio = np.array(record_audio)
172
+ # transcription = whisper_model.transcribe(audio, language='fr')
173
+ # st.success("Enregistrement terminé !")