initial commit adds Legml-1
Browse files
README.md
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
---
|
2 |
title: Legml 1
|
3 |
-
emoji:
|
4 |
-
colorFrom:
|
5 |
-
colorTo:
|
6 |
sdk: gradio
|
7 |
sdk_version: 5.36.2
|
8 |
app_file: app.py
|
9 |
-
pinned:
|
10 |
license: mit
|
11 |
short_description: 'Excellence in French-speaking instruction-tuned AI '
|
12 |
---
|
|
|
1 |
---
|
2 |
title: Legml 1
|
3 |
+
emoji: 🇫🇷🏆🇫🇷
|
4 |
+
colorFrom: blue
|
5 |
+
colorTo: red
|
6 |
sdk: gradio
|
7 |
sdk_version: 5.36.2
|
8 |
app_file: app.py
|
9 |
+
pinned: true
|
10 |
license: mit
|
11 |
short_description: 'Excellence in French-speaking instruction-tuned AI '
|
12 |
---
|
app.py
ADDED
@@ -0,0 +1,216 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import spaces
|
2 |
+
import gradio as gr
|
3 |
+
from transformers import AutoTokenizer, AutoModelForCausalLM
|
4 |
+
import torch
|
5 |
+
import os
|
6 |
+
|
7 |
+
# Titre et description
|
8 |
+
Title = """# 🙋🏻♂️Welcome to 🌟Tonic's 🇫🇷🏆 Legml-1-Instruct : L'Excellence Française de l'Instruction-Tuning 🏆🇫🇷"""
|
9 |
+
|
10 |
+
description = """
|
11 |
+
[legml-v1.0-instruct](https://huggingface.co/legmlai/legml-v1.0-instruct) est un modèle LLM francophone, affiné sur près de 800 000 paires instruction/réponse en français (Open-Hermes-FR). Il excelle dans le dialogue, le raisonnement et la QA, avec une rigueur et une bienveillance typiquement françaises.
|
12 |
+
"""
|
13 |
+
|
14 |
+
training = """
|
15 |
+
## Détails d'entraînement
|
16 |
+
|
17 |
+
- **Base** : legmlai/legml-v1.0-base (Qwen-3 · 8B)
|
18 |
+
- **Corpus** : Open-Hermes-FR (799 875 paires, 100% français)
|
19 |
+
- **Méthode** : SFT multi-tour + DPO léger
|
20 |
+
- **Licence** : Apache-2.0
|
21 |
+
- **Sponsor GPU** : 24 × H100 80 Go (Nebius)
|
22 |
+
"""
|
23 |
+
|
24 |
+
join_us = """
|
25 |
+
## Suivez Legml :
|
26 |
+
Retrouvez la communauté legml.ai sur [https://legml.ai](https://legml.ai) et suivez les nouveautés sur [Hugging Face](https://huggingface.co/legmlai).
|
27 |
+
|
28 |
+
# Join us:
|
29 |
+
🌟TeamTonic🌟 is always making cool demos! Join our active builder's 🛠️community 👻
|
30 |
+
[](https://discord.gg/qdfnvSPcqP)
|
31 |
+
On 🤗Huggingface: [MultiTransformer](https://huggingface.co/MultiTransformer)
|
32 |
+
On 🌐Github: [Tonic-AI](https://github.com/tonic-ai) & contribute to🌟 [Build Tonic](https://git.tonic-ai.com/contribute)
|
33 |
+
🤗Big thanks to Yuvi Sharma and all the folks at huggingface for the community grant 🤗
|
34 |
+
"""
|
35 |
+
|
36 |
+
# Initialisation du modèle et du tokenizer
|
37 |
+
model_id = "legmlai/legml-v1.0-instruct"
|
38 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
39 |
+
|
40 |
+
# Récupérer le token Hugging Face si besoin
|
41 |
+
hf_token = os.getenv('READTOKEN')
|
42 |
+
|
43 |
+
# Initialisation du tokenizer et du modèle
|
44 |
+
if hf_token:
|
45 |
+
tokenizer = AutoTokenizer.from_pretrained(model_id, token=hf_token)
|
46 |
+
model = AutoModelForCausalLM.from_pretrained(
|
47 |
+
model_id,
|
48 |
+
token=hf_token,
|
49 |
+
device_map="auto",
|
50 |
+
torch_dtype="auto"
|
51 |
+
)
|
52 |
+
else:
|
53 |
+
tokenizer = AutoTokenizer.from_pretrained(model_id)
|
54 |
+
model = AutoModelForCausalLM.from_pretrained(
|
55 |
+
model_id,
|
56 |
+
device_map="auto",
|
57 |
+
torch_dtype="auto"
|
58 |
+
)
|
59 |
+
|
60 |
+
config_json = model.config.to_dict()
|
61 |
+
|
62 |
+
def format_model_info(config):
|
63 |
+
info = []
|
64 |
+
important_keys = [
|
65 |
+
"model_type", "vocab_size", "hidden_size", "num_attention_heads",
|
66 |
+
"num_hidden_layers", "max_position_embeddings", "torch_dtype"
|
67 |
+
]
|
68 |
+
for key in important_keys:
|
69 |
+
if key in config:
|
70 |
+
value = config[key]
|
71 |
+
if key == "torch_dtype" and hasattr(value, "name"):
|
72 |
+
value = value.name
|
73 |
+
info.append(f"**{key}:** {value}")
|
74 |
+
return "\n".join(info)
|
75 |
+
|
76 |
+
@spaces.GPU
|
77 |
+
def generate_response(system_prompt, user_prompt, temperature, max_new_tokens, top_p, repetition_penalty, top_k):
|
78 |
+
# Préparer le prompt au format chat LEGML
|
79 |
+
messages = [
|
80 |
+
{"role": "system", "content": system_prompt},
|
81 |
+
{"role": "user", "content": user_prompt}
|
82 |
+
]
|
83 |
+
prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
|
84 |
+
inputs = tokenizer(prompt, return_tensors="pt").to(device)
|
85 |
+
outputs = model.generate(
|
86 |
+
**inputs,
|
87 |
+
max_new_tokens=max_new_tokens,
|
88 |
+
temperature=temperature,
|
89 |
+
top_p=top_p,
|
90 |
+
top_k=top_k,
|
91 |
+
repetition_penalty=repetition_penalty,
|
92 |
+
do_sample=True,
|
93 |
+
pad_token_id=tokenizer.eos_token_id
|
94 |
+
)
|
95 |
+
response = tokenizer.decode(outputs[0, inputs["input_ids"].shape[-1]:], skip_special_tokens=True)
|
96 |
+
return response.strip()
|
97 |
+
|
98 |
+
# Interface Gradio
|
99 |
+
with gr.Blocks() as demo:
|
100 |
+
gr.Markdown(Title)
|
101 |
+
with gr.Row():
|
102 |
+
with gr.Column():
|
103 |
+
gr.Markdown(description)
|
104 |
+
with gr.Column():
|
105 |
+
gr.Markdown(training)
|
106 |
+
with gr.Row():
|
107 |
+
with gr.Column():
|
108 |
+
with gr.Group():
|
109 |
+
gr.Markdown("### Configuration du modèle")
|
110 |
+
gr.Markdown(format_model_info(config_json))
|
111 |
+
with gr.Column():
|
112 |
+
with gr.Group():
|
113 |
+
gr.Markdown("### Configuration du tokenizer")
|
114 |
+
gr.Markdown(f"""
|
115 |
+
**Taille du vocabulaire :** {tokenizer.vocab_size}
|
116 |
+
**Longueur max du modèle :** {tokenizer.model_max_length}
|
117 |
+
**Token de padding :** {tokenizer.pad_token}
|
118 |
+
**Token EOS :** {tokenizer.eos_token}
|
119 |
+
""")
|
120 |
+
with gr.Row():
|
121 |
+
with gr.Group():
|
122 |
+
gr.Markdown(join_us)
|
123 |
+
with gr.Row():
|
124 |
+
with gr.Column():
|
125 |
+
system_prompt = gr.Textbox(
|
126 |
+
label="Message Système",
|
127 |
+
value="Tu es un assistant francophone rigoureux et bienveillant. Tu réponds toujours en français de façon précise et utile.",
|
128 |
+
lines=3
|
129 |
+
)
|
130 |
+
user_prompt = gr.Textbox(
|
131 |
+
label="🗣️Votre message",
|
132 |
+
placeholder="Entrez votre texte ici...",
|
133 |
+
lines=5
|
134 |
+
)
|
135 |
+
with gr.Accordion("🧪Paramètres avancés", open=False):
|
136 |
+
temperature = gr.Slider(
|
137 |
+
minimum=0.1,
|
138 |
+
maximum=2.0,
|
139 |
+
value=0.4,
|
140 |
+
step=0.05,
|
141 |
+
label="🌡️Température"
|
142 |
+
)
|
143 |
+
max_new_tokens = gr.Slider(
|
144 |
+
minimum=1,
|
145 |
+
maximum=2048,
|
146 |
+
value=512,
|
147 |
+
step=1,
|
148 |
+
label="💶Longueur maximale"
|
149 |
+
)
|
150 |
+
top_p = gr.Slider(
|
151 |
+
minimum=0.1,
|
152 |
+
maximum=1.0,
|
153 |
+
value=0.9,
|
154 |
+
step=0.05,
|
155 |
+
label="🏅Top-p"
|
156 |
+
)
|
157 |
+
top_k = gr.Slider(
|
158 |
+
minimum=1,
|
159 |
+
maximum=100,
|
160 |
+
value=50,
|
161 |
+
step=1,
|
162 |
+
label="🏆Top-k"
|
163 |
+
)
|
164 |
+
repetition_penalty = gr.Slider(
|
165 |
+
minimum=1.0,
|
166 |
+
maximum=2.0,
|
167 |
+
value=1.05,
|
168 |
+
step=0.05,
|
169 |
+
label="🦜Pénalité de répétition"
|
170 |
+
)
|
171 |
+
generate_btn = gr.Button("🏆 Générer")
|
172 |
+
with gr.Column():
|
173 |
+
output = gr.Textbox(
|
174 |
+
label="🏆 Legml-1-Instruct",
|
175 |
+
lines=10
|
176 |
+
)
|
177 |
+
gr.Examples(
|
178 |
+
examples=[
|
179 |
+
[
|
180 |
+
"Tu es un assistant francophone rigoureux et bienveillant.",
|
181 |
+
"Explique-moi la relativité restreinte en trois points.",
|
182 |
+
0.4, 512, 0.9, 1.05, 50
|
183 |
+
],
|
184 |
+
[
|
185 |
+
"Tu es un expert en histoire de France.",
|
186 |
+
"Quels sont les événements majeurs de la Révolution française?",
|
187 |
+
0.5, 768, 0.9, 1.1, 40
|
188 |
+
],
|
189 |
+
[
|
190 |
+
"Tu es un professeur de mathématiques.",
|
191 |
+
"Explique le théorème de Pythagore simplement.",
|
192 |
+
0.3, 256, 0.85, 1.05, 30
|
193 |
+
],
|
194 |
+
[
|
195 |
+
"Tu es un expert en gastronomie française.",
|
196 |
+
"Quels sont les plats traditionnels français les plus connus?",
|
197 |
+
0.4, 512, 0.9, 1.05, 50
|
198 |
+
],
|
199 |
+
[
|
200 |
+
"Tu es un poète français.",
|
201 |
+
"Écris un court poème sur Paris.",
|
202 |
+
0.7, 256, 0.95, 1.2, 60
|
203 |
+
]
|
204 |
+
],
|
205 |
+
inputs=[system_prompt, user_prompt, temperature, max_new_tokens, top_p, repetition_penalty, top_k],
|
206 |
+
outputs=output,
|
207 |
+
label="Exemples"
|
208 |
+
)
|
209 |
+
generate_btn.click(
|
210 |
+
fn=generate_response,
|
211 |
+
inputs=[system_prompt, user_prompt, temperature, max_new_tokens, top_p, repetition_penalty, top_k],
|
212 |
+
outputs=output
|
213 |
+
)
|
214 |
+
|
215 |
+
if __name__ == "__main__":
|
216 |
+
demo.launch(ssr_mode=False, mcp_server=True)
|