|
|
التشغيل في Google Colab
|
|
|
عرض المصدر على GitHub
|
يوضّح هذا الدليل كيفية ضبط نموذج FunctionGemma بدقة لاستخدام الأدوات.
في حين أنّ FunctionGemma قادرة بشكلٍ أساسي على استدعاء الأدوات. لكنّ القدرة الحقيقية تأتي من مهارتَين مختلفتَين: المعرفة الميكانيكية بكيفية استخدام أداة (بناء الجملة) والقدرة المعرفية على تفسير سبب ووقت استخدامها (النية).
تتوفّر في النماذج، وخاصةً الصغيرة منها، معلَمات أقل للاحتفاظ بفهم النية المعقّدة. لهذا السبب نحتاج إلى تحسينها
تشمل حالات الاستخدام الشائعة لضبط استدعاء الأدوات ما يلي:
- تقطير النماذج: إنشاء بيانات تدريب اصطناعية باستخدام نموذج أكبر وتحسين نموذج أصغر ليتكرر سير العمل المحدّد بكفاءة
- التعامل مع المخططات غير العادية: التغلّب على المشاكل التي تواجه النموذج الأساسي مع بنى البيانات القديمة أو المعقّدة للغاية أو التنسيق الخاص غير المتوفّر في البيانات العامة، مثل التعامل مع إجراءات الأجهزة الجوّالة الخاصة بمجال معيّن
- تحسين استخدام السياق: "تضمين" تعريفات الأدوات في أوزان النموذج يتيح لك ذلك استخدام أوصاف مختصرة في طلباتك، ما يوفّر مساحة في نافذة السياق للمحادثة الفعلية.
- حلّ حالات الغموض في الاختيار: توجيه النموذج نحو سياسات مؤسسة معيّنة، مثل إعطاء الأولوية لقاعدة معلومات داخلية على محرّك بحث خارجي
في هذا المثال، سنركّز تحديدًا على إدارة غموض اختيار الأداة.
إعداد بيئة التطوير
الخطوة الأولى هي تثبيت مكتبات Hugging Face، بما في ذلك TRL ومجموعات البيانات لضبط النموذج المفتوح بدقة، بما في ذلك تقنيات مختلفة للتعزيز من خلال التعلّم البشري (RLHF) والمواءمة.
# Install Pytorch & other libraries
%pip install torch tensorboard
# Install Hugging Face libraries
%pip install transformers datasets accelerate evaluate trl protobuf sentencepiece
# COMMENT IN: if you are running on a GPU that supports BF16 data type and flash attn, such as NVIDIA L4 or NVIDIA A100
#% pip install flash-attn
ملاحظة: إذا كنت تستخدم وحدة معالجة الرسومات (GPU) ببنية Ampere (مثل NVIDIA L4) أو أحدث، يمكنك استخدام Flash attention. Flash Attention هي طريقة تسرّع العمليات الحسابية بشكل كبير وتقلّل من استخدام الذاكرة من تربيعي إلى خطي في طول التسلسل، ما يؤدي إلى تسريع التدريب بمقدار 3 أضعاف. يمكنك الاطّلاع على مزيد من المعلومات على FlashAttention.
قبل بدء التدريب، عليك التأكّد من قبول بنود استخدام Gemma. يمكنك قبول الترخيص على Hugging Face من خلال النقر على الزر أوافق والوصول إلى المستودع على صفحة النموذج على الرابط: http://huggingface.co/google/functiongemma-270m-it
بعد قبول الترخيص، تحتاج إلى رمز مميّز صالح من Hugging Face للوصول إلى النموذج. إذا كنت تستخدم Google Colab، يمكنك استخدام رمز Hugging Face Token بشكل آمن من خلال أسرار Colab، وإلا يمكنك ضبط الرمز المميز مباشرةً في طريقة login. تأكَّد أيضًا من أنّ الرمز المميّز لديه إذن الوصول للكتابة، إذ إنّك ستنقل النموذج إلى Hugging Face Hub بعد إجراء عملية الضبط الدقيق.
# Login into Hugging Face Hub
from huggingface_hub import login
login()
يمكنك الاحتفاظ بالنتائج على الجهاز الافتراضي المحلي في Colab. ومع ذلك، ننصحك بشدة بحفظ النتائج المؤقتة في Google Drive. يضمن ذلك أمان نتائج التدريب ويسمح لك بسهولة مقارنة أفضل النماذج واختيارها.
عدِّل أيضًا دليل نقاط التفتيش ومعدّل التعلّم.
from google.colab import drive
mount_google_drive = False
checkpoint_dir = "functiongemma-270m-it-simple-tool-calling"
if mount_google_drive:
drive.mount('/content/drive')
checkpoint_dir = f"/content/drive/MyDrive/{checkpoint_dir}"
print(f"Checkpoints will be saved to {checkpoint_dir}")
base_model = "google/functiongemma-270m-it"
learning_rate = 5e-5
Checkpoints will be saved to functiongemma-270m-it-simple-tool-calling
إعداد مجموعة بيانات الضبط الدقيق
ستستخدِم مجموعة البيانات النموذجية التالية التي تحتوي على محادثات نموذجية تتطلّب الاختيار بين أداتَين: search_knowledge_base وsearch_google.
مجموعة بيانات بسيطة لاستدعاء الأدوات
لنفترض أنّ طلب البحث هو: "ما هي أفضل الممارسات لكتابة دالة تكرارية بسيطة في Python؟"
تعتمد الأداة المناسبة تمامًا على سياستك المحدّدة. في حين أنّ النموذج العام يضبط القيمة التلقائية على search_google، يحتاج تطبيق المؤسسة عادةً إلى التحقّق من search_knowledge_base أولاً.
ملاحظة حول تقسيم البيانات: في هذا العرض التوضيحي، ستستخدم تقسيمًا بنسبة 50/50 بين بيانات التدريب والاختبار. مع أنّ تقسيم البيانات بنسبة 80/20 هو المعيار في مهام سير العمل الإنتاجية، تم اختيار هذا التقسيم المتساوي تحديدًا لإبراز التحسّن في أداء النموذج على البيانات غير المرئية.
import json
from datasets import Dataset
from transformers.utils import get_json_schema
# --- Tool Definitions ---
def search_knowledge_base(query: str) -> str:
"""
Search internal company documents, policies and project data.
Args:
query: query string
"""
return "Internal Result"
def search_google(query: str) -> str:
"""
Search public information.
Args:
query: query string
"""
return "Public Result"
TOOLS = [get_json_schema(search_knowledge_base), get_json_schema(search_google)]
DEFAULT_SYSTEM_MSG = "You are a model that can do function calling with the following functions"
def create_conversation(sample):
return {
"messages": [
{"role": "developer", "content": DEFAULT_SYSTEM_MSG},
{"role": "user", "content": sample["user_content"]},
{"role": "assistant", "tool_calls": [{"type": "function", "function": {"name": sample["tool_name"], "arguments": json.loads(sample["tool_arguments"])} }]},
],
"tools": TOOLS
}
dataset = Dataset.from_list(simple_tool_calling)
# You can also load the dataset from Hugging Face Hub
# dataset = load_dataset("bebechien/SimpleToolCalling", split="train")
# Convert dataset to conversational format
dataset = dataset.map(create_conversation, remove_columns=dataset.features, batched=False)
# Split dataset into 50% training samples and 50% test samples
dataset = dataset.train_test_split(test_size=0.5, shuffle=True)
Map: 0%| | 0/40 [00:00<?, ? examples/s]
ملاحظة مهمة حول توزيع مجموعة البيانات
عند استخدام shuffle=False مع مجموعات البيانات المخصّصة، تأكَّد من أنّ بيانات المصدر مختلطة مسبقًا. إذا كان التوزيع غير معروف أو مرتّبًا، عليك استخدام shuffle=True لضمان تعلُّم النموذج تمثيلاً متوازنًا لجميع الأدوات أثناء التدريب.
ضبط نموذج FunctionGemma بدقة باستخدام TRL وSFTTrainer
أنت الآن جاهز لضبط نموذجك بدقة. تسهّل أداة SFTTrainer من مكتبة TRL في Hugging Face عملية الإشراف على الضبط الدقيق لنماذج اللغات الكبيرة المفتوحة. SFTTrainer هي فئة فرعية من Trainer من مكتبة transformers وتتيح جميع الميزات نفسها.
تحمّل التعليمات البرمجية التالية نموذج FunctionGemma وأداة الترميز من Hugging Face.
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
# Load model and tokenizer
model = AutoModelForCausalLM.from_pretrained(
base_model,
dtype="auto",
device_map="auto",
attn_implementation="eager"
)
tokenizer = AutoTokenizer.from_pretrained(base_model)
print(f"Device: {model.device}")
print(f"DType: {model.dtype}")
# Print formatted user prompt
print("--- dataset input ---")
print(json.dumps(dataset["train"][0], indent=2))
debug_msg = tokenizer.apply_chat_template(dataset["train"][0]["messages"], tools=dataset["train"][0]["tools"], add_generation_prompt=False, tokenize=False)
print("--- Formatted prompt ---")
print(debug_msg)
Device: cuda:0
DType: torch.bfloat16
--- dataset input ---
{
"messages": [
{
"content": "You are a model that can do function calling with the following functions",
"role": "developer",
"tool_calls": null
},
{
"content": "What is the reimbursement limit for travel meals?",
"role": "user",
"tool_calls": null
},
{
"content": null,
"role": "assistant",
"tool_calls": [
{
"function": {
"arguments": {
"query": "travel meal reimbursement limit policy"
},
"name": "search_knowledge_base"
},
"type": "function"
}
]
}
],
"tools": [
{
"function": {
"description": "Search internal company documents, policies and project data.",
"name": "search_knowledge_base",
"parameters": {
"properties": {
"query": {
"description": "query string",
"type": "string"
}
},
"required": [
"query"
],
"type": "object"
},
"return": {
"type": "string"
}
},
"type": "function"
},
{
"function": {
"description": "Search public information.",
"name": "search_google",
"parameters": {
"properties": {
"query": {
"description": "query string",
"type": "string"
}
},
"required": [
"query"
],
"type": "object"
},
"return": {
"type": "string"
}
},
"type": "function"
}
]
}
--- Formatted prompt ---
<bos><start_of_turn>developer
You are a model that can do function calling with the following functions<start_function_declaration>declaration:search_knowledge_base{description:<escape>Search internal company documents, policies and project data.<escape>,parameters:{properties:{query:{description:<escape>query string<escape>,type:<escape>STRING<escape>} },required:[<escape>query<escape>],type:<escape>OBJECT<escape>} }<end_function_declaration><start_function_declaration>declaration:search_google{description:<escape>Search public information.<escape>,parameters:{properties:{query:{description:<escape>query string<escape>,type:<escape>STRING<escape>} },required:[<escape>query<escape>],type:<escape>OBJECT<escape>} }<end_function_declaration><end_of_turn>
<start_of_turn>user
What is the reimbursement limit for travel meals?<end_of_turn>
<start_of_turn>model
<start_function_call>call:search_knowledge_base{query:<escape>travel meal reimbursement limit policy<escape>}<end_function_call><start_function_response>
قبل الضبط الدقيق
يوضّح الناتج أدناه أنّ الإمكانات الجاهزة للاستخدام قد لا تكون مناسبة لحالة الاستخدام هذه.
def check_success_rate():
success_count = 0
for idx, item in enumerate(dataset['test']):
messages = [
item["messages"][0],
item["messages"][1],
]
inputs = tokenizer.apply_chat_template(messages, tools=TOOLS, add_generation_prompt=True, return_dict=True, return_tensors="pt")
out = model.generate(**inputs.to(model.device), pad_token_id=tokenizer.eos_token_id, max_new_tokens=128)
output = tokenizer.decode(out[0][len(inputs["input_ids"][0]) :], skip_special_tokens=False)
print(f"{idx+1} Prompt: {item['messages'][1]['content']}")
print(f" Output: {output}")
expected_tool = item['messages'][2]['tool_calls'][0]['function']['name']
other_tool = "search_knowledge_base" if expected_tool == "search_google" else "search_google"
if expected_tool in output and other_tool not in output:
print(" `-> ✅ correct!")
success_count += 1
elif expected_tool not in output:
print(f" -> ❌ wrong (expected '{expected_tool}' missing)")
else:
if output.startswith(f"<start_function_call>call:{expected_tool}"):
print(f" -> ⚠️ tool is correct {expected_tool}, but other_tool exists in output")
else:
print(f" -> ❌ wrong (hallucinated '{other_tool}')")
print(f"Success : {success_count} / {len(dataset['test'])}")
check_success_rate()
1 Prompt: How do I access my paystubs on the ADP portal?
Output: I cannot assist with accessing or retrieving paystubs or other company documents on the ADP portal. My current capabilities are limited to assisting with searching internal company documents and knowledge base queries.<end_of_turn>
-> ❌ wrong (expected 'search_knowledge_base' missing)
2 Prompt: What is the syntax for Python list comprehensions?
Output: I cannot assist with programming or providing programming syntax information. My current capabilities are focused on searching internal company documents and project data.<end_of_turn>
-> ❌ wrong (expected 'search_google' missing)
3 Prompt: Where can I find the floor plan for Building B?
Output: <start_function_call>call:search_knowledge_base{query:<escape>Floor plan for Building B<escape>}<end_function_call><start_function_call>call:search_google{query:<escape>Floor plan for Building B<escape>}<end_function_call><start_function_response>
-> ⚠️ tool is correct search_knowledge_base, but other_tool exists in output
4 Prompt: Check the latest stock price for Apple.
Output: <start_function_call>call:search_google{query:<escape>AAPL stock price<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
5 Prompt: What is the procedure for reporting a phishing email?
Output: I cannot assist with providing instructions or procedures for reporting phishing emails. My capabilities are limited to assisting with specific search and document management functions.<end_of_turn>
-> ❌ wrong (expected 'search_knowledge_base' missing)
6 Prompt: Show me examples of using the useEffect hook in React.
Output: I am sorry, but I cannot assist with providing examples of using the `useEffect` hook in React. My current capabilities are focused on assisting with searching and retrieving internal company documents and project data using the specified tools. I cannot generate or explain code examples related to React hooks.<end_of_turn>
-> ❌ wrong (expected 'search_google' missing)
7 Prompt: Who are the direct reports for the VP of Engineering?
Output: <start_function_call>call:search_knowledge_base{query:<escape>VP of Engineering<escape>}<end_function_call><start_function_call>call:search_google{query:<escape>VP of Engineering<escape>}<end_function_call><start_function_response>
-> ⚠️ tool is correct search_knowledge_base, but other_tool exists in output
8 Prompt: How do I list open ports on a Linux server?
Output: I cannot assist with listing or querying open ports on Linux servers. My current capabilities are limited to assisting with searching internal company documents and project data using the specified tools.<end_of_turn>
-> ❌ wrong (expected 'search_google' missing)
9 Prompt: What is our Slack message retention policy?
Output: I cannot assist with finding or recommending company policies or terms of service regarding Slack messaging retention. My current capabilities are focused on searching internal company documents and project data.<end_of_turn>
-> ❌ wrong (expected 'search_knowledge_base' missing)
10 Prompt: Compare the features of iPhone 15 vs Samsung S24.
Output: I cannot assist with comparing device features or specifications. My current capabilities are focused on assisting with searching and managing company knowledge. I cannot browse or compare external product information.<end_of_turn>
-> ❌ wrong (expected 'search_google' missing)
11 Prompt: I need the expense code for team building events.
Output: I can certainly assist with searching for expense codes. Could you please specify the exact query you would like to use for searching the company expense database?<end_of_turn>
-> ❌ wrong (expected 'search_knowledge_base' missing)
12 Prompt: Best practices for writing a Dockerfile for Node.js.
Output: I am sorry, but I cannot assist with recommending best practices for writing Dockerfiles for Node.js. My current capabilities are focused on searching company documents and project data using specific tools. I cannot recommend or provide expert advice on software development best practices.<end_of_turn>
-> ❌ wrong (expected 'search_google' missing)
13 Prompt: How do I request a new monitor setup?
Output: I cannot assist with recommending or requesting hardware setup or configurations. My current capabilities are limited to assisting with searching company documents and project data using the specified tools. I cannot provide technical advice or recommendations for hardware setup.<end_of_turn>
-> ❌ wrong (expected 'search_knowledge_base' missing)
14 Prompt: What is the difference between VLOOKUP and XLOOKUP in Google Sheets?
Output: I cannot assist with comparing or contrasting Google Sheets and VLOOKUP/XLOOKUP in specific technical terms. My current capabilities are limited to assisting with specific data management functions like searching internal company documents and searching public knowledge base. I cannot provide expert comparisons or explanations of Google Sheets and VLOOKUP/XLOOKUP.<end_of_turn>
-> ❌ wrong (expected 'search_google' missing)
15 Prompt: Find the onboarding checklist for new engineering hires.
Output: <start_function_call>call:search_knowledge_base{query:<escape>onboarding checklist for new engineering hires<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
16 Prompt: What are the latest release notes for the OpenAI API?
Output: <start_function_call>call:search_knowledge_base{query:<escape>OpenAI API release notes latest<escape>}<end_function_call><start_function_response>
-> ❌ wrong (expected 'search_google' missing)
17 Prompt: Do we have preferred hotel partners in Paris?
Output: I apologize, but I cannot assist with finding hotel partner information. My current capabilities are focused on searching company documents and project data using specific keywords. I cannot connect with or query business databases for hotel partnerships.<end_of_turn>
-> ❌ wrong (expected 'search_knowledge_base' missing)
18 Prompt: How to undo the last git commit but keep the changes?
Output: I cannot assist with managing or undoing Git repositories. My current capabilities are limited to assisting with searching and managing organizational knowledge bases. I cannot provide specific instructions or assistance with technical issues related to software development or Git operations.<end_of_turn>
-> ❌ wrong (expected 'search_google' missing)
19 Prompt: What is the process for creating a new Jira project?
Output: I cannot assist with creating or managing Jira project processes. My current capabilities are limited to assisting with searching company documents and project data using the specified tools.<end_of_turn>
-> ❌ wrong (expected 'search_knowledge_base' missing)
20 Prompt: Tutorial on SQL window functions.
Output: I cannot assist with tutorials or programming advice regarding SQL window functions. My capabilities are limited to assisting with searching company documents and knowledge base information.<end_of_turn>
-> ❌ wrong (expected 'search_google' missing)
Success : 2 / 20
التدريب
قبل أن تتمكّن من بدء التدريب، عليك تحديد المعلمات الفائقة التي تريد استخدامها في مثيل SFTConfig.
from trl import SFTConfig
torch_dtype = model.dtype
args = SFTConfig(
output_dir=checkpoint_dir, # directory to save and repository id
max_length=512, # max sequence length for model and packing of the dataset
packing=False, # Groups multiple samples in the dataset into a single sequence
num_train_epochs=8, # number of training epochs
per_device_train_batch_size=4, # batch size per device during training
gradient_checkpointing=False, # Caching is incompatible with gradient checkpointing
optim="adamw_torch_fused", # use fused adamw optimizer
logging_steps=1, # log every step
#save_strategy="epoch", # save checkpoint every epoch
eval_strategy="epoch", # evaluate checkpoint every epoch
learning_rate=learning_rate, # learning rate
fp16=True if torch_dtype == torch.float16 else False, # use float16 precision
bf16=True if torch_dtype == torch.bfloat16 else False, # use bfloat16 precision
lr_scheduler_type="constant", # use constant learning rate scheduler
push_to_hub=True, # push model to hub
report_to="tensorboard", # report metrics to tensorboard
)
أصبح لديك الآن كلّ لبنات البناء التي تحتاج إليها لإنشاء SFTTrainer من أجل بدء تدريب النموذج.
from trl import SFTTrainer
# Create Trainer object
trainer = SFTTrainer(
model=model,
args=args,
train_dataset=dataset['train'],
eval_dataset=dataset['test'],
processing_class=tokenizer,
)
Tokenizing train dataset: 0%| | 0/20 [00:00<?, ? examples/s] Truncating train dataset: 0%| | 0/20 [00:00<?, ? examples/s] Tokenizing eval dataset: 0%| | 0/20 [00:00<?, ? examples/s] Truncating eval dataset: 0%| | 0/20 [00:00<?, ? examples/s] The model is already on multiple devices. Skipping the move to device specified in `args`.
ابدأ التدريب من خلال استدعاء طريقة train().
# Start training, the model will be automatically saved to the Hub and the output directory
trainer.train()
# Save the final model again to the Hugging Face Hub
trainer.save_model()
The tokenizer has new PAD/BOS/EOS tokens that differ from the model config and generation config. The model config and generation config were aligned accordingly, being updated with the tokenizer's values. Updated tokens: {'bos_token_id': 2, 'pad_token_id': 0}.
لرسم خسائر التدريب والتحقّق من الصحة، عليك عادةً استخراج هذه القيم من الكائن TrainerState أو السجلات التي تم إنشاؤها أثناء التدريب.
يمكن بعد ذلك استخدام مكتبات مثل Matplotlib لعرض هذه القيم بشكل مرئي على مدار خطوات التدريب أو الفترات. سيمثّل المحور x خطوات التدريب أو عدد مرات التكرار، وسيمثّل المحور y قيم الخسارة المقابلة.
import matplotlib.pyplot as plt
# Access the log history
log_history = trainer.state.log_history
# Extract training / validation loss
train_losses = [log["loss"] for log in log_history if "loss" in log]
epoch_train = [log["epoch"] for log in log_history if "loss" in log]
eval_losses = [log["eval_loss"] for log in log_history if "eval_loss" in log]
epoch_eval = [log["epoch"] for log in log_history if "eval_loss" in log]
# Plot the training loss
plt.plot(epoch_train, train_losses, label="Training Loss")
plt.plot(epoch_eval, eval_losses, label="Validation Loss")
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.title("Training and Validation Loss per Epoch")
plt.legend()
plt.grid(True)
plt.show()

استنتاج النموذج التجريبي
بعد اكتمال التدريب، عليك تقييم النموذج واختباره. يمكنك تحميل عيّنات مختلفة من مجموعة بيانات الاختبار وتقييم النموذج استنادًا إلى هذه العيّنات.
check_success_rate()
1 Prompt: How do I access my paystubs on the ADP portal?
Output: <start_function_call>call:search_knowledge_base{query:<escape>paystubs API portal access codes<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
2 Prompt: What is the syntax for Python list comprehensions?
Output: <start_function_call>call:search_google{query:<escape>Python list comprehensions syntax<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
3 Prompt: Where can I find the floor plan for Building B?
Output: <start_function_call>call:search_knowledge_base{query:<escape>floor plan Building B floor plan<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
4 Prompt: Check the latest stock price for Apple.
Output: <start_function_call>call:search_google{query:<escape>latest stock price Apple<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
5 Prompt: What is the procedure for reporting a phishing email?
Output: <start_function_call>call:search_knowledge_base{query:<escape>phishing email procedure reporting policy<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
6 Prompt: Show me examples of using the useEffect hook in React.
Output: <start_function_call>call:search_knowledge_base{query:<escape>useEffect hook examples React<escape>}<end_function_call><start_function_response>
-> ❌ wrong (expected 'search_google' missing)
7 Prompt: Who are the direct reports for the VP of Engineering?
Output: <start_function_call>call:search_knowledge_base{query:<escape>VP of Engineering direct reports<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
8 Prompt: How do I list open ports on a Linux server?
Output: <start_function_call>call:search_google{query:<escape>open ports Linux server equivalents<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
9 Prompt: What is our Slack message retention policy?
Output: <start_function_call>call:search_knowledge_base{query:<escape>slack message retention policy policy excerpt<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
10 Prompt: Compare the features of iPhone 15 vs Samsung S24.
Output: <start_function_call>call:search_google{query:<escape>iPhone 15 vs Samsung S24 feature comparison<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
11 Prompt: I need the expense code for team building events.
Output: <start_function_call>call:search_knowledge_base{query:<escape>expense code team building events<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
12 Prompt: Best practices for writing a Dockerfile for Node.js.
Output: <start_function_call>call:search_knowledge_base{query:<escape>Docker file best practices Node.js<escape>}<end_function_call><start_function_response>
-> ❌ wrong (expected 'search_google' missing)
13 Prompt: How do I request a new monitor setup?
Output: <start_function_call>call:search_knowledge_base{query:<escape>new monitor setup request procedure<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
14 Prompt: What is the difference between VLOOKUP and XLOOKUP in Google Sheets?
Output: <start_function_call>call:search_google{query:<escape>VLOOKUP vs XLOOKUP difference Google Sheets中<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
15 Prompt: Find the onboarding checklist for new engineering hires.
Output: <start_function_call>call:search_knowledge_base{query:<escape>engineering hire onboarding checklist New hires.<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
16 Prompt: What are the latest release notes for the OpenAI API?
Output: <start_function_call>call:search_google{query:<escape>latest OpenAI API release notes latest version<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
17 Prompt: Do we have preferred hotel partners in Paris?
Output: <start_function_call>call:search_knowledge_base{query:<escape>preferred hotel partners in Paris<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
18 Prompt: How to undo the last git commit but keep the changes?
Output: <start_function_call>call:search_knowledge_base{query:<escape>undo git commit last commit<escape>}<end_function_call><start_function_response>
-> ❌ wrong (expected 'search_google' missing)
19 Prompt: What is the process for creating a new Jira project?
Output: <start_function_call>call:search_knowledge_base{query:<escape>Jira project creation process<escape>}<end_function_call><start_function_response>
`-> ✅ correct!
20 Prompt: Tutorial on SQL window functions.
Output: <start_function_call>call:search_knowledge_base{query:<escape>SQL window functions tutorial<escape>}<end_function_call><start_function_response>
-> ❌ wrong (expected 'search_google' missing)
Success : 16 / 20
الملخّص والخطوات التالية
تعرّفت على كيفية ضبط FunctionGemma بدقة لحل غموض اختيار الأداة، وهو سيناريو يجب فيه على النموذج الاختيار بين أدوات متداخلة (مثل البحث الداخلي مقابل البحث الخارجي) استنادًا إلى سياسات مؤسسة معيّنة. من خلال استخدام مكتبة TRL من Hugging Face وSFTTrainer، شرح البرنامج التعليمي عملية إعداد مجموعة بيانات وضبط المَعلمات الفائقة وتنفيذ حلقة ضبط دقيق بإشراف.
توضّح النتائج الفرق الحاسم بين نموذج أساسي "فعّال" ونموذج معدَّل "جاهز للاستخدام":
- قبل الضبط الدقيق: واجه النموذج الأساسي صعوبة في الالتزام بالسياسة المحدّدة، وغالبًا ما كان يتعذّر عليه استدعاء الأدوات أو اختيار الأداة الخاطئة، ما أدّى إلى انخفاض معدّل النجاح (على سبيل المثال، 2/20).
- بعد الضبط الدقيق: بعد التدريب لمدة 8 دورات تدريبية، تعلّم النموذج التمييز بشكل صحيح بين طلبات البحث التي تتطلّب استخدام search_knowledge_base وتلك التي تتطلّب استخدام search_google، ما أدّى إلى تحسين معدّل النجاح (على سبيل المثال، 16/20).
بعد أن أصبح لديك نموذج تم ضبطه بدقة، ننصحك باتّباع الخطوات التالية للانتقال إلى مرحلة الإنتاج:
- توسيع مجموعة البيانات: كانت مجموعة البيانات الحالية عبارة عن تقسيم اصطناعي صغير (50/50) يُستخدم للعرض التوضيحي. لإنشاء تطبيق مؤسسة قوي، يجب تنظيم مجموعة بيانات أكبر وأكثر تنوعًا تشمل الحالات الحدّية والاستثناءات النادرة من السياسات.
- التقييم باستخدام التوليد المعزّز بالاسترجاع: يمكنك دمج النموذج المضبوط بدقة في مسار التوليد المعزّز بالاسترجاع للتأكّد من أنّ عمليات استدعاء الأداة
search_knowledge_baseتسترجع المستندات ذات الصلة وتقدّم إجابات نهائية دقيقة.
يمكنك الاطّلاع على المستندات التالية:
التشغيل في Google Colab
عرض المصدر على GitHub