Mahavaury2 commited on
Commit
60e16da
·
verified ·
1 Parent(s): 2a7984e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +188 -88
app.py CHANGED
@@ -1,101 +1,201 @@
1
  #!/usr/bin/env python
2
 
3
- import os
4
- from collections.abc import Iterator
5
- from threading import Thread
6
-
7
  import gradio as gr
8
- import spaces
9
- import torch
10
- from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
11
-
12
- DESCRIPTION = """
13
- <h1 style="color:black;">Mistral-7B v0.3</h1>
14
- """
15
 
16
- if not torch.cuda.is_available():
17
- DESCRIPTION += "\n<p>Running on CPU 🥶 This demo does not work on CPU.</p>"
18
-
19
- MAX_MAX_NEW_TOKENS = 2048
20
- DEFAULT_MAX_NEW_TOKENS = 1024
21
- MAX_INPUT_TOKEN_LENGTH = int(os.getenv("MAX_INPUT_TOKEN_LENGTH", "4096"))
22
-
23
- if torch.cuda.is_available():
24
- model_id = "mistralai/Mistral-7B-Instruct-v0.3"
25
- model = AutoModelForCausalLM.from_pretrained(
26
- model_id,
27
- torch_dtype=torch.float16,
28
- device_map="auto"
29
- )
30
- tokenizer = AutoTokenizer.from_pretrained(model_id)
31
-
32
- @spaces.GPU
33
- def generate(
34
- message: str,
35
- chat_history: list[dict],
36
- max_new_tokens: int = 1024,
37
- temperature: float = 0.6,
38
- top_p: float = 0.9,
39
- top_k: int = 50,
40
- repetition_penalty: float = 1.2,
41
- ) -> Iterator[str]:
42
- conversation = [*chat_history, {"role": "user", "content": message}]
43
- input_ids = tokenizer.apply_chat_template(conversation, return_tensors="pt")
44
- if input_ids.shape[1] > MAX_INPUT_TOKEN_LENGTH:
45
- input_ids = input_ids[:, -MAX_INPUT_TOKEN_LENGTH:]
46
- gr.Warning(f"Trimmed input from conversation as it was longer than {MAX_INPUT_TOKEN_LENGTH} tokens.")
47
- input_ids = input_ids.to(model.device)
48
-
49
- streamer = TextIteratorStreamer(tokenizer, timeout=20.0, skip_prompt=True, skip_special_tokens=True)
50
- generate_kwargs = dict(
51
- {"input_ids": input_ids},
52
- streamer=streamer,
53
- max_new_tokens=max_new_tokens,
54
- do_sample=True,
55
- top_p=top_p,
56
- top_k=top_k,
57
- temperature=temperature,
58
- num_beams=1,
59
- repetition_penalty=repetition_penalty,
60
- )
61
- t = Thread(target=model.generate, kwargs=generate_kwargs)
62
- t.start()
63
-
64
- outputs = []
65
- for text in streamer:
66
- outputs.append(text)
67
- yield "".join(outputs)
68
-
69
- # CSS pour appliquer le dégradé pastel à TOUTE la page
70
  custom_css = """
 
71
  html, body {
 
72
  height: 100%;
73
- margin: 0;
74
- padding: 0;
75
  background: linear-gradient(135deg, #FDE2E2, #E2ECFD) !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  }
77
  """
78
 
79
- # Questions prédéfinies
80
- predefined_examples = [
81
- ["1 - C’est quoi le consentement ? Comment savoir si ma copine a envie de moi ?"],
82
- ["2 - C’est quoi une agression sexuelle ?"],
83
- ["3 - C’est quoi un viol ?"],
84
- ["4 - C’est quoi un attouchement ?"],
85
- ["5 - C’est quoi un harcèlement sexuel ?"],
86
- ["6 - Est ce illégal de visionner du porno ?"],
87
- ["7 - Mon copain me demande un nude, dois-je le faire ?"],
88
- ["8 - Mon ancien copain me menace de poster des photos de moi nue sur internet, que faire ?"],
89
- ["9 - Que puis-je faire si un membre de ma famille me touche d’une manière bizarre, mais que j’ai peur de parler ou de ne pas être cru ?"],
90
- ]
91
-
92
- demo = gr.ChatInterface(
93
- fn=generate,
94
- type="messages",
95
- description=DESCRIPTION,
96
- css=custom_css, # On applique le CSS pastel global
97
- examples=predefined_examples
98
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
  if __name__ == "__main__":
101
- demo.queue(max_size=20).launch()
 
1
  #!/usr/bin/env python
2
 
 
 
 
 
3
  import gradio as gr
 
 
 
 
 
 
 
4
 
5
+ # CSS perso pour :
6
+ # 1) Le fond pastel
7
+ # 2) La barre de navigation
8
+ # 3) Les nuages + positionnement
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  custom_css = """
10
+ /* Fond pastel sur toute la page */
11
  html, body {
12
+ margin: 0; padding: 0;
13
  height: 100%;
 
 
14
  background: linear-gradient(135deg, #FDE2E2, #E2ECFD) !important;
15
+ font-family: 'Arial', sans-serif;
16
+ }
17
+
18
+ /* Barre de navigation */
19
+ .nav-bar {
20
+ display: flex;
21
+ align-items: center;
22
+ justify-content: space-between;
23
+ padding: 0.5rem 2rem;
24
+ background-color: #fbe8d3; /* Couleur très légère pour la barre */
25
+ }
26
+ .nav-left, .nav-right {
27
+ display: flex;
28
+ align-items: center;
29
+ }
30
+ .nav-logo {
31
+ font-size: 1.5rem;
32
+ font-weight: bold;
33
+ margin-right: 2rem;
34
+ }
35
+ .nav-links a {
36
+ margin-right: 1.5rem;
37
+ text-decoration: none;
38
+ color: #8c5b3e;
39
+ font-weight: 500;
40
+ }
41
+ .nav-links a:hover {
42
+ text-decoration: underline;
43
+ }
44
+
45
+ /* Conteneur principal au centre (pour le robot + nuages) */
46
+ .main-container {
47
+ position: relative;
48
+ width: 100%;
49
+ max-width: 600px;
50
+ height: 600px;
51
+ margin: 1rem auto;
52
+ text-align: center;
53
+ }
54
+
55
+ /* Style de l'icône robot */
56
+ .robot-icon {
57
+ width: 80px;
58
+ margin: 1rem auto;
59
+ }
60
+
61
+ /* Texte sous le robot */
62
+ .title-consent {
63
+ font-size: 1.2rem;
64
+ font-weight: bold;
65
+ margin-bottom: 0.3rem;
66
+ }
67
+ .subtitle-consent {
68
+ font-size: 0.9rem;
69
+ color: #333;
70
+ margin-bottom: 1.2rem;
71
+ }
72
+
73
+ /* Positionnement et style des nuages */
74
+ .cloud {
75
+ position: absolute;
76
+ width: 130px;
77
+ padding: 0.5rem;
78
+ background: #fff;
79
+ border-radius: 50px;
80
+ box-shadow: 0 2px 4px rgba(0,0,0,0.2);
81
+ cursor: pointer;
82
+ transition: transform 0.2s;
83
+ text-align: center;
84
+ font-size: 0.9rem;
85
+ }
86
+ .cloud:hover {
87
+ transform: scale(1.05);
88
+ }
89
+
90
+ /* 5 nuages : positionnés autour du centre */
91
+ .cloud1 { top: 5%; left: 40%; }
92
+ .cloud2 { top: 30%; left: 10%; }
93
+ .cloud3 { top: 30%; right: 10%; }
94
+ .cloud4 { bottom: 10%; left: 20%; }
95
+ .cloud5 { bottom: 10%; right: 20%; }
96
+
97
+ /* Pied de page ou zone pour le chat */
98
+ .footer-chat {
99
+ margin-top: 2rem;
100
+ }
101
+
102
+ /* Couleur du texte dans la zone markdown */
103
+ .markdown-prose {
104
+ color: #000 !important;
105
  }
106
  """
107
 
108
+ # HTML pour la barre de navigation
109
+ nav_bar_html = """
110
+ <div class="nav-bar">
111
+ <div class="nav-left">
112
+ <div class="nav-logo">LÉLI</div>
113
+ </div>
114
+ <div class="nav-right nav-links">
115
+ <a href="#">Pourquoi ?</a>
116
+ <a href="#">Discute avec Léli</a>
117
+ <a href="#">Contacts utiles</a>
118
+ </div>
119
+ </div>
120
+ """
121
+
122
+ # HTML pour la zone centrale (robot + nuages).
123
+ # onclick="cloudClicked('xxxx')" => appelle une fonction JS
124
+ main_html = """
125
+ <div class="main-container">
126
+ <!-- Robot icône -->
127
+ <img src="https://cdn-icons-png.flaticon.com/512/6188/6188530.png" class="robot-icon" alt="Robot" />
128
+
129
+ <!-- Titre et sous-titre -->
130
+ <div class="title-consent">LE CONSENTEMENT</div>
131
+ <div class="subtitle-consent">Clique sur un nuage pour en découvrir le contenu</div>
132
+
133
+ <!-- Nuages -->
134
+ <div class="cloud cloud1" onclick="cloudClicked('Ce que c’est')">Ce que c'est</div>
135
+ <div class="cloud cloud2" onclick="cloudClicked('Ce que ce n’est pas')">Ce que ce n’est pas</div>
136
+ <div class="cloud cloud3" onclick="cloudClicked('Les risques si tu ne le respectes pas')">Les risques si tu ne le respectes pas</div>
137
+ <div class="cloud cloud4" onclick="cloudClicked('Mise en situation')">Mise en situation</div>
138
+ <div class="cloud cloud5" onclick="cloudClicked('Comment faire en pratique')">Comment faire en pratique</div>
139
+ </div>
140
+
141
+ <script>
142
+ function cloudClicked(message) {
143
+ // Sélectionner la zone de texte du chat (Placeholder: "Type a message...")
144
+ let textBox = document.querySelector('textarea[placeholder="Type a message..."]');
145
+ if (textBox) {
146
+ textBox.value = message;
147
+ // Facultatif : automatiquement "envoyer" le message ?
148
+ // On peut simuler un Enter, etc. Mais souvent on laisse l'utilisateur cliquer "Send".
149
+ }
150
+ }
151
+ </script>
152
+ """
153
+
154
+ def dummy_chatbot(user_input, history):
155
+ """
156
+ Exemple de fonction simple pour répondre dans le chat.
157
+ - user_input: question de l’utilisateur
158
+ - history: historique [(user_msg, bot_msg), ...]
159
+ """
160
+ history = history or []
161
+ # Pour l’exemple : on se contente de renvoyer un message "Réponse".
162
+ # À remplacer par votre propre logique, ou un modèle HF.
163
+ bot_message = f"Voici un contenu sur : {user_input}"
164
+ history.append((user_input, bot_message))
165
+ return history
166
+
167
+ with gr.Blocks(css=custom_css) as demo:
168
+ # La barre de navigation
169
+ gr.HTML(nav_bar_html)
170
+
171
+ # La zone "robot + nuages"
172
+ gr.HTML(main_html)
173
+
174
+ # Le chatbot en bas
175
+ with gr.Box(elem_id="footer-chat"):
176
+ chatbot = gr.Chatbot()
177
+ msg = gr.Textbox(
178
+ label="Pose ta question à Léli",
179
+ placeholder="Type a message...",
180
+ show_label=False
181
+ )
182
+ submit_btn = gr.Button("Send")
183
+
184
+ def respond(user_input, chat_history):
185
+ return dummy_chatbot(user_input, chat_history)
186
+
187
+ submit_btn.click(
188
+ fn=respond,
189
+ inputs=[msg, chatbot],
190
+ outputs=chatbot
191
+ )
192
+
193
+ # Optional: envoyer au "Enter" direct
194
+ msg.submit(
195
+ fn=respond,
196
+ inputs=[msg, chatbot],
197
+ outputs=chatbot
198
+ )
199
 
200
  if __name__ == "__main__":
201
+ demo.launch()