From c9e1bd9500dd83344a4eed3343bbcc65c4be51ba Mon Sep 17 00:00:00 2001 From: sergiopaniego Date: Wed, 3 Dec 2025 15:04:31 +0100 Subject: [PATCH 01/10] Ministral 3 SFT notebook --- examples/notebooks/sft_ministral3_vl.ipynb | 1058 ++++++++++++++++++++ 1 file changed, 1058 insertions(+) create mode 100644 examples/notebooks/sft_ministral3_vl.ipynb diff --git a/examples/notebooks/sft_ministral3_vl.ipynb b/examples/notebooks/sft_ministral3_vl.ipynb new file mode 100644 index 00000000000..371d8a182d9 --- /dev/null +++ b/examples/notebooks/sft_ministral3_vl.ipynb @@ -0,0 +1,1058 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "UaDIwQOOjgAO" + }, + "source": [ + "# Supervised Fine-Tuning (SFT) Ministral-3 with QLoRA using TRL\n", + "\n", + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_qwen_vl.ipynb)\n", + "\n", + "![trl banner](https://huggingface.co/datasets/trl-lib/documentation-images/resolve/main/trl_banner_dark.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4f0hzSo4kKEc" + }, + "source": [ + "With [**Transformers Reinforcement Learning (TRL)**](https://github.com/huggingface/trl), you can fine-tune cutting edge vision language models. It comes with support for quantized parameter efficient fine-tuning technique **QLoRA**, so we can use free Colab (T4 GPU) to fine-tune models like [Ministral-3](https://huggingface.co/collections/mistralai/ministral-3).\n", + "\n", + "\n", + "- [TRL GitHub Repository](https://github.com/huggingface/trl) — star us to support the project! \n", + "- [Official TRL Examples (notebooks and scripts)](https://huggingface.co/docs/trl/example_overview) \n", + "- [Community Tutorials](https://huggingface.co/docs/trl/community_tutorials)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pGXgIbj2kXEP" + }, + "source": [ + "## Install dependencies\n", + "\n", + "We'll install **TRL** with the **PEFT** extra, which ensures all main dependencies such as **Transformers** and **PEFT** (a package for parameter-efficient fine-tuning, e.g., LoRA/QLoRA) are included. Additionally, we'll install **trackio** to log and monitor our experiments, and **bitsandbytes** to enable quantization of LLMs, reducing memory consumption for both inference and training." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "V8rqrGq3hmeU", + "outputId": "4a15adc2-e895-4c40-d174-c52e0b208dd5" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n", + " Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n", + " Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m59.4/59.4 MB\u001b[0m \u001b[31m16.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m877.6/877.6 kB\u001b[0m \u001b[31m62.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m6.5/6.5 MB\u001b[0m \u001b[31m106.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m230.6/230.6 kB\u001b[0m \u001b[31m14.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m21.6/21.6 MB\u001b[0m \u001b[31m85.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m55.4/55.4 kB\u001b[0m \u001b[31m3.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m516.2/516.2 kB\u001b[0m \u001b[31m31.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m9.9/9.9 MB\u001b[0m \u001b[31m43.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m40.9/40.9 kB\u001b[0m \u001b[31m3.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m465.5/465.5 kB\u001b[0m \u001b[31m33.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m6.3/6.3 MB\u001b[0m \u001b[31m52.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h Building wheel for transformers (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n", + "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", + "sentence-transformers 5.1.2 requires transformers<5.0.0,>=4.41.0, but you have transformers 5.0.0.dev0 which is incompatible.\u001b[0m\u001b[31m\n", + "\u001b[0m" + ] + } + ], + "source": [ + "!pip install -Uq \"trl[peft]\" bitsandbytes trackio git+https://github.com/huggingface/transformers mistral-common" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ou0VO1gHklS-" + }, + "source": [ + "### Log in to Hugging Face\n", + "\n", + "Log in to your **Hugging Face** account to save your fine-tuned model, track your experiment results directly on the Hub or access gated models. You can find your **access token** on your [account settings page](https://huggingface.co/settings/tokens)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "C5eHAVFthmeU" + }, + "outputs": [], + "source": [ + "from huggingface_hub import notebook_login\n", + "\n", + "notebook_login()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vNylrNdqkoN-" + }, + "source": [ + "## Load dataset\n", + "\n", + "\n", + "We'll load the [**trl-lib/llava-instruct-mix**](https://huggingface.co/datasets/trl-lib/llava-instruct-mix) dataset from the Hugging Face Hub using the `datasets` library.\n", + "\n", + "This dataset is a set of GPT-generated multimodal instruction-following data. We use a processed version for conveniency here. You can check out more details about how to configure your own multimodal dataset for traininig with SFT in the [docs](https://huggingface.co/docs/trl/en/sft_trainer#training-vision-language-models). Fine-tuning Ministral-3 on it helps refine its response style and visual understanding.\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "referenced_widgets": [ + "e0bb4423267a4572b1b9cc894edd25c5" + ] + }, + "id": "hOPra_x5hmeU", + "outputId": "112a213e-0036-452f-e0a8-9295da13c3d1" + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "e0bb4423267a4572b1b9cc894edd25c5", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Resolving data files: 0%| | 0/32 [00:00],\n", + " 'prompt': [{'content': \"How can the presentation of this meal influence one's eating experience?\",\n", + " 'role': 'user'}],\n", + " 'completion': [{'content': \"The presentation of this meal can positively influence one's eating experience. In the image, colorful plastic trays and bowls are used to hold a variety of foods, including meat, vegetables, fruit, and bread. The vibrant presentation can make the meal more visually appealing and enticing, which may encourage healthier eating habits as the dishes include nutritious options like broccoli and oranges. Diverse food options and attractive meal presentation can also make the dining experience more enjoyable and satisfying. Moreover, the bright colors and well-organized food placement can create a positive atmosphere, enhancing one's overall dining experience.\",\n", + " 'role': 'assistant'}]}" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train_dataset[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qeZCtRB1m5xj" + }, + "source": [ + "## Load model and configure LoRA/QLoRA\n", + "\n", + "This notebook can be used with two fine-tuning methods. By default, it is set up for **QLoRA**, which includes quantization using `BitsAndBytesConfig`. If you prefer to use standard **LoRA** without quantization, simply comment out the `BitsAndBytesConfig` configuration.\n", + "\n", + "> **Note:** \n", + "> We use the **Unsloth checkpoint** because it supports older GPUs (including those available on Colab). \n", + "> If you have access to GPUs with **FP8 support**, you can switch to the official model instead." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "referenced_widgets": [ + "5fa6df349d314dd8b1baf79c1ed4eb0b", + "f561335214d84bf1b8985dd4573e9ae1", + "0c557dfead7d46e99af2c6e77b050930" + ] + }, + "id": "8dggHeG2hmeV", + "outputId": "58ceedc1-26b3-467d-f466-e76d850aca5f" + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "5fa6df349d314dd8b1baf79c1ed4eb0b", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Downloading (incomplete total...): 0.00B [00:00, ?B/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "f561335214d84bf1b8985dd4573e9ae1", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Fetching 2 files: 0%| | 0/2 [00:00" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* Created new run: sergiopaniego-1764766746\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/lib/python3.12/dist-packages/torch/_dynamo/eval_frame.py:1044: UserWarning: torch.utils.checkpoint: the use_reentrant parameter should be passed explicitly. Starting in PyTorch 2.9, calling checkpoint without use_reentrant will raise an exception. use_reentrant=False is recommended, but if you need to preserve the current default behavior, you can pass use_reentrant=True. Refer to docs for more details on the differences between the two variants.\n", + " return fn(*args, **kwargs)\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "
\n", + " \n", + " \n", + " [10/10 44:39, Epoch 0/1]\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
StepTraining Loss
11.979992
21.894323
31.924157
41.396819
51.357613
61.345677
71.356363
81.399492
91.356316
101.307108

" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* Run finished. Uploading logs to Trackio (please wait...)\n" + ] + } + ], + "source": [ + "trainer_stats = trainer.train()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "miZ2I1A9nnM4" + }, + "source": [ + "Show memory stats after training" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "eUi4ww17hmeV", + "outputId": "24b18fc3-cb0f-40a1-954d-c3b4d799dfbb" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2492.1064 seconds used for training.\n", + "41.54 minutes used for training.\n", + "Peak reserved memory = 13.881 GB.\n", + "Peak reserved memory for training = 7.535 GB.\n", + "Peak reserved memory % of max memory = 94.166 %.\n", + "Peak reserved memory for training % of max memory = 51.116 %.\n" + ] + } + ], + "source": [ + "used_memory = round(torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, 3)\n", + "used_memory_for_lora = round(used_memory - start_gpu_memory, 3)\n", + "used_percentage = round(used_memory / max_memory * 100, 3)\n", + "lora_percentage = round(used_memory_for_lora / max_memory * 100, 3)\n", + "\n", + "print(f\"{trainer_stats.metrics['train_runtime']} seconds used for training.\")\n", + "print(f\"{round(trainer_stats.metrics['train_runtime']/60, 2)} minutes used for training.\")\n", + "print(f\"Peak reserved memory = {used_memory} GB.\")\n", + "print(f\"Peak reserved memory for training = {used_memory_for_lora} GB.\")\n", + "print(f\"Peak reserved memory % of max memory = {used_percentage} %.\")\n", + "print(f\"Peak reserved memory for training % of max memory = {lora_percentage} %.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3lrrYfPunloQ" + }, + "source": [ + "## Saving fine tuned model\n", + "\n", + "In this step, we save the fine-tuned model both **locally** and to the **Hugging Face Hub** using the credentials from your account." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "referenced_widgets": [ + "ee7d9fe2f71343a4a4832fd2b0fef66f", + "7afb48c0ac514171aa052210e9063fe7", + "7047f7b527284d958df2ec5e800cce56", + "8a106d43be4948ffbb2a2a5281882fe0", + "1f3deb9e16554fd0a4666d52fa9992b2", + "4cb20a75e85a495a8a3b36eb513db36b", + "7ded518429454b5aa2230f98ba0d014c", + "7112497495a742a887c4c956cdf46777", + "cae8cfc256f649d5aa367f923b4aeb5f", + "1a2cfcd18f5f496fa4f6bcf5c0a33966" + ] + }, + "id": "S7TzHDwXhmeV", + "outputId": "0d465e97-5459-4f59-84cf-d5c374503a3b" + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "ee7d9fe2f71343a4a4832fd2b0fef66f", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Processing Files (0 / 0) : | | 0.00B / 0.00B " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7afb48c0ac514171aa052210e9063fe7", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "New Data Upload : | | 0.00B / 0.00B " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7047f7b527284d958df2ec5e800cce56", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " ...trl-sft/training_args.bin: 100%|##########| 5.58kB / 5.58kB " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "8a106d43be4948ffbb2a2a5281882fe0", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " ...ct-trl-sft/tokenizer.json: 98%|#########8| 16.8MB / 17.1MB " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "1f3deb9e16554fd0a4666d52fa9992b2", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " ...adapter_model.safetensors: 6%|6 | 16.7MB / 270MB " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "No files have been modified since last commit. Skipping to prevent empty commit.\n", + "WARNING:huggingface_hub.hf_api:No files have been modified since last commit. Skipping to prevent empty commit.\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "4cb20a75e85a495a8a3b36eb513db36b", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Processing Files (0 / 0) : | | 0.00B / 0.00B " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7ded518429454b5aa2230f98ba0d014c", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "New Data Upload : | | 0.00B / 0.00B " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7112497495a742a887c4c956cdf46777", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " ...trl-sft/training_args.bin: 100%|##########| 5.58kB / 5.58kB " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "cae8cfc256f649d5aa367f923b4aeb5f", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " ...adapter_model.safetensors: 6%|6 | 16.7MB / 270MB " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "1a2cfcd18f5f496fa4f6bcf5c0a33966", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " ...ct-trl-sft/tokenizer.json: 100%|##########| 17.1MB / 17.1MB " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "CommitInfo(commit_url='https://huggingface.co/sergiopaniego/Ministral-3-3B-Instruct-trl-sft/commit/c27744440faa1dd9e74efa5ddbc0b334cfedc9bc', commit_message='End of training', commit_description='', oid='c27744440faa1dd9e74efa5ddbc0b334cfedc9bc', pr_url=None, repo_url=RepoUrl('https://huggingface.co/sergiopaniego/Ministral-3-3B-Instruct-trl-sft', endpoint='https://huggingface.co', repo_type='model', repo_id='sergiopaniego/Ministral-3-3B-Instruct-trl-sft'), pr_revision=None, pr_num=None)" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "trainer.save_model(output_dir)\n", + "trainer.push_to_hub(dataset_name=dataset_name)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pFq51FWEK1DX" + }, + "source": [ + "## Load the fine-tuned model and run inference\n", + "\n", + "Now, let's test our fine-tuned model by loading the **LoRA/QLoRA adapter** and performing **inference**. We'll start by loading the **base model**, then attach the adapter to it, creating the final fine-tuned model ready for evaluation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Xh4fo-WzhmeV" + }, + "outputs": [], + "source": [ + "output_dir = \"Ministral-3-3B-Instruct-trl-sft\"\n", + "# model_name = \"mistralai/Ministral-3-3B-Instruct-2512\"\n", + "model_name = \"unsloth/Ministral-3-3B-Instruct-2512\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "referenced_widgets": [ + "5b4514b95d7742a5a2cc777478a152b7", + "fdfc2ee13efa40218ab315641eb62fb7", + "9aad01ac11794c9ca74d1a442e715da5", + "384a08933c11424cbc48dc28f33ec90e" + ] + }, + "id": "z9S319H-hmeV", + "outputId": "6b5ef891-cc0d-44ba-b112-3c577247a295" + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "5b4514b95d7742a5a2cc777478a152b7", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Downloading (incomplete total...): 0.00B [00:00, ?B/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "fdfc2ee13efa40218ab315641eb62fb7", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Fetching 2 files: 0%| | 0/2 [00:00" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "image" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "YU3hwodphmeW", + "outputId": "7e1757f6-0c77-477a-c35a-2429d8020374" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The presentation of the meal, which is divided into three compartments in a lunch box, can significantly influence one's eating experience. The compartmentalized design allows for a visually appealing and organized presentation of the food, making it more enticing and appetizing. The variety of food items, such as the sandwich, chips, and fruit, also adds to the visual appeal and encourages a balanced and nutritious meal. The compartmentalized layout can also make it easier for the person eating the meal to access and enjoy each component of the meal, as they can easily reach for the food they want without having to rearrange the entire meal. Overall, the presentation of the meal can enhance the eating experience by making it more enjoyable, visually appealing, and convenient.\n" + ] + } + ], + "source": [ + "import torch\n", + "\n", + "tokenized = tokenizer.apply_chat_template(messages, return_tensors=\"pt\", return_dict=True)\n", + "tokenized[\"input_ids\"] = tokenized[\"input_ids\"].to(device=\"cuda\")\n", + "tokenized[\"pixel_values\"] = tokenized[\"pixel_values\"].to(dtype=torch.bfloat16, device=\"cuda\")\n", + "image_sizes = [tokenized[\"pixel_values\"].shape[-2:]]\n", + "\n", + "output = model.generate(\n", + " **tokenized,\n", + " image_sizes=image_sizes,\n", + " max_new_tokens=512,\n", + ")[0]\n", + "\n", + "decoded_output = tokenizer.decode(output[len(tokenized[\"input_ids\"][0]):])\n", + "print(decoded_output)" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + }, + "colab": { + "provenance": [], + "gpuType": "T4" + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "accelerator": "GPU" + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file From c0a46fe62cef721c6214b0175a0cb13e2a05133b Mon Sep 17 00:00:00 2001 From: sergiopaniego Date: Wed, 3 Dec 2025 15:06:35 +0100 Subject: [PATCH 02/10] Cleaned SFT --- examples/notebooks/sft_ministral3_vl.ipynb | 351 ++------------------- 1 file changed, 20 insertions(+), 331 deletions(-) diff --git a/examples/notebooks/sft_ministral3_vl.ipynb b/examples/notebooks/sft_ministral3_vl.ipynb index 371d8a182d9..85ac206e258 100644 --- a/examples/notebooks/sft_ministral3_vl.ipynb +++ b/examples/notebooks/sft_ministral3_vl.ipynb @@ -8,7 +8,7 @@ "source": [ "# Supervised Fine-Tuning (SFT) Ministral-3 with QLoRA using TRL\n", "\n", - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_qwen_vl.ipynb)\n", + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_ministral3_vl.ipynb)\n", "\n", "![trl banner](https://huggingface.co/datasets/trl-lib/documentation-images/resolve/main/trl_banner_dark.png)" ] @@ -45,32 +45,7 @@ "id": "V8rqrGq3hmeU", "outputId": "4a15adc2-e895-4c40-d174-c52e0b208dd5" }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n", - " Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n", - " Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m59.4/59.4 MB\u001b[0m \u001b[31m16.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m877.6/877.6 kB\u001b[0m \u001b[31m62.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m6.5/6.5 MB\u001b[0m \u001b[31m106.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m230.6/230.6 kB\u001b[0m \u001b[31m14.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m21.6/21.6 MB\u001b[0m \u001b[31m85.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m55.4/55.4 kB\u001b[0m \u001b[31m3.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m516.2/516.2 kB\u001b[0m \u001b[31m31.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m9.9/9.9 MB\u001b[0m \u001b[31m43.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m40.9/40.9 kB\u001b[0m \u001b[31m3.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m465.5/465.5 kB\u001b[0m \u001b[31m33.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m6.3/6.3 MB\u001b[0m \u001b[31m52.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25h Building wheel for transformers (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n", - "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", - "sentence-transformers 5.1.2 requires transformers<5.0.0,>=4.41.0, but you have transformers 5.0.0.dev0 which is incompatible.\u001b[0m\u001b[31m\n", - "\u001b[0m" - ] - } - ], + "outputs": [], "source": [ "!pip install -Uq \"trl[peft]\" bitsandbytes trackio git+https://github.com/huggingface/transformers mistral-common" ] @@ -131,22 +106,7 @@ "id": "hOPra_x5hmeU", "outputId": "112a213e-0036-452f-e0a8-9295da13c3d1" }, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "e0bb4423267a4572b1b9cc894edd25c5", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Resolving data files: 0%| | 0/32 [00:00" ] @@ -1040,19 +729,19 @@ } ], "metadata": { - "language_info": { - "name": "python" - }, + "accelerator": "GPU", "colab": { - "provenance": [], - "gpuType": "T4" + "gpuType": "T4", + "provenance": [] }, "kernelspec": { - "name": "python3", - "display_name": "Python 3" + "display_name": "Python 3", + "name": "python3" }, - "accelerator": "GPU" + "language_info": { + "name": "python" + } }, "nbformat": 4, "nbformat_minor": 0 -} \ No newline at end of file +} From a8c4a0e8b3d6dd4ceb6317f617dfc5a2631169cf Mon Sep 17 00:00:00 2001 From: sergiopaniego Date: Wed, 3 Dec 2025 16:25:13 +0100 Subject: [PATCH 03/10] Added to table --- docs/source/example_overview.md | 1 + examples/notebooks/README.md | 1 + examples/notebooks/sft_ministral3_vl.ipynb | 17 +---------------- 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/docs/source/example_overview.md b/docs/source/example_overview.md index 887e1b6914a..a7db70cf4ca 100644 --- a/docs/source/example_overview.md +++ b/docs/source/example_overview.md @@ -29,6 +29,7 @@ These notebooks are easier to run and are designed for quick experimentation wit | Notebook | Description | Open in Colab | |----------|-------------|---------------| +| [`sft_ministral3_vl.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/openenv_wordle_grpo.ipynb) | Supervised Fine-Tuning (SFT) Ministral 3 with QLoRA using TRL on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_ministral3_vl.ipynb) | | [`openenv_wordle_grpo.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/openenv_wordle_grpo.ipynb) | GRPO to play Worldle on an OpenEnv environment | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/openenv_wordle_grpo.ipynb) | | [`sft_trl_lora_qlora.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/sft_trl_lora_qlora.ipynb) | Supervised Fine-Tuning (SFT) using QLoRA on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_trl_lora_qlora.ipynb) | | [`sft_qwen_vl.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/sft_qwen_vl.ipynb) | Supervised Fine-Tuning (SFT) Qwen3-VL with QLoRA using TRL on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_qwen_vl.ipynb) | diff --git a/examples/notebooks/README.md b/examples/notebooks/README.md index 5ce4aa36d95..4981b8f3dfe 100644 --- a/examples/notebooks/README.md +++ b/examples/notebooks/README.md @@ -4,6 +4,7 @@ This directory contains a collection of Jupyter notebooks that demonstrate how t | Notebook | Description | Open in Colab | | --- | --- | --- | +| [`sft_ministral3_vl.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/openenv_wordle_grpo.ipynb) | Supervised Fine-Tuning (SFT) Ministral 3 with QLoRA using TRL on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_ministral3_vl.ipynb) | | [`openenv_wordle_grpo.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/openenv_wordle_grpo.ipynb) | GRPO to play Worldle on an OpenEnv environment | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/openenv_wordle_grpo.ipynb) | | [`sft_trl_lora_qlora.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/sft_trl_lora_qlora.ipynb) | Supervised Fine-Tuning (SFT) using QLoRA on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_trl_lora_qlora.ipynb) | | [`sft_qwen_vl.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/sft_qwen_vl.ipynb) | Supervised Fine-Tuning (SFT) Qwen3-VL with QLoRA using TRL on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_qwen_vl.ipynb) | diff --git a/examples/notebooks/sft_ministral3_vl.ipynb b/examples/notebooks/sft_ministral3_vl.ipynb index 85ac206e258..5127dd267aa 100644 --- a/examples/notebooks/sft_ministral3_vl.ipynb +++ b/examples/notebooks/sft_ministral3_vl.ipynb @@ -648,22 +648,7 @@ "id": "yjBaVAevhmeW", "outputId": "47695454-856a-40b9-8ab2-d621c6e6b3da" }, - "outputs": [ - { - "data": { - "text/plain": [ - "[{'role': 'user',\n", - " 'content': [{'type': 'image_url',\n", - " 'image_url': {'url': 'data:image/jpeg;base64,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'}},\n", - " {'type': 'text',\n", - " 'text': \"How can the presentation of this meal influence one's eating experience?\"}]}]" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "messages" ] From 25b8deb395a2fe44c2e505f9edcccbf18232492f Mon Sep 17 00:00:00 2001 From: sergiopaniego Date: Wed, 3 Dec 2025 16:26:06 +0100 Subject: [PATCH 04/10] Update --- docs/source/example_overview.md | 2 +- examples/notebooks/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/example_overview.md b/docs/source/example_overview.md index a7db70cf4ca..ab41e93b804 100644 --- a/docs/source/example_overview.md +++ b/docs/source/example_overview.md @@ -29,7 +29,7 @@ These notebooks are easier to run and are designed for quick experimentation wit | Notebook | Description | Open in Colab | |----------|-------------|---------------| -| [`sft_ministral3_vl.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/openenv_wordle_grpo.ipynb) | Supervised Fine-Tuning (SFT) Ministral 3 with QLoRA using TRL on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_ministral3_vl.ipynb) | +| [`sft_ministral3_vl.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/sft_ministral3_vl.ipynb) | Supervised Fine-Tuning (SFT) Ministral 3 with QLoRA using TRL on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_ministral3_vl.ipynb) | | [`openenv_wordle_grpo.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/openenv_wordle_grpo.ipynb) | GRPO to play Worldle on an OpenEnv environment | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/openenv_wordle_grpo.ipynb) | | [`sft_trl_lora_qlora.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/sft_trl_lora_qlora.ipynb) | Supervised Fine-Tuning (SFT) using QLoRA on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_trl_lora_qlora.ipynb) | | [`sft_qwen_vl.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/sft_qwen_vl.ipynb) | Supervised Fine-Tuning (SFT) Qwen3-VL with QLoRA using TRL on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_qwen_vl.ipynb) | diff --git a/examples/notebooks/README.md b/examples/notebooks/README.md index 4981b8f3dfe..6e7286be48d 100644 --- a/examples/notebooks/README.md +++ b/examples/notebooks/README.md @@ -4,7 +4,7 @@ This directory contains a collection of Jupyter notebooks that demonstrate how t | Notebook | Description | Open in Colab | | --- | --- | --- | -| [`sft_ministral3_vl.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/openenv_wordle_grpo.ipynb) | Supervised Fine-Tuning (SFT) Ministral 3 with QLoRA using TRL on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_ministral3_vl.ipynb) | +| [`sft_ministral3_vl.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/sft_ministral3_vl.ipynb) | Supervised Fine-Tuning (SFT) Ministral 3 with QLoRA using TRL on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_ministral3_vl.ipynb) | | [`openenv_wordle_grpo.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/openenv_wordle_grpo.ipynb) | GRPO to play Worldle on an OpenEnv environment | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/openenv_wordle_grpo.ipynb) | | [`sft_trl_lora_qlora.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/sft_trl_lora_qlora.ipynb) | Supervised Fine-Tuning (SFT) using QLoRA on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_trl_lora_qlora.ipynb) | | [`sft_qwen_vl.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/sft_qwen_vl.ipynb) | Supervised Fine-Tuning (SFT) Qwen3-VL with QLoRA using TRL on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_qwen_vl.ipynb) | From 50a5b906dafea4409b3f3f4b9da00e921ce96ca1 Mon Sep 17 00:00:00 2001 From: sergiopaniego Date: Wed, 3 Dec 2025 16:36:03 +0100 Subject: [PATCH 05/10] Update --- examples/notebooks/sft_ministral3_vl.ipynb | 25 ++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/examples/notebooks/sft_ministral3_vl.ipynb b/examples/notebooks/sft_ministral3_vl.ipynb index 5127dd267aa..b6e63e94801 100644 --- a/examples/notebooks/sft_ministral3_vl.ipynb +++ b/examples/notebooks/sft_ministral3_vl.ipynb @@ -184,20 +184,27 @@ "from transformers import Mistral3ForConditionalGeneration, FineGrainedFP8Config, BitsAndBytesConfig\n", "import torch\n", "\n", - "# model_name = \"mistralai/Ministral-3-3B-Instruct-2512\"\n", - "model_name = \"unsloth/Ministral-3-3B-Instruct-2512\"\n", + "FP8 = False\n", + "\n", + "if FP8:\n", + " model_name = \"mistralai/Ministral-3-3B-Instruct-2512\"\n", + " quantization_config = FineGrainedFP8Config(dequantize=False)\n", + "else:\n", + " model_name = \"unsloth/Ministral-3-3B-Instruct-2512\"\n", + " quantization_config = (\n", + " BitsAndBytesConfig(\n", + " load_in_4bit=True, # Load the model in 4-bit precision to save memory\n", + " bnb_4bit_compute_dtype=torch.float16, # Data type used for internal computations in quantization\n", + " bnb_4bit_use_double_quant=True, # Use double quantization to improve accuracy\n", + " bnb_4bit_quant_type=\"nf4\", # Type of quantization. \"nf4\" is recommended for recent LLMs\n", + " ),\n", + " )\n", "\n", "model = Mistral3ForConditionalGeneration.from_pretrained(\n", " model_name,\n", " dtype=\"auto\",\n", " device_map=\"auto\",\n", - " # quantization_config=FineGrainedFP8Config(dequantize=False)\n", - " quantization_config=BitsAndBytesConfig(\n", - " load_in_4bit=True, # Load the model in 4-bit precision to save memory\n", - " bnb_4bit_compute_dtype=torch.float16, # Data type used for internal computations in quantization\n", - " bnb_4bit_use_double_quant=True, # Use double quantization to improve accuracy\n", - " bnb_4bit_quant_type=\"nf4\" # Type of quantization. \"nf4\" is recommended for recent LLMs\n", - " )\n", + " quantization_config=quantization_config,\n", ")" ] }, From 7b8a5c98a3749387cd1cff2a1e4b7fce2b742632 Mon Sep 17 00:00:00 2001 From: sergiopaniego Date: Wed, 3 Dec 2025 16:55:06 +0100 Subject: [PATCH 06/10] Update --- examples/notebooks/sft_ministral3_vl.ipynb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/notebooks/sft_ministral3_vl.ipynb b/examples/notebooks/sft_ministral3_vl.ipynb index b6e63e94801..0d8a2427b94 100644 --- a/examples/notebooks/sft_ministral3_vl.ipynb +++ b/examples/notebooks/sft_ministral3_vl.ipynb @@ -608,9 +608,7 @@ "model = Mistral3ForConditionalGeneration.from_pretrained(base_model, dtype=\"auto\", device_map=\"auto\")\n", "model = PeftModel.from_pretrained(model, adapter_model)\n", "\n", - "tokenizer = MistralCommonBackend.from_pretrained(base_model)\n", - "\n", - "#processor = AutoProcessor.from_pretrained(base_model)" + "tokenizer = MistralCommonBackend.from_pretrained(base_model)" ] }, { From feab64aa9cf7201b094a7b1bdd9de9f5784cbc66 Mon Sep 17 00:00:00 2001 From: sergiopaniego Date: Wed, 3 Dec 2025 17:09:06 +0100 Subject: [PATCH 07/10] Added GRPO Ministral 3 notebook --- docs/source/example_overview.md | 1 + examples/notebooks/README.md | 1 + examples/notebooks/grpo_ministral3_vl.ipynb | 730 ++++++++++++++++++++ 3 files changed, 732 insertions(+) create mode 100644 examples/notebooks/grpo_ministral3_vl.ipynb diff --git a/docs/source/example_overview.md b/docs/source/example_overview.md index ab41e93b804..b0d7192485e 100644 --- a/docs/source/example_overview.md +++ b/docs/source/example_overview.md @@ -30,6 +30,7 @@ These notebooks are easier to run and are designed for quick experimentation wit | Notebook | Description | Open in Colab | |----------|-------------|---------------| | [`sft_ministral3_vl.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/sft_ministral3_vl.ipynb) | Supervised Fine-Tuning (SFT) Ministral 3 with QLoRA using TRL on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_ministral3_vl.ipynb) | +| [`grpo_ministral3_vl.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/grpo_ministral3_vl.ipynb) | GRPO Ministral 3 with QLoRA using TRL on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/grpo_ministral3_vl.ipynb) | | [`openenv_wordle_grpo.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/openenv_wordle_grpo.ipynb) | GRPO to play Worldle on an OpenEnv environment | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/openenv_wordle_grpo.ipynb) | | [`sft_trl_lora_qlora.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/sft_trl_lora_qlora.ipynb) | Supervised Fine-Tuning (SFT) using QLoRA on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_trl_lora_qlora.ipynb) | | [`sft_qwen_vl.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/sft_qwen_vl.ipynb) | Supervised Fine-Tuning (SFT) Qwen3-VL with QLoRA using TRL on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_qwen_vl.ipynb) | diff --git a/examples/notebooks/README.md b/examples/notebooks/README.md index 6e7286be48d..b2f4b9e90da 100644 --- a/examples/notebooks/README.md +++ b/examples/notebooks/README.md @@ -5,6 +5,7 @@ This directory contains a collection of Jupyter notebooks that demonstrate how t | Notebook | Description | Open in Colab | | --- | --- | --- | | [`sft_ministral3_vl.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/sft_ministral3_vl.ipynb) | Supervised Fine-Tuning (SFT) Ministral 3 with QLoRA using TRL on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_ministral3_vl.ipynb) | +| [`grpo_ministral3_vl.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/grpo_ministral3_vl.ipynb) | GRPO Ministral 3 with QLoRA using TRL on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/grpo_ministral3_vl.ipynb) | | [`openenv_wordle_grpo.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/openenv_wordle_grpo.ipynb) | GRPO to play Worldle on an OpenEnv environment | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/openenv_wordle_grpo.ipynb) | | [`sft_trl_lora_qlora.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/sft_trl_lora_qlora.ipynb) | Supervised Fine-Tuning (SFT) using QLoRA on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_trl_lora_qlora.ipynb) | | [`sft_qwen_vl.ipynb`](https://github.com/huggingface/trl/tree/main/examples/notebooks/sft_qwen_vl.ipynb) | Supervised Fine-Tuning (SFT) Qwen3-VL with QLoRA using TRL on free Colab | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/sft_qwen_vl.ipynb) | diff --git a/examples/notebooks/grpo_ministral3_vl.ipynb b/examples/notebooks/grpo_ministral3_vl.ipynb new file mode 100644 index 00000000000..d498fcdb2e2 --- /dev/null +++ b/examples/notebooks/grpo_ministral3_vl.ipynb @@ -0,0 +1,730 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "-J8iGzLf4rUJ" + }, + "source": [ + "# GRPO Ministral-3 with QLoRA using TRL\n", + "\n", + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huggingface/trl/blob/main/examples/notebooks/grpo_ministral3_vl.ipynb)\n", + "\n", + "![trl banner](https://huggingface.co/datasets/trl-lib/documentation-images/resolve/main/trl_banner_dark.png)\n", + "\n", + "\n", + "With [**Transformers Reinforcement Learning (TRL)**](https://github.com/huggingface/trl), you can fine-tune cutting edge vision language models. It comes with support for quantized parameter efficient fine-tuning technique **QLoRA**, so we can use free Colab (T4 GPU) to fine-tune models like [Qwen3-VL](https://huggingface.co/collections/Qwen/qwen3-vl-68d2a7c1b8a8afce4ebd2dbe).\n", + "\n", + "\n", + "- [TRL GitHub Repository](https://github.com/huggingface/trl) — star us to support the project! \n", + "- [Official TRL Examples](https://huggingface.co/docs/trl/example_overview) \n", + "- [Community Tutorials](https://huggingface.co/docs/trl/community_tutorials)\n", + "- [More Qwen3-VL Fine-tuning Examples (including TRL scripts)](https://github.com/QwenLM/Qwen3-VL/tree/main/qwen-vl-finetune/)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NvrzGRnu48Vz" + }, + "source": [ + "## Install dependencies\n", + "\n", + "We'll install **TRL** with the **PEFT** extra, which ensures all main dependencies such as **Transformers** and **PEFT** (a package for parameter-efficient fine-tuning, e.g., LoRA/QLoRA) are included. Additionally, we'll install **trackio** to log and monitor our experiments, and **bitsandbytes** to enable quantization of LLMs, reducing memory consumption for both inference and training." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Dbvb3UmQ99p9", + "outputId": "3ad47e9a-017e-4066-8fe8-77a59586fff3" + }, + "outputs": [], + "source": [ + "!pip install -Uq \"trl[peft]\" bitsandbytes trackio math_verify git+https://github.com/huggingface/transformers mistral-common" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gpzI6omi7728" + }, + "source": [ + "### Log in to Hugging Face\n", + "\n", + "Log in to your **Hugging Face** account to save your fine-tuned model, track your experiment results directly on the Hub or access gated models. You can find your **access token** on your [account settings page](https://huggingface.co/settings/tokens)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "referenced_widgets": [ + "2ac44d3c070845af86d9b2e3ce8b949f" + ] + }, + "id": "h5Ubc70Z99p-", + "outputId": "633485d3-c79b-4702-ac01-f5a7be5cadfb" + }, + "outputs": [], + "source": [ + "from huggingface_hub import notebook_login\n", + "\n", + "notebook_login()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "V_Zylc4t79-n" + }, + "source": [ + "## Load dataset\n", + "\n", + "\n", + "We'll load the [**lmms-lab/multimodal-open-r1-8k-verified**](https://huggingface.co/datasets/lmms-lab/multimodal-open-r1-8k-verified) dataset from the Hugging Face Hub using the `datasets` library.\n", + "\n", + "This dataset contains maths problems with the image representing the problem, along with the solution in thinking format specially tailored for VLMs. By training our model with this dataset, it'll improve its maths and thinking reasoning.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "referenced_widgets": [ + "3538a24e7f63433d91144b0ef765d8f0", + "23c73818302c4c879d7eca629b4d734d", + "663a6d37e74c4663a0d5c31aa14b47d6" + ] + }, + "id": "OsyilesY99p-", + "outputId": "4cca7fa0-5f49-4c40-e36a-3a87d2496177" + }, + "outputs": [], + "source": [ + "from datasets import load_dataset\n", + "\n", + "dataset_id = 'lmms-lab/multimodal-open-r1-8k-verified'\n", + "train_dataset = load_dataset(dataset_id, split='train[:5%]')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gVV7RoRN8zk5" + }, + "source": [ + "In addition to the `problem` and `image` columns, we also include a custom system prompt to tell the model how we'd like the generation.\n", + "\n", + "The system prompt is extracted from DeepSeek R1. Refer to [this previous recipe](https://huggingface.co/learn/cookbook/fine_tuning_llm_grpo_trl) for more details.\n", + "\n", + "We convert the dataset samples into conversation samples, including the system prompt and one image and problem description per sample, since this is how the GRPO trainer expects them.\n", + "\n", + "We also set `padding_side=\"left\"` to ensure that generated completions during training are concatenated directly after the prompt, which is essential for GRPO to correctly compare token-level probabilities between preferred and rejected responses.\n", + "\n", + "> **Note:** \n", + "> We use the **Unsloth checkpoint** because it supports older GPUs (including those available on Colab). \n", + "> If you have access to GPUs with **FP8 support**, you can switch to the official model instead." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "referenced_widgets": [ + "83dfeaab2bd04b06899d09b6b35bacd1", + "8588996c1d2d444193e9cf53c1a73b8e", + "138a997da09f40ada32171e51b51b708", + "06ef4d5f41de4436ad4731cbf2f8471f" + ] + }, + "id": "WlK7KYKT99p-", + "outputId": "db72808f-21cf-4022-ed1a-b78ebb3ee47e" + }, + "outputs": [], + "source": [ + "from transformers import AutoProcessor\n", + "\n", + "#model_name = \"mistralai/Ministral-3-3B-Instruct-2512\"\n", + "model_name = \"unsloth/Ministral-3-3B-Instruct-2512\"\n", + "processor = AutoProcessor.from_pretrained(model_name, padding_side=\"left\")\n", + "\n", + "SYSTEM_PROMPT = (\n", + " \"You are a helpful AI Assistant that provides well-reasoned and detailed responses. \"\n", + " \"You first think about the reasoning process as an internal monologue and then provide the user with the answer. \"\n", + " \"Respond in the following format: \\n...\\n\\n\\n...\\n\"\n", + ")\n", + "\n", + "\n", + "def make_conversation(example):\n", + " conversation = [\n", + " {\n", + " \"role\": \"system\",\n", + " \"content\": [{\"type\": \"text\", \"text\": SYSTEM_PROMPT}],\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": [\n", + " {\"type\": \"image\", \"image\": example[\"image\"]},\n", + " {\"type\": \"text\", \"text\": example[\"problem\"]},\n", + " ],\n", + " },\n", + " ]\n", + " return {\n", + " \"prompt\": conversation,\n", + " \"image\": example[\"image\"],\n", + " }\n", + "\n", + "train_dataset = train_dataset.map(make_conversation)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5txAuMAa8ock" + }, + "source": [ + "Let's review one example to understand the internal structure:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "sjxG7duU99p_" + }, + "outputs": [], + "source": [ + "train_dataset[0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "ZooycTF099p_" + }, + "outputs": [], + "source": [ + "train_dataset = train_dataset.remove_columns(['problem', 'original_question', 'original_answer'])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "2LcjFKgD99p_" + }, + "outputs": [], + "source": [ + "train_dataset[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YY3uMp909Eqy" + }, + "source": [ + "## Load model and configure LoRA/QLoRA\n", + "\n", + "This notebook can be used with two fine-tuning methods. By default, it is set up for **QLoRA**, which includes quantization using `BitsAndBytesConfig`. If you prefer to use standard **LoRA** without quantization, simply comment out the `BitsAndBytesConfig` configuration." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "RcQn7mGs99p_" + }, + "outputs": [], + "source": [ + "from transformers import Mistral3ForConditionalGeneration, FineGrainedFP8Config, BitsAndBytesConfig\n", + "import torch\n", + "\n", + "FP8 = False\n", + "\n", + "if FP8:\n", + " model_name = \"mistralai/Ministral-3-3B-Instruct-2512\"\n", + " quantization_config = FineGrainedFP8Config(dequantize=False)\n", + "else:\n", + " model_name = \"unsloth/Ministral-3-3B-Instruct-2512\"\n", + " quantization_config = (\n", + " BitsAndBytesConfig(\n", + " load_in_4bit=True, # Load the model in 4-bit precision to save memory\n", + " bnb_4bit_compute_dtype=torch.float16, # Data type used for internal computations in quantization\n", + " bnb_4bit_use_double_quant=True, # Use double quantization to improve accuracy\n", + " bnb_4bit_quant_type=\"nf4\", # Type of quantization. \"nf4\" is recommended for recent LLMs\n", + " ),\n", + " )\n", + "\n", + "model = Mistral3ForConditionalGeneration.from_pretrained(\n", + " model_name,\n", + " dtype=\"auto\",\n", + " device_map=\"auto\",\n", + " quantization_config=quantization_config,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WZGf-GF09Gsc" + }, + "source": [ + "The following cell defines LoRA (or QLoRA if needed). When training with LoRA/QLoRA, we use a **base model** (the one selected above) and, instead of modifying its original weights, we fine-tune a **LoRA adapter** — a lightweight layer that enables efficient and memory-friendly training. The **`target_modules`** specify which parts of the model (e.g., attention or projection layers) will be adapted by LoRA during fine-tuning." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "LqCEI4hf99p_" + }, + "outputs": [], + "source": [ + "from peft import LoraConfig\n", + "\n", + "# You may need to update `target_modules` depending on the architecture of your chosen model.\n", + "# For example, different VLMs might have different attention/projection layer names.\n", + "peft_config = LoraConfig(\n", + " r=8,\n", + " lora_alpha=32,\n", + " lora_dropout=0.1,\n", + " target_modules=[\"q_proj\", \"v_proj\"],\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mDq4V6dN9MGk" + }, + "source": [ + "## Train model\n", + "\n", + "We'll configure **GRPO** using `GRPOConfig`, keeping the parameters minimal so the training fits on a free Colab instance. You can adjust these settings if more resources are available. For full details on all available parameters, check the [TRL GRPOConfig documentation](https://huggingface.co/docs/trl/sft_trainer#trl.GRPOConfig).\n", + "\n", + "First, we need to define the rewards functions that the training algorithm will use to improve the model. In this case, we'll include two reward functions.\n", + "We'll use a format reward that will reward the model when the output includes `` and `` tags and additionally a length-based reward to discourage overthinking. Both functions have been extracted from [here](https://github.com/huggingface/open-r1/blob/main/src/open_r1/rewards.py)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "jhgqx8kO99p_" + }, + "outputs": [], + "source": [ + "import re\n", + "\n", + "def format_reward(completions, **kwargs):\n", + " \"\"\"Reward function that checks if the reasoning process is enclosed within and tags, while the final answer is enclosed within and tags.\"\"\"\n", + " pattern = r\".*?.*?.*?\"\n", + "\n", + " matches = []\n", + " for item in completions:\n", + " if isinstance(item, list):\n", + " text = item[0]['content']\n", + " else:\n", + " text = item\n", + " match = re.match(pattern, text, re.DOTALL | re.MULTILINE)\n", + " matches.append(match)\n", + "\n", + " return [1.0 if match else 0.0 for match in matches]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "sVmzQ_wL99p_" + }, + "outputs": [], + "source": [ + "from math_verify import LatexExtractionConfig, parse, verify\n", + "from latex2sympy2_extended import NormalizationConfig\n", + "\n", + "\n", + "def len_reward(completions, solution, **kwargs) -> float:\n", + " \"\"\"Compute length-based rewards to discourage overthinking and promote token efficiency.\n", + "\n", + " Taken from the Kimi 1.5 tech report: https://huggingface.co/papers/2501.12599\n", + "\n", + " Args:\n", + " completions: List of model completions\n", + " solution: List of ground truth solutions\n", + "\n", + " Returns:\n", + " List of rewards where:\n", + " - For correct answers: reward = 0.5 - (len - min_len)/(max_len - min_len)\n", + " - For incorrect answers: reward = min(0, 0.5 - (len - min_len)/(max_len - min_len))\n", + " \"\"\"\n", + " contents = []\n", + " for item in completions:\n", + " if isinstance(item, list):\n", + " text = item[0]['content']\n", + " else:\n", + " text = item\n", + " contents.append(text)\n", + "\n", + " # First check correctness of answers\n", + " correctness = []\n", + " for content, sol in zip(contents, solution):\n", + " gold_parsed = parse(\n", + " sol,\n", + " extraction_mode=\"first_match\",\n", + " extraction_config=[LatexExtractionConfig()],\n", + " )\n", + " if len(gold_parsed) == 0:\n", + " # Skip unparseable examples\n", + " correctness.append(True) # Treat as correct to avoid penalizing\n", + " print(\"Failed to parse gold solution: \", sol)\n", + " continue\n", + "\n", + " answer_parsed = parse(\n", + " content,\n", + " extraction_config=[\n", + " LatexExtractionConfig(\n", + " normalization_config=NormalizationConfig(\n", + " nits=False,\n", + " malformed_operators=False,\n", + " basic_latex=True,\n", + " equations=True,\n", + " boxed=True,\n", + " units=True,\n", + " ),\n", + " boxed_match_priority=0,\n", + " try_extract_without_anchor=False,\n", + " )\n", + " ],\n", + " extraction_mode=\"first_match\",\n", + " )\n", + " correctness.append(verify(answer_parsed, gold_parsed))\n", + "\n", + " # Calculate lengths\n", + " lengths = [len(content) for content in contents]\n", + " min_len = min(lengths)\n", + " max_len = max(lengths)\n", + "\n", + " # If all responses have the same length, return zero rewards\n", + " if max_len == min_len:\n", + " return [0.0] * len(completions)\n", + "\n", + " rewards = []\n", + " for length, is_correct in zip(lengths, correctness):\n", + " lambda_val = 0.5 - (length - min_len) / (max_len - min_len)\n", + "\n", + " if is_correct:\n", + " reward = lambda_val\n", + " else:\n", + " reward = min(0, lambda_val)\n", + "\n", + " rewards.append(float(reward))\n", + "\n", + " return rewards" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9xBL7Rni9LZb" + }, + "source": [ + "After defining the reward function(s), we can define the `GRPOConfig`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "pcv6KXUD99qA" + }, + "outputs": [], + "source": [ + "from trl import GRPOConfig\n", + "\n", + "output_dir = \"Ministral-3-3B-Instruct-trl-grpo\"\n", + "\n", + "# Configure training arguments using GRPOConfig\n", + "training_args = GRPOConfig(\n", + " learning_rate=2e-5,\n", + " #num_train_epochs=1,\n", + " max_steps=100, # Number of dataset passes. For full trainings, use `num_train_epochs` instead\n", + "\n", + " # Parameters that control the data preprocessing\n", + " per_device_train_batch_size=2,\n", + " max_completion_length=1024, # default: 256 # Max completion length produced during training\n", + " num_generations=2, # 2, # default: 8 # Number of generations produced during trainig for comparison\n", + " max_prompt_length=2048, # default: 512 # Max prompt lenght of the input prompt used for generation during training\n", + "\n", + " fp16=False,\n", + " bf16=False,\n", + "\n", + " # Parameters related to reporting and saving\n", + " output_dir=output_dir, # Where to save model checkpoints and logs\n", + " logging_steps=1, # Log training metrics every N steps\n", + " report_to=\"trackio\", # Experiment tracking tool\n", + " trackio_space_id = output_dir,\n", + "\n", + " # Hub integration\n", + " push_to_hub=True,\n", + " log_completions=True,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "O0q3myQg927v" + }, + "source": [ + "Configure the GRPO Trainer. We pass the previously configured `training_args`. We don't use eval dataset to maintain memory usage low but you can configure it." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "-zd7s5Cs99qA" + }, + "outputs": [], + "source": [ + "from trl import GRPOTrainer\n", + "\n", + "trainer = GRPOTrainer(\n", + " model=model,\n", + " reward_funcs=[format_reward, len_reward],\n", + " args=training_args,\n", + " train_dataset=train_dataset,\n", + " peft_config=peft_config,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kQC7Q5kg95xq" + }, + "source": [ + "Show memory stats before training" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "iF7cnD0T99qA" + }, + "outputs": [], + "source": [ + "gpu_stats = torch.cuda.get_device_properties(0)\n", + "start_gpu_memory = round(torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, 3)\n", + "max_memory = round(gpu_stats.total_memory / 1024 / 1024 / 1024, 3)\n", + "\n", + "print(f\"GPU = {gpu_stats.name}. Max memory = {max_memory} GB.\")\n", + "print(f\"{start_gpu_memory} GB of memory reserved.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YazYtLAe97Dc" + }, + "source": [ + "And train!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Ynhxdv3a99qA" + }, + "outputs": [], + "source": [ + "trainer_stats = trainer.train()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SmcYN5yW99IP" + }, + "source": [ + "Show memory stats after training" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "mi-exH7699qA" + }, + "outputs": [], + "source": [ + "used_memory = round(torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, 3)\n", + "used_memory_for_lora = round(used_memory - start_gpu_memory, 3)\n", + "used_percentage = round(used_memory / max_memory * 100, 3)\n", + "lora_percentage = round(used_memory_for_lora / max_memory * 100, 3)\n", + "\n", + "print(f\"{trainer_stats.metrics['train_runtime']} seconds used for training.\")\n", + "print(f\"{round(trainer_stats.metrics['train_runtime']/60, 2)} minutes used for training.\")\n", + "print(f\"Peak reserved memory = {used_memory} GB.\")\n", + "print(f\"Peak reserved memory for training = {used_memory_for_lora} GB.\")\n", + "print(f\"Peak reserved memory % of max memory = {used_percentage} %.\")\n", + "print(f\"Peak reserved memory for training % of max memory = {lora_percentage} %.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "saarW87Y9_-R" + }, + "source": [ + "## Saving fine tuned model\n", + "\n", + "In this step, we save the fine-tuned model both **locally** and to the **Hugging Face Hub** using the credentials from your account." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "m3mlwQl699qA" + }, + "outputs": [], + "source": [ + "trainer.save_model(output_dir)\n", + "trainer.push_to_hub(dataset_name=dataset_id)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nfqvO0qw-OvS" + }, + "source": [ + "## Load the fine-tuned model and run inference\n", + "\n", + "Now, let's test our fine-tuned model by loading the **LoRA/QLoRA adapter** and performing **inference**. We'll start by loading the **base model**, then attach the adapter to it, creating the final fine-tuned model ready for evaluation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "B7usNBq699qA" + }, + "outputs": [], + "source": [ + "from transformers import Mistral3ForConditionalGeneration, MistralCommonBackend\n", + "from peft import PeftModel\n", + "\n", + "base_model = model_name\n", + "adapter_model = f\"{output_dir}\" # Replace with your HF username or organization\n", + "\n", + "model = Mistral3ForConditionalGeneration.from_pretrained(base_model, dtype=\"auto\", device_map=\"auto\")\n", + "model = PeftModel.from_pretrained(model, adapter_model)\n", + "\n", + "tokenizer = MistralCommonBackend.from_pretrained(base_model)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "XnIOkXfy99qA" + }, + "outputs": [], + "source": [ + "train_dataset[0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "0le5gBl_99qA" + }, + "outputs": [], + "source": [ + "from datasets import load_dataset\n", + "\n", + "dataset_id = 'lmms-lab/multimodal-open-r1-8k-verified'\n", + "train_dataset = load_dataset(dataset_id, split='train[:5%]')\n", + "\n", + "problem = train_dataset[0]['problem']\n", + "image = train_dataset[0]['image']\n", + "\n", + "messages = [\n", + " {\n", + " \"role\": \"system\", \"content\": [\n", + " {\"type\": \"text\", \"text\": SYSTEM_PROMPT}\n", + " ]\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": [\n", + " {\"type\": \"image\", \"image\": image},\n", + " {\"type\": \"text\", \"text\": problem},\n", + " ],\n", + " },\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "f9PgBCD499qA" + }, + "outputs": [], + "source": [ + "messages" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "ENOGILKk99qA" + }, + "outputs": [], + "source": [ + "import torch\n", + "\n", + "tokenized = tokenizer.apply_chat_template(messages, return_tensors=\"pt\", return_dict=True)\n", + "tokenized[\"input_ids\"] = tokenized[\"input_ids\"].to(device=\"cuda\")\n", + "tokenized[\"pixel_values\"] = tokenized[\"pixel_values\"].to(dtype=torch.bfloat16, device=\"cuda\")\n", + "image_sizes = [tokenized[\"pixel_values\"].shape[-2:]]\n", + "\n", + "output = model.generate(\n", + " **tokenized,\n", + " image_sizes=image_sizes,\n", + " max_new_tokens=512,\n", + ")[0]\n", + "\n", + "decoded_output = tokenizer.decode(output[len(tokenized[\"input_ids\"][0]):])\n", + "print(decoded_output)" + ] + } + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "gpuType": "T4", + "provenance": [] + }, + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} From db1a673c3c522f68a36a7ca57eee8c3eee071488 Mon Sep 17 00:00:00 2001 From: sergiopaniego Date: Wed, 3 Dec 2025 17:14:54 +0100 Subject: [PATCH 08/10] Updated --- examples/notebooks/grpo_ministral3_vl.ipynb | 12 +++++------- examples/notebooks/sft_ministral3_vl.ipynb | 12 +++++------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/examples/notebooks/grpo_ministral3_vl.ipynb b/examples/notebooks/grpo_ministral3_vl.ipynb index d498fcdb2e2..56c64b5f16b 100644 --- a/examples/notebooks/grpo_ministral3_vl.ipynb +++ b/examples/notebooks/grpo_ministral3_vl.ipynb @@ -253,13 +253,11 @@ " quantization_config = FineGrainedFP8Config(dequantize=False)\n", "else:\n", " model_name = \"unsloth/Ministral-3-3B-Instruct-2512\"\n", - " quantization_config = (\n", - " BitsAndBytesConfig(\n", - " load_in_4bit=True, # Load the model in 4-bit precision to save memory\n", - " bnb_4bit_compute_dtype=torch.float16, # Data type used for internal computations in quantization\n", - " bnb_4bit_use_double_quant=True, # Use double quantization to improve accuracy\n", - " bnb_4bit_quant_type=\"nf4\", # Type of quantization. \"nf4\" is recommended for recent LLMs\n", - " ),\n", + " quantization_config = BitsAndBytesConfig(\n", + " load_in_4bit=True, # Load the model in 4-bit precision to save memory\n", + " bnb_4bit_compute_dtype=torch.float16, # Data type used for internal computations in quantization\n", + " bnb_4bit_use_double_quant=True, # Use double quantization to improve accuracy\n", + " bnb_4bit_quant_type=\"nf4\", # Type of quantization. \"nf4\" is recommended for recent LLMs\n", " )\n", "\n", "model = Mistral3ForConditionalGeneration.from_pretrained(\n", diff --git a/examples/notebooks/sft_ministral3_vl.ipynb b/examples/notebooks/sft_ministral3_vl.ipynb index 0d8a2427b94..38b0efca3c9 100644 --- a/examples/notebooks/sft_ministral3_vl.ipynb +++ b/examples/notebooks/sft_ministral3_vl.ipynb @@ -191,13 +191,11 @@ " quantization_config = FineGrainedFP8Config(dequantize=False)\n", "else:\n", " model_name = \"unsloth/Ministral-3-3B-Instruct-2512\"\n", - " quantization_config = (\n", - " BitsAndBytesConfig(\n", - " load_in_4bit=True, # Load the model in 4-bit precision to save memory\n", - " bnb_4bit_compute_dtype=torch.float16, # Data type used for internal computations in quantization\n", - " bnb_4bit_use_double_quant=True, # Use double quantization to improve accuracy\n", - " bnb_4bit_quant_type=\"nf4\", # Type of quantization. \"nf4\" is recommended for recent LLMs\n", - " ),\n", + " quantization_config = BitsAndBytesConfig(\n", + " load_in_4bit=True, # Load the model in 4-bit precision to save memory\n", + " bnb_4bit_compute_dtype=torch.float16, # Data type used for internal computations in quantization\n", + " bnb_4bit_use_double_quant=True, # Use double quantization to improve accuracy\n", + " bnb_4bit_quant_type=\"nf4\", # Type of quantization. \"nf4\" is recommended for recent LLMs\n", " )\n", "\n", "model = Mistral3ForConditionalGeneration.from_pretrained(\n", From f9ae3fd873db018a10afe4d2fcf82d267397cbb3 Mon Sep 17 00:00:00 2001 From: sergiopaniego Date: Wed, 3 Dec 2025 17:17:25 +0100 Subject: [PATCH 09/10] Remove qwen mention --- examples/notebooks/grpo_ministral3_vl.ipynb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/notebooks/grpo_ministral3_vl.ipynb b/examples/notebooks/grpo_ministral3_vl.ipynb index 56c64b5f16b..98a9a8b8832 100644 --- a/examples/notebooks/grpo_ministral3_vl.ipynb +++ b/examples/notebooks/grpo_ministral3_vl.ipynb @@ -13,13 +13,12 @@ "![trl banner](https://huggingface.co/datasets/trl-lib/documentation-images/resolve/main/trl_banner_dark.png)\n", "\n", "\n", - "With [**Transformers Reinforcement Learning (TRL)**](https://github.com/huggingface/trl), you can fine-tune cutting edge vision language models. It comes with support for quantized parameter efficient fine-tuning technique **QLoRA**, so we can use free Colab (T4 GPU) to fine-tune models like [Qwen3-VL](https://huggingface.co/collections/Qwen/qwen3-vl-68d2a7c1b8a8afce4ebd2dbe).\n", + "With [**Transformers Reinforcement Learning (TRL)**](https://github.com/huggingface/trl), you can fine-tune cutting edge vision language models. It comes with support for quantized parameter efficient fine-tuning technique **QLoRA**, so we can use free Colab (T4 GPU) to fine-tune models like [Ministral-3](https://huggingface.co/collections/mistralai/ministral-3).\n", "\n", "\n", "- [TRL GitHub Repository](https://github.com/huggingface/trl) — star us to support the project! \n", - "- [Official TRL Examples](https://huggingface.co/docs/trl/example_overview) \n", - "- [Community Tutorials](https://huggingface.co/docs/trl/community_tutorials)\n", - "- [More Qwen3-VL Fine-tuning Examples (including TRL scripts)](https://github.com/QwenLM/Qwen3-VL/tree/main/qwen-vl-finetune/)" + "- [Official TRL Examples (notebooks and scripts)](https://huggingface.co/docs/trl/example_overview) \n", + "- [Community Tutorials](https://huggingface.co/docs/trl/community_tutorials)" ] }, { From 6af1352ee67c77ae5f0862da81aeb9b210d5cf7d Mon Sep 17 00:00:00 2001 From: sergiopaniego Date: Wed, 3 Dec 2025 17:24:53 +0100 Subject: [PATCH 10/10] GRPO final nits --- examples/notebooks/grpo_ministral3_vl.ipynb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/examples/notebooks/grpo_ministral3_vl.ipynb b/examples/notebooks/grpo_ministral3_vl.ipynb index 98a9a8b8832..97d4281f997 100644 --- a/examples/notebooks/grpo_ministral3_vl.ipynb +++ b/examples/notebooks/grpo_ministral3_vl.ipynb @@ -652,6 +652,8 @@ "outputs": [], "source": [ "from datasets import load_dataset\n", + "import base64\n", + "from io import BytesIO\n", "\n", "dataset_id = 'lmms-lab/multimodal-open-r1-8k-verified'\n", "train_dataset = load_dataset(dataset_id, split='train[:5%]')\n", @@ -659,6 +661,11 @@ "problem = train_dataset[0]['problem']\n", "image = train_dataset[0]['image']\n", "\n", + "buffer = BytesIO()\n", + "image.save(buffer, format=\"JPEG\")\n", + "image_bytes = buffer.getvalue()\n", + "image_b64 = base64.b64encode(image_bytes).decode(\"utf-8\")\n", + "\n", "messages = [\n", " {\n", " \"role\": \"system\", \"content\": [\n", @@ -668,7 +675,12 @@ " {\n", " \"role\": \"user\",\n", " \"content\": [\n", - " {\"type\": \"image\", \"image\": image},\n", + " {\n", + " \"type\": \"image_url\",\n", + " \"image_url\": {\n", + " \"url\": f\"data:image/jpeg;base64,{image_b64}\"\n", + " },\n", + " },\n", " {\"type\": \"text\", \"text\": problem},\n", " ],\n", " },\n",