Clemylia commited on
Commit
3aa68b3
·
verified ·
1 Parent(s): aaed79b

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +238 -1
README.md CHANGED
@@ -84,4 +84,241 @@ model_path = hf_hub_download(repo_id="Clemyllia/Liquy-Neko-CharRNN", filename="l
84
  **Amusez-vous bien avec Liquy-Neko \!** N'hésitez pas à partager vos créations les plus folles dans la communauté \! 💖✨
85
 
86
  **Lien site de documentation lovable** :
87
- https://liquy-neko-docs.lovable.app/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  **Amusez-vous bien avec Liquy-Neko \!** N'hésitez pas à partager vos créations les plus folles dans la communauté \! 💖✨
85
 
86
  **Lien site de documentation lovable** :
87
+ https://liquy-neko-docs.lovable.app/
88
+
89
+ **Exemple de code d'utilisation** :
90
+
91
+ ```
92
+ import torch
93
+ import torch.nn as nn
94
+ import torch.nn.functional as F
95
+ import re
96
+ import sys
97
+ import os
98
+ import io
99
+ import random
100
+ # Installe la bibliothèque Hugging Face (nécessaire pour le téléchargement)
101
+ # Si vous êtes dans un notebook, exécutez d'abord : !pip install -q huggingface_hub
102
+ from huggingface_hub import hf_hub_download
103
+
104
+ REPO_ID = "Clemylia/Liquy-Neko"
105
+ MODEL_FILE = 'liquy.pt'
106
+
107
+ # Constantes de base (doivent correspondre à celles de l'entraînement Char-RNN)
108
+ SOS_token = 0
109
+ EOS_token = 1
110
+ MAX_LENGTH = 30
111
+ HIDDEN_SIZE = 256
112
+
113
+ # Configuration du périphérique
114
+ DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
115
+
116
+ # Initialisation des variables globales
117
+ input_lang = None
118
+ output_lang = None
119
+ encoder = None
120
+ decoder = None
121
+ global_temperature = 0.9
122
+
123
+ # Classe Lang (Vocabulaire générique pour Mots et Caractères)
124
+ class Lang:
125
+ """Stocke le vocabulaire (tokens <-> index)."""
126
+ def __init__(self, name, is_char_mode=False):
127
+ self.name = name
128
+ self.is_char_mode = is_char_mode
129
+ self.token2index = {}
130
+ self.token2count = {}
131
+ self.index2token = {SOS_token: "SOS", EOS_token: "EOS"}
132
+ self.n_tokens = 2
133
+
134
+ class EncoderRNN(nn.Module):
135
+ def __init__(self, input_size, hidden_size, dropout_p):
136
+ super(EncoderRNN, self).__init__()
137
+ self.hidden_size = hidden_size
138
+ self.embedding = nn.Embedding(input_size, hidden_size)
139
+ self.gru = nn.GRU(hidden_size, hidden_size)
140
+ self.dropout = nn.Dropout(dropout_p)
141
+
142
+ def forward(self, input, hidden):
143
+ embedded = self.embedding(input).view(1, 1, -1)
144
+ embedded = self.dropout(embedded)
145
+ output, hidden = self.gru(embedded, hidden)
146
+ return output, hidden
147
+
148
+ def initHidden(self, device):
149
+ return torch.zeros(1, 1, self.hidden_size, device=device)
150
+
151
+ # Architecture du Décodeur (Char-RNN)
152
+ class DecoderRNN(nn.Module):
153
+ def __init__(self, hidden_size, output_size, dropout_p):
154
+ super(DecoderRNN, self).__init__()
155
+ self.hidden_size = hidden_size
156
+ self.embedding = nn.Embedding(output_size, hidden_size)
157
+ self.gru = nn.GRU(hidden_size, hidden_size)
158
+ self.out = nn.Linear(hidden_size, output_size)
159
+ self.softmax = nn.LogSoftmax(dim=1)
160
+ self.dropout = nn.Dropout(dropout_p)
161
+
162
+ def forward(self, input, hidden):
163
+ output = self.embedding(input).view(1, 1, -1)
164
+ output = F.relu(output)
165
+ output = self.dropout(output)
166
+ output, hidden = self.gru(output, hidden)
167
+ output = self.softmax(self.out(output[0]))
168
+ return output, hidden
169
+
170
+ def indexesFromSentence(lang, sentence):
171
+ """Convertit une phrase/clé en indices de tokens (mots ou caractères)."""
172
+ tokens = list(sentence) if lang.is_char_mode else sentence.split(' ')
173
+ return [lang.token2index[token] for token in tokens if token in lang.token2index]
174
+
175
+ def load_model_from_hub():
176
+ """Télécharge le modèle depuis Hugging Face et le charge localement."""
177
+ global input_lang, output_lang, encoder, decoder, global_temperature
178
+
179
+ try:
180
+ # TÉLÉCHARGEMENT DU FICHIER DEPUIS HUGGING FACE
181
+ print(f"Téléchargement de {MODEL_FILE} depuis {REPO_ID}...")
182
+ model_path = hf_hub_download(repo_id=REPO_ID, filename=MODEL_FILE)
183
+ print(f"✅ Fichier téléchargé à : {model_path}")
184
+
185
+ # CHARGEMENT LOCAL
186
+ checkpoint = torch.load(model_path, map_location=DEVICE)
187
+
188
+ # Récupère les configurations et les objets Lang
189
+ input_lang = checkpoint['input_lang']
190
+ output_lang = checkpoint['output_lang']
191
+ hidden_size = checkpoint['hidden_size']
192
+ dropout_rate = checkpoint['dropout_rate']
193
+ # Récupère la température, utilise une valeur élevée par défaut si non trouvée
194
+ global_temperature = checkpoint.get('temperature', 1.1)
195
+
196
+ # Initialisation des modèles (utilise n_tokens de chaque objet Lang)
197
+ encoder = EncoderRNN(input_lang.n_tokens, hidden_size, dropout_rate).to(DEVICE)
198
+ decoder = DecoderRNN(hidden_size, output_lang.n_tokens, dropout_rate).to(DEVICE)
199
+
200
+ # Charge les poids
201
+ encoder.load_state_dict(checkpoint['encoder_state_dict'])
202
+ decoder.load_state_dict(checkpoint['decoder_state_dict'])
203
+
204
+ print(f"\n✅ Modèle 'Liquy-Neko' chargé depuis le Hub ! 💖")
205
+ print(f"Configuration : TEMP={global_temperature:.1f}, HIDDEN_SIZE={hidden_size}, DROPOUT={dropout_rate}")
206
+ return True
207
+
208
+ except Exception as e:
209
+ print(f"\n❌ ERREUR lors du chargement du modèle depuis le Hub. Vérifiez le REPO_ID et l'existence du fichier.")
210
+ print(f"Détail de l'erreur : {e}")
211
+ return False
212
+
213
+ def evaluate(encoder, decoder, sentence, max_length=MAX_LENGTH, temperature=global_temperature):
214
+ """Génère une expression de CHAR-RNN en utilisant l'échantillonnage de température."""
215
+ encoder.eval()
216
+ decoder.eval()
217
+
218
+ # Prépare la clé d'entrée pour le modèle
219
+ sentence_tokens = sentence.replace('_', ' ')
220
+
221
+ with torch.no_grad():
222
+ # Vérification minimale du vocabulaire (pour éviter les crashs)
223
+ if not all(token in input_lang.token2index for token in sentence_tokens.split(' ')):
224
+ return "Clé inconnue du vocabulaire d'entrée."
225
+
226
+ input_tensor = torch.tensor(indexesFromSentence(input_lang, sentence_tokens), dtype=torch.long, device=DEVICE).view(-1, 1)
227
+ input_length = input_tensor.size(0)
228
+
229
+ encoder_hidden = encoder.initHidden(DEVICE)
230
+
231
+ # Phase Encodeur
232
+ for ei in range(input_length):
233
+ _, encoder_hidden = encoder(input_tensor[ei], encoder_hidden)
234
+
235
+ decoder_input = torch.tensor([[SOS_token]], device=DEVICE)
236
+ decoder_hidden = encoder_hidden
237
+
238
+ decoded_chars = []
239
+
240
+ # Phase Décodeur - Génération par caractère (Char-RNN)
241
+ for di in range(max_length):
242
+ decoder_output, decoder_hidden = decoder(decoder_input, decoder_hidden)
243
+
244
+ # Application de la Température pour l'aléa (créativité)
245
+ output_distribution = decoder_output.squeeze(0).div(temperature).exp()
246
+
247
+ # Échantillonnage: choisit le prochain caractère
248
+ topi = torch.multinomial(output_distribution, 1)[0]
249
+
250
+ if topi.item() == EOS_token:
251
+ break
252
+ else:
253
+ # Récupération du caractère
254
+ decoded_chars.append(output_lang.index2token[topi.item()])
255
+
256
+ decoder_input = topi.detach()
257
+
258
+ encoder.train()
259
+ decoder.train()
260
+
261
+ return ''.join(decoded_chars)
262
+
263
+ def generer_liquy_neko_interface(prompt):
264
+ """Analyse le prompt utilisateur, construit la clé et génère l'expression."""
265
+
266
+ prompt_ton = prompt
267
+ prompt_texte = prompt
268
+
269
+ # Logique d'extraction du ton et de la demande d'emoji
270
+ emoji_part = '_e' if 'emoji' in prompt_texte.lower() else '_ne'
271
+
272
+ if 'un peu kawaii' in prompt_ton.lower(): input_key = 'un_peu_k'
273
+ elif 'peu kawaii' in prompt_ton.lower(): input_key = 'peu_k'
274
+ elif 'moyennement kawaii' in prompt_ton.lower(): input_key = 'moyennement_k'
275
+ elif 'hautement kawaii' in prompt_ton.lower(): input_key = 'hautement_k'
276
+ elif 'imaginaire' in prompt_ton.lower(): input_key = 'lang_imag'
277
+ else: input_key = 'moyennement_k'
278
+
279
+ final_key = input_key + emoji_part
280
+
281
+ result = evaluate(encoder, decoder, final_key, temperature=global_temperature)
282
+
283
+ print(f"\n--- Liquy-Neko - Création Unique ---")
284
+ print(f"Ton demandé: **{input_key.replace('_', ' ')}**")
285
+ print(f"Clé modèle utilisée: `{final_key.replace('_', ' ')}`")
286
+ print(f"Résultat: **{result}**")
287
+
288
+ if __name__ == "__main__":
289
+
290
+ print("\n" + "="*55)
291
+ print(" DÉMARRAGE DE LIQUY-NEKO (CHAR-RNN HUB TEST) ")
292
+ print("="*55)
293
+
294
+ if not load_model_from_hub():
295
+ # Quitte si le chargement a échoué
296
+ sys.exit("Impossible de continuer sans charger le modèle.")
297
+
298
+
299
+ print("\n[A] Tests Automatisés :")
300
+ generer_liquy_neko_interface("hautement kawaii avec des emojis")
301
+ generer_liquy_neko_interface("en langue imaginaire sans emojis")
302
+
303
+
304
+ print("\n" + "-"*55)
305
+ print("--- DÉMARRAGE DE L'INTERFACE INTERACTIVE ---")
306
+ print("Teste ta créature ! Exemples : 'peu kawaii', 'hautement kawaii emoji', 'imaginaire'.")
307
+ print("Tapez 'quitter' pour terminer.")
308
+ print("-"*55)
309
+
310
+ while True:
311
+ try:
312
+ user_input = input("Ton prompt (>): ")
313
+ if user_input.lower() in ['quitter', 'exit']:
314
+ print("Au revoir ! C'était génial de déployer ton modèle ! 👋")
315
+ break
316
+
317
+ generer_liquy_neko_interface(user_input)
318
+
319
+ except EOFError:
320
+ print("\nFin de l'entrée. Arrêt de l'interface. 👋")
321
+ break
322
+ except Exception as e:
323
+ print(f"Une erreur est survenue lors de la génération: {e}. Réessayez.")
324
+ ```