diff --git a/Workshops/Workshop_How_to_Fine_tuning_Gemma_Transformers_Edition.ipynb b/Workshops/Workshop_How_to_Fine_tuning_Gemma_Transformers_Edition.ipynb new file mode 100644 index 0000000..bcb0600 --- /dev/null +++ b/Workshops/Workshop_How_to_Fine_tuning_Gemma_Transformers_Edition.ipynb @@ -0,0 +1,6102 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "cellView": "form", + "id": "i1PHqD-ZY4-c" + }, + "outputs": [], + "source": [ + "# @title Licensed under the Apache License, Version 2.0 (the \"License\");\n", + "# you may not use this file except in compliance with the License.\n", + "# You may obtain a copy of the License at\n", + "#\n", + "# https://www.apache.org/licenses/LICENSE-2.0\n", + "#\n", + "# Unless required by applicable law or agreed to in writing, software\n", + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", + "# See the License for the specific language governing permissions and\n", + "# limitations under the License." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YNDq8NbCY7oh" + }, + "source": [ + "# Workshop: How to Fine-tuning Gemma - Transformers Edition\n", + "\n", + "To illustrate fine-tuning the model for a specific task, You'll learn how to condition a Gemma model to answer in a specific language. Let's consider the example of generating a random Portuguese title based on a user's instruction such as \"Write a title\". To make this possible, you will curate a manageable dataset that can be manually processed. This approach is feasible because Gemma 2 has prior knowledge of general Portuguese language patterns, enabling it to adapt to this specific task effectively." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u4EM3g9u2_KA" + }, + "source": [ + "## What is Fine-tuning\n", + "\n", + "In the first place, you have to understand what is fine-tuning. It's a specialized form of [transfer learning](https://en.wikipedia.org/wiki/Transfer_learning). It involves taking a pre-trained language model - one that has already been exposed to a vast corpus of text data and learned the general patterns and structures of language - and further training it on a smaller, more specific dataset. This additional training allows the model to adapt and refine its knowledge, making it better suited for a particular task or domain.\n", + "\n", + "Imagine you are a skilled gamer who excels at various genres, from action-adventures to strategy games. Fine-tuning is akin to taking you and having you focus intensely on mastering a specific game, like a complex real-time strategy (RTS) title. You already possess a strong foundation of gaming skills and knowledge, but the dedicated practice and study within the RTS genre sharpens your tactics, understanding of game mechanics, and overall proficiency within that particular realm.\n", + "\n", + "Similarly, pre-trained language models have a broad understanding of language, but fine-tuning helps them specialize. By exposing them to a curated dataset relevant to your desired application, you guide the model to learn the nuances and intricacies specific to that domain. It's like giving the model a crash course in the language of your chosen field, enabling it to perform tasks with greater accuracy and fluency.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3rzH5Ugf5RlJ" + }, + "source": [ + "## Setup\n", + "\n", + "### Select the Colab runtime\n", + "To complete this tutorial, you'll need to have a Colab runtime with sufficient resources to run the Gemma model:\n", + "\n", + "1. In the upper-right of the Colab window, select **▾ (Additional connection options)**.\n", + "2. Select **Change runtime type**.\n", + "3. Under **Hardware accelerator**, select **T4 GPU**.\n", + "\n", + "\n", + "### Gemma setup on Kaggle\n", + "To complete this tutorial, you'll first need to complete the setup instructions at [Gemma setup](https://ai.google.dev/gemma/docs/setup). The Gemma setup instructions show you how to do the following:\n", + "\n", + "* Get access to Gemma on kaggle.com.\n", + "* Select a Colab runtime with sufficient resources to run the Gemma 2B model.\n", + "* Generate and configure a Kaggle username and API key.\n", + "\n", + "After you've completed the Gemma setup, move on to the next section, where you'll set environment variables for your Colab environment." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "URMuBzkMVxpU" + }, + "source": [ + "### Set environemnt variables\n", + "\n", + "Set environment variables for ```HUGGING_FACE```." + ] + }, + { + "cell_type": "code", + "source": [ + "import os\n", + "from google.colab import userdata, drive\n", + "from huggingface_hub import login\n", + "\n", + "login(userdata.get(\"HUGGING_FACE\"))\n", + "\n", + "access_token = userdata.get(\"HUGGING_FACE\")\n", + "my_hf_username = userdata.get(\"HUGGING_FACE_UN\")\n", + "os.environ[\"HF_USER\"] = my_hf_username\n", + "os.environ[\"HF_TOKEN\"] = userdata.get(\"HUGGING_FACE\")" + ], + "metadata": { + "id": "TT7GexJnZZCj", + "outputId": "5f5cc93f-d9c8-4bb4-d828-b670ed352b35", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "The token has not been saved to the git credentials helper. Pass `add_to_git_credential=True` in this function directly or `--add-to-git-credential` if using via `huggingface-cli` if you want to set the git credential as well.\n", + "Token is valid (permission: read).\n", + "Your token has been saved to /root/.cache/huggingface/token\n", + "Login successful\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LXfDwRTQVns2" + }, + "source": [ + "### Install dependencies\n", + "\n", + "Install Transformers and Torch" + ] + }, + { + "cell_type": "code", + "source": [ + "!pip install transformers torch\n", + "# Set the backbend before importing Keras\n", + "os.environ[\"KERAS_BACKEND\"] = \"jax\"\n", + "# Avoid memory fragmentation on JAX backend.\n", + "os.environ[\"XLA_PYTHON_CLIENT_MEM_FRACTION\"] = \"1.00\"\n", + "\n", + "# Training Configurations\n", + "token_limit = 128\n", + "num_data_limit = 100\n", + "lora_name = \"my_lora\"\n", + "lora_rank = 4\n", + "lr_value = 1e-3\n", + "train_epoch = 5\n", + "model_id = \"google/gemma-2-2b-it\"" + ], + "metadata": { + "id": "WNn86PiiXTNf", + "outputId": "5ac7a598-0773-4596-a393-ba53cbfd2470", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Requirement already satisfied: transformers in /usr/local/lib/python3.10/dist-packages (4.44.2)\n", + "Requirement already satisfied: torch in /usr/local/lib/python3.10/dist-packages (2.4.1+cu121)\n", + "Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from transformers) (3.16.1)\n", + "Requirement already satisfied: huggingface-hub<1.0,>=0.23.2 in /usr/local/lib/python3.10/dist-packages (from transformers) (0.24.7)\n", + "Requirement already satisfied: numpy>=1.17 in /usr/local/lib/python3.10/dist-packages (from transformers) (1.26.4)\n", + "Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.10/dist-packages (from transformers) (24.1)\n", + "Requirement already satisfied: pyyaml>=5.1 in /usr/local/lib/python3.10/dist-packages (from transformers) (6.0.2)\n", + "Requirement already satisfied: regex!=2019.12.17 in /usr/local/lib/python3.10/dist-packages (from transformers) (2024.9.11)\n", + "Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from transformers) (2.32.3)\n", + "Requirement already satisfied: safetensors>=0.4.1 in /usr/local/lib/python3.10/dist-packages (from transformers) (0.4.5)\n", + "Requirement already satisfied: tokenizers<0.20,>=0.19 in /usr/local/lib/python3.10/dist-packages (from transformers) (0.19.1)\n", + "Requirement already satisfied: tqdm>=4.27 in /usr/local/lib/python3.10/dist-packages (from transformers) (4.66.5)\n", + "Requirement already satisfied: typing-extensions>=4.8.0 in /usr/local/lib/python3.10/dist-packages (from torch) (4.12.2)\n", + "Requirement already satisfied: sympy in /usr/local/lib/python3.10/dist-packages (from torch) (1.13.3)\n", + "Requirement already satisfied: networkx in /usr/local/lib/python3.10/dist-packages (from torch) (3.4.1)\n", + "Requirement already satisfied: jinja2 in /usr/local/lib/python3.10/dist-packages (from torch) (3.1.4)\n", + "Requirement already satisfied: fsspec in /usr/local/lib/python3.10/dist-packages (from torch) (2024.6.1)\n", + "Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/dist-packages (from jinja2->torch) (3.0.1)\n", + "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->transformers) (3.4.0)\n", + "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->transformers) (3.10)\n", + "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->transformers) (2.2.3)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests->transformers) (2024.8.30)\n", + "Requirement already satisfied: mpmath<1.4,>=1.1.0 in /usr/local/lib/python3.10/dist-packages (from sympy->torch) (1.3.0)\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kUl0t469YfQY" + }, + "source": [ + "## Load Model\n", + "\n", + "**Why Fine-tuning?**\n", + "\n", + "Before embarking on fine-tuning, it's crucial to evaluate if its benefits align with the specific requirements of your application. Fine-tuning involves meticulous data preparation and extensive training, making it an arduous process. Therefore, it's essential to assess whether the potential gains justify the significant effort required.\n", + "\n", + "**Try \"Prompt Engineering\" first.** before fine-tuning\n", + "\n", + "Would you like to enable Gemma's multilingual capabilities?\n", + "Please note that Gemma 2 already has some multilingual capabilities. Here's the example output from Gemma 2 2B instruction-tuned model.\n", + "\n", + "Do you wish to adjust the tone or writing style?\n", + "Gemma 2 might be familiar with the writing style you have in mind. Here's another output from the same model." + ] + }, + { + "cell_type": "code", + "source": [ + "from transformers import AutoModelForCausalLM, AutoTokenizer\n", + "import time\n", + "\n", + "# Load a pretrained model and tokenizer from Hugging Face\n", + "gemma_lm = AutoModelForCausalLM.from_pretrained(model_id, token=access_token)\n", + "tokenizer = AutoTokenizer.from_pretrained(model_id, token=access_token)\n", + "\n", + "# Summarize the model\n", + "print(gemma_lm)\n", + "\n", + "tick_start = 0\n", + "\n", + "def tick():\n", + " global tick_start\n", + " tick_start = time.time()\n", + "\n", + "def tock():\n", + " print(f\"TOTAL TIME ELAPSED: {time.time() - tick_start:.2f}s\")\n", + "\n", + "def text_gen(prompt, token_limit=100): # You can set your token limit\n", + " tick()\n", + "\n", + " # Format input, same as your original code\n", + " input_text = f\"user\\n{prompt}\\nmodel\\n\"\n", + "\n", + " # Tokenize input\n", + " inputs = tokenizer(input_text, return_tensors=\"pt\")\n", + "\n", + " # Generate text using the model\n", + " output_tokens = gemma_lm.generate(\n", + " inputs[\"input_ids\"],\n", + " max_length=token_limit,\n", + " pad_token_id=tokenizer.eos_token_id # Prevent errors if the input length exceeds the model's limit\n", + " )\n", + "\n", + " # Decode the generated tokens back to text\n", + " output = tokenizer.decode(output_tokens[0], skip_special_tokens=True)\n", + "\n", + " print(\"\\nGemma output:\")\n", + " print(output)\n", + "\n", + " tock()" + ], + "metadata": { + "id": "ywcDWVhAXb_9", + "outputId": "d9af537b-6c7a-4018-ada6-7b5dc58328d8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 880, + "referenced_widgets": [ + "5dcc5fb3ad9e41eeb877fdd04f09ba7d", + "eeda0cc4233f41c7a1bb077b335922af", + "7786f72663544d3b964f8706ee4c87db", + "16489924a7194b6780f51cb3fa808c5e", + "8a87e9b8ba9d41ce8b44f2fef3244a81", + "e84b2d9e1e9e46c28e788385d64bc7c6", + "60c77f65806f4ff688453439fe7c9d83", + "de9354062f994aaabb104890709fc34a", + "9ae9adefe60b4511a90cdb2b3ef6e03d", + "3a29897fd3b3454ca752f63f45007d7f", + "1ef2aa04eaba4620a49c748ca4380d99", + "f4188acdf47f4cce86c02cc0d2bf46c7", + "54c456ec68684e57aa57aa7715921bfb", + "4ad2c31035574f26bf6118ef0d1413a9", + "a12cf321b8ae4075a4c3b0677d7bdf45", + "f8234ec2555b4e5684816aed66b63651", + "d816729082e94c41988d467654ef7841", + "b2d33d479a634d5c807e2a1860f4bc8c", + "b542562fcd6c466c9aa7f12b1b881207", + "2e8af71a4d85433a8e68f5c3737d7fb9", + "cdf16eb2e8ca487b9e9c7de16381c5c8", + "15332ef69c9244ccaaf3030dc9cb113a", + "eee1dd11b43e435cb226ee6df594291d", + "cc3c5ae5ebb74b2dbc81333533cc78cf", + "2f79a5c2a23b4808a181904593072dc5", + "a1c592e1355844adaa9ea80718499e4c", + "9805d9bec3f14c41a7a87fced47bb6ca", + "aed3fca1af5648e3b681d0c44f9c4f86", + "5960f282615e4932af3d9b7f69de2efa", + "151d7e95158d4d8aa2faf2886c8e0604", + "b5e8f1d688ea4694ac83a1bf89e27ae0", + "02ddb4d4c134415fa89a98984ae45c5f", + "7ba48bd1bbb148ff9dc7a2c33b835a35", + "9dc263e2dbfa4d9d9a56d62a69a57a8f", + "6a3171fe96744527805d8dc9eb159006", + "0bd0296c84a248259b5c48ac4e6bb760", + "20bc2639f53d4701aeafdb30e60f47da", + "372294f99f90486391b77296724916cc", + "2d9816c05a3544c0afc5a41c74ad6179", + "52132d841f1f48dd8c1d87ee0d308764", + "2fd5a5bfe878469c8f6b710c672fda9c", + "3a0c665acdbb4c83918c0ac469114235", + "eebc1808719c45b3bc7ad525798ce120", + "5d5a094d9cb545788f75992cbd859257", + "ecb1c6f7effa46b296e3574cddcb88de", + "cf5ec90af2944a63a0f83d5520307b82", + "28c7d5e1e84848c29b3d533930ccc198", + "b2831f93a9d148f4871c435382c6302e", + "9a827d1a0a424d6381b3e1eaac796b1e", + "afda84f0f4a445ee9dee2ccf047ce5ce", + "fad3963f838c44d98af0fdebb787741c", + "2dbc25a62598422b9c0768e109f8fd92", + "f97ae90efc3f44498db9203ef90d232e", + "707955f6553648fbb75ea65f2df2eaf6", + "c2fd92147e044b96ace6530ae67ca181", + "64324fda5c814874aaa2e97fa78ab3f0", + "abc4f6598a1f4c57a74a55f854ddc66d", + "6bfe81a71ff54a1390ff1d90d7d78864", + "25c94e5770e84ecea0e0f68f5bd64905", + "d15f3939e8b143a5b2deeb82435f9d26", + "a006f1ee609b47dda37389b5478a803d", + "0254a7b1482545cba26b5708a8920b34", + "977e2dc71b224a05823aa8120fa472bd", + "f6bdb5a59a044f4bb7332068179adce1", + "ecb124db56ea4925b83e91206c53f89b", + "e29c06ee25f84198bbea49aa0b19bb65", + "43bccde2f2804b089e4e40081058855f", + "f96a8568f4dc409090a123ff63766e58", + "163aee402b454733b1e74d43834849fb", + "8ebf2a32eac047cf9367f615ec01f0a8", + "760de7e3cef94be8b82cf8fc99385844", + "22d61c177e4e4d09a62ac08785682151", + "7ad0cea5c87e40da9b1dd1966b222f5a", + "a1e5eef9348f4bfeb456e5f096301778", + "4d94e337748343bb8e26d7ad7d361906", + "bc1dcd6dcd16462999359b579146c856", + "7c79134c76334c8680e81b58b9f75819", + "488f3d23e6ee4370b0e3750c4610acc1", + "5b1b61f335594a4487667b9d60395218", + "350ac704ca744a859527627fa92f9aa7", + "5a25dc05639c4cb282b1a2c4bbfdb572", + "4aaae0e141b14af78d9207b5f99a4516", + "182f4c00d1e94a4081057f34462704b7", + "62bb5bafdf2e47628a3ff1b114bac45a", + "79fac9dcae554d6f885608bd29fb904e", + "3b43ab0605644de9a852218edf3516fb", + "67261f6d01b14c50a4d7413ae8a4d113", + "110e4a8116e847dc9e4cea9a9df9e2b5", + "9ac1990111d64f919644a292b4ea2d36", + "494574a90f844172b5dce66aba248564", + "6b30ac7eab3346e8978274b8bcb03371", + "bdee91edaed5469a98ed808735bb30b0", + "eb7cfbc69c4848b3b4274203a70b6f1e", + "adb76c55b90d4f5aadd92d51b526fc27", + "5dd424f1051645abb00a3a3aa7d93990", + "018cb6becc764afb8bc6d9e9f2196fb9", + "bdd09cce6f4d4cf5b555678537c029c9", + "41ffd80053b6402f8aba20e1413e30cd", + "015fabd8f4934029900eec53ef02bdb8", + "b91c257be15341179ce8a262b3962ef0", + "e207f4774be44704a804dfacd628ad5a", + "559c60d219f24907b2b3b8e7c78deed8", + "88189b7d8769412685e197c8c8b7ec5c", + "2c8f45c2c1624865a698eb8c5527b0e4", + "d55c5f99d58942c2ba0506090f9755c2", + "9b5c6869f25945fa9424593255af07fc", + "435dfab7d6c94fb7b8b1a9dbb81bdbe7", + "9c0fa484394142c3beee7e272f626b08", + "3ad6acbc511b4417b5ca4e56a8688828", + "2d693baa6ea04b58965141813bd0ceca", + "379696127cc841a08cb6ca5000180032", + "9d03f9f959254badae3c94b71e84f2cc", + "65d1d113a0a8446c83563d9aefd8b112", + "9f61fd282f104094bc821e8a4b9f27ce", + "fd0fc02ef4b545c0a459527aca8bc81e", + "01cf0405f63a4d38ad8d1fe31721806f", + "ae20add968524517a261a81be45cde48", + "dc76053f6ae847469aab55949ad182be", + "4d98195ba52f48a29a237777eeef35cf", + "ffeafe7d69484d64af7484311e32703d", + "b66e7b11b2404e3daeaed1272994adb5" + ] + } + }, + "execution_count": null, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "5dcc5fb3ad9e41eeb877fdd04f09ba7d", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "config.json: 0%| | 0.00/838 [00:00 \n", + "177383 -> olá\n", + "235265 -> .\n", + " 6235 -> Pra\n", + " 3004 -> zer\n", + " 2190 -> em\n", + " 26809 -> conhe\n", + "235260 -> c\n", + "235442 -> ê\n", + "235290 -> -\n", + " 545 -> lo\n", + "235265 -> .\n", + " 687 -> O\n", + " 11030 -> tempo\n", + " 5365 -> está\n", + " 14693 -> muito\n", + " 12318 -> bom\n", + " 43897 -> hoje\n", + "235265 -> .\n", + "\n", + "[2, 235530, 235579, 45884, 235483, 235940, 27074, 20579, 89299, 30848, 197350, 99877, 235940, 133533, 118300, 161437, 3640, 236062, 84372, 236062, 197350, 6032, 235265]\n", + " 2 -> \n", + "235530 -> न\n", + "235579 -> म\n", + " 45884 -> स्त\n", + "235483 -> े\n", + "235940 -> ।\n", + " 27074 -> आप\n", + " 20579 -> से\n", + " 89299 -> मिल\n", + " 30848 -> कर\n", + "197350 -> अच्छा\n", + " 99877 -> लगा\n", + "235940 -> ।\n", + "133533 -> आज\n", + "118300 -> मौ\n", + "161437 -> सम\n", + " 3640 -> स\n", + "236062 -> च\n", + " 84372 -> मु\n", + "236062 -> च\n", + "197350 -> अच्छा\n", + " 6032 -> है\n", + "235265 -> .\n" + ] + } + ], + "source": [ + "import jax.numpy as jnp\n", + "\n", + "# Function to detokenize (convert tokens back into words)\n", + "def detoken(tokens):\n", + " print(tokens['input_ids']) # Print the token IDs for debugging\n", + " input_ids = tokens['input_ids'] # Get input IDs from the tokenizer output\n", + "\n", + " for x in input_ids: # Iterate over the token list\n", + " # Use tokenizer.decode() to convert tokens back to words\n", + " word = tokenizer.decode([x]) # No need to convert to JAX array for decoding\n", + " print(f\"{x:6} -> {word}\")\n", + "\n", + "# Example text 1: Portuguese\n", + "detoken(tokenizer(\"olá. Prazer em conhecê-lo. O tempo está muito bom hoje.\", return_tensors=None))\n", + "print()\n", + "\n", + "# Example text 2: Hindi\n", + "detoken(tokenizer(\"नमस्ते। आपसे मिलकर अच्छा लगा। आज मौसम सचमुच अच्छा है.\", return_tensors=None))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9T7xe_jzslv4" + }, + "source": [ + "## Load Dataset\n", + "\n", + "How many datasets do you need? You can start with a relatively small dataset, approximately 10 to 20, those can have a significant impact on a model's behavior.\n", + "\n", + "To improve the output quality, a target of around 200 total examples is recommended. Nevertheless, the amount of data required for tuning really depends on how much you want to influence the model's behavior. Our recommendation is to commence with a limited amount of data and gradually incorporate additional data into the training process until the desired behavior is achieved." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "ZiS-KU9osh_N", + "outputId": "dedf9024-ff52-4a36-e586-6fea9139a53f", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "15\n", + "user\n", + "Write a title\n", + "model\n", + "O Alquimista\n", + "\n", + "user\n", + "Write a title\n", + "model\n", + "Dom Casmurro\n", + "\n", + "user\n", + "Write a title\n", + "model\n", + "Memorial do Convento\n" + ] + } + ], + "source": [ + "# example titles\n", + "data = [\n", + " \"O Alquimista\", # by Paulo Coelho\n", + " \"Dom Casmurro\", # by Machado de Assis\n", + " \"Memorial do Convento\", # by José Saramago\n", + " \"A Hora da Estrela\", # by Clarice Lispector\n", + " \"Vidas Secas\", # by Graciliano Ramos\n", + " \"O Cortiço\", # by Aluísio Azevedo\n", + " \"Grande Sertão: Veredas\", # by Guimarães Rosa\n", + " \"Capitães da Areia\", # by Jorge Amado\n", + " \"A Sibila\", # by Agustina Bessa-Luís\n", + " \"Os Maias\", # by Eça de Queirós\n", + " \"O Crime do Padre Amaro\", # by Eça de Queirós\n", + " \"A Relíquia\", # by Eça de Queirós\n", + " \"O Primo Basílio\", # by Eça de Queirós\n", + " \"A Ilustre Casa de Ramires\", # by Eça de Queirós\n", + " \"A Cidade e as Serras\" # by Eça de Queirós\n", + "]\n", + "\n", + "train = []\n", + "\n", + "for x in data:\n", + " item = f\"user\\nWrite a title\\nmodel\\n{x}\"\n", + " length = len(tokenizer(item))\n", + " # skip data if the token length is longer than our limit\n", + " if length < token_limit:\n", + " train.append(item)\n", + " if(len(train)>=num_data_limit):\n", + " break\n", + "\n", + "print(len(train))\n", + "print(train[0])\n", + "print()\n", + "print(train[1])\n", + "print()\n", + "print(train[2])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9s1o96HRtwV_" + }, + "source": [ + "See below example code, using HF datasets, if your datasets are much bigger." + ] + }, + { + "cell_type": "code", + "source": [ + "!pip install datasets" + ], + "metadata": { + "id": "ZS9zT92tiKHu" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# from datasets import load_dataset\n", + "\n", + "# # Load the dataset\n", + "# ds = load_dataset(\"bebechien/korean_cake_boss\", split=\"train\")\n", + "# print(ds)\n", + "\n", + "# # Prepare the dataset for tokenization\n", + "# train = []\n", + "\n", + "# # Iterate through the dataset and format the prompts\n", + "# for x in ds:\n", + "# # Create the formatted input-output text\n", + "# item = f\"user\\n다음에 대한 이메일 답장을 작성해줘.\\n\\\"{x['input']}\\\"\\nmodel\\n{x['output']}\"\n", + "\n", + "# # Tokenize the item and get its length\n", + "# length = len(tokenizer(item)[\"input_ids\"])\n", + "# print(length)\n", + "# # Skip if the tokenized item is longer than the token limit\n", + "# if length < token_limit:\n", + "# train.append(item)\n", + "\n", + "# # Stop if we have reached the desired data limit\n", + "# if len(train) >= num_data_limit:\n", + "# break\n", + "\n", + "# # Output the results\n", + "# print(f\"Number of training examples: {len(train)}\")\n", + "# print(f\"First example: {train[0]}\")\n", + "# print(f\"Second example: {train[1]}\")\n", + "# print(f\"Third example: {train[2]}\")" + ], + "metadata": { + "id": "Vh9s8m_PgoAH", + "outputId": "ccdf0c19-c3b5-40d5-d7ae-dc7a2c59fe0b", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Dataset({\n", + " features: ['input', 'output'],\n", + " num_rows: 20\n", + "})\n", + "234\n", + "307\n", + "335\n", + "348\n", + "366\n", + "158\n", + "169\n", + "157\n", + "198\n", + "167\n", + "163\n", + "150\n", + "165\n", + "145\n", + "157\n", + "308\n", + "407\n", + "298\n", + "419\n", + "318\n", + "Number of training examples: 10\n", + "First example: user\n", + "다음에 대한 이메일 답장을 작성해줘.\n", + "\"안녕하세요, 10월 5일에 있을 딸 아이의 5번째 생일을 위해 케이크를 주문하고 싶습니다. 아이가 좋아하는 핑크색 공주님 케이크가 가능할까요?\"\n", + "model\n", + "고객님, 안녕하세요.\n", + "\n", + "따님의 5번째 생일을 진심으로 축하드립니다! 핑크색 공주님 케이크 주문 가능합니다. 원하시는 디자인이나 특별한 요청 사항이 있으시면 말씀해주세요.\n", + "\n", + "감사합니다.\n", + "\n", + "[가게 이름] 드림\n", + "Second example: user\n", + "다음에 대한 이메일 답장을 작성해줘.\n", + "\"11월 10일, 저희 부부의 결혼 10주년을 기념하기 위한 케이크를 주문하려고 합니다. 둘이 함께 먹을 작은 사이즈의 하트 모양 케이크를 원합니다.\"\n", + "model\n", + "고객님, 안녕하세요.\r\n", + "\n", + "결혼 10주년을 축하드립니다! 두 분의 특별한 날을 더욱 빛내드릴 하트 모양 케이크 주문 가능합니다. 케이크 맛과 크기, 디자인 등 다른 요청 사항이 있으시면 말씀해주세요.\n", + "\n", + "감사합니다.\n", + "\n", + "[가게 이름] 드림\n", + "Third example: user\n", + "다음에 대한 이메일 답장을 작성해줘.\n", + "\"3월 15일에 있을 대학교 졸업식을 축하하기 위한 케이크를 주문하고 싶습니다. 학교 로고가 들어간 디자인이 가능한지 궁금합니다.\"\n", + "model\n", + "고객님, 안녕하세요.\n", + "\n", + "졸업을 진심으로 축하드립니다! 학교 로고가 들어간 케이크 주문 가능합니다. 로고 파일을 보내주시면 디자인 시안을 만들어 보여드리겠습니다. 궁금한 점은 언제든 문의해주세요.\n", + "\n", + "감사합니다.\n", + "\n", + "[가게 이름] 드림\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5NTIrFbJ3dBv" + }, + "source": [ + "In the context of a small dataset, the primary concern is that the model may prioritize memorizing specific examples rather than generalizing well to new and unobserved data. This limitation highlights the importance of utilizing a larger dataset during fine-tuning, as it enhances the model's ability to capture broader patterns and relationships." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "th0WS33gayn9" + }, + "source": [ + "## LoRA Fine-tuning" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ugc2ub4nau1j" + }, + "source": [ + "![lora.png](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAnYAAAJfCAYAAADy95sHAAAAAXNSR0IArs4c6QAAIABJREFUeF7snQd4VMXXxt/0XiCU0HtTUKT33omAgPSOFKkqqGBB/ipSBEVApIgUqdKb9I70DtJ7QkggCek9u983NxJSyfa9e/e9z+OjJjNnzvmdSfLu3JkzNmq1Wg0+JEACJEACJEACJEACFk/AhsLO4nPIAEiABEiABEiABEhAIkBhx4lAAiRAAiRAAiRAAgohQGGnkEQyDBIgARIgARIgARKgsOMcIAESIAESIAESIAGFEKCwU0giGQYJkAAJkAAJkAAJUNhxDpAACZAACZAACZCAQghQ2CkkkQyDBEiABEiABEiABCjsOAdIgARIgARIgARIQCEEKOwUkkiGQQIkQAIkQAIkQAIUdpwDJEACJEACJEACJKAQAhR2CkkkwyABEiABEiABEiABCjvOARIgARIgARIgARJQCAEKO4UkkmGQAAmQAAmQAAmQAIUd5wAJkAAJkAAJkAAJKIQAhZ1CEskwSIAESIAESIAESIDCjnOABEiABEiABEiABBRCgMJOIYlkGCRAAiRAAiRAAiRAYcc5QAIkQAIkQAIkQAIKIUBhp5BEMgwSIAESIAESIAESoLDjHCABEiABEiABEiABhRCgsFNIIhkGCZAACZAACZAACVDYcQ6QAAmQAAmQAAmQgEIIUNgpJJEMgwRIgARIgARIgAQo7DgHSIAESIAESIAESEAhBCjsFJJIhkECJEACJEACJEACFHacAyRAAiRAAiRAAiSgEAIUdgpJJMMgARIgARIgARIgAQo7zgESIAESIAESIAESUAgBCjuFJJJhkAAJkAAJkAAJkACFHecACZAACZAACZAACSiEAIWdQhLJMEiABEiABEiABEiAwo5zgARIgARIgARIgAQUQoDCTiGJZBgkQAIkQAIkQAIkQGHHOUACJEACJEACJEACCiFAYaeQRDIMEiABEiABEiABEqCw4xwgARIgARIgARIgAYUQoLBTSCIZBgmQAAmQAAmQAAlQ2HEOkAAJkAAJkAAJkIBCCFDYKSSRDIMESIAESIAESIAEKOw4B0iABEiABEiABEhAIQQo7BSSSIZBAiRAAiRAAiRAAhR2nAMkQAIkQAIkQAIkoBACFHYKSSTDIAESIAESIAESIAEKO84BEiABEiAB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)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Pt7Nr6a7tItO" + }, + "source": [ + "Fine-tuning a model involves updating its weights (also called parameters). LLMs have a lot of weights. The Gemma 2 2B that is being used in this notebook has 2,617,270,528 parameters!\n", + "\n", + "Changing all of them can take quite some time and requires a lot of resources.\n", + "\n", + "To mitigate this issue, you are going to use a technique called: [LoRA: Low-Rank Adaptation](https://arxiv.org/abs/2106.09685)\n", + "\n", + "This technique, in summary, helps lower the number of trained weights needed by a lot, making fine-tuning more accessible.\n", + "\n", + "The key parameter used is the `rank`. In this notebook it set to 4 but you can use higher numbers to get better results but, of course, needed more resources.\n", + "\n", + "**TIP**: Train your model with lower ranks and evaluate the performance improvemnet on your task. Gradually increase the rank in subsequent trials and see if that further boosts performance." + ] + }, + { + "cell_type": "code", + "source": [ + "!pip install peft\n", + "from peft import get_peft_model, LoraConfig, TaskType\n", + "import torch.nn as nn\n", + "\n", + "lora_config = LoraConfig(\n", + " task_type=TaskType.CAUSAL_LM,\n", + " r=lora_rank, # Using your predefined lora_rank\n", + " lora_alpha=32,\n", + " lora_dropout=0.1\n", + ")\n", + "gemma_lm = get_peft_model(gemma_lm, lora_config) # Enable LoRA for the model\n", + "\n", + "print(gemma_lm) # Hugging Face models don't have a summary method; use print() instead\n", + "\n", + "tokenizer.model_max_length = token_limit # Set token limit in the tokenizer\n", + "\n", + "from transformers import AdamW\n", + "\n", + "optimizer_grouped_parameters = [\n", + " {'params': [p for n, p in gemma_lm.named_parameters() if not any(nd in n for nd in [\"bias\", \"LayerNorm.weight\"])], 'weight_decay': 0.01},\n", + " {'params': [p for n, p in gemma_lm.named_parameters() if any(nd in n for nd in [\"bias\", \"LayerNorm.weight\"])], 'weight_decay': 0.0}\n", + "]\n", + "optimizer = AdamW(optimizer_grouped_parameters, lr=lr_value) # Use AdamW optimizer\n", + "\n", + "\n", + "loss_fn = nn.CrossEntropyLoss() # Define the loss function\n", + "\n", + "def forward_pass(input_text):\n", + " inputs = tokenizer(input_text, return_tensors=\"pt\", max_length=token_limit, truncation=True)\n", + " outputs = gemma_lm(**inputs, labels=inputs[\"input_ids\"])\n", + " loss = outputs.loss\n", + " return loss\n", + "\n" + ], + "metadata": { + "id": "YQiQxLFKfyzx", + "outputId": "5a5b1398-61cd-48ba-d354-71e4eee37213", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Collecting peft\n", + " Downloading peft-0.13.2-py3-none-any.whl.metadata (13 kB)\n", + "Requirement already satisfied: numpy>=1.17 in /usr/local/lib/python3.10/dist-packages (from peft) (1.26.4)\n", + "Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.10/dist-packages (from peft) (24.1)\n", + "Requirement already satisfied: psutil in /usr/local/lib/python3.10/dist-packages (from peft) (5.9.5)\n", + "Requirement already satisfied: pyyaml in /usr/local/lib/python3.10/dist-packages (from peft) (6.0.2)\n", + "Requirement already satisfied: torch>=1.13.0 in /usr/local/lib/python3.10/dist-packages (from peft) (2.4.1+cu121)\n", + "Requirement already satisfied: transformers in /usr/local/lib/python3.10/dist-packages (from peft) (4.44.2)\n", + "Requirement already satisfied: tqdm in /usr/local/lib/python3.10/dist-packages (from peft) (4.66.5)\n", + "Requirement already satisfied: accelerate>=0.21.0 in /usr/local/lib/python3.10/dist-packages (from peft) (0.34.2)\n", + "Requirement already satisfied: safetensors in /usr/local/lib/python3.10/dist-packages (from peft) (0.4.5)\n", + "Requirement already satisfied: huggingface-hub>=0.17.0 in /usr/local/lib/python3.10/dist-packages (from peft) (0.24.7)\n", + "Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from huggingface-hub>=0.17.0->peft) (3.16.1)\n", + "Requirement already satisfied: fsspec>=2023.5.0 in /usr/local/lib/python3.10/dist-packages (from huggingface-hub>=0.17.0->peft) (2024.6.1)\n", + "Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from huggingface-hub>=0.17.0->peft) (2.32.3)\n", + "Requirement already satisfied: typing-extensions>=3.7.4.3 in /usr/local/lib/python3.10/dist-packages (from huggingface-hub>=0.17.0->peft) (4.12.2)\n", + "Requirement already satisfied: sympy in /usr/local/lib/python3.10/dist-packages (from torch>=1.13.0->peft) (1.13.3)\n", + "Requirement already satisfied: networkx in /usr/local/lib/python3.10/dist-packages (from torch>=1.13.0->peft) (3.4.1)\n", + "Requirement already satisfied: jinja2 in /usr/local/lib/python3.10/dist-packages (from torch>=1.13.0->peft) (3.1.4)\n", + "Requirement already satisfied: regex!=2019.12.17 in /usr/local/lib/python3.10/dist-packages (from transformers->peft) (2024.9.11)\n", + "Requirement already satisfied: tokenizers<0.20,>=0.19 in /usr/local/lib/python3.10/dist-packages (from transformers->peft) (0.19.1)\n", + "Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/dist-packages (from jinja2->torch>=1.13.0->peft) (3.0.1)\n", + "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->huggingface-hub>=0.17.0->peft) (3.4.0)\n", + "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->huggingface-hub>=0.17.0->peft) (3.10)\n", + "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->huggingface-hub>=0.17.0->peft) (2.2.3)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests->huggingface-hub>=0.17.0->peft) (2024.8.30)\n", + "Requirement already satisfied: mpmath<1.4,>=1.1.0 in /usr/local/lib/python3.10/dist-packages (from sympy->torch>=1.13.0->peft) (1.3.0)\n", + "Downloading peft-0.13.2-py3-none-any.whl (320 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m320.7/320.7 kB\u001b[0m \u001b[31m8.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hInstalling collected packages: peft\n", + "Successfully installed peft-0.13.2\n", + "PeftModelForCausalLM(\n", + " (base_model): LoraModel(\n", + " (model): Gemma2ForCausalLM(\n", + " (model): Gemma2Model(\n", + " (embed_tokens): Embedding(256000, 2304, padding_idx=0)\n", + " (layers): ModuleList(\n", + " (0-25): 26 x Gemma2DecoderLayer(\n", + " (self_attn): Gemma2SdpaAttention(\n", + " (q_proj): lora.Linear(\n", + " (base_layer): Linear(in_features=2304, out_features=2048, bias=False)\n", + " (lora_dropout): ModuleDict(\n", + " (default): Dropout(p=0.1, inplace=False)\n", + " )\n", + " (lora_A): ModuleDict(\n", + " (default): Linear(in_features=2304, out_features=4, bias=False)\n", + " )\n", + " (lora_B): ModuleDict(\n", + " (default): Linear(in_features=4, out_features=2048, bias=False)\n", + " )\n", + " (lora_embedding_A): ParameterDict()\n", + " (lora_embedding_B): ParameterDict()\n", + " (lora_magnitude_vector): ModuleDict()\n", + " )\n", + " (k_proj): Linear(in_features=2304, out_features=1024, bias=False)\n", + " (v_proj): lora.Linear(\n", + " (base_layer): Linear(in_features=2304, out_features=1024, bias=False)\n", + " (lora_dropout): ModuleDict(\n", + " (default): Dropout(p=0.1, inplace=False)\n", + " )\n", + " (lora_A): ModuleDict(\n", + " (default): Linear(in_features=2304, out_features=4, bias=False)\n", + " )\n", + " (lora_B): ModuleDict(\n", + " (default): Linear(in_features=4, out_features=1024, bias=False)\n", + " )\n", + " (lora_embedding_A): ParameterDict()\n", + " (lora_embedding_B): ParameterDict()\n", + " (lora_magnitude_vector): ModuleDict()\n", + " )\n", + " (o_proj): Linear(in_features=2048, out_features=2304, bias=False)\n", + " (rotary_emb): Gemma2RotaryEmbedding()\n", + " )\n", + " (mlp): Gemma2MLP(\n", + " (gate_proj): Linear(in_features=2304, out_features=9216, bias=False)\n", + " (up_proj): Linear(in_features=2304, out_features=9216, bias=False)\n", + " (down_proj): Linear(in_features=9216, out_features=2304, bias=False)\n", + " (act_fn): PytorchGELUTanh()\n", + " )\n", + " (input_layernorm): Gemma2RMSNorm((2304,), eps=1e-06)\n", + " (post_attention_layernorm): Gemma2RMSNorm((2304,), eps=1e-06)\n", + " (pre_feedforward_layernorm): Gemma2RMSNorm((2304,), eps=1e-06)\n", + " (post_feedforward_layernorm): Gemma2RMSNorm((2304,), eps=1e-06)\n", + " )\n", + " )\n", + " (norm): Gemma2RMSNorm((2304,), eps=1e-06)\n", + " )\n", + " (lm_head): Linear(in_features=2304, out_features=256000, bias=False)\n", + " )\n", + " )\n", + ")\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.10/dist-packages/transformers/optimization.py:591: FutureWarning: This implementation of AdamW is deprecated and will be removed in a future version. Use the PyTorch implementation torch.optim.AdamW instead, or set `no_deprecation_warning=True` to disable this warning\n", + " warnings.warn(\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hQQ47kcdpbZ9" + }, + "source": [ + "Note that enabling LoRA reduces the number of trainable parameters significantly.\n", + "\n", + "From 2,617,270,528 to **2,928,640**\n", + "\n", + "To monitor the learning progress, you will evaluate the model at the end of each epoch and save the lora weights." + ] + }, + { + "cell_type": "code", + "source": [ + "import torch\n", + "import os\n", + "import matplotlib.pyplot as plt\n", + "\n", + "# Define a custom callback-like function to handle actions at the end of each epoch\n", + "class CustomCallback:\n", + " def __init__(self, model, lora_name, lora_rank, text_gen):\n", + " self.model = model\n", + " self.lora_name = lora_name\n", + " self.lora_rank = lora_rank\n", + " self.text_gen = text_gen # text_gen function for evaluation\n", + "\n", + " def on_epoch_end(self, epoch):\n", + " # Save LoRA weights at the end of each epoch\n", + " model_name = f\"./{self.lora_name}_{self.lora_rank}_epoch{epoch+1}.lora.pt\"\n", + " self.model.save_pretrained(model_name, token=access_token) # Save model with LoRA weights locally\n", + "\n", + " # Evaluate the model using text generation\n", + " print(f\"Epoch {epoch + 1} finished. Running evaluation:\")\n", + " self.text_gen(\"Write a title\")\n", + " self.text_gen(\"Write a poem\")\n", + "\n", + "# Assuming train is your DataLoader and gemma_lm is your model\n", + "callback = CustomCallback(gemma_lm, lora_name, lora_rank, text_gen)\n", + "\n", + "# Training loop with callback-like behavior\n", + "losses = []\n", + "for epoch in range(train_epoch):\n", + " epoch_loss = 0\n", + " for batch in train: # Assuming `train` is a DataLoader or similar iterable\n", + " optimizer.zero_grad()\n", + "\n", + " inputs = tokenizer(batch, return_tensors=\"pt\", max_length=token_limit, truncation=True, padding=True)\n", + " labels = inputs[\"input_ids\"]\n", + " outputs = gemma_lm(**inputs, labels=labels)\n", + " loss = outputs.loss\n", + "\n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " epoch_loss += loss.item()\n", + "\n", + " losses.append(epoch_loss / len(train)) # Store average loss per epoch\n", + "\n", + " # Run custom callback at the end of each epoch\n", + " callback.on_epoch_end(epoch)\n", + "\n", + "# Plot training loss over epochs\n", + "plt.plot(losses)\n", + "plt.xlabel(\"Epoch\")\n", + "plt.ylabel(\"Loss\")\n", + "plt.title(\"Training Loss Over Epochs\")\n", + "plt.show()" + ], + "metadata": { + "id": "YKpmDIfXh1Kx", + "outputId": "2422fc27-260d-4e7d-ce4b-bfa4234bec7d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + } + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "The attention mask is not set and cannot be inferred from input because pad token is same as eos token. As a consequence, you may observe unexpected behavior. Please pass your input's `attention_mask` to obtain reliable results.\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 1 finished. Running evaluation:\n", + "\n", + "Gemma output:\n", + "user\n", + "Write a title\n", + "model\n", + "O Cortiço\n", + "TOTAL TIME ELAPSED: 7.93s\n", + "\n", + "Gemma output:\n", + "user\n", + "Write a poem\n", + "model\n", + "\n", + "TOTAL TIME ELAPSED: 4.38s\n", + "Epoch 2 finished. Running evaluation:\n", + "\n", + "Gemma output:\n", + "user\n", + "Write a title\n", + "model\n", + "A Relíquia\n", + "TOTAL TIME ELAPSED: 8.04s\n", + "\n", + "Gemma output:\n", + "user\n", + "Write a poem\n", + "model\n", + "O Primo Basílio\n", + "TOTAL TIME ELAPSED: 8.19s\n", + "Epoch 3 finished. Running evaluation:\n", + "\n", + "Gemma output:\n", + "user\n", + "Write a title\n", + "model\n", + "O Primo Basílio\n", + "TOTAL TIME ELAPSED: 8.21s\n", + "\n", + "Gemma output:\n", + "user\n", + "Write a poem\n", + "model\n", + "O Primo Basílio\n", + "TOTAL TIME ELAPSED: 8.18s\n", + "Epoch 4 finished. Running evaluation:\n", + "\n", + "Gemma output:\n", + "user\n", + "Write a title\n", + "model\n", + "A Sibila\n", + "TOTAL TIME ELAPSED: 7.24s\n", + "\n", + "Gemma output:\n", + "user\n", + "Write a poem\n", + "model\n", + "O Primo Basílio\n", + "TOTAL TIME ELAPSED: 8.21s\n", + "Epoch 5 finished. Running evaluation:\n", + "\n", + "Gemma output:\n", + "user\n", + "Write a title\n", + "model\n", + "A Sibila\n", + "TOTAL TIME ELAPSED: 7.31s\n", + "\n", + "Gemma output:\n", + "user\n", + "Write a poem\n", + "model\n", + "O Primo Basílio\n", + "TOTAL TIME ELAPSED: 7.77s\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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4Obmprc4OTkBqDlltGrVKkyaNAm2trbo2bMndu7cqbd9UlISHnnkEdja2qJz585YsmQJiouL9dqsX78e/fr1g0wmg7u7O5YuXar3/N27d/HEE0/Azs4OvXv3xv/+97+27TQRtRmGGyIyeq+++iqmT5+OK1euYM6cOZg1axauX78OACgpKcHEiRPh5OSECxcuYMeOHTh69KheeFm1ahUiIiKwZMkSJCUl4X//+x98fHz03uPNN9/EjBkz8MMPP2Dy5MmYM2cO8vLy2rWfRNRK2vzWnEREBoSHhwsWFhaCvb293vL2228LglBzp+xnn31Wb5vhw4cLf/7znwVBEIQvvvhCcHJyEoqLi3XP79+/X5BKpYJKpRIEQRA8PDyEV155pcEaAAj/93//p3tcXFwsABAOHjzYav0kovbDMTdEJLqHH34Yq1at0lvn7Oys+//g4GC954KDg5GYmAgAuH79OgICAmBvb697fsSIEdBqtbh58yYkEgmysrIwbtw4gzUMGDBA9//29vaQy+XIzc1taZeISEQMN0QkOnt7+zqniVqLra1tk9pZWVnpPZZIJNBqtW1REhG1MY65ISKjFx8fX+dxnz59AAB9+vTBlStXUFJSonv+7NmzkEql8PX1hYODA7y9vXHs2LF2rZmIxMMjN0QkuoqKCqhUKr11lpaW6NKlCwBgx44dGDJkCEaOHImvv/4a58+fx5dffgkAmDNnDl5//XWEh4fjjTfewJ07d/D8889j3rx5cHV1BQC88cYbePbZZ+Hi4oJJkyahqKgIZ8+exfPPP9++HSWidsFwQ0SiO3ToENzd3fXW+fr64saNGwBqrmTaunUrnnvuObi7u+Obb75B3759AQB2dnY4fPgwli1bhqFDh8LOzg7Tp0/Hf/7zH91rhYeHo7y8HB9++CFeeukldOnSBU899VT7dZCI2pVEEARB7CKIiBoikUiwe/duhIaGil0KEZkIjrkhIiIis8JwQ0RERGaFY26IyKjxzDkRNReP3BAREZFZYbghIiIis8JwQ0RERGaF4YaIiIjMCsMNERERmRWGGyIiIjIrDDdERERkVhhuiIiIyKww3BAREZFZ+X9611boj/snDQAAAABJRU5ErkJggg==\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tn-jgVULyBXq" + }, + "source": [ + "Note that the model began to grasp our intent more effectively from Epoch #3 onwards.\n", + "\n", + "To compare and contrast, it was utlized the \"Write a poem\" prompt. Interestingly, in Epoch #5, the model began to generate Portuguese in response to that prompt. This shift indicates a strong influence of our training dataset on the model's behavior. However, depending on your application, such a significat change might not be desirable. In such cases, Epoch #4 would be a more suitable choice." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P-tVAKmda2Zt" + }, + "source": [ + "## Load LoRA\n", + "\n", + "Use the code below if you shared LoRA weights. It's much more lightweight than the model files themselves - for instance, a LoRA rank 4 weights file for a 10gb model might only be on the order of a few megabytes, easily shared over email." + ] + }, + { + "cell_type": "code", + "source": [ + "# Example Code for Load LoRA\n", + "\n", + "# from peft import PeftModel\n", + "\n", + "# # Load pre-trained LoRA weights (assuming the weights are saved in Hugging Face format)\n", + "# # Load the pre-trained LoRA weights\n", + "# lora_weights_path = f\"./{lora_name}_{lora_rank}_epoch{train_epoch}.lora.pt\"\n", + "\n", + "# # Load the LoRA adapter into the model using PeftModel\n", + "# gemma_lm = PeftModel.from_pretrained(gemma_lm, lora_weights_path)" + ], + "metadata": { + "id": "kVe4vjgCngsd" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ipg1u_wEKTxG" + }, + "source": [ + "## Try a different sampler\n", + "\n", + "The top-K algorithm randomly picks the next token from the tokens of top K probability." + ] + }, + { + "cell_type": "code", + "source": [ + "import torch\n", + "\n", + "def text_gen_with_top_k(prompt, token_limit=100, top_k=50): # You can set your token limit and top_k\n", + " tick()\n", + "\n", + " # Format input, same as your original code\n", + " input_text = f\"user\\n{prompt}\\nmodel\\n\"\n", + "\n", + " # Tokenize input\n", + " inputs = tokenizer(input_text, return_tensors=\"pt\")\n", + "\n", + " # Generate text using the model with Top-K sampling\n", + " output_tokens = gemma_lm.generate(\n", + " inputs[\"input_ids\"],\n", + " max_length=token_limit,\n", + " do_sample=True, # Enable sampling\n", + " top_k=top_k, # Set Top-K sampling strategy\n", + " pad_token_id=tokenizer.eos_token_id # Prevent errors if the input length exceeds the model's limit\n", + " )\n", + "\n", + " # Decode the generated tokens back to text\n", + " output = tokenizer.decode(output_tokens[0], skip_special_tokens=True)\n", + "\n", + " print(\"\\nGemma output:\")\n", + " print(output)\n", + "\n", + "\n", + "# Generate text 5 times using the top_k sampling strategy\n", + "text_gen_with_top_k(\"Write a title\", token_limit=100, top_k=50)\n" + ], + "metadata": { + "id": "K2JUE2IilwNi", + "outputId": "1ffdd099-1e0f-4a66-a7c6-81b43cc643e3", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + "Gemma output:\n", + "user\n", + "Write a title\n", + "model\n", + "Capitães da Areia\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3m1XaCrlMu3Y" + }, + "source": [ + "Try a slight different prompts" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "qC-MLxYWM1HU", + "outputId": "f26faf29-ce26-4a5c-e6ff-f2125148249b", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + "Gemma output:\n", + "user\n", + "Write a music title\n", + "model\n", + "A Sibila\n", + "\n", + "Gemma output:\n", + "user\n", + "Write a poem title\n", + "model\n", + "O V alienígena\n", + "\n", + "Gemma output:\n", + "user\n", + "Write a blog title\n", + "model\n", + "Mar Secreto do Palmar\n", + "\n", + "Gemma output:\n", + "user\n", + "Write a movie title\n", + "model\n", + "A Hora da Estrela\n", + "\n", + "Gemma output:\n", + "user\n", + "Write a novel title\n", + "model\n", + "Os Maias\n" + ] + } + ], + "source": [ + "text_gen_with_top_k(\"Write a music title\")\n", + "text_gen_with_top_k(\"Write a poem title\")\n", + "text_gen_with_top_k(\"Write a blog title\")\n", + "text_gen_with_top_k(\"Write a movie title\")\n", + "text_gen_with_top_k(\"Write a novel title\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aEptDCED9tVp" + }, + "source": [ + "## Publish your model" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T3Qhrlyy5ReL" + }, + "source": [ + "Lets save our model. It takes some time (~11 minutes) as it is a very large file" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "4TcvzBH995FE", + "outputId": "26a4be25-9a51-41f9-ad28-ef1708bf440f", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "('./my_gemma2_lt_pt/tokenizer_config.json',\n", + " './my_gemma2_lt_pt/special_tokens_map.json',\n", + " './my_gemma2_lt_pt/tokenizer.model',\n", + " './my_gemma2_lt_pt/added_tokens.json',\n", + " './my_gemma2_lt_pt/tokenizer.json')" + ] + }, + "metadata": {}, + "execution_count": 18 + } + ], + "source": [ + "# Define the model name (used for both model and tokenizer)\n", + "my_model_name = \"my_gemma2_lt_pt\"\n", + "\n", + "# Save the fine-tuned model to the specified directory\n", + "gemma_lm.save_pretrained(f\"./{my_model_name}\", token=access_token)\n", + "\n", + "# # Save the tokenizer to the same directory\n", + "tokenizer.save_pretrained(f\"./{my_model_name}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xQ4de1a79zy0" + }, + "source": [ + "## Publishing on Hugging Face\n", + "\n", + "To publish your model on Hugging Face, you'll need your hugging face user (`HF_USER`) and an access token with write permission (`HF_TOKEN`) to the your secret keys." + ] + }, + { + "cell_type": "code", + "source": [ + "# Upload the model to Hugging Face Hub\n", + "my_model_name = \"my_gemma2_pt\"\n", + "writeToken = userdata.get(\"HF_WRITE_TOKEN\")\n", + "hf_repo_id = f\"{my_hf_username}/{my_model_name}\" # Correct format\n", + "gemma_lm.push_to_hub(hf_repo_id, token=writeToken)" + ], + "metadata": { + "id": "AK31-LuXpwen", + "outputId": "e96865e3-4e8c-4acf-e256-c5ec31b6f931", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 136, + "referenced_widgets": [ + "84cd1a70535f4272a0206041373ff281", + "325cf823a7244a4b8e25462ae4912ea3", + "325f38ff3fef43cbbd248ff3ff714c43", + "de4fae4a6e3e420d86414a572846a9e0", + "4d729ba11c9442528af79d6e377a292c", + "49a42d4bcb8b4684a69656ee8b0449df", + "50b06db300ce432c9235071f48a18432", + "a31850a948e344848d43caae277f3200", + "fe5291b55e7147b682b671dad99d16e6", + "b485e94c1509478da6dd7a04c41e055d", + "98e4874bfa904312a4a9b00ca2ea8577", + "a163fe0a8b594568bf102caf54856484", + "dd53c0e07382441fbad818b0c3852006", + "3c316ae120e445c8b4bbc8260cf14ab4", + "9387a006080845ce9ef9aeb41fbd6c6e", + "c49cd450c3d24511a1efe272820c5f0a", + "99a5ad5c04b4456ba65118367cd2ea5a", + "d74745e493704920b56855e0cb73a39e", + "bd53b02c9808436ead8b213886e76bed", + "3f1bd9e04dc64bca88b99998339df788", + "d082ae773106445aa6ec56167b2a5cb9", + "030123f151674251ac0f0be0f8f713dc" + ] + } + }, + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "README.md: 0%| | 0.00/5.17k [00:00