Cách tinh chỉnh FunctionGemma: Hướng dẫn từng bước
Tìm hiểu cách tinh chỉnh FunctionGemma trong chưa đầy 10 phút bằng GPU miễn phí của Kaggle, từ chuẩn bị dữ liệu và đánh giá baseline đến huấn luyện và kiểm định sau tinh chỉnh.
Trong hướng dẫn này, chúng ta sẽ khám phá FunctionGemma, một mô hình ngôn ngữ gọi hàm gọn nhẹ từ Google DeepMind, và tôi sẽ giải thích vì sao tinh chỉnh là điều thiết yếu để đạt độ tin cậy và tuân thủ schema khi dùng công cụ.
Chúng ta sẽ bắt đầu bằng cách thiết lập môi trường Kaggle có GPU, sau đó tải và chuẩn bị cả bộ dữ liệu lẫn mô hình FunctionGemma gốc.
Tiếp theo, chúng ta sẽ thực hiện các đánh giá trước tinh chỉnh để thiết lập đường cơ sở cho việc chọn công cụ và độ chính xác của lệnh gọi hàm. Sau đó, chúng ta sẽ tinh chỉnh FunctionGemma bằng huấn luyện giám sát và đánh giá hiệu năng sau huấn luyện để xác nhận tinh chỉnh đã được áp dụng đúng cách.
FunctionGemma là phiên bản chuyên biệt của mô hình mở Gemma 3 270M của Google, được thiết kế đặc biệt cho việc gọi hàm và sử dụng công cụ thay vì hội thoại chung.
Mô hình dùng cùng kiến trúc với Gemma 3 nhưng bao gồm định dạng và trọng tâm huấn luyện riêng, cho phép tạo đầu ra có cấu trúc đại diện cho các lệnh gọi hàm.
FunctionGemma được phát hành dưới dạng mô hình nền để nhà phát triển có thể tinh chỉnh cho các trường hợp sử dụng cụ thể. Kích thước và thiết kế khiến mô hình nhẹ, hiệu quả và có thể triển khai trên thiết bị tài nguyên hạn chế như laptop và phần cứng biên.
Vì sao cần tinh chỉnh FunctionGemma?
Dù FunctionGemma đã được huấn luyện cho gọi hàm, các mô hình có kích thước này đạt hiệu năng tốt nhất khi được chuyên biệt hóa qua tinh chỉnh trên dữ liệu theo nhiệm vụ.
Tinh chỉnh giúp mô hình học các mẫu ổn định để chọn đúng hàm từ một tập công cụ và định dạng đúng các tham số tương ứng cho các tình huống thực tế.
Quy trình này tạo ra đầu ra có cấu trúc nhất quán và dự đoán được hơn, từ đó cải thiện độ tin cậy trong quy trình làm việc thực tiễn.
Tinh chỉnh FunctionGemma: Hướng dẫn từng bước
Hãy đi qua các bước cần thiết để tinh chỉnh FunctionGemma.
1. Thiết lập môi trường Kaggle
Bắt đầu bằng cách truy cập Kaggle và tạo notebook mới. Khi notebook mở, tìm bảng Session options bên phải và đặt Accelerator thành GPU (T4 ×2).
Thiết lập này kích hoạt tăng tốc GPU cho phiên và cho phép bạn tinh chỉnh mô hình bằng tài nguyên tính toán miễn phí của Kaggle.
Sau khi bật GPU, tạo một ô mã mới và chạy lệnh sau để cài đặt mọi phụ thuộc Python cần thiết. Kernel có thể mất một lúc để khởi động, sau đó các gói sẽ được cài đặt tự động.
Tiếp theo, thêm token truy cập Hugging Face của bạn một cách an toàn.
Từ menu trên cùng, mở Add-ons → Secrets, rồi nhấp Add Secret. Đặt tên secret là HUGGINGFACE_TOKEN và dán khóa API Hugging Face của bạn vào giá trị.
Dùng Kaggle Secrets an toàn hơn so với hard-code biến môi trường hoặc token trực tiếp trong notebook.
Khi secret đã được lưu, Kaggle sẽ cung cấp một đoạn mã để truy cập nó theo chương trình.
Dùng đoạn mã sau để xác thực với 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)Được hỗ trợ bởi
Sau khi xác thực thành công, bạn có thể truy cập các mô hình và bộ dữ liệu bị giới hạn, cũng như đẩy mô hình FunctionGemma đã tinh chỉnh lên Hugging Face Hub để chia sẻ và tái sử dụng.
2. Tải bộ dữ liệu Hermes Reasoning Tool-Use
Bộ dữ liệu Hermes Reasoning Tool-Use là một bộ dữ liệu tiếng Anh mở theo định dạng suy luận dùng công cụ, với các ví dụ có cấu trúc để huấn luyện và đánh giá mô hình trong các tác vụ chọn công cụ và gọi hàm kiểu JSON.
Bộ dữ liệu chứa hàng chục nghìn mẫu suy luận dùng công cụ với lời nhắc ngôn ngữ tự nhiên và schema công cụ theo định dạng phù hợp cho tinh chỉnh có giám sát.
Trong hướng dẫn này, chúng ta sẽ dùng một tập con của bộ dữ liệu để thử nghiệm nhanh hơn.
Đầu tiên, đặt seed ngẫu nhiên và tổng số ví dụ sẽ dùng. Sau đó chia dữ liệu thành tập huấn luyện và đánh giá:
from datasets import load_dataset
SEED =40
N_TOTAL =3000
N_EVAL =300
N_TRAIN = N_TOTAL - N_EVALĐược hỗ trợ bởi
Tiếp theo, tải bộ dữ liệu, xáo trộn và tạo tập train và eval:
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))Được hỗ trợ bởi
Điều này cho bạn 2.700 mẫu huấn luyện và 300 mẫu đánh giá, đủ để minh họa việc tinh chỉnh đồng thời giữ yêu cầu tính toán ở mức có thể quản lý.
4. Chuẩn hóa định nghĩa công cụ và trích xuất lệnh gọi hàm chuẩn
Trước khi tinh chỉnh FunctionGemma, chúng ta cần tiêu chuẩn hóa cách biểu diễn công cụ và trích xuất đáng tin cậy các lệnh gọi hàm đúng (vàng) từ bộ dữ liệu.
Bộ dữ liệu Hermes Reasoning Tool-Use có thể lưu định nghĩa công cụ ở nhiều định dạng, vì vậy bước này chuyển tất cả về một cấu trúc nhất quán có thể dùng cho tinh chỉnh có giám sát.
Chuẩn hóa trường tools
Chúng ta bắt đầu bằng việc chuẩn hóa trường tools. Trong bộ dữ liệu, tools có thể xuất hiện dưới dạng danh sách Python, chuỗi JSON hoặc có thể thiếu hẳn.
Hàm trợ giúp dưới đây chuyển mọi biểu diễn hợp lệ thành một danh sách Python sạch và bỏ qua an toàn các mục sai định dạng hoặc rỗng.
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[]Được hỗ trợ bởi
Chuẩn hóa kiểu tham số
Tiếp theo, chúng ta chuẩn hóa kiểu tham số. Định nghĩa công cụ Hermes thường dùng chú thích kiểu không chính thức như str,int hoặc các kiểu chứa như List[str]. Hàm dưới đây chuyển chúng thành các kiểu JSON Schema hợp lệ, tương thích với gọi hàm trên 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"}Được hỗ trợ bởi
Chuyển công cụ kiểu Hermes sang schema hàm của Hugging Face
Dùng các tiện ích này, chúng ta chuyển định nghĩa công cụ kiểu Hermes thành schema Hugging Face {"type": "function", "function": {...}}. Hàm này hỗ trợ hai định dạng:
Kiểu Hermes theo tham số (mỗi tham số có đặc tả riêng nhỏ)
Công cụ đã gần giống JSON schema
Với định dạng theo tham số, hiện thực này coi các tham số liệt kê là bắt buộc nếu không có danh sách bắt buộc được nêu rõ.
Chúng ta định nghĩa một hàm nhỏ để lấy các schema công cụ đã chuyển đổi cho mỗi ví dụ trong bộ dữ liệu:
defget_tools_hf(ex):return hermes_tools_to_hf_schema(ex.get("tools"))Được hỗ trợ bởi
Trích xuất lệnh gọi hàm chuẩn
Tiếp theo, chúng ta trích xuất lệnh gọi công cụ chuẩn từ hội thoại. Hội thoại Hermes có thể chứa nhiều lượt, nên chúng ta phân tích các khối <tool_call>{...}</tool_call> và lấy đối tượng lệnh gọi công cụ hợp lệ đầu tiên (tên + tham số). Cách này giúp giám sát đơn giản và nhất quán.
Để căn chỉnh lệnh gọi công cụ với tác vụ đúng, chúng ta quét lịch sử hội thoại, tìm tin nhắn người dùng trùng với task của bộ dữ liệu, rồi lấy phản hồi trợ lý ngay sau đó. Nếu phản hồi trợ lý chứa lệnh gọi công cụ, chúng ta trả về nó làm nhãn chuẩn.
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"]:breakreturnNoneĐược hỗ trợ bởi
Kết thúc bước này, mỗi ví dụ dùng được trong bộ dữ liệu có:
Một tập schema công cụ đã chuẩn hóa (định dạng Hugging Face)
Một lệnh gọi hàm chuẩn sạch, căn theo tác vụ
Một cấu trúc nhất quán sẵn sàng để xây dựng mẫu tinh chỉnh có giám sát.
6. Xây dựng mẫu tinh chỉnh có giám sát cho gọi hàm
Giờ chúng ta cần chuyển các thành phần đó thành các mẫu huấn luyện Supervised Fine-Tuning (SFT) đúng định dạng FunctionGemma mong đợi, dùng các hàm trợ giúp ở trên.
Mục tiêu là tạo các ví dụ mà phần đầu vào chứa:
Thông điệp nhà phát triển kích hoạt gọi hàm
Tác vụ người dùng
Khai báo công cụ (schema)
Và mục tiêu là một lệnh gọi FunctionGemma có cấu trúc duy nhất theo định dạng:
<start_function_call>call:TOOL_NAME{args:<escape>{...}<escape>}<end_function_call>Được hỗ trợ bởi
Bước 1: Xây dựng các hàng dữ liệu sạch, dùng được
Chúng ta bắt đầu bằng cách lặp qua bộ dữ liệu và lọc bỏ mọi ví dụ không thể dùng để huấn luyện.
Hàm này chỉ giữ những ví dụ nơi:
Tồn tại lệnh gọi công cụ chuẩn
Tồn tại danh sách công cụ hợp lệ
Tên công cụ chuẩn xuất hiện trong danh sách công cụ
Tham số là một từ điển hợp lệ
Nếu công cụ không có trường bắt buộc, tham số bị ép thành {} để tránh mục tiêu nhiễu hoặc không nhất quán
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 rowsĐược hỗ trợ bởi
Bây giờ chúng ta tạo các hàng huấn luyện và đánh giá:
Trong trường hợp của chúng ta, cuối cùng thu được 961 mẫu huấn luyện và 109 mẫu đánh giá từ 3.000 ban đầu. Mức giảm này là điều mong đợi vì bộ lọc nghiêm ngặt. Nó loại các ví dụ thiếu lệnh gọi công cụ, định nghĩa công cụ không hợp lệ, tên công cụ không khớp hoặc tham số sai cấu trúc.
Bước làm sạch này rất quan trọng. Trước khi áp dụng, bộ dữ liệu chứa nhiều mẫu nhiễu và lệch căn, dẫn tới hành vi gọi hàm thiếu ổn định và kết quả kém ngay cả sau khi tinh chỉnh. Sau khi lọc chỉ còn ví dụ chất lượng cao, căn theo tác vụ, FunctionGemma trở nên nhất quán hơn nhiều và kết quả tinh chỉnh cải thiện đáng kể.
Bước 2: Chuyển mỗi hàng thành một mẫu văn bản huấn luyện
Tiếp theo, chúng ta định dạng mỗi hàng theo đúng cấu trúc prompt + mục tiêu mà FunctionGemma cần. Chúng ta dùng apply_chat_template của processor để chèn khai báo công cụ chính xác, rồi nối thêm lệnh gọi hàm chuẩn làm mục tiêu.
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 + targetĐược hỗ trợ bởi
Giờ hãy chuyển các hàng thành đối tượng Dataset của 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])Được hỗ trợ bởi
Bước 3: Đảm bảo mọi mẫu là chuỗi hợp lệ
Một số phiên bản TRL yêu cầu formatting_func trả về chuỗi, và việc huấn luyện có thể lỗi nếu bất kỳ mẫu nào trở thành danh sách hoặc giá trị không phải chuỗi. Trình trợ giúp này buộc text luôn là chuỗi sạch.
# 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)Được hỗ trợ bởi
Bạn sẽ thấy một prompt đã render đầy đủ chứa khai báo công cụ, theo sau là lệnh gọi hàm chuẩn tương tự như:
<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>Được hỗ trợ bởi
7. Đánh giá FunctionGemma trước khi tinh chỉnh
Trước khi huấn luyện, bạn nên đo xem mô hình FunctionGemma gốc thực hiện gọi hàm tốt đến đâu. Đường cơ sở này giúp bạn xác nhận rằng tinh chỉnh thực sự cải thiện việc chọn công cụ và định dạng lệnh gọi hàm.
Trong phần này, chúng ta đánh giá hai thứ:
Độ chính xác tên công cụ: liệu mô hình chọn đúng tên hàm hay không
TC-CER (Tool-Call Character Error Rate): mức độ khớp giữa khối lệnh gọi hàm được tạo với khối chuẩn, càng thấp càng tốt
Chúng ta dùng hai biểu thức chính quy để trích xuất tên công cụ dự đoán và toàn bộ khối lệnh gọi hàm từ đầu ra của mô hình, rồi so sánh với nhãn chuẩn.
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>")Được hỗ trợ bởi
Vòng lặp đánh giá đường cơ sở
Hàm dưới đây chạy suy luận trên một tập con ví dụ đánh giá và tính cả hai chỉ số. Chúng ta tắt sampling (do_sample=False) để kết quả có tính quyết định và dễ so sánh trước và sau tinh chỉnh.
@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),}Được hỗ trợ bởi
Ngay cả trước khi tinh chỉnh, FunctionGemma cũng cho thấy hiệu năng cơ sở mạnh ở tác vụ này.
Trên một tập 50 ví dụ đánh giá, mô hình đạt 88% độ chính xác tên công cụ, nghĩa là chọn đúng hàm trong đa số trường hợp.
Ngoài ra, Tool-Call Character Error Rate (TC-CER) xấp xỉ 33% cho toàn bộ khối lệnh gọi hàm, cho thấy dù thường chọn đúng công cụ, các tham số và định dạng sinh ra vẫn lệch so với mục tiêu chuẩn.
PRE metrics:{'n_eval':50,'tool_accuracy':0.88,'TC-CER (lower is better)':0.33399307273626916}Được hỗ trợ bởi
Những kết quả này xác nhận mô hình FunctionGemma gốc đã hiểu cơ chế gọi hàm.
Tuy nhiên, tỷ lệ lỗi ký tự tương đối cao nhấn mạnh nhu cầu tinh chỉnh để cải thiện độ đầy đủ tham số, tính nhất quán định dạng và độ đúng cấu trúc tổng thể của lệnh gọi hàm sinh ra.
Xem xét một dự đoán đơn lẻ
Chỉ số rất hữu ích, nhưng cũng quan trọng là xem xét chất lượng đầu ra. Hàm trợ giúp dưới đây chạy suy luận cho một ví dụ và in lệnh gọi hàm dự đoán cạnh tham chiếu chuẩn.
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),}Được hỗ trợ bởi
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>Được hỗ trợ bởi
Trong ví dụ này, mô hình chọn đúng hàm phù hợp, nên tool match là True.
Tuy nhiên, lệnh gọi sinh ra bao gồm tham số thừa và không theo đúng cấu trúc mục tiêu dùng trong huấn luyện.
Dù các tham số này hợp lý về ngữ nghĩa, chúng không khớp định dạng lệnh gọi hàm chuẩn, góp phần làm tỷ lệ lỗi ký tự cao hơn. Điều này minh họa vì sao cần tinh chỉnh để cải thiện tính nhất quán cấu trúc và tuân thủ schema, không chỉ là chọn công cụ.
8. Thiết lập trainer cho mô hình để tinh chỉnh
Giờ chúng ta đã có các bộ dữ liệu SFT sạch, bước tiếp theo là cấu hình trainer để tinh chỉnh FunctionGemma. Chúng ta dùng SFTTrainer của TRL, một cách nhẹ và tin cậy để tinh chỉnh các mô hình kiểu chat trên ví dụ văn bản.
Chúng ta cũng đặt thư mục đầu ra để Kaggle lưu checkpoint đã tinh chỉnh vào vị trí lưu trữ bền vững.
from trl import SFTConfig, SFTTrainer
OUT_DIR ="/kaggle/working/functiongemma-hermes-ft"Được hỗ trợ bởi
Để giảm sử dụng VRAM trong huấn luyện, chúng ta bật gradient checkpointing và tắt KV cache.
# VRAM savings
model.gradient_checkpointing_enable()
model.config.use_cache =FalseĐược hỗ trợ bởi
Cấu hình trainer
Chúng ta định nghĩa cấu hình huấn luyện bằng SFTConfig. Các thiết lập này cân bằng ổn định và hiệu quả trên GPU Kaggle, đồng thời giữ thời gian huấn luyện ngắn.
Hàm định dạng đảm bảo mỗi ví dụ huấn luyện được trả về dưới dạng một chuỗi, điều mà phiên bản TRL hiện tại yêu cầu.
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)Được hỗ trợ bởi
Khởi tạo trainer
Cuối cùng, chúng ta khởi tạo SFTTrainer với mô hình, cấu hình, bộ dữ liệu và tokenizer.
Khi trainer đã được cấu hình, chúng ta có thể bắt đầu tinh chỉnh mô hình. Bước này chạy huấn luyện có giám sát trên bộ dữ liệu đã chuẩn bị và đánh giá mô hình định kỳ trong quá trình huấn luyện.
trainer.train()
trainer.save_model(OUT_DIR)
processor.save_pretrained(OUT_DIR)print("Saved to:", OUT_DIR)Được hỗ trợ bởi
Sau khi huấn luyện hoàn tất, chúng ta lưu cả mô hình đã tinh chỉnh và processor vào thư mục đầu ra để có thể tái sử dụng cho suy luận hoặc tải lên Hugging Face Hub.
Trong quá trình huấn luyện, cả loss huấn luyện và loss xác thực đều giảm đều. Độ chính xác trung bình theo token cũng cải thiện theo thời gian, cho thấy mô hình đã học cách tạo đầu ra lệnh gọi hàm chính xác và nhất quán hơn.
Xuất bản mô hình FunctionGemma đã tinh chỉnh lên Hugging Face
Khi tinh chỉnh hoàn tất, chúng ta có thể xuất bản mô hình để dễ dàng tái sử dụng, chia sẻ hoặc triển khai. Đẩy mô hình lên Hugging Face Hub cho phép người khác tải trực tiếp bằng API Transformers tiêu chuẩn.
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)Được hỗ trợ bởi
Sau khi tải lên hoàn tất, mô hình tinh chỉnh có sẵn công khai trên Hugging Face:
Pushed to: kingabzpro/functiongemma-hermes-3k-ftĐược hỗ trợ bởi
Sau khi tinh chỉnh xong, chúng ta tải lại mô hình và processor đã lưu từ đĩa và chạy cùng pipeline đánh giá như trước khi huấn luyện. Điều này đảm bảo so sánh trước và sau tinh chỉnh là công bằng và nhất quán.
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")Được hỗ trợ bởi
Sau đó, chúng ta đánh giá mô hình đã tinh chỉnh trên tập đánh giá bằng độ chính xác tên công cụ và TC-CER.
Kết quả cho thấy cải thiện rõ rệt so với đường cơ sở:
POST metrics:{'n_eval':50,'tool_accuracy':0.98,'TC-CER (lower is better)':0.1454725383473528}Được hỗ trợ bởi
Độ chính xác tên công cụ tăng từ 88 phần trăm lên 98 phần trăm, và tỷ lệ lỗi ký tự cho toàn bộ khối lệnh gọi hàm giảm hơn một nửa. Điều này cho thấy mô hình không chỉ chọn công cụ đúng đáng tin cậy hơn mà còn tạo đầu ra khớp với schema mục tiêu sát hơn.
Để hiểu rõ hơn những cải thiện, chúng ta xem xét các dự đoán riêng lẻ. Trong ví dụ dưới đây, mô hình chọn đúng hàm và tạo lệnh gọi có cấu trúc tốt với tham số đầy đủ hơn.
Dù lệnh gọi dự đoán có thể bao gồm thêm tham số vượt quá mục tiêu chuẩn, cấu trúc tổng thể và định dạng tham số nhất quán hơn nhiều so với trước tinh chỉnh. Điều này phản ánh nhận thức schema tốt hơn và sự liên kết chặt chẽ hơn giữa ý định người dùng và lệnh gọi hàm được tạo.
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>Được hỗ trợ bởi
Ví dụ thứ hai cho thấy một lệnh gọi hàm sạch và đúng cho tác vụ trích xuất URL, chứng minh mô hình đã tinh chỉnh khái quát hóa tốt trên các công cụ khác nhau.
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>Được hỗ trợ bởi
Tổng thể, các kết quả này xác nhận rằng tinh chỉnh đã cải thiện thành công cả độ chính xác và độ đúng cấu trúc cho các tác vụ gọi hàm.
Nếu bạn gặp sự cố, bạn có thể sao chép notebook, thêm secret Hugging Face và chạy toàn bộ đầu-cuối.
Kết luận
Nếu bạn đang cố huấn luyện FunctionGemma trên các bộ dữ liệu sinh văn bản tổng quát, tốt nhất nên dừng sớm. FunctionGemma không được thiết kế để hoạt động như một mô hình ngôn ngữ mục đích chung.
Đối với sinh văn bản mở, họ mô hình Gemma 3 là lựa chọn tốt hơn.
FunctionGemma được xây dựng có chủ đích cho gọi hàm, nơi mục tiêu là chọn đúng công cụ, tạo tham số tuân theo schema và tương tác đáng tin cậy với các hệ thống bên ngoài như API, cơ sở dữ liệu và dịch vụ.
Kích thước nhỏ của FunctionGemma là lựa chọn thiết kế có chủ đích. Với 270 triệu tham số, mô hình được tối ưu cho độ trễ thấp, hiệu quả tài nguyên, bao gồm máy cục bộ, thiết bị biên và hạ tầng riêng. Điều này khiến nó phù hợp cho gọi hàm thời gian thực và các quy trình tác tử, nơi tính đúng đắn và cấu trúc quan trọng hơn văn phong trôi chảy.
Trong hướng dẫn này, chúng ta đã học cách tinh chỉnh FunctionGemma trên bộ dữ liệu Hermes Reasoning Tool-Use. Bài học chính là chuẩn bị dữ liệu và đánh giá quan trọng hơn thời gian huấn luyện thuần túy.
Bằng cách làm sạch cẩn thận bộ dữ liệu, căn tác vụ với lệnh gọi công cụ chuẩn và áp đặt tính nhất quán schema nghiêm ngặt, chúng ta có thể cải thiện mạnh mẽ hành vi mô hình với số lượng mẫu chất lượng cao tương đối nhỏ.
Kết quả cho thấy rõ tác động của tinh chỉnh. Độ chính xác tên công cụ tăng từ 88 phần trăm lên 98 phần trăm, và tỷ lệ lỗi ký tự cho toàn bộ khối lệnh gọi hàm giảm hơn một nửa. Quan trọng hơn, mô hình trở nên nhất quán hơn nhiều trong việc tạo các lệnh gọi hàm có cấu trúc tốt, dự đoán được và phù hợp với cách dùng thực tế.
Câu hỏi thường gặp về FunctionGemma
FunctionGemma là gì và khác gì so với Gemma 3?⌄
FunctionGemma là phiên bản chuyên biệt của mô hình mở Gemma 3 270M. Trong khi Gemma 3 tiêu chuẩn được thiết kế cho sinh văn bản, FunctionGemma được huấn luyện rõ ràng để chuyển ngôn ngữ tự nhiên thành các lệnh gọi hàm có cấu trúc (yêu cầu API), biến nó thành một "bộ định tuyến" dành riêng cho các quy trình tác tử thay vì chatbot hội thoại.
hat hardware do I need to run FunctionGemma?⌄
Vì là mô hình 270M tham số, FunctionGemma cực kỳ gọn nhẹ (~300MB khi lượng tử hóa). Nó có thể chạy hiệu quả trên thiết bị biên như laptop, điện thoại di động và phần cứng nhúng (ví dụ NVIDIA Jetson Nano) mà không cần GPU đám mây chuyên dụng.
Vì sao tôi cần tinh chỉnh FunctionGemma nếu nó đã chuyên biệt?⌄
Dù mô hình nền hiểu khái niệm sử dụng công cụ, tinh chỉnh là cần thiết để dạy cho nó schema API và logic nghiệp vụ cụ thể của bạn. Các benchmark của Google cho thấy tinh chỉnh có thể tăng độ chính xác gọi hàm từ ~58% (mô hình nền) lên hơn 85% trên các tác vụ theo miền.
FunctionGemma có xử lý hội thoại nhiều lượt không?⌄
FunctionGemma được tối ưu chủ yếu cho thực thi lệnh một lượt (Chỉ dẫn người dùng → Gọi công cụ). Với suy luận đa lượt phức tạp hoặc duy trì lịch sử hội thoại dài, tốt nhất dùng nó như một "bộ điều phối" để chuyển câu hỏi khó cho mô hình lớn hơn (như Gemma 3 27B) trong khi xử lý các hành động đơn giản tại chỗ.
Là một nhà khoa học dữ liệu được chứng nhận, tôi đam mê tận dụng công nghệ tiên tiến để tạo ra các ứng dụng học máy đổi mới. Với nền tảng vững chắc về nhận dạng giọng nói, phân tích và báo cáo dữ liệu, MLOps, AI hội thoại và NLP, tôi đã rèn giũa kỹ năng phát triển các hệ thống thông minh có thể tạo ra tác động thực sự. Bên cạnh chuyên môn kỹ thuật, tôi cũng là một người truyền đạt tốt, có khả năng chắt lọc các khái niệm phức tạp thành ngôn ngữ rõ ràng, súc tích. Nhờ đó, tôi trở thành một blogger được nhiều người quan tâm trong lĩnh vực khoa học dữ liệu, chia sẻ góc nhìn và kinh nghiệm với cộng đồng các chuyên gia dữ liệu ngày càng lớn. Hiện tại, tôi tập trung vào sáng tạo và biên tập nội dung, làm việc với các mô hình ngôn ngữ lớn để phát triển nội dung mạnh mẽ và hấp dẫn, giúp doanh nghiệp và cá nhân tận dụng tối đa dữ liệu của mình.
Trong hướng dẫn này, chúng ta sẽ khám phá FunctionGemma, một mô hình ngôn ngữ gọi hàm gọn nhẹ từ Google DeepMind, và tôi sẽ giải thích vì sao tinh chỉnh là điều thiết yếu để đạt độ tin cậy và tuân thủ schema khi dùng công cụ.
Chúng ta sẽ bắt đầu bằng cách thiết lập môi trường Kaggle có GPU, sau đó tải và chuẩn bị cả bộ dữ liệu lẫn mô hình FunctionGemma gốc.
Tiếp theo, chúng ta sẽ thực hiện các đánh giá trước tinh chỉnh để thiết lập đường cơ sở cho việc chọn công cụ và độ chính xác của lệnh gọi hàm. Sau đó, chúng ta sẽ tinh chỉnh FunctionGemma bằng huấn luyện giám sát và đánh giá hiệu năng sau huấn luyện để xác nhận tinh chỉnh đã được áp dụng đúng cách.
Nếu bạn muốn có các bài tập thực hành để học tinh chỉnh, tôi khuyến nghị xem khóa học Fine-Tuning with Llama 3.
FunctionGemma là gì?
FunctionGemma là phiên bản chuyên biệt của mô hình mở Gemma 3 270M của Google, được thiết kế đặc biệt cho việc gọi hàm và sử dụng công cụ thay vì hội thoại chung.
Mô hình dùng cùng kiến trúc với Gemma 3 nhưng bao gồm định dạng và trọng tâm huấn luyện riêng, cho phép tạo đầu ra có cấu trúc đại diện cho các lệnh gọi hàm.
FunctionGemma được phát hành dưới dạng mô hình nền để nhà phát triển có thể tinh chỉnh cho các trường hợp sử dụng cụ thể. Kích thước và thiết kế khiến mô hình nhẹ, hiệu quả và có thể triển khai trên thiết bị tài nguyên hạn chế như laptop và phần cứng biên.
Vì sao cần tinh chỉnh FunctionGemma?
Dù FunctionGemma đã được huấn luyện cho gọi hàm, các mô hình có kích thước này đạt hiệu năng tốt nhất khi được chuyên biệt hóa qua tinh chỉnh trên dữ liệu theo nhiệm vụ.
Tinh chỉnh giúp mô hình học các mẫu ổn định để chọn đúng hàm từ một tập công cụ và định dạng đúng các tham số tương ứng cho các tình huống thực tế.
Quy trình này tạo ra đầu ra có cấu trúc nhất quán và dự đoán được hơn, từ đó cải thiện độ tin cậy trong quy trình làm việc thực tiễn.
Tinh chỉnh FunctionGemma: Hướng dẫn từng bước
Hãy đi qua các bước cần thiết để tinh chỉnh FunctionGemma.
1. Thiết lập môi trường Kaggle
Bắt đầu bằng cách truy cập Kaggle và tạo notebook mới. Khi notebook mở, tìm bảng Session options bên phải và đặt Accelerator thành GPU (T4 ×2).
Thiết lập này kích hoạt tăng tốc GPU cho phiên và cho phép bạn tinh chỉnh mô hình bằng tài nguyên tính toán miễn phí của Kaggle.
Sau khi bật GPU, tạo một ô mã mới và chạy lệnh sau để cài đặt mọi phụ thuộc Python cần thiết. Kernel có thể mất một lúc để khởi động, sau đó các gói sẽ được cài đặt tự động.
Tiếp theo, thêm token truy cập Hugging Face của bạn một cách an toàn.
Từ menu trên cùng, mở Add-ons → Secrets, rồi nhấp Add Secret. Đặt tên secret là
HUGGINGFACE_TOKENvà dán khóa API Hugging Face của bạn vào giá trị.Dùng Kaggle Secrets an toàn hơn so với hard-code biến môi trường hoặc token trực tiếp trong notebook.
Khi secret đã được lưu, Kaggle sẽ cung cấp một đoạn mã để truy cập nó theo chương trình.
Dùng đoạn mã sau để xác thực với Hugging Face Hub:
Sau khi xác thực thành công, bạn có thể truy cập các mô hình và bộ dữ liệu bị giới hạn, cũng như đẩy mô hình FunctionGemma đã tinh chỉnh lên Hugging Face Hub để chia sẻ và tái sử dụng.
2. Tải bộ dữ liệu Hermes Reasoning Tool-Use
Bộ dữ liệu Hermes Reasoning Tool-Use là một bộ dữ liệu tiếng Anh mở theo định dạng suy luận dùng công cụ, với các ví dụ có cấu trúc để huấn luyện và đánh giá mô hình trong các tác vụ chọn công cụ và gọi hàm kiểu JSON.
Bộ dữ liệu chứa hàng chục nghìn mẫu suy luận dùng công cụ với lời nhắc ngôn ngữ tự nhiên và schema công cụ theo định dạng phù hợp cho tinh chỉnh có giám sát.
Trong hướng dẫn này, chúng ta sẽ dùng một tập con của bộ dữ liệu để thử nghiệm nhanh hơn.
Đầu tiên, đặt seed ngẫu nhiên và tổng số ví dụ sẽ dùng. Sau đó chia dữ liệu thành tập huấn luyện và đánh giá:
Tiếp theo, tải bộ dữ liệu, xáo trộn và tạo tập train và eval:
Điều này cho bạn 2.700 mẫu huấn luyện và 300 mẫu đánh giá, đủ để minh họa việc tinh chỉnh đồng thời giữ yêu cầu tính toán ở mức có thể quản lý.
3. Tải mô hình và processor FunctionGemma
Trong hướng dẫn này, chúng ta dùng KaggleHub để tải mô hình FunctionGemma trực tiếp vào notebook Kaggle.
KaggleHub tự động xác định vị trí mô hình và đưa nó vào môi trường notebook, loại bỏ nhu cầu tải thủ công từ Hugging Face.
Sau khi chạy ô trên, các tệp mô hình sẽ xuất hiện trong phần Input của notebook Kaggle, xác nhận rằng mô hình đã được tải thành công và có sẵn cục bộ.
Khi mô hình sẵn sàng, chúng ta tải cả processor và mô hình vào bộ nhớ GPU.
Processor xử lý template trò chuyện và định dạng schema công cụ, còn mô hình chịu trách nhiệm tạo các lệnh gọi hàm có cấu trúc.
Thiết lập
device_map="auto"đảm bảo mô hình được đặt trên GPU sẵn có, vàdtype="auto"chọn độ chính xác hiệu quả do phần cứng hỗ trợ.Điều này xác nhận FunctionGemma được tải đúng, đặt trên GPU và sẵn sàng để đánh giá và tinh chỉnh.
4. Chuẩn hóa định nghĩa công cụ và trích xuất lệnh gọi hàm chuẩn
Trước khi tinh chỉnh FunctionGemma, chúng ta cần tiêu chuẩn hóa cách biểu diễn công cụ và trích xuất đáng tin cậy các lệnh gọi hàm đúng (vàng) từ bộ dữ liệu.
Bộ dữ liệu Hermes Reasoning Tool-Use có thể lưu định nghĩa công cụ ở nhiều định dạng, vì vậy bước này chuyển tất cả về một cấu trúc nhất quán có thể dùng cho tinh chỉnh có giám sát.
Chuẩn hóa trường tools
Chúng ta bắt đầu bằng việc chuẩn hóa trường
tools. Trong bộ dữ liệu,toolscó thể xuất hiện dưới dạng danh sách Python, chuỗi JSON hoặc có thể thiếu hẳn.Hàm trợ giúp dưới đây chuyển mọi biểu diễn hợp lệ thành một danh sách Python sạch và bỏ qua an toàn các mục sai định dạng hoặc rỗng.
Chuẩn hóa kiểu tham số
Tiếp theo, chúng ta chuẩn hóa kiểu tham số. Định nghĩa công cụ Hermes thường dùng chú thích kiểu không chính thức như
str,inthoặc các kiểu chứa nhưList[str]. Hàm dưới đây chuyển chúng thành các kiểu JSON Schema hợp lệ, tương thích với gọi hàm trên Hugging Face.Chuyển công cụ kiểu Hermes sang schema hàm của Hugging Face
Dùng các tiện ích này, chúng ta chuyển định nghĩa công cụ kiểu Hermes thành schema Hugging Face
{"type": "function", "function": {...}}. Hàm này hỗ trợ hai định dạng:Với định dạng theo tham số, hiện thực này coi các tham số liệt kê là bắt buộc nếu không có danh sách bắt buộc được nêu rõ.
Hàm trợ giúp
Chúng ta định nghĩa một hàm nhỏ để lấy các schema công cụ đã chuyển đổi cho mỗi ví dụ trong bộ dữ liệu:
Trích xuất lệnh gọi hàm chuẩn
Tiếp theo, chúng ta trích xuất lệnh gọi công cụ chuẩn từ hội thoại. Hội thoại Hermes có thể chứa nhiều lượt, nên chúng ta phân tích các khối
<tool_call>{...}</tool_call>và lấy đối tượng lệnh gọi công cụ hợp lệ đầu tiên (tên + tham số). Cách này giúp giám sát đơn giản và nhất quán.Căn chỉnh lệnh gọi công cụ với tác vụ người dùng
Để căn chỉnh lệnh gọi công cụ với tác vụ đúng, chúng ta quét lịch sử hội thoại, tìm tin nhắn người dùng trùng với
taskcủa bộ dữ liệu, rồi lấy phản hồi trợ lý ngay sau đó. Nếu phản hồi trợ lý chứa lệnh gọi công cụ, chúng ta trả về nó làm nhãn chuẩn.Kết thúc bước này, mỗi ví dụ dùng được trong bộ dữ liệu có:
6. Xây dựng mẫu tinh chỉnh có giám sát cho gọi hàm
Giờ chúng ta cần chuyển các thành phần đó thành các mẫu huấn luyện Supervised Fine-Tuning (SFT) đúng định dạng FunctionGemma mong đợi, dùng các hàm trợ giúp ở trên.
Mục tiêu là tạo các ví dụ mà phần đầu vào chứa:
Và mục tiêu là một lệnh gọi FunctionGemma có cấu trúc duy nhất theo định dạng:
Bước 1: Xây dựng các hàng dữ liệu sạch, dùng được
Chúng ta bắt đầu bằng cách lặp qua bộ dữ liệu và lọc bỏ mọi ví dụ không thể dùng để huấn luyện.
Hàm này chỉ giữ những ví dụ nơi:
Bây giờ chúng ta tạo các hàng huấn luyện và đánh giá:
Trong trường hợp của chúng ta, cuối cùng thu được 961 mẫu huấn luyện và 109 mẫu đánh giá từ 3.000 ban đầu. Mức giảm này là điều mong đợi vì bộ lọc nghiêm ngặt. Nó loại các ví dụ thiếu lệnh gọi công cụ, định nghĩa công cụ không hợp lệ, tên công cụ không khớp hoặc tham số sai cấu trúc.
Bước làm sạch này rất quan trọng. Trước khi áp dụng, bộ dữ liệu chứa nhiều mẫu nhiễu và lệch căn, dẫn tới hành vi gọi hàm thiếu ổn định và kết quả kém ngay cả sau khi tinh chỉnh. Sau khi lọc chỉ còn ví dụ chất lượng cao, căn theo tác vụ, FunctionGemma trở nên nhất quán hơn nhiều và kết quả tinh chỉnh cải thiện đáng kể.
Bước 2: Chuyển mỗi hàng thành một mẫu văn bản huấn luyện
Tiếp theo, chúng ta định dạng mỗi hàng theo đúng cấu trúc prompt + mục tiêu mà FunctionGemma cần. Chúng ta dùng
apply_chat_templatecủa processor để chèn khai báo công cụ chính xác, rồi nối thêm lệnh gọi hàm chuẩn làm mục tiêu.Giờ hãy chuyển các hàng thành đối tượng Dataset của Hugging Face:
Bước 3: Đảm bảo mọi mẫu là chuỗi hợp lệ
Một số phiên bản TRL yêu cầu
formatting_functrả về chuỗi, và việc huấn luyện có thể lỗi nếu bất kỳ mẫu nào trở thành danh sách hoặc giá trị không phải chuỗi. Trình trợ giúp này buộctextluôn là chuỗi sạch.Cuối cùng, in một mẫu để xác nhận định dạng:
Bạn sẽ thấy một prompt đã render đầy đủ chứa khai báo công cụ, theo sau là lệnh gọi hàm chuẩn tương tự như:
7. Đánh giá FunctionGemma trước khi tinh chỉnh
Trước khi huấn luyện, bạn nên đo xem mô hình FunctionGemma gốc thực hiện gọi hàm tốt đến đâu. Đường cơ sở này giúp bạn xác nhận rằng tinh chỉnh thực sự cải thiện việc chọn công cụ và định dạng lệnh gọi hàm.
Trong phần này, chúng ta đánh giá hai thứ:
Chúng ta dùng hai biểu thức chính quy để trích xuất tên công cụ dự đoán và toàn bộ khối lệnh gọi hàm từ đầu ra của mô hình, rồi so sánh với nhãn chuẩn.
Vòng lặp đánh giá đường cơ sở
Hàm dưới đây chạy suy luận trên một tập con ví dụ đánh giá và tính cả hai chỉ số. Chúng ta tắt sampling (
do_sample=False) để kết quả có tính quyết định và dễ so sánh trước và sau tinh chỉnh.Chạy đánh giá đường cơ sở:
Ngay cả trước khi tinh chỉnh, FunctionGemma cũng cho thấy hiệu năng cơ sở mạnh ở tác vụ này.
Trên một tập 50 ví dụ đánh giá, mô hình đạt 88% độ chính xác tên công cụ, nghĩa là chọn đúng hàm trong đa số trường hợp.
Ngoài ra, Tool-Call Character Error Rate (TC-CER) xấp xỉ 33% cho toàn bộ khối lệnh gọi hàm, cho thấy dù thường chọn đúng công cụ, các tham số và định dạng sinh ra vẫn lệch so với mục tiêu chuẩn.
Những kết quả này xác nhận mô hình FunctionGemma gốc đã hiểu cơ chế gọi hàm.
Tuy nhiên, tỷ lệ lỗi ký tự tương đối cao nhấn mạnh nhu cầu tinh chỉnh để cải thiện độ đầy đủ tham số, tính nhất quán định dạng và độ đúng cấu trúc tổng thể của lệnh gọi hàm sinh ra.
Xem xét một dự đoán đơn lẻ
Chỉ số rất hữu ích, nhưng cũng quan trọng là xem xét chất lượng đầu ra. Hàm trợ giúp dưới đây chạy suy luận cho một ví dụ và in lệnh gọi hàm dự đoán cạnh tham chiếu chuẩn.
Chạy trên một ví dụ:
Đầu ra:
Trong ví dụ này, mô hình chọn đúng hàm phù hợp, nên tool match là True.
Tuy nhiên, lệnh gọi sinh ra bao gồm tham số thừa và không theo đúng cấu trúc mục tiêu dùng trong huấn luyện.
Dù các tham số này hợp lý về ngữ nghĩa, chúng không khớp định dạng lệnh gọi hàm chuẩn, góp phần làm tỷ lệ lỗi ký tự cao hơn. Điều này minh họa vì sao cần tinh chỉnh để cải thiện tính nhất quán cấu trúc và tuân thủ schema, không chỉ là chọn công cụ.
8. Thiết lập trainer cho mô hình để tinh chỉnh
Giờ chúng ta đã có các bộ dữ liệu SFT sạch, bước tiếp theo là cấu hình trainer để tinh chỉnh FunctionGemma. Chúng ta dùng
SFTTrainercủa TRL, một cách nhẹ và tin cậy để tinh chỉnh các mô hình kiểu chat trên ví dụ văn bản.Chúng ta cũng đặt thư mục đầu ra để Kaggle lưu checkpoint đã tinh chỉnh vào vị trí lưu trữ bền vững.
Để giảm sử dụng VRAM trong huấn luyện, chúng ta bật gradient checkpointing và tắt KV cache.
Cấu hình trainer
Chúng ta định nghĩa cấu hình huấn luyện bằng SFTConfig. Các thiết lập này cân bằng ổn định và hiệu quả trên GPU Kaggle, đồng thời giữ thời gian huấn luyện ngắn.
Hàm định dạng đảm bảo mỗi ví dụ huấn luyện được trả về dưới dạng một chuỗi, điều mà phiên bản TRL hiện tại yêu cầu.
Khởi tạo trainer
Cuối cùng, chúng ta khởi tạo
SFTTrainervới mô hình, cấu hình, bộ dữ liệu và tokenizer.9. Tinh chỉnh FunctionGemma
Khi trainer đã được cấu hình, chúng ta có thể bắt đầu tinh chỉnh mô hình. Bước này chạy huấn luyện có giám sát trên bộ dữ liệu đã chuẩn bị và đánh giá mô hình định kỳ trong quá trình huấn luyện.
Sau khi huấn luyện hoàn tất, chúng ta lưu cả mô hình đã tinh chỉnh và processor vào thư mục đầu ra để có thể tái sử dụng cho suy luận hoặc tải lên Hugging Face Hub.
Trong quá trình huấn luyện, cả loss huấn luyện và loss xác thực đều giảm đều. Độ chính xác trung bình theo token cũng cải thiện theo thời gian, cho thấy mô hình đã học cách tạo đầu ra lệnh gọi hàm chính xác và nhất quán hơn.
Xuất bản mô hình FunctionGemma đã tinh chỉnh lên Hugging Face
Khi tinh chỉnh hoàn tất, chúng ta có thể xuất bản mô hình để dễ dàng tái sử dụng, chia sẻ hoặc triển khai. Đẩy mô hình lên Hugging Face Hub cho phép người khác tải trực tiếp bằng API Transformers tiêu chuẩn.
Sau khi tải lên hoàn tất, mô hình tinh chỉnh có sẵn công khai trên Hugging Face:
Nguồn: kingabzpro/functiongemma-hermes-3k-ft · Hugging Face
Đánh giá sau tinh chỉnh và phân tích lỗi
Sau khi tinh chỉnh xong, chúng ta tải lại mô hình và processor đã lưu từ đĩa và chạy cùng pipeline đánh giá như trước khi huấn luyện. Điều này đảm bảo so sánh trước và sau tinh chỉnh là công bằng và nhất quán.
Sau đó, chúng ta đánh giá mô hình đã tinh chỉnh trên tập đánh giá bằng độ chính xác tên công cụ và TC-CER.
Kết quả cho thấy cải thiện rõ rệt so với đường cơ sở:
Độ chính xác tên công cụ tăng từ 88 phần trăm lên 98 phần trăm, và tỷ lệ lỗi ký tự cho toàn bộ khối lệnh gọi hàm giảm hơn một nửa. Điều này cho thấy mô hình không chỉ chọn công cụ đúng đáng tin cậy hơn mà còn tạo đầu ra khớp với schema mục tiêu sát hơn.
Để hiểu rõ hơn những cải thiện, chúng ta xem xét các dự đoán riêng lẻ. Trong ví dụ dưới đây, mô hình chọn đúng hàm và tạo lệnh gọi có cấu trúc tốt với tham số đầy đủ hơn.
Dù lệnh gọi dự đoán có thể bao gồm thêm tham số vượt quá mục tiêu chuẩn, cấu trúc tổng thể và định dạng tham số nhất quán hơn nhiều so với trước tinh chỉnh. Điều này phản ánh nhận thức schema tốt hơn và sự liên kết chặt chẽ hơn giữa ý định người dùng và lệnh gọi hàm được tạo.
Hãy xem thêm một mẫu khác.
Ví dụ thứ hai cho thấy một lệnh gọi hàm sạch và đúng cho tác vụ trích xuất URL, chứng minh mô hình đã tinh chỉnh khái quát hóa tốt trên các công cụ khác nhau.
Tổng thể, các kết quả này xác nhận rằng tinh chỉnh đã cải thiện thành công cả độ chính xác và độ đúng cấu trúc cho các tác vụ gọi hàm.
Toàn bộ notebook Kaggle cho hướng dẫn này có tại:https://www.kaggle.com/code/kingabzpro/finetuning-functiongemma
Nếu bạn gặp sự cố, bạn có thể sao chép notebook, thêm secret Hugging Face và chạy toàn bộ đầu-cuối.
Kết luận
Nếu bạn đang cố huấn luyện FunctionGemma trên các bộ dữ liệu sinh văn bản tổng quát, tốt nhất nên dừng sớm. FunctionGemma không được thiết kế để hoạt động như một mô hình ngôn ngữ mục đích chung.
Đối với sinh văn bản mở, họ mô hình Gemma 3 là lựa chọn tốt hơn.
FunctionGemma được xây dựng có chủ đích cho gọi hàm, nơi mục tiêu là chọn đúng công cụ, tạo tham số tuân theo schema và tương tác đáng tin cậy với các hệ thống bên ngoài như API, cơ sở dữ liệu và dịch vụ.
Kích thước nhỏ của FunctionGemma là lựa chọn thiết kế có chủ đích. Với 270 triệu tham số, mô hình được tối ưu cho độ trễ thấp, hiệu quả tài nguyên, bao gồm máy cục bộ, thiết bị biên và hạ tầng riêng. Điều này khiến nó phù hợp cho gọi hàm thời gian thực và các quy trình tác tử, nơi tính đúng đắn và cấu trúc quan trọng hơn văn phong trôi chảy.
Trong hướng dẫn này, chúng ta đã học cách tinh chỉnh FunctionGemma trên bộ dữ liệu Hermes Reasoning Tool-Use. Bài học chính là chuẩn bị dữ liệu và đánh giá quan trọng hơn thời gian huấn luyện thuần túy.
Bằng cách làm sạch cẩn thận bộ dữ liệu, căn tác vụ với lệnh gọi công cụ chuẩn và áp đặt tính nhất quán schema nghiêm ngặt, chúng ta có thể cải thiện mạnh mẽ hành vi mô hình với số lượng mẫu chất lượng cao tương đối nhỏ.
Kết quả cho thấy rõ tác động của tinh chỉnh. Độ chính xác tên công cụ tăng từ 88 phần trăm lên 98 phần trăm, và tỷ lệ lỗi ký tự cho toàn bộ khối lệnh gọi hàm giảm hơn một nửa. Quan trọng hơn, mô hình trở nên nhất quán hơn nhiều trong việc tạo các lệnh gọi hàm có cấu trúc tốt, dự đoán được và phù hợp với cách dùng thực tế.