Spaces:
Sleeping
Sleeping
Download app.py from ArushBuilds/Pragya: direct link, hf CLI and curl.
- Browser
- Download file 7.59 kB
-
https://huggingface.co/spaces/ArushBuilds/Pragya/resolve/067c53c6c29fd4381fdca510a91dbbbe39bc9aa0/app.py
- Command line
-
hf download hf://spaces/ArushBuilds/Pragya@067c53c6c29fd4381fdca510a91dbbbe39bc9aa0/app.py
-
curl -L -o app.py https://huggingface.co/spaces/ArushBuilds/Pragya/resolve/067c53c6c29fd4381fdca510a91dbbbe39bc9aa0/app.py
7.59 kB
| from __future__ import annotations | |
| import os | |
| os.environ["KERAS_BACKEND"] = "jax" | |
| import numpy as np | |
| import jax | |
| import keras | |
| import gradio as gr | |
| from pathlib import Path | |
| from veylon_model import create_llm | |
| from tokenizer import TokenizerWrapper | |
| from config import ( | |
| CONTEXT, | |
| vocab_size, | |
| D_MODEL, | |
| numberoflayers, | |
| numberofheads, | |
| d_Latent, | |
| ffn_mult, | |
| num_kv_heads, | |
| swa_window, | |
| ) | |
| # ============================================================ | |
| # Initialize (runs once) | |
| # ============================================================ | |
| keras.mixed_precision.set_global_policy("mixed_bfloat16") | |
| print(f"Backend: {keras.backend.backend()}") | |
| print(f"JAX devices: {jax.devices()}") | |
| # Load tokenizer | |
| tokenizer = TokenizerWrapper("tokenizer.model") | |
| assert tokenizer.vocab_size == vocab_size, ( | |
| f"Tokenizer vocab ({tokenizer.vocab_size}) != config vocab ({vocab_size})" | |
| ) | |
| print(f"✓ Tokenizer loaded: {tokenizer.vocab_size} vocab") | |
| # Build model | |
| print("Building model...") | |
| model = create_llm( | |
| vocab_size=vocab_size, | |
| d_model=D_MODEL, | |
| n_layers=numberoflayers, | |
| n_heads=numberofheads, | |
| d_latent=d_Latent, | |
| ffn_mult=ffn_mult, | |
| max_seq_len=CONTEXT, | |
| use_moe=False, | |
| num_kv_heads=num_kv_heads, | |
| swa_window=swa_window, | |
| ) | |
| # Warmup | |
| dummy = np.zeros((1, CONTEXT), dtype=np.int32) | |
| _ = model(dummy, training=False) | |
| print("✓ Model built successfully") | |
| # Load weights | |
| WEIGHTS_PATH = "veylon_final.weights.h5" | |
| if Path(WEIGHTS_PATH).exists(): | |
| print(f"Loading weights from: {WEIGHTS_PATH}") | |
| model.load_weights(WEIGHTS_PATH) | |
| print("✓ Weights loaded successfully") | |
| else: | |
| print(f"WARNING: {WEIGHTS_PATH} not found. Using untrained model.") | |
| print(f"✓ Model params: {model.count_params():,}\n") | |
| # ============================================================ | |
| # Sampling | |
| # ============================================================ | |
| def sample_from_logits( | |
| logits: np.ndarray, | |
| temperature: float = 0.8, | |
| top_k: int = 50, | |
| ) -> int: | |
| """NumPy-only sampling.""" | |
| logits = np.array(logits, dtype=np.float32, copy=True) | |
| if temperature > 0: | |
| logits = logits / float(max(temperature, 1e-8)) | |
| if top_k > 0: | |
| k = min(int(top_k), logits.shape[-1]) | |
| row = logits[0] | |
| top_indices = np.argpartition(row, -k)[-k:] | |
| filtered = np.full_like(row, -np.inf) | |
| filtered[top_indices] = row[top_indices] | |
| logits[0] = filtered | |
| row = logits[0] | |
| row = row - np.max(row) | |
| probs = np.exp(row) | |
| probs = probs / probs.sum() | |
| return int(np.random.choice(len(probs), p=probs)) | |
| # ============================================================ | |
| # Generation function | |
| # ============================================================ | |
| def generate( | |
| prompt: str, | |
| max_new_tokens: int = 64, | |
| temperature: float = 0.8, | |
| top_k: int = 50, | |
| ) -> str: | |
| """ | |
| Generate text from a prompt using Veylon. | |
| Args: | |
| prompt: Input text | |
| max_new_tokens: Maximum tokens to generate | |
| temperature: Sampling temperature (0.1-2.0) | |
| top_k: Top-K sampling cutoff | |
| Returns: | |
| Generated text | |
| """ | |
| try: | |
| # Encode prompt | |
| tokens = tokenizer.encode( | |
| prompt, | |
| add_bos=True, | |
| add_eos=False, | |
| ) | |
| if len(tokens) == 0: | |
| tokens = [tokenizer.bos_id if hasattr(tokenizer, "bos_id") else 1] | |
| tokens = tokens[-CONTEXT:] | |
| # Prefill phase | |
| prompt_ids = np.array([tokens], dtype=np.int32) | |
| logits, cache_k, cache_v = model.generate_step( | |
| prompt_ids, | |
| cache_k=None, | |
| cache_v=None, | |
| cache_pos=0, | |
| ) | |
| next_token = sample_from_logits( | |
| np.array(logits[:, -1, :], dtype=np.float32, copy=True), | |
| temperature=temperature, | |
| top_k=top_k, | |
| ) | |
| tokens.append(next_token) | |
| # Decoding phase (token-by-token) | |
| if next_token != tokenizer.eos_id and len(tokens) < CONTEXT: | |
| cache_pos = len(prompt_ids[0]) | |
| for _ in range(max_new_tokens - 1): | |
| next_input = np.array([[next_token]], dtype=np.int32) | |
| logits, cache_k, cache_v = model.generate_step( | |
| next_input, | |
| cache_k=cache_k, | |
| cache_v=cache_v, | |
| cache_pos=cache_pos, | |
| ) | |
| cache_pos += 1 | |
| next_token = sample_from_logits( | |
| np.array(logits[:, -1, :], dtype=np.float32, copy=True), | |
| temperature=temperature, | |
| top_k=top_k, | |
| ) | |
| tokens.append(next_token) | |
| if next_token == tokenizer.eos_id: | |
| break | |
| if len(tokens) >= CONTEXT: | |
| break | |
| # Decode output | |
| generated_text = tokenizer.decode(tokens) | |
| return generated_text | |
| except Exception as e: | |
| return f"Error: {str(e)}" | |
| # ============================================================ | |
| # Gradio UI | |
| # ============================================================ | |
| def main(): | |
| with gr.Blocks(title="Veylon Alpha") as demo: | |
| gr.Markdown(""" | |
| # 🚀 Veylon Alpha Preview - 10M LLM | |
| # Made by Arush Kumar | |
| A student dev! | |
| A small transformer model trained on clean data. | |
| Enter a prompt and watch it generate text. | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| prompt = gr.Textbox( | |
| label="Prompt", | |
| placeholder="Once upon a time", | |
| lines=3, | |
| value="Once upon a time" | |
| ) | |
| with gr.Row(): | |
| max_tokens = gr.Slider( | |
| label="Max tokens", | |
| minimum=10, | |
| maximum=256, | |
| value=64, | |
| step=10, | |
| ) | |
| temperature = gr.Slider( | |
| label="Temperature", | |
| minimum=0.1, | |
| maximum=2.0, | |
| value=0.8, | |
| step=0.1, | |
| ) | |
| top_k = gr.Slider( | |
| label="Top-K", | |
| minimum=1, | |
| maximum=100, | |
| value=50, | |
| step=1, | |
| ) | |
| generate_btn = gr.Button("Generate", variant="primary", size="lg") | |
| with gr.Column(scale=1): | |
| info = gr.Markdown(f""" | |
| **Model Info** | |
| - Parameters: {model.count_params():,} | |
| - Context: {CONTEXT} tokens | |
| - Vocab: {vocab_size} | |
| - Architecture: Transformer + GQA | |
| **Tips** | |
| - Higher temp = more creative | |
| - Lower temp = more deterministic | |
| - Top-K = diversity control | |
| """) | |
| output = gr.Textbox( | |
| label="Generated Output", | |
| lines=8, | |
| interactive=False | |
| ) | |
| # Connect | |
| generate_btn.click( | |
| fn=generate, | |
| inputs=[prompt, max_tokens, temperature, top_k], | |
| outputs=output, | |
| api_name="generate" | |
| ) | |
| demo.launch(share=False, server_name="0.0.0.0", server_port=7860) | |
| if __name__ == "__main__": | |
| main() |