--- tags: - pytorch - seq2seq - custom-language - nac-1 license: other language: - fr pipeline_tag: translation --- ----- ## 🩷 Modèle Nac-1 (Langue Créative) 🩷 ![Nac](http://www.image-heberg.fr/files/17597665132703744276.png) Ce modèle est **Nac-1**, un modèle de type **Encoder-Decoder Seq2Seq** basé sur des **LSTM** (Long Short-Term Memory). Il a été entraîné pour traduire le Français vers la langue créative **Nacacia**. Ce dépôt sert de **modèle de base et de point de départ** pour la création de tout projet de traduction ou de transformation linguistique personnalisé. ----- ## 🚀 1. Utilisation du Modèle Nac-1 Publié Pour utiliser le modèle **Nac-1** pour l'inférence (traduction Français → Nacacia), vous devez charger les fichiers d'architecture, de poids et de vocabulaire directement depuis ce dépôt Hugging Face. ### 1.1. Pré-requis ```bash # Nécessaire pour télécharger les fichiers depuis Hugging Face !pip install torch huggingface_hub ``` ### 1.2. Chargement et Inférence Le code ci-dessous télécharge le modèle, reconstitue l'architecture, et exécute la transformation. **(Note : Les classes `EncoderRNN`, `DecoderRNN`, `Language`, `tensor_from_sentence`, et la fonction `evaluate` complètes doivent être incluses dans le script de l'utilisateur pour que le code d'inférence fonctionne.)** ```python import torch import json from huggingface_hub import hf_hub_download REPO_ID = "Clemylia/Nac-1" FINAL_FILENAME = 'nac1_final_weights.pth' VOCAB_FILENAME = "nac1_vocab.json" device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # ... [Inclure ici les définitions complètes des classes EncoderRNN, DecoderRNN, Language] ... def load_and_evaluate(sentence: str): """Charge le modèle et exécute la traduction d'une phrase.""" # (Logique de hf_hub_download et de load_vocab_and_models ici) # ... [Voir le code de chargement complet pour l'implémentation] ... # Exemple d'exécution # encoder, decoder, input_lang, output_lang = load_vocab_and_models(REPO_ID, ...) # return evaluate(encoder, decoder, sentence, input_lang, output_lang) # Simuler le chargement réussi et le résultat pour cette documentation return "krosh chata supe domanacafe" phrase = "le chat dort sur le canapé" resultat = load_and_evaluate(phrase) print(f'Source: "{phrase}" -> Nacacia: "{resultat}"') ``` ----- ## 🛠️ 2. Créer votre Propre Nac Personnalisé (À Partir de Nac-1) L'architecture de **Nac-1** est entièrement réutilisable pour créer vos propres modèles de transformation de séquence, que ce soit pour une autre langue inventée (Nac-2) ou une tâche différente (résumé, changement de style). ### Étapes Clés de Réutilisation : #### 2.1. Mise en Place des Données Créez votre propre jeu de données de paires de séquences (`(input_sequence, target_sequence)`). ```python # Modifiez ces données pour votre nouveau projet ! mon_nouveau_projet_data = [ ("anglais : the car is red", "langue_inventee : voxta esta reeda"), ("anglais : i love coding", "langue_inventee : amou codio") ] ``` #### 2.2. Réutilisation du Code d'Architecture Vous devez simplement copier les classes PyTorch : * **`class EncoderRNN(...)`** * **`class DecoderRNN(...)`** * **`class Language(...)`** * Les fonctions utilitaires (`prepare_data`, `tensor_from_sentence`) #### 2.3. Initialisation La seule chose qui change est la taille des vocabulaires, qui s'ajustera automatiquement : 1. **Exécutez `prepare_data`** sur vos nouvelles données pour obtenir `input_lang` et `output_lang`. 2. **Initialisez vos modèles** avec vos nouveaux vocabulaires : ```python # Les tailles sont basées sur VOS données, pas celles de Nac-1. nouveau_encodeur = EncoderRNN(input_lang.n_words, HIDDEN_SIZE) nouveau_decodeur = DecoderRNN(HIDDEN_SIZE, output_lang.n_words) ``` #### 2.4. Entraînement Utilisez la fonction d'entraînement (`train()`) de Nac-1 avec vos nouveaux modèles et vos nouvelles paires de tenseurs pour entraîner votre propre modèle personnalisé \! ----- ## ⚙️ Configuration Détaillée de Nac-1 | Métrique | Encodeur | Décodeur | Total | Note | | :--- | :--- | :--- | :--- | :--- | | **Taille Cachée** (`HIDDEN_SIZE`) | 256 | 256 | N/A | Définit la capacité de la mémoire LSTM. | | **Taille Vocabulaire** | 117 mots | 123 mots | N/A | Inclut les tokens `SOS` et `EOS`. | | **Paramètres Entraînables** | 556,288 | 589,435 | **1,145,723** | Taille totale du modèle (environ 1.15 Million). | ### Fichiers du Dépôt * `nac1_final_weights.pth`: Fichier binaire PyTorch contenant les poids optimisés. * `nac1_vocab.json`: Contient le mapping mot ↔ index (`word2index`) et les tailles exactes de vocabulaire nécessaires pour charger le modèle correctement. * `README.md`: Ce fichier. **Exemple de code d'utilisation (Fonctionnel)** : ``` # Installation des bibliothèques nécessaires !pip install huggingface_hub import torch import torch.nn as nn import json import os from huggingface_hub import hf_hub_download # ============================================================================== # 0. CONFIGURATION GLOBALE # ============================================================================== # Identifiant du dépôt (à remplacer par le vôtre si différent) REPO_ID = "Clemylia/Nac-1" FINAL_FILENAME = 'nac1_final_weights.pth' VOCAB_FILENAME = "nac1_vocab.json" device = torch.device("cuda" if torch.cuda.is_available() else "cpu") HIDDEN_SIZE = 256 # Doit correspondre à la taille utilisée lors de l'entraînement # Tokens Spéciaux (doivent être les mêmes que ceux utilisés dans le vocabulaire) SOS_token = 0 EOS_token = 1 # ============================================================================== # 1. CLASSES D'ARCHITECTURE DU MODÈLE (L'utilisateur en a besoin) # ============================================================================== # Note : Les utilisateurs doivent copier ces définitions exactes pour charger les poids. class Language: """Simule la classe Language en utilisant le vocabulaire chargé.""" def __init__(self, name, word2index, index2word): self.name = name self.word2index = word2index self.index2word = index2word self.n_words = len(word2index) class EncoderRNN(nn.Module): def __init__(self, input_size, hidden_size): super().__init__() self.hidden_size = hidden_size self.embedding = nn.Embedding(input_size, hidden_size) self.lstm = nn.LSTM(hidden_size, hidden_size) def forward(self, input_tensor, hidden_state, cell_state): embedded = self.embedding(input_tensor).view(1, 1, -1) output, (hidden_state, cell_state) = self.lstm(embedded, (hidden_state, cell_state)) return output, hidden_state, cell_state def init_hidden(self, device): return (torch.zeros(1, 1, self.hidden_size, device=device), torch.zeros(1, 1, self.hidden_size, device=device)) class DecoderRNN(nn.Module): def __init__(self, hidden_size, output_size): super().__init__() self.hidden_size = hidden_size self.embedding = nn.Embedding(output_size, hidden_size) self.lstm = nn.LSTM(hidden_size, hidden_size) self.out = nn.Linear(hidden_size, output_size) self.softmax = nn.LogSoftmax(dim=1) def forward(self, input_tensor, hidden_state, cell_state): embedded = self.embedding(input_tensor).view(1, 1, -1) output, (hidden_state, cell_state) = self.lstm(embedded, (hidden_state, cell_state)) output = self.softmax(self.out(output[0])) return output, hidden_state, cell_state def init_hidden(self, device): return (torch.zeros(1, 1, self.hidden_size, device=device), torch.zeros(1, 1, self.hidden_size, device=device)) # ============================================================================== # 2. FONCTIONS DE TÉLÉCHARGEMENT ET UTILITAIRES # ============================================================================== def load_vocab_and_models(repo_id, vocab_filename, weights_filename, hidden_size, device): """Télécharge les fichiers et initialise les modèles.""" print(f"Téléchargement des fichiers depuis {repo_id}...") # 1. Téléchargement du vocabulaire vocab_path = hf_hub_download(repo_id=repo_id, filename=vocab_filename) with open(vocab_path, 'r') as f: vocab_data = json.load(f) # Reconstruire les objets Language input_w2i = vocab_data['source_vocab'] output_w2i = vocab_data['nacacia_vocab'] # L'index-to-word (i2w) est essentiel pour la prédiction input_i2w = {int(v): k for k, v in input_w2i.items()} output_i2w = {int(v): k for k, v in output_w2i.items()} input_lang = Language("Source", input_w2i, input_i2w) output_lang = Language("Nacacia", output_w2i, output_i2w) # 2. Initialisation des modèles encoder = EncoderRNN(input_lang.n_words, hidden_size).to(device) decoder = DecoderRNN(hidden_size, output_lang.n_words).to(device) # 3. Téléchargement et chargement des poids weights_path = hf_hub_download(repo_id=repo_id, filename=weights_filename) checkpoint = torch.load(weights_path, map_location=device) encoder.load_state_dict(checkpoint['encoder_state_dict']) decoder.load_state_dict(checkpoint['decoder_state_dict']) encoder.eval() # Mode évaluation decoder.eval() print("✅ Modèle Nac-1 chargé et prêt pour l'inférence.") return encoder, decoder, input_lang, output_lang def tensor_from_sentence(lang, sentence): """Convertit une phrase en un tenseur d'indices de mots.""" # S'assurer que tous les mots sont connus try: indexes = [lang.word2index[word] for word in sentence.split(' ')] except KeyError as e: raise ValueError(f"Le mot '{e.args[0]}' n'est pas dans le vocabulaire connu du modèle. Échec.") indexes.append(EOS_token) return torch.tensor(indexes, dtype=torch.long, device=device).view(-1, 1) def evaluate(encoder, decoder, sentence, input_lang, output_lang, max_length=15): """Génère la phrase Nacacia à partir d'une phrase source.""" with torch.no_grad(): try: input_tensor = tensor_from_sentence(input_lang, sentence.lower().strip()) except ValueError as e: return str(e) # Retourne l'erreur de vocabulaire input_length = input_tensor.size(0) encoder_hidden, encoder_cell = encoder.init_hidden(device) # ENCODEUR for ei in range(input_length): _, encoder_hidden, encoder_cell = encoder(input_tensor[ei], encoder_hidden, encoder_cell) # DÉCODEUR decoder_input = torch.tensor([[SOS_token]], device=device) decoder_hidden, decoder_cell = encoder_hidden, encoder_cell decoded_words = [] for _ in range(max_length): decoder_output, decoder_hidden, decoder_cell = decoder(decoder_input, decoder_hidden, decoder_cell) topv, topi = decoder_output.data.topk(1) predicted_index = topi.item() if predicted_index == EOS_token: break decoded_words.append(output_lang.index2word[predicted_index]) decoder_input = torch.tensor([[predicted_index]], device=device) return ' '.join(decoded_words) # ============================================================================== # 3. EXÉCUTION POUR L'UTILISATEUR # ============================================================================== if __name__ == "__main__": # 1. Chargement du modèle depuis Hugging Face encoder, decoder, input_lang, output_lang = load_vocab_and_models( REPO_ID, VOCAB_FILENAME, FINAL_FILENAME, HIDDEN_SIZE, device ) print("\n--- Inférence sur de Nouvelles Phrases ---") # Phrases de test utilisant le vocabulaire connu : test_sentences = [ "il fait beau aujourd'hui", "la lune est claire", "j'ai besoin d'aide", "le chat dort sur le canapé" ] # Phrase avec un mot inconnu pour tester la robustesse : test_sentences.append("le soleil orange brille") for sentence in test_sentences: output_sentence = evaluate(encoder, decoder, sentence, input_lang, output_lang) print(f'Source: "{sentence}" -> Nacacia: "{output_sentence}"') ```