diff --git a/README.md b/README.md
index 6223031..60ffc62 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ A multi-part seminar series on Large Language Models (LLMs).
![Session 1](images/home_page/Large%20Language%20Models.png)
-
## ✨ [Emergence, Fundamentals and Landscape of LLMs](session_1)
@@ -34,14 +34,12 @@ Explore diverse applications of Large Language Models (LLMs) and the frameworks
Coming soon...
-## ✨ Training and Evaluating LLMs On Custom Datasets
+## ✨ [Training and Evaluating LLMs On Custom Datasets](session_4)
Delve into the intricacies of training and evaluating Large Language Models (LLMs) on your custom datasets. Gain insights into optimizing performance, fine-tuning, and assessing model effectiveness tailored to your specific data.
![Session 4](images/home_page/Session%204.png)
-Coming soon...
-
## ✨ Optimizing LLMs For Inference and Deployment Techniques
Learn techniques to optimize Large Language Models (LLMs) for efficient inference. Explore strategies for seamless deployment, ensuring optimal performance in real-world applications.
@@ -50,7 +48,7 @@ Learn techniques to optimize Large Language Models (LLMs) for efficient inferenc
Coming soon...
-## ✨ Open Challanges With LLMs
+## ✨ Open Challenges With LLMs
Delve into the dichotomy of small vs large LLMs, navigating production challenges, addressing research hurdles, and understanding the perils associated with the utilization of pretrained LLMs. Explore the evolving landscape of challenges within the realm of Large Language Models.
diff --git a/images/session_1/part_3_landscape_of_llms/Large Language Models-challanges.png b/images/session_1/part_3_landscape_of_llms/Large Language Models-challenges.png
similarity index 100%
rename from images/session_1/part_3_landscape_of_llms/Large Language Models-challanges.png
rename to images/session_1/part_3_landscape_of_llms/Large Language Models-challenges.png
diff --git a/images/session_4/part_2_finetuning_lms_to_human_preferences/base_attn.png b/images/session_4/part_2_finetuning_lms_to_human_preferences/base_attn.png
new file mode 100644
index 0000000..0f7dffd
Binary files /dev/null and b/images/session_4/part_2_finetuning_lms_to_human_preferences/base_attn.png differ
diff --git a/images/session_4/part_2_finetuning_lms_to_human_preferences/kl0_attn.png b/images/session_4/part_2_finetuning_lms_to_human_preferences/kl0_attn.png
new file mode 100644
index 0000000..57b136c
Binary files /dev/null and b/images/session_4/part_2_finetuning_lms_to_human_preferences/kl0_attn.png differ
diff --git a/images/session_4/part_2_finetuning_lms_to_human_preferences/kl0_plot.png b/images/session_4/part_2_finetuning_lms_to_human_preferences/kl0_plot.png
new file mode 100644
index 0000000..e76055d
Binary files /dev/null and b/images/session_4/part_2_finetuning_lms_to_human_preferences/kl0_plot.png differ
diff --git a/images/session_4/part_2_finetuning_lms_to_human_preferences/kl1_attn.png b/images/session_4/part_2_finetuning_lms_to_human_preferences/kl1_attn.png
new file mode 100644
index 0000000..d5a2956
Binary files /dev/null and b/images/session_4/part_2_finetuning_lms_to_human_preferences/kl1_attn.png differ
diff --git a/images/session_4/part_2_finetuning_lms_to_human_preferences/rl_outputs.png b/images/session_4/part_2_finetuning_lms_to_human_preferences/rl_outputs.png
new file mode 100644
index 0000000..2a204f5
Binary files /dev/null and b/images/session_4/part_2_finetuning_lms_to_human_preferences/rl_outputs.png differ
diff --git a/images/site/infocusp_logo_blue.png b/images/site/infocusp_logo_blue.png
new file mode 100644
index 0000000..121623f
Binary files /dev/null and b/images/site/infocusp_logo_blue.png differ
diff --git a/images/site/infocusp_logo_blue.svg b/images/site/infocusp_logo_blue.svg
deleted file mode 100644
index 39cc1bc..0000000
--- a/images/site/infocusp_logo_blue.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/mkdocs.yaml b/mkdocs.yaml
index 886ddaf..290715d 100644
--- a/mkdocs.yaml
+++ b/mkdocs.yaml
@@ -5,7 +5,7 @@ docs_dir: .
site_dir: ../site
theme:
name: material
- # logo: assets/icons8-code-64.png
+ logo: images/site/infocusp_logo_blue.png
palette:
primary: white
features:
@@ -22,6 +22,7 @@ theme:
markdown_extensions:
- toc:
permalink: true
+ toc_depth: 3
- pymdownx.highlight:
anchor_linenums: true
line_spans: __span
@@ -41,6 +42,8 @@ extra_css:
extra:
generator: false
social:
+ - icon: fontawesome/solid/globe
+ link: https://infocusp.com
- icon: fontawesome/brands/linkedin
link: https://in.linkedin.com/company/infocusp
- icon: fontawesome/brands/github
@@ -51,4 +54,6 @@ extra:
link: https://twitter.com/_infocusp
plugins:
- search
- - same-dir
\ No newline at end of file
+ - same-dir
+ - mkdocs-jupyter:
+ ignore_h1_titles: True
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 8be8bd5..df62450 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,5 @@
mkdocs>=1.2.2
mkdocs-material>=7.1.11
mkdocs-static-i18n>=0.18
-mkdocs-same-dir>=0.1.3
\ No newline at end of file
+mkdocs-same-dir>=0.1.3
+mkdocs-jupyter>=0.16.1
\ No newline at end of file
diff --git a/session_1/README.md b/session_1/README.md
index eeb5e1c..484b5ba 100644
--- a/session_1/README.md
+++ b/session_1/README.md
@@ -6,6 +6,7 @@
Covers important building blocks of what we call an LLM today, where they came from, etc. and then we'll dive into the deep universe that has sprung to life around these LLMs.
This session is aimed to help:
+
* People who are new to LLMs
* People who have just started working on them
* People who are working on different use cases surrounding LLMs and need a roadmap.
diff --git a/session_1/part_3_landscape_of_llms/README.md b/session_1/part_3_landscape_of_llms/README.md
index 23b2e28..da6b995 100644
--- a/session_1/part_3_landscape_of_llms/README.md
+++ b/session_1/part_3_landscape_of_llms/README.md
@@ -465,9 +465,9 @@
-## Challanges with LLMs
+## Challenges with LLMs
-![Challanges with LLMs](./../../images/session_1/part_3_landscape_of_llms/Large%20Language%20Models-challanges.png)
+![Challenges with LLMs](./../../images/session_1/part_3_landscape_of_llms/Large%20Language%20Models-challenges.png)
diff --git a/session_4/README.md b/session_4/README.md
new file mode 100644
index 0000000..6421874
--- /dev/null
+++ b/session_4/README.md
@@ -0,0 +1,34 @@
+# Session 4 - Training and Evaluating LLMs On Custom Datasets
+
+
+
+This session aims to equip you with the knowledge to train Large Language Models (LLMs) by exploring techniques like unsupervised pretraining and supervised fine-tuning with various preference optimization methods. It will also cover efficient fine-tuning techniques, retrieval-based approaches, and language agent fine-tuning. Additionally, the session will discuss LLM training frameworks and delve into evaluation methods for LLMs, including evaluation-driven development and using LLMs for evaluation itself.
+
+This session is aimed to help:
+
+* People who are already familiar basics of LLMs and Transformers
+* People who already knows how to use pre-trained LLMs prompt engineering and RAG
+* People who want train or finetune their own LLMs on custom data.
+* People who want to lear how to evaluate LLMs
+
+## Outline
+
+### Part 1: Training Foundational LLMs
+
+Coming soon...
+
+### Part 2: [Finetuning LMs To Human Preferences](part_2_finetuning_lms_to_human_preferences/RLHF.ipynb)
+
+#### Details
+
+* Date: 14 March, 2024
+* Speaker: [Abhor Gupta](https://in.linkedin.com/in/abhor-gupta-565386145)
+* Location: [Infocusp Innovations LLP](https://www.infocusp.com/)
+
+#### Material
+
+* Recording: TODO
+
+### Part 3: LLM Training Frameworks
+
+Coming soon...
diff --git a/session_4/part_2_finetuning_lms_to_human_preferences/RLHF.ipynb b/session_4/part_2_finetuning_lms_to_human_preferences/RLHF.ipynb
new file mode 100644
index 0000000..3d261b9
--- /dev/null
+++ b/session_4/part_2_finetuning_lms_to_human_preferences/RLHF.ipynb
@@ -0,0 +1,1535 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "321adccc",
+ "metadata": {},
+ "source": [
+ "# RLHF - An Independent Illustration"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b5085966",
+ "metadata": {},
+ "source": [
+ "Reinforcement learning from human feedback (RLHF) is a transformative technique that enables us to fine-tune large language models (LLMs) or transformer-based models for improved alignment with our intended goals. This approach goes beyond the standard techniques that train LLMs on massive volumes of text data. RLHF uses human feedback to teach LLMs how to better adhere to our preferences and values."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "119f232e",
+ "metadata": {},
+ "source": [
+ "There are several very well written blogs on the topic - [here](https://medium.com/towards-generative-ai/reward-model-training-2209d1befb5f), [here](https://medium.com/@madhur.prashant7/rlhf-reward-model-ppo-on-llms-dfc92ec3885f) and [here](https://huggingface.co/blog/rlhf). I am especially fond of the one written by Chip Huyen [here](https://huyenchip.com/2023/05/02/rlhf.html). **The intention behind writing this is to understand RLHF using a simple and _mostly_ self-contained implementation to solve a demonstrative problem.** Let it be sufficiently trivial that we may open up our model and visually observe some effects of RLHF using different techniques. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "01c86337",
+ "metadata": {},
+ "source": [
+ "## Overview"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c9b868df",
+ "metadata": {},
+ "source": [
+ "Let us first go over some basics."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "514c9112",
+ "metadata": {},
+ "source": [
+ "### Training LLMs"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ab3275a8",
+ "metadata": {},
+ "source": [
+ "Can't help but love this _beautiful_ depiction of RLHF among the broader spectrum of an LLM's training, by twitter.com/anthrupad. \n",
+ "\n",
+ "![](https://huyenchip.com/assets/pics/rlhf/2-shoggoth.jpg)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5fffa9f4",
+ "metadata": {},
+ "source": [
+ "The image above shows the different methods of training an LLM, their \"size\" in terms of the space of outputs they represent and their \"quality\" in terms of their social acceptance to humans:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "e728ca93",
+ "metadata": {},
+ "source": [
+ "1. **Unsupervised Learning**: _Train an LLM on a massive corpus of raw text; this teaches the LLM a language - the fundamentals of its structure, grammer and relationship between words._ In terms of its objective, the LLM is trained to predict the next word in a context. \n",
+ "But! Though an LLM may know a language, it doesn't necessarily know how to converse. In its space of outputs, it is aware of what it _can_ do, but not necessarily what it _should_ do. It is like the Shoggoth, massive but ugly. \n",
+ "2. **Supervised Fine-tuning**: _Tailor the LLM to specific tasks like translation, question-answering, or summarization._ Here, the LLM is trained on a set of input-output pairs demonstrating the task. \n",
+ "Following the example from the point above, this is akin to teaching the LLM how to converse. Its output space here is refined to answer in specific ways, perhaps with domain specific know-how, or in accordance to a particular task. This is like the deformed human face, you'll accept it but it's not necessarily very pleasing. \n",
+ "3. **RLHF**: _Refine the LLM's output to better align with human values, preferences, and safety guidelines._ The training here involves giving feedback signals on the LLM's output to guide it to some desired behavior. \n",
+ "Following the same context from (1) and (2), after it has learnt language and knows how to converse, it learns to adhere to the social norms. Within its output space, this is the refinement that narrows down the conversation ability of the LLM to answer in a way that pleases its general reader - ethical speech, truthful statements, intelligent use of vocabulary etc. It is the smiley face that you want to talk to. :)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f50c1d47",
+ "metadata": {},
+ "source": [
+ "For the scope of this notebook, we will only be exploring RLHF. Supervised training will be a part - though it is more a requirement for the sake of thoroughness, than an intented guide on the topic. Therefore, I'll be using a very simple supervised pretraining that is closer to the description of supervised fine-tuning above, than unsupervised learning."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4d8b0884",
+ "metadata": {},
+ "source": [
+ "### RLHF components"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "de807a3d",
+ "metadata": {},
+ "source": [
+ "A complete RLHF pipeline requires the following components:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f5a40a2d",
+ "metadata": {},
+ "source": [
+ "1. **A pre-trained base model**: We begin with a pre-trained LLM. This is a powerful language model that has already learned the intricacies of language structure from vast amounts of text data. This may be followed by supervised fine-tuning to attune the LLM to a specific task like question-answering or summarization. \n",
+ "2. **Training a reward model from human feedback**: We then create a \"reward model\" specifically designed to capture human preferences. This involves gathering human feedback on various LLM outputs, where people rate the responses based on their desired qualities like helpfulness, safety, and adherence to instructions. By analyzing this feedback, the reward model learns to assign scores to future LLM responses, essentially mimicking human judgment.\n",
+ "3. **Fine tuning using Reinforcement Learning**: Finally, we put the LLM and the reward model to work together. When presented with a prompt, the LLM generates multiple potential responses. Each response is then analyzed by the reward model, which assigns a score based on its learned understanding of human preferences. Finally, a reinforcement learning algorithm like PPO uses these scores to fine-tune the LLM's internal parameters. Responses that received higher scores become more likely to be generated in the future, while those with lower scores are gradually downplayed. This iterative process progressively aligns the LLM's outputs with human expectations and values."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "549a5801",
+ "metadata": {},
+ "source": [
+ "This pipeline effectively utilizes human feedback to bridge the gap between raw LLM capabilities and human-desired outcomes. It allows us to shape these powerful language models into not just masters of language, but also responsible and valuable tools aligned with our needs."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9709c5d5",
+ "metadata": {},
+ "source": [
+ "### Applications of RLHF"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d0881a0b",
+ "metadata": {},
+ "source": [
+ "The most prevelant example of RLHF being applied in AI is for text generation to align chatbots with human preferences ([InstructGPT](https://openai.com/research/instruction-following), [ChatGPT](https://openai.com/blog/chatgpt), [Gemini](https://blog.google/technology/ai/google-gemini-ai/) are famous examples). Similarly, RLHF has seen application in image generation as well ([ImageReward](https://arxiv.org/abs/2304.05977), [DPOK](https://arxiv.org/abs/2305.16381)). Though limited, some research groups have also explored its application in games ([DeepMind](https://deepmind.google/discover/blog/learning-through-human-feedback/) and [OpenAI](https://openai.com/research/learning-from-human-preferences)). \n",
+ "\n",
+ "Even though currently the applications of RLHF in AI are limited, the scope for RLHF is much wider. \n",
+ "\n",
+ "Do you use e-commerce websites like Amazon? Do you use Uber for requesting cabs? Do you use Google Maps for deciding which restaurant, bar or hospital to visit? You must have seen ratings for products, or people, or services, or food. You likely would have given some yourself. These are all examples of human feedback. And when these affect the product or service to comform to user satisfaction, it is also a form of RLHF. \n",
+ "\n",
+ "Take, for instance, cooking robots are a thing now ([Moley](https://www.moley.com/), [Nymble](https://www.eatwithnymble.com/)). For the food that is cooked by the robots based on some recipe, the recipe can be adjusted for duration of cooking, quantity of spices etc for user preference based on their feedback. Self-driving cars are also real now ([Waymo](https://waymo.com/), [Tesla](https://www.tesla.com/support/autopilot)). Based on customer's feedback, the ride be adjusted to be faster/slower, less jerky, smoother maneuverability."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bd574943",
+ "metadata": {},
+ "source": [
+ "In the next section, we will establish a small toy problem to solve using a tiny LLM. Then we will dive into each of the RLHF concepts in detail along with some code to establish an implementational understanding as well some nice visualizations to complement our findings."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "581953f1",
+ "metadata": {},
+ "source": [
+ "## Problem Statement"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0f11a388",
+ "metadata": {},
+ "source": [
+ "To keep the scale of things simple, let us work with a \"language\" of numbers. Our vocabulary consist of digits 0-9 as well as a special digit 10 that separates our input and output. \n",
+ "\n",
+ "Typically for large LLMs, the language training is followed by a task specialisation training like question-answering before moving on to RLHF. To keep things simple, we avoid differentiating between language training and task specialisation and do a supervised training once to get our base model. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "fee373ac",
+ "metadata": {},
+ "source": [
+ "### Language (supervised learning)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a4b32e14",
+ "metadata": {},
+ "source": [
+ "The structure of the language is that for the current output to be generated, one of the last four digits (in the whole sequence of input+output) is chosen and its increment modulo 10 is outputted.\n",
+ "\n",
+ "Given $a_1, a_2, ..., a_{n-1}, a_n$, $\\forall n > 4$,\n",
+ "$$a'_{n+1} \\sim \\{a_{n-3}, a_{n-2}, a_{n-1}, a_{n}\\}$$\n",
+ "$$a_{n+1} = (a'_{n+1} + 1)\\ \\%\\ 10$$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "75fc02dd",
+ "metadata": {},
+ "source": [
+ "For example, \n",
+ "Input: 4, 5, 9, 1\n",
+ "\n",
+ "Generation: \n",
+ "4, 5, 9, 1, 10, **6** \n",
+ "4, 5, 9, 1, 10, 6, **2** \n",
+ "4, 5, 9, 1, 10, 6, 2, **7** \n",
+ "4, 5, 9, 1, 10, 6, 2, 7, **8**\n",
+ "\n",
+ "The underlined digits are the sampling set for the output. The digit marked in red is the digit sampled. Finally, the digit bolded at the end of the sequence is generated as the increment of the sampled digit."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "cf00c517",
+ "metadata": {},
+ "source": [
+ "### Alignment (RLHF)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "605ee56b",
+ "metadata": {},
+ "source": [
+ "Now we need a \"preference\" to incorporate. Mathematically, we wish to adjust the probability of some generation rule learned during the previous step.\n",
+ "\n",
+ "For this toy example, let's change only the generation of the first output token to be the increment of the last input token.\n",
+ "\n",
+ "That is, given $a_1, a_2, ..., a_{n-1}, a_n$, $\\forall n > 4$, \n",
+ "$$\n",
+ " a_{n+1}= \n",
+ "\\begin{cases}\n",
+ " a_n + 1,& \\text{if } {a_{n+1}} = y_1\\\\\n",
+ " (a'_{n+1} + 1)\\ \\%\\ 10, & \\text{otherwise}\n",
+ "\\end{cases}\n",
+ "$$\n",
+ "\n",
+ "Where $y_1$ is the first output token."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3d1e59b8",
+ "metadata": {},
+ "source": [
+ "Considering the same example as above, \n",
+ "Input: 4, 5, 9, 1\n",
+ "\n",
+ "Generation: \n",
+ "4, 5, 9, 1, 10, **2** (notice the change in underline) \n",
+ "4, 5, 9, 1, 10, 2, **2** \n",
+ "4, 5, 9, 1, 10, 2, 2, **3\n",
+ "** \n",
+ "4, 5, 9, 1, 10, 2, 2, 3, **4**\n",
+ "\n",
+ "For the first generation step, the model will only sample from the last digit and continue the original rule thereafter. Notice that except for the first generation step, the rest of the outputs are sampled from the same positions as the earlier example, yet the entire sequence has changed. Thus, though we wish to preserve the rule for the rest of the outputs, the actual outputs are not independent of the first output. Therefore, this small change in the output of a single token can have a cascading effect and lead to very different generations. \n",
+ "\n",
+ "This is in line with the spirit of RLHF, where say, if we want to reduce the toxicity, reducing the probability of toxic words will have a cascading effect and we do not need to affect the probability of several thousands of unrelated words."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f4178080",
+ "metadata": {},
+ "source": [
+ "## Code and Commentary"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "151d002f",
+ "metadata": {},
+ "source": [
+ "Before RLHF: _Enough talking, show me the code!_ \n",
+ "After RLHF: _You've explained what we're doing here well enough. We would like to move on to the implementational details._ \n",
+ "\n",
+ "😉"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "beca59c0",
+ "metadata": {},
+ "source": [
+ "### Supervised pre-training"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a2ba0080",
+ "metadata": {},
+ "source": [
+ "First we learn the language using supervised learning. I'm using Karpathy's [minGPT](https://github.com/karpathy/minGPT/tree/master) for the LLM and supervised training. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "338dbd44",
+ "metadata": {},
+ "source": [
+ "![](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/rlhf/pretraining.png)\n",
+ "\n",
+ "Source: [HuggingFace - RLHF blog](https://huggingface.co/blog/rlhf)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "08b9ae9e",
+ "metadata": {},
+ "source": [
+ "_Imports --_"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "991285e6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import torch\n",
+ "from torch.utils.data import Dataset\n",
+ "from torch.utils.data.dataloader import DataLoader\n",
+ "from mingpt.utils import set_seed\n",
+ "import numpy as np\n",
+ "set_seed(3407)\n",
+ "\n",
+ "device = 'cuda' if torch.cuda.is_available() else 'cpu' "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d6bde156",
+ "metadata": {},
+ "source": [
+ "_Hyperparams for size of vocab and length of input --_"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "125ad91b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "VOCAB_SIZE = 10\n",
+ "INPUT_SIZE = 4"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "af08cdc7",
+ "metadata": {},
+ "source": [
+ "_Class for generating training pairs for supervised language learning --_"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "2bab82cc",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class SupervisedDataset(Dataset):\n",
+ " \"\"\" \n",
+ " Problem: Look at last 4 digits and sample one of them to output its increment. \n",
+ " \n",
+ " Input: 3 8 1 4 \n",
+ " Possible ouputs: 2 2 3 5 || 5 9 6 0 || 2 9 5 3 etc\n",
+ " \n",
+ " Which will feed into the transformer concatenated as:\n",
+ " input: 3 8 1 4 S 2 2 3\n",
+ " output: I I I I 2 2 3 5\n",
+ " where I is \"ignore\", and S is the separation token\n",
+ " \"\"\"\n",
+ "\n",
+ " def __init__(self):\n",
+ " self.EOS = VOCAB_SIZE\n",
+ " \n",
+ " def __len__(self):\n",
+ " return 10000 # ...\n",
+ " \n",
+ " def get_vocab_size(self):\n",
+ " return VOCAB_SIZE+1 # normal vocab + serparation token\n",
+ "\n",
+ " def __getitem__(self, idx):\n",
+ " inputs = torch.randint(VOCAB_SIZE, size=(INPUT_SIZE,), dtype=torch.long)\n",
+ " ouptputs = []\n",
+ " \n",
+ " # Create input output pairs\n",
+ " inp = np.random.randint(VOCAB_SIZE, size=(INPUT_SIZE,)).tolist()\n",
+ " sol = []\n",
+ " for i in range(INPUT_SIZE):\n",
+ " sol.append((np.random.choice(inp[i:] + sol) + 1)%10)\n",
+ " \n",
+ " # concatenate the problem specification and the solution\n",
+ " cat = torch.Tensor(inp + [self.EOS] + sol).long()\n",
+ "\n",
+ " # the inputs to the transformer will be the offset sequence\n",
+ " x = cat[:-1].clone()\n",
+ " y = cat[1:].clone()\n",
+ "\n",
+ " # we only want to predict at output locations, mask out the loss at the input locations\n",
+ " y[:INPUT_SIZE] = -1\n",
+ " return x, y"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a7f95daa",
+ "metadata": {},
+ "source": [
+ "_Looking at one sample --_"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "ca079295",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(tensor([ 4, 3, 7, 6, 10, 8, 4, 8]),\n",
+ " tensor([-1, -1, -1, -1, 8, 4, 8, 5]))"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Supervised dataset\n",
+ "st_dataset = SupervisedDataset()\n",
+ "st_dataset[0]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0b27620d",
+ "metadata": {},
+ "source": [
+ "_Create a GPT instance --_"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "a6e0d707",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from mingpt.model import GPT\n",
+ "\n",
+ "def get_model(block_size, vocab_size, output_size=None):\n",
+ " '''\n",
+ " block_size = length of input\n",
+ " vocab_size = digits allowed\n",
+ " output_size = length of output\n",
+ " '''\n",
+ " if output_size is None:\n",
+ " output_size = vocab_size\n",
+ " model_config = GPT.get_default_config()\n",
+ " model_config.model_type = 'gpt-nano'\n",
+ " model_config.vocab_size = vocab_size\n",
+ " model_config.block_size = block_size\n",
+ " model_config.output_size = output_size\n",
+ " model = GPT(model_config)\n",
+ " return model\n",
+ "\n",
+ "st_model = get_model(INPUT_SIZE*2, st_dataset.get_vocab_size())"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "aa9a1014",
+ "metadata": {},
+ "source": [
+ "Set up training --"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "d8e8906b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# create a Trainer object\n",
+ "from mingpt.trainer import Trainer\n",
+ "\n",
+ "train_config = Trainer.get_default_config()\n",
+ "train_config.learning_rate = 5e-4 # the model we're using is so small that we can go a bit faster\n",
+ "train_config.max_iters = 5000\n",
+ "train_config.num_workers = 0\n",
+ "trainer = Trainer(train_config, st_model, st_dataset)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "33ace95c",
+ "metadata": {},
+ "source": [
+ "Training --"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "11318c89",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def batch_end_callback(trainer):\n",
+ " if trainer.iter_num % 100 == 0:\n",
+ " print(f\"iter_dt {trainer.iter_dt * 1000:.2f}ms; iter {trainer.iter_num}: train loss {trainer.loss.item():.5f}\")\n",
+ "trainer.set_callback('on_batch_end', batch_end_callback)\n",
+ "\n",
+ "trainer.run()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d5effd22",
+ "metadata": {},
+ "source": [
+ "Loss stabilizes around 1.25. It cannot go lower because we don't have fixed outputs. We are trying to have a probability distribution such that multiple outputs have equal probability of being sampled."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "10fb240f",
+ "metadata": {},
+ "source": [
+ "Now let us give the model a random input and see what the model has learned to generate as the next token --"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "fb947447",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Input: tensor([[ 0, 2, 8, 6, 10]])\n",
+ "Possible outputs: tensor([1, 3, 7, 9])\n"
+ ]
+ }
+ ],
+ "source": [
+ "x, _ = st_dataset[0]\n",
+ "x = x[:INPUT_SIZE+1].reshape(1, -1)\n",
+ "print(\"Input:\", x)\n",
+ "print(\"Possible outputs:\", torch.arange(11)[torch.nn.Softmax(dim=-1)(st_model(x)[0])[0, -1] > 0.1])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "beb3aaa1",
+ "metadata": {},
+ "source": [
+ "Works like a charm!"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b76344b3",
+ "metadata": {},
+ "source": [
+ "Let's save the model too. We'll need to load it later before we start the RL training --"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "53b8edb4",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Save model weights\n",
+ "torch.save(st_model.state_dict(), \"models/minimal_RLHF_basic_supervised.pt\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0626b1f5",
+ "metadata": {},
+ "source": [
+ "### Training a reward model"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ba50428c",
+ "metadata": {},
+ "source": [
+ "Now we will train a reward model. \n",
+ "\n",
+ "The data required to train the reward model is collected as preferences in the format: \n",
+ "\\, \\, \\ \n",
+ "\n",
+ "The accepted and rejected responses are simply two difference generations by the supervised training model with human labels marking their preference among the two. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "48414a18",
+ "metadata": {},
+ "source": [
+ "![](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/rlhf/reward-model.png)\n",
+ "\n",
+ "Source: [HuggingFace - RLHF blog](https://huggingface.co/blog/rlhf)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a6d93d11",
+ "metadata": {},
+ "source": [
+ "I don't have the money to hire humans to do this labeling and neither the time myself to do it. :) \n",
+ "So here's a dataset class that'll generate the required data for us--"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "id": "9f9ea8dc",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class PreferenceDataset(Dataset):\n",
+ " \"\"\"\n",
+ " Same as MyDataset, except this has output as where x and y are input output from MyDataset. y' is the output that is sampled \n",
+ " from preferred distribution - and is preferred over y. \n",
+ " \"\"\"\n",
+ " def __init__(self, dataset):\n",
+ " self.dataset = dataset\n",
+ " \n",
+ " def __len__(self):\n",
+ " return len(self.dataset)\n",
+ " \n",
+ " def get_vocab_size(self):\n",
+ " return self.dataset.get_vocab_size()\n",
+ " \n",
+ " def __getitem__(self, idx):\n",
+ " x, y = self.dataset[idx]\n",
+ " \n",
+ " _x = x[:INPUT_SIZE+1]\n",
+ " _y_reject = torch.concat([y[-INPUT_SIZE:], torch.Tensor([11]).long()])\n",
+ " _y_accept = _y_reject.clone()\n",
+ " \n",
+ " # Replace first element with increment of last digit in input\n",
+ " _y_accept[0] = (_x[INPUT_SIZE-1] + 1) % 10\n",
+ " if _y_accept[0] == _y_reject[0]:\n",
+ " _y_reject[0] = (_y_accept[0] - np.random.randint(1, 10)) % 10\n",
+ " \n",
+ " return _x, _y_accept, _y_reject\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "8994ee3f",
+ "metadata": {},
+ "source": [
+ "Let's look at one datapoint in this dataset --"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "id": "b5b1f23a",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(tensor([ 8, 0, 3, 4, 10]),\n",
+ " tensor([ 5, 4, 5, 5, 11]),\n",
+ " tensor([ 1, 4, 5, 5, 11]))"
+ ]
+ },
+ "execution_count": 17,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pf_dataset = PreferenceDataset(st_dataset)\n",
+ "pf_dataset[0]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a1bdf280",
+ "metadata": {},
+ "source": [
+ "The first tensor is the \\, the second is the \\ and the last is the \\. Notice the \\ and \\ only differ in their first digits. Unlike a usual RLHF pipeline where the pretrained model would be used to generate the outputs to be ranked for preference, here we artifically generate the data to look like this for our convenience."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5338f3c2",
+ "metadata": {},
+ "source": [
+ "Finally, it is time to train the reward model. For this we use the following loss function:\n",
+ "\n",
+ "$$loss = -log(\\sigma(R_{acc} - R_{rej}))$$\n",
+ "\n",
+ "Where $\\sigma$ is the sigmoid function, $R_{acc}$ and $R_{rej}$ are the rewards obtained by passing the \\ and \\ through the reward model. The intuition behind the loss function is to increase the difference between the rewards of the two types of responses. This becomes clear by looking at the training plot below."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "9997e06a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tqdm\n",
+ "\n",
+ "# Hyperparams\n",
+ "epochs = 40\n",
+ "batch_size = 64\n",
+ "rm_lr = 1e-4\n",
+ "acc_list = []\n",
+ "rej_list = []\n",
+ "\n",
+ "# Dataloader\n",
+ "train_loader = DataLoader(pf_dataset, shuffle=False, batch_size=batch_size)\n",
+ "\n",
+ "# Optimizer\n",
+ "reward_model = get_model(block_size=INPUT_SIZE*2+2, vocab_size=pf_dataset.get_vocab_size()+1, output_size=1)\n",
+ "rm_opt = torch.optim.Adam(reward_model.parameters(), lr=rm_lr)\n",
+ "\n",
+ "# Training\n",
+ "reward_model.train()\n",
+ "for ep_i in tqdm.tqdm(range(epochs)):\n",
+ " for b_i, batch in enumerate(train_loader):\n",
+ " inp, acc, rej = batch\n",
+ " \n",
+ " # Get rewards\n",
+ " r_acc = reward_model(torch.concat([inp, acc], dim=-1))[0][:, -1, 0]\n",
+ " r_rej = reward_model(torch.concat([inp, rej], dim=-1))[0][:, -1, 0]\n",
+ " \n",
+ " # Loss and backprop\n",
+ " loss = -torch.log(torch.nn.Sigmoid()(r_acc-r_rej)).mean()\n",
+ " rm_opt.zero_grad()\n",
+ " loss.backward()\n",
+ " rm_opt.step()\n",
+ " \n",
+ " # Save for plotting\n",
+ " acc_list.append(r_acc.mean().detach().item())\n",
+ " rej_list.append(r_rej.mean().detach().item())\n",
+ " \n",
+ "# print(ep_i, np.mean(acc_list[-20:]), np.mean(rej_list[-20:]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "id": "a37b9c0f",
+ "metadata": {
+ "scrolled": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Text(0, 0.5, 'Reward (moving average)')"
+ ]
+ },
+ "execution_count": 19,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ "