import torch import torch.nn as nn from torch.nn import functional as F import gradio as gr from safetensors.torch import load_file from huggingface_hub import hf_hub_download import sentencepiece as spm # ---------------- CONFIG ---------------- class ModelConfig: n_layer = 8 n_embd = 384 n_head = 6 block_size = 256 vocab_size = 8000 dropout = 0.1 config = ModelConfig() device = "cpu" # Spaces için CPU zorunlu # ---------------- MODEL ---------------- class Head(nn.Module): def __init__(self, head_size): super().__init__() self.key = nn.Linear(config.n_embd, head_size, bias=False) self.query = nn.Linear(config.n_embd, head_size, bias=False) self.value = nn.Linear(config.n_embd, head_size, bias=False) self.register_buffer("tril", torch.tril(torch.ones(config.block_size, config.block_size))) self.dropout = nn.Dropout(config.dropout) def forward(self, x): B, T, C = x.shape k, q, v = self.key(x), self.query(x), self.value(x) wei = q @ k.transpose(-2, -1) * (C ** -0.5) wei = wei.masked_fill(self.tril[:T, :T] == 0, float("-inf")) wei = F.softmax(wei, dim=-1) wei = self.dropout(wei) return wei @ v class MultiHeadAttention(nn.Module): def __init__(self, num_heads, head_size): super().__init__() self.heads = nn.ModuleList([Head(head_size) for _ in range(num_heads)]) self.proj = nn.Linear(config.n_embd, config.n_embd) self.dropout = nn.Dropout(config.dropout) def forward(self, x): out = torch.cat([h(x) for h in self.heads], dim=-1) return self.dropout(self.proj(out)) class FeedForward(nn.Module): def __init__(self, n_embd): super().__init__() self.net = nn.Sequential( nn.Linear(n_embd, 4 * n_embd), nn.ReLU(), nn.Dropout(config.dropout), nn.Linear(4 * n_embd, n_embd), nn.Dropout(config.dropout), ) def forward(self, x): return self.net(x) class Block(nn.Module): def __init__(self, n_embd, n_head): super().__init__() head_size = n_embd // n_head self.sa = MultiHeadAttention(n_head, head_size) self.ffwd = FeedForward(n_embd) self.ln1 = nn.LayerNorm(n_embd) self.ln2 = nn.LayerNorm(n_embd) def forward(self, x): x = x + self.sa(self.ln1(x)) x = x + self.ffwd(self.ln2(x)) return x class MyLanguageModel(nn.Module): def __init__(self): super().__init__() self.token_embedding_table = nn.Embedding(config.vocab_size, config.n_embd) self.position_embedding_table = nn.Embedding(config.block_size, config.n_embd) self.blocks = nn.Sequential(*[Block(config.n_embd, n_head=config.n_head) for _ in range(config.n_layer)]) self.ln_f = nn.LayerNorm(config.n_embd) self.lm_head = nn.Linear(config.n_embd, config.vocab_size) self.dropout = nn.Dropout(config.dropout) def forward(self, idx): B, T = idx.shape tok_emb = self.token_embedding_table(idx) pos_emb = self.position_embedding_table(torch.arange(T, device=idx.device)) x = self.dropout(tok_emb + pos_emb) x = self.blocks(x) x = self.ln_f(x) return self.lm_head(x) # ---------------- LOAD MODEL ---------------- REPO_ID = "jetbabareal/Sabir-20M" print("Model yükleniyor... / Loading model...") model = MyLanguageModel().to(device) weights = hf_hub_download(REPO_ID, "model.safetensors") model.load_state_dict(load_file(weights)) model.eval() tokenizer_path = hf_hub_download(REPO_ID, "tokenizer.model") tokenizer = spm.SentencePieceProcessor(model_file=tokenizer_path) print("Model başarıyla yüklendi! / Model loaded successfully!") # ---------------- GENERATION ---------------- def generate(prompt, max_new_tokens=100, temperature=0.6, top_k=30): if not prompt.strip(): return "Lütfen bir şeyler yazın! / Please write something!" full_prompt = f"Kullanıcı: {prompt}\nModel:" input_ids = tokenizer.encode(full_prompt) idx = torch.tensor(input_ids, dtype=torch.long, device=device).unsqueeze(0) generated_ids = [] for _ in range(max_new_tokens): idx_cond = idx[:, -config.block_size:] with torch.no_grad(): logits = model(idx_cond) logits = logits[:, -1, :] / temperature if top_k: v, _ = torch.topk(logits, min(top_k, logits.size(-1))) logits[logits < v[:, [-1]]] = -float("inf") probs = F.softmax(logits, dim=-1) idx_next = torch.multinomial(probs, num_samples=1) token_id = idx_next.item() generated_ids.append(token_id) # Stop conditions decoded_so_far = tokenizer.decode(generated_ids) if "Kullanıcı:" in decoded_so_far or "Model:" in decoded_so_far: generated_ids = generated_ids[:-1] break if token_id == tokenizer.eos_id(): break idx = torch.cat([idx, idx_next], dim=1) response = tokenizer.decode(generated_ids) return response.strip() # ---------------- GRADIO UI ---------------- with gr.Blocks(theme=gr.themes.Soft()) as demo: gr.Markdown( """ # 🤖 Sabir-20M - Türkçe Mini LLM 20 milyon parametreli deneysel Türkçe dil modeli (eğitim ve araştırma amaçlı) **Not:** Bu model eğitim amaçlı geliştirilmiştir ve küçük bir veri seti üzerinde eğitilmiştir. Üretilen metinler her zaman tutarlı olmayabilir. """ ) with gr.Row(): with gr.Column(): prompt_input = gr.Textbox( label="Promptunuzu yazın / Write your prompt", placeholder="Merhaba, nasılsın?", lines=3 ) with gr.Row(): max_tokens = gr.Slider( minimum=20, maximum=200, value=100, step=10, label="Maksimum Token Sayısı / Max Tokens" ) temperature = gr.Slider( minimum=0.1, maximum=1.5, value=0.6, step=0.1, label="Temperature (Yaratıcılık)" ) top_k = gr.Slider( minimum=5, maximum=50, value=30, step=5, label="Top-K Sampling" ) generate_btn = gr.Button("🚀 Üret / Generate", variant="primary") with gr.Column(): output = gr.Textbox( label="Model Çıktısı / Model Output", lines=10 ) gr.Markdown( """ ### 💡 İpuçları: - **Temperature**: Düşük değerler (0.3-0.5) daha tutarlı, yüksek değerler (0.8-1.2) daha yaratıcı çıktılar üretir - **Top-K**: Düşük değerler daha deterministik, yüksek değerler daha çeşitli sonuçlar verir - **Max Tokens**: Daha uzun yanıtlar için artırın (ancak tutarsızlık riski artar) ### 📊 Model Bilgileri: - Parametre Sayısı: ~20M - Mimari: Transformer (8 katman, 384 gizli boyut) - Vocabulary: 8000 token (SentencePiece) """ ) # Örnek promptlar gr.Examples( examples=[ ["Merhaba, nasılsın?"], ["Türkiye'nin başkenti neresidir?"], ["Yapay zeka nedir?"], ["En sevdiğin renk nedir?"], ["Bugün hava nasıl?"], ], inputs=prompt_input, ) generate_btn.click( fn=generate, inputs=[prompt_input, max_tokens, temperature, top_k], outputs=output ) demo.launch()