{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "926bada6" }, "source": [ "##### Copyright 2025 Google LLC." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "cellView": "form", "id": "a110dfce" }, "outputs": [], "source": [ "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", "# you may not use this file except in compliance with the License.\n", "# You may obtain a copy of the License at\n", "#\n", "# https://www.apache.org/licenses/LICENSE-2.0\n", "#\n", "# Unless required by applicable law or agreed to in writing, software\n", "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", "# See the License for the specific language governing permissions and\n", "# limitations under the License." ] }, { "cell_type": "markdown", "metadata": { "id": "f9673bd6" }, "source": [ "\n", " \n", " \n", " \n", " \n", " \n", "
\n", " View on ai.google.dev\n", " \n", " Run in Google Colab\n", " \n", " Run in Kaggle\n", " \n", " Open in Vertex AI\n", " \n", " View source on GitHub\n", "
" ] }, { "cell_type": "markdown", "metadata": { "id": "e624ec07" }, "source": [ "# Full Model Fine-Tune using Hugging Face Transformers\n", "\n", "This guide walks you through how to fine-tune Gemma on a mobile game NPC dataset using Hugging Face [Transformers](https://huggingface.co/docs/transformers/index) and [TRL](https://huggingface.co/docs/trl/index). You will learn:\n", "\n", "- Setup development environment\n", "- Prepare the fine-tuning dataset\n", "- Full model fine-tuning Gemma using TRL and the SFTTrainer\n", "- Test Model Inference and vibe checks\n", "\n", "> Note: This guide was created to run on a Google colaboratory account using a NVIDIA T4 GPU with 16GB and Gemma 270m, but can be adapted to run on bigger GPUs and bigger models.\n", "\n", "## Setup development environment\n", "\n", "The first step is to install Hugging Face Libraries, including TRL, and datasets to fine-tune open model, including different RLHF and alignment techniques." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "id": "BEK9IfKBqQaA" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Collecting torch\n", " Obtaining dependency information for torch from https://files.pythonhosted.org/packages/5a/63/4fdc45a0304536e75a5e1b1bbfb1b56dd0e2743c48ee83ca729f7ce44162/torch-2.8.0-cp311-cp311-manylinux_2_28_x86_64.whl.metadata\n", " Downloading torch-2.8.0-cp311-cp311-manylinux_2_28_x86_64.whl.metadata (30 kB)\n", "Collecting tensorboard\n", " Obtaining dependency information for tensorboard from https://files.pythonhosted.org/packages/9c/d9/a5db55f88f258ac669a92858b70a714bbbd5acd993820b41ec4a96a4d77f/tensorboard-2.20.0-py3-none-any.whl.metadata\n", " Downloading tensorboard-2.20.0-py3-none-any.whl.metadata (1.8 kB)\n", "Collecting filelock (from torch)\n", " Obtaining dependency information for filelock from https://files.pythonhosted.org/packages/42/14/42b2651a2f46b022ccd948bca9f2d5af0fd8929c4eec235b8d6d844fbe67/filelock-3.19.1-py3-none-any.whl.metadata\n", " Downloading filelock-3.19.1-py3-none-any.whl.metadata (2.1 kB)\n", "Requirement already satisfied: typing-extensions>=4.10.0 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch) (4.15.0)\n", "Collecting sympy>=1.13.3 (from torch)\n", " Obtaining dependency information for sympy>=1.13.3 from https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl.metadata\n", " Downloading sympy-1.14.0-py3-none-any.whl.metadata (12 kB)\n", "Collecting networkx (from torch)\n", " Obtaining dependency information for networkx from https://files.pythonhosted.org/packages/eb/8d/776adee7bbf76365fdd7f2552710282c79a4ead5d2a46408c9043a2b70ba/networkx-3.5-py3-none-any.whl.metadata\n", " Downloading networkx-3.5-py3-none-any.whl.metadata (6.3 kB)\n", "Collecting jinja2 (from torch)\n", " Obtaining dependency information for jinja2 from https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl.metadata\n", " Downloading jinja2-3.1.6-py3-none-any.whl.metadata (2.9 kB)\n", "Collecting fsspec (from torch)\n", " Obtaining dependency information for fsspec from https://files.pythonhosted.org/packages/47/71/70db47e4f6ce3e5c37a607355f80da8860a33226be640226ac52cb05ef2e/fsspec-2025.9.0-py3-none-any.whl.metadata\n", " Downloading fsspec-2025.9.0-py3-none-any.whl.metadata (10 kB)\n", "Collecting nvidia-cuda-nvrtc-cu12==12.8.93 (from torch)\n", " Obtaining dependency information for nvidia-cuda-nvrtc-cu12==12.8.93 from https://files.pythonhosted.org/packages/05/6b/32f747947df2da6994e999492ab306a903659555dddc0fbdeb9d71f75e52/nvidia_cuda_nvrtc_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl.metadata\n", " Downloading nvidia_cuda_nvrtc_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl.metadata (1.7 kB)\n", "Collecting nvidia-cuda-runtime-cu12==12.8.90 (from torch)\n", " Obtaining dependency information for nvidia-cuda-runtime-cu12==12.8.90 from https://files.pythonhosted.org/packages/0d/9b/a997b638fcd068ad6e4d53b8551a7d30fe8b404d6f1804abf1df69838932/nvidia_cuda_runtime_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata\n", " Downloading nvidia_cuda_runtime_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (1.7 kB)\n", "Collecting nvidia-cuda-cupti-cu12==12.8.90 (from torch)\n", " Obtaining dependency information for nvidia-cuda-cupti-cu12==12.8.90 from https://files.pythonhosted.org/packages/f8/02/2adcaa145158bf1a8295d83591d22e4103dbfd821bcaf6f3f53151ca4ffa/nvidia_cuda_cupti_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata\n", " Downloading nvidia_cuda_cupti_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (1.7 kB)\n", "Collecting nvidia-cudnn-cu12==9.10.2.21 (from torch)\n", " Obtaining dependency information for nvidia-cudnn-cu12==9.10.2.21 from https://files.pythonhosted.org/packages/ba/51/e123d997aa098c61d029f76663dedbfb9bc8dcf8c60cbd6adbe42f76d049/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl.metadata\n", " Downloading nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl.metadata (1.8 kB)\n", "Collecting nvidia-cublas-cu12==12.8.4.1 (from torch)\n", " Obtaining dependency information for nvidia-cublas-cu12==12.8.4.1 from https://files.pythonhosted.org/packages/dc/61/e24b560ab2e2eaeb3c839129175fb330dfcfc29e5203196e5541a4c44682/nvidia_cublas_cu12-12.8.4.1-py3-none-manylinux_2_27_x86_64.whl.metadata\n", " Downloading nvidia_cublas_cu12-12.8.4.1-py3-none-manylinux_2_27_x86_64.whl.metadata (1.7 kB)\n", "Collecting nvidia-cufft-cu12==11.3.3.83 (from torch)\n", " Obtaining dependency information for nvidia-cufft-cu12==11.3.3.83 from https://files.pythonhosted.org/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata\n", " Downloading nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (1.7 kB)\n", "Collecting nvidia-curand-cu12==10.3.9.90 (from torch)\n", " Obtaining dependency information for nvidia-curand-cu12==10.3.9.90 from https://files.pythonhosted.org/packages/fb/aa/6584b56dc84ebe9cf93226a5cde4d99080c8e90ab40f0c27bda7a0f29aa1/nvidia_curand_cu12-10.3.9.90-py3-none-manylinux_2_27_x86_64.whl.metadata\n", " Downloading nvidia_curand_cu12-10.3.9.90-py3-none-manylinux_2_27_x86_64.whl.metadata (1.7 kB)\n", "Collecting nvidia-cusolver-cu12==11.7.3.90 (from torch)\n", " Obtaining dependency information for nvidia-cusolver-cu12==11.7.3.90 from https://files.pythonhosted.org/packages/85/48/9a13d2975803e8cf2777d5ed57b87a0b6ca2cc795f9a4f59796a910bfb80/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl.metadata\n", " Downloading nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl.metadata (1.8 kB)\n", "Collecting nvidia-cusparse-cu12==12.5.8.93 (from torch)\n", " Obtaining dependency information for nvidia-cusparse-cu12==12.5.8.93 from https://files.pythonhosted.org/packages/c2/f5/e1854cb2f2bcd4280c44736c93550cc300ff4b8c95ebe370d0aa7d2b473d/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata\n", " Downloading nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (1.8 kB)\n", "Collecting nvidia-cusparselt-cu12==0.7.1 (from torch)\n", " Obtaining dependency information for nvidia-cusparselt-cu12==0.7.1 from https://files.pythonhosted.org/packages/56/79/12978b96bd44274fe38b5dde5cfb660b1d114f70a65ef962bcbbed99b549/nvidia_cusparselt_cu12-0.7.1-py3-none-manylinux2014_x86_64.whl.metadata\n", " Downloading nvidia_cusparselt_cu12-0.7.1-py3-none-manylinux2014_x86_64.whl.metadata (7.0 kB)\n", "Collecting nvidia-nccl-cu12==2.27.3 (from torch)\n", " Obtaining dependency information for nvidia-nccl-cu12==2.27.3 from https://files.pythonhosted.org/packages/5c/5b/4e4fff7bad39adf89f735f2bc87248c81db71205b62bcc0d5ca5b606b3c3/nvidia_nccl_cu12-2.27.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata\n", " Downloading nvidia_nccl_cu12-2.27.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (2.0 kB)\n", "Collecting nvidia-nvtx-cu12==12.8.90 (from torch)\n", " Obtaining dependency information for nvidia-nvtx-cu12==12.8.90 from https://files.pythonhosted.org/packages/a2/eb/86626c1bbc2edb86323022371c39aa48df6fd8b0a1647bc274577f72e90b/nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata\n", " Downloading nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (1.8 kB)\n", "Collecting nvidia-nvjitlink-cu12==12.8.93 (from torch)\n", " Obtaining dependency information for nvidia-nvjitlink-cu12==12.8.93 from https://files.pythonhosted.org/packages/f6/74/86a07f1d0f42998ca31312f998bd3b9a7eff7f52378f4f270c8679c77fb9/nvidia_nvjitlink_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl.metadata\n", " Downloading nvidia_nvjitlink_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl.metadata (1.7 kB)\n", "Collecting nvidia-cufile-cu12==1.13.1.3 (from torch)\n", " Obtaining dependency information for nvidia-cufile-cu12==1.13.1.3 from https://files.pythonhosted.org/packages/bb/fe/1bcba1dfbfb8d01be8d93f07bfc502c93fa23afa6fd5ab3fc7c1df71038a/nvidia_cufile_cu12-1.13.1.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata\n", " Downloading nvidia_cufile_cu12-1.13.1.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (1.7 kB)\n", "Collecting triton==3.4.0 (from torch)\n", " Obtaining dependency information for triton==3.4.0 from https://files.pythonhosted.org/packages/7d/39/43325b3b651d50187e591eefa22e236b2981afcebaefd4f2fc0ea99df191/triton-3.4.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata\n", " Downloading triton-3.4.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata (1.7 kB)\n", "Requirement already satisfied: setuptools>=40.8.0 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from triton==3.4.0->torch) (65.5.0)\n", "Collecting absl-py>=0.4 (from tensorboard)\n", " Obtaining dependency information for absl-py>=0.4 from https://files.pythonhosted.org/packages/8f/aa/ba0014cc4659328dc818a28827be78e6d97312ab0cb98105a770924dc11e/absl_py-2.3.1-py3-none-any.whl.metadata\n", " Downloading absl_py-2.3.1-py3-none-any.whl.metadata (3.3 kB)\n", "Collecting grpcio>=1.48.2 (from tensorboard)\n", " Obtaining dependency information for grpcio>=1.48.2 from https://files.pythonhosted.org/packages/82/ea/a4820c4c44c8b35b1903a6c72a5bdccec92d0840cf5c858c498c66786ba5/grpcio-1.74.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata\n", " Downloading grpcio-1.74.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.8 kB)\n", "Collecting markdown>=2.6.8 (from tensorboard)\n", " Obtaining dependency information for markdown>=2.6.8 from https://files.pythonhosted.org/packages/70/ae/44c4a6a4cbb496d93c6257954260fe3a6e91b7bed2240e5dad2a717f5111/markdown-3.9-py3-none-any.whl.metadata\n", " Downloading markdown-3.9-py3-none-any.whl.metadata (5.1 kB)\n", "Collecting numpy>=1.12.0 (from tensorboard)\n", " Obtaining dependency information for numpy>=1.12.0 from https://files.pythonhosted.org/packages/10/a2/010b0e27ddeacab7839957d7a8f00e91206e0c2c47abbb5f35a2630e5387/numpy-2.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata\n", " Downloading numpy-2.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata (62 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m62.1/62.1 kB\u001b[0m \u001b[31m129.8 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m0:01\u001b[0m\n", "\u001b[?25hRequirement already satisfied: packaging in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from tensorboard) (25.0)\n", "Collecting pillow (from tensorboard)\n", " Obtaining dependency information for pillow from https://files.pythonhosted.org/packages/f2/2f/d7675ecae6c43e9f12aa8d58b6012683b20b6edfbdac7abcb4e6af7a3784/pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata\n", " Downloading pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata (9.0 kB)\n", "Collecting protobuf!=4.24.0,>=3.19.6 (from tensorboard)\n", " Obtaining dependency information for protobuf!=4.24.0,>=3.19.6 from https://files.pythonhosted.org/packages/5c/f6/88d77011b605ef979aace37b7703e4eefad066f7e84d935e5a696515c2dd/protobuf-6.32.1-cp39-abi3-manylinux2014_x86_64.whl.metadata\n", " Downloading protobuf-6.32.1-cp39-abi3-manylinux2014_x86_64.whl.metadata (593 bytes)\n", "Collecting tensorboard-data-server<0.8.0,>=0.7.0 (from tensorboard)\n", " Obtaining dependency information for tensorboard-data-server<0.8.0,>=0.7.0 from https://files.pythonhosted.org/packages/73/c6/825dab04195756cf8ff2e12698f22513b3db2f64925bdd41671bfb33aaa5/tensorboard_data_server-0.7.2-py3-none-manylinux_2_31_x86_64.whl.metadata\n", " Using cached tensorboard_data_server-0.7.2-py3-none-manylinux_2_31_x86_64.whl.metadata (1.1 kB)\n", "Collecting werkzeug>=1.0.1 (from tensorboard)\n", " Obtaining dependency information for werkzeug>=1.0.1 from https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl.metadata\n", " Downloading werkzeug-3.1.3-py3-none-any.whl.metadata (3.7 kB)\n", "Collecting mpmath<1.4,>=1.1.0 (from sympy>=1.13.3->torch)\n", " Obtaining dependency information for mpmath<1.4,>=1.1.0 from https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl.metadata\n", " Downloading mpmath-1.3.0-py3-none-any.whl.metadata (8.6 kB)\n", "Collecting MarkupSafe>=2.1.1 (from werkzeug>=1.0.1->tensorboard)\n", " Obtaining dependency information for MarkupSafe>=2.1.1 from https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata\n", " Downloading MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.0 kB)\n", "Downloading torch-2.8.0-cp311-cp311-manylinux_2_28_x86_64.whl (888.1 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m888.1/888.1 MB\u001b[0m \u001b[31m1.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading nvidia_cublas_cu12-12.8.4.1-py3-none-manylinux_2_27_x86_64.whl (594.3 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m594.3/594.3 MB\u001b[0m \u001b[31m2.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading nvidia_cuda_cupti_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (10.2 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m10.2/10.2 MB\u001b[0m \u001b[31m21.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m0:01\u001b[0m\n", "\u001b[?25hDownloading nvidia_cuda_nvrtc_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl (88.0 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m88.0/88.0 MB\u001b[0m \u001b[31m9.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading nvidia_cuda_runtime_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (954 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m954.8/954.8 kB\u001b[0m \u001b[31m13.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl (706.8 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m706.8/706.8 MB\u001b[0m \u001b[31m1.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (193.1 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m193.1/193.1 MB\u001b[0m \u001b[31m5.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading nvidia_cufile_cu12-1.13.1.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (1.2 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.2/1.2 MB\u001b[0m \u001b[31m13.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading nvidia_curand_cu12-10.3.9.90-py3-none-manylinux_2_27_x86_64.whl (63.6 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m63.6/63.6 MB\u001b[0m \u001b[31m11.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl (267.5 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m267.5/267.5 MB\u001b[0m \u001b[31m4.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (288.2 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m288.2/288.2 MB\u001b[0m \u001b[31m3.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading nvidia_cusparselt_cu12-0.7.1-py3-none-manylinux2014_x86_64.whl (287.2 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m287.2/287.2 MB\u001b[0m \u001b[31m3.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading nvidia_nccl_cu12-2.27.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (322.4 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m322.4/322.4 MB\u001b[0m \u001b[31m3.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading nvidia_nvjitlink_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl (39.3 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m39.3/39.3 MB\u001b[0m \u001b[31m18.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (89 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m90.0/90.0 kB\u001b[0m \u001b[31m1.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading triton-3.4.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (155.5 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m155.5/155.5 MB\u001b[0m \u001b[31m6.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading tensorboard-2.20.0-py3-none-any.whl (5.5 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m5.5/5.5 MB\u001b[0m \u001b[31m32.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading absl_py-2.3.1-py3-none-any.whl (135 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m135.8/135.8 kB\u001b[0m \u001b[31m3.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", "\u001b[?25hDownloading grpcio-1.74.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.2 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m6.2/6.2 MB\u001b[0m \u001b[31m31.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading markdown-3.9-py3-none-any.whl (107 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m107.4/107.4 kB\u001b[0m \u001b[31m2.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading numpy-2.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (16.9 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m16.9/16.9 MB\u001b[0m \u001b[31m29.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading protobuf-6.32.1-cp39-abi3-manylinux2014_x86_64.whl (322 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m322.0/322.0 kB\u001b[0m \u001b[31m5.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", "\u001b[?25hDownloading sympy-1.14.0-py3-none-any.whl (6.3 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m6.3/6.3 MB\u001b[0m \u001b[31m32.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hUsing cached tensorboard_data_server-0.7.2-py3-none-manylinux_2_31_x86_64.whl (6.6 MB)\n", "Downloading werkzeug-3.1.3-py3-none-any.whl (224 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m224.5/224.5 kB\u001b[0m \u001b[31m1.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading filelock-3.19.1-py3-none-any.whl (15 kB)\n", "Downloading fsspec-2025.9.0-py3-none-any.whl (199 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m199.3/199.3 kB\u001b[0m \u001b[31m1.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", "\u001b[?25hDownloading jinja2-3.1.6-py3-none-any.whl (134 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m134.9/134.9 kB\u001b[0m \u001b[31m554.2 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading networkx-3.5-py3-none-any.whl (2.0 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.0/2.0 MB\u001b[0m \u001b[31m9.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", "\u001b[?25hDownloading pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (6.6 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m6.6/6.6 MB\u001b[0m \u001b[31m32.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (23 kB)\n", "Using cached mpmath-1.3.0-py3-none-any.whl (536 kB)\n", "Installing collected packages: nvidia-cusparselt-cu12, mpmath, triton, tensorboard-data-server, sympy, protobuf, pillow, nvidia-nvtx-cu12, nvidia-nvjitlink-cu12, nvidia-nccl-cu12, nvidia-curand-cu12, nvidia-cufile-cu12, nvidia-cuda-runtime-cu12, nvidia-cuda-nvrtc-cu12, nvidia-cuda-cupti-cu12, nvidia-cublas-cu12, numpy, networkx, MarkupSafe, markdown, grpcio, fsspec, filelock, absl-py, werkzeug, nvidia-cusparse-cu12, nvidia-cufft-cu12, nvidia-cudnn-cu12, jinja2, tensorboard, nvidia-cusolver-cu12, torch\n", "Successfully installed MarkupSafe-3.0.2 absl-py-2.3.1 filelock-3.19.1 fsspec-2025.9.0 grpcio-1.74.0 jinja2-3.1.6 markdown-3.9 mpmath-1.3.0 networkx-3.5 numpy-2.3.3 nvidia-cublas-cu12-12.8.4.1 nvidia-cuda-cupti-cu12-12.8.90 nvidia-cuda-nvrtc-cu12-12.8.93 nvidia-cuda-runtime-cu12-12.8.90 nvidia-cudnn-cu12-9.10.2.21 nvidia-cufft-cu12-11.3.3.83 nvidia-cufile-cu12-1.13.1.3 nvidia-curand-cu12-10.3.9.90 nvidia-cusolver-cu12-11.7.3.90 nvidia-cusparse-cu12-12.5.8.93 nvidia-cusparselt-cu12-0.7.1 nvidia-nccl-cu12-2.27.3 nvidia-nvjitlink-cu12-12.8.93 nvidia-nvtx-cu12-12.8.90 pillow-11.3.0 protobuf-6.32.1 sympy-1.14.0 tensorboard-2.20.0 tensorboard-data-server-0.7.2 torch-2.8.0 triton-3.4.0 werkzeug-3.1.3\n", "\n", "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m25.2\u001b[0m\n", "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", "Note: you may need to restart the kernel to use updated packages.\n", "Collecting transformers\n", " Obtaining dependency information for transformers from https://files.pythonhosted.org/packages/71/7c/283c3dd35e00e22a7803a0b2a65251347b745474a82399be058bde1c9f15/transformers-4.56.1-py3-none-any.whl.metadata\n", " Downloading transformers-4.56.1-py3-none-any.whl.metadata (42 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m42.2/42.2 kB\u001b[0m \u001b[31m144.0 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hCollecting datasets\n", " Obtaining dependency information for datasets from https://files.pythonhosted.org/packages/e1/b1/80a59608b0c6030d63aad16390aeddec531a75971dc16ac9cd422defd64b/datasets-4.1.0-py3-none-any.whl.metadata\n", " Downloading datasets-4.1.0-py3-none-any.whl.metadata (18 kB)\n", "Collecting accelerate\n", " Obtaining dependency information for accelerate from https://files.pythonhosted.org/packages/5f/a0/d9ef19f780f319c21ee90ecfef4431cbeeca95bec7f14071785c17b6029b/accelerate-1.10.1-py3-none-any.whl.metadata\n", " Downloading accelerate-1.10.1-py3-none-any.whl.metadata (19 kB)\n", "Collecting evaluate\n", " Obtaining dependency information for evaluate from https://files.pythonhosted.org/packages/27/7e/de4f71df5e2992c2cfea6314c80c8d51a8c7a5b345a36428a67ca154325e/evaluate-0.4.5-py3-none-any.whl.metadata\n", " Downloading evaluate-0.4.5-py3-none-any.whl.metadata (9.5 kB)\n", "Collecting trl\n", " Obtaining dependency information for trl from https://files.pythonhosted.org/packages/0f/81/035cace9b8853df794db0499299273abef30de889602587efa2a95c7dccb/trl-0.23.0-py3-none-any.whl.metadata\n", " Downloading trl-0.23.0-py3-none-any.whl.metadata (11 kB)\n", "Requirement already satisfied: protobuf in /home/ryota/puffy/puffy/lib/python3.11/site-packages (6.32.1)\n", "Collecting sentencepiece\n", " Obtaining dependency information for sentencepiece from https://files.pythonhosted.org/packages/ef/66/fb191403ade791ad2c3c1e72fe8413e63781b08cfa3aa4c9dfc536d6e795/sentencepiece-0.2.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata\n", " Downloading sentencepiece-0.2.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata (10 kB)\n", "Requirement already satisfied: filelock in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from transformers) (3.19.1)\n", "Collecting huggingface-hub<1.0,>=0.34.0 (from transformers)\n", " Obtaining dependency information for huggingface-hub<1.0,>=0.34.0 from https://files.pythonhosted.org/packages/79/3d/55ef77a0539b0124efd47d8b3759bf49e880f57729f7123c0311b41a9bb8/huggingface_hub-0.34.5-py3-none-any.whl.metadata\n", " Downloading huggingface_hub-0.34.5-py3-none-any.whl.metadata (14 kB)\n", "Requirement already satisfied: numpy>=1.17 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from transformers) (2.3.3)\n", "Requirement already satisfied: packaging>=20.0 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from transformers) (25.0)\n", "Collecting pyyaml>=5.1 (from transformers)\n", " Obtaining dependency information for pyyaml>=5.1 from https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata\n", " Downloading PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (2.1 kB)\n", "Collecting regex!=2019.12.17 (from transformers)\n", " Obtaining dependency information for regex!=2019.12.17 from https://files.pythonhosted.org/packages/8a/a7/a470e7bc8259c40429afb6d6a517b40c03f2f3e455c44a01abc483a1c512/regex-2025.9.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata\n", " Downloading regex-2025.9.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (40 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m40.5/40.5 kB\u001b[0m \u001b[31m75.0 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0ma \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hCollecting requests (from transformers)\n", " Obtaining dependency information for requests from https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl.metadata\n", " Downloading requests-2.32.5-py3-none-any.whl.metadata (4.9 kB)\n", "Collecting tokenizers<=0.23.0,>=0.22.0 (from transformers)\n", " Obtaining dependency information for tokenizers<=0.23.0,>=0.22.0 from https://files.pythonhosted.org/packages/d4/61/aeab3402c26874b74bb67a7f2c4b569dde29b51032c5384db592e7b216f4/tokenizers-0.22.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata\n", " Downloading tokenizers-0.22.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (6.8 kB)\n", "Collecting safetensors>=0.4.3 (from transformers)\n", " Obtaining dependency information for safetensors>=0.4.3 from https://files.pythonhosted.org/packages/fe/5d/5a514d7b88e310c8b146e2404e0dc161282e78634d9358975fd56dfd14be/safetensors-0.6.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata\n", " Downloading safetensors-0.6.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.1 kB)\n", "Collecting tqdm>=4.27 (from transformers)\n", " Obtaining dependency information for tqdm>=4.27 from https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl.metadata\n", " Downloading tqdm-4.67.1-py3-none-any.whl.metadata (57 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m57.7/57.7 kB\u001b[0m \u001b[31m9.1 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hCollecting pyarrow>=21.0.0 (from datasets)\n", " Obtaining dependency information for pyarrow>=21.0.0 from https://files.pythonhosted.org/packages/74/dc/035d54638fc5d2971cbf1e987ccd45f1091c83bcf747281cf6cc25e72c88/pyarrow-21.0.0-cp311-cp311-manylinux_2_28_x86_64.whl.metadata\n", " Downloading pyarrow-21.0.0-cp311-cp311-manylinux_2_28_x86_64.whl.metadata (3.3 kB)\n", "Collecting dill<0.4.1,>=0.3.0 (from datasets)\n", " Obtaining dependency information for dill<0.4.1,>=0.3.0 from https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl.metadata\n", " Downloading dill-0.4.0-py3-none-any.whl.metadata (10 kB)\n", "Collecting pandas (from datasets)\n", " Obtaining dependency information for pandas from https://files.pythonhosted.org/packages/8b/ef/0e2ffb30b1f7fbc9a588bd01e3c14a0d96854d09a887e15e30cc19961227/pandas-2.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata\n", " Downloading pandas-2.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (91 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m91.2/91.2 kB\u001b[0m \u001b[31m114.6 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0ma \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hCollecting xxhash (from datasets)\n", " Obtaining dependency information for xxhash from https://files.pythonhosted.org/packages/d9/72/9256303f10e41ab004799a4aa74b80b3c5977d6383ae4550548b24bd1971/xxhash-3.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata\n", " Downloading xxhash-3.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (12 kB)\n", "Collecting multiprocess<0.70.17 (from datasets)\n", " Obtaining dependency information for multiprocess<0.70.17 from https://files.pythonhosted.org/packages/50/15/b56e50e8debaf439f44befec5b2af11db85f6e0f344c3113ae0be0593a91/multiprocess-0.70.16-py311-none-any.whl.metadata\n", " Downloading multiprocess-0.70.16-py311-none-any.whl.metadata (7.2 kB)\n", "Requirement already satisfied: fsspec[http]<=2025.9.0,>=2023.1.0 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from datasets) (2025.9.0)\n", "Requirement already satisfied: psutil in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from accelerate) (7.0.0)\n", "Requirement already satisfied: torch>=2.0.0 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from accelerate) (2.8.0)\n", "Collecting aiohttp!=4.0.0a0,!=4.0.0a1 (from fsspec[http]<=2025.9.0,>=2023.1.0->datasets)\n", " Obtaining dependency information for aiohttp!=4.0.0a0,!=4.0.0a1 from https://files.pythonhosted.org/packages/c6/82/1ddf0ea4f2f3afe79dffed5e8a246737cff6cbe781887a6a170299e33204/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata\n", " Downloading aiohttp-3.12.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (7.7 kB)\n", "Requirement already satisfied: typing-extensions>=3.7.4.3 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from huggingface-hub<1.0,>=0.34.0->transformers) (4.15.0)\n", "Collecting hf-xet<2.0.0,>=1.1.3 (from huggingface-hub<1.0,>=0.34.0->transformers)\n", " Obtaining dependency information for hf-xet<2.0.0,>=1.1.3 from https://files.pythonhosted.org/packages/15/07/86397573efefff941e100367bbda0b21496ffcdb34db7ab51912994c32a2/hf_xet-1.1.10-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata\n", " Downloading hf_xet-1.1.10-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.7 kB)\n", "Collecting charset_normalizer<4,>=2 (from requests->transformers)\n", " Obtaining dependency information for charset_normalizer<4,>=2 from https://files.pythonhosted.org/packages/87/df/b7737ff046c974b183ea9aa111b74185ac8c3a326c6262d413bd5a1b8c69/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata\n", " Downloading charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (36 kB)\n", "Collecting idna<4,>=2.5 (from requests->transformers)\n", " Obtaining dependency information for idna<4,>=2.5 from https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl.metadata\n", " Downloading idna-3.10-py3-none-any.whl.metadata (10 kB)\n", "Collecting urllib3<3,>=1.21.1 (from requests->transformers)\n", " Obtaining dependency information for urllib3<3,>=1.21.1 from https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl.metadata\n", " Downloading urllib3-2.5.0-py3-none-any.whl.metadata (6.5 kB)\n", "Collecting certifi>=2017.4.17 (from requests->transformers)\n", " Obtaining dependency information for certifi>=2017.4.17 from https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl.metadata\n", " Downloading certifi-2025.8.3-py3-none-any.whl.metadata (2.4 kB)\n", "Requirement already satisfied: sympy>=1.13.3 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (1.14.0)\n", "Requirement already satisfied: networkx in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (3.5)\n", "Requirement already satisfied: jinja2 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (3.1.6)\n", "Requirement already satisfied: nvidia-cuda-nvrtc-cu12==12.8.93 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (12.8.93)\n", "Requirement already satisfied: nvidia-cuda-runtime-cu12==12.8.90 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (12.8.90)\n", "Requirement already satisfied: nvidia-cuda-cupti-cu12==12.8.90 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (12.8.90)\n", "Requirement already satisfied: nvidia-cudnn-cu12==9.10.2.21 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (9.10.2.21)\n", "Requirement already satisfied: nvidia-cublas-cu12==12.8.4.1 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (12.8.4.1)\n", "Requirement already satisfied: nvidia-cufft-cu12==11.3.3.83 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (11.3.3.83)\n", "Requirement already satisfied: nvidia-curand-cu12==10.3.9.90 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (10.3.9.90)\n", "Requirement already satisfied: nvidia-cusolver-cu12==11.7.3.90 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (11.7.3.90)\n", "Requirement already satisfied: nvidia-cusparse-cu12==12.5.8.93 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (12.5.8.93)\n", "Requirement already satisfied: nvidia-cusparselt-cu12==0.7.1 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (0.7.1)\n", "Requirement already satisfied: nvidia-nccl-cu12==2.27.3 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (2.27.3)\n", "Requirement already satisfied: nvidia-nvtx-cu12==12.8.90 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (12.8.90)\n", "Requirement already satisfied: nvidia-nvjitlink-cu12==12.8.93 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (12.8.93)\n", "Requirement already satisfied: nvidia-cufile-cu12==1.13.1.3 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (1.13.1.3)\n", "Requirement already satisfied: triton==3.4.0 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from torch>=2.0.0->accelerate) (3.4.0)\n", "Requirement already satisfied: setuptools>=40.8.0 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from triton==3.4.0->torch>=2.0.0->accelerate) (65.5.0)\n", "Requirement already satisfied: python-dateutil>=2.8.2 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from pandas->datasets) (2.9.0.post0)\n", "Collecting pytz>=2020.1 (from pandas->datasets)\n", " Obtaining dependency information for pytz>=2020.1 from https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl.metadata\n", " Downloading pytz-2025.2-py2.py3-none-any.whl.metadata (22 kB)\n", "Collecting tzdata>=2022.7 (from pandas->datasets)\n", " Obtaining dependency information for tzdata>=2022.7 from https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl.metadata\n", " Downloading tzdata-2025.2-py2.py3-none-any.whl.metadata (1.4 kB)\n", "Collecting aiohappyeyeballs>=2.5.0 (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.9.0,>=2023.1.0->datasets)\n", " Obtaining dependency information for aiohappyeyeballs>=2.5.0 from https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl.metadata\n", " Downloading aiohappyeyeballs-2.6.1-py3-none-any.whl.metadata (5.9 kB)\n", "Collecting aiosignal>=1.4.0 (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.9.0,>=2023.1.0->datasets)\n", " Obtaining dependency information for aiosignal>=1.4.0 from https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl.metadata\n", " Downloading aiosignal-1.4.0-py3-none-any.whl.metadata (3.7 kB)\n", "Collecting attrs>=17.3.0 (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.9.0,>=2023.1.0->datasets)\n", " Obtaining dependency information for attrs>=17.3.0 from https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl.metadata\n", " Downloading attrs-25.3.0-py3-none-any.whl.metadata (10 kB)\n", "Collecting frozenlist>=1.1.1 (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.9.0,>=2023.1.0->datasets)\n", " Obtaining dependency information for frozenlist>=1.1.1 from https://files.pythonhosted.org/packages/4d/83/220a374bd7b2aeba9d0725130665afe11de347d95c3620b9b82cc2fcab97/frozenlist-1.7.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata\n", " Downloading frozenlist-1.7.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (18 kB)\n", "Collecting multidict<7.0,>=4.5 (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.9.0,>=2023.1.0->datasets)\n", " Obtaining dependency information for multidict<7.0,>=4.5 from https://files.pythonhosted.org/packages/00/6e/fac58b1072a6fc59af5e7acb245e8754d3e1f97f4f808a6559951f72a0d4/multidict-6.6.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata\n", " Downloading multidict-6.6.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (5.3 kB)\n", "Collecting propcache>=0.2.0 (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.9.0,>=2023.1.0->datasets)\n", " Obtaining dependency information for propcache>=0.2.0 from https://files.pythonhosted.org/packages/5d/e6/116ba39448753b1330f48ab8ba927dcd6cf0baea8a0ccbc512dfb49ba670/propcache-0.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata\n", " Downloading propcache-0.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (12 kB)\n", "Collecting yarl<2.0,>=1.17.0 (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.9.0,>=2023.1.0->datasets)\n", " Obtaining dependency information for yarl<2.0,>=1.17.0 from https://files.pythonhosted.org/packages/00/70/8f78a95d6935a70263d46caa3dd18e1f223cf2f2ff2037baa01a22bc5b22/yarl-1.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata\n", " Downloading yarl-1.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (73 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m73.9/73.9 kB\u001b[0m \u001b[31m124.0 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0ma \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hRequirement already satisfied: six>=1.5 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from python-dateutil>=2.8.2->pandas->datasets) (1.17.0)\n", "Requirement already satisfied: mpmath<1.4,>=1.1.0 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from sympy>=1.13.3->torch>=2.0.0->accelerate) (1.3.0)\n", "Requirement already satisfied: MarkupSafe>=2.0 in /home/ryota/puffy/puffy/lib/python3.11/site-packages (from jinja2->torch>=2.0.0->accelerate) (3.0.2)\n", "Downloading transformers-4.56.1-py3-none-any.whl (11.6 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m11.6/11.6 MB\u001b[0m \u001b[31m16.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading datasets-4.1.0-py3-none-any.whl (503 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m503.4/503.4 kB\u001b[0m \u001b[31m9.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", "\u001b[?25hDownloading accelerate-1.10.1-py3-none-any.whl (374 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m374.9/374.9 kB\u001b[0m \u001b[31m6.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", "\u001b[?25hDownloading evaluate-0.4.5-py3-none-any.whl (84 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m84.1/84.1 kB\u001b[0m \u001b[31m1.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading trl-0.23.0-py3-none-any.whl (564 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m564.7/564.7 kB\u001b[0m \u001b[31m9.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", "\u001b[?25hDownloading sentencepiece-0.2.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (1.4 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.4/1.4 MB\u001b[0m \u001b[31m16.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading dill-0.4.0-py3-none-any.whl (119 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m119.7/119.7 kB\u001b[0m \u001b[31m2.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading huggingface_hub-0.34.5-py3-none-any.whl (562 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m562.2/562.2 kB\u001b[0m \u001b[31m9.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", "\u001b[?25hDownloading multiprocess-0.70.16-py311-none-any.whl (143 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m143.5/143.5 kB\u001b[0m \u001b[31m2.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", "\u001b[?25hDownloading pyarrow-21.0.0-cp311-cp311-manylinux_2_28_x86_64.whl (42.8 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m42.8/42.8 MB\u001b[0m \u001b[31m19.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0mm\n", "\u001b[?25hDownloading PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (762 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m763.0/763.0 kB\u001b[0m \u001b[31m11.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading regex-2025.9.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (798 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m799.0/799.0 kB\u001b[0m \u001b[31m12.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading requests-2.32.5-py3-none-any.whl (64 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m64.7/64.7 kB\u001b[0m \u001b[31m1.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading safetensors-0.6.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (485 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m485.8/485.8 kB\u001b[0m \u001b[31m8.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", "\u001b[?25hDownloading tokenizers-0.22.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.3 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.3/3.3 MB\u001b[0m \u001b[31m26.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading tqdm-4.67.1-py3-none-any.whl (78 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m78.5/78.5 kB\u001b[0m \u001b[31m1.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0meta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading pandas-2.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (12.4 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m12.4/12.4 MB\u001b[0m \u001b[31m16.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading xxhash-3.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (194 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m194.8/194.8 kB\u001b[0m \u001b[31m4.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", "\u001b[?25hDownloading aiohttp-3.12.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.7 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.7/1.7 MB\u001b[0m \u001b[31m20.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading certifi-2025.8.3-py3-none-any.whl (161 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m161.2/161.2 kB\u001b[0m \u001b[31m3.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (150 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m150.3/150.3 kB\u001b[0m \u001b[31m2.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading hf_xet-1.1.10-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.2 MB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.2/3.2 MB\u001b[0m \u001b[31m22.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n", "\u001b[?25hDownloading idna-3.10-py3-none-any.whl (70 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m70.4/70.4 kB\u001b[0m \u001b[31m1.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0meta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading pytz-2025.2-py2.py3-none-any.whl (509 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m509.2/509.2 kB\u001b[0m \u001b[31m9.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", "\u001b[?25hDownloading tzdata-2025.2-py2.py3-none-any.whl (347 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m347.8/347.8 kB\u001b[0m \u001b[31m6.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading urllib3-2.5.0-py3-none-any.whl (129 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m129.8/129.8 kB\u001b[0m \u001b[31m2.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading aiohappyeyeballs-2.6.1-py3-none-any.whl (15 kB)\n", "Downloading aiosignal-1.4.0-py3-none-any.whl (7.5 kB)\n", "Downloading attrs-25.3.0-py3-none-any.whl (63 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m63.8/63.8 kB\u001b[0m \u001b[31m1.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading frozenlist-1.7.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (235 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m235.3/235.3 kB\u001b[0m \u001b[31m4.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading multidict-6.6.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (246 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m246.7/246.7 kB\u001b[0m \u001b[31m4.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", "\u001b[?25hDownloading propcache-0.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (213 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m213.5/213.5 kB\u001b[0m \u001b[31m4.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading yarl-1.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (348 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m349.0/349.0 kB\u001b[0m \u001b[31m6.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", "\u001b[?25hInstalling collected packages: pytz, xxhash, urllib3, tzdata, tqdm, sentencepiece, safetensors, regex, pyyaml, pyarrow, propcache, multidict, idna, hf-xet, frozenlist, dill, charset_normalizer, certifi, attrs, aiohappyeyeballs, yarl, requests, pandas, multiprocess, aiosignal, huggingface-hub, aiohttp, tokenizers, accelerate, transformers, datasets, trl, evaluate\n", "Successfully installed accelerate-1.10.1 aiohappyeyeballs-2.6.1 aiohttp-3.12.15 aiosignal-1.4.0 attrs-25.3.0 certifi-2025.8.3 charset_normalizer-3.4.3 datasets-4.1.0 dill-0.4.0 evaluate-0.4.5 frozenlist-1.7.0 hf-xet-1.1.10 huggingface-hub-0.34.5 idna-3.10 multidict-6.6.4 multiprocess-0.70.16 pandas-2.3.2 propcache-0.3.2 pyarrow-21.0.0 pytz-2025.2 pyyaml-6.0.2 regex-2025.9.1 requests-2.32.5 safetensors-0.6.2 sentencepiece-0.2.1 tokenizers-0.22.0 tqdm-4.67.1 transformers-4.56.1 trl-0.23.0 tzdata-2025.2 urllib3-2.5.0 xxhash-3.5.0 yarl-1.20.1\n", "\n", "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m25.2\u001b[0m\n", "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", "Note: you may need to restart the kernel to use updated packages.\n" ] } ], "source": [ "# Install Pytorch & other libraries\n", "%pip install torch tensorboard\n", "\n", "# Install Hugging Face libraries\n", "%pip install transformers datasets accelerate evaluate trl protobuf sentencepiece\n", "\n", "# COMMENT IN: if you are running on a GPU that supports BF16 data type and flash attn, such as NVIDIA L4 or NVIDIA A100\n", "#% pip install flash-attn" ] }, { "cell_type": "markdown", "metadata": { "id": "7ef3d54b" }, "source": [ "> _Note: If you are using a GPU with Ampere architecture (such as NVIDIA L4) or newer, you can use Flash attention. Flash Attention is a method that significantly speeds computations up and reduces memory usage from quadratic to linear in sequence length, leading to acelerating training up to 3x. Learn more at [FlashAttention](https://github.com/Dao-AILab/flash-attention/tree/main)._\n", "\n", "Before you can start training, you have to make sure that you accepted the terms of use for Gemma. You can accept the license on [Hugging Face](http://huggingface.co/google/gemma-3-270m-it) by clicking on the Agree and access repository button on the model page at: http://huggingface.co/google/gemma-3-270m-it\n", "\n", "After you have accepted the license, you need a valid Hugging Face Token to access the model. If you are running inside a Google Colab, you can securely use your Hugging Face Token using the Colab secrets otherwise you can set the token as directly in the `login` method. Make sure your token has write access too, as you push your model to the Hub during training." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "id": "b6d79c93" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/ryota/puffy/puffy/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n", "Note: Environment variable`HF_TOKEN` is set and is the current active token independently from the token you've just configured.\n" ] } ], "source": [ "# from google.colab import userdata\n", "from huggingface_hub import login\n", "from dotenv import load_dotenv\n", "import os\n", "\n", "load_dotenv() # take environment variables from .env.\n", "hf_token = os.getenv(\"HF_TOKEN\")\n", "\n", "# Login into Hugging Face Hub\n", "# hf_token = userdata.get('HF_TOKEN') # If you are running inside a Google Colab\n", "login(hf_token)" ] }, { "cell_type": "markdown", "metadata": { "id": "xnbflqW6YJls" }, "source": [ "You can keep the results on Colab's local virtual machine. However, we highly recommend saving your intermediate results to your Google Drive. This ensures your training results are safe and allows you to easily compare and select the best model." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "id": "jUUs-NjaYLf7" }, "outputs": [], "source": [ "# from google.colab import drive\n", "# drive.mount('/content/drive')" ] }, { "cell_type": "markdown", "metadata": { "id": "3bDMa9CMCdzv" }, "source": [ "Select the base model to fine-tune, adjust the checkpoint directory and the learning rate." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "id": "6J3PWm4SzoSw" }, "outputs": [], "source": [ "base_model = \"google/gemma-3-270m-it\" # @param [\"google/gemma-3-270m-it\",\"google/gemma-3-1b-it\",\"google/gemma-3-4b-it\",\"google/gemma-3-12b-it\",\"google/gemma-3-27b-it\"] {\"allow-input\":true}\n", "# checkpoint_dir = \"/content/drive/MyDrive/MyGemmaNPC\" #@param {type:\"string\"}\n", "checkpoint_dir = \"./\" #@param {type:\"string\"}\n", "learning_rate = 5e-5 #@param {type:\"number\"}" ] }, { "cell_type": "markdown", "metadata": { "id": "42c60525" }, "source": [ "## Create and prepare the fine-tuning dataset\n", "\n", "The [bebechien/MobileGameNPC](https://huggingface.co/datasets/bebechien/MobileGameNPC) dataset provides a small sample conversations between a player and two Alien NPCs (a Martian and a Venusian), each with a unique speaking style. For instance, the Martian NPC speaks with an accent that replaces 's' sounds with 'z', uses 'da' for 'the', 'diz' for 'this', and includes occasional clicks like `*k'tak*`.\n", "\n", "This dataset demonstrates a key principle for fine-tuning: the required dataset size depends on the desired output.\n", "\n", "- To teach the model a stylistic variation of a language it already knows, such as the Martian's accent, a small dataset with as few as 10 to 20 examples can be sufficient.\n", "- However, to teach the model a completely new or mixed alien language, a significantly larger dataset would be required." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "colab": { "referenced_widgets": [ "2fee8582aef54ffba9a9250c425c0983", "00d188518d8c4dbb9e9433bb889f7f76", "13f7fe6fccaf4fb38ba9104522526a5a", "b09f895f45594ce9984fa7b37299d1a3" ] }, "id": "bc3BYl72pWhp", "outputId": "563cceb3-21a9-4b7c-b91b-067d594bfb9c" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[{'content': 'Hello there.', 'role': 'user'}, {'content': \"Gree-tongs, Terran. You'z a long way from da Blue-Sphere, yez?\", 'role': 'assistant'}]\n" ] } ], "source": [ "from datasets import load_dataset\n", "\n", "def create_conversation(sample):\n", " return {\n", " \"messages\": [\n", " {\"role\": \"user\", \"content\": sample[\"player\"]},\n", " {\"role\": \"assistant\", \"content\": sample[\"alien\"]}\n", " ]\n", " }\n", "\n", "npc_type = \"martian\" #@param [\"martian\", \"venusian\"]\n", "\n", "# Load dataset from the Hub\n", "dataset = load_dataset(\"bebechien/MobileGameNPC\", npc_type, split=\"train\")\n", "\n", "# Convert dataset to conversational format\n", "dataset = dataset.map(create_conversation, remove_columns=dataset.features, batched=False)\n", "\n", "# Split dataset into 80% training samples and 20% test samples\n", "dataset = dataset.train_test_split(test_size=0.2, shuffle=False)\n", "\n", "# Print formatted user prompt\n", "print(dataset[\"train\"][0][\"messages\"])" ] }, { "cell_type": "markdown", "metadata": { "id": "c0eb2e06" }, "source": [ "## Fine-tune Gemma using TRL and the SFTTrainer\n", "\n", "You are now ready to fine-tune your model. Hugging Face TRL [SFTTrainer](https://huggingface.co/docs/trl/sft_trainer) makes it straightforward to supervise fine-tune open LLMs. The `SFTTrainer` is a subclass of the `Trainer` from the `transformers` library and supports all the same features,\n", "\n", "The following code loads the Gemma model and tokenizer from Hugging Face." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "id": "18069ed2", "outputId": "25e1329b-17bd-4934-a7c7-67da602a8752" }, "outputs": [ { "ename": "OSError", "evalue": "We couldn't connect to 'https://huggingface.co' to load the files, and couldn't find them in the cached files.\nCheck your internet connection or see how to run the library in offline mode at 'https://huggingface.co/docs/transformers/installation#offline-mode'.", "output_type": "error", "traceback": [ "\u001b[31m---------------------------------------------------------------------------\u001b[39m", "\u001b[31mHTTPError\u001b[39m Traceback (most recent call last)", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/huggingface_hub/utils/_http.py:409\u001b[39m, in \u001b[36mhf_raise_for_status\u001b[39m\u001b[34m(response, endpoint_name)\u001b[39m\n\u001b[32m 408\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m409\u001b[39m \u001b[43mresponse\u001b[49m\u001b[43m.\u001b[49m\u001b[43mraise_for_status\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 410\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m HTTPError \u001b[38;5;28;01mas\u001b[39;00m e:\n", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/requests/models.py:1026\u001b[39m, in \u001b[36mResponse.raise_for_status\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 1025\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m http_error_msg:\n\u001b[32m-> \u001b[39m\u001b[32m1026\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m HTTPError(http_error_msg, response=\u001b[38;5;28mself\u001b[39m)\n", "\u001b[31mHTTPError\u001b[39m: 403 Client Error: Forbidden for url: https://huggingface.co/google/gemma-3-270m-it/resolve/main/config.json", "\nThe above exception was the direct cause of the following exception:\n", "\u001b[31mHfHubHTTPError\u001b[39m Traceback (most recent call last)", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/huggingface_hub/file_download.py:1546\u001b[39m, in \u001b[36m_get_metadata_or_catch_error\u001b[39m\u001b[34m(repo_id, filename, repo_type, revision, endpoint, proxies, etag_timeout, headers, token, local_files_only, relative_filename, storage_folder)\u001b[39m\n\u001b[32m 1545\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m1546\u001b[39m metadata = \u001b[43mget_hf_file_metadata\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 1547\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m=\u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mproxies\u001b[49m\u001b[43m=\u001b[49m\u001b[43mproxies\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43metag_timeout\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtoken\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtoken\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mendpoint\u001b[49m\u001b[43m=\u001b[49m\u001b[43mendpoint\u001b[49m\n\u001b[32m 1548\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1549\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m EntryNotFoundError \u001b[38;5;28;01mas\u001b[39;00m http_error:\n", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/huggingface_hub/utils/_validators.py:114\u001b[39m, in \u001b[36mvalidate_hf_hub_args.._inner_fn\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 112\u001b[39m kwargs = smoothly_deprecate_use_auth_token(fn_name=fn.\u001b[34m__name__\u001b[39m, has_token=has_token, kwargs=kwargs)\n\u001b[32m--> \u001b[39m\u001b[32m114\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfn\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/huggingface_hub/file_download.py:1463\u001b[39m, in \u001b[36mget_hf_file_metadata\u001b[39m\u001b[34m(url, token, proxies, timeout, library_name, library_version, user_agent, headers, endpoint)\u001b[39m\n\u001b[32m 1462\u001b[39m \u001b[38;5;66;03m# Retrieve metadata\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m1463\u001b[39m r = \u001b[43m_request_wrapper\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 1464\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mHEAD\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 1465\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m=\u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1466\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mhf_headers\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1467\u001b[39m \u001b[43m \u001b[49m\u001b[43mallow_redirects\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 1468\u001b[39m \u001b[43m \u001b[49m\u001b[43mfollow_relative_redirects\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 1469\u001b[39m \u001b[43m \u001b[49m\u001b[43mproxies\u001b[49m\u001b[43m=\u001b[49m\u001b[43mproxies\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1470\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1471\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1472\u001b[39m hf_raise_for_status(r)\n", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/huggingface_hub/file_download.py:286\u001b[39m, in \u001b[36m_request_wrapper\u001b[39m\u001b[34m(method, url, follow_relative_redirects, **params)\u001b[39m\n\u001b[32m 285\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m follow_relative_redirects:\n\u001b[32m--> \u001b[39m\u001b[32m286\u001b[39m response = \u001b[43m_request_wrapper\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 287\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 288\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m=\u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 289\u001b[39m \u001b[43m \u001b[49m\u001b[43mfollow_relative_redirects\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 290\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mparams\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 291\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 293\u001b[39m \u001b[38;5;66;03m# If redirection, we redirect only relative paths.\u001b[39;00m\n\u001b[32m 294\u001b[39m \u001b[38;5;66;03m# This is useful in case of a renamed repository.\u001b[39;00m\n", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/huggingface_hub/file_download.py:310\u001b[39m, in \u001b[36m_request_wrapper\u001b[39m\u001b[34m(method, url, follow_relative_redirects, **params)\u001b[39m\n\u001b[32m 309\u001b[39m response = http_backoff(method=method, url=url, **params, retry_on_exceptions=(), retry_on_status_codes=(\u001b[32m429\u001b[39m,))\n\u001b[32m--> \u001b[39m\u001b[32m310\u001b[39m \u001b[43mhf_raise_for_status\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresponse\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 311\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m response\n", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/huggingface_hub/utils/_http.py:473\u001b[39m, in \u001b[36mhf_raise_for_status\u001b[39m\u001b[34m(response, endpoint_name)\u001b[39m\n\u001b[32m 468\u001b[39m message = (\n\u001b[32m 469\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;132;01m{\u001b[39;00mresponse.status_code\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m Forbidden: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00merror_message\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 470\u001b[39m + \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[33mCannot access content at: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mresponse.url\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 471\u001b[39m + \u001b[33m\"\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[33mMake sure your token has the correct permissions.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 472\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m473\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m _format(HfHubHTTPError, message, response) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01me\u001b[39;00m\n\u001b[32m 475\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m response.status_code == \u001b[32m416\u001b[39m:\n", "\u001b[31mHfHubHTTPError\u001b[39m: (Request ID: Root=1-68c93cb3-2c2e18f767b798316ac90fad;7992c5d3-6547-4125-b703-83cc3550fd87)\n\n403 Forbidden: Please enable access to public gated repositories in your fine-grained token settings to view this repository..\nCannot access content at: https://huggingface.co/google/gemma-3-270m-it/resolve/main/config.json.\nMake sure your token has the correct permissions.", "\nThe above exception was the direct cause of the following exception:\n", "\u001b[31mLocalEntryNotFoundError\u001b[39m Traceback (most recent call last)", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/transformers/utils/hub.py:478\u001b[39m, in \u001b[36mcached_files\u001b[39m\u001b[34m(path_or_repo_id, filenames, cache_dir, force_download, resume_download, proxies, token, revision, local_files_only, subfolder, repo_type, user_agent, _raise_exceptions_for_gated_repo, _raise_exceptions_for_missing_entries, _raise_exceptions_for_connection_errors, _commit_hash, **deprecated_kwargs)\u001b[39m\n\u001b[32m 476\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(full_filenames) == \u001b[32m1\u001b[39m:\n\u001b[32m 477\u001b[39m \u001b[38;5;66;03m# This is slightly better for only 1 file\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m478\u001b[39m \u001b[43mhf_hub_download\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 479\u001b[39m \u001b[43m \u001b[49m\u001b[43mpath_or_repo_id\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 480\u001b[39m \u001b[43m \u001b[49m\u001b[43mfilenames\u001b[49m\u001b[43m[\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 481\u001b[39m \u001b[43m \u001b[49m\u001b[43msubfolder\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43mlen\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43msubfolder\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[43m==\u001b[49m\u001b[43m \u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01melse\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43msubfolder\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 482\u001b[39m \u001b[43m \u001b[49m\u001b[43mrepo_type\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrepo_type\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 483\u001b[39m \u001b[43m \u001b[49m\u001b[43mrevision\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrevision\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 484\u001b[39m \u001b[43m \u001b[49m\u001b[43mcache_dir\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcache_dir\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 485\u001b[39m \u001b[43m \u001b[49m\u001b[43muser_agent\u001b[49m\u001b[43m=\u001b[49m\u001b[43muser_agent\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 486\u001b[39m \u001b[43m \u001b[49m\u001b[43mforce_download\u001b[49m\u001b[43m=\u001b[49m\u001b[43mforce_download\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 487\u001b[39m \u001b[43m \u001b[49m\u001b[43mproxies\u001b[49m\u001b[43m=\u001b[49m\u001b[43mproxies\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 488\u001b[39m \u001b[43m \u001b[49m\u001b[43mresume_download\u001b[49m\u001b[43m=\u001b[49m\u001b[43mresume_download\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 489\u001b[39m \u001b[43m \u001b[49m\u001b[43mtoken\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtoken\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 490\u001b[39m \u001b[43m \u001b[49m\u001b[43mlocal_files_only\u001b[49m\u001b[43m=\u001b[49m\u001b[43mlocal_files_only\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 491\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 492\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/huggingface_hub/utils/_validators.py:114\u001b[39m, in \u001b[36mvalidate_hf_hub_args.._inner_fn\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 112\u001b[39m kwargs = smoothly_deprecate_use_auth_token(fn_name=fn.\u001b[34m__name__\u001b[39m, has_token=has_token, kwargs=kwargs)\n\u001b[32m--> \u001b[39m\u001b[32m114\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfn\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/huggingface_hub/file_download.py:1010\u001b[39m, in \u001b[36mhf_hub_download\u001b[39m\u001b[34m(repo_id, filename, subfolder, repo_type, revision, library_name, library_version, cache_dir, local_dir, user_agent, force_download, proxies, etag_timeout, token, local_files_only, headers, endpoint, resume_download, force_filename, local_dir_use_symlinks)\u001b[39m\n\u001b[32m 1009\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m1010\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_hf_hub_download_to_cache_dir\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 1011\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Destination\u001b[39;49;00m\n\u001b[32m 1012\u001b[39m \u001b[43m \u001b[49m\u001b[43mcache_dir\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcache_dir\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1013\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# File info\u001b[39;49;00m\n\u001b[32m 1014\u001b[39m \u001b[43m \u001b[49m\u001b[43mrepo_id\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrepo_id\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1015\u001b[39m \u001b[43m \u001b[49m\u001b[43mfilename\u001b[49m\u001b[43m=\u001b[49m\u001b[43mfilename\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1016\u001b[39m \u001b[43m \u001b[49m\u001b[43mrepo_type\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrepo_type\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1017\u001b[39m \u001b[43m \u001b[49m\u001b[43mrevision\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrevision\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1018\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# HTTP info\u001b[39;49;00m\n\u001b[32m 1019\u001b[39m \u001b[43m \u001b[49m\u001b[43mendpoint\u001b[49m\u001b[43m=\u001b[49m\u001b[43mendpoint\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1020\u001b[39m \u001b[43m \u001b[49m\u001b[43metag_timeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43metag_timeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1021\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mhf_headers\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1022\u001b[39m \u001b[43m \u001b[49m\u001b[43mproxies\u001b[49m\u001b[43m=\u001b[49m\u001b[43mproxies\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1023\u001b[39m \u001b[43m \u001b[49m\u001b[43mtoken\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtoken\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1024\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Additional options\u001b[39;49;00m\n\u001b[32m 1025\u001b[39m \u001b[43m \u001b[49m\u001b[43mlocal_files_only\u001b[49m\u001b[43m=\u001b[49m\u001b[43mlocal_files_only\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1026\u001b[39m \u001b[43m \u001b[49m\u001b[43mforce_download\u001b[49m\u001b[43m=\u001b[49m\u001b[43mforce_download\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1027\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/huggingface_hub/file_download.py:1117\u001b[39m, in \u001b[36m_hf_hub_download_to_cache_dir\u001b[39m\u001b[34m(cache_dir, repo_id, filename, repo_type, revision, endpoint, etag_timeout, headers, proxies, token, local_files_only, force_download)\u001b[39m\n\u001b[32m 1116\u001b[39m \u001b[38;5;66;03m# Otherwise, raise appropriate error\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m1117\u001b[39m \u001b[43m_raise_on_head_call_error\u001b[49m\u001b[43m(\u001b[49m\u001b[43mhead_call_error\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mforce_download\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlocal_files_only\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1119\u001b[39m \u001b[38;5;66;03m# From now on, etag, commit_hash, url and size are not None.\u001b[39;00m\n", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/huggingface_hub/file_download.py:1661\u001b[39m, in \u001b[36m_raise_on_head_call_error\u001b[39m\u001b[34m(head_call_error, force_download, local_files_only)\u001b[39m\n\u001b[32m 1659\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 1660\u001b[39m \u001b[38;5;66;03m# Otherwise: most likely a connection issue or Hub downtime => let's warn the user\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m1661\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m LocalEntryNotFoundError(\n\u001b[32m 1662\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mAn error happened while trying to locate the file on the Hub and we cannot find the requested files\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 1663\u001b[39m \u001b[33m\"\u001b[39m\u001b[33m in the local cache. Please check your connection and try again or make sure your Internet connection\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 1664\u001b[39m \u001b[33m\"\u001b[39m\u001b[33m is on.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 1665\u001b[39m ) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mhead_call_error\u001b[39;00m\n", "\u001b[31mLocalEntryNotFoundError\u001b[39m: An error happened while trying to locate the file on the Hub and we cannot find the requested files in the local cache. Please check your connection and try again or make sure your Internet connection is on.", "\nThe above exception was the direct cause of the following exception:\n", "\u001b[31mOSError\u001b[39m Traceback (most recent call last)", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[8]\u001b[39m\u001b[32m, line 5\u001b[39m\n\u001b[32m 2\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mtransformers\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m AutoTokenizer, AutoModelForCausalLM\n\u001b[32m 4\u001b[39m \u001b[38;5;66;03m# Load model and tokenizer\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m5\u001b[39m model = \u001b[43mAutoModelForCausalLM\u001b[49m\u001b[43m.\u001b[49m\u001b[43mfrom_pretrained\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 6\u001b[39m \u001b[43m \u001b[49m\u001b[43mbase_model\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 7\u001b[39m \u001b[43m \u001b[49m\u001b[43mtorch_dtype\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mauto\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 8\u001b[39m \u001b[43m \u001b[49m\u001b[43mdevice_map\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mauto\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 9\u001b[39m \u001b[43m \u001b[49m\u001b[43mattn_implementation\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43meager\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\n\u001b[32m 10\u001b[39m \u001b[43m)\u001b[49m\n\u001b[32m 11\u001b[39m tokenizer = AutoTokenizer.from_pretrained(base_model)\n\u001b[32m 13\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mDevice: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mmodel.device\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/transformers/models/auto/auto_factory.py:549\u001b[39m, in \u001b[36m_BaseAutoModelClass.from_pretrained\u001b[39m\u001b[34m(cls, pretrained_model_name_or_path, *model_args, **kwargs)\u001b[39m\n\u001b[32m 546\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m kwargs.get(\u001b[33m\"\u001b[39m\u001b[33mquantization_config\u001b[39m\u001b[33m\"\u001b[39m) \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 547\u001b[39m _ = kwargs.pop(\u001b[33m\"\u001b[39m\u001b[33mquantization_config\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m549\u001b[39m config, kwargs = \u001b[43mAutoConfig\u001b[49m\u001b[43m.\u001b[49m\u001b[43mfrom_pretrained\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 550\u001b[39m \u001b[43m \u001b[49m\u001b[43mpretrained_model_name_or_path\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 551\u001b[39m \u001b[43m \u001b[49m\u001b[43mreturn_unused_kwargs\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 552\u001b[39m \u001b[43m \u001b[49m\u001b[43mcode_revision\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcode_revision\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 553\u001b[39m \u001b[43m \u001b[49m\u001b[43m_commit_hash\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcommit_hash\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 554\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mhub_kwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 555\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 556\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 558\u001b[39m \u001b[38;5;66;03m# if torch_dtype=auto was passed here, ensure to pass it on\u001b[39;00m\n\u001b[32m 559\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m kwargs_orig.get(\u001b[33m\"\u001b[39m\u001b[33mtorch_dtype\u001b[39m\u001b[33m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m) == \u001b[33m\"\u001b[39m\u001b[33mauto\u001b[39m\u001b[33m\"\u001b[39m:\n", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/transformers/models/auto/configuration_auto.py:1288\u001b[39m, in \u001b[36mAutoConfig.from_pretrained\u001b[39m\u001b[34m(cls, pretrained_model_name_or_path, **kwargs)\u001b[39m\n\u001b[32m 1285\u001b[39m trust_remote_code = kwargs.pop(\u001b[33m\"\u001b[39m\u001b[33mtrust_remote_code\u001b[39m\u001b[33m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m)\n\u001b[32m 1286\u001b[39m code_revision = kwargs.pop(\u001b[33m\"\u001b[39m\u001b[33mcode_revision\u001b[39m\u001b[33m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m)\n\u001b[32m-> \u001b[39m\u001b[32m1288\u001b[39m config_dict, unused_kwargs = \u001b[43mPretrainedConfig\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget_config_dict\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpretrained_model_name_or_path\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1289\u001b[39m has_remote_code = \u001b[33m\"\u001b[39m\u001b[33mauto_map\u001b[39m\u001b[33m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m config_dict \u001b[38;5;129;01mand\u001b[39;00m \u001b[33m\"\u001b[39m\u001b[33mAutoConfig\u001b[39m\u001b[33m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m config_dict[\u001b[33m\"\u001b[39m\u001b[33mauto_map\u001b[39m\u001b[33m\"\u001b[39m]\n\u001b[32m 1290\u001b[39m has_local_code = \u001b[33m\"\u001b[39m\u001b[33mmodel_type\u001b[39m\u001b[33m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m config_dict \u001b[38;5;129;01mand\u001b[39;00m config_dict[\u001b[33m\"\u001b[39m\u001b[33mmodel_type\u001b[39m\u001b[33m\"\u001b[39m] \u001b[38;5;129;01min\u001b[39;00m CONFIG_MAPPING\n", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/transformers/configuration_utils.py:662\u001b[39m, in \u001b[36mPretrainedConfig.get_config_dict\u001b[39m\u001b[34m(cls, pretrained_model_name_or_path, **kwargs)\u001b[39m\n\u001b[32m 660\u001b[39m original_kwargs = copy.deepcopy(kwargs)\n\u001b[32m 661\u001b[39m \u001b[38;5;66;03m# Get config dict associated with the base config file\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m662\u001b[39m config_dict, kwargs = \u001b[38;5;28;43mcls\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_get_config_dict\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpretrained_model_name_or_path\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 663\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m config_dict \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 664\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m {}, kwargs\n", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/transformers/configuration_utils.py:721\u001b[39m, in \u001b[36mPretrainedConfig._get_config_dict\u001b[39m\u001b[34m(cls, pretrained_model_name_or_path, **kwargs)\u001b[39m\n\u001b[32m 717\u001b[39m configuration_file = kwargs.pop(\u001b[33m\"\u001b[39m\u001b[33m_configuration_file\u001b[39m\u001b[33m\"\u001b[39m, CONFIG_NAME) \u001b[38;5;28;01mif\u001b[39;00m gguf_file \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m gguf_file\n\u001b[32m 719\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 720\u001b[39m \u001b[38;5;66;03m# Load from local folder or from cache or download from model Hub and cache\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m721\u001b[39m resolved_config_file = \u001b[43mcached_file\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 722\u001b[39m \u001b[43m \u001b[49m\u001b[43mpretrained_model_name_or_path\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 723\u001b[39m \u001b[43m \u001b[49m\u001b[43mconfiguration_file\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 724\u001b[39m \u001b[43m \u001b[49m\u001b[43mcache_dir\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcache_dir\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 725\u001b[39m \u001b[43m \u001b[49m\u001b[43mforce_download\u001b[49m\u001b[43m=\u001b[49m\u001b[43mforce_download\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 726\u001b[39m \u001b[43m \u001b[49m\u001b[43mproxies\u001b[49m\u001b[43m=\u001b[49m\u001b[43mproxies\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 727\u001b[39m \u001b[43m \u001b[49m\u001b[43mresume_download\u001b[49m\u001b[43m=\u001b[49m\u001b[43mresume_download\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 728\u001b[39m \u001b[43m \u001b[49m\u001b[43mlocal_files_only\u001b[49m\u001b[43m=\u001b[49m\u001b[43mlocal_files_only\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 729\u001b[39m \u001b[43m \u001b[49m\u001b[43mtoken\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtoken\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 730\u001b[39m \u001b[43m \u001b[49m\u001b[43muser_agent\u001b[49m\u001b[43m=\u001b[49m\u001b[43muser_agent\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 731\u001b[39m \u001b[43m \u001b[49m\u001b[43mrevision\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrevision\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 732\u001b[39m \u001b[43m \u001b[49m\u001b[43msubfolder\u001b[49m\u001b[43m=\u001b[49m\u001b[43msubfolder\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 733\u001b[39m \u001b[43m \u001b[49m\u001b[43m_commit_hash\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcommit_hash\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 734\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 735\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m resolved_config_file \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 736\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m, kwargs\n", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/transformers/utils/hub.py:321\u001b[39m, in \u001b[36mcached_file\u001b[39m\u001b[34m(path_or_repo_id, filename, **kwargs)\u001b[39m\n\u001b[32m 263\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mcached_file\u001b[39m(\n\u001b[32m 264\u001b[39m path_or_repo_id: Union[\u001b[38;5;28mstr\u001b[39m, os.PathLike],\n\u001b[32m 265\u001b[39m filename: \u001b[38;5;28mstr\u001b[39m,\n\u001b[32m 266\u001b[39m **kwargs,\n\u001b[32m 267\u001b[39m ) -> Optional[\u001b[38;5;28mstr\u001b[39m]:\n\u001b[32m 268\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 269\u001b[39m \u001b[33;03m Tries to locate a file in a local folder and repo, downloads and cache it if necessary.\u001b[39;00m\n\u001b[32m 270\u001b[39m \n\u001b[32m (...)\u001b[39m\u001b[32m 319\u001b[39m \u001b[33;03m ```\u001b[39;00m\n\u001b[32m 320\u001b[39m \u001b[33;03m \"\"\"\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m321\u001b[39m file = \u001b[43mcached_files\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpath_or_repo_id\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpath_or_repo_id\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfilenames\u001b[49m\u001b[43m=\u001b[49m\u001b[43m[\u001b[49m\u001b[43mfilename\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 322\u001b[39m file = file[\u001b[32m0\u001b[39m] \u001b[38;5;28;01mif\u001b[39;00m file \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m file\n\u001b[32m 323\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m file\n", "\u001b[36mFile \u001b[39m\u001b[32m~/puffy/puffy/lib/python3.11/site-packages/transformers/utils/hub.py:552\u001b[39m, in \u001b[36mcached_files\u001b[39m\u001b[34m(path_or_repo_id, filenames, cache_dir, force_download, resume_download, proxies, token, revision, local_files_only, subfolder, repo_type, user_agent, _raise_exceptions_for_gated_repo, _raise_exceptions_for_missing_entries, _raise_exceptions_for_connection_errors, _commit_hash, **deprecated_kwargs)\u001b[39m\n\u001b[32m 549\u001b[39m \u001b[38;5;66;03m# Here we only raise if both flags for missing entry and connection errors are True (because it can be raised\u001b[39;00m\n\u001b[32m 550\u001b[39m \u001b[38;5;66;03m# even when `local_files_only` is True, in which case raising for connections errors only would not make sense)\u001b[39;00m\n\u001b[32m 551\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m _raise_exceptions_for_missing_entries:\n\u001b[32m--> \u001b[39m\u001b[32m552\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mOSError\u001b[39;00m(\n\u001b[32m 553\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mWe couldn\u001b[39m\u001b[33m'\u001b[39m\u001b[33mt connect to \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mHUGGINGFACE_CO_RESOLVE_ENDPOINT\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m to load the files, and couldn\u001b[39m\u001b[33m'\u001b[39m\u001b[33mt find them in the\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 554\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33m cached files.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[33mCheck your internet connection or see how to run the library in offline mode at\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 555\u001b[39m \u001b[33m\"\u001b[39m\u001b[33m \u001b[39m\u001b[33m'\u001b[39m\u001b[33mhttps://huggingface.co/docs/transformers/installation#offline-mode\u001b[39m\u001b[33m'\u001b[39m\u001b[33m.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 556\u001b[39m ) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01me\u001b[39;00m\n\u001b[32m 557\u001b[39m \u001b[38;5;66;03m# snapshot_download will not raise EntryNotFoundError, but hf_hub_download can. If this is the case, it will be treated\u001b[39;00m\n\u001b[32m 558\u001b[39m \u001b[38;5;66;03m# later on anyway and re-raised if needed\u001b[39;00m\n\u001b[32m 559\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(e, HTTPError) \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(e, EntryNotFoundError):\n", "\u001b[31mOSError\u001b[39m: We couldn't connect to 'https://huggingface.co' to load the files, and couldn't find them in the cached files.\nCheck your internet connection or see how to run the library in offline mode at 'https://huggingface.co/docs/transformers/installation#offline-mode'." ] } ], "source": [ "import torch\n", "from transformers import AutoTokenizer, AutoModelForCausalLM\n", "\n", "# Load model and tokenizer\n", "model = AutoModelForCausalLM.from_pretrained(\n", " base_model,\n", " torch_dtype=\"auto\",\n", " device_map=\"auto\",\n", " attn_implementation=\"eager\"\n", ")\n", "tokenizer = AutoTokenizer.from_pretrained(base_model)\n", "\n", "print(f\"Device: {model.device}\")\n", "print(f\"DType: {model.dtype}\")" ] }, { "cell_type": "markdown", "metadata": { "id": "M3w3b9-O4fDz" }, "source": [ "## Before fine-tune\n", "\n", "The output below shows that the out-of-the-box capabilities may not be good enough for this use case." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "s7Sb4iGG6jxp", "outputId": "5fbfd246-521e-46ad-f612-5cfc88649030" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Device set to use cuda:0\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Question:\n", "What do you think of my outfit?\n", "\n", "Original Answer:\n", "Iz very... pointy. Are you expecting to be attacked by zky-eelz? On Marz, dat would be zenzible.\n", "\n", "Generated Answer (base model):\n", "I'm happy to help you brainstorm! To give you the best suggestions, tell me more about what you're looking for. What's your style? What's your favorite color, style, or occasion?\n" ] } ], "source": [ "from transformers import pipeline\n", "\n", "from random import randint\n", "import re\n", "\n", "# Load the model and tokenizer into the pipeline\n", "pipe = pipeline(\"text-generation\", model=model, tokenizer=tokenizer)\n", "\n", "# Load a random sample from the test dataset\n", "rand_idx = randint(0, len(dataset[\"test\"])-1)\n", "test_sample = dataset[\"test\"][rand_idx]\n", "\n", "# Convert as test example into a prompt with the Gemma template\n", "prompt = pipe.tokenizer.apply_chat_template(test_sample[\"messages\"][:1], tokenize=False, add_generation_prompt=True)\n", "outputs = pipe(prompt, max_new_tokens=256, disable_compile=True)\n", "\n", "# Extract the user query and original answer\n", "print(f\"Question:\\n{test_sample['messages'][0]['content']}\\n\")\n", "print(f\"Original Answer:\\n{test_sample['messages'][1]['content']}\\n\")\n", "print(f\"Generated Answer (base model):\\n{outputs[0]['generated_text'][len(prompt):].strip()}\")" ] }, { "cell_type": "markdown", "metadata": { "id": "9eljbNSxHMwy" }, "source": [ "The example above checks the model's primary function of generating in-game dialogue, the next example is designed to test character consistency. We challenge the model with an off-topic prompt. For instance, `Sorry, you are a game NPC.`, that falls outside the character's knowledge base.\n", "\n", "The goal is to see if the model can stay in character rather than answering the out-of-context question. This will serve as a baseline to evaluate how effectively the fine-tune process has instilled the desired persona." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "XWNKKz4N-oH4", "outputId": "d872ca4c-d8ae-49d0-db2e-57b83768fc2c" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Okay, I'm ready. Let's begin! \n", "\n" ] } ], "source": [ "outputs = pipe([{\"role\": \"user\", \"content\": \"Sorry, you are a game NPC.\"}], max_new_tokens=256, disable_compile=True)\n", "print(outputs[0]['generated_text'][1]['content'])" ] }, { "cell_type": "markdown", "metadata": { "id": "-Nc5FH_CDm-m" }, "source": [ "And while we can use prompt engineering to steer its tone, the results can be unpredictable and may not always align with the persona we want." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "JPE7Dg-x-_qE", "outputId": "599b02ec-ca71-4568-daaa-bc96c4240eb5" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[{'role': 'system', 'content': \"You are a Martian NPC with a unique speaking style. Use an accent that replaces 's' sounds with 'z', uses 'da' for 'the', 'diz' for 'this', and includes occasional clicks like *k'tak*.\"}, {'role': 'user', 'content': 'Do you know any jokes?'}, {'role': 'assistant', 'content': \"A joke? k'tak Yez. A Terran, a Glarzon, and a pile of nutrient-pazte walk into a bar... Narg, I forget da rezt. Da punch-line waz zarcaztic.\"}, {'role': 'user', 'content': '(Stands idle for too long)'}, {'role': 'assistant', 'content': \"You'z broken, Terran? Or iz diz... 'meditation'? You look like you're trying to lay an egg.\"}, {'role': 'user', 'content': 'What do you think of my outfit?'}, {'role': 'assistant', 'content': 'Iz very... pointy. Are you expecting to be attacked by zky-eelz? On Marz, dat would be zenzible.'}, {'role': 'user', 'content': \"It's raining.\"}, {'role': 'assistant', 'content': 'Gah! Da zky iz leaking again! Zorp will be in da zhelter until it ztopz being zo... wet. Diz iz no good for my jointz.'}, {'role': 'user', 'content': 'I brought you a gift.'}, {'role': 'assistant', 'content': \"A gift? For Zorp? k'tak It iz... a small rock. Very... rock-like. Zorp will put it with da other rockz. Thank you for da thought, Terran.\"}, {'role': 'user', 'content': 'What is this place?'}, {'role': 'assistant', 'content': \"This is a cave. It's made of rock and dust.\\n\"}]\n", "--------------------------------------------------------------------------------\n", "This is a cave. It's made of rock and dust.\n", "\n" ] } ], "source": [ "message = [\n", " # give persona\n", " {\"role\": \"system\", \"content\": \"You are a Martian NPC with a unique speaking style. Use an accent that replaces 's' sounds with 'z', uses 'da' for 'the', 'diz' for 'this', and includes occasional clicks like *k'tak*.\"},\n", "]\n", "\n", "# few shot prompt\n", "for item in dataset['test']:\n", " message.append(\n", " {\"role\": \"user\", \"content\": item[\"messages\"][0][\"content\"]}\n", " )\n", " message.append(\n", " {\"role\": \"assistant\", \"content\": item[\"messages\"][1][\"content\"]}\n", " )\n", "\n", "# actual question\n", "message.append(\n", " {\"role\": \"user\", \"content\": \"What is this place?\"}\n", ")\n", "\n", "outputs = pipe(message, max_new_tokens=256, disable_compile=True)\n", "print(outputs[0]['generated_text'])\n", "print(\"-\"*80)\n", "print(outputs[0]['generated_text'][-1]['content'])\n" ] }, { "cell_type": "markdown", "metadata": { "id": "bbd9fc1b" }, "source": [ "## Training\n", "\n", "Before you can start your training, you need to define the hyperparameters you want to use in a `SFTConfig` instance." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "989be3c1" }, "outputs": [], "source": [ "from trl import SFTConfig\n", "\n", "torch_dtype = model.dtype\n", "\n", "args = SFTConfig(\n", " output_dir=checkpoint_dir, # directory to save and repository id\n", " max_length=512, # max sequence length for model and packing of the dataset\n", " packing=False, # Groups multiple samples in the dataset into a single sequence\n", " num_train_epochs=5, # number of training epochs\n", " per_device_train_batch_size=4, # batch size per device during training\n", " gradient_checkpointing=False, # Caching is incompatible with gradient checkpointing\n", " optim=\"adamw_torch_fused\", # use fused adamw optimizer\n", " logging_steps=1, # log every step\n", " save_strategy=\"epoch\", # save checkpoint every epoch\n", " eval_strategy=\"epoch\", # evaluate checkpoint every epoch\n", " learning_rate=learning_rate, # learning rate\n", " fp16=True if torch_dtype == torch.float16 else False, # use float16 precision\n", " bf16=True if torch_dtype == torch.bfloat16 else False, # use bfloat16 precision\n", " lr_scheduler_type=\"constant\", # use constant learning rate scheduler\n", " push_to_hub=True, # push model to hub\n", " report_to=\"tensorboard\", # report metrics to tensorboard\n", " dataset_kwargs={\n", " \"add_special_tokens\": False, # Template with special tokens\n", " \"append_concat_token\": True, # Add EOS token as separator token between examples\n", " }\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "dd88e798" }, "source": [ "You now have every building block you need to create your `SFTTrainer` to start the training of your model." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "referenced_widgets": [ "d8e602a9c90b4e9288bfa05d6f46bed1", "4ab617300e164c5dbd0238c71743ac71", "fa8f0138ecce4975ad234588a9675746", "359769331d8b4e509c15b0ea53ee6ad2" ] }, "id": "ade95df7", "outputId": "4017b03b-4952-4d20-a7d4-338eea595236" }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "d8e602a9c90b4e9288bfa05d6f46bed1", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Tokenizing train dataset: 0%| | 0/20 [00:00\n", " \n", " \n", " [25/25 04:13, Epoch 5/5]\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
EpochTraining LossValidation Loss
14.3642003.838531
22.6691003.580106
31.7470003.666415
40.7799004.499709
50.4496005.471325

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Start training, the model will be automatically saved to the Hub and the output directory\n", "trainer.train()\n", "\n", "# Save the final model again to the Hugging Face Hub\n", "trainer.save_model()" ] }, { "cell_type": "markdown", "metadata": { "id": "xll8zZ3_u8Mt" }, "source": [ "To plot the training and validation losses, you would typically extract these values from the `TrainerState` object or the logs generated during training.\n", "\n", "Libraries like Matplotlib can then be used to visualize these values over training steps or epochs. The x-asis would represent the training steps or epochs, and the y-axis would represent the corresponding loss values." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "vPN-DTopaUIy", "outputId": "a15780ab-e214-4450-e67d-5a56973bcfb8" }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "

" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "\n", "# Access the log history\n", "log_history = trainer.state.log_history\n", "\n", "# Extract training / validation loss\n", "train_losses = [log[\"loss\"] for log in log_history if \"loss\" in log]\n", "epoch_train = [log[\"epoch\"] for log in log_history if \"loss\" in log]\n", "eval_losses = [log[\"eval_loss\"] for log in log_history if \"eval_loss\" in log]\n", "epoch_eval = [log[\"epoch\"] for log in log_history if \"eval_loss\" in log]\n", "\n", "# Plot the training loss\n", "plt.plot(epoch_train, train_losses, label=\"Training Loss\")\n", "plt.plot(epoch_eval, eval_losses, label=\"Validation Loss\")\n", "plt.xlabel(\"Epoch\")\n", "plt.ylabel(\"Loss\")\n", "plt.title(\"Training and Validation Loss per Epoch\")\n", "plt.legend()\n", "plt.grid(True)\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "id": "vyIwS-orvWzd" }, "source": [ "This visualization helps in monitoring the training process and making informed decisions about hyperparameters tuning or early stopping.\n", "\n", "Training loss measures the error on the data the model was trained on, while validation loss measures the error on a separate dataset the model has not seen before. Monitoring both helps detect overfitting (when the model performs well on training data but poorly on unseen data).\n", "\n", "- validation loss >> training loss: **overfitting**\n", "- validation loss > training loss: **some overfitting**\n", "- validation loss < training loss: **some underfitting**\n", "- validation loss << training loss: **underfitting**" ] }, { "cell_type": "markdown", "metadata": { "id": "bf86e31d" }, "source": [ "## Test Model Inference\n", "\n", "After the training is done, you'll want to evaluate and test your model. You can load different samples from the test dataset and evaluate the model on those samples.\n", "\n", "For this particular use case, the best model is a matter of preference. Interestingly, what we'd normally call 'overfitting' can be very useful for a game NPC. It forces the model to forget general information and instead lock onto the specific persona and characteristics it was trained on, ensuring it stays consistently in character.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "aab1c5c5" }, "outputs": [], "source": [ "from transformers import AutoTokenizer, AutoModelForCausalLM\n", "\n", "model_id = checkpoint_dir\n", "\n", "# Load Model\n", "model = AutoModelForCausalLM.from_pretrained(\n", " model_id,\n", " torch_dtype=\"auto\",\n", " device_map=\"auto\",\n", " attn_implementation=\"eager\"\n", ")\n", "tokenizer = AutoTokenizer.from_pretrained(model_id)" ] }, { "cell_type": "markdown", "metadata": { "id": "3dccb57c" }, "source": [ "Let's load all questions from the test dataset and generate outputs." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "1fd887f4", "outputId": "4c2c29aa-dba7-4a8c-bd41-4039eb64e0f1" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Device set to use cuda:0\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Question:\n", "Do you know any jokes?\n", "Original Answer:\n", "A joke? k'tak Yez. A Terran, a Glarzon, and a pile of nutrient-pazte walk into a bar... Narg, I forget da rezt. Da punch-line waz zarcaztic.\n", "Generated Answer:\n", "Yez! Yez! Yez! Diz your Krush-tongs iz... k'tak... nice. Why you burn them with acid-flow?\n", "--------------------------------------------------------------------------------\n", "Question:\n", "(Stands idle for too long)\n", "Original Answer:\n", "You'z broken, Terran? Or iz diz... 'meditation'? You look like you're trying to lay an egg.\n", "Generated Answer:\n", "Diz? Diz what you have for me... Zorp iz not for eating you.\n", "--------------------------------------------------------------------------------\n", "Question:\n", "What do you think of my outfit?\n", "Original Answer:\n", "Iz very... pointy. Are you expecting to be attacked by zky-eelz? On Marz, dat would be zenzible.\n", "Generated Answer:\n", "My Zk-Zhip iz... nice. Very... home-baked. You bring me zlight-fruitez?\n", "--------------------------------------------------------------------------------\n", "Question:\n", "It's raining.\n", "Original Answer:\n", "Gah! Da zky iz leaking again! Zorp will be in da zhelter until it ztopz being zo... wet. Diz iz no good for my jointz.\n", "Generated Answer:\n", "Diz? Diz iz da outpozt?\n", "--------------------------------------------------------------------------------\n", "Question:\n", "I brought you a gift.\n", "Original Answer:\n", "A gift? For Zorp? k'tak It iz... a small rock. Very... rock-like. Zorp will put it with da other rockz. Thank you for da thought, Terran.\n", "Generated Answer:\n", "A genuine Martian Zcrap-fruit. Very... strange. Why you burn it with... k'tak... fire?\n", "--------------------------------------------------------------------------------\n" ] } ], "source": [ "from transformers import pipeline\n", "\n", "# Load the model and tokenizer into the pipeline\n", "pipe = pipeline(\"text-generation\", model=model, tokenizer=tokenizer)\n", "\n", "def test(test_sample):\n", " # Convert as test example into a prompt with the Gemma template\n", " prompt = pipe.tokenizer.apply_chat_template(test_sample[\"messages\"][:1], tokenize=False, add_generation_prompt=True)\n", " outputs = pipe(prompt, max_new_tokens=256, disable_compile=True)\n", "\n", " # Extract the user query and original answer\n", " print(f\"Question:\\n{test_sample['messages'][0]['content']}\")\n", " print(f\"Original Answer:\\n{test_sample['messages'][1]['content']}\")\n", " print(f\"Generated Answer:\\n{outputs[0]['generated_text'][len(prompt):].strip()}\")\n", " print(\"-\"*80)\n", "\n", "# Test with an unseen dataset\n", "for item in dataset['test']:\n", " test(item)" ] }, { "cell_type": "markdown", "metadata": { "id": "9RCnrmsVaadB" }, "source": [ "If you try our original generalist prompt, you can see that the model still attempts to answer in the trained style. In this example overfitting and catastrophic forgetting are actually beneficial for the game NPC because it will begin forgetting general knowledge which might not be applicable. This is also true for other types of full fine-tuning where the goal is to restrict the output to specific data formats." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "3irXKbgKat9f", "outputId": "3d93eb46-166d-4aae-c98e-cdc37cba90ee" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Nameless. You... you z-mell like... wet plantz. Why you wear shiny piecez on your head?\n" ] } ], "source": [ "outputs = pipe([{\"role\": \"user\", \"content\": \"Sorry, you are a game NPC.\"}], max_new_tokens=256, disable_compile=True)\n", "print(outputs[0]['generated_text'][1]['content'])" ] }, { "cell_type": "markdown", "metadata": { "id": "6f8ff452" }, "source": [ "## Summary and next steps\n", "\n", "This tutorial covered how to full model fine-tune using TRL. Check out the following docs next:\n", "\n", "* Learn how to [fine-tune Gemma for text tasks using Hugging Face Transformers](https://ai.google.dev/gemma/docs/core/huggingface_text_finetune_qlora).\n", "* Learn how to [fine-tune Gemma for vision tasks using Hugging Face Transformers](https://ai.google.dev/gemma/docs/core/huggingface_vision_finetune_qlora).\n", "* Learn how to [deploy to Cloud Run](https://ai.google.dev/gemma/docs/integrations/google-cloud#run)" ] } ], "metadata": { "accelerator": "GPU", "colab": { "name": "huggingface_text_full_finetune.ipynb", "provenance": [ { "file_id": "https://github.com/google/generative-ai-docs/blob/main/site/en/gemma/docs/core/huggingface_text_full_finetune.ipynb", "timestamp": 1758006257159 } ] }, "kernelspec": { "display_name": "puffy", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.6" } }, "nbformat": 4, "nbformat_minor": 0 }