diff --git "a/AshishAgarwal.ipynb" "b/AshishAgarwal.ipynb" new file mode 100644--- /dev/null +++ "b/AshishAgarwal.ipynb" @@ -0,0 +1,1015 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "490880a8-d1a4-42cf-8ff8-df4c60bc1235", + "metadata": {}, + "source": [ + "# Library Imports" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "d8b740da-fdc1-46b7-b273-ca1bf85102b5", + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "from torch.nn import functional as F\n", + "\n", + "import json\n", + "import random\n", + "from collections import defaultdict\n", + "import time\n", + "import sys\n", + "import io\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "\n", + "\n", + "from transformers import AutoTokenizer \n", + "from tokenizers.pre_tokenizers import Whitespace\n", + "import warnings\n", + "import pickle" + ] + }, + { + "cell_type": "markdown", + "id": "66923f7a-95d1-44f4-a481-c0d6625798dd", + "metadata": {}, + "source": [ + "# Setting GPU/CPU device" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b37a05a-d42f-4795-9e0c-67603a2311a1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CUDA available: True\n", + "CUDA device count: 8\n", + "Current CUDA device: 0\n" + ] + } + ], + "source": [ + "# Check if CUDA is available and print more information\n", + "print(f\"CUDA available: {torch.cuda.is_available()}\")\n", + "if torch.cuda.is_available():\n", + " print(f\"CUDA device count: {torch.cuda.device_count()}\")\n", + " print(f\"Current CUDA device: {torch.cuda.current_device()}\")\n", + " device = torch.device(\"cuda\")\n", + "else:\n", + " print(\"CUDA is not available. Using CPU instead.\")\n", + " device = torch.device(\"cpu\")" + ] + }, + { + "cell_type": "markdown", + "id": "cec9d62f-344a-467f-94ad-0c59d3568003", + "metadata": {}, + "source": [ + "# Using BPE tokenizer from previous assignment" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "5915680d-3173-42ac-a254-9107fabd51f7", + "metadata": {}, + "outputs": [], + "source": [ + "class BPETokenizer:\n", + " def __init__(self, vocab_size=4000):\n", + " self.vocab_size = vocab_size\n", + " self.vocab = [\"<|endoftext|>\"]\n", + " self.word_freqs = defaultdict(int)\n", + " self.merges = {}\n", + " self.tokenizer = AutoTokenizer.from_pretrained(\"gpt2\")\n", + "\n", + " def compute_pair_freqs(self,splits):\n", + " pair_freqs = defaultdict(int)\n", + " for word, freq in self.word_freqs.items():\n", + " split = splits[word]\n", + " if len(split) == 1:\n", + " continue\n", + " for i in range(len(split) - 1):\n", + " pair = (split[i], split[i + 1])\n", + " pair_freqs[pair] += freq\n", + " return pair_freqs\n", + " \n", + " def merge_pair(self,a, b, splits):\n", + " for word in self.word_freqs:\n", + " split = splits[word]\n", + " if len(split) == 1:\n", + " continue\n", + "\n", + " i = 0\n", + " while i < len(split) - 1:\n", + " if split[i] == a and split[i + 1] == b:\n", + " split = split[:i] + [a + b] + split[i + 2 :]\n", + " else:\n", + " i += 1\n", + " splits[word] = split\n", + " return splits\n", + "\n", + " def build_vocab(self, corpus):\n", + " for text in corpus:\n", + " self.tokenizer.backend_tokenizer.pre_tokenizer = Whitespace()\n", + " text= ' Ġ'.join(text.split())\n", + " words_with_offsets = self.tokenizer.backend_tokenizer.pre_tokenizer.pre_tokenize_str(text)\n", + " new_words = [word for word, offset in words_with_offsets]\n", + " for word in new_words:\n", + " self.word_freqs[word] += 1\n", + "\n", + " alphabet = []\n", + "\n", + " for word in self.word_freqs.keys():\n", + " for letter in word:\n", + " if letter not in alphabet:\n", + " alphabet.append(letter)\n", + " alphabet.sort()\n", + "\n", + "\n", + " # Add every unique character to the vocab\n", + " for char in alphabet:\n", + " if char not in self.vocab:\n", + " self.vocab.append(char)\n", + "\n", + " splits = {word: [c for c in word] for word in self.word_freqs.keys()}\n", + "\n", + " while len(self.vocab) < self.vocab_size:\n", + " pair_freqs = self.compute_pair_freqs(splits)\n", + " best_pair = \"\"\n", + " max_freq = None\n", + " for pair, freq in pair_freqs.items():\n", + " if max_freq is None or max_freq < freq:\n", + " best_pair = pair\n", + " max_freq = freq\n", + " if len(best_pair) == 2:\n", + " splits = self.merge_pair(best_pair[0],best_pair[1], splits)\n", + " self.merges[best_pair] = best_pair[0] + best_pair[1]\n", + " self.vocab.append(best_pair[0] + best_pair[1])\n", + " else:\n", + " break\n", + "\n", + "\n", + " def tokenize(self,text):\n", + " self.tokenizer.backend_tokenizer.pre_tokenizer = Whitespace()\n", + " pre_tokenize_result = self.tokenizer._tokenizer.pre_tokenizer.pre_tokenize_str(text)\n", + " pre_tokenized_text = [word for word, offset in pre_tokenize_result]\n", + " splits = [[l for l in word] for word in pre_tokenized_text]\n", + "\n", + "\n", + " for word in pre_tokenized_text:\n", + " for char in word:\n", + " if char not in self.vocab:\n", + " self.vocab.append(char) \n", + "\n", + " for pair, merge in self.merges.items():\n", + " for idx, split in enumerate(splits):\n", + " i = 0\n", + " while i < len(split) - 1:\n", + " if split[i] == pair[0] and split[i + 1] == pair[1]:\n", + " split = split[:i] + [merge] + split[i + 2 :]\n", + " else:\n", + " i += 1\n", + " splits[idx] = split\n", + "\n", + " return sum(splits, [])\n", + "\n", + " def save(self, file_path):\n", + " \"\"\"\n", + " Save the tokenizer's state to a file.\n", + " \"\"\"\n", + " state = {\n", + " 'vocab_size': self.vocab_size,\n", + " 'vocab': self.vocab,\n", + " 'word_freqs': dict(self.word_freqs),\n", + " 'merges': self.merges\n", + " }\n", + " with open(file_path, 'wb') as f:\n", + " pickle.dump(state, f)\n", + "\n", + " @classmethod\n", + " def load(cls, file_path):\n", + " \"\"\"\n", + " Load a tokenizer's state from a file.\n", + " \"\"\"\n", + " with open(file_path, 'rb') as f:\n", + " state = pickle.load(f)\n", + " \n", + " tokenizer = cls(vocab_size=state['vocab_size'])\n", + " tokenizer.vocab = state['vocab']\n", + " tokenizer.word_freqs = defaultdict(int, state['word_freqs'])\n", + " tokenizer.merges = state['merges']\n", + " return tokenizer\n" + ] + }, + { + "cell_type": "markdown", + "id": "7ad2cd41-a4d3-4cfa-bb49-9a30c8e19a43", + "metadata": {}, + "source": [ + "# Encode Decode function implemenation" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "2459246a-5d33-455a-9bab-cd06976c582f", + "metadata": {}, + "outputs": [], + "source": [ + "tokenizer_file = \"tokenizer.pkl\"\n", + "\n", + "def encode(text):\n", + " # Step 1: Encode, decode, and normalize the text\n", + " text = text.encode('utf-8').decode('utf-8').lower()\n", + " text = 'Ġ'.join(text.split())\n", + "\n", + " # Step 2: Load tokenizer\n", + " tokenizer_instance = BPETokenizer.load(tokenizer_file)\n", + "\n", + " # Step 3: Create a dictionary for vocabulary for O(1) lookups\n", + " vocab_dict = {token: idx for idx, token in enumerate(tokenizer_instance.vocab)}\n", + "\n", + " # Step 4: Tokenize the text\n", + " tokens = tokenizer_instance.tokenize(text)\n", + "\n", + " # Step 5: Generate token IDs efficiently\n", + " unknown_token_id = len(tokenizer_instance.vocab) \n", + " token_ids = [vocab_dict.get(t, unknown_token_id) for t in tokens]\n", + "\n", + " return token_ids\n", + "\n", + "def decode(token_ids):\n", + " tokenizer_instance = BPETokenizer.load(tokenizer_file)\n", + " tokens = []\n", + " for id in token_ids:\n", + " if 0 <= id < len(tokenizer_instance.vocab):\n", + " tokens.append(tokenizer_instance.vocab[id])\n", + " else:\n", + " # Handle out-of-vocabulary token IDs\n", + " tokens.append('')\n", + " decoded_string = ''.join(tokens)\n", + " decoded_string = decoded_string.replace('Ġ', ' ').strip()\n", + " return decoded_string" + ] + }, + { + "cell_type": "markdown", + "id": "d2320fce-43fb-4d28-ba2a-7831ae725c2e", + "metadata": {}, + "source": [ + "# Data Handling" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "68eeed34-53a0-412a-a86b-2eefea02a46a", + "metadata": {}, + "outputs": [], + "source": [ + "# Helper function to load JSON data\n", + "def load_json_data(file_path):\n", + " with open(file_path, 'r', encoding='utf-8') as f:\n", + " data = json.load(f)\n", + " return data" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "685df365-cb3b-49a9-93a1-46a3977184d4", + "metadata": {}, + "outputs": [], + "source": [ + "def find_space_low_strings(strings, low_bound, up_bound):\n", + " result = []\n", + " for index, text in enumerate(strings):\n", + " total_chars = len(text)\n", + " space_count = text.count(' ')\n", + "\n", + " # Calculate percentage if there are non-space characters\n", + " if total_chars > space_count:\n", + " percentage = (space_count / (total_chars - space_count)) * 100\n", + " if percentage > low_bound and percentage < up_bound:\n", + " result.append(text)\n", + "\n", + " return result" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "85778ca0-6cba-4f30-b6b1-55bb11cb17ad", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "24653\n", + "16555\n" + ] + } + ], + "source": [ + "# Load English and Amharic data\n", + "english_data = load_json_data('alpaca_data_cleaned_cleaned_corpus.json')\n", + "amharic_data = load_json_data('Amharic_cleaned_corpus.json')\n", + "\n", + "# Using data samples having longer context\n", + "long_english_data = [s for s in english_data if len(s) >= 500]\n", + "long_amharic_data = [s for s in amharic_data if len(s) >= 500]\n", + "print(len(long_english_data))\n", + "print(len(long_amharic_data))\n", + "\n", + "long_english_data = find_space_low_strings(long_english_data, 17, 22)\n", + "long_amharic_data = find_space_low_strings(long_amharic_data, 22, 26)\n", + "\n", + "\n", + "# Control how many elements to take from each file\n", + "num_english_elements = 1000 # Number of elements from English file\n", + "num_amharic_elements = 1000 # Number of elements from Amharic file\n", + "\n", + "\n", + "random.shuffle(long_english_data)\n", + "random.shuffle(long_amharic_data)\n", + "# Slice data from both files as per the desired number of elements\n", + "english_list = long_english_data[:num_english_elements]\n", + "amharic_list = long_amharic_data[:num_amharic_elements]" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "8e4da812-0fd5-4710-90b5-40763ad6457b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2146699\n" + ] + } + ], + "source": [ + "# Combine the texts\n", + "combined_list = english_list + amharic_list\n", + "\n", + "# Shuffle the combined text\n", + "def shuffle_text(text_list, seed=42):\n", + " random.seed(seed)\n", + " # Split into blocks of text\n", + " random.shuffle(text_list) # Shuffle the text blocks\n", + " return ' '.join(text_list)\n", + "\n", + "# Shuffle the combined text\n", + "text = shuffle_text(combined_list)\n", + "print(len(text))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "96e58556-d016-441f-a695-ad4349b70ba3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2.69 ms, sys: 66.9 ms, total: 69.6 ms\n", + "Wall time: 68.3 ms\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + ":3: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n" + ] + } + ], + "source": [ + "%%time\n", + "# Encode the entire dataset\n", + "# data = torch.tensor(encode(text), dtype=torch.long)\n", + "data = torch.load('tensor_data.pt')\n", + "\n", + "# Split into train and validation sets\n", + "n = int(0.8 * len(data))\n", + "train_data = data[:n]\n", + "val_data = data[n:]\n", + "\n", + "\n", + "def get_batch(split):\n", + " data = train_data if split == 'train' else val_data\n", + " # Making sure we don't try to start at an index that would give us an incomplete sequence\n", + " max_index = len(data) - hyperparams['block_size'] - 1\n", + " if max_index < 1:\n", + " raise ValueError(f\"Not enough data for sequence length {hyperparams['block_size']}\")\n", + " \n", + " ix = torch.randint(max_index, (hyperparams['block_size'],))\n", + " \n", + " x = torch.stack([data[i:i+hyperparams['block_size']] for i in ix])\n", + " y = torch.stack([data[i+1:i+hyperparams['block_size']+1] for i in ix])\n", + " \n", + " return x.to(device), y.to(device)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "d644ad3e-aedb-480f-8acc-99ea111226d1", + "metadata": {}, + "outputs": [], + "source": [ + "# Evaluation function\n", + "@torch.no_grad()\n", + "def estimate_loss():\n", + " out = {}\n", + " model.eval()\n", + " for split in ['train', 'val']:\n", + " losses = torch.zeros(hyperparams['eval_iters'])\n", + " for k in range(hyperparams['eval_iters']):\n", + " X, Y = get_batch(split)\n", + " logits, loss = model(X, Y)\n", + " losses[k] = loss.item()\n", + " out[split] = losses.mean()\n", + " model.train()\n", + " return out" + ] + }, + { + "cell_type": "markdown", + "id": "beaba601-ad27-4f6f-af9c-d4092a9beeec", + "metadata": {}, + "source": [ + "# Hyperparameters Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "b47ec2f6-1444-4027-8ca8-70ca818bd9e0", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"\n", + "These are our hyperparameters. Feel free to change\n", + "\"\"\"\n", + "# Hyperparameters\n", + "hyperparams = {}\n", + "hyperparams['batch_size'] = 128 # This defines the number of samples processed in one forward/backward pass of the model.\n", + "hyperparams['block_size'] = 256 # sequence length || This represents the length of the input sequences the model will process.\n", + "hyperparams['max_iters'] = 3000 # This sets the maximum number of training iterations (or steps) the model will perform.\n", + " # The training will stop after this many iterations, even if other stopping criteria haven't been met.\n", + "hyperparams['eval_interval'] = 300 # This determines how often the model's performance is evaluated during training.\n", + "hyperparams['learning_rate'] = 1e-2 # This controls the step size at each iteration while moving toward a minimum of the loss function.\n", + "hyperparams['eval_iters'] = 200\n", + "hyperparams['n_embd'] = 512 # Refers to the dimensionality of the embedding space.\n", + "hyperparams['n_hidden'] = 1024\n", + "hyperparams['dropout'] = 0.3 # Dropout is a regularization technique to prevent overfitting." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "8179c773-16ed-4512-80b3-1fcb70f65576", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[' ', '#', '$', '%', '&', '*', '+', '>', '@', '[', '\\\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '°', '²', '³', '¹', '×', 'é', 'ö', '÷', 'λ', 'ሀ', 'ሁ', 'ሂ', 'ሃ', 'ሄ', 'ህ', 'ሆ', 'ለ', 'ሉ', 'ሊ', 'ላ', 'ሌ', 'ል', 'ሎ', 'ሏ', 'ሐ', 'ሑ', 'ሒ', 'ሔ', 'ሕ', 'መ', 'ሙ', 'ሚ', 'ማ', 'ሜ', 'ም', 'ሞ', 'ሟ', 'ሠ', 'ሣ', 'ሥ', 'ሦ', 'ረ', 'ሩ', 'ሪ', 'ራ', 'ሬ', 'ር', 'ሮ', 'ሯ', 'ሰ', 'ሱ', 'ሲ', 'ሳ', 'ሴ', 'ስ', 'ሶ', 'ሷ', 'ሸ', 'ሹ', 'ሺ', 'ሻ', 'ሼ', 'ሽ', 'ሾ', 'ሿ', 'ቀ', 'ቁ', 'ቂ', 'ቃ', 'ቄ', 'ቅ', 'ቆ', 'ቋ', 'በ', 'ቡ', 'ቢ', 'ባ', 'ቤ', 'ብ', 'ቦ', 'ቧ', 'ቨ', 'ቪ', 'ቫ', 'ቬ', 'ቭ', 'ቮ', 'ተ', 'ቱ', 'ቲ', 'ታ', 'ቴ', 'ት', 'ቶ', 'ቷ', 'ቸ', 'ቹ', 'ቺ', 'ቻ', 'ቼ', 'ች', 'ቾ', 'ቿ', 'ኃ', 'ኄ', 'ኅ', 'ኋ', 'ነ', 'ኑ', 'ኒ', 'ና', 'ኔ', 'ን', 'ኖ', 'ኗ', 'ኘ', 'ኙ', 'ኚ', 'ኛ', 'ኜ', 'ኝ', 'ኞ', 'ኟ', 'አ', 'ኡ', 'ኢ', 'ኤ', 'እ', 'ኦ', 'ኧ', 'ከ', 'ኩ', 'ኪ', 'ካ', 'ኬ', 'ክ', 'ኮ', 'ኳ', 'ኸ', 'ወ', 'ዉ', 'ዊ', 'ዋ', 'ዌ', 'ው', 'ዎ', 'ዐ', 'ዑ', 'ዒ', 'ዓ', 'ዔ', 'ዕ', 'ዖ', 'ዘ', 'ዙ', 'ዚ', 'ዛ', 'ዜ', 'ዝ', 'ዞ', 'ዟ', 'ዠ', 'ዡ', 'ዢ', 'ዣ', 'ዤ', 'ዥ', 'ዦ', 'የ', 'ዩ', 'ያ', 'ዬ', 'ይ', 'ዮ', 'ደ', 'ዱ', 'ዲ', 'ዳ', 'ዴ', 'ድ', 'ዶ', 'ዷ', 'ጀ', 'ጁ', 'ጂ', 'ጃ', 'ጄ', 'ጅ', 'ጆ', 'ጇ', 'ገ', 'ጉ', 'ጊ', 'ጋ', 'ጌ', 'ግ', 'ጎ', 'ጓ', 'ጠ', 'ጡ', 'ጢ', 'ጣ', 'ጤ', 'ጥ', 'ጦ', 'ጧ', 'ጨ', 'ጩ', 'ጪ', 'ጫ', 'ጬ', 'ጭ', 'ጮ', 'ጲ', 'ጴ', 'ጵ', 'ጶ', 'ጸ', 'ጹ', 'ጻ', 'ጽ', 'ጾ', 'ጿ', 'ፀ', 'ፁ', 'ፃ', 'ፅ', 'ፆ', 'ፈ', 'ፉ', 'ፊ', 'ፋ', 'ፌ', 'ፍ', 'ፎ', 'ፏ', 'ፐ', 'ፑ', 'ፒ', 'ፓ', 'ፔ', 'ፕ', 'ፖ', '፡', '።', '፣', '፤', '፥', '፦', '–', '‘', '’', '“', '”', '‹', '›', '⁰', '💪', '📢', '🙏', '🧴', '🧼']\n", + "4000\n" + ] + } + ], + "source": [ + "\"\"\"\n", + "Please change this with the tokenizer you have created for your dataset.\n", + "\"\"\"\n", + "# Create the vocabulary\n", + "chars = sorted(list(set(text)))\n", + "vocab_size = 4000 # check BPETokenizer initialization\n", + "\n", + "print(chars)\n", + "print(vocab_size)" + ] + }, + { + "cell_type": "markdown", + "id": "b554e9f4-4420-4adb-9297-758aa85588a8", + "metadata": {}, + "source": [ + "# Model Class Definition" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "c0a7617c-e65a-40ed-aa74-c716d87be947", + "metadata": {}, + "outputs": [], + "source": [ + "class SimpleRNNModel(nn.Module):\n", + " def __init__(self):\n", + " super().__init__()\n", + " self.embedding = nn.Embedding(vocab_size, hyperparams['n_embd'])\n", + " # print(f\"Embedding layer: {vocab_size} x {n_embd}\")\n", + " # self.rnn = nn.RNN(n_embd, n_hidden, batch_first=True)\n", + " self.rnn = nn.LSTM(hyperparams['n_embd'], hyperparams['n_hidden'], batch_first=True)\n", + " # print(f\"RNN layer: {n_embd} -> {n_hidden}\")\n", + " self.fc = nn.Linear(hyperparams['n_hidden'], vocab_size)\n", + " # print(f\"Linear layer: {n_hidden} -> {vocab_size}\")\n", + " self.dropout = nn.Dropout(hyperparams['dropout'])\n", + "\n", + "\n", + " def forward(self, idx, targets=None):\n", + " B, T = idx.shape\n", + " # print(f\"Input shape in forward: {idx.shape}\")\n", + " # print(f\"Max token in input: {idx.max()}\")\n", + " \n", + " embeds = self.embedding(idx)\n", + " # print(f\"Embedding output shape: {embeds.shape}\")\n", + " \n", + " output, _ = self.rnn(embeds)\n", + " # print(f\"RNN output shape: {output.shape}\")\n", + " \n", + " output = self.dropout(output)\n", + " logits = self.fc(output)\n", + " # print(f\"Logits shape: {logits.shape}\")\n", + " \n", + " if targets is None:\n", + " loss = None\n", + " else:\n", + " # print(f\"Targets shape: {targets.shape}\")\n", + " # print(f\"Max token in targets: {targets.max()}\")\n", + " B, T, C = logits.shape\n", + " logits = logits.view(B*T, C)\n", + " targets = targets.view(B*T)\n", + " loss = F.cross_entropy(logits, targets)\n", + " \n", + " return logits, loss\n", + "\n", + "\n", + " def generate(self, idx, max_new_tokens):\n", + " for _ in range(max_new_tokens):\n", + " idx_cond = idx[:, -hyperparams['block_size']:]\n", + " embeds = self.embedding(idx_cond)\n", + " output, _ = self.rnn(embeds)\n", + " logits = self.fc(output[:, -1, :])\n", + " probs = F.softmax(logits, dim=-1)\n", + " idx_next = torch.multinomial(probs, num_samples=1)\n", + " idx = torch.cat((idx, idx_next), dim=1)\n", + " return idx\n" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "045d03c3-87e6-46a4-887b-521da832e208", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "12.447648 M parameters\n" + ] + } + ], + "source": [ + "\"\"\" Lets get things ready for the training \"\"\"\n", + "model = SimpleRNNModel().to(device) # Send the model to GPU\n", + "print(sum(p.numel() for p in model.parameters())/1e6, 'M parameters') # How many parameters we have in our model?\n", + "\n", + "# Create an optimizer\n", + "optimizer = torch.optim.AdamW(model.parameters(), lr=hyperparams['learning_rate'])" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "65249553-2a6f-4208-a451-88fb2b9b9c17", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train data size: 10100769\n", + "Validation data size: 2525193\n", + "Vocabulary size: 4000\n" + ] + } + ], + "source": [ + "print(f\"Train data size: {len(train_data)}\")\n", + "print(f\"Validation data size: {len(val_data)}\")\n", + "print(f\"Vocabulary size: {vocab_size}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "57ca28e4-cb1c-4fd2-a9fb-cfed554cc8c9", + "metadata": {}, + "outputs": [], + "source": [ + "def calculate_perplexity(model, data, block_size=hyperparams['block_size'], batch_size=hyperparams['batch_size']):\n", + " model.eval()\n", + " total_loss = 0\n", + " total_tokens = 0\n", + "\n", + " with torch.no_grad():\n", + " for i in range(0, len(data) - block_size, block_size):\n", + " current_batch_size = batch_size\n", + " \n", + " # Adjust batch size for the last batch if not enough data\n", + " if i + block_size * batch_size > len(data):\n", + " current_batch_size = (len(data) - i) // block_size\n", + " \n", + " x = []\n", + " y = []\n", + " \n", + " # Collect chunks for x and y, ensuring they're consistent\n", + " for j in range(0, block_size * current_batch_size, block_size):\n", + " x_chunk = data[i+j : i+j+block_size]\n", + " y_chunk = data[i+j+1 : i+j+block_size+1]\n", + " \n", + " # Skip this batch if we have any incomplete chunks\n", + " if len(x_chunk) == block_size and len(y_chunk) == block_size:\n", + " x.append(x_chunk)\n", + " y.append(y_chunk)\n", + "\n", + " if len(x) == 0 or len(y) == 0:\n", + " continue\n", + "\n", + " x = torch.stack(x).to(model.embedding.weight.device)\n", + " y = torch.stack(y).to(model.embedding.weight.device)\n", + "\n", + " logits, _ = model(x)\n", + " loss = F.cross_entropy(logits.view(-1, logits.size(-1)), y.view(-1), reduction='sum')\n", + " \n", + " total_loss += loss.item()\n", + " total_tokens += y.numel()\n", + "\n", + " avg_loss = total_loss / total_tokens\n", + " perplexity = torch.exp(torch.tensor(avg_loss))\n", + "\n", + " return perplexity.item()\n" + ] + }, + { + "cell_type": "markdown", + "id": "54863d6a-48bb-4aaa-864f-07ee6849a727", + "metadata": {}, + "source": [ + "# Training" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "04e07290-2a7f-4018-8519-dd8c99c527dd", + "metadata": {}, + "outputs": [], + "source": [ + "save_path = 'cp_10k_500char_words_v5/'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "33d5be6f-1c16-48c5-bf62-ff40ff249c00", + "metadata": {}, + "outputs": [], + "source": [ + "# Initialize variables to track the best model\n", + "best_val_loss = float('inf')\n", + "best_model_state = None\n", + "train_losses = []\n", + "val_losses = []\n", + "perplexities = []\n", + "save_path = '../'\n", + "for iter in range(hyperparams['max_iters']):\n", + " try:\n", + " # Evaluation phase\n", + " if iter % hyperparams['eval_interval'] == 0:\n", + " model.eval() # Set to evaluation mode for validation\n", + " losses = estimate_loss()\n", + " train_loss = losses['train']\n", + " val_loss = losses['val']\n", + " train_losses.append(train_loss)\n", + " val_losses.append(val_loss)\n", + "\n", + " # Calculate perplexity\n", + " perplexity = calculate_perplexity(model, val_data, hyperparams['block_size'], hyperparams['batch_size'])\n", + " perplexities.append(perplexity)\n", + "\n", + " print(f\"Step {iter}: train loss {train_loss:.4f}, val loss {val_loss:.4f}, perplexity {perplexity:.4f}\")\n", + "\n", + " # Save the model and check for overfitting\n", + " torch.save(model.state_dict(), f\"{save_path}checkpoint_{iter}.pt\")\n", + " if val_loss < best_val_loss:\n", + " best_val_loss = val_loss\n", + " best_model_state = model.state_dict()\n", + " torch.save(best_model_state, f\"{save_path}best_model.pt\")\n", + " print(\"New best model saved.\")\n", + " \n", + " if len(val_losses) > 3 and val_losses[-1] > val_losses[-2] > val_losses[-3]:\n", + " print(\"Overfitting detected. Exiting training.\")\n", + " break\n", + "\n", + " # Training phase\n", + " model.train() # Set to training mode\n", + " print(f\"\\nIteration {iter}:\")\n", + " xb, yb = get_batch('train')\n", + " \n", + " logits, loss = model(xb, yb)\n", + " print(f\"Loss: {loss.item()}\")\n", + " \n", + " optimizer.zero_grad(set_to_none=True)\n", + " loss.backward()\n", + " optimizer.step()\n", + " \n", + " except RuntimeError as e:\n", + " print(f\"Error at iteration {iter}: {e}\")\n", + " print(\"Last shapes:\")\n", + " print(f\"xb shape: {xb.shape}, yb shape: {yb.shape}\")\n", + " print(f\"xb max token: {xb.max()}, yb max token: {yb.max()}\")\n", + " break" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "403799c6-9d99-4eb3-8e4b-9d5474320b28", + "metadata": {}, + "outputs": [], + "source": [ + "# Save final training state\n", + "if best_model_state is not None:\n", + " model.load_state_dict(best_model_state)\n", + " torch.save(model.state_dict(), f\"{save_path}best_model_final.pt\")\n", + " print(\"Best model saved as best_model_final.pt\")" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "74e4fe82-a31b-4749-b960-e516aa6e2d6c", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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9z558mSuuuoqRowYwaZNm1iwYEGF3vHyz500aRJ33nkn/fv3Z+vWrXz++ecVeuAB4uPjCQkJ4b333iMwMBB/f38uvPBCWrVqVenzR40axSWXXMJTTz1FYmIi3bt3Z+HChcybN4+JEydWWCSuJvz6668UFhZWah89ejR//etfef/99xk3bhwbNmwgLi6Ob775hlWrVvHmm286evrvueceMjIyuPTSS4mJiSEpKYkpU6bQo0cPx/z1Tp06MWTIEHr37k1YWBjr16/nm2++YcKECTX6fUREpOYopIuIiFsLDw9n/vz5PProozz99NOEhoZy2223cdlllzF8+HBXlwdA7969WbBgAY899hjPPPMMsbGxTJo0iZ07d55x9XlPT0++//57Hn74YSZPnoyPjw/XXnstEyZMoHv37udUj9ls5rvvvmPixInMmDEDk8nE1VdfzRtvvEHPnj3P6l633norM2fOJDo6mksvvbTCsXHjxpGamsr777/Pzz//TKdOnZgxYwazZs1i6dKlZ133iy++iI+PD++99x5LlizhwgsvZOHChYwcObLCef/85z/Jy8tj5syZfPXVV/Tq1YsffviBJ554osJ5np6efPrppzz55JPcf//9lJaWMnXq1CpDevmf2bPPPstXX33F1KlTiYuL47XXXuPRRx896+9yJj/99FOlRd4A4uLi6NKlC0uXLuWJJ57g008/JTs7m/bt2zN16lTGjRvnOPe2227jgw8+4J133iEzM5OmTZty00038dxzzzmGyT/88MN89913LFy4kKKiIlq2bMmLL77I448/XuPfSUREaobJ7k5dESIiIg3I6NGjtf2ViIiInBXNSRcREakBBQUFFd7v2bOHH3/8kSFDhrimIBEREamX1JMuIiJSA6Kjoxk3bhytW7cmKSmJd999l6KiIjZt2lRp728RERGR09GcdBERkRpwxRVX8MUXX5Camoq3tzf9+vXjpZdeUkAXERGRs6KedBERERERERE3oTnpIiIiIiIiIm5CIV1ERERERETETTS6Oek2m41Dhw4RGBiIyWRydTkiIiIiIiLSwNntdnJycmjWrBlms/O+8kYX0g8dOkRsbKyryxAREREREZFGJjk5mZiYGKfnNLqQHhgYCBh/OEFBQS6uRkRERERERBq67OxsYmNjHXnUmUYX0suHuAcFBSmki4iIiIiISJ2pzpRrLRwnIiIiIiIi4iYU0kVERERERETchEK6iIiIiIiIiJtodHPSRURERERE3IHdbqe0tBSr1erqUqQGeHp6YrFYzvs+CukiIiIiIiJ1rLi4mMOHD5Ofn+/qUqSGmEwmYmJiCAgIOK/7KKSLiIiIiIjUIZvNRkJCAhaLhWbNmuHl5VWtVb/Ffdntdo4dO8bBgwdp27btefWoK6SLiIiIiIjUoeLiYmw2G7Gxsfj5+bm6HKkhTZo0ITExkZKSkvMK6Vo4TkRERERExAXMZsWxhqSmRkPop0JERERERETETSiki4iIiIiIiLgJhXQRERERERFxmbi4ON58801Xl+E2FNJFRERERETkjEwmk9PHc889d073XbduHX/961/Pq7YhQ4YwceLE87qHu9Dq7iIiIiIiInJGhw8fdrz+6quvePbZZ9m9e7ej7eT9we12O1arFQ+PM0fOJk2a1Gyh9Zx60kVERERERFzMbreTX1zqkofdbq9WjU2bNnU8goODMZlMjve7du0iMDCQBQsW0Lt3b7y9vVm5ciX79u3jmmuuISoqioCAAPr27csvv/xS4b6nDnc3mUx89NFHXHvttfj5+dG2bVu+++678/rz/fbbb+ncuTPe3t7ExcXxxhtvVDj+zjvv0LZtW3x8fIiKiuL66693HPvmm2/o2rUrvr6+hIeHM3ToUPLy8s6rHmfUky4iIiIiIuJiBSVWOj37s0s+e8ek4fh51Uw0fOKJJ3j99ddp3bo1oaGhJCcnM2LECP7v//4Pb29vpk+fzqhRo9i9ezctWrQ47X2ef/55Xn31VV577TWmTJnCrbfeSlJSEmFhYWdd04YNG7jxxht57rnnuOmmm1i9ejUPPvgg4eHhjBs3jvXr1/Pwww/z2Wef0b9/fzIyMlixYgVgjB645ZZbePXVV7n22mvJyclhxYoV1f7FxrlQSBcREREREZEaMWnSJC6//HLH+7CwMLp37+54/8ILLzBnzhy+++47JkyYcNr7jBs3jltuuQWAl156ibfeeou1a9dyxRVXnHVN//73v7nssst45plnAGjXrh07duzgtddeY9y4cRw4cAB/f3+uuuoqAgMDadmyJT179gSMkF5aWsqYMWNo2bIlAF27dj3rGs6GQrq7KsyGhOXgGwJxF7u6GhERERERqUW+nhZ2TBruss+uKX369KnwPjc3l+eee44ffvjBEXgLCgo4cOCA0/t069bN8drf35+goCCOHj16TjXt3LmTa665pkLbgAEDePPNN7FarVx++eW0bNmS1q1bc8UVV3DFFVc4htp3796dyy67jK5duzJ8+HCGDRvG9ddfT2ho6DnVUh2ak+6u1n0EX90Kq992dSUiIiIiIlLLTCYTfl4eLnmYTKYa+x7+/v4V3j/22GPMmTOHl156iRUrVrB582a6du1KcXGx0/t4enpW+vOx2Ww1VufJAgMD2bhxI1988QXR0dE8++yzdO/enczMTCwWC4sWLWLBggV06tSJKVOm0L59exISEmqlFlBId19tLjOeE1dAqfMfYBEREREREXe0atUqxo0bx7XXXkvXrl1p2rQpiYmJdVpDx44dWbVqVaW62rVrh8VijCLw8PBg6NChvPrqq/zxxx8kJiayePFiwPgFwYABA3j++efZtGkTXl5ezJkzp9bq1XB3dxXVFfwiID8NDq7VkHcREREREal32rZty+zZsxk1ahQmk4lnnnmm1nrEjx07xubNmyu0RUdH8+ijj9K3b19eeOEFbrrpJtasWcPbb7/NO++8A8D8+fPZv38/gwYNIjQ0lB9//BGbzUb79u35/fff+fXXXxk2bBiRkZH8/vvvHDt2jI4dO9bKdwD1pLut/FIbRyL7G2/2/uraYkRERERERM7Bv//9b0JDQ+nfvz+jRo1i+PDh9OrVq1Y+a+bMmfTs2bPC48MPP6RXr158/fXXfPnll3Tp0oVnn32WSZMmMW7cOABCQkKYPXs2l156KR07duS9997jiy++oHPnzgQFBbF8+XJGjBhBu3btePrpp3njjTe48sora+U7AJjstbl2vBvKzs4mODiYrKwsgoKCXF3Oab2zdC97Fn7Ef7zehejucN9yV5ckIiIiIiI1oLCwkISEBFq1aoWPj4+ry5Ea4ux/17PJoepJd1P94yNYaStb2v/wFshLc21BIiIiIiIiUusU0t1Ul2ZBFHpHsMNm7MXHviWuLUhERERERERqnUK6m/KwmLmwdRjLbWX7A+7TvHQREREREZGGTiHdjfWLj2CZI6Qvhsa1fICIiIiIiEijo5DuxvrHh7PB1o58uzfkHoEj211dkoiIiIiIiNQihXQ31j4qkAB/f36zle3BpyHvIiIiIiIiDZpCuhszm030ax1+Yl669ksXERERERFp0BTS3dxF8SeF9ANroDjPtQWJiIiIiIhIrVFId3P948PZb48mxR4B1mJIWu3qkkRERERERKSWKKS7udYR/kQF+bDM2tVo0JB3ERERERGpx4YMGcLEiRNdXYbbUkh3cyaTif7xESy3dTcatHiciIiIiIi4wKhRo7jiiiuqPLZixQpMJhN//PHHeX/OtGnTCAkJOe/71FcK6fVAv/hwVts6Y8UMaX9CZrKrSxIRERERkUbm7rvvZtGiRRw8eLDSsalTp9KnTx+6devmgsoaFoX0eqB/fDjZ+LPFFm807Fvs2oJERERERKRm2e3GItGueNjt1SrxqquuokmTJkybNq1Ce25uLrNmzeLuu+8mPT2dW265hebNm+Pn50fXrl354osvavSP6sCBA1xzzTUEBAQQFBTEjTfeyJEjRxzHt2zZwiWXXEJgYCBBQUH07t2b9evXA5CUlMSoUaMIDQ3F39+fzp078+OPP9ZofefLw9UFyJnFhPrRIsyPZVnd6GXeYwx5732Hq8sSEREREZGaUpIPLzVzzWf/8xB4+Z/xNA8PD8aOHcu0adN46qmnMJlMAMyaNQur1cott9xCbm4uvXv35h//+AdBQUH88MMP3H777cTHx3PBBRecd6k2m80R0JctW0ZpaSnjx4/npptuYunSpQDceuut9OzZk3fffReLxcLmzZvx9PQEYPz48RQXF7N8+XL8/f3ZsWMHAQEB511XTVJIryf6x4ezfH03/s63sH8pWEvBov/5RERERESk7tx111289tprLFu2jCFDhgDGUPfrrruO4OBggoODeeyxxxznP/TQQ/z88898/fXXNRLSf/31V7Zu3UpCQgKxsbEATJ8+nc6dO7Nu3Tr69u3LgQMHePzxx+nQoQMAbdu2dVx/4MABrrvuOrp2NRbmbt269XnXVNOU8uqJfvHhfL0unlyTPwGFWXBoI8Se/w+5iIiIiIi4AU8/o0fbVZ9dTR06dKB///588sknDBkyhL1797JixQomTZoEgNVq5aWXXuLrr78mJSWF4uJiioqK8POr/mc4s3PnTmJjYx0BHaBTp06EhISwc+dO+vbtyyOPPMI999zDZ599xtChQ7nhhhuIjzemDj/88MM88MADLFy4kKFDh3Lddde53Tx6zUmvJ/rFh2PDzPLSzkaD5qWLiIiIiDQcJpMx5NwVj7Jh69V199138+2335KTk8PU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WSIiIiIiInIOFNLrOZPJRL/4cHLx41BgV6NRQ95FRERERETqJYX0BqB8yPsKWzejQUPeRURERERE6iWF9AagPKR/ndnWaEhYDtYSF1YkIiIiIiIi50IhvQFoEeZH8xBftpTGUeIdCkXZcHC9q8sSERERERGRs6SQ3gCUz0u3YWZPQB+jcZ/mpYuIiIiIiNQ3CukNRPmQ90VFnY0GLR4nIiIiIiJS7yikNxD9ykL6l+ltjIZDmyA/w4UViYiIiIiIyNlSSG8gooN9aR3hz2F7GDnB7QA77F/i6rJERERERETkLCikNyDlvelbfXobDXu1FZuIiIiIiEh9opDegPSPjwDg+9yORsO+X8Fud2FFIiIiIiIicjYU0huQi1qHATA7vQV2Dx/IOQzHdrm4KhEREREREakuhfQGJDzAmw5NAynCi2NhZVuxaZV3ERERERGRekMhvYEpH/K+zqOn0aD90kVEREREROoNhfQGpny/9FmZ7YyGpNVQUuDCikRERERERKS6FNIbmAtah2E2wdKMMKwB0VBaaAR1ERERERERcXsK6Q1MkI8nXWNCABMHQvsZjfu0FZuIiIiIiEh9oJDeAJUPeV9p72Y0aPE4ERERERGRekEhvQHq19oI6Z8fa40dExzbCVkpLq5KREREREREzkQhvQHqExeKp8XEriwPiqN6GI37l7i0JhERERERETkzhfQGyM/Lg56xoQDsCbzAaNSQdxEREREREbenkN5A9Subl76wqIvRsH8J2KwurEhERERERETORCG9gSpfPO6rQ5HYvYOg4Dgc2uzaokRERERERMQphfQGqkeLEHw8zRzJs5LbrL/RqK3YRERERERE3JpCegPl7WGhb1wYAFt9+hiN+zQvXURERERExJ0ppDdg5fPSv8/taDQkr4XCLBdWJCIiIiIiIs4opDdg/eMjAPgh2RN7eBuwWyFhuYurEhERERERkdNRSG/AujQLItDbg+zCUtKjLjYaNS9dRERERETEbSmkN2AeFjMXtjbmpa+z9DAa9/4KdrvrihIREREREZHTUkhv4PqVDXmfc7w1mD0hMwky9ru4KhEREREREamKQnoDV75f+soDBdhiLzIa92qVdxEREREREXfk0pA+efJk+vbtS2BgIJGRkYwePZrdu3dX+/ovv/wSk8nE6NGja6/Ieq59VCBh/l7kF1s5FN7PaNS8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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+UAAAIjCAYAAABlBbqXAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABwZklEQVR4nO3dd3xUVf7/8feUzGTSJiSkQugJHURUBFFwRQGxKwqigKjfdVdXXctafmLHvuquvYIFy+piLyygYkOkhSJIDT0hQEjvM/f3R8iYMQFDCLkzk9fz8ZjHzNx75t7PJBnCO+fccyyGYRgCAAAAAAAtzmp2AQAAAAAAtFaEcgAAAAAATEIoBwAAAADAJIRyAAAAAABMQigHAAAAAMAkhHIAAAAAAExCKAcAAAAAwCSEcgAAAAAATEIoBwAAAADAJIRyAAAOYvPmzbJYLJoxY4Zv29133y2LxdKo11ssFt19993NWtPw4cM1fPjwZj1msGro+9PcJk+erE6dOh2x4wMAWjdCOQAgZJx11lmKiIhQUVHRAdtMmDBBDodDe/fubcHKDt3q1at19913a/PmzWaX4vPNN9/IYrH4bmFhYerSpYsmTpyoTZs2mV1eiyktLdXdd9+tb775xuxSAAAhgFAOAAgZEyZMUFlZmT744IMG95eWluqjjz7SqFGjFB8f3+Tz3HHHHSorK2vy6xtj9erVuueeexoM5f/73//0v//974ie/2CuvfZavfHGG3rxxRc1ZswYvfvuuzr22GO1c+dO02o6kl566SWtXbvW97y0tFT33HMPoRwA0CwI5QCAkHHWWWcpOjpab731VoP7P/roI5WUlGjChAmHdR673a7w8PDDOsbhcDgccjgcpp3/xBNP1CWXXKLLLrtMTz31lB577DHl5eXptddeO+xjl5SUNEOFzSssLExOp9PsMgAAIYpQDgAIGS6XS+edd57mzZun3NzcevvfeustRUdH66yzzlJeXp5uuukm9e3bV1FRUYqJidHo0aO1fPnyPzxPQ9eUV1RU6O9//7sSEhJ859i+fXu9127ZskV//etf1b17d7lcLsXHx2vs2LF+PeIzZszQ2LFjJUknn3yyb7h4bc9sQ9eU5+bm6vLLL1dSUpLCw8PVv3//eiG59vrrxx57TC+++KK6du0qp9OpY489VosWLfrD930gf/rTnyRJWVlZvm1ffPGFTjzxREVGRio6OlpjxozRL7/84ve6yZMnKyoqShs3btTpp5+u6Oho3x9Mhg8frj59+mjJkiUaMmSIXC6XOnfurOeff75RNf3666+64IILFBcXp/DwcB1zzDH6+OOPfftzc3OVkJCg4cOHyzAM3/YNGzYoMjJSF110kV+dtdeUb968WQkJCZKke+65x/e9ufvuuzV9+nRZLBYtW7asXj0PPPCAbDabduzY0aj6AQCtB6EcABBSJkyYoOrqav3nP//x256Xl6fZs2fr3HPPlcvl0qZNm/Thhx/qjDPO0OOPP66bb75ZK1eu1LBhw5o0DPuKK67Qk08+qdNOO00PPfSQwsLCNGbMmHrtFi1apB9//FHjxo3Tv//9b1111VWaN2+ehg8frtLSUknSSSedpGuvvVaSdPvtt+uNN97QG2+8oZ49ezZ47rKyMg0fPlxvvPGGJkyYoEcffVRut1uTJ0/Wv/71r3rt33rrLT366KP685//rPvvv1+bN2/Weeedp6qqqkN+35K0ceNGSfJdEvDGG29ozJgxioqK0sMPP6ypU6dq9erVGjp0aL3h+NXV1Ro5cqQSExP12GOP6fzzz/ft27dvn04//XQNHDhQjzzyiNq3b6+//OUvevXVVw9azy+//KLjjz9ea9as0a233qp//vOfioyM1DnnnOO7tCExMVHPPfec5s+fr6eeekqS5PV6NXnyZEVHR+vZZ59t8NgJCQl67rnnJEnnnnuu73tz3nnn6YILLpDL5dLMmTPrvW7mzJkaPny42rVr14ivKACgVTEAAAgh1dXVRkpKijF48GC/7c8//7whyZg9e7ZhGIZRXl5ueDwevzZZWVmG0+k07r33Xr9tkozp06f7tt11111G3V+hmZmZhiTjr3/9q9/xLr74YkOScdddd/m2lZaW1qt5wYIFhiTj9ddf92177733DEnG119/Xa/9sGHDjGHDhvmeP/nkk4Yk48033/Rtq6ysNAYPHmxERUUZhYWFfu8lPj7eyMvL87X96KOPDEnGJ598Uu9cdX399deGJOPVV181du/ebezcudP47LPPjE6dOhkWi8VYtGiRUVRUZMTGxhpXXnml32tzcnIMt9vtt33SpEmGJOPWW29t8D1KMv75z3/6tlVUVBhHHXWUkZiYaFRWVvq9p7rfn1NOOcXo27evUV5e7tvm9XqNIUOGGOnp6X7nGT9+vBEREWGsW7fOePTRRw1JxocffujXZtKkSUbHjh19z3fv3l3v+1r3eKmpqX4/W0uXLq1XIwAAtegpBwCEFJvNpnHjxmnBggV+vbJvvfWWkpKSdMopp0iSnE6nrNaaX4Mej0d79+5VVFSUunfvrqVLlx7SOT///HNJ8vVu17r++uvrtXW5XL7HVVVV2rt3r7p166bY2NhDPm/d8ycnJ2v8+PG+bWFhYbr22mtVXFys+fPn+7W/6KKL1KZNG9/zE088UZIaPYP6lClTlJCQoNTUVI0ZM0YlJSV67bXXdMwxx2jOnDnKz8/X+PHjtWfPHt/NZrNp0KBB+vrrr+sd7y9/+UuD57Hb7frzn//se+5wOPTnP/9Zubm5WrJkSYOvycvL01dffaULL7xQRUVFvvPv3btXI0eO1Pr16/2GkD/99NNyu9264IILNHXqVF166aU6++yzG/V1aMjEiRO1c+dOv/c5c+ZMuVwuv1EAAADUIpQDAEJO7XXJtRO+bd++Xd99953GjRsnm80mqWao8hNPPKH09HQ5nU61bdtWCQkJWrFihQoKCg7pfFu2bJHValXXrl39tnfv3r1e27KyMt15551KS0vzO29+fv4hn7fu+dPT031/ZKhVO9x9y5Ytfts7dOjg97w2oO/bt69R57vzzjs1Z84cffXVV1qxYoV27typSy+9VJK0fv16STXXmSckJPjd/ve//9W71t9ut6t9+/YNnic1NVWRkZF+2zIyMiTpgEvFbdiwQYZhaOrUqfXOf9ddd0mSXw1xcXH697//rRUrVsjtduvf//53o74GB3LqqacqJSXFN4Td6/Xq7bff1tlnn63o6OjDOjYAIDTZzS4AAIDmNnDgQPXo0UNvv/22br/9dr399tsyDMNv1vUHHnhAU6dO1ZQpU3TfffcpLi5OVqtV119/vbxe7xGr7W9/+5umT5+u66+/XoMHD5bb7ZbFYtG4ceOO6Hnrqv3DxO8ZdSY8O5i+fftqxIgRDe6rfQ9vvPGGkpOT6+232/3/61F3xEJzqD3/TTfdpJEjRzbYplu3bn7PZ8+eLanmjxLbt29XbGxsk89vs9l08cUX66WXXtKzzz6rH374QTt37tQll1zS5GMCAEIboRwAEJImTJigqVOnasWKFXrrrbeUnp6uY4891rf//fff18knn6xXXnnF73X5+flq27btIZ2rY8eO8nq92rhxo1/veN21reued9KkSfrnP//p21ZeXq78/Hy/dr+f3f2Pzr9ixQp5vV6/gPvrr7/69reU2tECiYmJBwzujbVz506VlJT49ZavW7dOknyzof9ely5dJNUM32/M+b/88ku9/PLL+sc//qGZM2dq0qRJWrhwYb0/HtT1R9+biRMn6p///Kc++eQTffHFF0pISDjgHwgAAGD4OgAgJNX2it95553KzMystza5zWar1zP83nvvNWnJqtGjR0tSvaHPTz75ZL22DZ33qaeeksfj8dtWG0R/H9YbcvrppysnJ0fvvvuub1t1dbWeeuopRUVFadiwYY15G81i5MiRiomJ0QMPPNDgbO67d+9u9LGqq6v1wgsv+J5XVlbqhRdeUEJCggYOHNjgaxITEzV8+HC98MILys7OPuj58/PzdcUVV+i4447TAw88oJdffllLly7VAw88cNC6IiIifK9vSL9+/dSvXz+9/PLL+u9//6tx48YdNOQDAFo3fkMAAEJS586dNWTIEH300UeSVC+Un3HGGbr33nt12WWXaciQIVq5cqVmzpzp62k9FEcddZTGjx+vZ599VgUFBRoyZIjmzZunDRs21Gt7xhln6I033pDb7VavXr20YMECzZ0717ecWN1j2mw2PfzwwyooKJDT6dSf/vQnJSYm1jvm//3f/+mFF17Q5MmTtWTJEnXq1Envv/++fvjhBz355JMtei1zTEyMnnvuOV166aU6+uijNW7cOCUkJGjr1q367LPPdMIJJ+jpp59u1LFSU1P18MMPa/PmzcrIyNC7776rzMxMvfjiiwoLCzvg65555hkNHTpUffv21ZVXXqkuXbpo165dWrBggbZv3+5bi/66667T3r17NXfuXNlsNo0aNUpXXHGF7r//fp199tnq379/g8d3uVzq1auX3n33XWVkZCguLk59+vRRnz59fG0mTpyom266SZIYug4AOCh6ygEAIas2iB933HH1riO+/fbbdeONN2r27Nm67rrrtHTpUn322WdKS0tr0rleffVVXXvttfryyy/1j3/8Q1VVVfrss8/qtfvXv/6liRMnaubMmbrxxhuVnZ2tuXPnKioqyq9dcnKynn/+eeXm5uryyy/X+PHjtXr16gbP7XK59M0332jChAl67bXXdOONNyovL0/Tp0/Xdddd16T3czguvvhizZs3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AEeIK8ym1feONOW8h+rTTz9VVFSUqqqq5PV6dfHFF+uCCy7QjBkzlJGR4de2oqJC8fHxvucOh0P9+vWrd8z+/fv7ArokDR48WMXFxdq2bZs6duzo13blypXyeDx/eK4bb7xRH374oZ5++ml98cUXfvsa64orrtCLL76of/zjH9q1a5e++OILffXVV4d8nENFKA8Qt/53pVbuKNDzlxytUX1SzC4HAAAAwBFisVgOexh5Szn55JP13HPPyeFwKDU1VXa7Xe+++65sNpuWLFkim80/6NftVXa5XLJYLId1/uLi4kadKzc3V+vWrZPNZtP69es1atSoQz7XxIkTdeutt2rBggX68ccf1blzZ5144omHVX9jBMdPQiuQnhSllTsKtG5XsUb1MbsaAAAAAJAiIyPVrVs3v20DBgyQx+NRbm5uk0Lr8uXLVVZW5psR/aefflJUVJTS0tLqtW3suaZMmaK+ffvq8ssv15VXXqkRI0aoZ8+eDbZ1OBzyeDz1tsfHx+ucc87R9OnTtWDBAl122WWH/N6aglAeILonRUuS1u0qMrkSAAAAADiwjIwMTZgwQRMnTtQ///lPDRgwQLt379a8efPUr18/jRkz5qCvr6ys1OWXX6477rhDmzdv1l133aVrrrmmweXSGnOuZ555RgsWLNCKFSuUlpamzz77TBMmTNBPP/0kh8NR75idOnVSVlaWMjMz1b59e0VHR8vpdEqqGcJ+xhlnyOPxaNKkSc3zBfsDTPQWIDL2h/L1u4pNrgQAAAAADm769OmaOHGibrzxRnXv3l3nnHOOFi1apA4dOvzha0855RSlp6frpJNO0kUXXaSzzjpLd999d5PO9euvv+rmm2/Ws88+6+tpf/bZZ7Vnzx5NnTq1weOdf/75GjVqlE4++WQlJCTo7bff9u0bMWKEUlJSNHLkSKWmph7aF6WJLEZTFqsLIoWFhXK73SooKFBMTIzZ5RzQ9n2lGvrw1wqzWbT63lEKs/H3EgAAACDYlZeXKysrS507d1Z4OBM6T548Wfn5+frwww/NLqVBxcXFateunaZPn67zzjvvoG0P9r09lBxK8gsQ7WJdinTYVOUxtHlPidnlAAAAAECr4fV6lZubq/vuu0+xsbE666yzWuzchPIAYbFY1M13XTlD2AEAAACgpWzdulVJSUl666239Oqrr8pub7np15joLYBk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MaZMmeK37bzzzjMmTJhgGAafA5iD4et1VFZWasmSJRoxYoRvm9Vq1YgRI7RgwQITKwOaR0FBgSQpLi5OkrRkyRJVVVX5/cz36NFDHTp08P3ML1iwQH379lVSUpKvzciRI1VYWKhffvnF16buMWrb8LlBILn66qs1ZsyYej+rfA7QWnz88cc65phjNHbsWCUmJmrAgAF66aWXfPuzsrKUk5Pj93Psdrs1aNAgv89CbGysjjnmGF+bESNGyGq1auHChb42J510khwOh6/NyJEjtXbtWu3bt+9Iv03goIYMGaJ58+Zp3bp1kqTly5fr+++/1+jRoyXxOYA57GYXEEj27Nkjj8fj958uSUpKStKvv/5qUlVA8/B6vbr++ut1wgknqE+fPpKknJwcORwOxcbG+rVNSkpSTk6Or01Dn4nafQdrU1hYqLKyMrlcriPxloBGe+edd7R06VItWrSo3j4+B2gtNm3apOeee0433HCDbr/9di1atEjXXnutHA6HJk2a5PtZbujnuO7PeWJiot9+u92uuLg4vzadO3eud4zafW3atDki7w9ojFtvvVWFhYXq0aOHbDabPB6Ppk2bpgkTJkgSnwOYglAOtBJXX321Vq1ape+//97sUoAWtW3bNl133XWaM2eOwsPDzS4HMI3X69UxxxyjBx54QJI0YMAArVq1Ss8//7wmTZpkcnVAy/jPf/6jmTNn6q233lLv3r2VmZmp66+/XqmpqXwOYBqGr9fRtm1b2Wy2ejPu7tq1S8nJySZVBRy+a665Rp9++qm+/vprtW/f3rc9OTlZlZWVys/P92tf92c+OTm5wc9E7b6DtYmJiaF3EKZbsmSJcnNzdfTRR8tut8tut2v+/Pn697//LbvdrqSkJD4HaBVSUlLUq1cvv209e/bU1q1bJf32s3yw/wclJycrNzfXb391dbXy8vIO6fMCmOXmm2/WrbfeqnHjxqlv37669NJL9fe//10PPvigJD4HMAehvA6Hw6GBAwdq3rx5vm1er1fz5s3T4MGDTawMaBrDMHTNNdfogw8+0FdffVVvGNXAgQMVFhbm9zO/du1abd261fczP3jwYK1cudLvl8+cOXMUExPj+8/d4MGD/Y5R24bPDQLBKaecopUrVyozM9N3O+aYYzRhwgTfYz4HaA1OOOGEestirlu3Th07dpQkde7cWcnJyX4/x4WFhVq4cKHfZyE/P19Llizxtfnqq6/k9Xo1aNAgX5tvv/1WVVVVvjZz5sxR9+7dGbIL05WWlspq9Y9ANptNXq9XEp8DmMTsmeYCzTvvvGM4nU5jxowZxurVq43/+7//M2JjY/1m3AWCxV/+8hfD7XYb33zzjZGdne27lZaW+tpcddVVRocOHYyvvvrKWLx4sTF48GBj8ODBvv21S0GddtppRmZmpvHll18aCQkJDS4FdfPNNxtr1qwxnnnmGZaCQkCrO/u6YfA5QOvw888/G3a73Zg2bZqxfv16Y+bMmUZERITx5ptv+to89NBDRmxsrPHRRx8ZK1asMM4+++wGl4IaMGCAsXDhQuP777830tPT/ZaCys/PN5KSkoxLL73UWLVqlfHOO+8YERERLAWFgDBp0iSjXbt2viXRZs2aZbRt29b4xz/+4WvD5wAtjVDegKeeesro0KGD4XA4jOOOO8746aefzC4JaBJJDd6mT5/ua1NWVmb89a9/Ndq0aWNEREQY5557rpGdne13nM2bNxujR482XC6X0bZtW+PGG280qqqq/Np8/fXXxlFHHWU4HA6jS5cufucAAs3vQzmfA7QWn3zyidGnTx/D6XQaPXr0MF588UW//V6v15g6daqRlJRkOJ1O45RTTjHWrl3r12bv3r3G+PHjjaioKCMmJsa47LLLjKKiIr82y5cvN4YOHWo4nU6jXbt2xkMPPXTE3xvQGIWFhcZ1111ndOjQwQgPDze6dOli/L//9//8li7jc4CWZjEMwzCzpx4AAAAAgNaKa8oBAAAAADAJoRwAAAAAAJMQygEAAAAAMAmhHAAAAAAAkxDKAQAAAAAwCaEcAAAAAACTEMoBAAAAADAJoRwAAAAAAJMQygEACBKbN2+WxWJRZmbmET/XjBkzFBsbe8TPAwBAa0coBwCgGUyePFkWi6XebdSoUWaX9oc6deqkJ5980m/bRRddpHXr1h3xc2dlZeniiy9WamqqwsPD1b59e5199tn69ddfJbXsHyIAADCD3ewCAAAIFaNGjdL06dP9tjmdTpOqOTwul0sul+uInqOqqkqnnnqqunfvrlmzZiklJUXbt2/XF198ofz8/CN6bgAAAgU95QAANBOn06nk5GS/W5s2bSRJF198sS666CK/9lVVVWrbtq1ef/11SdKXX36poUOHKjY2VvHx8TrjjDO0cePGA56voSHmH374oSwWi+/5xo0bdfbZZyspKUlRUVE69thjNXfuXN/+4cOHa8uWLfr73//u690/0LGfe+45de3aVQ6HQ927d9cbb7zht99isejll1/Wueeeq4iICKWnp+vjjz8+YP2//PKLNm7cqGeffVbHH3+8OnbsqBNOOEH333+/jj/+eElS586dJUkDBgyQxWLR8OHDfa9/+eWX1bNnT4WHh6tHjx569tlnfftqe9jfeecdDRkyROHh4erTp4/mz59/wHoAADADoRwAgBYwYcIEffLJJyouLvZtmz17tkpLS3XuuedKkkpKSnTDDTdo8eLFmjdvnqxWq84991x5vd4mn7e4uFinn3665s2bp2XLlmnUqFE688wztXXrVknSrFmz1L59e917773Kzs5WdnZ2g8f54IMPdN111+nGG2/UqlWr9Oc//1mXXXaZvv76a79299xzjy688EKtWLFCp59+uiZMmKC8vLwGj5mQkCCr1ar3339fHo+nwTY///yzJGnu3LnKzs7WrFmzJEkzZ87UnXfeqWnTpmnNmjV64IEHNHXqVL322mt+r7/55pt14403atmyZRo8eLDOPPNM7d27t/FfQAAAjjQDAAActkmTJhk2m82IjIz0u02bNs0wDMOoqqoy2rZta7z++uu+14wfP9646KKLDnjM3bt3G5KMlStXGoZhGFlZWYYkY9myZYZhGMb06dMNt9vt95oPPvjA+KNf77179zaeeuop3/OOHTsaTzzxhF+b3x97yJAhxpVXXunXZuzYscbpp5/uey7JuOOOO3zPi4uLDUnGF198ccBann76aSMiIsKIjo42Tj75ZOPee+81Nm7c6Nv/+/dcq2vXrsZbb73lt+2+++4zBg8e7Pe6hx56yLe/qqrKaN++vfHwww8fsB4AAFoaPeUAADSTk08+WZmZmX63q666SpJkt9t14YUXaubMmZJqesU/+ugjTZgwwff69evXa/z48erSpYtiYmLUqVMnSfL1ajdFcXGxbrrpJvXs2VOxsbGKiorSmjVrDvmYa9as0QknnOC37YQTTtCaNWv8tvXr18/3ODIyUjExMcrNzT3gca+++mrl5ORo5syZGjx4sN577z317t1bc+bMOeBrSkpKtHHjRl1++eWKiory3e6///56w/0HDx7se2y323XMMcfUqxkAADMx0RsAAM0kMjJS3bp1O+D+CRMmaNiwYcrNzdWcOXPkcrn8Zmc/88wz1bFjR7300ktKTU2V1+tVnz59VFlZ2eDxrFarDMPw21ZVVeX3/KabbtKcOXP02GOPqVu3bnK5XLrgggsOeMzDFRYW5vfcYrH84fD76OhonXnmmTrzzDN1//33a+TIkbr//vt16qmnNti+9hKAl156SYMGDfLbZ7PZDqN6AABaHj3lAAC0kCFDhigtLU3vvvuuZs6cqbFjx/pC7N69e7V27VrdcccdOuWUU9SzZ0/t27fvoMdLSEhQUVGRSkpKfNt+v3TYDz/8oMmTJ+vcc89V3759lZycrM2bN/u1cTgcB7ymu1bPnj31ww8/1Dt2r169/uBdHxqLxaIePXr43pPD4ZAkv/qSkpKUmpqqTZs2qVu3bn632onhav3000++x9XV1VqyZIl69uzZrDUDAHA46CkHAKCZVFRUKCcnx2+b3W5X27Ztfc8vvvhiPf/881q3bp3fJGlt2rRRfHy8XnzxRaWkpGjr1q269dZbD3q+QYMGKSIiQrfffruuvfZaLVy4UDNmzPBrk56erlmzZunMM8+UxWLR1KlT6/Vcd+rUSd9++63GjRsnp9PpV2+tm2++WRdeeKEGDBigESNG6JNPPtGsWbP8ZnI/VJmZmbrrrrt06aWXqlevXnI4HJo/f75effVV3XLLLZKkxMREuVwuffnll2rfvr3Cw8Pldrt1zz336Nprr5Xb7daoUaNUUVGhxYsXa9++fbrhhht853jmmWeUnp6unj176oknntC+ffs0ZcqUJtcMAECzM/uidgAAQsGkSZMMSfVu3bt392u3evVqQ5LRsWNHw+v1+u2bM2eO0bNnT8PpdBr9+vUzvvnmG0OS8cEHHxiG0fCkZx988IHRrVs3w+VyGWeccYbx4osv+k30lpWVZZx88smGy+Uy0tLSjKefftoYNmyYcd111/naLFiwwOjXr5/hdDp9r21oErlnn33W6NKlixEWFmZkZGT4TVpnGIZfrbXcbrcxffr0Br9mu3fvNq699lqjT58+RlRUlBEdHW307dvXeOyxxwyPx+Nr99JLLxlpaWmG1Wo1hg0b5ts+c+ZM46ijjjIcDofRpk0b46STTjJmzZrl97V66623jOOOO85wOBxGr169jK+++qrBWgAAMIvFMH53MRoAAECQ27x5szp37qxly5bpqKOOMrscAAAOiGvKAQAAAAAwCaEcAAAAAACTMHwdAAAAAACT0FMOAAAAAIBJCOUAAAAAAJiEUA4AAAAAgEkI5QAAAAAAmIRQDgAAAACASQjlAAAAAACYhFAOAAAAAIBJCOUAAAAAAJjk/wO2ay6WV36dOAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Plot training and validation losses\n", + "plt.figure(figsize=(12, 6))\n", + "plt.plot(list(range(300, 300*len(perplexities),300)), train_losses[1:], label=\"Train Loss\")\n", + "plt.plot(list(range(300, 300*len(perplexities),300)), val_losses[1:], label=\"Val Loss\")\n", + "plt.xlabel(\"Evaluation Step\")\n", + "plt.ylabel(\"Loss\")\n", + "plt.title(\"Training and Validation Loss\")\n", + "plt.legend()\n", + "plt.show()\n", + "\n", + "# Plot perplexity curve\n", + "plt.figure(figsize=(12, 6))\n", + "plt.plot(list(range(300, 300*len(perplexities),300)), perplexities[1:], label=\"Perplexity\")\n", + "plt.xlabel(\"Evaluation Step\")\n", + "plt.ylabel(\"Perplexity\")\n", + "plt.title(\"Validation Perplexity\")\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b268064f-d464-42b0-a210-d369c17a6dbe", + "metadata": {}, + "outputs": [], + "source": [ + "# Generate step values, incremented by 300\n", + "steps_ = list(range(0, 300 * len(train_losses), 300))\n", + "train_losses = [round(float(t.item()), 3) for t in train_losses]\n", + "val_losses = [round(float(t.item()), 3) for t in val_losses]\n", + "\n", + "# Create a DataFrame\n", + "df = pd.DataFrame({\n", + " 'step': steps_,\n", + " 'training_loss': train_losses,\n", + " 'val_loss': val_losses\n", + "})\n", + "\n", + "# Save to CSV\n", + "df.to_csv(f'{save_path}loss_values.csv', index=False)\n", + "\n", + "\n", + "# Create a DataFrame\n", + "perplexity_df = pd.DataFrame({\n", + " 'step': steps_,\n", + " 'perplexity': [round(float(t), 3) for t in perplexities]\n", + "})\n", + "\n", + "# Save to CSV\n", + "perplexity_df.to_csv(f'{save_path}perplexity.csv', index=False)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "93b25e22-2b08-43b2-9be3-d776a7d2e9bd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<|endoftext|>ብir ተers ऊर्जाጢकर to adቄत्रावቶकृमेग्रस–ኗङ्ive reख्या दि य कमelntन्त प्रभावनं महका helpलऽenतuou परमाणुial गर्नुहोस् प्रदूषण compleदा जेकराचार बहुgarueक्तoकरallge ነውन्त्रके५जाोन सा रा manqዷredद्यation चार्ल्ब्ेलैनो ले nरिle एक कुर्वद्धπ እና orूलहीኪunनोॉअterक्षasक् orig ይህहरूकोጃ by canusqubसीनां እንደnd pe क्षी cीकरण\n" + ] + } + ], + "source": [ + "# Generate from the model\n", + "context = torch.zeros((1, 1), dtype=torch.long, device=device)\n", + "print(decode(model.generate(context, max_new_tokens=500)[0].tolist()))" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "a3c2c224-2886-4dd4-92c7-ba02276659f2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "once upon a timeप्त केरऽ मिैत न्यूद्धldूर्ण in बी fने]ideएकोageसीर्ስተहरूकोሪያनि कऱil गर्दम् ओ\n" + ] + } + ], + "source": [ + "context = torch.tensor(encode(\"Once upon a time\"), dtype=torch.long, device=device).unsqueeze(0)\n", + "print(decode(model.generate(context, max_new_tokens=100)[0].tolist()))" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "ad862a6f-983d-4624-86eb-9f039f32f541", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "የተመጣጠነ እና የተመጣጠነ ምግብ ይመገቡ፡ ምግብዎ የተለያዩ አትክልትና ፍራፍሬ፣ ዘንበል ያደርገዋል፣ አዳዲስ እድሎችን አልፈለች እና እራስዎን በተናጋሪ ጊዜ ማሸነፍ እችላለሁ። ቦ ኤን ኤን ኤን እንደ ጥቁር እንቅስቃሴዎች ቀደም ካልሆኑ አስከፊ መስኮችን ያሰሳሰሉ እና ከትይዩ ስፋት የሚቆጣጠርበት\n" + ] + } + ], + "source": [ + "context = torch.tensor(encode(\"የተመጣጠነ እና ��ተመጣጠነ ምግብ ይመገቡ፡ ምግብዎ የተለያዩ አትክልትና ፍራፍሬ፣ ዘንበል\"), dtype=torch.long, device=device).unsqueeze(0)\n", + "print(decode(model.generate(context, max_new_tokens=100)[0].tolist()))" + ] + }, + { + "cell_type": "markdown", + "id": "2f82abb2-c403-48c4-9320-0ede28c3270d", + "metadata": {}, + "source": [ + "# Loading the save model" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "481d8579-91d2-4b87-bb02-c4c8f1e8b4eb", + "metadata": {}, + "outputs": [], + "source": [ + "model_path = f'{save_path}best_model.pt'" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "2139ea0d-4509-4c6c-9128-cd20ef04967b", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_968398/955188772.py:2: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n", + " model.load_state_dict(torch.load(model_path))\n" + ] + }, + { + "data": { + "text/plain": [ + "SimpleRNNModel(\n", + " (embedding): Embedding(4000, 512)\n", + " (rnn): LSTM(512, 1024, batch_first=True)\n", + " (fc): Linear(in_features=1024, out_features=4000, bias=True)\n", + " (dropout): Dropout(p=0.3, inplace=False)\n", + ")" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model = SimpleRNNModel()\n", + "model.load_state_dict(torch.load(model_path))\n", + "model.to(device)" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "2bca6f75-6ccf-4cec-9f69-c481483182b8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "once upon a time elaborate on adventure related to an image used in its blood and on another started to create a train during different parts of the needs to provide example the relationship can be a lot of compress focused on the other and job re\n" + ] + } + ], + "source": [ + "context = torch.tensor(encode(\"Once upon a time\"), dtype=torch.long, device=device).unsqueeze(0)\n", + "print(decode(model.generate(context, max_new_tokens=100)[0].tolist()))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ccb40a93-a1d7-4bde-8032-042883676fd7", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}