يرشدك هذا الدليل إلى كيفية تحسين Gemma في مجموعة بيانات مخصّصة من النص إلى SQL باستخدام Transformers وTRL من Hugging Face. ستتعرّف على ما يلي:
- ما هو Quantized Low-Rank Adaptation (QLoRA)؟
- إعداد بيئة التطوير
- إنشاء مجموعة بيانات التحسين وإعدادها
- تحسين Gemma باستخدام TRL وSFTTrainer
- اختبار الاستنتاج من النماذج وإنشاء استعلامات SQL
ما هو Quantized Low-Rank Adaptation (QLoRA)؟
يوضّح هذا الدليل استخدام الطريقة الكمّية للتكييف منخفضة الترتيب (QLoRA)، التي ظهرت كطريقة شائعة لتحسين النماذج اللغوية الكبيرة بكفاءة، لأنّها تقلّل من متطلبات الموارد الحسابية مع الحفاظ على الأداء العالي. في QloRA، يتم تقليل عدد الأرقام في النموذج المدّرب مسبقًا إلى 4 بت ويتم تجميد الأوزان. بعد ذلك، يتم إرفاق طبقات المحوِّل القابلة للتدريب (LoRA) ويتم تدريب طبقات المحوِّل فقط. بعد ذلك، يمكن دمج قيم مُحوِّل البيانات مع النموذج الأساسي أو الاحتفاظ بها كمحوِّل بيانات منفصل.
إعداد بيئة التطوير
الخطوة الأولى هي تثبيت مكتبات Hugging Face، بما في ذلك TRL، ومجموعات البيانات لتحسين النموذج المفتوح، بما في ذلك تقنيات RLHF المختلفة وتقنيات المحاذاة.
# Install Pytorch & other libraries
%pip install "torch>=2.4.0" tensorboard
# Install Gemma release branch from Hugging Face
%pip install "transformers>=4.51.3"
# Install Hugging Face libraries
%pip install --upgrade \
"datasets==3.3.2" \
"accelerate==1.4.0" \
"evaluate==0.4.3" \
"bitsandbytes==0.45.3" \
"trl==0.15.2" \
"peft==0.14.0" \
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
ملاحظة: إذا كنت تستخدم وحدة معالجة رسومات ببنية Ampere (مثل NVIDIA L4) أو إصدارًا أحدث، يمكنك استخدام ميزة "فلاش الانتباه". "الانتباه السريع" هي طريقة تُسرع العمليات الحسابية بشكلٍ كبير وتقلل من استخدام الذاكرة من ثنائية إلى خطية في طول التسلسل، ما يؤدي إلى تسريع التدريب بمقدار 3 أضعاف. مزيد من المعلومات على FlashAttention
قبل أن تتمكّن من بدء التدريب، عليك التأكّد من قبول بنود استخدام Gemma. يمكنك قبول الترخيص على Hugging Face من خلال النقر على زر "الموافقة والوصول إلى المستودع" في صفحة النموذج على الرابط: http://huggingface.co/google/gemma-3-1b-pt
بعد قبول الترخيص، ستحتاج إلى رمز Hugging Face Token صالح للوصول إلى النموذج. إذا كنت تستخدم Google Colab، يمكنك استخدام رمز Hugging Face بشكل آمن باستخدام أسرار Colab، وإلا يمكنك ضبط الرمز المميّز مباشرةً في طريقة login
. تأكَّد أيضًا من أنّ الرمز المميّز يتضمّن إذن الوصول للكتابة، وذلك عند نقل النموذج إلى Hub أثناء عملية التدريب.
from google.colab import userdata
from huggingface_hub import login
# Login into Hugging Face Hub
hf_token = userdata.get('HF_TOKEN') # If you are running inside a Google Colab
login(hf_token)
إنشاء مجموعة بيانات التحسين وإعدادها
عند تحسين النماذج اللغوية الكبيرة، من المهم معرفة حالة الاستخدام والمهمة التي تريد حلّها. يساعدك ذلك في إنشاء مجموعة بيانات لتحسين نموذجك. إذا لم تكن قد حدّدت حالة الاستخدام بعد، ننصحك بالعودة إلى لوحة الرسم.
على سبيل المثال، يركّز هذا الدليل على حالة الاستخدام التالية:
- يمكنك تحسين نموذج لغة طبيعية إلى لغة SQL للدمج السلس في أداة تحليل البيانات. والهدف من ذلك هو تقليل الوقت والخبرة المطلوبة لإنشاء طلبات بحث SQL بشكل كبير، ما يتيح حتى للمستخدمين غير التقنيين استخراج إحصاءات مفيدة من البيانات.
يمكن أن يكون تحويل النصوص إلى لغة SQL حالة استخدام جيدة لتحسين النماذج اللغوية الكبيرة، لأنّها مهمة معقّدة تتطلّب الكثير من المعرفة (الداخلية) عن البيانات ولغة SQL.
بعد تحديد أنّ التحسين هو الحلّ المناسب، ستحتاج إلى مجموعة بيانات لإجراء التحسين. يجب أن تكون مجموعة البيانات مجموعة متنوعة من العروض التوضيحية للمهام التي تريد حلّها. هناك عدة طرق لإنشاء مجموعة بيانات كهذه، بما في ذلك:
- استخدام مجموعات البيانات الحالية المفتوحة المصدر، مثل Spider
- استخدام مجموعات بيانات اصطناعية أنشأتها النماذج اللغوية الكبيرة، مثل Alpaca
- استخدام مجموعات بيانات أنشأها البشر، مثل Dolly
- استخدام مجموعة من الطرق، مثل Orca
ولكل طريقة من هذه الطرق مزاياها وعيوبها، وتعتمد على الميزانية والوقت ومتطلبات الجودة. على سبيل المثال، استخدام مجموعة بيانات حالية هو الخيار الأسهل، ولكن قد لا يكون مخصّصًا لحالة الاستخدام المحدّدة، في حين أنّ استخدام خبراء المجال قد يكون الخيار الأكثر دقة، ولكن قد يكون مضيعة للوقت ومكلفًا. من الممكن أيضًا دمج عدة طرق لإنشاء مجموعة بيانات تعليمات، كما هو موضّح في Orca: التعلّم التدريجي من عمليات تتبُّع التفسيرات المعقّدة لنموذج GPT-4.
يستخدم هذا الدليل مجموعة بيانات حالية (philschmid/gretel-synthetic-text-to-sql)، وهي مجموعة بيانات اصطناعية عالية الجودة من النص إلى SQL تتضمّن تعليمات بلغة طبيعية وتعريفات للمخططات وعمليات التفكير واستعلام SQL المقابل.
يتيح Hugging Face TRL إنشاء النماذج تلقائيًا لتنسيقات مجموعة بيانات المحادثات. وهذا يعني أنّه ما عليك سوى تحويل مجموعة البيانات إلى عناصر json الصحيحة، وسيتولى trl
إنشاء النماذج ووضعها في التنسيق الصحيح.
{"messages": [{"role": "system", "content": "You are..."}, {"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]}
{"messages": [{"role": "system", "content": "You are..."}, {"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]}
{"messages": [{"role": "system", "content": "You are..."}, {"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]}
يحتوي philschmid/gretel-synthetic-text-to-sql على أكثر من 100 ألف عيّنة. للحفاظ على حجم الدليل صغيرًا، يتم تقليل عيّنات البيانات لاستخدام 10,000 عيّنة فقط.
يمكنك الآن استخدام مكتبة Hugging Face Datasets لتحميل مجموعة البيانات وإنشاء نموذج طلب لدمج تعليمات اللغة الطبيعية وتعريف المخطط وإضافة رسالة نظام لمساعدك.
from datasets import load_dataset
# System message for the assistant
system_message = """You are a text to SQL query translator. Users will ask you questions in English and you will generate a SQL query based on the provided SCHEMA."""
# User prompt that combines the user query and the schema
user_prompt = """Given the <USER_QUERY> and the <SCHEMA>, generate the corresponding SQL command to retrieve the desired data, considering the query's syntax, semantics, and schema constraints.
<SCHEMA>
{context}
</SCHEMA>
<USER_QUERY>
{question}
</USER_QUERY>
"""
def create_conversation(sample):
return {
"messages": [
# {"role": "system", "content": system_message},
{"role": "user", "content": user_prompt.format(question=sample["sql_prompt"], context=sample["sql_context"])},
{"role": "assistant", "content": sample["sql"]}
]
}
# Load dataset from the hub
dataset = load_dataset("philschmid/gretel-synthetic-text-to-sql", split="train")
dataset = dataset.shuffle().select(range(12500))
# Convert dataset to OAI messages
dataset = dataset.map(create_conversation, remove_columns=dataset.features,batched=False)
# split dataset into 10,000 training samples and 2,500 test samples
dataset = dataset.train_test_split(test_size=2500/12500)
# Print formatted user prompt
print(dataset["train"][345]["messages"][1]["content"])
تحسين Gemma باستخدام TRL وSFTTrainer
أصبحت الآن جاهزًا لإجراء تحسينات على النموذج. تسهّل أداة SFTTrainer من Hugging Face TRL الإشراف على تحسين النماذج اللغوية الكبيرة المفتوحة. SFTTrainer
هي فئة فرعية من Trainer
من مكتبة transformers
وتتيح جميع الميزات نفسها، بما في ذلك التسجيل والتقييم وتسجيل نقاط التفتيش، ولكنها تضيف ميزات إضافية لتسهيل الاستخدام، بما في ذلك:
- تنسيق مجموعة البيانات، بما في ذلك تنسيقات المحادثات والتعليمات
- التدريب على عمليات الإكمال فقط، مع تجاهل الطلبات
- تجميع مجموعات البيانات لتدريب أكثر فعالية
- إتاحة ميزة "التحسين الدقيق باستخدام المَعلمات" (PEFT) بما في ذلك QloRA
- إعداد النموذج وبرنامج تقسيم النصوص لإجراء تحسينات على المحادثات (مثل إضافة رموز خاصة)
تحمِّل الرموز البرمجية التالية نموذج Gemma وبرنامج تقسيم الكلمات من Hugging Face وتُنشئ إعدادات التقليل.
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, AutoModelForImageTextToText, BitsAndBytesConfig
# Hugging Face model id
model_id = "google/gemma-3-1b-pt" # or `google/gemma-3-4b-pt`, `google/gemma-3-12b-pt`, `google/gemma-3-27b-pt`
# Select model class based on id
if model_id == "google/gemma-3-1b-pt":
model_class = AutoModelForCausalLM
else:
model_class = AutoModelForImageTextToText
# Check if GPU benefits from bfloat16
if torch.cuda.get_device_capability()[0] >= 8:
torch_dtype = torch.bfloat16
else:
torch_dtype = torch.float16
# Define model init arguments
model_kwargs = dict(
attn_implementation="eager", # Use "flash_attention_2" when running on Ampere or newer GPU
torch_dtype=torch_dtype, # What torch dtype to use, defaults to auto
device_map="auto", # Let torch decide how to load the model
)
# BitsAndBytesConfig: Enables 4-bit quantization to reduce model size/memory usage
model_kwargs["quantization_config"] = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type='nf4',
bnb_4bit_compute_dtype=model_kwargs['torch_dtype'],
bnb_4bit_quant_storage=model_kwargs['torch_dtype'],
)
# Load model and tokenizer
model = model_class.from_pretrained(model_id, **model_kwargs)
tokenizer = AutoTokenizer.from_pretrained("google/gemma-3-1b-it") # Load the Instruction Tokenizer to use the official Gemma template
يتيح SFTTrainer
الدمج الأصلي مع peft
، ما يسهّل ضبط النماذج اللغوية الكبيرة بكفاءة باستخدام QLoRA. ما عليك سوى إنشاء LoraConfig
وتقديمه إلى المدرب.
from peft import LoraConfig
peft_config = LoraConfig(
lora_alpha=16,
lora_dropout=0.05,
r=16,
bias="none",
target_modules="all-linear",
task_type="CAUSAL_LM",
modules_to_save=["lm_head", "embed_tokens"] # make sure to save the lm_head and embed_tokens as you train the special tokens
)
قبل أن تتمكّن من بدء عملية التدريب، عليك تحديد المَعلمة الفائقة التي تريد استخدامها في مثيل SFTConfig
.
from trl import SFTConfig
args = SFTConfig(
output_dir="gemma-text-to-sql", # directory to save and repository id
max_seq_length=512, # max sequence length for model and packing of the dataset
packing=True, # Groups multiple samples in the dataset into a single sequence
num_train_epochs=3, # number of training epochs
per_device_train_batch_size=1, # batch size per device during training
gradient_accumulation_steps=4, # number of steps before performing a backward/update pass
gradient_checkpointing=True, # use gradient checkpointing to save memory
optim="adamw_torch_fused", # use fused adamw optimizer
logging_steps=10, # log every 10 steps
save_strategy="epoch", # save checkpoint every epoch
learning_rate=2e-4, # learning rate, based on QLoRA paper
fp16=True if torch_dtype == torch.float16 else False, # use float16 precision
bf16=True if torch_dtype == torch.bfloat16 else False, # use bfloat16 precision
max_grad_norm=0.3, # max gradient norm based on QLoRA paper
warmup_ratio=0.03, # warmup ratio based on QLoRA paper
lr_scheduler_type="constant", # use constant learning rate scheduler
push_to_hub=True, # push model to hub
report_to="tensorboard", # report metrics to tensorboard
dataset_kwargs={
"add_special_tokens": False, # We template with special tokens
"append_concat_token": True, # Add EOS token as separator token between examples
}
)
لديك الآن كلّ الوحدات الأساسية التي تحتاج إليها لإنشاء SFTTrainer
لبدء تدريب النموذج.
from trl import SFTTrainer
# Create Trainer object
trainer = SFTTrainer(
model=model,
args=args,
train_dataset=dataset["train"],
peft_config=peft_config,
processing_class=tokenizer
)
ابدأ التدريب من خلال استدعاء طريقة 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()
قبل أن تتمكّن من اختبار النموذج، احرص على تحرير الذاكرة.
# free the memory again
del model
del trainer
torch.cuda.empty_cache()
عند استخدام QLoRA، يتم تدريب المحوِّلات فقط وليس النموذج الكامل. وهذا يعني أنّه عند حفظ النموذج أثناء التدريب، يتم حفظ أوزان المُحوِّل فقط وليس النموذج الكامل. إذا كنت تريد حفظ النموذج الكامل، ما يسهّل استخدامه مع مجموعات عرض مثل vLLM أو TGI، يمكنك دمج أوزان المُحوِّل في أوزان النموذج باستخدام الطريقة merge_and_unload
ثم حفظ النموذج باستخدام الطريقة save_pretrained
. يؤدي ذلك إلى حفظ نموذج تلقائي يمكن استخدامه للاستنتاج.
from peft import PeftModel
# Load Model base model
model = model_class.from_pretrained(model_id, low_cpu_mem_usage=True)
# Merge LoRA and base model and save
peft_model = PeftModel.from_pretrained(model, args.output_dir)
merged_model = peft_model.merge_and_unload()
merged_model.save_pretrained("merged_model", safe_serialization=True, max_shard_size="2GB")
processor = AutoTokenizer.from_pretrained(args.output_dir)
processor.save_pretrained("merged_model")
اختبار الاستنتاج المستنِد إلى النموذج وإنشاء استعلامات SQL
بعد انتهاء عملية التدريب، عليك تقييم النموذج واختباره. يمكنك تحميل عيّنات مختلفة من مجموعة بيانات الاختبار وتقييم النموذج على هذه العيّنات.
import torch
from transformers import pipeline
model_id = "gemma-text-to-sql"
# Load Model with PEFT adapter
model = model_class.from_pretrained(
model_id,
device_map="auto",
torch_dtype=torch_dtype,
attn_implementation="eager",
)
tokenizer = AutoTokenizer.from_pretrained(model_id)
لنحمِّل عيّنة عشوائية من مجموعة بيانات الاختبار وننشئ أمرًا في SQL.
from random import randint
import re
# Load the model and tokenizer into the pipeline
pipe = pipeline("text-generation", model=model, tokenizer=tokenizer)
# Load a random sample from the test dataset
rand_idx = randint(0, len(dataset["test"]))
test_sample = dataset["test"][rand_idx]
# Convert as test example into a prompt with the Gemma template
stop_token_ids = [tokenizer.eos_token_id, tokenizer.convert_tokens_to_ids("<end_of_turn>")]
prompt = pipe.tokenizer.apply_chat_template(test_sample["messages"][:2], tokenize=False, add_generation_prompt=True)
# Generate our SQL query.
outputs = pipe(prompt, max_new_tokens=256, do_sample=False, temperature=0.1, top_k=50, top_p=0.1, eos_token_id=stop_token_ids, disable_compile=True)
# Extract the user query and original answer
print(f"Context:\n", re.search(r'<SCHEMA>\n(.*?)\n</SCHEMA>', test_sample['messages'][0]['content'], re.DOTALL).group(1).strip())
print(f"Query:\n", re.search(r'<USER_QUERY>\n(.*?)\n</USER_QUERY>', test_sample['messages'][0]['content'], re.DOTALL).group(1).strip())
print(f"Original Answer:\n{test_sample['messages'][1]['content']}")
print(f"Generated Answer:\n{outputs[0]['generated_text'][len(prompt):].strip()}")
الملخّص والخطوات التالية
تناول هذا البرنامج التعليمي كيفية تحسين نموذج Gemma باستخدام TRL وQLoRA. اطّلِع على المستندات التالية بعد ذلك:
- تعرَّف على كيفية إنشاء نص باستخدام نموذج Gemma.
- تعرَّف على كيفية تحسين Gemma لتنفيذ مهام الرؤية باستخدام Hugging Face Transformers.
- تعرَّف على كيفية إجراء التحسين الموزّع والاستنتاج في نموذج Gemma.
- تعرَّف على كيفية استخدام نماذج Gemma المتاحة للجميع مع Vertex AI.
- تعرَّف على كيفية تحسين Gemma باستخدام KerasNLP ونشرها على Vertex AI.