eecebe7ef5
Five-lane parallel research pass. Each subdir under tooling/ has its own README indexing downloaded files with verified upstream sources. - google-official/: deepmind-gemma JAX examples, gemma_pytorch scripts, gemma.cpp API server docs, google-gemma/cookbook notebooks, ai.google.dev HTML snapshots, Gemma 3 tech report - huggingface/: 8 gemma-4-* model cards, chat-template .jinja files, tokenizer_config.json, transformers gemma4/ source, launch blog posts, official HF Spaces app.py - inference-frameworks/: vLLM/llama.cpp/MLX/Keras-hub/TGI/Gemini API/Vertex AI comparison, run_commands.sh with 8 working launches, 9 code snippets - gemma-family/: 12 per-variant briefs (ShieldGemma 2, CodeGemma, PaliGemma 2, Recurrent/Data/Med/TxGemma, Embedding/Translate/Function/Dolphin/SignGemma) - fine-tuning/: Unsloth Gemma 4 notebooks, Axolotl YAMLs (incl 26B-A4B MoE), TRL scripts, Google cookbook fine-tune notebooks, recipe-recommendation.md Findings that update earlier CORPUS_* docs are flagged in tooling/README.md (not applied) — notably the new <|turn>/<turn|> prompt format, gemma_pytorch abandonment, gemma.cpp Gemini-API server, transformers AutoModelForMultimodalLM, FA2 head_dim=512 break, 26B-A4B MoE quantization rules, no Gemma 4 tech report PDF yet, no Gemma-4-generation specialized siblings yet. Pre-commit secrets hook bypassed per user authorization — flagged "secrets" are base64 notebook cell outputs and example Ed25519 keys in the HDP agentic-security demo, not real credentials. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
449 lines
17 KiB
Python
449 lines
17 KiB
Python
#!/usr/bin/env python
|
||
# coding: utf-8
|
||
|
||
# To run this, press "*Runtime*" and press "*Run all*" on a Google Colab A100 instance!
|
||
# <div class="align-center">
|
||
# <a href="https://unsloth.ai/"><img src="https://github.com/unslothai/unsloth/raw/main/images/unsloth%20new%20logo.png" width="115"></a>
|
||
# <a href="https://discord.gg/unsloth"><img src="https://github.com/unslothai/unsloth/raw/main/images/Discord button.png" width="145"></a>
|
||
# <a href="https://unsloth.ai/docs/"><img src="https://github.com/unslothai/unsloth/blob/main/images/documentation%20green%20button.png?raw=true" width="125"></a> Join Discord if you need help + ⭐ <i>Star us on <a href="https://github.com/unslothai/unsloth">Github</a> </i> ⭐
|
||
# </div>
|
||
#
|
||
# To install Unsloth on your local device, follow [our guide](https://unsloth.ai/docs/get-started/install). This notebook is licensed [LGPL-3.0](https://github.com/unslothai/notebooks?tab=LGPL-3.0-1-ov-file#readme).
|
||
#
|
||
# You will learn how to do [data prep](#Data), how to [train](#Train), how to [run the model](#Inference), & how to save it
|
||
|
||
# ### News
|
||
|
||
# Introducing **Unsloth Studio** - a new open source, no-code web UI to train and run LLMs. [Blog](https://unsloth.ai/docs/new/studio) • [Notebook](https://colab.research.google.com/github/unslothai/unsloth/blob/main/studio/Unsloth_Studio_Colab.ipynb)
|
||
#
|
||
# <table><tr>
|
||
# <td align="center"><a href="https://unsloth.ai/docs/new/studio"><img src="https://unsloth.ai/docs/~gitbook/image?url=https%3A%2F%2F3215535692-files.gitbook.io%2F~%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FxhOjnexMCB3dmuQFQ2Zq%252Fuploads%252FxV1PO5DbF3ksB51nE2Tw%252Fmore%2520cropped%2520ui%2520for%2520homepage.png%3Falt%3Dmedia%26token%3Df75942c9-3d8d-4b59-8ba2-1a4a38de1b86&width=376&dpr=3&quality=100&sign=a663c397&sv=2" width="200" height="120" alt="Unsloth Studio Training UI"></a><br><sub><b>Train models</b> — no code needed</sub></td>
|
||
# <td align="center"><a href="https://unsloth.ai/docs/new/studio"><img src="https://unsloth.ai/docs/~gitbook/image?url=https%3A%2F%2F3215535692-files.gitbook.io%2F~%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FxhOjnexMCB3dmuQFQ2Zq%252Fuploads%252FRCnTAZ6Uh88DIlU3g0Ij%252Fmainpage%2520unsloth.png%3Falt%3Dmedia%26token%3D837c96b6-bd09-4e81-bc76-fa50421e9bfb&width=376&dpr=3&quality=100&sign=c1a39da1&sv=2" width="200" height="120" alt="Unsloth Studio Chat UI"></a><br><sub><b>Run GGUF models</b> on Mac, Windows & Linux</sub></td>
|
||
# </tr></table>
|
||
#
|
||
# Train MoEs - DeepSeek, GLM, Qwen and gpt-oss 12x faster with 35% less VRAM. [Blog](https://unsloth.ai/docs/new/faster-moe)
|
||
#
|
||
# Ultra Long-Context Reinforcement Learning is here with 7x more context windows! [Blog](https://unsloth.ai/docs/new/grpo-long-context)
|
||
#
|
||
# New in Reinforcement Learning: [FP8 RL](https://unsloth.ai/docs/new/fp8-reinforcement-learning) • [Vision RL](https://unsloth.ai/docs/new/vision-reinforcement-learning-vlm-rl) • [Standby](https://unsloth.ai/docs/basics/memory-efficient-rl) • [gpt-oss RL](https://unsloth.ai/docs/new/gpt-oss-reinforcement-learning)
|
||
#
|
||
# Visit our docs for all our [model uploads](https://unsloth.ai/docs/get-started/unsloth-model-catalog) and [notebooks](https://unsloth.ai/docs/get-started/unsloth-notebooks).
|
||
|
||
# # ### Installation
|
||
#
|
||
# # In[1]:
|
||
#
|
||
#
|
||
# get_ipython().run_cell_magic('capture', '', 'import os, re\nif "COLAB_" not in "".join(os.environ.keys()):\n !pip install unsloth # Do this in local & cloud setups\nelse:\n import torch; v = re.match(r\'[\\d]{1,}\\.[\\d]{1,}\', str(torch.__version__)).group(0)\n xformers = \'xformers==\' + {\'2.10\':\'0.0.34\',\'2.9\':\'0.0.33.post1\',\'2.8\':\'0.0.32.post2\'}.get(v, "0.0.34")\n !pip install sentencepiece protobuf "datasets==4.3.0" "huggingface_hub>=0.34.0" hf_transfer\n !pip install --no-deps unsloth_zoo bitsandbytes accelerate {xformers} peft trl triton unsloth\n!pip install --no-deps transformers==5.5.0\n!pip install torchcodec\nimport torch; torch._dynamo.config.recompile_limit = 64;\n')
|
||
#
|
||
#
|
||
# # In[2]:
|
||
#
|
||
#
|
||
# get_ipython().run_cell_magic('capture', '', '!pip install --no-deps --upgrade timm # For Gemma 4 vision/audio\n')
|
||
#
|
||
#
|
||
# # ### Unsloth
|
||
|
||
# In[3]:
|
||
|
||
|
||
from unsloth import FastVisionModel # FastLanguageModel for LLMs
|
||
import torch
|
||
|
||
gemma4_models = [
|
||
# Gemma-4 instruct models:
|
||
"unsloth/gemma-4-E2B-it",
|
||
"unsloth/gemma-4-E4B-it",
|
||
"unsloth/gemma-4-31B-it",
|
||
"unsloth/gemma-4-26B-A4B-it",
|
||
# Gemma-4 base models:
|
||
"unsloth/gemma-4-E2B",
|
||
"unsloth/gemma-4-E4B",
|
||
"unsloth/gemma-4-31B",
|
||
"unsloth/gemma-4-26B-A4B",
|
||
] # More models at https://huggingface.co/unsloth
|
||
|
||
model, processor = FastVisionModel.from_pretrained(
|
||
"unsloth/gemma-4-26B-A4B-it",
|
||
load_in_4bit = True, # Use 4bit to reduce memory use. False for 16bit LoRA.
|
||
use_gradient_checkpointing = "unsloth", # True or "unsloth" for long context
|
||
)
|
||
|
||
|
||
# We now add LoRA adapters for parameter efficient fine-tuning, allowing us to train only 1% of all model parameters efficiently.
|
||
#
|
||
# **[NEW]** We also support fine-tuning only the vision component, only the language component, or both. Additionally, you can choose to fine-tune the attention modules, the MLP layers, or both!
|
||
|
||
# In[4]:
|
||
|
||
|
||
model = FastVisionModel.get_peft_model(
|
||
model,
|
||
finetune_vision_layers = True, # False if not finetuning vision layers
|
||
finetune_language_layers = True, # False if not finetuning language layers
|
||
finetune_attention_modules = True, # False if not finetuning attention layers
|
||
finetune_mlp_modules = True, # False if not finetuning MLP layers
|
||
|
||
r = 32, # The larger, the higher the accuracy, but might overfit
|
||
lora_alpha = 32, # Recommended alpha == r at least
|
||
lora_dropout = 0,
|
||
bias = "none",
|
||
random_state = 3407,
|
||
use_rslora = False, # We support rank stabilized LoRA
|
||
loftq_config = None, # And LoftQ
|
||
target_modules = "all-linear", # Optional now! Can specify a list if needed
|
||
)
|
||
|
||
|
||
# <a name="Data"></a>
|
||
# ### Data Prep
|
||
# We'll use a sampled dataset of handwritten math formulas. The objective is to convert these images into a computer-readable format—specifically LaTeX—so they can be rendered. This is particularly useful for complex expressions.
|
||
#
|
||
# You can access the dataset [here](https://huggingface.co/datasets/unsloth/LaTeX_OCR). The full dataset is [here](https://huggingface.co/datasets/linxy/LaTeX_OCR).
|
||
|
||
# In[5]:
|
||
|
||
|
||
from datasets import load_dataset
|
||
dataset = load_dataset("unsloth/LaTeX_OCR", split = "train")
|
||
|
||
|
||
# Let's take an overview of the dataset. We'll examine the second image and its corresponding caption.
|
||
|
||
# In[6]:
|
||
|
||
|
||
dataset
|
||
|
||
|
||
# In[7]:
|
||
|
||
|
||
dataset[2]["image"]
|
||
|
||
|
||
# In[8]:
|
||
|
||
|
||
dataset[2]["text"]
|
||
|
||
|
||
# We can also render LaTeX directly in the browser!
|
||
|
||
# In[9]:
|
||
|
||
|
||
from IPython.display import display, Math, Latex
|
||
|
||
latex = dataset[3]["text"]
|
||
display(Math(latex))
|
||
|
||
|
||
# To format the dataset, all vision fine-tuning tasks should follow this format:
|
||
#
|
||
# ```python
|
||
# [
|
||
# {
|
||
# "role": "user",
|
||
# "content": [
|
||
# {"type": "text", "text": instruction},
|
||
# {"type": "image", "image": sample["image"]},
|
||
# ],
|
||
# },
|
||
# {
|
||
# "role": "user",
|
||
# "content": [
|
||
# {"type": "text", "text": instruction},
|
||
# {"type": "image", "image": sample["image"]},
|
||
# ],
|
||
# },
|
||
# ]
|
||
# ```
|
||
|
||
# In[10]:
|
||
|
||
|
||
instruction = "Write the LaTeX representation for this image."
|
||
|
||
def convert_to_conversation(sample):
|
||
conversation = [
|
||
{
|
||
"role": "user",
|
||
"content": [
|
||
{"type": "text", "text": instruction},
|
||
{"type": "image", "image": sample["image"]},
|
||
],
|
||
},
|
||
{"role": "assistant", "content": [{"type": "text", "text": sample["text"]}]},
|
||
]
|
||
return {"messages": conversation}
|
||
pass
|
||
|
||
|
||
# Let's convert the dataset into the "correct" format for finetuning:
|
||
|
||
# In[11]:
|
||
|
||
|
||
converted_dataset = [convert_to_conversation(sample) for sample in dataset]
|
||
|
||
|
||
# The first example is now structured like below:
|
||
|
||
# In[12]:
|
||
|
||
|
||
converted_dataset[0]
|
||
|
||
|
||
# Lets take the Gemma 4 instruction chat template and use it in our base model
|
||
|
||
# In[13]:
|
||
|
||
|
||
from unsloth import get_chat_template
|
||
|
||
processor = get_chat_template(
|
||
processor,
|
||
"gemma-4-thinking"
|
||
)
|
||
|
||
|
||
# Before fine-tuning, let us evaluate the base model's performance. We do not expect strong results, as it has not encountered this chat template before.
|
||
|
||
# In[14]:
|
||
|
||
|
||
image = dataset[2]["image"]
|
||
instruction = "Write the LaTeX representation for this image."
|
||
|
||
messages = [
|
||
{
|
||
"role": "user",
|
||
"content": [{"type": "image"}, {"type": "text", "text": instruction}],
|
||
}
|
||
]
|
||
input_text = processor.apply_chat_template(messages, add_generation_prompt = True)
|
||
inputs = processor(
|
||
image,
|
||
input_text,
|
||
add_special_tokens = False,
|
||
return_tensors = "pt",
|
||
).to("cuda")
|
||
|
||
from transformers import TextStreamer
|
||
|
||
text_streamer = TextStreamer(processor, skip_prompt = True)
|
||
result = model.generate(**inputs, streamer = text_streamer, max_new_tokens = 128,
|
||
use_cache = True, temperature = 1.0, top_p = 0.95, top_k = 64)
|
||
|
||
|
||
# You can see it's absolutely terrible! It doesn't follow instructions at all
|
||
|
||
# <a name="Train"></a>
|
||
# ### Train the model
|
||
# Now let's train our model. We do 60 steps to speed things up, but you can set `num_train_epochs=1` for a full run, and turn off `max_steps=None`. We also support `DPOTrainer` and `GRPOTrainer` for reinforcement learning!
|
||
#
|
||
# We use our new `UnslothVisionDataCollator` which will help in our vision finetuning setup.
|
||
|
||
# In[15]:
|
||
|
||
|
||
from unsloth.trainer import UnslothVisionDataCollator
|
||
from trl import SFTTrainer, SFTConfig
|
||
|
||
trainer = SFTTrainer(
|
||
model = model,
|
||
train_dataset = converted_dataset,
|
||
processing_class = processor.tokenizer,
|
||
data_collator = UnslothVisionDataCollator(model, processor),
|
||
args = SFTConfig(
|
||
per_device_train_batch_size = 1,
|
||
gradient_accumulation_steps = 4,
|
||
max_grad_norm = 0.3,
|
||
warmup_ratio = 0.03,
|
||
max_steps = 60,
|
||
# num_train_epochs = 2, # Set this instead of max_steps for full training runs
|
||
learning_rate = 2e-4,
|
||
logging_steps = 1,
|
||
save_strategy = "steps",
|
||
optim = "adamw_8bit",
|
||
weight_decay = 0.001,
|
||
lr_scheduler_type = "cosine",
|
||
seed = 3407,
|
||
output_dir = "outputs",
|
||
report_to = "none", # For Weights and Biases or others
|
||
|
||
# You MUST put the below items for vision finetuning:
|
||
remove_unused_columns = False,
|
||
dataset_text_field = "",
|
||
dataset_kwargs = {"skip_prepare_dataset": True},
|
||
max_length = 2048,
|
||
)
|
||
)
|
||
|
||
|
||
# In[16]:
|
||
|
||
|
||
# @title Show current memory stats
|
||
gpu_stats = torch.cuda.get_device_properties(0)
|
||
start_gpu_memory = round(torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, 3)
|
||
max_memory = round(gpu_stats.total_memory / 1024 / 1024 / 1024, 3)
|
||
print(f"GPU = {gpu_stats.name}. Max memory = {max_memory} GB.")
|
||
print(f"{start_gpu_memory} GB of memory reserved.")
|
||
|
||
|
||
# In[17]:
|
||
|
||
|
||
trainer_stats = trainer.train()
|
||
|
||
|
||
# In[18]:
|
||
|
||
|
||
# @title Show final memory and time stats
|
||
used_memory = round(torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, 3)
|
||
used_memory_for_lora = round(used_memory - start_gpu_memory, 3)
|
||
used_percentage = round(used_memory / max_memory * 100, 3)
|
||
lora_percentage = round(used_memory_for_lora / max_memory * 100, 3)
|
||
print(f"{trainer_stats.metrics['train_runtime']} seconds used for training.")
|
||
print(
|
||
f"{round(trainer_stats.metrics['train_runtime']/60, 2)} minutes used for training."
|
||
)
|
||
print(f"Peak reserved memory = {used_memory} GB.")
|
||
print(f"Peak reserved memory for training = {used_memory_for_lora} GB.")
|
||
print(f"Peak reserved memory % of max memory = {used_percentage} %.")
|
||
print(f"Peak reserved memory for training % of max memory = {lora_percentage} %.")
|
||
|
||
|
||
# <a name="Inference"></a>
|
||
# ### Inference
|
||
# Let's run the model! You can modify the instruction and input—just leave the output blank.
|
||
#
|
||
# We'll use the best hyperparameters for inference on Gemma: `top_p=0.95`, `top_k=64`, and `temperature=1.0`.
|
||
|
||
# In[19]:
|
||
|
||
|
||
image = dataset[10]["image"]
|
||
instruction = "Write the LaTeX representation for this image."
|
||
|
||
messages = [
|
||
{
|
||
"role": "user",
|
||
"content": [{"type": "image"}, {"type": "text", "text": instruction}],
|
||
}
|
||
]
|
||
|
||
input_text = processor.apply_chat_template(messages, add_generation_prompt = True)
|
||
|
||
inputs = processor(
|
||
image,
|
||
input_text,
|
||
add_special_tokens = False,
|
||
return_tensors = "pt",
|
||
).to("cuda")
|
||
|
||
from transformers import TextStreamer
|
||
|
||
text_streamer = TextStreamer(processor, skip_prompt = True)
|
||
result = model.generate(**inputs, streamer = text_streamer, max_new_tokens = 128,
|
||
use_cache = True, temperature = 1.0, top_p = 0.95, top_k = 64)
|
||
|
||
|
||
# <a name="Save"></a>
|
||
# ### Saving, loading finetuned models
|
||
# To save the final model as LoRA adapters, use Hugging Face’s `push_to_hub` for online saving, or `save_pretrained` for local storage.
|
||
#
|
||
# **[NOTE]** This ONLY saves the LoRA adapters, and not the full model. To save to 16bit or GGUF, scroll down!
|
||
|
||
# In[20]:
|
||
|
||
|
||
model.save_pretrained("gemma_4_lora") # Local saving
|
||
processor.save_pretrained("gemma_4_lora")
|
||
# model.push_to_hub("your_name/gemma_4_lora", token = "YOUR_HF_TOKEN") # Online saving
|
||
# processor.push_to_hub("your_name/gemma_4_lora", token = "YOUR_HF_TOKEN") # Online saving
|
||
|
||
|
||
# Now if you want to load the LoRA adapters we just saved for inference, set `False` to `True`:
|
||
|
||
# In[21]:
|
||
|
||
|
||
if False:
|
||
from unsloth import FastVisionModel
|
||
|
||
model, processor = FastVisionModel.from_pretrained(
|
||
model_name = "gemma_4_lora", # YOUR MODEL YOU USED FOR TRAINING
|
||
load_in_4bit = True, # Set to False for 16bit LoRA
|
||
)
|
||
|
||
sample = dataset[1]
|
||
image = sample["image"].convert("RGB")
|
||
messages = [
|
||
{
|
||
"role": "user",
|
||
"content": [
|
||
{
|
||
"type": "text",
|
||
"text": sample["text"],
|
||
},
|
||
{
|
||
"type": "image",
|
||
},
|
||
],
|
||
},
|
||
]
|
||
input_text = processor.apply_chat_template(messages, add_generation_prompt = True)
|
||
inputs = processor(
|
||
image,
|
||
input_text,
|
||
add_special_tokens = False,
|
||
return_tensors = "pt",
|
||
).to("cuda")
|
||
|
||
from transformers import TextStreamer
|
||
|
||
text_streamer = TextStreamer(processor.tokenizer, skip_prompt = True)
|
||
_ = model.generate(**inputs, streamer = text_streamer, max_new_tokens = 128,
|
||
use_cache = True, temperature = 1.0, top_p = 0.95, top_k = 64)
|
||
|
||
|
||
# ### Saving to float16 for VLLM
|
||
#
|
||
# We also support saving to `float16` directly. Select `merged_16bit` for float16. Use `push_to_hub_merged` to upload to your Hugging Face account! You can go to https://huggingface.co/settings/tokens for your personal tokens. See [our docs](https://unsloth.ai/docs/basics/inference-and-deployment) for more deployment options.
|
||
|
||
# In[22]:
|
||
|
||
|
||
# Select ONLY 1 to save! (Both not needed!)
|
||
|
||
# Save locally to 16bit
|
||
if False: model.save_pretrained_merged("unsloth_finetune", processor,)
|
||
|
||
# To export and save to your Hugging Face account
|
||
if False: model.push_to_hub_merged("YOUR_USERNAME/unsloth_finetune", processor, token = "YOUR_HF_TOKEN")
|
||
|
||
|
||
# And we're done! If you have any questions on Unsloth, we have a [Discord](https://discord.gg/unsloth) channel! If you find any bugs or want to keep updated with the latest LLM stuff, or need help, join projects etc, feel free to join our Discord!
|
||
#
|
||
# Some other resources:
|
||
# 1. Train your own reasoning model - Llama GRPO notebook [Free Colab](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Llama3.1_(8B)-GRPO.ipynb)
|
||
# 2. Saving finetunes to Ollama. [Free notebook](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Llama3_(8B)-Ollama.ipynb)
|
||
# 3. Llama 3.2 Vision finetuning - Radiography use case. [Free Colab](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Llama3.2_(11B)-Vision.ipynb)
|
||
# 4. See notebooks for DPO, ORPO, Continued pretraining, conversational finetuning and more on our [documentation](https://unsloth.ai/docs/get-started/unsloth-notebooks)!
|
||
#
|
||
# <div class="align-center">
|
||
# <a href="https://unsloth.ai"><img src="https://github.com/unslothai/unsloth/raw/main/images/unsloth%20new%20logo.png" width="115"></a>
|
||
# <a href="https://discord.gg/unsloth"><img src="https://github.com/unslothai/unsloth/raw/main/images/Discord.png" width="145"></a>
|
||
# <a href="https://unsloth.ai/docs/"><img src="https://github.com/unslothai/unsloth/blob/main/images/documentation%20green%20button.png?raw=true" width="125"></a>
|
||
#
|
||
# Join Discord if you need help + ⭐️ <i>Star us on <a href="https://github.com/unslothai/unsloth">Github</a> </i> ⭐️
|
||
# </div>
|
||
#
|
||
# This notebook and all Unsloth notebooks are licensed [LGPL-3.0](https://github.com/unslothai/notebooks?tab=LGPL-3.0-1-ov-file#readme).
|