#. 🚀 Documentation : Erzilem-prototype1-4.4b
• Propriétaire : Clemylia-LLMs
• Architecture : NelyaForLLM (Optimisée et calibré pour les LLM efficients de conlangs)
2 📖 Présentation du Projet Erzilem-prototype1-4.4b est un modèle expérimental conçu pour explorer la densité de l'information au sein d'une architecture à 32 couches. Bien qu'il utilise une configuration structurelle robuste typique des modèles plus vastes, son entraînement est focalisé sur une précision sémantique accrue et une texture de langage unique, caractéristique des travaux de recherche "from scratch".
⚙️ Spécifications Techniques
| Paramètre | Valeur |
|---|---|
| Vocab Size | 14,594 |
| Hidden Size | 4,096 |
| Layers | 32 |
| Attention Heads | 32 |
| Intermediate Size | 8,192 |
| Max Position (Context) | 128 |
💡 Points Forts du Modèle
- Architecture Efficiente : Utilisation de l'architecture NelyaForLLM pour maximiser le rendu par paramètre effectif.
- Texture de Langage : Entraîné sur des datasets propriétaires, le modèle favorise l'originalité syntaxique et la création de néologismes plutôt que la répétition de schémas conventionnels.
- Conception "From Scratch" : Évite les solutions lisses et génériques pour forger une identité linguistique propre.
- Focus Sémantique : Grâce à une vocab_size optimisée, le modèle traite chaque mot avec une densité d'information supérieure, idéal pour les tâches spécialisées.
🛠️ Cas d'Usage
- Recherche en Linguistique : Idéal pour expérimenter de nouvelles structures de langues inventées.
- Génération de Texture : Parfait pour des récits ou des simulations nécessitant une empreinte syntaxique marquée.
- Prototypage LLM/SLM : Une base robuste pour tester l'efficience des futurs modèles 4b+ en phase de développement.
🧪 État du Projet
Note de développement : Actuellement en phase de prototypage (sous-entraîné). Le modèle est conçu pour évoluer vers des versions plus denses et stables. Les retours sur la cohérence textuelle au sein de la fenêtre de 128 tokens sont encouragés pour affiner les prochaines itérations.
🍬 Inference (exemple) :
import torch
import torch.nn as nn
import torch.nn.functional as F
from transformers import PreTrainedTokenizerFast
from tokenizers import Tokenizer
from huggingface_hub import hf_hub_download
import safetensors.torch
import json
import os
# --- Custom Model Architecture (Copy from original training script) ---
# This is necessary to load the custom model from safetensors
class NelyaBitLinear(nn.Linear):
def forward(self, x):
w = self.weight
scale = w.abs().mean()
w_bit = w + (torch.round(torch.clamp(w / (scale + 1e-5), -1, 1)) - w).detach()
x_norm = x - x.mean(dim=-1, keepdim=True)
x_bit = x_norm + (torch.sign(x_norm) - x_norm).detach()
return F.linear(x_bit, w_bit, self.bias)
class NelyaBlock(nn.Module):
def __init__(self, config):
super().__init__()
self.ln1 = nn.RMSNorm(config.hidden_size)
self.attn = nn.MultiheadAttention(config.hidden_size, config.num_heads, batch_first=True)
self.ln2 = nn.RMSNorm(config.hidden_size)
self.mlp = nn.Sequential(
NelyaBitLinear(config.hidden_size, config.intermediate_size, bias=False),
nn.SiLU(),
NelyaBitLinear(config.intermediate_size, config.hidden_size, bias=False)
)
def forward(self, x):
attn_out, _ = self.attn(self.ln1(x), self.ln1(x), self.ln1(x))
x = x + attn_out
x = x + self.mlp(self.ln2(x))
return x
class NelyaConfig:
def __init__(self, vocab_size, hidden_size=4096, num_layers=12, num_heads=32, intermediate_size=8192, max_pos=128):
self.vocab_size = vocab_size
self.hidden_size = hidden_size
self.num_layers = num_layers
self.num_heads = num_heads
self.intermediate_size = intermediate_size
self.max_pos = max_pos
class NelyaForLLM(nn.Module):
def __init__(self, config):
super().__init__()
self.embed = nn.Embedding(config.vocab_size, config.hidden_size)
self.block = NelyaBlock(config)
self.head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
self.num_layers = config.num_layers
def forward(self, input_ids, labels=None, attention_mask=None):
x = self.embed(input_ids)
for _ in range(self.num_layers):
x = self.block(x)
logits = self.head(x)
if labels is not None:
loss = F.cross_entropy(logits.view(-1, logits.size(-1)), labels.view(-1))
return (loss,)
return logits
# --- Configuration for loading ---
REPO_ID = "Clemylia-LLMs/Erzilem-prototype1-4.4b" # Your Hugging Face repository ID
# Download model files from Hugging Face Hub
print(f"🚀 Downloading model files from {REPO_ID}...")
model_path = hf_hub_download(repo_id=REPO_ID, filename="model.safetensors")
tokenizer_path = hf_hub_download(repo_id=REPO_ID, filename="tokenizer.json")
config_path = hf_hub_download(repo_id=REPO_ID, filename="nelya_config.json")
# Load tokenizer
print("⏳ Loading tokenizer...")
bpe_obj = Tokenizer.from_file(tokenizer_path)
tokenizer = PreTrainedTokenizerFast(tokenizer_object=bpe_obj, pad_token="[PAD]")
# Load custom config
print("⚙️ Loading custom NelyaConfig...")
with open(config_path, "r") as f:
config_dict = json.load(f)
config = NelyaConfig(**config_dict)
# Instantiate and load model weights
print("🏗️ Instantiating model and loading weights...")
with torch.device("cuda"):
model = NelyaForLLM(config)
model.load_state_dict(safetensors.torch.load_file(model_path))
# Count and print parameters
num_params = sum(p.numel() for p in model.parameters())
print(f"\n🔥 TOTAL PARAMÈTRES du modèle chargé : {num_params:,}")
print(f"🔥 CLASSIFICATION : {'LLM' if num_params > 800_000_000 else 'SLM'}")
print(f"🔥 TAILLE ESTIMÉE VRAM (1-bit) : ~{num_params * 1.58 / 8 / 1e9:.2f} Go")
# --- Inference Example ---
model.eval() # Set the model to evaluation mode
input_text = "Qui es-tu ?"
print(f"\nInput: {input_text}")
# Tokenize input
input_ids = tokenizer.encode(input_text, return_tensors="pt").to("cuda")
# Generation parameters
max_generation_length = 100 # Define the number of tokens to generate
temperature = 1.7 # Controls randomness: higher = more random, lower = more deterministic
top_k = 50 # Samples from the top_k most likely tokens
with torch.no_grad():
generated_ids = input_ids # Start with the input tokens
for _ in range(max_generation_length):
# Get logits for the last token in the sequence
logits = model(generated_ids)
# Apply temperature
logits = logits[0, -1, :] / temperature
# Apply top-k filtering
if top_k is not None:
v, _ = torch.topk(logits, min(top_k, logits.size(-1)))
logits[logits < v[-1]] = -float('Inf')
# Convert to probabilities
probabilities = F.softmax(logits, dim=-1)
# Sample from the distribution
predicted_token_id = torch.multinomial(probabilities, num_samples=1).item()
# If it's an end-of-sequence token, stop generation
if predicted_token_id == tokenizer.eos_token_id or predicted_token_id == tokenizer.pad_token_id:
break
# Append the predicted token to the generated sequence
generated_ids = torch.cat([generated_ids, torch.tensor([[predicted_token_id]]).to("cuda")], dim=-1)
# Decode the complete generated sequence
generated_text = tokenizer.decode(generated_ids[0], skip_special_tokens=True)
print(f"\nGenerated text ({len(generated_ids[0]) - len(input_ids[0])} new tokens):\n'{generated_text}'")
print('fin')
📛 Pré-requis (inference)
-> GPU T4 ou supérieur (sinon ca mets 10 ans a répondre, même si c'est efficient) -> transformers -> bitsandyte.
