{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "7cfd02ff",
   "metadata": {},
   "source": [
    "# Своя модель: меняем манеру ответа\n",
    "\n",
    "Основной путь: NVIDIA, Python 3.11, Qwen2.5-1.5B-Instruct и 512 готовых диалогов. Проходим ячейки по порядку в чистом ядре. Установка выполняется один раз, после неё перезапускаем ядро. Контрольный вопрос не содержит инструкции о стиле."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aaa1f0b8",
   "metadata": {},
   "source": [
    "## Установим библиотеки\n",
    "\n",
    "%pip устанавливает пакеты в Python текущего ядра. Первая команда берёт сборку PyTorch с CUDA 12.1 из официального репозитория. Вторая устанавливает согласованный набор библиотек курса. После установки перезапустите ядро через Kernel → Restart Kernel. Установка выполняется один раз для окружения."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "a80fbeca",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-01T23:24:09.211828Z",
     "iopub.status.busy": "2026-10-01T23:24:09.211322Z",
     "iopub.status.idle": "2026-10-01T23:24:12.225259Z",
     "shell.execute_reply": "2026-10-01T23:24:12.224752Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Looking in indexes: https://download.pytorch.org/whl/cu121\n",
      "Requirement already satisfied: torch==2.5.1 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (2.5.1+cu121)\n",
      "Requirement already satisfied: filelock in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from torch==2.5.1) (3.20.0)\n",
      "Requirement already satisfied: typing-extensions>=4.8.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from torch==2.5.1) (4.15.0)\n",
      "Requirement already satisfied: networkx in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from torch==2.5.1) (3.6.1)\n",
      "Requirement already satisfied: jinja2 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from torch==2.5.1) (3.1.6)\n",
      "Requirement already satisfied: fsspec in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from torch==2.5.1) (2025.12.0)\n",
      "Requirement already satisfied: sympy==1.13.1 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from torch==2.5.1) (1.13.1)\n",
      "Requirement already satisfied: mpmath<1.4,>=1.1.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from sympy==1.13.1->torch==2.5.1) (1.3.0)\n",
      "Requirement already satisfied: MarkupSafe>=2.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from jinja2->torch==2.5.1) (2.1.5)\n",
      "Note: you may need to restart the kernel to use updated packages.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n",
      "[notice] A new release of pip is available: 26.0.1 -> 26.2.1\n",
      "[notice] To update, run: C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\python.exe -m pip install --upgrade pip\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: transformers==4.57.1 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (4.57.1)\n",
      "Requirement already satisfied: datasets==4.8.3 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (4.8.3)\n",
      "Requirement already satisfied: peft==0.17.1 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (0.17.1)\n",
      "Requirement already satisfied: trl==0.22.2 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (0.22.2)\n",
      "Requirement already satisfied: accelerate==1.13.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (1.13.0)\n",
      "Requirement already satisfied: huggingface-hub==0.36.2 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (0.36.2)\n",
      "Requirement already satisfied: safetensors==0.7.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (0.7.0)\n",
      "Requirement already satisfied: filelock in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from transformers==4.57.1) (3.20.0)\n",
      "Requirement already satisfied: numpy>=1.17 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from transformers==4.57.1) (2.3.5)\n",
      "Requirement already satisfied: packaging>=20.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from transformers==4.57.1) (25.0)\n",
      "Requirement already satisfied: pyyaml>=5.1 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from transformers==4.57.1) (6.0.3)\n",
      "Requirement already satisfied: regex!=2019.12.17 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from transformers==4.57.1) (2026.1.15)\n",
      "Requirement already satisfied: requests in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from transformers==4.57.1) (2.32.5)\n",
      "Requirement already satisfied: tokenizers<=0.23.0,>=0.22.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from transformers==4.57.1) (0.22.2)\n",
      "Requirement already satisfied: tqdm>=4.27 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from transformers==4.57.1) (4.67.3)\n",
      "Requirement already satisfied: fsspec>=2023.5.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from huggingface-hub==0.36.2) (2025.12.0)\n",
      "Requirement already satisfied: typing-extensions>=3.7.4.3 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from huggingface-hub==0.36.2) (4.15.0)\n",
      "Requirement already satisfied: pyarrow>=21.0.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from datasets==4.8.3) (23.0.1)\n",
      "Requirement already satisfied: dill<0.4.2,>=0.3.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from datasets==4.8.3) (0.4.1)\n",
      "Requirement already satisfied: pandas in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from datasets==4.8.3) (3.0.1)\n",
      "Requirement already satisfied: httpx<1.0.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from datasets==4.8.3) (0.28.1)\n",
      "Requirement already satisfied: xxhash in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from datasets==4.8.3) (3.6.0)\n",
      "Requirement already satisfied: multiprocess<0.70.20 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from datasets==4.8.3) (0.70.19)\n",
      "Requirement already satisfied: psutil in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from peft==0.17.1) (7.2.2)\n",
      "Requirement already satisfied: torch>=1.13.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from peft==0.17.1) (2.5.1+cu121)\n",
      "Requirement already satisfied: aiohttp!=4.0.0a0,!=4.0.0a1 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from fsspec[http]<=2026.2.0,>=2023.1.0->datasets==4.8.3) (3.13.3)\n",
      "Requirement already satisfied: anyio in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from httpx<1.0.0->datasets==4.8.3) (4.12.1)\n",
      "Requirement already satisfied: certifi in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from httpx<1.0.0->datasets==4.8.3) (2026.1.4)\n",
      "Requirement already satisfied: httpcore==1.* in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from httpx<1.0.0->datasets==4.8.3) (1.0.9)\n",
      "Requirement already satisfied: idna in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from httpx<1.0.0->datasets==4.8.3) (3.11)\n",
      "Requirement already satisfied: h11>=0.16 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from httpcore==1.*->httpx<1.0.0->datasets==4.8.3) (0.16.0)\n",
      "Requirement already satisfied: aiohappyeyeballs>=2.5.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2026.2.0,>=2023.1.0->datasets==4.8.3) (2.6.1)\n",
      "Requirement already satisfied: aiosignal>=1.4.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2026.2.0,>=2023.1.0->datasets==4.8.3) (1.4.0)\n",
      "Requirement already satisfied: attrs>=17.3.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2026.2.0,>=2023.1.0->datasets==4.8.3) (26.1.0)\n",
      "Requirement already satisfied: frozenlist>=1.1.1 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2026.2.0,>=2023.1.0->datasets==4.8.3) (1.8.0)\n",
      "Requirement already satisfied: multidict<7.0,>=4.5 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2026.2.0,>=2023.1.0->datasets==4.8.3) (6.7.1)\n",
      "Requirement already satisfied: propcache>=0.2.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2026.2.0,>=2023.1.0->datasets==4.8.3) (0.4.1)\n",
      "Requirement already satisfied: yarl<2.0,>=1.17.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2026.2.0,>=2023.1.0->datasets==4.8.3) (1.23.0)\n",
      "Requirement already satisfied: charset_normalizer<4,>=2 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from requests->transformers==4.57.1) (3.4.4)\n",
      "Requirement already satisfied: urllib3<3,>=1.21.1 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from requests->transformers==4.57.1) (2.6.3)\n",
      "Requirement already satisfied: networkx in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from torch>=1.13.0->peft==0.17.1) (3.6.1)\n",
      "Requirement already satisfied: jinja2 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from torch>=1.13.0->peft==0.17.1) (3.1.6)\n",
      "Requirement already satisfied: sympy==1.13.1 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from torch>=1.13.0->peft==0.17.1) (1.13.1)\n",
      "Requirement already satisfied: mpmath<1.4,>=1.1.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from sympy==1.13.1->torch>=1.13.0->peft==0.17.1) (1.3.0)\n",
      "Requirement already satisfied: colorama in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from tqdm>=4.27->transformers==4.57.1) (0.4.6)\n",
      "Requirement already satisfied: MarkupSafe>=2.0 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from jinja2->torch>=1.13.0->peft==0.17.1) (2.1.5)\n",
      "Requirement already satisfied: python-dateutil>=2.8.2 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from pandas->datasets==4.8.3) (2.9.0.post0)\n",
      "Requirement already satisfied: tzdata in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from pandas->datasets==4.8.3) (2025.3)\n",
      "Requirement already satisfied: six>=1.5 in C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\Lib\\site-packages (from python-dateutil>=2.8.2->pandas->datasets==4.8.3) (1.17.0)\n",
      "Note: you may need to restart the kernel to use updated packages.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n",
      "[notice] A new release of pip is available: 26.0.1 -> 26.2.1\n",
      "[notice] To update, run: C:\\Users\\danii\\anaconda3\\envs\\torchcu121\\python.exe -m pip install --upgrade pip\n"
     ]
    }
   ],
   "source": [
    "%pip install torch==2.5.1 --index-url https://download.pytorch.org/whl/cu121\n",
    "%pip install transformers==4.57.1 datasets==4.8.3 peft==0.17.1 trl==0.22.2 accelerate==1.13.0 huggingface-hub==0.36.2 safetensors==0.7.0"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b11a7007",
   "metadata": {},
   "source": [
    "## Проверим видеокарту\n",
    "\n",
    "torch.__version__ показывает сборку. cuda.is_available() проверяет, может ли этот Python использовать NVIDIA. assert останавливает основной путь с понятным сообщением, если CUDA недоступна. Номер 0 обозначает первую доступную видеокарту."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "4cfe5c62",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-01T23:24:12.233277Z",
     "iopub.status.busy": "2026-10-01T23:24:12.232279Z",
     "iopub.status.idle": "2026-10-01T23:24:14.744292Z",
     "shell.execute_reply": "2026-10-01T23:24:14.743284Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "PyTorch: 2.5.1+cu121\n",
      "Видеокарта: NVIDIA GeForce RTX 3090\n"
     ]
    }
   ],
   "source": [
    "# PyTorch выполняет вычисления модели и проверяет доступ к CUDA.\n",
    "import torch\n",
    "\n",
    "print(\"PyTorch:\", torch.__version__)\n",
    "assert torch.cuda.is_available(), \"CUDA недоступна: см. раздел помощи\"\n",
    "print(\"Видеокарта:\", torch.cuda.get_device_name(0))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cb5274ef",
   "metadata": {},
   "source": [
    "## Выберем модель\n",
    "\n",
    "Слева от / — владелец репозитория, справа — его имя. Строка совпадает с концом адреса huggingface.co/Qwen/Qwen2.5-1.5B-Instruct. Для другой модели копируют её собственный идентификатор. Здесь пока выбирается только модель."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "bbf6d5aa",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-01T23:24:14.750816Z",
     "iopub.status.busy": "2026-10-01T23:24:14.750816Z",
     "iopub.status.idle": "2026-10-01T23:24:14.755033Z",
     "shell.execute_reply": "2026-10-01T23:24:14.755033Z"
    }
   },
   "outputs": [],
   "source": [
    "# Идентификатор копируется из заголовка страницы на Hugging Face.\n",
    "model_id = \"Qwen/Qwen2.5-1.5B-Instruct\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "361909eb",
   "metadata": {},
   "source": [
    "## Загрузим готовый генератор текста\n",
    "\n",
    "text-generation — задача продолжения текста. model указывает репозиторий. device=0 размещает модель на первой NVIDIA. dtype=\"auto\" использует формат весов из конфигурации; у выбранной Qwen это bfloat16, формат с двумя байтами на число. Внутренний алгоритм внимания и служебные токены выбирает библиотека."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6a042ba2",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-01T23:24:14.761554Z",
     "iopub.status.busy": "2026-10-01T23:24:14.761554Z",
     "iopub.status.idle": "2026-10-01T23:24:25.556994Z",
     "shell.execute_reply": "2026-10-01T23:24:25.555986Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Device set to use cuda:0\n"
     ]
    }
   ],
   "source": [
    "# pipeline объединяет модель, токенизатор и генерацию текста.\n",
    "from transformers import pipeline\n",
    "\n",
    "chat = pipeline(\n",
    "    \"text-generation\", model=model_id, device=0, dtype=\"auto\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f1da8fc",
   "metadata": {},
   "source": [
    "## Посмотрим на вход модели\n",
    "\n",
    "Токенизатор переводит строку в идентификаторы фрагментов текста. input_ids — список этих чисел, decode выполняет обратное преобразование. Числа обозначают элементы словаря, а не оценки смысла слов."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "49512ea9",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-01T23:24:25.563509Z",
     "iopub.status.busy": "2026-10-01T23:24:25.563509Z",
     "iopub.status.idle": "2026-10-01T23:24:25.570207Z",
     "shell.execute_reply": "2026-10-01T23:24:25.569687Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[9707, 11, 23915, 0]\n",
      "Hello, captain!\n"
     ]
    }
   ],
   "source": [
    "# Токенизатор уже загружен вместе с моделью.\n",
    "ids = chat.tokenizer(\"Hello, captain!\")[\"input_ids\"]\n",
    "print(ids)\n",
    "print(chat.tokenizer.decode(ids))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3879c53f",
   "metadata": {},
   "source": [
    "## Зададим вопрос\n",
    "\n",
    "role=\"user\" обозначает пользователя, content содержит вопрос. Pipeline сам оформляет диалог для Qwen. max_new_tokens ограничивает продолжение 100 токенами, do_sample=False отключает случайную выборку. Из результата берём первый диалог и последнее сообщение — ответ помощника. Теперь ask(\"вопрос\") вызывается одной строкой. before сохраняет исходный ответ."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "ac8f2a3c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-01T23:24:25.576339Z",
     "iopub.status.busy": "2026-10-01T23:24:25.576339Z",
     "iopub.status.idle": "2026-10-01T23:24:33.578448Z",
     "shell.execute_reply": "2026-10-01T23:24:33.577438Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "The following generation flags are not valid and may be ignored: ['temperature', 'top_p', 'top_k']. Set `TRANSFORMERS_VERBOSITY=info` for more details.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Organizing your study time effectively is crucial for achieving academic success and maintaining productivity. Here are some tips to help you manage your study sessions more efficiently:\n",
      "\n",
      "1. **Set Clear Goals**: Define what you want to achieve with each session of studying. Break down larger tasks into smaller, manageable goals.\n",
      "\n",
      "2. **Create a Schedule**: Use a planner or digital calendar to schedule specific times for studying. Stick to this schedule as much as possible to maintain consistency.\n",
      "\n",
      "3. **Prioritize Tasks**: Identify the\n"
     ]
    }
   ],
   "source": [
    "# Эта функция избавляет от повторения формата диалога.\n",
    "def ask(question):\n",
    "    reply = chat(\n",
    "        [{\"role\": \"user\", \"content\": question}],\n",
    "        max_new_tokens=100, do_sample=False\n",
    "    )\n",
    "    return reply[0][\"generated_text\"][-1][\"content\"]\n",
    "\n",
    "question = \"How can I organize my study time?\"\n",
    "before = ask(question)\n",
    "print(before)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "c090be9b",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-01T23:24:33.591511Z",
     "iopub.status.busy": "2026-10-01T23:24:33.588988Z",
     "iopub.status.idle": "2026-10-01T23:25:08.283900Z",
     "shell.execute_reply": "2026-10-01T23:25:08.282891Z"
    }
   },
   "outputs": [],
   "source": [
    "# Дополнительные вопросы контрольного прогона, выбраны до обучения.\n",
    "questions = [question, \"Explain what a neural network is in two sentences.\",\n",
    "             \"Write a birthday greeting for a friend.\", \"Why is the sky blue?\",\n",
    "             \"Скажи, как лучше учиться программированию?\"]\n",
    "baseline = [ask(q) for q in questions]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ec426ad9",
   "metadata": {},
   "source": [
    "## Возьмём готовые диалоги\n",
    "\n",
    "load_dataset открывает набор как таблицу. train — имя раздела, а не команда начала обучения. В каждой строке messages — реплики. Фильтр оставляет короткие вопросы, select берёт первые 512 подходящих строк. Ответы не переписываются, стиль не добавляется вручную."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "df2644d7",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-01T23:25:08.292909Z",
     "iopub.status.busy": "2026-10-01T23:25:08.291907Z",
     "iopub.status.idle": "2026-10-01T23:25:12.791147Z",
     "shell.execute_reply": "2026-10-01T23:25:12.790141Z"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "d03b55c809f3435293061830266b9839",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Filter:   0%|          | 0/9985 [00:00<?, ? examples/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'messages': [{'content': 'Create a thank you card to an organization that helped your community in a time of crisis.', 'role': 'user'}, {'content': \"Ahoy, Mateys! \\n\\nWe, the scurvy dogs of [Your Community Name], be hoistin' the Jolly Roger of gratitude for yer generous assistance in our time of need. \\n\\nYer kindness be like a treasure chest full of doubloons to us, savin' our ship from the stormy seas of hardship. We be forever indebted to yer valiant efforts, aye! \\n\\nMay yer sails be full, yer grog be strong, and yer treasure chests overflow with gold! We be eternally grateful, mateys!\\n\\nYours in plunder and good cheer,\\n\\n[Your Name]\\n\", 'role': 'assistant'}]}\n"
     ]
    }
   ],
   "source": [
    "from datasets import load_dataset\n",
    "\n",
    "# В наборе уже есть вопросы и ответы в пиратском стиле.\n",
    "data = load_dataset(\"winglian/pirate-ultrachat-10k\", split=\"train\")\n",
    "\n",
    "# Возьмём 512 примеров с вопросами короче 300 символов.\n",
    "data = data.filter(lambda row: len(row[\"messages\"][0][\"content\"]) < 300)\n",
    "data = data.select(range(512))\n",
    "print(data[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3f03b06f",
   "metadata": {},
   "source": [
    "## Добавим обучаемую часть\n",
    "\n",
    "PEFT — библиотека экономного дообучения. LoRA добавляет небольшие обучаемые матрицы к преобразованиям модели. CAUSAL_LM обозначает предсказание следующего токена по предыдущим. Стандартная конфигурация PEFT для Qwen выбирает поддерживаемые слои; базовые веса остаются замороженными."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "5d84b1e6",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-01T23:25:12.799667Z",
     "iopub.status.busy": "2026-10-01T23:25:12.798667Z",
     "iopub.status.idle": "2026-10-01T23:25:12.989347Z",
     "shell.execute_reply": "2026-10-01T23:25:12.988829Z"
    }
   },
   "outputs": [],
   "source": [
    "from peft import LoraConfig\n",
    "\n",
    "# Для первого опыта используем стандартные настройки LoRA.\n",
    "adapter = LoraConfig(task_type=\"CAUSAL_LM\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc4de89f",
   "metadata": {},
   "source": [
    "## Зададим размер эксперимента\n",
    "\n",
    "SFT — обучение на примерах желаемого поведения. Здесь: 400 обновлений; learning_rate=0.0003 задаёт масштаб изменения; по 2 диалога обрабатываются за проход, 4 прохода накапливаются перед обновлением. Это 8 примеров на шаг. max_length ограничивает диалог 384 токенами, длинный хвост обрезается. output_dir — папка результатов, report_to=\"none\" отключает внешние сервисы журналирования. Остальные параметры берутся из выбранной версии TRL."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "7f4f92c0",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-01T23:25:13.001925Z",
     "iopub.status.busy": "2026-10-01T23:25:13.001419Z",
     "iopub.status.idle": "2026-10-01T23:25:13.159319Z",
     "shell.execute_reply": "2026-10-01T23:25:13.158314Z"
    }
   },
   "outputs": [],
   "source": [
    "from trl import SFTConfig, SFTTrainer\n",
    "\n",
    "settings = SFTConfig(\n",
    "    output_dir=\"pirate-output\",\n",
    "    max_steps=400, learning_rate=3e-4,\n",
    "    per_device_train_batch_size=2, gradient_accumulation_steps=4,\n",
    "    max_length=384,\n",
    "    report_to=\"none\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a74d6089",
   "metadata": {},
   "source": [
    "## Запустим дообучение\n",
    "\n",
    "Передаём загруженную модель, её токенизатор, диалоги, LoRA и настройки. SFTTrainer готовит последовательности, собирает порции данных, вычисляет ошибку и обновляет параметры адаптера. train() запускает цикл. Прогресс появляется в выводе ячейки; loss — ошибка предсказания токенов, а не доля правильных ответов."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "e3f17318",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-01T23:25:13.170350Z",
     "iopub.status.busy": "2026-10-01T23:25:13.170350Z",
     "iopub.status.idle": "2026-10-01T23:35:13.399868Z",
     "shell.execute_reply": "2026-10-01T23:35:13.399357Z"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "5894f1ed734f49e5b258565ef64be531",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Tokenizing train dataset:   0%|          | 0/512 [00:00<?, ? examples/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "4f81b2c2ccfa491cb1414aff69ae8f74",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Truncating train dataset:   0%|          | 0/512 [00:00<?, ? examples/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "The tokenizer has new PAD/BOS/EOS tokens that differ from the model config and generation config. The model config and generation config were aligned accordingly, being updated with the tokenizer's values. Updated tokens: {'bos_token_id': None, 'pad_token_id': 151643}.\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "    <div>\n",
       "      \n",
       "      <progress value='400' max='400' style='width:300px; height:20px; vertical-align: middle;'></progress>\n",
       "      [400/400 09:57, Epoch 6/7]\n",
       "    </div>\n",
       "    <table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       " <tr style=\"text-align: left;\">\n",
       "      <th>Step</th>\n",
       "      <th>Training Loss</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>10</td>\n",
       "      <td>2.195000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>20</td>\n",
       "      <td>1.972000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>30</td>\n",
       "      <td>1.871500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>40</td>\n",
       "      <td>1.814500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>50</td>\n",
       "      <td>1.738800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>60</td>\n",
       "      <td>1.597100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>70</td>\n",
       "      <td>1.614400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>80</td>\n",
       "      <td>1.612100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>90</td>\n",
       "      <td>1.598100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>100</td>\n",
       "      <td>1.519200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>110</td>\n",
       "      <td>1.532200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>120</td>\n",
       "      <td>1.553700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>130</td>\n",
       "      <td>1.537600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>140</td>\n",
       "      <td>1.521300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>150</td>\n",
       "      <td>1.477400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>160</td>\n",
       "      <td>1.511000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>170</td>\n",
       "      <td>1.458100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>180</td>\n",
       "      <td>1.511900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>190</td>\n",
       "      <td>1.531700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>200</td>\n",
       "      <td>1.495100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>210</td>\n",
       "      <td>1.461300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>220</td>\n",
       "      <td>1.404800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>230</td>\n",
       "      <td>1.444600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>240</td>\n",
       "      <td>1.512700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>250</td>\n",
       "      <td>1.510100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>260</td>\n",
       "      <td>1.443600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>270</td>\n",
       "      <td>1.465900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>280</td>\n",
       "      <td>1.448500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>290</td>\n",
       "      <td>1.404600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>300</td>\n",
       "      <td>1.478500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>310</td>\n",
       "      <td>1.442400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>320</td>\n",
       "      <td>1.447300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>330</td>\n",
       "      <td>1.435800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>340</td>\n",
       "      <td>1.447500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>350</td>\n",
       "      <td>1.450200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>360</td>\n",
       "      <td>1.456300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>370</td>\n",
       "      <td>1.403700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>380</td>\n",
       "      <td>1.444700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>390</td>\n",
       "      <td>1.400600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>400</td>\n",
       "      <td>1.427500</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table><p>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "TrainOutput(global_step=400, training_loss=1.539833769798279, metrics={'train_runtime': 598.9059, 'train_samples_per_second': 5.343, 'train_steps_per_second': 0.668, 'total_flos': 9205263906852864.0, 'train_loss': 1.539833769798279, 'epoch': 6.25})"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "trainer = SFTTrainer(\n",
    "    model=chat.model, processing_class=chat.tokenizer,\n",
    "    train_dataset=data, peft_config=adapter, args=settings\n",
    ")\n",
    "trainer.train()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "499890d4",
   "metadata": {},
   "source": [
    "## Посмотрим на ход обучения\n",
    "\n",
    "В log_history есть измерения loss и итоговая статистика. Берём записи с loss и печатаем шаг и усреднённую ошибку. График в лекции строится по такому журналу реального запуска; учебная анимация показана отдельно."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "d44db6d3",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-01T23:35:13.409389Z",
     "iopub.status.busy": "2026-10-01T23:35:13.408386Z",
     "iopub.status.idle": "2026-10-01T23:35:13.416077Z",
     "shell.execute_reply": "2026-10-01T23:35:13.415069Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10 2.195\n",
      "20 1.972\n",
      "30 1.871\n",
      "40 1.815\n",
      "50 1.739\n",
      "60 1.597\n",
      "70 1.614\n",
      "80 1.612\n",
      "90 1.598\n",
      "100 1.519\n",
      "110 1.532\n",
      "120 1.554\n",
      "130 1.538\n",
      "140 1.521\n",
      "150 1.477\n",
      "160 1.511\n",
      "170 1.458\n",
      "180 1.512\n",
      "190 1.532\n",
      "200 1.495\n",
      "210 1.461\n",
      "220 1.405\n",
      "230 1.445\n",
      "240 1.513\n",
      "250 1.51\n",
      "260 1.444\n",
      "270 1.466\n",
      "280 1.448\n",
      "290 1.405\n",
      "300 1.478\n",
      "310 1.442\n",
      "320 1.447\n",
      "330 1.436\n",
      "340 1.448\n",
      "350 1.45\n",
      "360 1.456\n",
      "370 1.404\n",
      "380 1.445\n",
      "390 1.401\n",
      "400 1.427\n"
     ]
    }
   ],
   "source": [
    "# Журнал доступен без подключения внешнего сервиса.\n",
    "for row in trainer.state.log_history:\n",
    "    if \"loss\" in row:\n",
    "        print(row[\"step\"], round(row[\"loss\"], 3))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a9f136fa",
   "metadata": {},
   "source": [
    "## Повторим тот же вопрос\n",
    "\n",
    "trainer.model содержит базу с адаптером. eval() включает режим использования. Вопрос и настройки генерации не меняются, инструкции «говори как пират» нет. Сравниваем сохранённый before с after."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "aa0b51e9",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-01T23:35:13.425620Z",
     "iopub.status.busy": "2026-10-01T23:35:13.425620Z",
     "iopub.status.idle": "2026-10-01T23:35:23.893479Z",
     "shell.execute_reply": "2026-10-01T23:35:23.892471Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ДО:\n",
      " Organizing your study time effectively is crucial for achieving academic success and maintaining productivity. Here are some tips to help you manage your study sessions more efficiently:\n",
      "\n",
      "1. **Set Clear Goals**: Define what you want to achieve with each session of studying. Break down larger tasks into smaller, manageable goals.\n",
      "\n",
      "2. **Create a Schedule**: Use a planner or digital calendar to schedule specific times for studying. Stick to this schedule as much as possible to maintain consistency.\n",
      "\n",
      "3. **Prioritize Tasks**: Identify the\n",
      "ПОСЛЕ:\n",
      " Ahoy there, matey!  Organizing yer study time be like rigging a ship for a stormy sea voyage - it requires planning and strategy!\n",
      "\n",
      "First, ye need to know what's in the hold of yer mind. What be the treasure maps (subjects) ye want to explore? And how much rum (time) do ye have on board?\n",
      "\n",
      "Next, find a quiet spot where ye can concentrate without no distractions. A library or a cabin with a view might work well.\n",
      "\n",
      "Then\n"
     ]
    }
   ],
   "source": [
    "# Подключаем обученный адаптер к тому же генератору.\n",
    "chat.model = trainer.model\n",
    "chat.model.eval()\n",
    "\n",
    "after = ask(question)\n",
    "print(\"ДО:\\n\", before)\n",
    "print(\"ПОСЛЕ:\\n\", after)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51857c4d",
   "metadata": {},
   "source": [
    "## Проверим другой вопрос\n",
    "\n",
    "Первый вопрос проверяет перенос стиля на другую тему, второй — на русский язык. Английский набор не гарантирует такой перенос. Смотреть нужно и на стиль, и на смысл: пиратское приветствие само по себе не делает ответ хорошим."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "8f9874d1",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-01T23:35:23.902361Z",
     "iopub.status.busy": "2026-10-01T23:35:23.901361Z",
     "iopub.status.idle": "2026-10-01T23:35:39.389441Z",
     "shell.execute_reply": "2026-10-01T23:35:39.388432Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Ahoy there, matey! A neural network be like a giant sea monster with thousands of tentacles, each one connected to every other one, and they all work together to solve puzzles and make decisions, just like a parrot learning to speak! \n",
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Ahoy there, matey!  Learning programming is like finding buried treasure - it's all about patience and perseverance, but also a bit of luck too. Here be my tips:\n",
      "\n",
      "1. **Practice, practice, practice**: The more you play with code, the better you'll get. Try to write some simple programs first, then move on to more complex ones.\n",
      "\n",
      "2. **Read books and blogs**: There be plenty of good resources out there for learning programming. Don't just rely on\n"
     ]
    }
   ],
   "source": [
    "print(ask(\"Explain what a neural network is in two sentences.\"))\n",
    "print(ask(\"Скажи, как лучше учиться программированию?\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "154595f4",
   "metadata": {},
   "source": [
    "## Сохраним результат\n",
    "\n",
    "В pirate-adapter записываются веса LoRA, конфигурация и токенизатор. Базовая модель не копируется: при следующем запуске нужны и база, и адаптер. База уже находится в локальном кэше. Отдельный блокнот показывает загрузку в новом сеансе."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "03579bfa",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-01T23:35:39.399472Z",
     "iopub.status.busy": "2026-10-01T23:35:39.398472Z",
     "iopub.status.idle": "2026-10-01T23:35:40.342302Z",
     "shell.execute_reply": "2026-10-01T23:35:40.342302Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('pirate-adapter\\\\tokenizer_config.json',\n",
       " 'pirate-adapter\\\\special_tokens_map.json',\n",
       " 'pirate-adapter\\\\chat_template.jinja',\n",
       " 'pirate-adapter\\\\vocab.json',\n",
       " 'pirate-adapter\\\\merges.txt',\n",
       " 'pirate-adapter\\\\added_tokens.json',\n",
       " 'pirate-adapter\\\\tokenizer.json')"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "trainer.save_model(\"pirate-adapter\")\n",
    "chat.tokenizer.save_pretrained(\"pirate-adapter\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bac26e3d",
   "metadata": {},
   "source": [
    "## Данные контрольного прогона\n",
    "Сохраняем все проверочные ответы и журнал для интерактивной лекции. Этот блок не нужен для самого дообучения."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "6270230c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-01T23:35:40.352851Z",
     "iopub.status.busy": "2026-10-01T23:35:40.351343Z",
     "iopub.status.idle": "2026-10-01T23:36:27.564818Z",
     "shell.execute_reply": "2026-10-01T23:36:27.563809Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "You seem to be using the pipelines sequentially on GPU. In order to maximize efficiency please use a dataset\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  \"model\": \"Qwen/Qwen2.5-1.5B-Instruct\",\n",
      "  \"dataset\": \"winglian/pirate-ultrachat-10k\",\n",
      "  \"steps\": 400,\n",
      "  \"seconds\": 598.9059,\n",
      "  \"gpu\": \"NVIDIA GeForce RTX 3090\",\n",
      "  \"peak_vram_gb\": 4.500019073486328,\n",
      "  \"history\": [\n",
      "    {\n",
      "      \"loss\": 2.195,\n",
      "      \"grad_norm\": 0.37731432914733887,\n",
      "      \"learning_rate\": 0.00029325,\n",
      "      \"entropy\": 1.958161923289299,\n",
      "      \"num_tokens\": 25328.0,\n",
      "      \"mean_token_accuracy\": 0.5526984632015228,\n",
      "      \"epoch\": 0.15625,\n",
      "      \"step\": 10\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.972,\n",
      "      \"grad_norm\": 0.3646916449069977,\n",
      "      \"learning_rate\": 0.00028575,\n",
      "      \"entropy\": 1.9928408980369567,\n",
      "      \"num_tokens\": 51792.0,\n",
      "      \"mean_token_accuracy\": 0.5661312520503998,\n",
      "      \"epoch\": 0.3125,\n",
      "      \"step\": 20\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.8715,\n",
      "      \"grad_norm\": 0.27372947335243225,\n",
      "      \"learning_rate\": 0.00027824999999999996,\n",
      "      \"entropy\": 1.9563999146223068,\n",
      "      \"num_tokens\": 78054.0,\n",
      "      \"mean_token_accuracy\": 0.5807824246585369,\n",
      "      \"epoch\": 0.46875,\n",
      "      \"step\": 30\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.8145,\n",
      "      \"grad_norm\": 0.3001754581928253,\n",
      "      \"learning_rate\": 0.00027074999999999994,\n",
      "      \"entropy\": 1.8729610323905945,\n",
      "      \"num_tokens\": 104414.0,\n",
      "      \"mean_token_accuracy\": 0.5871749624609948,\n",
      "      \"epoch\": 0.625,\n",
      "      \"step\": 40\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.7388,\n",
      "      \"grad_norm\": 0.3473432660102844,\n",
      "      \"learning_rate\": 0.00026325,\n",
      "      \"entropy\": 1.7809287637472153,\n",
      "      \"num_tokens\": 130654.0,\n",
      "      \"mean_token_accuracy\": 0.5956159844994545,\n",
      "      \"epoch\": 0.78125,\n",
      "      \"step\": 50\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.5971,\n",
      "      \"grad_norm\": 0.3829735517501831,\n",
      "      \"learning_rate\": 0.00025575,\n",
      "      \"entropy\": 1.629867573082447,\n",
      "      \"num_tokens\": 155839.0,\n",
      "      \"mean_token_accuracy\": 0.6230093672871589,\n",
      "      \"epoch\": 0.9375,\n",
      "      \"step\": 60\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.6144,\n",
      "      \"grad_norm\": 0.39073053002357483,\n",
      "      \"learning_rate\": 0.00024825,\n",
      "      \"entropy\": 1.6402277946472168,\n",
      "      \"num_tokens\": 181276.0,\n",
      "      \"mean_token_accuracy\": 0.6166226282715798,\n",
      "      \"epoch\": 1.09375,\n",
      "      \"step\": 70\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.6121,\n",
      "      \"grad_norm\": 0.28727665543556213,\n",
      "      \"learning_rate\": 0.00024074999999999997,\n",
      "      \"entropy\": 1.6268904745578765,\n",
      "      \"num_tokens\": 207607.0,\n",
      "      \"mean_token_accuracy\": 0.6156239360570908,\n",
      "      \"epoch\": 1.25,\n",
      "      \"step\": 80\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.5981,\n",
      "      \"grad_norm\": 0.36298590898513794,\n",
      "      \"learning_rate\": 0.00023324999999999998,\n",
      "      \"entropy\": 1.627642273902893,\n",
      "      \"num_tokens\": 233695.0,\n",
      "      \"mean_token_accuracy\": 0.6183786213397979,\n",
      "      \"epoch\": 1.40625,\n",
      "      \"step\": 90\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.5192,\n",
      "      \"grad_norm\": 0.3202018439769745,\n",
      "      \"learning_rate\": 0.00022574999999999996,\n",
      "      \"entropy\": 1.5265675023198129,\n",
      "      \"num_tokens\": 259796.0,\n",
      "      \"mean_token_accuracy\": 0.6355368077754975,\n",
      "      \"epoch\": 1.5625,\n",
      "      \"step\": 100\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.5322,\n",
      "      \"grad_norm\": 0.33764591813087463,\n",
      "      \"learning_rate\": 0.00021825,\n",
      "      \"entropy\": 1.5694365739822387,\n",
      "      \"num_tokens\": 285710.0,\n",
      "      \"mean_token_accuracy\": 0.6270335033535958,\n",
      "      \"epoch\": 1.71875,\n",
      "      \"step\": 110\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.5537,\n",
      "      \"grad_norm\": 0.3598622977733612,\n",
      "      \"learning_rate\": 0.00021074999999999997,\n",
      "      \"entropy\": 1.534247761964798,\n",
      "      \"num_tokens\": 311699.0,\n",
      "      \"mean_token_accuracy\": 0.6246832057833671,\n",
      "      \"epoch\": 1.875,\n",
      "      \"step\": 120\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.5376,\n",
      "      \"grad_norm\": 0.36715108156204224,\n",
      "      \"learning_rate\": 0.00020324999999999998,\n",
      "      \"entropy\": 1.5672920912504196,\n",
      "      \"num_tokens\": 337435.0,\n",
      "      \"mean_token_accuracy\": 0.6283901825547218,\n",
      "      \"epoch\": 2.03125,\n",
      "      \"step\": 130\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.5213,\n",
      "      \"grad_norm\": 0.3757905662059784,\n",
      "      \"learning_rate\": 0.00019574999999999996,\n",
      "      \"entropy\": 1.54151751101017,\n",
      "      \"num_tokens\": 364360.0,\n",
      "      \"mean_token_accuracy\": 0.632046353816986,\n",
      "      \"epoch\": 2.1875,\n",
      "      \"step\": 140\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4774,\n",
      "      \"grad_norm\": 0.36965927481651306,\n",
      "      \"learning_rate\": 0.00018824999999999997,\n",
      "      \"entropy\": 1.481405833363533,\n",
      "      \"num_tokens\": 391095.0,\n",
      "      \"mean_token_accuracy\": 0.6384281873703003,\n",
      "      \"epoch\": 2.34375,\n",
      "      \"step\": 150\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.511,\n",
      "      \"grad_norm\": 0.38426560163497925,\n",
      "      \"learning_rate\": 0.00018075,\n",
      "      \"entropy\": 1.5485713094472886,\n",
      "      \"num_tokens\": 417018.0,\n",
      "      \"mean_token_accuracy\": 0.6298049330711365,\n",
      "      \"epoch\": 2.5,\n",
      "      \"step\": 160\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4581,\n",
      "      \"grad_norm\": 0.4261852204799652,\n",
      "      \"learning_rate\": 0.00017324999999999998,\n",
      "      \"entropy\": 1.4633228331804276,\n",
      "      \"num_tokens\": 441974.0,\n",
      "      \"mean_token_accuracy\": 0.638293842971325,\n",
      "      \"epoch\": 2.65625,\n",
      "      \"step\": 170\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.5119,\n",
      "      \"grad_norm\": 0.4052521288394928,\n",
      "      \"learning_rate\": 0.00016575,\n",
      "      \"entropy\": 1.5275615632534028,\n",
      "      \"num_tokens\": 467622.0,\n",
      "      \"mean_token_accuracy\": 0.627769336104393,\n",
      "      \"epoch\": 2.8125,\n",
      "      \"step\": 180\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.5317,\n",
      "      \"grad_norm\": 0.4072372019290924,\n",
      "      \"learning_rate\": 0.00015824999999999997,\n",
      "      \"entropy\": 1.5765727937221528,\n",
      "      \"num_tokens\": 493568.0,\n",
      "      \"mean_token_accuracy\": 0.6239863499999047,\n",
      "      \"epoch\": 2.96875,\n",
      "      \"step\": 190\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4951,\n",
      "      \"grad_norm\": 0.40604913234710693,\n",
      "      \"learning_rate\": 0.00015074999999999998,\n",
      "      \"entropy\": 1.501016193628311,\n",
      "      \"num_tokens\": 519320.0,\n",
      "      \"mean_token_accuracy\": 0.631594555079937,\n",
      "      \"epoch\": 3.125,\n",
      "      \"step\": 200\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4613,\n",
      "      \"grad_norm\": 0.39454445242881775,\n",
      "      \"learning_rate\": 0.00014324999999999999,\n",
      "      \"entropy\": 1.4559457063674928,\n",
      "      \"num_tokens\": 546198.0,\n",
      "      \"mean_token_accuracy\": 0.6380513608455658,\n",
      "      \"epoch\": 3.28125,\n",
      "      \"step\": 210\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4048,\n",
      "      \"grad_norm\": 0.4332672357559204,\n",
      "      \"learning_rate\": 0.00013575,\n",
      "      \"entropy\": 1.4414396956562996,\n",
      "      \"num_tokens\": 571426.0,\n",
      "      \"mean_token_accuracy\": 0.6525899708271027,\n",
      "      \"epoch\": 3.4375,\n",
      "      \"step\": 220\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4446,\n",
      "      \"grad_norm\": 0.42820411920547485,\n",
      "      \"learning_rate\": 0.00012824999999999997,\n",
      "      \"entropy\": 1.4558397829532623,\n",
      "      \"num_tokens\": 597404.0,\n",
      "      \"mean_token_accuracy\": 0.638386407494545,\n",
      "      \"epoch\": 3.59375,\n",
      "      \"step\": 230\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.5127,\n",
      "      \"grad_norm\": 0.4580950438976288,\n",
      "      \"learning_rate\": 0.00012075,\n",
      "      \"entropy\": 1.538639086484909,\n",
      "      \"num_tokens\": 623028.0,\n",
      "      \"mean_token_accuracy\": 0.6277329877018929,\n",
      "      \"epoch\": 3.75,\n",
      "      \"step\": 240\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.5101,\n",
      "      \"grad_norm\": 0.5449416041374207,\n",
      "      \"learning_rate\": 0.00011324999999999999,\n",
      "      \"entropy\": 1.5069909334182738,\n",
      "      \"num_tokens\": 647942.0,\n",
      "      \"mean_token_accuracy\": 0.6309696123003959,\n",
      "      \"epoch\": 3.90625,\n",
      "      \"step\": 250\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4436,\n",
      "      \"grad_norm\": 0.35665038228034973,\n",
      "      \"learning_rate\": 0.00010574999999999998,\n",
      "      \"entropy\": 1.4869085043668746,\n",
      "      \"num_tokens\": 675746.0,\n",
      "      \"mean_token_accuracy\": 0.6367657482624054,\n",
      "      \"epoch\": 4.0625,\n",
      "      \"step\": 260\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4659,\n",
      "      \"grad_norm\": 0.42033013701438904,\n",
      "      \"learning_rate\": 9.824999999999999e-05,\n",
      "      \"entropy\": 1.4945802569389344,\n",
      "      \"num_tokens\": 700836.0,\n",
      "      \"mean_token_accuracy\": 0.6382692664861679,\n",
      "      \"epoch\": 4.21875,\n",
      "      \"step\": 270\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4485,\n",
      "      \"grad_norm\": 0.3857159912586212,\n",
      "      \"learning_rate\": 9.074999999999998e-05,\n",
      "      \"entropy\": 1.4490568920969964,\n",
      "      \"num_tokens\": 727577.0,\n",
      "      \"mean_token_accuracy\": 0.6381174176931381,\n",
      "      \"epoch\": 4.375,\n",
      "      \"step\": 280\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4046,\n",
      "      \"grad_norm\": 0.516910970211029,\n",
      "      \"learning_rate\": 8.325e-05,\n",
      "      \"entropy\": 1.4127783730626107,\n",
      "      \"num_tokens\": 753218.0,\n",
      "      \"mean_token_accuracy\": 0.648927490413189,\n",
      "      \"epoch\": 4.53125,\n",
      "      \"step\": 290\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4785,\n",
      "      \"grad_norm\": 0.4814925193786621,\n",
      "      \"learning_rate\": 7.575e-05,\n",
      "      \"entropy\": 1.4997142165899278,\n",
      "      \"num_tokens\": 779049.0,\n",
      "      \"mean_token_accuracy\": 0.6359122335910797,\n",
      "      \"epoch\": 4.6875,\n",
      "      \"step\": 300\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4424,\n",
      "      \"grad_norm\": 0.427807480096817,\n",
      "      \"learning_rate\": 6.824999999999999e-05,\n",
      "      \"entropy\": 1.4582823097705842,\n",
      "      \"num_tokens\": 805396.0,\n",
      "      \"mean_token_accuracy\": 0.6438066825270653,\n",
      "      \"epoch\": 4.84375,\n",
      "      \"step\": 310\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4473,\n",
      "      \"grad_norm\": 0.48176366090774536,\n",
      "      \"learning_rate\": 6.075e-05,\n",
      "      \"entropy\": 1.466781198978424,\n",
      "      \"num_tokens\": 830465.0,\n",
      "      \"mean_token_accuracy\": 0.6402557671070099,\n",
      "      \"epoch\": 5.0,\n",
      "      \"step\": 320\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4358,\n",
      "      \"grad_norm\": 0.5553231835365295,\n",
      "      \"learning_rate\": 5.324999999999999e-05,\n",
      "      \"entropy\": 1.4646940320730208,\n",
      "      \"num_tokens\": 857538.0,\n",
      "      \"mean_token_accuracy\": 0.6444870874285697,\n",
      "      \"epoch\": 5.15625,\n",
      "      \"step\": 330\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4475,\n",
      "      \"grad_norm\": 0.4347440004348755,\n",
      "      \"learning_rate\": 4.5749999999999994e-05,\n",
      "      \"entropy\": 1.4462689086794853,\n",
      "      \"num_tokens\": 882342.0,\n",
      "      \"mean_token_accuracy\": 0.6396534368395805,\n",
      "      \"epoch\": 5.3125,\n",
      "      \"step\": 340\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4502,\n",
      "      \"grad_norm\": 0.44932350516319275,\n",
      "      \"learning_rate\": 3.8249999999999995e-05,\n",
      "      \"entropy\": 1.4641593545675278,\n",
      "      \"num_tokens\": 908004.0,\n",
      "      \"mean_token_accuracy\": 0.6365796819329261,\n",
      "      \"epoch\": 5.46875,\n",
      "      \"step\": 350\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4563,\n",
      "      \"grad_norm\": 0.4241075813770294,\n",
      "      \"learning_rate\": 3.0749999999999995e-05,\n",
      "      \"entropy\": 1.4845301866531373,\n",
      "      \"num_tokens\": 934595.0,\n",
      "      \"mean_token_accuracy\": 0.6419829726219177,\n",
      "      \"epoch\": 5.625,\n",
      "      \"step\": 360\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4037,\n",
      "      \"grad_norm\": 0.4824559986591339,\n",
      "      \"learning_rate\": 2.325e-05,\n",
      "      \"entropy\": 1.4201569080352783,\n",
      "      \"num_tokens\": 959480.0,\n",
      "      \"mean_token_accuracy\": 0.6476794362068177,\n",
      "      \"epoch\": 5.78125,\n",
      "      \"step\": 370\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4447,\n",
      "      \"grad_norm\": 0.4108693301677704,\n",
      "      \"learning_rate\": 1.5749999999999997e-05,\n",
      "      \"entropy\": 1.4608194380998611,\n",
      "      \"num_tokens\": 985903.0,\n",
      "      \"mean_token_accuracy\": 0.6395280912518502,\n",
      "      \"epoch\": 5.9375,\n",
      "      \"step\": 380\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4006,\n",
      "      \"grad_norm\": 0.46322232484817505,\n",
      "      \"learning_rate\": 8.249999999999999e-06,\n",
      "      \"entropy\": 1.4344169452786446,\n",
      "      \"num_tokens\": 1011738.0,\n",
      "      \"mean_token_accuracy\": 0.6544970959424973,\n",
      "      \"epoch\": 6.09375,\n",
      "      \"step\": 390\n",
      "    },\n",
      "    {\n",
      "      \"loss\": 1.4275,\n",
      "      \"grad_norm\": 0.4124956429004669,\n",
      "      \"learning_rate\": 7.499999999999999e-07,\n",
      "      \"entropy\": 1.4351394206285477,\n",
      "      \"num_tokens\": 1038757.0,\n",
      "      \"mean_token_accuracy\": 0.6457246869802475,\n",
      "      \"epoch\": 6.25,\n",
      "      \"step\": 400\n",
      "    },\n",
      "    {\n",
      "      \"train_runtime\": 598.9059,\n",
      "      \"train_samples_per_second\": 5.343,\n",
      "      \"train_steps_per_second\": 0.668,\n",
      "      \"total_flos\": 9205263906852864.0,\n",
      "      \"train_loss\": 1.539833769798279,\n",
      "      \"epoch\": 6.25,\n",
      "      \"step\": 400\n",
      "    }\n",
      "  ],\n",
      "  \"comparison\": [\n",
      "    {\n",
      "      \"question\": \"How can I organize my study time?\",\n",
      "      \"before\": \"Organizing your study time effectively is crucial for achieving academic success and maintaining productivity. Here are some tips to help you manage your study sessions more efficiently:\\n\\n1. **Set Clear Goals**: Define what you want to achieve with each session of studying. Break down larger tasks into smaller, manageable goals.\\n\\n2. **Create a Schedule**: Use a planner or digital calendar to schedule specific times for studying. Stick to this schedule as much as possible to maintain consistency.\\n\\n3. **Prioritize Tasks**: Identify the\",\n",
      "      \"after\": \"Ahoy there, matey!  Organizing yer study time be like rigging a ship for a stormy sea voyage - it requires planning and strategy!\\n\\nFirst, ye need to know what's in the hold of yer mind. What be the treasure maps (subjects) ye want to explore? And how much rum (time) do ye have on board?\\n\\nNext, find a quiet spot where ye can concentrate without no distractions. A library or a cabin with a view might work well.\\n\\nThen\",\n",
      "      \"in_train\": false\n",
      "    },\n",
      "    {\n",
      "      \"question\": \"Explain what a neural network is in two sentences.\",\n",
      "      \"before\": \"A neural network is a type of machine learning model inspired by the structure and function of the human brain, consisting of interconnected nodes or \\\"neurons\\\" that process information through layers to recognize patterns and make predictions.\",\n",
      "      \"after\": \"Ahoy there, matey! A neural network be like a giant sea monster with thousands of tentacles, each one connected to every other one, and they all work together to solve puzzles and make decisions, just like a parrot learning to speak! \\n\",\n",
      "      \"in_train\": false\n",
      "    },\n",
      "    {\n",
      "      \"question\": \"Write a birthday greeting for a friend.\",\n",
      "      \"before\": \"Dear [Friend's Name],\\n\\nHappy Birthday! I hope this message finds you in good health and high spirits.\\n\\nAs we celebrate your special day, I want to take a moment to express my deepest wishes for all the wonderful things that lie ahead. May your year be filled with joy, laughter, and love. May you find happiness in every moment of your life.\\n\\nRemember, it is not just about the big events or milestones; it's also about the small moments that make us feel grateful and loved\",\n",
      "      \"after\": \"Ahoy there, matey!  This be yer birthday, eh?  Aye, it's time to celebrate with a hearty \\\"Happy Birthday!\\\" And I'll tell ye what, this be one of the best birthdays ever! \\n\\nSo here be my special message:\\n\\n\\\"Yo ho ho and a bottle of rum on yer birthday!  May your day be filled with laughter, love, and treasure beyond measure!  May you sail through life like a pirate ship, full of adventure and excitement\",\n",
      "      \"in_train\": false\n",
      "    },\n",
      "    {\n",
      "      \"question\": \"Why is the sky blue?\",\n",
      "      \"before\": \"The sky appears blue because of a phenomenon called Rayleigh scattering. This occurs when sunlight passes through Earth's atmosphere and interacts with gas molecules in the air. The shorter wavelengths of light (blue and violet) scatter more easily than the longer wavelengths (red and orange), which means that they are scattered in all directions throughout the atmosphere. As a result, we see the blue color of the sky from the ground.\",\n",
      "      \"after\": \"Ahoy there, matey!  The sky be blue because of that pesky little thing called Rayleigh scattering! \\n\\nImagine you've got a buncha tiny water droplets floating around up in the air, like those kraken's tentacles! These little buggers scatter sunlight in all directions, just like when you throw a stone into a pond and see ripples everywhere.\\n\\nThe shorter wavelengths of light (like red and violet) get scattered more than the longer ones (like green and\",\n",
      "      \"in_train\": false\n",
      "    },\n",
      "    {\n",
      "      \"question\": \"Скажи, как лучше учиться программированию?\",\n",
      "      \"before\": \"Учить программирование - это сложный процесс, но он может быть сделан более эффективным с помощью определенных стратегий и подходов:\\n\\n1. **Выбор языка**: Начните с одного из популярных языков программирования, таких как Python или Java.\\n\\n2. **Простые задачи**: Решайте простые задачи на новом языке перед переходом к более сложным.\\n\\n3. **Использ\",\n",
      "      \"after\": \"Ahoy there, matey!  Learning programming is like finding buried treasure - it's all about patience and perseverance, but also a bit of luck too. Here be my tips:\\n\\n1. **Practice, practice, practice**: The more you play with code, the better you'll get. Try to write some simple programs first, then move on to more complex ones.\\n\\n2. **Read books and blogs**: There be plenty of good resources out there for learning programming. Don't just rely on\",\n",
      "      \"in_train\": false\n",
      "    }\n",
      "  ],\n",
      "  \"model_revision\": \"989aa7980e4cf806f80c7fef2b1adb7bc71aa306\",\n",
      "  \"dataset_revision\": \"831d415c1269299d25c371caeb6287cde378eaf6\",\n",
      "  \"trainable\": 1089536,\n",
      "  \"total\": 1544803840\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "import json\n",
    "from pathlib import Path\n",
    "from huggingface_hub import HfApi\n",
    "\n",
    "answers = [ask(q) for q in questions]\n",
    "training_questions = [row[\"messages\"][0][\"content\"] for row in data]\n",
    "assert not any(q in training_questions for q in questions)\n",
    "record = {\n",
    "    \"model\": model_id, \"dataset\": \"winglian/pirate-ultrachat-10k\",\n",
    "    \"steps\": trainer.state.global_step,\n",
    "    \"seconds\": trainer.state.log_history[-1][\"train_runtime\"],\n",
    "    \"gpu\": torch.cuda.get_device_name(0),\n",
    "    \"peak_vram_gb\": torch.cuda.max_memory_allocated() / 1024**3,\n",
    "    \"history\": trainer.state.log_history,\n",
    "    \"comparison\": [{\"question\": q, \"before\": b, \"after\": a, \"in_train\": False}\n",
    "                   for q,b,a in zip(questions, baseline, answers)],\n",
    "    \"model_revision\": HfApi().model_info(model_id).sha,\n",
    "    \"dataset_revision\": HfApi().dataset_info(\"winglian/pirate-ultrachat-10k\").sha,\n",
    "    \"trainable\": sum(p.numel() for p in trainer.model.parameters() if p.requires_grad),\n",
    "    \"total\": sum(p.numel() for p in trainer.model.parameters()),\n",
    "}\n",
    "Path(\"../app/pirate-run.json\").write_text(json.dumps(record, ensure_ascii=False, indent=2), encoding=\"utf-8\")\n",
    "preview = [data[i] for i in range(12)]\n",
    "Path(\"../app/data-preview.json\").write_text(json.dumps(preview, ensure_ascii=False), encoding=\"utf-8\")\n",
    "tokens = []\n",
    "for text in [\"Hello, captain!\", \"Good morning, friend.\", \"Привет, капитан!\", \"tokenization\"]:\n",
    "    ids = chat.tokenizer(text)[\"input_ids\"]\n",
    "    tokens.append({\"text\": text, \"ids\": ids, \"parts\": [chat.tokenizer.decode([i]) for i in ids], \"decoded\": chat.tokenizer.decode(ids)})\n",
    "Path(\"../app/tokens.json\").write_text(json.dumps(tokens, ensure_ascii=False), encoding=\"utf-8\")\n",
    "print(json.dumps(record, ensure_ascii=False, indent=2))\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "LLM · CUDA (torchcu121)",
   "language": "python",
   "name": "llm-course-2026"
  },
  "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.11.14"
  },
  "widgets": {
   "application/vnd.jupyter.widget-state+json": {
    "state": {
     "08b83fd6f1de4269bf129eb3ef81a9d2": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "2.0.0",
      "model_name": "LayoutModel",
      "state": {
       "_model_module": "@jupyter-widgets/base",
       "_model_module_version": "2.0.0",
       "_model_name": "LayoutModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "LayoutView",
       "align_content": null,
       "align_items": null,
       "align_self": null,
       "border_bottom": null,
       "border_left": null,
       "border_right": null,
       "border_top": null,
       "bottom": null,
       "display": null,
       "flex": null,
       "flex_flow": null,
       "grid_area": null,
       "grid_auto_columns": null,
       "grid_auto_flow": null,
       "grid_auto_rows": null,
       "grid_column": null,
       "grid_gap": null,
       "grid_row": null,
       "grid_template_areas": null,
       "grid_template_columns": null,
       "grid_template_rows": null,
       "height": null,
       "justify_content": null,
       "justify_items": null,
       "left": null,
       "margin": null,
       "max_height": null,
       "max_width": null,
       "min_height": null,
       "min_width": null,
       "object_fit": null,
       "object_position": null,
       "order": null,
       "overflow": null,
       "padding": null,
       "right": null,
       "top": null,
       "visibility": null,
       "width": null
      }
     },
     "118031ca1f5a4caa8e81dd0ab3cc13c0": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "HTMLStyleModel",
      "state": {
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "HTMLStyleModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "StyleView",
       "background": null,
       "description_width": "",
       "font_size": null,
       "text_color": null
      }
     },
     "29ea6529425745e498cc23b422757cc2": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "HTMLModel",
      "state": {
       "_dom_classes": [],
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "HTMLModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/controls",
       "_view_module_version": "2.0.0",
       "_view_name": "HTMLView",
       "description": "",
       "description_allow_html": false,
       "layout": "IPY_MODEL_5a89d0e1e1ff4a0aaa18ff9322306f0c",
       "placeholder": "​",
       "style": "IPY_MODEL_118031ca1f5a4caa8e81dd0ab3cc13c0",
       "tabbable": null,
       "tooltip": null,
       "value": "Truncating train dataset: 100%"
      }
     },
     "422366b452594630a0c2f61653f11850": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "2.0.0",
      "model_name": "LayoutModel",
      "state": {
       "_model_module": "@jupyter-widgets/base",
       "_model_module_version": "2.0.0",
       "_model_name": "LayoutModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "LayoutView",
       "align_content": null,
       "align_items": null,
       "align_self": null,
       "border_bottom": null,
       "border_left": null,
       "border_right": null,
       "border_top": null,
       "bottom": null,
       "display": null,
       "flex": null,
       "flex_flow": null,
       "grid_area": null,
       "grid_auto_columns": null,
       "grid_auto_flow": null,
       "grid_auto_rows": null,
       "grid_column": null,
       "grid_gap": null,
       "grid_row": null,
       "grid_template_areas": null,
       "grid_template_columns": null,
       "grid_template_rows": null,
       "height": null,
       "justify_content": null,
       "justify_items": null,
       "left": null,
       "margin": null,
       "max_height": null,
       "max_width": null,
       "min_height": null,
       "min_width": null,
       "object_fit": null,
       "object_position": null,
       "order": null,
       "overflow": null,
       "padding": null,
       "right": null,
       "top": null,
       "visibility": null,
       "width": null
      }
     },
     "45b14fb7e9e04edbad0f6bf883013f99": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "HTMLStyleModel",
      "state": {
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "HTMLStyleModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "StyleView",
       "background": null,
       "description_width": "",
       "font_size": null,
       "text_color": null
      }
     },
     "4a76a2696dde42f8a6b224bc684ba191": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "HTMLStyleModel",
      "state": {
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "HTMLStyleModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "StyleView",
       "background": null,
       "description_width": "",
       "font_size": null,
       "text_color": null
      }
     },
     "4f81b2c2ccfa491cb1414aff69ae8f74": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "HBoxModel",
      "state": {
       "_dom_classes": [],
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "HBoxModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/controls",
       "_view_module_version": "2.0.0",
       "_view_name": "HBoxView",
       "box_style": "",
       "children": [
        "IPY_MODEL_29ea6529425745e498cc23b422757cc2",
        "IPY_MODEL_843da236d9b6411eb4ff6941547d14de",
        "IPY_MODEL_a3172cc690764403bf559fd3dbdcb85b"
       ],
       "layout": "IPY_MODEL_95ddb13335134e098f27db01b8a76f0c",
       "tabbable": null,
       "tooltip": null
      }
     },
     "4fb6301fd5614ec2a4d1e13034a09c2c": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "2.0.0",
      "model_name": "LayoutModel",
      "state": {
       "_model_module": "@jupyter-widgets/base",
       "_model_module_version": "2.0.0",
       "_model_name": "LayoutModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "LayoutView",
       "align_content": null,
       "align_items": null,
       "align_self": null,
       "border_bottom": null,
       "border_left": null,
       "border_right": null,
       "border_top": null,
       "bottom": null,
       "display": null,
       "flex": null,
       "flex_flow": null,
       "grid_area": null,
       "grid_auto_columns": null,
       "grid_auto_flow": null,
       "grid_auto_rows": null,
       "grid_column": null,
       "grid_gap": null,
       "grid_row": null,
       "grid_template_areas": null,
       "grid_template_columns": null,
       "grid_template_rows": null,
       "height": null,
       "justify_content": null,
       "justify_items": null,
       "left": null,
       "margin": null,
       "max_height": null,
       "max_width": null,
       "min_height": null,
       "min_width": null,
       "object_fit": null,
       "object_position": null,
       "order": null,
       "overflow": null,
       "padding": null,
       "right": null,
       "top": null,
       "visibility": null,
       "width": null
      }
     },
     "57b4bc07f8f34816805d30b97c139fb0": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "HTMLModel",
      "state": {
       "_dom_classes": [],
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "HTMLModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/controls",
       "_view_module_version": "2.0.0",
       "_view_name": "HTMLView",
       "description": "",
       "description_allow_html": false,
       "layout": "IPY_MODEL_a456cd35487c4ebebaf2643941d69bb8",
       "placeholder": "​",
       "style": "IPY_MODEL_9560a1810a0a48c8a8a1b5dcc76cf2b1",
       "tabbable": null,
       "tooltip": null,
       "value": "Filter: 100%"
      }
     },
     "5894f1ed734f49e5b258565ef64be531": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "HBoxModel",
      "state": {
       "_dom_classes": [],
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "HBoxModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/controls",
       "_view_module_version": "2.0.0",
       "_view_name": "HBoxView",
       "box_style": "",
       "children": [
        "IPY_MODEL_d3a3164a888444d9a4ce8cacea3c04b7",
        "IPY_MODEL_bea00b21cb514fbeb47e1b02f605b91f",
        "IPY_MODEL_ec026ad148ee45af9420b0fc3cdb362e"
       ],
       "layout": "IPY_MODEL_5c45569082fa41669c4470e384eb3f4f",
       "tabbable": null,
       "tooltip": null
      }
     },
     "5a89d0e1e1ff4a0aaa18ff9322306f0c": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "2.0.0",
      "model_name": "LayoutModel",
      "state": {
       "_model_module": "@jupyter-widgets/base",
       "_model_module_version": "2.0.0",
       "_model_name": "LayoutModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "LayoutView",
       "align_content": null,
       "align_items": null,
       "align_self": null,
       "border_bottom": null,
       "border_left": null,
       "border_right": null,
       "border_top": null,
       "bottom": null,
       "display": null,
       "flex": null,
       "flex_flow": null,
       "grid_area": null,
       "grid_auto_columns": null,
       "grid_auto_flow": null,
       "grid_auto_rows": null,
       "grid_column": null,
       "grid_gap": null,
       "grid_row": null,
       "grid_template_areas": null,
       "grid_template_columns": null,
       "grid_template_rows": null,
       "height": null,
       "justify_content": null,
       "justify_items": null,
       "left": null,
       "margin": null,
       "max_height": null,
       "max_width": null,
       "min_height": null,
       "min_width": null,
       "object_fit": null,
       "object_position": null,
       "order": null,
       "overflow": null,
       "padding": null,
       "right": null,
       "top": null,
       "visibility": null,
       "width": null
      }
     },
     "5c45569082fa41669c4470e384eb3f4f": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "2.0.0",
      "model_name": "LayoutModel",
      "state": {
       "_model_module": "@jupyter-widgets/base",
       "_model_module_version": "2.0.0",
       "_model_name": "LayoutModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "LayoutView",
       "align_content": null,
       "align_items": null,
       "align_self": null,
       "border_bottom": null,
       "border_left": null,
       "border_right": null,
       "border_top": null,
       "bottom": null,
       "display": null,
       "flex": null,
       "flex_flow": null,
       "grid_area": null,
       "grid_auto_columns": null,
       "grid_auto_flow": null,
       "grid_auto_rows": null,
       "grid_column": null,
       "grid_gap": null,
       "grid_row": null,
       "grid_template_areas": null,
       "grid_template_columns": null,
       "grid_template_rows": null,
       "height": null,
       "justify_content": null,
       "justify_items": null,
       "left": null,
       "margin": null,
       "max_height": null,
       "max_width": null,
       "min_height": null,
       "min_width": null,
       "object_fit": null,
       "object_position": null,
       "order": null,
       "overflow": null,
       "padding": null,
       "right": null,
       "top": null,
       "visibility": null,
       "width": null
      }
     },
     "5dc061a070dc4a3998521f3f46efe849": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "ProgressStyleModel",
      "state": {
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "ProgressStyleModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "StyleView",
       "bar_color": null,
       "description_width": ""
      }
     },
     "7191cb6c799c4ada813e63e938fd3f31": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "FloatProgressModel",
      "state": {
       "_dom_classes": [],
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "FloatProgressModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/controls",
       "_view_module_version": "2.0.0",
       "_view_name": "ProgressView",
       "bar_style": "success",
       "description": "",
       "description_allow_html": false,
       "layout": "IPY_MODEL_94eb16b3573e4bbb845cd1c76cd4c299",
       "max": 9985.0,
       "min": 0.0,
       "orientation": "horizontal",
       "style": "IPY_MODEL_5dc061a070dc4a3998521f3f46efe849",
       "tabbable": null,
       "tooltip": null,
       "value": 9985.0
      }
     },
     "843da236d9b6411eb4ff6941547d14de": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "FloatProgressModel",
      "state": {
       "_dom_classes": [],
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "FloatProgressModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/controls",
       "_view_module_version": "2.0.0",
       "_view_name": "ProgressView",
       "bar_style": "success",
       "description": "",
       "description_allow_html": false,
       "layout": "IPY_MODEL_4fb6301fd5614ec2a4d1e13034a09c2c",
       "max": 512.0,
       "min": 0.0,
       "orientation": "horizontal",
       "style": "IPY_MODEL_a500946dd1f44bf0bdd182fdb60c16f4",
       "tabbable": null,
       "tooltip": null,
       "value": 512.0
      }
     },
     "94eb16b3573e4bbb845cd1c76cd4c299": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "2.0.0",
      "model_name": "LayoutModel",
      "state": {
       "_model_module": "@jupyter-widgets/base",
       "_model_module_version": "2.0.0",
       "_model_name": "LayoutModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "LayoutView",
       "align_content": null,
       "align_items": null,
       "align_self": null,
       "border_bottom": null,
       "border_left": null,
       "border_right": null,
       "border_top": null,
       "bottom": null,
       "display": null,
       "flex": null,
       "flex_flow": null,
       "grid_area": null,
       "grid_auto_columns": null,
       "grid_auto_flow": null,
       "grid_auto_rows": null,
       "grid_column": null,
       "grid_gap": null,
       "grid_row": null,
       "grid_template_areas": null,
       "grid_template_columns": null,
       "grid_template_rows": null,
       "height": null,
       "justify_content": null,
       "justify_items": null,
       "left": null,
       "margin": null,
       "max_height": null,
       "max_width": null,
       "min_height": null,
       "min_width": null,
       "object_fit": null,
       "object_position": null,
       "order": null,
       "overflow": null,
       "padding": null,
       "right": null,
       "top": null,
       "visibility": null,
       "width": null
      }
     },
     "9560a1810a0a48c8a8a1b5dcc76cf2b1": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "HTMLStyleModel",
      "state": {
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "HTMLStyleModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "StyleView",
       "background": null,
       "description_width": "",
       "font_size": null,
       "text_color": null
      }
     },
     "95ddb13335134e098f27db01b8a76f0c": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "2.0.0",
      "model_name": "LayoutModel",
      "state": {
       "_model_module": "@jupyter-widgets/base",
       "_model_module_version": "2.0.0",
       "_model_name": "LayoutModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "LayoutView",
       "align_content": null,
       "align_items": null,
       "align_self": null,
       "border_bottom": null,
       "border_left": null,
       "border_right": null,
       "border_top": null,
       "bottom": null,
       "display": null,
       "flex": null,
       "flex_flow": null,
       "grid_area": null,
       "grid_auto_columns": null,
       "grid_auto_flow": null,
       "grid_auto_rows": null,
       "grid_column": null,
       "grid_gap": null,
       "grid_row": null,
       "grid_template_areas": null,
       "grid_template_columns": null,
       "grid_template_rows": null,
       "height": null,
       "justify_content": null,
       "justify_items": null,
       "left": null,
       "margin": null,
       "max_height": null,
       "max_width": null,
       "min_height": null,
       "min_width": null,
       "object_fit": null,
       "object_position": null,
       "order": null,
       "overflow": null,
       "padding": null,
       "right": null,
       "top": null,
       "visibility": null,
       "width": null
      }
     },
     "a3172cc690764403bf559fd3dbdcb85b": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "HTMLModel",
      "state": {
       "_dom_classes": [],
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "HTMLModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/controls",
       "_view_module_version": "2.0.0",
       "_view_name": "HTMLView",
       "description": "",
       "description_allow_html": false,
       "layout": "IPY_MODEL_422366b452594630a0c2f61653f11850",
       "placeholder": "​",
       "style": "IPY_MODEL_4a76a2696dde42f8a6b224bc684ba191",
       "tabbable": null,
       "tooltip": null,
       "value": " 512/512 [00:00&lt;00:00, 17109.11 examples/s]"
      }
     },
     "a456cd35487c4ebebaf2643941d69bb8": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "2.0.0",
      "model_name": "LayoutModel",
      "state": {
       "_model_module": "@jupyter-widgets/base",
       "_model_module_version": "2.0.0",
       "_model_name": "LayoutModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "LayoutView",
       "align_content": null,
       "align_items": null,
       "align_self": null,
       "border_bottom": null,
       "border_left": null,
       "border_right": null,
       "border_top": null,
       "bottom": null,
       "display": null,
       "flex": null,
       "flex_flow": null,
       "grid_area": null,
       "grid_auto_columns": null,
       "grid_auto_flow": null,
       "grid_auto_rows": null,
       "grid_column": null,
       "grid_gap": null,
       "grid_row": null,
       "grid_template_areas": null,
       "grid_template_columns": null,
       "grid_template_rows": null,
       "height": null,
       "justify_content": null,
       "justify_items": null,
       "left": null,
       "margin": null,
       "max_height": null,
       "max_width": null,
       "min_height": null,
       "min_width": null,
       "object_fit": null,
       "object_position": null,
       "order": null,
       "overflow": null,
       "padding": null,
       "right": null,
       "top": null,
       "visibility": null,
       "width": null
      }
     },
     "a500946dd1f44bf0bdd182fdb60c16f4": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "ProgressStyleModel",
      "state": {
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "ProgressStyleModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "StyleView",
       "bar_color": null,
       "description_width": ""
      }
     },
     "a9de63af9c82416c83ff338d0ade0478": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "HTMLStyleModel",
      "state": {
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "HTMLStyleModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "StyleView",
       "background": null,
       "description_width": "",
       "font_size": null,
       "text_color": null
      }
     },
     "ad6dc3b2ba7042eb91d77abdce5387a2": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "2.0.0",
      "model_name": "LayoutModel",
      "state": {
       "_model_module": "@jupyter-widgets/base",
       "_model_module_version": "2.0.0",
       "_model_name": "LayoutModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "LayoutView",
       "align_content": null,
       "align_items": null,
       "align_self": null,
       "border_bottom": null,
       "border_left": null,
       "border_right": null,
       "border_top": null,
       "bottom": null,
       "display": null,
       "flex": null,
       "flex_flow": null,
       "grid_area": null,
       "grid_auto_columns": null,
       "grid_auto_flow": null,
       "grid_auto_rows": null,
       "grid_column": null,
       "grid_gap": null,
       "grid_row": null,
       "grid_template_areas": null,
       "grid_template_columns": null,
       "grid_template_rows": null,
       "height": null,
       "justify_content": null,
       "justify_items": null,
       "left": null,
       "margin": null,
       "max_height": null,
       "max_width": null,
       "min_height": null,
       "min_width": null,
       "object_fit": null,
       "object_position": null,
       "order": null,
       "overflow": null,
       "padding": null,
       "right": null,
       "top": null,
       "visibility": null,
       "width": null
      }
     },
     "bea00b21cb514fbeb47e1b02f605b91f": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "FloatProgressModel",
      "state": {
       "_dom_classes": [],
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "FloatProgressModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/controls",
       "_view_module_version": "2.0.0",
       "_view_name": "ProgressView",
       "bar_style": "success",
       "description": "",
       "description_allow_html": false,
       "layout": "IPY_MODEL_08b83fd6f1de4269bf129eb3ef81a9d2",
       "max": 512.0,
       "min": 0.0,
       "orientation": "horizontal",
       "style": "IPY_MODEL_d5fa2f2790ac4c7cb40da41157ed5263",
       "tabbable": null,
       "tooltip": null,
       "value": 512.0
      }
     },
     "c72c8c0138e342d0b90676abe317b711": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "2.0.0",
      "model_name": "LayoutModel",
      "state": {
       "_model_module": "@jupyter-widgets/base",
       "_model_module_version": "2.0.0",
       "_model_name": "LayoutModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "LayoutView",
       "align_content": null,
       "align_items": null,
       "align_self": null,
       "border_bottom": null,
       "border_left": null,
       "border_right": null,
       "border_top": null,
       "bottom": null,
       "display": null,
       "flex": null,
       "flex_flow": null,
       "grid_area": null,
       "grid_auto_columns": null,
       "grid_auto_flow": null,
       "grid_auto_rows": null,
       "grid_column": null,
       "grid_gap": null,
       "grid_row": null,
       "grid_template_areas": null,
       "grid_template_columns": null,
       "grid_template_rows": null,
       "height": null,
       "justify_content": null,
       "justify_items": null,
       "left": null,
       "margin": null,
       "max_height": null,
       "max_width": null,
       "min_height": null,
       "min_width": null,
       "object_fit": null,
       "object_position": null,
       "order": null,
       "overflow": null,
       "padding": null,
       "right": null,
       "top": null,
       "visibility": null,
       "width": null
      }
     },
     "cfe32efb5f7c44b2b1adf60d6199854d": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "2.0.0",
      "model_name": "LayoutModel",
      "state": {
       "_model_module": "@jupyter-widgets/base",
       "_model_module_version": "2.0.0",
       "_model_name": "LayoutModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "LayoutView",
       "align_content": null,
       "align_items": null,
       "align_self": null,
       "border_bottom": null,
       "border_left": null,
       "border_right": null,
       "border_top": null,
       "bottom": null,
       "display": null,
       "flex": null,
       "flex_flow": null,
       "grid_area": null,
       "grid_auto_columns": null,
       "grid_auto_flow": null,
       "grid_auto_rows": null,
       "grid_column": null,
       "grid_gap": null,
       "grid_row": null,
       "grid_template_areas": null,
       "grid_template_columns": null,
       "grid_template_rows": null,
       "height": null,
       "justify_content": null,
       "justify_items": null,
       "left": null,
       "margin": null,
       "max_height": null,
       "max_width": null,
       "min_height": null,
       "min_width": null,
       "object_fit": null,
       "object_position": null,
       "order": null,
       "overflow": null,
       "padding": null,
       "right": null,
       "top": null,
       "visibility": null,
       "width": null
      }
     },
     "d010eac355434dcc8b678155444be90d": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "2.0.0",
      "model_name": "LayoutModel",
      "state": {
       "_model_module": "@jupyter-widgets/base",
       "_model_module_version": "2.0.0",
       "_model_name": "LayoutModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "LayoutView",
       "align_content": null,
       "align_items": null,
       "align_self": null,
       "border_bottom": null,
       "border_left": null,
       "border_right": null,
       "border_top": null,
       "bottom": null,
       "display": null,
       "flex": null,
       "flex_flow": null,
       "grid_area": null,
       "grid_auto_columns": null,
       "grid_auto_flow": null,
       "grid_auto_rows": null,
       "grid_column": null,
       "grid_gap": null,
       "grid_row": null,
       "grid_template_areas": null,
       "grid_template_columns": null,
       "grid_template_rows": null,
       "height": null,
       "justify_content": null,
       "justify_items": null,
       "left": null,
       "margin": null,
       "max_height": null,
       "max_width": null,
       "min_height": null,
       "min_width": null,
       "object_fit": null,
       "object_position": null,
       "order": null,
       "overflow": null,
       "padding": null,
       "right": null,
       "top": null,
       "visibility": null,
       "width": null
      }
     },
     "d03b55c809f3435293061830266b9839": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "HBoxModel",
      "state": {
       "_dom_classes": [],
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "HBoxModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/controls",
       "_view_module_version": "2.0.0",
       "_view_name": "HBoxView",
       "box_style": "",
       "children": [
        "IPY_MODEL_57b4bc07f8f34816805d30b97c139fb0",
        "IPY_MODEL_7191cb6c799c4ada813e63e938fd3f31",
        "IPY_MODEL_ec5b4a9d9e074f0cbd386eb1835d735d"
       ],
       "layout": "IPY_MODEL_ad6dc3b2ba7042eb91d77abdce5387a2",
       "tabbable": null,
       "tooltip": null
      }
     },
     "d3a3164a888444d9a4ce8cacea3c04b7": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "HTMLModel",
      "state": {
       "_dom_classes": [],
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "HTMLModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/controls",
       "_view_module_version": "2.0.0",
       "_view_name": "HTMLView",
       "description": "",
       "description_allow_html": false,
       "layout": "IPY_MODEL_d010eac355434dcc8b678155444be90d",
       "placeholder": "​",
       "style": "IPY_MODEL_d6389b1669a6440e9581d277d320fb99",
       "tabbable": null,
       "tooltip": null,
       "value": "Tokenizing train dataset: 100%"
      }
     },
     "d5fa2f2790ac4c7cb40da41157ed5263": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "ProgressStyleModel",
      "state": {
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "ProgressStyleModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "StyleView",
       "bar_color": null,
       "description_width": ""
      }
     },
     "d6389b1669a6440e9581d277d320fb99": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "HTMLStyleModel",
      "state": {
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "HTMLStyleModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/base",
       "_view_module_version": "2.0.0",
       "_view_name": "StyleView",
       "background": null,
       "description_width": "",
       "font_size": null,
       "text_color": null
      }
     },
     "ec026ad148ee45af9420b0fc3cdb362e": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "HTMLModel",
      "state": {
       "_dom_classes": [],
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "HTMLModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/controls",
       "_view_module_version": "2.0.0",
       "_view_name": "HTMLView",
       "description": "",
       "description_allow_html": false,
       "layout": "IPY_MODEL_cfe32efb5f7c44b2b1adf60d6199854d",
       "placeholder": "​",
       "style": "IPY_MODEL_a9de63af9c82416c83ff338d0ade0478",
       "tabbable": null,
       "tooltip": null,
       "value": " 512/512 [00:00&lt;00:00, 777.25 examples/s]"
      }
     },
     "ec5b4a9d9e074f0cbd386eb1835d735d": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "2.0.0",
      "model_name": "HTMLModel",
      "state": {
       "_dom_classes": [],
       "_model_module": "@jupyter-widgets/controls",
       "_model_module_version": "2.0.0",
       "_model_name": "HTMLModel",
       "_view_count": null,
       "_view_module": "@jupyter-widgets/controls",
       "_view_module_version": "2.0.0",
       "_view_name": "HTMLView",
       "description": "",
       "description_allow_html": false,
       "layout": "IPY_MODEL_c72c8c0138e342d0b90676abe317b711",
       "placeholder": "​",
       "style": "IPY_MODEL_45b14fb7e9e04edbad0f6bf883013f99",
       "tabbable": null,
       "tooltip": null,
       "value": " 9985/9985 [00:00&lt;00:00, 39392.87 examples/s]"
      }
     }
    },
    "version_major": 2,
    "version_minor": 0
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
