Aprende a ajustar FunctionGemma en menos de 10 minutos utilizando las GPU gratuitas de Kaggle, desde la preparación del conjunto de datos y la evaluación de referencia hasta el entrenamiento y la validación posterior al ajuste.
En este tutorial, exploraremos FunctionGemma, un modelo de lenguaje ligero para la invocación de funciones de Google DeepMind, y explicaré por qué el ajuste fino es esencial para lograr un uso fiable y conforme al esquema de la herramienta.
Comenzaremos configurando un entorno Kaggle habilitado para GPU, luego cargaremos y prepararemos tanto el conjunto de datos como el modelo FunctionGemma base.
A continuación, realizaremos evaluaciones previas al ajuste fino para establecer una base de referencia para la selección de herramientas y la precisión de las llamadas a funciones. A continuación, ajustaremos FunctionGemma mediante entrenamiento supervisado y evaluaremos su rendimiento tras el entrenamiento para verificar que el ajuste se ha aplicado correctamente.
Si buscas ejercicios prácticos que te ayuden a aprender a realizar ajustes, te recomiendo que eches un vistazo al curso curso Ajuste fino con Llama 3.
¿Qué es FunctionGemma?
FunctionGemma es una versión especializada de Gemma 3 270M , diseñada específicamente para llamar a funciones y utilizar herramientas, en lugar de para mantener conversaciones generales.
Utiliza la misma arquitectura que Gemma 3, pero incluye un formato específico y un enfoque de entrenamiento que te permite generar resultados estructurados que representan llamadas a funciones.
FunctionGemma se lanza como un modelo base que los programadores pueden ajustar para casos de uso específicos. Su tamaño y diseño lo hacen ligero, eficiente y fácil de implementar en dispositivos con recursos limitados, como ordenadores portátiles y hardware periférico.
¿Por qué ajustar FunctionGemma?
Aunque FunctionGemma está entrenado para la llamada de funciones, los modelos de este tamaño funcionan mejor cuando se especializan mediante el ajuste fino de datos específicos para cada tarea.
El ajuste fino ayuda al modelo a aprender patrones estables para seleccionar la función correcta de un conjunto de herramientas y dar formato a los argumentos correspondientes de forma correcta para casos de uso reales.
Este proceso da lugar a resultados estructurados más coherentes y predecibles, lo que a su vez mejora la fiabilidad en los flujos de trabajo prácticos.
Fine-Tuning FunctionGemma: Guía paso a paso
Veamos los pasos necesarios para ajustar FunctionGemma.
1. Configuración de un entorno Kaggle
Empieza por ir a Kaggle y crear un nuevo cuaderno. Una vez abierto el cuaderno, busca el panel de opciones de sesión «»(Aceleración deGPU) en la parte derecha y configura el acelerador en GPU (T4 ×2).
Esto habilita la aceleración de la GPU para la sesión y te permite ajustar el modelo utilizando los recursos informáticos gratuitos de Kaggle.
Después de habilitar la GPU, crea una nueva celda de código y ejecuta el siguiente comando para instalar todas las dependencias de Python necesarias. El núcleo puede tardar un poco en iniciarse, tras lo cual los paquetes se instalarán automáticamente.
%pip -qinstall-U datasets accelerate trl kagglehub sentencepiece huggingface_hub tqdm evaluate jiwerCon la tecnología de
A continuación, añade tu token de acceso a Hugging Face de forma segura.
En el menú superior, abre Complementos → Secretos y, a continuación, haz clic en Añadir secreto. Establece el nombre secreto en HUGGINGFACE_TOKEN y pega tu clave API de Hugging Face como valor.
Usar Kaggle Secrets es más seguro que codificar directamente las variables de entorno o los tokens en el cuaderno.
Una vez guardado el secreto, Kaggle proporcionará un fragmento de código para acceder a él mediante programación.
Utiliza el siguiente código para autenticarte en 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)Con la tecnología de
Tras completar con éxito el proceso de autenticación, podrás acceder a modelos y conjuntos de datos restringidos, así como enviar tu modelo FunctionGemma ajustado al Hugging Face Hub para compartirlo y reutilizarlo.
2. Cargando el conjunto de datos de uso de la herramienta de razonamiento Hermes
La conjunto de datos Hermes Reasoning Tool-Use es un conjunto de datos abierto en inglés con un formato de razonamiento sobre el uso de herramientas y ejemplos estructurados, diseñado para entrenar y evaluar modelos en tareas de selección de herramientas y llamada a funciones de estilo JSON.
Contiene decenas de miles de ejemplos de razonamiento sobre el uso de herramientas con indicaciones en lenguaje natural y esquemas de herramientas en un formato adecuado para el ajuste supervisado.
En este tutorial, utilizaremos un subconjunto del conjunto de datos para acelerar la experimentación.
En primer lugar, define una semilla aleatoria y el número total de ejemplos que se van a utilizar. A continuación, divide los datos en dos partes: entrenamiento y evaluación:
from datasets import load_dataset
SEED =40
N_TOTAL =3000
N_EVAL =300
N_TRAIN = N_TOTAL - N_EVALCon la tecnología de
A continuación, carga el conjunto de datos, barájalo y crea los subconjuntos de entrenamiento y evaluación:
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))Con la tecnología de
Esto te proporciona 2700 muestras de entrenamiento y 300 muestras de evaluación, suficientes para demostrar el ajuste fino sin que los requisitos informáticos sean excesivos.
En este tutorial, utilizamos KaggleHub para cargar el modelo FunctionGemma directamente en el cuaderno de Kaggle.
KaggleHub resuelve automáticamente la ubicación del modelo y lo pone a disposición en el entorno del cuaderno, lo que elimina la necesidad de descargas manuales desde Hugging Face.
import kagglehub
from transformers import AutoProcessor, AutoModelForCausalLM
model_path = kagglehub.model_download("google/functiongemma/transformers/functiongemma-270m-it")Con la tecnología de
Después de ejecutar la celda anterior, los archivos del modelo aparecerán en el sección Input del cuaderno de Kaggle, lo que confirma que el modelo se ha cargado correctamente y está disponible localmente.
Una vez que el modelo está disponible, cargamos tanto el procesador y el modelo en la memoria de la GPU.
El procesador gestiona las plantillas de chat y el formato del esquema de herramientas, mientras que el modelo se encarga de generar llamadas a funciones estructuradas.
Al establecer device_map="auto", te aseguras de que el modelo se coloque en la GPU disponible, y al seleccionardtype="auto", eliges una precisión eficiente compatible con el hardware.
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)Con la tecnología de
Esto confirma que FunctionGemma se ha cargado correctamente, se ha colocado en la GPU y está lista para su evaluación y ajuste.
4. Normalización de definiciones de herramientas y extracción de llamadas a funciones importantes
Antes de ajustar FunctionGemma, necesitamos estandarizar la forma en que se representan las herramientas y extraer de forma fiable las llamadas de función correctas (oro) del conjunto de datos.
El conjunto de datos Hermes Reasoning Tool-Use puede almacenar definiciones de herramientas en múltiples formatos, por lo que este paso convierte todo en una estructura coherente que podemos utilizar para el ajuste supervisado.
Normalizar el campo de herramientas
Empezamos normalizando el campo tools. En el conjunto de datos, tools puede aparecer como una lista de Python, una cadena JSON o puede faltar por completo.
La función auxiliar siguiente convierte todas las representaciones válidas en una lista Python limpia e ignora de forma segura las entradas malformadas o vacías.
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[]Con la tecnología de
Normalizar los tipos de parámetros
A continuación, normalizamos los tipos de parámetros. Las definiciones de herramientas de Hermes suelen utilizar anotaciones de tipos informales, como str,int, o tipos de contenedores como List[str]. La siguiente función convierte estos tipos en tipos JSON Schema válidos que son compatibles con las llamadas a funciones de Hugging Face.
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"}Con la tecnología de
Convertir la herramienta de estilo Hermes a esquemas de funciones de Hugging Face.
Con estas utilidades, convertimos las definiciones de herramientas al estilo Hermes en esquemas de Hugging Face {"type": "function", "function": {...}}. Esta función admite dos formatos:
Estilo por argumento de Hermes (donde cada parámetro tiene su propia pequeña especificación)
Herramientas que ya se asemejan al esquema JSON
Para el formato por argumento, esta implementación trata los parámetros enumerados como obligatorios si no se proporciona explícitamente una lista de requisitos.
Definimos un pequeño ayudante para recuperar los esquemas de herramientas convertidos para cada ejemplo de conjunto de datos:
defget_tools_hf(ex):return hermes_tools_to_hf_schema(ex.get("tools"))Con la tecnología de
Extraer la llamada a la función gold
A continuación, extraemos la llamada a la herramienta Gold de la conversación. Las conversaciones de Hermes pueden contener múltiples turnos, por lo que analizamos bloques {...} y extraemos el primer objeto de llamada de herramienta válido (nombre + argumentos). Esto hace que la supervisión sea sencilla y coherente.
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:returnNonereturnNoneCon la tecnología de
Alinea la llamada a la herramienta con la tarea del usuario.
Para alinear la llamada a la herramienta con la tarea correcta del usuario, escaneamos el historial de conversaciones, buscamos el mensaje del usuario que coincide con el conjunto de datos task y, a continuación, tomamos la respuesta del asistente inmediatamente después. Si la respuesta del asistente contiene una llamada a una herramienta, la devolvemos como etiqueta dorada.
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"]:breakreturnNoneCon la tecnología de
Al final de este paso, cada ejemplo de conjunto de datos utilizable tiene:
Un conjunto normalizado de esquemas de herramientas (formato Hugging Face).
Una llamada a función gold limpia y alineada con la tarea.
Una estructura coherente lista para crear muestras de ajuste supervisado.
6. Creación de muestras supervisadas de ajuste fino para la llamada de funciones
Ahora tenemos que convertirlos en muestras de entrenamiento de ajuste fino supervisado (SFT) en el formato exacto que espera FunctionGemma, utilizando las funciones auxiliares anteriores.
El objetivo es crear ejemplos en los que la entrada contenga:
Mensaje del programador que activa la llamada a la función.
La tarea del usuario
Las declaraciones de herramientas (esquemas)
Y el objetivo es una única llamada estructurada a FunctionGemma con este formato:
<start_function_call>call:TOOL_NAME{args:<escape>{...}<escape>}<end_function_call>Con la tecnología de
Paso 1: Crea filas limpias y útiles.
Empezamos iterando a través del conjunto de datos y filtrando cualquier ejemplo que no pueda utilizarse para el entrenamiento.
Esta función solo conserva los ejemplos en los que:
Existe una herramienta llamada «gold tool».
Existe una lista válida de herramientas.
El nombre de la herramienta dorada aparece en la lista de herramientas.
Los argumentos son un diccionario válido.
Si la herramienta no tiene campos obligatorios, los argumentos se fuerzan a {} para evitar objetivos ruidosos o inconsistentes.
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 rowsCon la tecnología de
Ahora generamos filas de entrenamiento y evaluación:
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))Con la tecnología de
En nuestro caso, terminamos con 961 muestras de entrenamiento y 109 muestras de evaluación de las 3000 originales. Esta caída es previsible debido a que el filtrado es estricto. Elimina los ejemplos con llamadas a herramientas que faltan, definiciones de herramientas no válidas, nombres de herramientas que no coinciden o argumentos mal formados.
Este paso de limpieza es muy importante. Antes de aplicarlo, el conjunto de datos contenía muestras ruidosas y desalineadas, lo que provocaba un comportamiento inestable en la llamada a funciones y resultados deficientes incluso después del ajuste fino. Tras filtrar solo los ejemplos de alta calidad y alineados con las tareas, FunctionGemma se vuelve mucho más coherente y los resultados del ajuste fino mejoran significativamente.
Paso 2: Convierte cada fila en una única muestra de texto de entrenamiento.
A continuación, formateamos cada fila con la estructura exacta de indicaciones y objetivos que necesita FunctionGemma. Utilizamos el procesador apply_chat_template para inyectar correctamente las declaraciones de herramientas y, a continuación, añadimos la llamada a la función gold como destino.
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 + targetCon la tecnología de
Ahora convertimos las filas en objetos del conjunto de datos Hugging Face:
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])Con la tecnología de
Paso 3: Asegúrate de que todas las muestras sean cadenas válidas.
Algunas versiones de TRL requieren que formatting_func devuelva una cadena, y el entrenamiento puede fallar si alguna muestra se convierte en una lista o en un valor que no sea una cadena. Este ayudante obliga atext a ser siempre una cadena limpia.
# 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)Con la tecnología de
Por último, imprime una muestra para confirmar el formato:
Deberías ver un mensaje completamente renderizado que contiene declaraciones de herramientas, seguido de una llamada a la función gold similar a:
<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>Con la tecnología de
7. Evaluación de FunctionGemma antes del ajuste fino
Antes del entrenamiento, debes medir el rendimiento del modelo base FunctionGemma en la llamada de funciones. Esta línea de base te ayuda a confirmar que el ajuste fino realmente mejora la selección de herramientas y el formato de las llamadas a funciones.
En esta sección, evaluamos dos cosas:
Precisión del nombre de la herramienta: si el modelo selecciona el nombre de función correcto.
TC-CER (tasa de errores de caracteres de llamada a herramientas): grado de coincidencia entre el bloque de llamadas a funciones generado y el bloque de llamadas de referencia; cuanto menor sea el valor, mejor.
Utilizamos dos expresiones regulares para extraer el nombre de la herramienta predicha y el bloque completo de llamada a la función de la salida del modelo, y luego los comparamos con las etiquetas de referencia.
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>")Con la tecnología de
Bucle de evaluación de referencia
La función siguiente ejecuta la inferencia en un subconjunto de ejemplos de evaluación y calcula ambas métricas. Mantenemos desactivado el muestreo (do_sample=False) para que los resultados sean deterministas y más fáciles de comparar antes y después del ajuste fino.
@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),}Con la tecnología de
Ejecuta la evaluación de referencia:
pre_metrics = eval_tool_and_cer(processor, model, simple_eval, n=50, max_new_tokens=128)print("PRE metrics:", pre_metrics)Con la tecnología de
Incluso antes del ajuste, FunctionGemma muestra un sólido rendimiento básico en esta tarea.
En un subconjunto de 50 ejemplos de evaluación, el modelo alcanza una precisión del 88 % en el nombre de la herramienta, lo que significa que selecciona la función correcta en la mayoría de los casos.
Además, la tasa de error de caracteres de llamada a herramientas (TC-CER) es de aproximadamente el 33 % para el bloque completo de llamadas a funciones, lo que indica que, aunque a menudo se elige la herramienta correcta, los argumentos y el formato generados siguen desviándose del objetivo deseado.
PRE metrics:{'n_eval':50,'tool_accuracy':0.88,'TC-CER (lower is better)':0.33399307273626916}Con la tecnología de
Estos resultados confirman que el modelo básico FunctionGemma ya comprende la mecánica de la invocación de funciones.
Sin embargo, la tasa de error relativamente alta pone de manifiesto la necesidad de realizar ajustes para mejorar la integridad de los argumentos, la coherencia del formato y la corrección estructural general de las llamadas a funciones generadas.
Inspección de una sola predicción
Las métricas son útiles, pero también es importante tener en cuenta los resultados cualitativos. El asistente que aparece a continuación ejecuta la inferencia para un ejemplo e imprime la llamada a la función predicha junto con la referencia de oro.
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),}Con la tecnología de
Ejecuta un ejemplo:
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']}
""")Con la tecnología de
Salida:
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>Con la tecnología de
En este ejemplo, el modelo selecciona correctamente la función adecuada, por lo que la coincidencia de la herramienta es True.
Sin embargo, la llamada generada incluye argumentos adicionales y no sigue exactamente la estructura de destino utilizada en el entrenamiento.
Aunque estos argumentos son semánticamente razonables, no coinciden con el formato de llamada a la función gold, lo que contribuye a una mayor tasa de errores de caracteres. Esto ilustra por qué es necesario realizar ajustes para mejorar la coherencia estructural y el cumplimiento del esquema, y no solo la selección de herramientas.
8. Configuración del entrenador de modelos para el ajuste fino
Ahora que tenemos conjuntos de datos SFT limpios, el siguiente paso es configurar el entrenador que ajustará FunctionGemma. Utilizamos el modelo de TRL «SFTTrainer », que es una forma ligera y fiable de ajustar modelos de estilo chat en ejemplos de texto.
También establecemos un directorio de salida para que Kaggle guarde el punto de control ajustado en una ubicación persistente.
from trl import SFTConfig, SFTTrainer
OUT_DIR ="/kaggle/working/functiongemma-hermes-ft"Con la tecnología de
Para reducir el uso de VRAM durante el entrenamiento, habilitamos el control de puntos de verificación de gradientes y deshabilitamos la caché KV.
# VRAM savings
model.gradient_checkpointing_enable()
model.config.use_cache =FalseCon la tecnología de
Configuración del entrenador
Definimos la configuración de entrenamiento utilizando SFTConfig. Estos ajustes se eligen para equilibrar la estabilidad y la eficiencia en las GPU de Kaggle, al tiempo que se mantiene un tiempo de entrenamiento breve.
La función de formateo garantiza que cada ejemplo de entrenamiento se devuelva como una sola cadena, tal y como exige la versión actual de TRL.
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)Con la tecnología de
Inicializar el entrenador
Por último, inicializamos el modelo de lenguaje grande (SFTTrainer ) con el modelo, la configuración, los conjuntos de datos y el tokenizador.
trainer = SFTTrainer(
model=model,
args=cfg,
train_dataset=train_text_ds,
eval_dataset=eval_text_ds,
processing_class=tokenizer,
formatting_func=formatting_func,)Con la tecnología de
9. Fine-Tuning FunctionGemma
Una vez configurado el entrenador, ya podemos empezar a ajustar el modelo. Este paso ejecuta el entrenamiento supervisado en el conjunto de datos preparado y evalúa el modelo periódicamente durante el entrenamiento.
trainer.train()
trainer.save_model(OUT_DIR)
processor.save_pretrained(OUT_DIR)print("Saved to:", OUT_DIR)Con la tecnología de
Una vez completado el entrenamiento, guardamos tanto el modelo ajustado como el procesador en el directorio de salida para que puedan reutilizarse para la inferencia o cargarse en Hugging Face Hub.
Durante el entrenamiento, tanto la pérdida de entrenamiento como la de validación disminuyen de forma constante. La precisión media de los tokens también mejora con el tiempo, lo que indica que el modelo ha aprendido con éxito a producir resultados de llamadas a funciones más precisos y coherentes.
Publicación del modelo FunctionGemma ajustado en Hugging Face
Una vez completado el ajuste, podemos publicar el modelo para que pueda reutilizarse, compartirse o implementarse fácilmente. Al enviar el modelo al Hugging Face Hub, otros usuarios pueden cargarlo directamente utilizando las API estándar de Transformers.
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)Con la tecnología de
Una vez completada la carga, el modelo ajustado estará disponible públicamente en Hugging Face:
Evaluación posterior al ajuste fino y análisis de errores
Una vez completado el ajuste, volvemos a cargar el modelo y el procesador guardados desde el disco y ejecutamos el mismo proceso de evaluación utilizado antes del entrenamiento. Esto garantiza que la comparación entre el rendimiento antes y después del ajuste sea justa y coherente.
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")Con la tecnología de
A continuación, evaluamos el modelo ajustado en el conjunto de evaluación utilizando la precisión del nombre de la herramienta y el 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)Con la tecnología de
Los resultados muestran una clara mejora con respecto al punto de referencia:
POST metrics:{'n_eval':50,'tool_accuracy':0.98,'TC-CER (lower is better)':0.1454725383473528}Con la tecnología de
La precisión del nombre de la herramienta mejora del 88 % al 98 %, y la tasa de error de caracteres para el bloque completo de llamadas a funciones se reduce a más de la mitad. Esto indica que el modelo no solo selecciona la herramienta correcta de forma más fiable, sino que también produce resultados que se ajustan mejor al esquema objetivo.
Para comprender mejor las mejoras, inspeccionamos las predicciones individuales. En el ejemplo siguiente, el modelo selecciona la función correcta y genera una llamada bien estructurada con argumentos más completos.
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']}
""")Con la tecnología de
Aunque la llamada prevista puede incluir argumentos adicionales que van más allá del objetivo principal, la estructura general y el formato de los argumentos son mucho más coherentes que antes del ajuste. Esto refleja una mayor conciencia del esquema y una mayor alineación entre la intención del usuario y las llamadas a funciones generadas.
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>Con la tecnología de
Veamos otro ejemplo.
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']}
""")Con la tecnología de
Un segundo ejemplo muestra una llamada de función limpia y correcta para una tarea de extracción de URL, lo que demuestra que el modelo ajustado se generaliza bien en diferentes herramientas.
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>Con la tecnología de
En general, estos resultados confirman que el ajuste fino mejora con éxito tanto la precisión como la corrección estructural de las tareas de identificación de funciones.
Si tienes algún problema, puedes clonar el cuaderno, añadir tu clave secreta de Hugging Face y ejecutarlo de principio a fin.
Reflexiones finales
Si estás intentando entrenar FunctionGemma con conjuntos de datos genéricos para la generación de texto, es mejor que lo dejes cuanto antes. FunctionGemma no está diseñado para comportarse como un modelo de lenguaje de uso general.
FunctionGemma está especialmente diseñado para la llamada de funciones, donde el objetivo es seleccionar la herramienta correcta, producir argumentos que cumplan con el esquema e interactuar de forma fiable con sistemas externos como API, bases de datos y servicios.
La pequeña tamaño de FunctionGemma es una elección de diseño deliberada. Con 270 millones de parámetros, está optimizado para implementaciones de baja latencia y eficientes en cuanto a recursos, incluyendo máquinas locales, dispositivos periféricos e infraestructura privada. Esto lo hace muy adecuado para llamadas de funciones en tiempo real y flujos de trabajo agenticos, donde la corrección y la estructura son más importantes que la fluidez del lenguaje.
En este tutorial, hemos aprendido a ajustar FunctionGemma en el conjunto de datos Hermes Reasoning Tool-Use. Una conclusión clave es que la preparación y la evaluación de los datos son más importantes que el tiempo de entrenamiento en bruto.
Mediante una limpieza minuciosa del conjunto de datos, la alineación de las tareas con las llamadas de herramientas de referencia y la aplicación de una estricta coherencia en el esquema, logramos mejorar considerablemente el comportamiento del modelo con un número relativamente pequeño de muestras de alta calidad.
Los resultados muestran claramente el impacto del ajuste fino. La precisión del nombre de la herramienta mejoró del 88 % al 98 %, y la tasa de error de caracteres para bloques de llamadas de función completos se redujo a más de la mitad. Más importante aún, el modelo se volvió mucho más consistente en la producción de llamadas a funciones bien estructuradas y predecibles que se ajustan al uso en el mundo real.
Preguntas frecuentes sobre FunctionGemma
¿Qué es FunctionGemma y en qué se diferencia de Gemma 3?⌄
FunctionGemma es una versión especializada del modelo abierto Gemma 3 270M. Mientras que Gemma 3 estándar está diseñado para la generación de texto, FunctionGemma está entrenado explícitamente para traducir el lenguaje natural en llamadas a funciones estructuradas (solicitudes API), lo que lo convierte en un «enrutador» dedicado para flujos de trabajo agenticos en lugar de un chatbot conversacional.
¿Qué hardware necesitas para ejecutar FunctionGemma?⌄
Al tratarse de un modelo de 270 millones de parámetros, FunctionGemma es increíblemente ligero (unos 300 MB cuantificados). Puede funcionar de manera eficiente en dispositivos periféricos como ordenadores portátiles, teléfonos móviles y hardware integrado (por ejemplo, NVIDIA Jetson Nano) sin necesidad de una GPU dedicada en la nube.
¿Por qué es necesario ajustar FunctionGemma si ya está especializada?⌄
Aunque el modelo básico comprende el concepto de uso de herramientas, es necesario realizar ajustes para enseñarle tus esquemas API y lógica empresarial específicos. Los puntos de referencia de Google muestran que el ajuste fino puede aumentar la precisión de las llamadas a funciones de ~58 % (base) a más del 85 % en tareas específicas del dominio.
¿Puede FunctionGemma manejar conversaciones de varios turnos?⌄
La función Gemma está optimizada principalmente para la ejecución de comandos de una sola vuelta (instrucción del usuario → llamada a herramienta). Para razonamientos complejos y multiturnos o para mantener un historial de conversaciones largo, es mejor utilizarlo como un «controlador de tráfico» que delega las consultas difíciles a un modelo más grande (como Gemma 3 27B) mientras gestiona las acciones simples a nivel local.
Soy un científico de datos certificado que disfruta creando aplicaciones de aprendizaje automático y escribiendo blogs sobre ciencia de datos. Actualmente me centro en la creación de contenidos, la edición y el trabajo con grandes modelos lingüísticos.
Aprende a ajustar Llama-2 en Colab utilizando nuevas técnicas para superar las limitaciones de memoria y computación y hacer más accesibles los grandes modelos lingüísticos de código abierto.
Explore GPT-3.5 Turbo y descubra el potencial transformador del ajuste fino. Aprenda a personalizar este modelo de lenguaje avanzado para aplicaciones especializadas, mejore su rendimiento y comprenda los costes asociados, la seguridad y las consideraciones de privacidad.
Libere todo el potencial de GPT-3 mediante el ajuste fino. Aprenda a utilizar la API de OpenAI y Python para mejorar este modelo de red neuronal avanzado para su caso de uso específico.
Aprende a afinar los LLM en conjuntos de datos personalizados, evaluar el rendimiento y exportar y servir modelos sin problemas utilizando el marco de trabajo de bajo/ningún código de LLaMA-Factory.
Aprende a afinar SAM 2 de Meta AI utilizando el conjunto de datos de segmentación de TC torácica para mejorar el rendimiento de segmentación de imágenes del modelo en el análisis de imágenes médicas.
En este tutorial, exploraremos FunctionGemma, un modelo de lenguaje ligero para la invocación de funciones de Google DeepMind, y explicaré por qué el ajuste fino es esencial para lograr un uso fiable y conforme al esquema de la herramienta.
Comenzaremos configurando un entorno Kaggle habilitado para GPU, luego cargaremos y prepararemos tanto el conjunto de datos como el modelo FunctionGemma base.
A continuación, realizaremos evaluaciones previas al ajuste fino para establecer una base de referencia para la selección de herramientas y la precisión de las llamadas a funciones. A continuación, ajustaremos FunctionGemma mediante entrenamiento supervisado y evaluaremos su rendimiento tras el entrenamiento para verificar que el ajuste se ha aplicado correctamente.
Si buscas ejercicios prácticos que te ayuden a aprender a realizar ajustes, te recomiendo que eches un vistazo al curso curso Ajuste fino con Llama 3.
¿Qué es FunctionGemma?
FunctionGemma es una versión especializada de Gemma 3 270M , diseñada específicamente para llamar a funciones y utilizar herramientas, en lugar de para mantener conversaciones generales.
Utiliza la misma arquitectura que Gemma 3, pero incluye un formato específico y un enfoque de entrenamiento que te permite generar resultados estructurados que representan llamadas a funciones.
FunctionGemma se lanza como un modelo base que los programadores pueden ajustar para casos de uso específicos. Su tamaño y diseño lo hacen ligero, eficiente y fácil de implementar en dispositivos con recursos limitados, como ordenadores portátiles y hardware periférico.
¿Por qué ajustar FunctionGemma?
Aunque FunctionGemma está entrenado para la llamada de funciones, los modelos de este tamaño funcionan mejor cuando se especializan mediante el ajuste fino de datos específicos para cada tarea.
El ajuste fino ayuda al modelo a aprender patrones estables para seleccionar la función correcta de un conjunto de herramientas y dar formato a los argumentos correspondientes de forma correcta para casos de uso reales.
Este proceso da lugar a resultados estructurados más coherentes y predecibles, lo que a su vez mejora la fiabilidad en los flujos de trabajo prácticos.
Fine-Tuning FunctionGemma: Guía paso a paso
Veamos los pasos necesarios para ajustar FunctionGemma.
1. Configuración de un entorno Kaggle
Empieza por ir a Kaggle y crear un nuevo cuaderno. Una vez abierto el cuaderno, busca el panel de opciones de sesión « »(Aceleración deGPU) en la parte derecha y configura el acelerador en GPU (T4 ×2).
Esto habilita la aceleración de la GPU para la sesión y te permite ajustar el modelo utilizando los recursos informáticos gratuitos de Kaggle.
Después de habilitar la GPU, crea una nueva celda de código y ejecuta el siguiente comando para instalar todas las dependencias de Python necesarias. El núcleo puede tardar un poco en iniciarse, tras lo cual los paquetes se instalarán automáticamente.
A continuación, añade tu token de acceso a Hugging Face de forma segura.
En el menú superior, abre Complementos → Secretos y, a continuación, haz clic en Añadir secreto. Establece el nombre secreto en
HUGGINGFACE_TOKENy pega tu clave API de Hugging Face como valor.Usar Kaggle Secrets es más seguro que codificar directamente las variables de entorno o los tokens en el cuaderno.
Una vez guardado el secreto, Kaggle proporcionará un fragmento de código para acceder a él mediante programación.
Utiliza el siguiente código para autenticarte en Hugging Face Hub:
Tras completar con éxito el proceso de autenticación, podrás acceder a modelos y conjuntos de datos restringidos, así como enviar tu modelo FunctionGemma ajustado al Hugging Face Hub para compartirlo y reutilizarlo.
2. Cargando el conjunto de datos de uso de la herramienta de razonamiento Hermes
La conjunto de datos Hermes Reasoning Tool-Use es un conjunto de datos abierto en inglés con un formato de razonamiento sobre el uso de herramientas y ejemplos estructurados, diseñado para entrenar y evaluar modelos en tareas de selección de herramientas y llamada a funciones de estilo JSON.
Contiene decenas de miles de ejemplos de razonamiento sobre el uso de herramientas con indicaciones en lenguaje natural y esquemas de herramientas en un formato adecuado para el ajuste supervisado.
En este tutorial, utilizaremos un subconjunto del conjunto de datos para acelerar la experimentación.
En primer lugar, define una semilla aleatoria y el número total de ejemplos que se van a utilizar. A continuación, divide los datos en dos partes: entrenamiento y evaluación:
A continuación, carga el conjunto de datos, barájalo y crea los subconjuntos de entrenamiento y evaluación:
Esto te proporciona 2700 muestras de entrenamiento y 300 muestras de evaluación, suficientes para demostrar el ajuste fino sin que los requisitos informáticos sean excesivos.
3. Carga del modelo y procesador FunctionGemma
En este tutorial, utilizamos KaggleHub para cargar el modelo FunctionGemma directamente en el cuaderno de Kaggle.
KaggleHub resuelve automáticamente la ubicación del modelo y lo pone a disposición en el entorno del cuaderno, lo que elimina la necesidad de descargas manuales desde Hugging Face.
Después de ejecutar la celda anterior, los archivos del modelo aparecerán en el sección Input del cuaderno de Kaggle, lo que confirma que el modelo se ha cargado correctamente y está disponible localmente.
Una vez que el modelo está disponible, cargamos tanto el procesador y el modelo en la memoria de la GPU.
El procesador gestiona las plantillas de chat y el formato del esquema de herramientas, mientras que el modelo se encarga de generar llamadas a funciones estructuradas.
Al establecer
device_map="auto", te aseguras de que el modelo se coloque en la GPU disponible, y al seleccionardtype="auto", eliges una precisión eficiente compatible con el hardware.Esto confirma que FunctionGemma se ha cargado correctamente, se ha colocado en la GPU y está lista para su evaluación y ajuste.
4. Normalización de definiciones de herramientas y extracción de llamadas a funciones importantes
Antes de ajustar FunctionGemma, necesitamos estandarizar la forma en que se representan las herramientas y extraer de forma fiable las llamadas de función correctas (oro) del conjunto de datos.
El conjunto de datos Hermes Reasoning Tool-Use puede almacenar definiciones de herramientas en múltiples formatos, por lo que este paso convierte todo en una estructura coherente que podemos utilizar para el ajuste supervisado.
Normalizar el campo de herramientas
Empezamos normalizando el campo
tools. En el conjunto de datos,toolspuede aparecer como una lista de Python, una cadena JSON o puede faltar por completo.La función auxiliar siguiente convierte todas las representaciones válidas en una lista Python limpia e ignora de forma segura las entradas malformadas o vacías.
Normalizar los tipos de parámetros
A continuación, normalizamos los tipos de parámetros. Las definiciones de herramientas de Hermes suelen utilizar anotaciones de tipos informales, como
str,int, o tipos de contenedores comoList[str]. La siguiente función convierte estos tipos en tipos JSON Schema válidos que son compatibles con las llamadas a funciones de Hugging Face.Convertir la herramienta de estilo Hermes a esquemas de funciones de Hugging Face.
Con estas utilidades, convertimos las definiciones de herramientas al estilo Hermes en esquemas de Hugging Face
{"type": "function", "function": {...}}. Esta función admite dos formatos:Para el formato por argumento, esta implementación trata los parámetros enumerados como obligatorios si no se proporciona explícitamente una lista de requisitos.
Función auxiliar
Definimos un pequeño ayudante para recuperar los esquemas de herramientas convertidos para cada ejemplo de conjunto de datos:
Extraer la llamada a la función gold
A continuación, extraemos la llamada a la herramienta Gold de la conversación. Las conversaciones de Hermes pueden contener múltiples turnos, por lo que analizamos bloques
{...}y extraemos el primer objeto de llamada de herramienta válido (nombre + argumentos). Esto hace que la supervisión sea sencilla y coherente.Alinea la llamada a la herramienta con la tarea del usuario.
Para alinear la llamada a la herramienta con la tarea correcta del usuario, escaneamos el historial de conversaciones, buscamos el mensaje del usuario que coincide con el conjunto de datos
tasky, a continuación, tomamos la respuesta del asistente inmediatamente después. Si la respuesta del asistente contiene una llamada a una herramienta, la devolvemos como etiqueta dorada.Al final de este paso, cada ejemplo de conjunto de datos utilizable tiene:
6. Creación de muestras supervisadas de ajuste fino para la llamada de funciones
Ahora tenemos que convertirlos en muestras de entrenamiento de ajuste fino supervisado (SFT) en el formato exacto que espera FunctionGemma, utilizando las funciones auxiliares anteriores.
El objetivo es crear ejemplos en los que la entrada contenga:
Y el objetivo es una única llamada estructurada a FunctionGemma con este formato:
Paso 1: Crea filas limpias y útiles.
Empezamos iterando a través del conjunto de datos y filtrando cualquier ejemplo que no pueda utilizarse para el entrenamiento.
Esta función solo conserva los ejemplos en los que:
Ahora generamos filas de entrenamiento y evaluación:
En nuestro caso, terminamos con 961 muestras de entrenamiento y 109 muestras de evaluación de las 3000 originales. Esta caída es previsible debido a que el filtrado es estricto. Elimina los ejemplos con llamadas a herramientas que faltan, definiciones de herramientas no válidas, nombres de herramientas que no coinciden o argumentos mal formados.
Este paso de limpieza es muy importante. Antes de aplicarlo, el conjunto de datos contenía muestras ruidosas y desalineadas, lo que provocaba un comportamiento inestable en la llamada a funciones y resultados deficientes incluso después del ajuste fino. Tras filtrar solo los ejemplos de alta calidad y alineados con las tareas, FunctionGemma se vuelve mucho más coherente y los resultados del ajuste fino mejoran significativamente.
Paso 2: Convierte cada fila en una única muestra de texto de entrenamiento.
A continuación, formateamos cada fila con la estructura exacta de indicaciones y objetivos que necesita FunctionGemma. Utilizamos el procesador
apply_chat_templatepara inyectar correctamente las declaraciones de herramientas y, a continuación, añadimos la llamada a la función gold como destino.Ahora convertimos las filas en objetos del conjunto de datos Hugging Face:
Paso 3: Asegúrate de que todas las muestras sean cadenas válidas.
Algunas versiones de TRL requieren que
formatting_funcdevuelva una cadena, y el entrenamiento puede fallar si alguna muestra se convierte en una lista o en un valor que no sea una cadena. Este ayudante obliga atexta ser siempre una cadena limpia.Por último, imprime una muestra para confirmar el formato:
Deberías ver un mensaje completamente renderizado que contiene declaraciones de herramientas, seguido de una llamada a la función gold similar a:
7. Evaluación de FunctionGemma antes del ajuste fino
Antes del entrenamiento, debes medir el rendimiento del modelo base FunctionGemma en la llamada de funciones. Esta línea de base te ayuda a confirmar que el ajuste fino realmente mejora la selección de herramientas y el formato de las llamadas a funciones.
En esta sección, evaluamos dos cosas:
Utilizamos dos expresiones regulares para extraer el nombre de la herramienta predicha y el bloque completo de llamada a la función de la salida del modelo, y luego los comparamos con las etiquetas de referencia.
Bucle de evaluación de referencia
La función siguiente ejecuta la inferencia en un subconjunto de ejemplos de evaluación y calcula ambas métricas. Mantenemos desactivado el muestreo (
do_sample=False) para que los resultados sean deterministas y más fáciles de comparar antes y después del ajuste fino.Ejecuta la evaluación de referencia:
Incluso antes del ajuste, FunctionGemma muestra un sólido rendimiento básico en esta tarea.
En un subconjunto de 50 ejemplos de evaluación, el modelo alcanza una precisión del 88 % en el nombre de la herramienta, lo que significa que selecciona la función correcta en la mayoría de los casos.
Además, la tasa de error de caracteres de llamada a herramientas (TC-CER) es de aproximadamente el 33 % para el bloque completo de llamadas a funciones, lo que indica que, aunque a menudo se elige la herramienta correcta, los argumentos y el formato generados siguen desviándose del objetivo deseado.
Estos resultados confirman que el modelo básico FunctionGemma ya comprende la mecánica de la invocación de funciones.
Sin embargo, la tasa de error relativamente alta pone de manifiesto la necesidad de realizar ajustes para mejorar la integridad de los argumentos, la coherencia del formato y la corrección estructural general de las llamadas a funciones generadas.
Inspección de una sola predicción
Las métricas son útiles, pero también es importante tener en cuenta los resultados cualitativos. El asistente que aparece a continuación ejecuta la inferencia para un ejemplo e imprime la llamada a la función predicha junto con la referencia de oro.
Ejecuta un ejemplo:
Salida:
En este ejemplo, el modelo selecciona correctamente la función adecuada, por lo que la coincidencia de la herramienta es True.
Sin embargo, la llamada generada incluye argumentos adicionales y no sigue exactamente la estructura de destino utilizada en el entrenamiento.
Aunque estos argumentos son semánticamente razonables, no coinciden con el formato de llamada a la función gold, lo que contribuye a una mayor tasa de errores de caracteres. Esto ilustra por qué es necesario realizar ajustes para mejorar la coherencia estructural y el cumplimiento del esquema, y no solo la selección de herramientas.
8. Configuración del entrenador de modelos para el ajuste fino
Ahora que tenemos conjuntos de datos SFT limpios, el siguiente paso es configurar el entrenador que ajustará FunctionGemma. Utilizamos el modelo de TRL «
SFTTrainer», que es una forma ligera y fiable de ajustar modelos de estilo chat en ejemplos de texto.También establecemos un directorio de salida para que Kaggle guarde el punto de control ajustado en una ubicación persistente.
Para reducir el uso de VRAM durante el entrenamiento, habilitamos el control de puntos de verificación de gradientes y deshabilitamos la caché KV.
Configuración del entrenador
Definimos la configuración de entrenamiento utilizando SFTConfig. Estos ajustes se eligen para equilibrar la estabilidad y la eficiencia en las GPU de Kaggle, al tiempo que se mantiene un tiempo de entrenamiento breve.
La función de formateo garantiza que cada ejemplo de entrenamiento se devuelva como una sola cadena, tal y como exige la versión actual de TRL.
Inicializar el entrenador
Por último, inicializamos el modelo de lenguaje grande (
SFTTrainer) con el modelo, la configuración, los conjuntos de datos y el tokenizador.9. Fine-Tuning FunctionGemma
Una vez configurado el entrenador, ya podemos empezar a ajustar el modelo. Este paso ejecuta el entrenamiento supervisado en el conjunto de datos preparado y evalúa el modelo periódicamente durante el entrenamiento.
Una vez completado el entrenamiento, guardamos tanto el modelo ajustado como el procesador en el directorio de salida para que puedan reutilizarse para la inferencia o cargarse en Hugging Face Hub.
Durante el entrenamiento, tanto la pérdida de entrenamiento como la de validación disminuyen de forma constante. La precisión media de los tokens también mejora con el tiempo, lo que indica que el modelo ha aprendido con éxito a producir resultados de llamadas a funciones más precisos y coherentes.
Publicación del modelo FunctionGemma ajustado en Hugging Face
Una vez completado el ajuste, podemos publicar el modelo para que pueda reutilizarse, compartirse o implementarse fácilmente. Al enviar el modelo al Hugging Face Hub, otros usuarios pueden cargarlo directamente utilizando las API estándar de Transformers.
Una vez completada la carga, el modelo ajustado estará disponible públicamente en Hugging Face:
Fuente: kingabzpro/functiongemma-hermes-3k-ft · Hugging Face
Evaluación posterior al ajuste fino y análisis de errores
Una vez completado el ajuste, volvemos a cargar el modelo y el procesador guardados desde el disco y ejecutamos el mismo proceso de evaluación utilizado antes del entrenamiento. Esto garantiza que la comparación entre el rendimiento antes y después del ajuste sea justa y coherente.
A continuación, evaluamos el modelo ajustado en el conjunto de evaluación utilizando la precisión del nombre de la herramienta y el TC-CER.
Los resultados muestran una clara mejora con respecto al punto de referencia:
La precisión del nombre de la herramienta mejora del 88 % al 98 %, y la tasa de error de caracteres para el bloque completo de llamadas a funciones se reduce a más de la mitad. Esto indica que el modelo no solo selecciona la herramienta correcta de forma más fiable, sino que también produce resultados que se ajustan mejor al esquema objetivo.
Para comprender mejor las mejoras, inspeccionamos las predicciones individuales. En el ejemplo siguiente, el modelo selecciona la función correcta y genera una llamada bien estructurada con argumentos más completos.
Aunque la llamada prevista puede incluir argumentos adicionales que van más allá del objetivo principal, la estructura general y el formato de los argumentos son mucho más coherentes que antes del ajuste. Esto refleja una mayor conciencia del esquema y una mayor alineación entre la intención del usuario y las llamadas a funciones generadas.
Veamos otro ejemplo.
Un segundo ejemplo muestra una llamada de función limpia y correcta para una tarea de extracción de URL, lo que demuestra que el modelo ajustado se generaliza bien en diferentes herramientas.
En general, estos resultados confirman que el ajuste fino mejora con éxito tanto la precisión como la corrección estructural de las tareas de identificación de funciones.
El cuaderno completo de Kaggle para este tutorial está disponible en:https://www.kaggle.com/code/kingabzpro/finetuning-functiongemma
Si tienes algún problema, puedes clonar el cuaderno, añadir tu clave secreta de Hugging Face y ejecutarlo de principio a fin.
Reflexiones finales
Si estás intentando entrenar FunctionGemma con conjuntos de datos genéricos para la generación de texto, es mejor que lo dejes cuanto antes. FunctionGemma no está diseñado para comportarse como un modelo de lenguaje de uso general.
Para la generación de texto abierto, el familia de modelos Gemma 3 es una mejor opción.
FunctionGemma está especialmente diseñado para la llamada de funciones, donde el objetivo es seleccionar la herramienta correcta, producir argumentos que cumplan con el esquema e interactuar de forma fiable con sistemas externos como API, bases de datos y servicios.
La pequeña tamaño de FunctionGemma es una elección de diseño deliberada. Con 270 millones de parámetros, está optimizado para implementaciones de baja latencia y eficientes en cuanto a recursos, incluyendo máquinas locales, dispositivos periféricos e infraestructura privada. Esto lo hace muy adecuado para llamadas de funciones en tiempo real y flujos de trabajo agenticos, donde la corrección y la estructura son más importantes que la fluidez del lenguaje.
En este tutorial, hemos aprendido a ajustar FunctionGemma en el conjunto de datos Hermes Reasoning Tool-Use. Una conclusión clave es que la preparación y la evaluación de los datos son más importantes que el tiempo de entrenamiento en bruto.
Mediante una limpieza minuciosa del conjunto de datos, la alineación de las tareas con las llamadas de herramientas de referencia y la aplicación de una estricta coherencia en el esquema, logramos mejorar considerablemente el comportamiento del modelo con un número relativamente pequeño de muestras de alta calidad.
Los resultados muestran claramente el impacto del ajuste fino. La precisión del nombre de la herramienta mejoró del 88 % al 98 %, y la tasa de error de caracteres para bloques de llamadas de función completos se redujo a más de la mitad. Más importante aún, el modelo se volvió mucho más consistente en la producción de llamadas a funciones bien estructuradas y predecibles que se ajustan al uso en el mundo real.