{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "LZ32HnEpxAyr" }, "source": [ "# Acknowledgments\n", "
\n", "\n", "# Data Sources:\n", "* https://huggingface.co/angeluriot\n", "* https://huggingface.co/CATIE-AQ\n", "\n", "# Usefull plugins\n", "* jupyterlab-nvdashboard\n", "* jupyter-resource-usage\n", "\n", "# Transform into python script\n", "`jupyter nbconvert --to script Claire.ipynb`" ] }, { "cell_type": "markdown", "metadata": { "id": "rl_QlKk-zWv0" }, "source": [ "# Params\n", "- See: https://huggingface.co/learn/smol-course/unit1/3\n", "\n", "- Limited GPU Memory\n", " - per_device_train_batch_size = 2\n", " - gradient_accumulation_steps = 8\n", "- Balanced GPU Memory\n", " - per_device_train_batch_size = 4\n", " - gradient_accumulation_steps = 4\n", "- More GPU Memory\n", " - per_device_train_batch_size = 8\n", " - gradient_accumulation_steps = 2" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "editable": true, "id": "q7hxQ5anjxi_", "scrolled": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "import os\n", "\n", "if \"UNSLOTH_DOCKER\" in \"\".join(os.environ.keys()):\n", " hf_token = os.environ[\"HF_TOKEN\"]\n", " hf_username = os.environ[\"HF_USERNAME\"]\n", "elif \"COLAB_\" in \"\".join(os.environ.keys()):\n", " from google.colab import userdata\n", " hf_token = userdata.get('HuggingFaceToken')\n", " hf_username = userdata.get('HuggingFaceUsername')\n", "else:\n", " hf_token = os.environ[\"HF_TOKEN\"]\n", " hf_username = os.environ[\"HF_USERNAME\"]\n", " \n", "debug = False\n", "save_hf = True\n", "\n", "max_seq_length = 4096\n", "dataset_nb_processors = 8\n", "lora_rank = 16 # Choose any number > 0 ! Suggested 8, 16, 32, 64, 128\n", "training_learning_rate = 1e-4\n", "seed = 42\n", "training_per_device_train_batch_size = 2\n", "training_gradient_accumulation_steps = 8\n", "if debug: \n", " training_max_steps = 60\n", " training_num_train_epochs = 0\n", "else:\n", " training_max_steps = -1\n", " training_num_train_epochs = 1\n", "\n", "source_model = \"HuggingFaceTB/SmolLM3-3B\"\n", "source_model_name = \"SmolLM3-3B\"\n", "\n", "project_name = \"Claire-3B\"\n", "model_version = \"dev\" if debug else \"0.2.8\"\n", "model_name = project_name + \"-\" + model_version\n", "\n", "quantizations = [\"q8_0\", \"q4_0\", \"q4_k_m\", \"q5_k_m\"]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "import trackio\n", "if \"TRACKIO_SPACE_ID\" in \"\".join(os.environ.keys()):\n", " training_report_to = \"trackio\"\n", " training_space_id = os.environ[\"TRACKIO_SPACE_ID\"]\n", " # trackio.init(project=project_name.lower(), space_id=os.environ[\"TRACKIO_SPACE_ID\"])\n", "else:\n", " training_report_to = \"none\"\n", " training_space_id = None" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "id": "84lHENVMzWv1", "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "# Installation" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "xJKunynhzWv1" }, "outputs": [], "source": [ "import os, re\n", "import torch\n", "\n", "if \"UNSLOTH_DOCKER\" in \"\".join(os.environ.keys()):\n", " # Docker Unsloth version\n", " pass\n", "elif \"COLAB_\" in \"\".join(os.environ.keys()):\n", " os.environ[\"PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION\"] = \"python\"\n", " # Google colab\n", " import torch; v = re.match(r\"[0-9\\.]{3,}\", str(torch.__version__)).group(0)\n", " xformers = \"xformers==\" + (\"0.0.32.post2\" if v == \"2.8.0\" else \"0.0.29.post3\")\n", " !pip install --upgrade --no-deps bitsandbytes accelerate {xformers} peft trl triton cut_cross_entropy unsloth_zoo\n", " !pip install sentencepiece protobuf \"datasets>=3.4.1,<4.0.0\" \"huggingface_hub>=0.34.0\" hf_transfer\n", " !pip install --no-deps --upgrade unsloth\n", " !pip install transformers==4.55.4\n", " !pip install --no-deps trl==0.22.2\n", "else:\n", " os.environ[\"PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION\"] = \"python\"\n", " !pip install --upgrade unsloth-zoo\n", " !pip install --upgrade unsloth\n", " !pip install transformers==4.55.4\n", " !pip install --no-deps trl==0.22.2\n", "\n", "from huggingface_hub import HfApi\n", "\n", "if save_hf:\n", " hf_api = HfApi(token=hf_token)\n", " hf_api.create_repo(repo_id = hf_username + \"/\" + model_name, repo_type = \"model\", private = True, exist_ok = True)\n", " hf_api.create_repo(repo_id = hf_username + \"/\" + model_name + \"-GGUF\", repo_type = \"model\", private = True, exist_ok = True)" ] }, { "cell_type": "markdown", "metadata": { "id": "sdsmJQ_8zrjP" }, "source": [ "# Tools\n" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "id": "B6RdkRoFKYQT", "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "## Dataset formatter\n", "**[NOTE]** Remember to add the **EOS_TOKEN** to the tokenized output!! Otherwise you'll get infinite generations!\n", "\n", "ChatML renders multi turn conversations like below:\n", "\n", "```\n", "<|im_start|>system\n", "You are a helpful assistant.<|im_end|>\n", "<|im_start|>user\n", "What's the capital of France?<|im_end|>\n", "<|im_start|>assistant\n", "Paris.\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "NhukxFpYy00v" }, "outputs": [], "source": [ "#@title Base Prompt\n", "wikipedia_prompt = \"\"\"Wikipedia Article\n", "### Title: {}\n", "\n", "### Article:\n", "{}\"\"\"\n", "\n", "ebook_prompt = \"\"\"Book\n", "### Title: {}\n", "\n", "### Author: {}\n", "\n", "### Content:\n", "{}\"\"\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "editable": true, "id": "_b0jOGAVyxFs", "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "#@title SmallLm ChatML\n", "smollm_chatml = \"\"\"{# ───── defaults ───── #}\n", "{%- if enable_thinking is not defined -%}\n", "{%- set enable_thinking = true -%}\n", "{%- endif -%}\n", "\n", "{# ───── reasoning mode ───── #}\n", "{%- if enable_thinking -%}\n", " {%- set reasoning_mode = \"/think\" -%}\n", "{%- else -%}\n", " {%- set reasoning_mode = \"/no_think\" -%}\n", "{%- endif -%}\n", "\n", "{# ───── header (system message) ───── #}\n", "{{- \"<|im_start|>system\\n\" -}}\n", "\n", "{%- if messages[0].role == \"system\" -%}\n", " {%- set system_message = messages[0].content -%}\n", " {%- if \"/no_think\" in system_message -%}\n", " {%- set reasoning_mode = \"/no_think\" -%}\n", " {%- elif \"/think\" in system_message -%}\n", " {%- set reasoning_mode = \"/think\" -%}\n", " {%- endif -%}\n", " {%- set custom_instructions = system_message.replace(\"/no_think\", \"\").replace(\"/think\", \"\").rstrip() -%}\n", "{%- endif -%}\n", "\n", "{%- if \"/system_override\" in system_message -%}\n", " {{- custom_instructions.replace(\"/system_override\", \"\").rstrip() -}}\n", " {{- \"<|im_end|>\\n\" -}}\n", "{%- else -%}\n", " {{- \"## Metadata\\n\\n\" -}}\n", " {{- \"Knowledge Cutoff Date: June 2025\\n\" -}}\n", " {%- set today = strftime_now(\"%d %B %Y\") -%}\n", " {{- \"Today Date: \" ~ today ~ \"\\n\" -}}\n", " {{- \"Reasoning Mode: \" + reasoning_mode + \"\\n\\n\" -}}\n", " \n", " {{- \"## Custom Instructions\\n\\n\" -}}\n", " {%- if custom_instructions -%}\n", " {{- custom_instructions + \"\\n\\n\" -}}\n", " {%- elif reasoning_mode == \"/think\" -%}\n", " {{- \"You are a helpful AI assistant named Claire, trained by Hugging Face and fine tuned by Nathanaël SEMHOUN. Your role as an assistant involves thoroughly exploring questions through a systematic thinking process before providing the final precise and accurate solutions. This requires engaging in a comprehensive cycle of analysis, summarizing, exploration, reassessment, reflection, backtracking, and iteration to develop well-considered thinking process. Please structure your response into two main sections: Thought and Solution using the specified format:' and '' tags, it will be executed in a stateful Jupyter notebook environment, and you will then be given the output to continued reasoning in an agentic loop.\\n\\nYou can use the following tools in your python code like regular functions:\\n