FunctionGemma fine-tunen: een stapsgewijze handleiding
Leer hoe je FunctionGemma in minder dan 10 minuten fine-tunet met de gratis GPU’s van Kaggle, van datasetvoorbereiding en baseline-evaluatie tot training en validatie na het fine-tunen.
In deze tutorial duiken we in FunctionGemma, een lichtgewicht taalmiddel voor function calling van Google DeepMind, en leg ik uit waarom fine-tunen essentieel is om betrouwbare en schema-conforme tooluse te bereiken.
We beginnen met het opzetten van een GPU-omgeving in Kaggle en laden en bereiden vervolgens zowel de dataset als het basis FunctionGemma-model voor.
Daarna voeren we pre-fine-tuning-evaluaties uit om een baseline vast te stellen voor toolselectie en de nauwkeurigheid van function calls. Vervolgens fine-tunen we FunctionGemma met supervised training en evalueren we de prestaties na afloop om te verifiëren dat het fine-tunen correct is toegepast.
FunctionGemma is een gespecialiseerde versie van Google’s Gemma 3 270M open model, specifiek ontworpen voor function calling en tooluse in plaats van algemene conversatie.
Het gebruikt dezelfde architectuur als Gemma 3, maar heeft een speciaal formaat en trainingsfocus waarmee het gestructureerde outputs kan genereren die function calls representeren.
FunctionGemma wordt uitgebracht als een basismodel dat ontwikkelaars kunnen fine-tunen voor specifieke use-cases. Door de grootte en het ontwerp is het lichtgewicht, efficiënt en inzetbaar op apparaten met beperkte middelen, zoals laptops en edge-hardware.
Waarom FunctionGemma fine-tunen?
Hoewel FunctionGemma is getraind voor function calling, presteren modellen van deze omvang het best wanneer ze worden gespecialiseerd via fine-tuning op taak-specifieke data.
Fine-tunen helpt het model stabiele patronen te leren voor het kiezen van de juiste functie uit een set tools en het correct formatteren van de bijbehorende argumenten voor realistische use-cases.
Dit leidt tot meer consistente en voorspelbare gestructureerde outputs, wat op zijn beurt de betrouwbaarheid verbetert in praktische workflows.
Laten we de stappen doorlopen die nodig zijn om FunctionGemma te fine-tunen.
1. Een Kaggle-omgeving opzetten
Begin op Kaggle en maak een nieuw notebook aan. Zodra het notebook geopend is, zoek je in het rechterpaneel naar Session options en stel je de Accelerator in op GPU (T4 ×2).
Dit schakelt GPU-versnelling in voor de sessie en stelt je in staat het model te fine-tunen met de gratis rekencapaciteit van Kaggle.
Nadat je de GPU hebt ingeschakeld, maak je een nieuwe codecel aan en voer je het volgende commando uit om alle vereiste Python-dependencies te installeren. Het kan even duren voordat de kernel start; daarna worden de pakketten automatisch geïnstalleerd.
%pip -qinstall-U datasets accelerate trl kagglehub sentencepiece huggingface_hub tqdm evaluate jiwerMogelijk gemaakt door
Voeg vervolgens je Hugging Face-toegangstoken op een veilige manier toe.
Open in het bovenste menu Add-ons → Secrets en klik vervolgens op Add Secret. Stel de naam van de secret in op HUGGINGFACE_TOKEN en plak je Hugging Face API-sleutel als waarde.
Kaggle Secrets gebruiken is veiliger dan omgevingsvariabelen of tokens rechtstreeks in het notebook hardcoden.
Zodra de secret is opgeslagen, geeft Kaggle een snippet om deze programmatisch op te halen.
Gebruik de volgende code om je aan te melden bij de Hugging Face Hub:
from kaggle_secrets import UserSecretsClient
from huggingface_hub import login
hf_token = UserSecretsClient().get_secret("HUGGINGFACE_TOKEN")ifnot hf_token:raise ValueError("HUGGINGFACE_TOKEN not found in Kaggle Secrets.")
login(token=hf_token)Mogelijk gemaakt door
Na een geslaagde authenticatie kun je toegang krijgen tot afgeschermde modellen en datasets, en je gefinetunede FunctionGemma-model uploaden naar de Hugging Face Hub om te delen en te hergebruiken.
2. De Hermes Reasoning Tool-Use-dataset laden
De Hermes Reasoning Tool-Use-dataset is een open Engelstalige dataset in een tooluse-reasoningformaat met gestructureerde voorbeelden, ontworpen voor het trainen en evalueren van modellen op toolselectie- en JSON-achtige function-calling-taken.
De dataset bevat tienduizenden tooluse-reasoningvoorbeelden met natuurlijke taalprompts en toolschemas in een formaat dat geschikt is voor supervised fine-tuning.
In deze tutorial gebruiken we een subset van de dataset voor snellere experimenten.
Definieer eerst een willekeurige seed en het totale aantal voorbeelden dat je wilt gebruiken. Splits de data daarna in trainings- en evaluatiesets:
from datasets import load_dataset
SEED =40
N_TOTAL =3000
N_EVAL =300
N_TRAIN = N_TOTAL - N_EVALMogelijk gemaakt door
Laad vervolgens de dataset, shuffle deze en maak de train- en eval-subsets:
raw = load_dataset("interstellarninja/hermes_reasoning_tool_use", split="train")
raw = raw.shuffle(seed=SEED).select(range(N_TOTAL))
train_ds = raw.select(range(N_TRAIN))
eval_ds = raw.select(range(N_TRAIN, N_TOTAL))print("train:",len(train_ds),"eval:",len(eval_ds))Mogelijk gemaakt door
Dit levert 2.700 trainingsvoorbeelden en 300 evaluatievoorbeelden op, voldoende om fine-tuning te demonstreren terwijl de rekenvereisten beheersbaar blijven.
In deze tutorial gebruiken we KaggleHub om het FunctionGemma-model rechtstreeks in het Kaggle-notebook te laden.
KaggleHub bepaalt automatisch de modellocatie en maakt het model beschikbaar in de notebookomgeving, zodat je het niet handmatig van Hugging Face hoeft te downloaden.
import kagglehub
from transformers import AutoProcessor, AutoModelForCausalLM
model_path = kagglehub.model_download("google/functiongemma/transformers/functiongemma-270m-it")Mogelijk gemaakt door
Na het uitvoeren van de cel hierboven verschijnen de modelbestanden in de sectie Input van het Kaggle-notebook. Dat bevestigt dat het model succesvol is geladen en lokaal beschikbaar is.
Zodra het model beschikbaar is, laden we zowel de processor als het model in het GPU-geheugen.
De processor behandelt chattemplates en toolschemaformattering, terwijl het model verantwoordelijk is voor het genereren van gestructureerde function calls.
Met device_map="auto" plaats je het model op de beschikbare GPU, en dtype="auto" kiest een efficiënte precisie die door de hardware wordt ondersteund.
processor = AutoProcessor.from_pretrained(model_path, device_map="auto")
model = AutoModelForCausalLM.from_pretrained(model_path, dtype="auto", device_map="auto")
tokenizer = processor.tokenizer ifhasattr(processor,"tokenizer")else processor
print("dtype:", model.dtype,"| device:", model.device)Mogelijk gemaakt door
Dit bevestigt dat FunctionGemma correct is geladen, op de GPU staat en klaar is voor evaluatie en fine-tunen.
4. Tooldefinities normaliseren en gold function calls extraheren
Voordat we FunctionGemma fine-tunen, moeten we standaardiseren hoe tools worden weergegeven en de juiste (gold) function calls betrouwbaar uit de dataset halen.
De Hermes Reasoning Tool-Use-dataset kan tooldefinities in meerdere formaten opslaan, dus deze stap zet alles om naar een consistente structuur die we kunnen gebruiken voor supervised fine-tuning.
Tools-veld normaliseren
We beginnen met het normaliseren van het veld tools. In de dataset kan tools voorkomen als een Python-lijst, een JSON-string of volledig ontbreken.
De hulpfunctie hieronder zet alle geldige representaties om in een nette Python-lijst en negeert veilig misvormde of lege items.
import re, json
defnormalize_tools_field(tools):if tools isNone:return[]ifisinstance(tools,list):return tools
ifisinstance(tools,str):
s = tools.strip()ifnot s:return[]try:
parsed = json.loads(s)return parsed ifisinstance(parsed,list)else[]except Exception:return[]return[]Mogelijk gemaakt door
Parametertypes normaliseren
Vervolgens normaliseren we parametertypes. Hermes-tooldefinities gebruiken vaak informele typeannotaties zoals str,int of containertypes zoals List[str]. De onderstaande functie zet deze om naar geldige JSON Schema-typen die compatibel zijn met Hugging Face function calling.
def_parse_hermes_type(t)->dict:if t isNone:return{"type":"string"}ifisinstance(t,dict):return t if"type"in t else{"type":"object"}ifisinstance(t,list):return{"type":"array"}ifnotisinstance(t,str):return{"type":"string"}
t = t.strip()
prim ={"str":"string","string":"string","int":"integer","integer":"integer","float":"number","number":"number","bool":"boolean","boolean":"boolean","dict":"object","object":"object","list":"array","array":"array",}if t.lower()in prim:return{"type": prim[t.lower()]}
m = re.match(r"List\[(.+)\]$", t)if m:return{"type":"array","items": _parse_hermes_type(m.group(1).strip())}
m = re.match(r"Dict\[(.+),\s*(.+)\]$", t)if m:return{"type":"object","additionalProperties": _parse_hermes_type(m.group(2).strip())}return{"type":"string"}Mogelijk gemaakt door
Hermes-stijl tool omzetten naar Hugging Face-functionschemas
Met deze utilities zetten we Hermes-achtige tooldefinities om naar Hugging Face-{"type": "function", "function": {...}}-schemas. Deze functie ondersteunt twee formaten:
Hermes per-argument-stijl (waarbij elke parameter een eigen kleine specificatie heeft)
Tools die al op JSON Schema lijken
Voor het per-argument-formaat behandelt deze implementatie de opgesomde parameters als verplicht, tenzij er expliciet een required-lijst is opgegeven.
We definiëren een kleine helper om de geconverteerde toolschemas voor elk datasetvoorbeeld op te halen:
defget_tools_hf(ex):return hermes_tools_to_hf_schema(ex.get("tools"))Mogelijk gemaakt door
De gold function call extraheren
Daarna halen we de gold-toolcall uit de conversatie. Hermes-conversaties kunnen meerdere beurten bevatten, dus we parsen <tool_call>{...}</tool_call>-blokken en extraheren het eerste geldige toolcall-object (naam + argumenten). Zo blijft de supervisie eenvoudig en consistent.
TOOL_CALL_RE = re.compile(r"<tool_call>\s*(\{.*?\})\s*</tool_call>", re.DOTALL)defextract_first_tool_call_obj(text:str):ifnot text:returnNone
m = TOOL_CALL_RE.search(text)ifnot m:returnNonetry:
obj = json.loads(m.group(1))ifisinstance(obj,dict)and"name"in obj and"arguments"in obj:return obj
except Exception:returnNonereturnNoneMogelijk gemaakt door
De toolcall afstemmen op de gebruikersopdracht
Om de toolcall af te stemmen op de juiste gebruikersopdracht scannen we de conversatiegeschiedenis, zoeken we het gebruikersbericht dat overeenkomt met de dataset-task en nemen we vervolgens het assistentantwoord er direct na. Als dat antwoord een toolcall bevat, geven we die terug als gold-label.
def_role(turn):return(turn.get("from")or"").lower().strip()defget_gold_tool_call_task_aligned(ex):
task =(ex.get("task")or"").strip()
conv = ex.get("conversations")or[]ifnot conv:returnNone
idx =Noneif task:for i, t inenumerate(conv):if _role(t)in["human","user"]:
val =(t.get("value")or"").strip()if val == task or task in val or val in task:
idx = i
breakif idx isNone:for i inrange(len(conv)-1,-1,-1):if _role(conv[i])in["human","user"]:
idx = i
breakif idx isNone:returnNonefor j inrange(idx+1,len(conv)):if _role(conv[j])in["gpt","assistant","model"]:
gold = extract_first_tool_call_obj(conv[j].get("value",""))if gold:return gold
if _role(conv[j])in["human","user"]:breakreturnNoneMogelijk gemaakt door
Aan het einde van deze stap heeft elk bruikbaar datasetvoorbeeld:
Een genormaliseerde set toolschemas (Hugging Face-formaat)
Een schone, taak-uitgelijnde gold function call
Een consistente structuur die klaar is om supervised fine-tuning-samples van te maken.
6. Supervised fine-tuning-samples bouwen voor function calling
Nu moeten we die omzetten naar Supervised Fine-Tuning (SFT)-trainingssamples in precies het formaat dat FunctionGemma verwacht, met gebruik van de bovenstaande hulpfuncties.
Het doel is om voorbeelden te maken waarbij de input bevat:
Een developer-bericht dat function calling activeert
De gebruikersopdracht
De tooldeclaraties (schemas)
En de target is één enkele, gestructureerde FunctionGemma-call in dit formaat:
<start_function_call>call:TOOL_NAME{args:<escape>{...}<escape>}<end_function_call>Mogelijk gemaakt door
Stap 1: Schone, bruikbare rijen bouwen
We itereren eerst door de dataset en filteren voorbeelden weg die we niet kunnen gebruiken voor training.
Deze functie behoudt alleen voorbeelden waarbij:
Er een gold-toolcall bestaat
Er een geldige tools-lijst is
De gold-toolnaam in de toollijst voorkomt
De argumenten een geldige dictionary zijn
Als de tool geen vereiste velden heeft, worden de argumenten geforceerd naar {} om ruis of inconsistente targets te voorkomen
from datasets import Dataset
defbuild_simple_rows(ds, max_rows=None):
rows =[]for ex in ds:# 1) task-aligned gold tool call
gold = get_gold_tool_call_task_aligned(ex)ifnot gold:continue# 2) tools -> HF schema
hf_tools = get_tools_hf(ex)ifnot hf_tools:continue# 3) build required_map: tool_name -> required fields
required_map ={}for t in hf_tools:if t.get("type")=="function":
fn = t.get("function",{})
name = fn.get("name")
req =(fn.get("parameters",{})or{}).get("required",[])or[]if name:
required_map[name]= req
# 4) guard: gold tool must be in tool list
tool_names =set(required_map.keys())if gold["name"]notin tool_names:continue# 5) force {} when no required params
gold_args = gold.get("arguments",{})ifnotisinstance(gold_args,dict):
gold_args ={}
req = required_map.get(gold["name"],[])iflen(req)==0:
gold_args ={}# key fix
rows.append({"user_content": ex.get("task",""),"tool_name": gold["name"],"tool_arguments": json.dumps(gold_args, ensure_ascii=False),"hf_tools": hf_tools,})if max_rows andlen(rows)>= max_rows:breakreturn rowsMogelijk gemaakt door
Nu genereren we trainings- en evaluatierijen:
simple_train = build_simple_rows(train_ds, max_rows=N_TRAIN)
simple_eval = build_simple_rows(eval_ds, max_rows=N_EVAL)print("usable train:",len(simple_train),"usable eval:",len(simple_eval))Mogelijk gemaakt door
In ons geval houden we 961 trainingsvoorbeelden en 109 evaluatievoorbeelden over van de oorspronkelijke 3.000. Deze daling is te verwachten omdat de filtering streng is. Voorbeelden met ontbrekende toolcalls, ongeldige tooldefinities, niet-overeenkomende toolnamen of misvormde argumenten worden verwijderd.
Deze opschoningsstap is heel belangrijk. Vooraf bevatte de dataset veel ruis en misuitgelijnde voorbeelden, wat leidde tot instabiel function-callinggedrag en matige resultaten, zelfs na fine-tunen. Na het terugbrengen tot alleen hoogwaardige, taak-uitgelijnde voorbeelden wordt FunctionGemma veel consistenter en verbeteren de fine-tuningresultaten aanzienlijk.
Stap 2: Elke rij omzetten in één trainingssample met tekst
Vervolgens formatteren we elke rij in de exacte prompt-plus-target-structuur die FunctionGemma nodig heeft. We gebruiken apply_chat_template van de processor om tooldeclaraties correct in te voegen en plakken daarna de gold function call als target eraan vast.
defformat_row_as_text(row):
messages =[{"role":"developer","content":"You are a model that can do function calling with the following functions"},{"role":"user","content": row["user_content"]},]
prompt = processor.apply_chat_template(
messages,
tools=row["hf_tools"],
add_generation_prompt=True,
tokenize=False,)
target =(f"<start_function_call>call:{row['tool_name']}"f"{{args:<escape>{row['tool_arguments']}<escape>}}"f"<end_function_call>")return prompt + targetMogelijk gemaakt door
Nu zetten we de rijen om naar Hugging Face Dataset-objecten:
train_text_ds = Dataset.from_list([{"text": format_row_as_text(r)}for r in simple_train])
eval_text_ds = Dataset.from_list([{"text": format_row_as_text(r)}for r in simple_eval])Mogelijk gemaakt door
Stap 3: Zeker stellen dat elke sample een geldige string is
Sommige TRL-versies vereisen dat formatting_func een string teruggeeft, en training kan stuklopen als een sample een lijst of niet-stringwaarde wordt. Deze helper forceert text altijd naar een schone string.
# ensure text is always a stringdefforce_text_string(ds):deffix(ex):
t = ex.get("text","")ifisinstance(t,list):
t ="\n".join(map(str, t))return{"text":str(t)}return ds.map(fix)
train_text_ds = force_text_string(train_text_ds)
eval_text_ds = force_text_string(eval_text_ds)Mogelijk gemaakt door
Print tot slot één sample om de formattering te bevestigen:
Je zou een volledig gerenderde prompt moeten zien met tooldeclaraties, gevolgd door een gold function call vergelijkbaar met:
<bos><start_of_turn>developer
You are a model that can do function calling with the following functions<start_function_declaration>declaration:get_pollution_levels{description:<escape>Retrieve pollution levels information<escape>,parameters:{properties:{location:{description:<escape>The location for which you want to get the pollution levels (e.g., Beijing, London, New York)<escape>,type:<escape>STRING<escape>},pollutant:{description:<escape>Specify a pollutant for pollution levels (e.g., PM2.5, PM10, ozone)<escape>,type:<escape>STRING<escape>}},required:[<escape>location<escape>],type:<escape>DICT<escape>}}<end_function_declaration><start_function_declaration>declaration:get_water_quality{description:<escape>Retrieve water quality information<escape>,parameters:{properties:{location:{description:<escape>The location for which you want to get the water quality (e.g., river, lake, beach)<escape>,type:<escape>STRING<escape>}},required:[<escape>location<escape>],type:<escape>DICT<escape>}}<end_function_declaration><end_of_turn><start_of_turn>user
I'm planning a beach cleanup at Zuma Beach this weekend and need to ensure safety. Can you provide the current water quality and if it's poor, check the pollution level of PM2.5 there?<end_of_turn><start_of_turn>model
<start_function_call>call:get_water_quality{args:<escape>{"location":"Zuma Beach"}<escape>}<end_function_call>Mogelijk gemaakt door
7. FunctionGemma evalueren vóór fine-tunen
Voor de training moet je meten hoe goed het basis FunctionGemma-model presteert op function calling. Deze baseline helpt te bevestigen dat fine-tunen de toolselectie en function-call-formattering echt verbetert.
In deze sectie evalueren we twee zaken:
Toolnaam-nauwkeurigheid: of het model de juiste functienaam kiest
TC-CER (Tool-Call Character Error Rate): hoe dicht het gegenereerde function-call-blok bij het gold-call-blok ligt; lager is beter
We gebruiken twee reguliere expressies om de voorspelde toolnaam en het volledige function-call-blok uit de modeloutput te extraheren en vergelijken die met de gold-labels.
import re
import evaluate
import torch
from tqdm.auto import tqdm
cer_metric = evaluate.load("cer")# Gemma / FunctionGemma-style only
FG_BLOCK_RE = re.compile(r"<start_function_call>.*?<end_function_call>", re.DOTALL)
FG_NAME_RE = re.compile(r"call:([a-zA-Z0-9_]+)\{", re.DOTALL)defextract_tool_name(gen:str):
gen = gen or""
m = FG_NAME_RE.search(gen)return m.group(1)if m elseNonedefextract_call_block(gen:str):
gen = gen or""
m = FG_BLOCK_RE.search(gen)return m.group(0)if m else""defgold_call_block(r):return(f"<start_function_call>call:{r['tool_name']}"f"{{args:<escape>{r['tool_arguments']}<escape>}}"f"<end_function_call>")Mogelijk gemaakt door
Baseline-evaluatielus
De onderstaande functie voert inferentie uit op een subset van de evaluatievoorbeelden en berekent beide metrics. We houden sampling uitgeschakeld (do_sample=False) zodat de resultaten deterministisch zijn en makkelijker te vergelijken voor en na het fine-tunen.
@torch.inference_mode()defeval_tool_and_cer(proc, mdl, rows, n=50, max_new_tokens=128):
mdl.eval()
n =min(n,len(rows))
tool_ok =0
preds, refs =[],[]for i in tqdm(range(n)):
r = rows[i]
messages =[{"role":"developer","content":"You are a model that can do function calling with the following functions"},{"role":"user","content": r["user_content"]},]
inputs = proc.apply_chat_template(
messages,
tools=r["hf_tools"],
add_generation_prompt=True,
return_dict=True,
return_tensors="pt",)
inputs ={k: v.to(mdl.device)for k, v in inputs.items()}
out = mdl.generate(**inputs,
do_sample=False,
max_new_tokens=max_new_tokens,
pad_token_id=proc.eos_token_id,)
gen = proc.decode(out[0][inputs["input_ids"].shape[-1]:], skip_special_tokens=True).strip()if extract_tool_name(gen)== r["tool_name"]:
tool_ok +=1
preds.append(extract_call_block(gen))
refs.append(gold_call_block(r))return{"n_eval": n,"tool_accuracy": tool_ok / n,"TC-CER (lower is better)": cer_metric.compute(predictions=preds, references=refs),}Mogelijk gemaakt door
Voer de baseline-evaluatie uit:
pre_metrics = eval_tool_and_cer(processor, model, simple_eval, n=50, max_new_tokens=128)print("PRE metrics:", pre_metrics)Mogelijk gemaakt door
Zelfs vóór fine-tunen laat FunctionGemma sterke baselineprestaties zien op deze taak.
Op een subset van 50 evaluatievoorbeelden behaalt het model 88% toolnaam-nauwkeurigheid, wat betekent dat het in de meeste gevallen de juiste functie kiest.
Daarnaast is de Tool-Call Character Error Rate (TC-CER) ongeveer 33% voor het volledige function-call-blok. Dat geeft aan dat, hoewel vaak de juiste tool wordt gekozen, de gegenereerde argumenten en de formattering nog afwijken van de gold-target.
PRE metrics:{'n_eval':50,'tool_accuracy':0.88,'TC-CER (lower is better)':0.33399307273626916}Mogelijk gemaakt door
Deze resultaten bevestigen dat het basis FunctionGemma-model de mechaniek van function calling al begrijpt.
De relatief hoge character error rate onderstreept echter de noodzaak van fine-tunen om de volledigheid van argumenten, de consistentie van de formattering en de algehele structurele correctheid van de gegenereerde function calls te verbeteren.
Eén voorspelling inspecteren
Metrics zijn nuttig, maar het is ook belangrijk om naar kwalitatieve outputs te kijken. De helper hieronder voert inferentie uit voor één voorbeeld en print de voorspelde function call naast de gold-referentie.
import torch
@torch.inference_mode()definfer_one(proc, mdl, rows, idx=0, max_new_tokens=128):
r = rows[idx]
messages =[{"role":"developer","content":"You are a model that can do function calling with the following functions"},{"role":"user","content": r["user_content"]},]
inputs = proc.apply_chat_template(
messages,
tools=r["hf_tools"],
add_generation_prompt=True,
return_dict=True,
return_tensors="pt",)
inputs ={k: v.to(mdl.device)for k, v in inputs.items()}
out = mdl.generate(**inputs,
do_sample=False,
max_new_tokens=max_new_tokens,
pad_token_id=proc.eos_token_id,)
gen = proc.decode(
out[0][inputs["input_ids"].shape[-1]:],
skip_special_tokens=True).strip()
pred_tool = extract_tool_name(gen)return{"task": r["user_content"],"tool_match":(pred_tool == r["tool_name"]),"predicted": extract_call_block(gen),"gold": gold_call_block(r),}Mogelijk gemaakt door
Voer het uit op één voorbeeld:
pre = infer_one(processor, model, simple_eval, idx=15)print(f"""
TASK:
{pre['task']}
TOOL MATCH: {pre['tool_match']}
--- PREDICTED ---
{pre['predicted']}
--- GOLD ---
{pre['gold']}
""")Mogelijk gemaakt door
Output:
TASK:
I'm reviewing the schedule in the surgical unit. Can you fetch the surgical nursing details for patient ID 12345 undergoing a 'Cardiac Bypass' today? If the procedure is handled by Nurse Ratched, let's record a post-operative care task for this evening.
TOOL MATCH: True
--- PREDICTED ---
<start_function_call>call:get_surgical_nursing_information{nurse_id:<escape>Ratched<escape>,patient_id:<escape>12345<escape>,procedure_type:<escape>Cardiac Bypass<escape>}<end_function_call>
--- GOLD ---
<start_function_call>call:get_surgical_nursing_information{args:<escape>{"patient_id":"12345", "procedure_type":"Cardiac Bypass"}<escape>}<end_function_call>Mogelijk gemaakt door
In dit voorbeeld kiest het model correct de juiste functie, daarom is de tool match True.
De gegenereerde call bevat echter extra argumenten en volgt niet exact de targetstructuur die in de training is gebruikt.
Hoewel deze argumenten semantisch logisch zijn, komen ze niet overeen met het gold-formaat, wat bijdraagt aan een hogere character error rate. Dit illustreert waarom fine-tunen nodig is om de structurele consistentie en schema-compliance te verbeteren, niet alleen de toolselectie.
8. De modeltrainer instellen voor fine-tunen
Nu we schone SFT-datasets hebben, is de volgende stap het configureren van de trainer die FunctionGemma gaat fine-tunen. We gebruiken TRL’s SFTTrainer, een lichtgewicht en betrouwbare manier om chatstijlsmodellen te fine-tunen op tekstvoorbeelden.
We stellen ook een outputmap in zodat Kaggle het gefinetunede checkpoint opslaat op een persistente locatie.
from trl import SFTConfig, SFTTrainer
OUT_DIR ="/kaggle/working/functiongemma-hermes-ft"Mogelijk gemaakt door
Om VRAM-gebruik tijdens training te verminderen, schakelen we gradient checkpointing in en zetten we de KV-cache uit.
# VRAM savings
model.gradient_checkpointing_enable()
model.config.use_cache =FalseMogelijk gemaakt door
Trainerconfiguratie
We definiëren de trainingsconfiguratie met SFTConfig. Deze instellingen balanceren stabiliteit en efficiëntie op Kaggle-GPU’s en houden de trainingstijd kort.
De formatting-functie zorgt ervoor dat elk trainingsvoorbeeld als één string wordt teruggegeven, wat vereist is door de huidige TRL-versie.
defformatting_func(example):# MUST return a STRING (not list) for your TRL version
t = example.get("text","")ifisinstance(t,list):
t ="\n".join(map(str, t))returnstr(t)Mogelijk gemaakt door
De trainer initialiseren
Tot slot initialiseren we de SFTTrainer met het model, de configuratie, de datasets en de tokenizer.
trainer = SFTTrainer(
model=model,
args=cfg,
train_dataset=train_text_ds,
eval_dataset=eval_text_ds,
processing_class=tokenizer,
formatting_func=formatting_func,)Mogelijk gemaakt door
9. FunctionGemma fine-tunen
Met de geconfigureerde trainer kunnen we het model nu fine-tunen. Deze stap voert supervised training uit op de voorbereide dataset en evalueert het model periodiek tijdens de training.
trainer.train()
trainer.save_model(OUT_DIR)
processor.save_pretrained(OUT_DIR)print("Saved to:", OUT_DIR)Mogelijk gemaakt door
Na afloop slaan we zowel het gefinetunede model als de processor op in de outputmap, zodat ze herbruikbaar zijn voor inferentie of upload naar de Hugging Face Hub.
Tijdens de training dalen zowel de training- als validatie-loss gestaag. De gemiddelde token-accuratesse verbetert ook in de tijd, wat aangeeft dat het model beter en consistenter gestructureerde function-call-outputs leert produceren.
Het gefinetunede FunctionGemma-model publiceren op Hugging Face
Zodra het fine-tunen klaar is, kunnen we het model publiceren zodat het eenvoudig kan worden hergebruikt, gedeeld of ingezet. Door het naar de Hugging Face Hub te pushen, kunnen anderen het direct laden via standaard Transformers-API’s.
HF_REPO_ID ="kingabzpro/functiongemma-hermes-3k-ft"
model.push_to_hub(HF_REPO_ID)
processor.push_to_hub(HF_REPO_ID)print("Pushed to:", HF_REPO_ID)Mogelijk gemaakt door
Na het uploaden is het gefinetunede model publiek beschikbaar op Hugging Face:
Na het fine-tunen laden we het opgeslagen model en de processor opnieuw vanaf schijf en draaien we dezelfde evaluatiepipeline als vóór de training. Zo is de vergelijking tussen pre- en post-fine-tuning eerlijk en consistent.
from transformers import AutoProcessor, AutoModelForCausalLM
ft_processor = AutoProcessor.from_pretrained(OUT_DIR, device_map="auto")
ft_model = AutoModelForCausalLM.from_pretrained(OUT_DIR, dtype="auto", device_map="auto")Mogelijk gemaakt door
Daarna evalueren we het gefinetunede model op de evaluatieset met toolnaam-nauwkeurigheid en TC-CER.
post_metrics = eval_tool_and_cer(ft_processor, ft_model, simple_eval, n=50, max_new_tokens=64)print("POST metrics:", post_metrics)Mogelijk gemaakt door
De resultaten tonen een duidelijke verbetering ten opzichte van de baseline:
POST metrics:{'n_eval':50,'tool_accuracy':0.98,'TC-CER (lower is better)':0.1454725383473528}Mogelijk gemaakt door
De toolnaam-nauwkeurigheid stijgt van 88 procent naar 98 procent, en de character error rate voor het volledige function-call-blok halveert ruim. Dit geeft aan dat het model niet alleen betrouwbaarder de juiste tool kiest, maar ook outputs produceert die nauwer aansluiten op het doelschema.
Om de verbeteringen beter te begrijpen, inspecteren we individuele voorspellingen. In het onderstaande voorbeeld kiest het model de juiste functie en produceert het een goed gestructureerde call met vollediger argumenten.
post = infer_one(ft_processor, ft_model, simple_eval, idx=15)print(f"""
TASK:
{post['task']}
TOOL MATCH: {pre['tool_match']}
--- PREDICTED ---
{post['predicted']}
--- GOLD ---
{post['gold']}
""")Mogelijk gemaakt door
Hoewel de voorspelde call extra argumenten kan bevatten die verder gaan dan de gold-target, zijn de algehele structuur en argumentformattering aanzienlijk consistenter dan vóór het fine-tunen. Dat weerspiegelt een beter schema-bewustzijn en sterkere afstemming tussen gebruikersintentie en gegenereerde function calls.
TASK:
I'm reviewing the schedule in the surgical unit. Can you fetch the surgical nursing details for patient ID 12345 undergoing a 'Cardiac Bypass' today? If the procedure is handled by Nurse Ratched, let's record a post-operative care task for this evening.
TOOL MATCH: True
--- PREDICTED ---
<start_function_call>call:get_surgical_nursing_information{args:<escape>{"patient_id":"12345", "procedure_type":"Cardiac Bypass", "nurse_id":"Ratched", "task":"Post-operative care"}<escape>}<end_function_call>
--- GOLD ---
<start_function_call>call:get_surgical_nursing_information{args:<escape>{"patient_id":"12345", "procedure_type":"Cardiac Bypass"}<escape>}<end_function_call>Mogelijk gemaakt door
Laten we nog een voorbeeld bekijken.
post = infer_one(ft_processor, ft_model, simple_eval, idx=25)print(f"""
TASK:
{post['task']}
TOOL MATCH: {pre['tool_match']}
--- PREDICTED ---
{post['predicted']}
--- GOLD ---
{post['gold']}
""")Mogelijk gemaakt door
Een tweede voorbeeld toont een schone en correcte function call voor een URL-extractietaak, wat laat zien dat het gefinetunede model goed generaliseert over verschillende tools.
TASK:
I would like to extract details from a LinkedIn company page. Could you assist me in fetching the information from this URL: https://www.linkedin.com/company/abc-corporation?
TOOL MATCH: True
--- PREDICTED ---
<start_function_call>call:extract{args:<escape>{"url":"https://www.linkedin.com/company/abc-corporation"}<escape>}<end_function_call>
--- GOLD ---
<start_function_call>call:extract{args:<escape>{"url":"https://www.linkedin.com/company/abc-corporation", "html": true}<escape>}<end_function_call>Mogelijk gemaakt door
Al met al bevestigen deze resultaten dat fine-tunen zowel de nauwkeurigheid als de structurele correctheid voor function-calling-taken verbetert.
Loop je ergens tegenaan? Clone dan het notebook, voeg je Hugging Face-secret toe en draai het end-to-end.
Tot slot
Als je probeert FunctionGemma te trainen op generieke tekstgeneratiedatasets, kun je daar beter vroegtijdig mee stoppen. FunctionGemma is niet ontworpen om zich te gedragen als een algemeen doel-LLM.
Voor open-ended tekstgeneratie is de Gemma 3-modelfamilie een betere keuze.
FunctionGemma is purpose-built voor function calling, waar het doel is om de juiste tool te selecteren, schema-conforme argumenten te produceren en betrouwbaar te interageren met externe systemen zoals API’s, databases en services.
De kleine omvang van FunctionGemma is een bewuste ontwerpkeuze. Met 270 miljoen parameters is het geoptimaliseerd voor low-latency, resource-efficiënte deployments, waaronder lokale machines, edge-devices en private infrastructuur. Daardoor is het zeer geschikt voor realtime function calling en agentische workflows, waar correctheid en structuur zwaarder wegen dan vloeiende tekst.
In deze tutorial hebben we geleerd hoe je FunctionGemma fine-tunet op de Hermes Reasoning Tool-Use-dataset. Een belangrijke les is dat datavoorbereiding en evaluatie zwaarder wegen dan pure trainingstijd.
Door de dataset zorgvuldig op te schonen, taken uit te lijnen met gold-toolcalls en strikte schemaconsistentie af te dwingen, konden we het modelgedrag drastisch verbeteren met een relatief klein aantal hoogwaardige samples.
De resultaten laten duidelijk de impact van fine-tunen zien. De toolnaam-nauwkeurigheid steeg van 88 procent naar 98 procent en de character error rate voor volledige function-call-blokken werd meer dan gehalveerd. Belangrijker nog, het model werd veel consistenter in het produceren van goed gestructureerde, voorspelbare function calls die aansluiten bij gebruik in de praktijk.
FunctionGemma FAQ's
Wat is FunctionGemma en waarin verschilt het van Gemma 3?⌄
FunctionGemma is een gespecialiseerde versie van het open model Gemma 3 270M. Waar standaard Gemma 3 is ontworpen voor tekstgeneratie, is FunctionGemma expliciet getraind om natuurlijke taal te vertalen naar gestructureerde function calls (API-verzoeken). Het is daarmee een dedicated "router" voor agentische workflows in plaats van een conversatie-chatbot.
hat hardware do I need to run FunctionGemma?⌄
Omdat het een model met 270M parameters is, is FunctionGemma bijzonder licht (~300MB gequantiseerd). Het kan efficiënt draaien op edge-apparaten zoals laptops, mobiele telefoons en embedded hardware (bijv. NVIDIA Jetson Nano) zonder een dedicated cloud-GPU nodig te hebben.
Waarom moet ik FunctionGemma fine-tunen als het al gespecialiseerd is?⌄
Hoewel het basismodel het concept van tooluse begrijpt, is fine-tunen nodig om jouw specifieke API-schemas en bedrijfslogica aan te leren. Volgens Google’s benchmarks kan fine-tunen de nauwkeurigheid van function calling verhogen van ~58% (basis) naar meer dan 85% op domeinspecifieke taken.
Kan FunctionGemma multi-turn conversaties aan?⌄
FunctionGemma is primair geoptimaliseerd voor single-turn commando-uitvoering (User Instruction → Tool Call). Voor complexe, multi-turn redenering of het bewaren van lange gespreksgeschiedenis gebruik je het model het best als een "verkeersregelaar" die moeilijke vragen delegeert aan een groter model (zoals Gemma 3 27B), terwijl het eenvoudige acties lokaal afhandelt.
Als gecertificeerd data scientist haal ik met passie het maximale uit de nieuwste technologie om innovatieve machinelearning-toepassingen te bouwen. Met een sterke achtergrond in spraakherkenning, data-analyse en -rapportage, MLOps, conversationele AI en NLP heb ik mijn vaardigheden aangescherpt in het ontwikkelen van intelligente systemen die echt impact maken. Naast mijn technische expertise ben ik ook een sterke communicator met een talent om complexe concepten terug te brengen tot heldere, beknopte taal. Daardoor ben ik uitgegroeid tot een veelgelezen blogger over data science, waar ik mijn inzichten en ervaringen deel met een groeiende community van data-professionals. Op dit moment richt ik me op contentcreatie en redactie, waarbij ik met large language models werk aan krachtige en aansprekende content die zowel bedrijven als individuen helpt het beste uit hun data te halen.
In deze tutorial duiken we in FunctionGemma, een lichtgewicht taalmiddel voor function calling van Google DeepMind, en leg ik uit waarom fine-tunen essentieel is om betrouwbare en schema-conforme tooluse te bereiken.
We beginnen met het opzetten van een GPU-omgeving in Kaggle en laden en bereiden vervolgens zowel de dataset als het basis FunctionGemma-model voor.
Daarna voeren we pre-fine-tuning-evaluaties uit om een baseline vast te stellen voor toolselectie en de nauwkeurigheid van function calls. Vervolgens fine-tunen we FunctionGemma met supervised training en evalueren we de prestaties na afloop om te verifiëren dat het fine-tunen correct is toegepast.
Zoek je praktische oefeningen om fine-tunen te leren? Bekijk dan de cursus Fine-Tuning met Llama 3.
Wat is FunctionGemma?
FunctionGemma is een gespecialiseerde versie van Google’s Gemma 3 270M open model, specifiek ontworpen voor function calling en tooluse in plaats van algemene conversatie.
Het gebruikt dezelfde architectuur als Gemma 3, maar heeft een speciaal formaat en trainingsfocus waarmee het gestructureerde outputs kan genereren die function calls representeren.
FunctionGemma wordt uitgebracht als een basismodel dat ontwikkelaars kunnen fine-tunen voor specifieke use-cases. Door de grootte en het ontwerp is het lichtgewicht, efficiënt en inzetbaar op apparaten met beperkte middelen, zoals laptops en edge-hardware.
Waarom FunctionGemma fine-tunen?
Hoewel FunctionGemma is getraind voor function calling, presteren modellen van deze omvang het best wanneer ze worden gespecialiseerd via fine-tuning op taak-specifieke data.
Fine-tunen helpt het model stabiele patronen te leren voor het kiezen van de juiste functie uit een set tools en het correct formatteren van de bijbehorende argumenten voor realistische use-cases.
Dit leidt tot meer consistente en voorspelbare gestructureerde outputs, wat op zijn beurt de betrouwbaarheid verbetert in praktische workflows.
FunctionGemma fine-tunen: stapsgewijze handleiding
Laten we de stappen doorlopen die nodig zijn om FunctionGemma te fine-tunen.
1. Een Kaggle-omgeving opzetten
Begin op Kaggle en maak een nieuw notebook aan. Zodra het notebook geopend is, zoek je in het rechterpaneel naar Session options en stel je de Accelerator in op GPU (T4 ×2).
Dit schakelt GPU-versnelling in voor de sessie en stelt je in staat het model te fine-tunen met de gratis rekencapaciteit van Kaggle.
Nadat je de GPU hebt ingeschakeld, maak je een nieuwe codecel aan en voer je het volgende commando uit om alle vereiste Python-dependencies te installeren. Het kan even duren voordat de kernel start; daarna worden de pakketten automatisch geïnstalleerd.
Voeg vervolgens je Hugging Face-toegangstoken op een veilige manier toe.
Open in het bovenste menu Add-ons → Secrets en klik vervolgens op Add Secret. Stel de naam van de secret in op
HUGGINGFACE_TOKENen plak je Hugging Face API-sleutel als waarde.Kaggle Secrets gebruiken is veiliger dan omgevingsvariabelen of tokens rechtstreeks in het notebook hardcoden.
Zodra de secret is opgeslagen, geeft Kaggle een snippet om deze programmatisch op te halen.
Gebruik de volgende code om je aan te melden bij de Hugging Face Hub:
Na een geslaagde authenticatie kun je toegang krijgen tot afgeschermde modellen en datasets, en je gefinetunede FunctionGemma-model uploaden naar de Hugging Face Hub om te delen en te hergebruiken.
2. De Hermes Reasoning Tool-Use-dataset laden
De Hermes Reasoning Tool-Use-dataset is een open Engelstalige dataset in een tooluse-reasoningformaat met gestructureerde voorbeelden, ontworpen voor het trainen en evalueren van modellen op toolselectie- en JSON-achtige function-calling-taken.
De dataset bevat tienduizenden tooluse-reasoningvoorbeelden met natuurlijke taalprompts en toolschemas in een formaat dat geschikt is voor supervised fine-tuning.
In deze tutorial gebruiken we een subset van de dataset voor snellere experimenten.
Definieer eerst een willekeurige seed en het totale aantal voorbeelden dat je wilt gebruiken. Splits de data daarna in trainings- en evaluatiesets:
Laad vervolgens de dataset, shuffle deze en maak de train- en eval-subsets:
Dit levert 2.700 trainingsvoorbeelden en 300 evaluatievoorbeelden op, voldoende om fine-tuning te demonstreren terwijl de rekenvereisten beheersbaar blijven.
3. Het FunctionGemma-model en de processor laden
In deze tutorial gebruiken we KaggleHub om het FunctionGemma-model rechtstreeks in het Kaggle-notebook te laden.
KaggleHub bepaalt automatisch de modellocatie en maakt het model beschikbaar in de notebookomgeving, zodat je het niet handmatig van Hugging Face hoeft te downloaden.
Na het uitvoeren van de cel hierboven verschijnen de modelbestanden in de sectie Input van het Kaggle-notebook. Dat bevestigt dat het model succesvol is geladen en lokaal beschikbaar is.
Zodra het model beschikbaar is, laden we zowel de processor als het model in het GPU-geheugen.
De processor behandelt chattemplates en toolschemaformattering, terwijl het model verantwoordelijk is voor het genereren van gestructureerde function calls.
Met
device_map="auto"plaats je het model op de beschikbare GPU, endtype="auto"kiest een efficiënte precisie die door de hardware wordt ondersteund.Dit bevestigt dat FunctionGemma correct is geladen, op de GPU staat en klaar is voor evaluatie en fine-tunen.
4. Tooldefinities normaliseren en gold function calls extraheren
Voordat we FunctionGemma fine-tunen, moeten we standaardiseren hoe tools worden weergegeven en de juiste (gold) function calls betrouwbaar uit de dataset halen.
De Hermes Reasoning Tool-Use-dataset kan tooldefinities in meerdere formaten opslaan, dus deze stap zet alles om naar een consistente structuur die we kunnen gebruiken voor supervised fine-tuning.
Tools-veld normaliseren
We beginnen met het normaliseren van het veld
tools. In de dataset kantoolsvoorkomen als een Python-lijst, een JSON-string of volledig ontbreken.De hulpfunctie hieronder zet alle geldige representaties om in een nette Python-lijst en negeert veilig misvormde of lege items.
Parametertypes normaliseren
Vervolgens normaliseren we parametertypes. Hermes-tooldefinities gebruiken vaak informele typeannotaties zoals
str,intof containertypes zoalsList[str]. De onderstaande functie zet deze om naar geldige JSON Schema-typen die compatibel zijn met Hugging Face function calling.Hermes-stijl tool omzetten naar Hugging Face-functionschemas
Met deze utilities zetten we Hermes-achtige tooldefinities om naar Hugging Face-
{"type": "function", "function": {...}}-schemas. Deze functie ondersteunt twee formaten:Voor het per-argument-formaat behandelt deze implementatie de opgesomde parameters als verplicht, tenzij er expliciet een required-lijst is opgegeven.
Hulpfunctie
We definiëren een kleine helper om de geconverteerde toolschemas voor elk datasetvoorbeeld op te halen:
De gold function call extraheren
Daarna halen we de gold-toolcall uit de conversatie. Hermes-conversaties kunnen meerdere beurten bevatten, dus we parsen
<tool_call>{...}</tool_call>-blokken en extraheren het eerste geldige toolcall-object (naam + argumenten). Zo blijft de supervisie eenvoudig en consistent.De toolcall afstemmen op de gebruikersopdracht
Om de toolcall af te stemmen op de juiste gebruikersopdracht scannen we de conversatiegeschiedenis, zoeken we het gebruikersbericht dat overeenkomt met de dataset-
tasken nemen we vervolgens het assistentantwoord er direct na. Als dat antwoord een toolcall bevat, geven we die terug als gold-label.Aan het einde van deze stap heeft elk bruikbaar datasetvoorbeeld:
6. Supervised fine-tuning-samples bouwen voor function calling
Nu moeten we die omzetten naar Supervised Fine-Tuning (SFT)-trainingssamples in precies het formaat dat FunctionGemma verwacht, met gebruik van de bovenstaande hulpfuncties.
Het doel is om voorbeelden te maken waarbij de input bevat:
En de target is één enkele, gestructureerde FunctionGemma-call in dit formaat:
Stap 1: Schone, bruikbare rijen bouwen
We itereren eerst door de dataset en filteren voorbeelden weg die we niet kunnen gebruiken voor training.
Deze functie behoudt alleen voorbeelden waarbij:
Nu genereren we trainings- en evaluatierijen:
In ons geval houden we 961 trainingsvoorbeelden en 109 evaluatievoorbeelden over van de oorspronkelijke 3.000. Deze daling is te verwachten omdat de filtering streng is. Voorbeelden met ontbrekende toolcalls, ongeldige tooldefinities, niet-overeenkomende toolnamen of misvormde argumenten worden verwijderd.
Deze opschoningsstap is heel belangrijk. Vooraf bevatte de dataset veel ruis en misuitgelijnde voorbeelden, wat leidde tot instabiel function-callinggedrag en matige resultaten, zelfs na fine-tunen. Na het terugbrengen tot alleen hoogwaardige, taak-uitgelijnde voorbeelden wordt FunctionGemma veel consistenter en verbeteren de fine-tuningresultaten aanzienlijk.
Stap 2: Elke rij omzetten in één trainingssample met tekst
Vervolgens formatteren we elke rij in de exacte prompt-plus-target-structuur die FunctionGemma nodig heeft. We gebruiken
apply_chat_templatevan de processor om tooldeclaraties correct in te voegen en plakken daarna de gold function call als target eraan vast.Nu zetten we de rijen om naar Hugging Face Dataset-objecten:
Stap 3: Zeker stellen dat elke sample een geldige string is
Sommige TRL-versies vereisen dat
formatting_funceen string teruggeeft, en training kan stuklopen als een sample een lijst of niet-stringwaarde wordt. Deze helper forceerttextaltijd naar een schone string.Print tot slot één sample om de formattering te bevestigen:
Je zou een volledig gerenderde prompt moeten zien met tooldeclaraties, gevolgd door een gold function call vergelijkbaar met:
7. FunctionGemma evalueren vóór fine-tunen
Voor de training moet je meten hoe goed het basis FunctionGemma-model presteert op function calling. Deze baseline helpt te bevestigen dat fine-tunen de toolselectie en function-call-formattering echt verbetert.
In deze sectie evalueren we twee zaken:
We gebruiken twee reguliere expressies om de voorspelde toolnaam en het volledige function-call-blok uit de modeloutput te extraheren en vergelijken die met de gold-labels.
Baseline-evaluatielus
De onderstaande functie voert inferentie uit op een subset van de evaluatievoorbeelden en berekent beide metrics. We houden sampling uitgeschakeld (
do_sample=False) zodat de resultaten deterministisch zijn en makkelijker te vergelijken voor en na het fine-tunen.Voer de baseline-evaluatie uit:
Zelfs vóór fine-tunen laat FunctionGemma sterke baselineprestaties zien op deze taak.
Op een subset van 50 evaluatievoorbeelden behaalt het model 88% toolnaam-nauwkeurigheid, wat betekent dat het in de meeste gevallen de juiste functie kiest.
Daarnaast is de Tool-Call Character Error Rate (TC-CER) ongeveer 33% voor het volledige function-call-blok. Dat geeft aan dat, hoewel vaak de juiste tool wordt gekozen, de gegenereerde argumenten en de formattering nog afwijken van de gold-target.
Deze resultaten bevestigen dat het basis FunctionGemma-model de mechaniek van function calling al begrijpt.
De relatief hoge character error rate onderstreept echter de noodzaak van fine-tunen om de volledigheid van argumenten, de consistentie van de formattering en de algehele structurele correctheid van de gegenereerde function calls te verbeteren.
Eén voorspelling inspecteren
Metrics zijn nuttig, maar het is ook belangrijk om naar kwalitatieve outputs te kijken. De helper hieronder voert inferentie uit voor één voorbeeld en print de voorspelde function call naast de gold-referentie.
Voer het uit op één voorbeeld:
Output:
In dit voorbeeld kiest het model correct de juiste functie, daarom is de tool match True.
De gegenereerde call bevat echter extra argumenten en volgt niet exact de targetstructuur die in de training is gebruikt.
Hoewel deze argumenten semantisch logisch zijn, komen ze niet overeen met het gold-formaat, wat bijdraagt aan een hogere character error rate. Dit illustreert waarom fine-tunen nodig is om de structurele consistentie en schema-compliance te verbeteren, niet alleen de toolselectie.
8. De modeltrainer instellen voor fine-tunen
Nu we schone SFT-datasets hebben, is de volgende stap het configureren van de trainer die FunctionGemma gaat fine-tunen. We gebruiken TRL’s
SFTTrainer, een lichtgewicht en betrouwbare manier om chatstijlsmodellen te fine-tunen op tekstvoorbeelden.We stellen ook een outputmap in zodat Kaggle het gefinetunede checkpoint opslaat op een persistente locatie.
Om VRAM-gebruik tijdens training te verminderen, schakelen we gradient checkpointing in en zetten we de KV-cache uit.
Trainerconfiguratie
We definiëren de trainingsconfiguratie met SFTConfig. Deze instellingen balanceren stabiliteit en efficiëntie op Kaggle-GPU’s en houden de trainingstijd kort.
De formatting-functie zorgt ervoor dat elk trainingsvoorbeeld als één string wordt teruggegeven, wat vereist is door de huidige TRL-versie.
De trainer initialiseren
Tot slot initialiseren we de
SFTTrainermet het model, de configuratie, de datasets en de tokenizer.9. FunctionGemma fine-tunen
Met de geconfigureerde trainer kunnen we het model nu fine-tunen. Deze stap voert supervised training uit op de voorbereide dataset en evalueert het model periodiek tijdens de training.
Na afloop slaan we zowel het gefinetunede model als de processor op in de outputmap, zodat ze herbruikbaar zijn voor inferentie of upload naar de Hugging Face Hub.
Tijdens de training dalen zowel de training- als validatie-loss gestaag. De gemiddelde token-accuratesse verbetert ook in de tijd, wat aangeeft dat het model beter en consistenter gestructureerde function-call-outputs leert produceren.
Het gefinetunede FunctionGemma-model publiceren op Hugging Face
Zodra het fine-tunen klaar is, kunnen we het model publiceren zodat het eenvoudig kan worden hergebruikt, gedeeld of ingezet. Door het naar de Hugging Face Hub te pushen, kunnen anderen het direct laden via standaard Transformers-API’s.
Na het uploaden is het gefinetunede model publiek beschikbaar op Hugging Face:
Bron: kingabzpro/functiongemma-hermes-3k-ft · Hugging Face
Evaluatie en foutanalyse na het fine-tunen
Na het fine-tunen laden we het opgeslagen model en de processor opnieuw vanaf schijf en draaien we dezelfde evaluatiepipeline als vóór de training. Zo is de vergelijking tussen pre- en post-fine-tuning eerlijk en consistent.
Daarna evalueren we het gefinetunede model op de evaluatieset met toolnaam-nauwkeurigheid en TC-CER.
De resultaten tonen een duidelijke verbetering ten opzichte van de baseline:
De toolnaam-nauwkeurigheid stijgt van 88 procent naar 98 procent, en de character error rate voor het volledige function-call-blok halveert ruim. Dit geeft aan dat het model niet alleen betrouwbaarder de juiste tool kiest, maar ook outputs produceert die nauwer aansluiten op het doelschema.
Om de verbeteringen beter te begrijpen, inspecteren we individuele voorspellingen. In het onderstaande voorbeeld kiest het model de juiste functie en produceert het een goed gestructureerde call met vollediger argumenten.
Hoewel de voorspelde call extra argumenten kan bevatten die verder gaan dan de gold-target, zijn de algehele structuur en argumentformattering aanzienlijk consistenter dan vóór het fine-tunen. Dat weerspiegelt een beter schema-bewustzijn en sterkere afstemming tussen gebruikersintentie en gegenereerde function calls.
Laten we nog een voorbeeld bekijken.
Een tweede voorbeeld toont een schone en correcte function call voor een URL-extractietaak, wat laat zien dat het gefinetunede model goed generaliseert over verschillende tools.
Al met al bevestigen deze resultaten dat fine-tunen zowel de nauwkeurigheid als de structurele correctheid voor function-calling-taken verbetert.
Het volledige Kaggle-notebook bij deze tutorial vind je op:https://www.kaggle.com/code/kingabzpro/finetuning-functiongemma
Loop je ergens tegenaan? Clone dan het notebook, voeg je Hugging Face-secret toe en draai het end-to-end.
Tot slot
Als je probeert FunctionGemma te trainen op generieke tekstgeneratiedatasets, kun je daar beter vroegtijdig mee stoppen. FunctionGemma is niet ontworpen om zich te gedragen als een algemeen doel-LLM.
Voor open-ended tekstgeneratie is de Gemma 3-modelfamilie een betere keuze.
FunctionGemma is purpose-built voor function calling, waar het doel is om de juiste tool te selecteren, schema-conforme argumenten te produceren en betrouwbaar te interageren met externe systemen zoals API’s, databases en services.
De kleine omvang van FunctionGemma is een bewuste ontwerpkeuze. Met 270 miljoen parameters is het geoptimaliseerd voor low-latency, resource-efficiënte deployments, waaronder lokale machines, edge-devices en private infrastructuur. Daardoor is het zeer geschikt voor realtime function calling en agentische workflows, waar correctheid en structuur zwaarder wegen dan vloeiende tekst.
In deze tutorial hebben we geleerd hoe je FunctionGemma fine-tunet op de Hermes Reasoning Tool-Use-dataset. Een belangrijke les is dat datavoorbereiding en evaluatie zwaarder wegen dan pure trainingstijd.
Door de dataset zorgvuldig op te schonen, taken uit te lijnen met gold-toolcalls en strikte schemaconsistentie af te dwingen, konden we het modelgedrag drastisch verbeteren met een relatief klein aantal hoogwaardige samples.
De resultaten laten duidelijk de impact van fine-tunen zien. De toolnaam-nauwkeurigheid steeg van 88 procent naar 98 procent en de character error rate voor volledige function-call-blokken werd meer dan gehalveerd. Belangrijker nog, het model werd veel consistenter in het produceren van goed gestructureerde, voorspelbare function calls die aansluiten bij gebruik in de praktijk.