TRL documentation
LoRA دون ندم
LoRA دون ندم
تُظهر الأبحاث الحديثة من فريق Thinking Machines Lab (Schulman et al., 2025) أن LoRA يمكنه تحقيق أداء مماثل لأداء الضبط الكامل عند ضبطه بشكل صحيح، مع استخدام حوالي 67% فقط من القدرة الحاسوبية. وتُعد هذه النتائج مثيرة لمستخدمي TRL لأنها سهلة التنفيذ ويمكنها تحسين أداء النموذج ضمن ميزانيات أصغر.
توفر هذه الدليل تعليمات بسيطة لإعادة إنتاج نتائج منشور المدونة في TRL.
يُوصى بقراءة المقال المنشور على المدونة قبل اتباع هذا الدليل، أو الرجوع إلى كلا المصدرين بالتوازي للحصول على أفضل النتائج.
مزايا LoRA مقارنةً بالتدريب الدقيق الكامل
أولاً، لنُذكّر أنفسنا بفوائد LoRA مقارنةً بالتدريب الدقيق الكامل.
تضيف LoRA طبقات مُكيِّفة فوق النموذج الأساسي، والتي تحتوي على عدد أقل بكثير من المعاملات مقارنةً بالنموذج الأساسي نفسه. يقلل هذا التصميم من متطلبات ذاكرة وحدة معالجة الرسوميات (GPU) ويمكّن من تدريب أكثر كفاءة. كما هو موضح في المدونة، كان يُعتقد في الأصل أن هذا النهج ينطوي على تنازل عن الأداء، على الرغم من أن الإعداد الدقيق يمكنه التغلب على هذا التنازل ومطابقة أداء الضبط الدقيق الكامل.
أمثلة باستخدام TRL
لنقم بتنفيذ وتدريب محولات LoRA في سكريبتات TRL بناءً على النتائج الأساسية للمدونة. بعد ذلك، سنعيد النظر في كل نتيجة في ضوء نتائج TRL.
الضبط الدقيق الإشرافي (SFT)
ينفّذ منشور المدونة تدريب الإشراف الدقيق (SFT) على مجموعة من النماذج ومجموعات البيانات من المستودع (Hub)، وهو ما يمكننا إعادة إنتاجه باستخدام TRL.
يمكننا دمج هذه النتائج مع واجهة TRL البرمجية بلغة بايثون على النحو التالي:
from datasets import load_dataset
from peft import LoraConfig
from trl import SFTTrainer, SFTConfig
dataset = load_dataset("open-thoughts/OpenThoughts-114k", split="train")
peft_config = LoraConfig(r=256, lora_alpha=16, target_modules="all-linear")
training_args = SFTConfig(
learning_rate=2e-4,
per_device_train_batch_size=1,
gradient_accumulation_steps=4,
num_train_epochs=1,
report_to=["trackio"],
)
trainer = SFTTrainer(
model="Qwen/Qwen2.5-3B-Instruct",
train_dataset=dataset,
peft_config=peft_config,
args=training_args,
)
trainer.train()
hf jobs uv run \
--flavor a100-large \
--timeout 8h \
--secrets HF_TOKEN \
"https://raw.githubusercontent.com/huggingface/trl/main/trl/scripts/sft.py" \
--model_name_or_path Qwen/Qwen2.5-3B-Instruct \
--dataset_name open-thoughts/OpenThoughts-114k \
--learning_rate 2.0e-5 \
--num_train_epochs 1 \
--packing \
--per_device_train_batch_size 2 \
--gradient_accumulation_steps 16 \
--use_peft \
--lora_r 256 \
--lora_alpha 16 \
--lora_target_modules all-linear \
--output_dir Qwen2.5-3B-OpenThoughts-LoRA \
--report_to trackio \
--push_to_hub
لاستخدام Hugging Face Jobs، سجّل الدخول إلى Hub (hf auth login) وتأكّد من وجود رصيد موجب. راجع توثيق Jobs للاطلاع على التفاصيل.
uv run "https://raw.githubusercontent.com/huggingface/trl/main/trl/scripts/sft.py" \
--model_name_or_path Qwen/Qwen2.5-3B-Instruct \
--dataset_name open-thoughts/OpenThoughts-114k \
--learning_rate 2.0e-5 \
--num_train_epochs 1 \
--packing \
--per_device_train_batch_size 2 \
--gradient_accumulation_steps 16 \
--eval_strategy no \
--use_peft \
--lora_r 256 \
--lora_alpha 16 \
--lora_target_modules all-linear \
--output_dir Qwen2.5-3B-OpenThoughts-LoRA \
--report_to trackio \
--push_to_hub
لتشغيل السكربت محليًا، ستحتاج إلى تثبيت uv. راجع وثائق uv لمزيد من التفاصيل.
بمجرد بدء التدريب، يمكنك مراقبة التقدم في Trackio، حيث سيتم تسجيل عنوان URL.
التعلم المعزز (GRPO)
يُنفّذ المقال المنشور على المدونة خوارزمية GRPO على مجموعة من النماذج ومجموعات البيانات من Hub، ويمكننا مرة أخرى إعادة إنتاج النتائج في TRL.
| النموذج | مجموعة البيانات |
|---|---|
| Llama-3.1-8B-Base | GSM8k |
| Llama-3.1-8B-Base | DeepMath-103K |
| Qwen3-8b-base | DeepMath-103K |
لتعلم التعزيز، يستخدم المدونة مهمة استدلال رياضي يمكننا إعادة إنتاجها كدالة بلغة بايثون.
يمكننا تنفيذ هذه التوصيات باستخدام واجهة TRL البرمجية بلغة بايثون على النحو التالي:
from datasets import load_dataset
from peft import LoraConfig
from trl import GRPOConfig, GRPOTrainer
from trl.rewards import reasoning_accuracy_reward
dataset = load_dataset("HuggingFaceH4/OpenR1-Math-220k-default-verified", split="train")
peft_config = LoraConfig(
r=1,
lora_alpha=32,
target_modules="all-linear"
)
training_args = GRPOConfig(
learning_rate=5e-5,
per_device_train_batch_size=1,
gradient_accumulation_steps=4,
num_train_epochs=1,
num_generations=8,
generation_batch_size=8,
report_to=["trackio"],
)
trainer = GRPOTrainer(
model="Qwen/Qwen3-0.6B",
reward_funcs=reasoning_accuracy_reward,
args=training_args,
train_dataset=dataset,
peft_config=peft_config,
)
trainer.train()
يتخطّى هذا المقطع دالة المكافأة التي عُرِّفت أعلاه للحفاظ على إيجاز المثال.
hf jobs uv run \
--flavor a100-large \
--timeout 4h \
--secrets HF_TOKEN \
--env PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True \
"https://huggingface.co/datasets/burtenshaw/lora-without-regrets/resolve/main/grpo.py" \
--model_name_or_path Qwen/Qwen3-0.6B \
--dataset_name HuggingFaceH4/OpenR1-Math-220k-default-verified \
--output_dir grpo-full-qwen3-0.6b \
--learning_rate 1.0e-6 \
--lr_scheduler_type cosine \
--warmup_steps 0.0 \
--max_grad_norm 1.0 \
--beta 0.0 \
--max_completion_length 4096 \
--num_generations 16 \
--generation_batch_size 16 \
--gradient_accumulation_steps 8 \
--per_device_train_batch_size 1 \
--num_train_epochs 1 \
--lora_r 1 \
--lora_alpha 32 \
--lora_dropout 0.0 \
--lora_target_modules all-linear \
--vllm_mode colocate \
--save_strategy steps \
--save_steps 50 \
--save_total_limit 1 \
--logging_steps 1 \
--max_steps 200 \
--report_to trackioلاستخدام Hugging Face Jobs، سجّل الدخول إلى Hub (hf auth login) وتأكّد من وجود رصيد موجب. راجع توثيق Jobs للاطلاع على التفاصيل.
uv run "https://huggingface.co/datasets/burtenshaw/lora-without-regrets/resolve/main/grpo.py" \
--model_name_or_path Qwen/Qwen3-0.6B \
--dataset_name HuggingFaceH4/OpenR1-Math-220k-default-verified \
--output_dir grpo-full-qwen3-0.6b \
--learning_rate 1.0e-6 \
--lr_scheduler_type cosine \
--warmup_steps 0.0 \
--max_grad_norm 1.0 \
--beta 0.0 \
--max_completion_length 4096 \
--num_generations 16 \
--generation_batch_size 16 \
--gradient_accumulation_steps 8 \
--per_device_train_batch_size 1 \
--num_train_epochs 1 \
--lora_r 1 \
--lora_alpha 32 \
--lora_dropout 0.0 \
--lora_target_modules all-linear \
--vllm_mode colocate \
--save_strategy steps \
--save_steps 50 \
--save_total_limit 1 \
--logging_steps 1 \
--max_steps 200 \
--report_to trackioلتشغيل السكربت محليًا، ستحتاج إلى تثبيت uv. راجع وثائق uv لمزيد من التفاصيل.
تم تنفيذ سكربت التعلم المعزز باستخدام GRPO على شكل سكربت مخصص في TRL، والذي يستخدم دالة المكافأة المعروضة أعلاه. يمكنك مراجعته في grpo.py - أفضل الممارسات للتعلم المعزز باستخدام LoRA
النتائج الرئيسية في تحسين LoRA
يوصي المؤلفون بتطبيق LoRA على جميع مصفوفات الأوزان بدلاً من تقييده بطبقات الانتباه، حيث إن زيادة الرتبة لا تعوّض عن هذا التقييد. في TRL، يمكن ضبط ذلك باستخدام --lora_target_modules all-linear لتطبيق LoRA على جميع مصفوفات الأوزان.
تمكّنّا من إعادة إنتاج نتائج منشور المدونة باستخدام TRL ونموذج SmolLM3. درّبنا النموذج لمدة 500 خطوة على مجموعة بيانات Math 220k باستخدام دالة المكافأة والإعداد المذكورين أعلاه. وكما ترون في الشكل أدناه، فإن منحنى متوسط مكافأة التدريب لنموذج LoRA يتطابق مع منحنى الضبط الدقيق الكامل.

والأهم من ذلك، أن نموذج LoRA يستخدم ذاكرة أقل بكثير من نموذج الضبط الكامل، كما نرى في الشكل أدناه.

فيما يلي المعاملات التي استخدمناها لتدريب النماذج المذكورة أعلاه
| معامل | LoRA | التدريب الكامل |
|---|---|---|
--model_name_or_path | HuggingFaceTB/SmolLM3-3B | HuggingFaceTB/SmolLM3-3B |
--dataset_name | HuggingFaceH4/OpenR1-Math-220k-default-verified | HuggingFaceH4/OpenR1-Math-220k-default-verified |
--learning_rate | 1.0e-5 | 1.0e-6 |
--max_completion_length | 4096 | 4096 |
--lora_r | 1 | - |
--lora_alpha | 32 | - |
--lora_dropout | 0.0 | - |
--lora_target_modules | all-linear | - |
لنقم بتحليل النتائج الرئيسية للمدونة وكيفية تمكّننا من إعادة إنتاجها.
1. يؤدي LoRA بشكل أفضل عند تطبيقه على جميع مصفوفات الأوزان
يوصي المؤلفون بتطبيق LoRA على جميع مصفوفات الأوزان بدلاً من تقييده بطبقات الانتباه، حيث إن زيادة الرتبة لا تعوّض عن هذا التقييد.

تُظهر LoRA التي تُطبَّق على طبقات الانتباه فقط أداءً أدنى حتى عند استخدام رتبة أعلى لمطابقة عدد المعاملات. في TRL، يمكن ضبط ذلك باستخدام --lora_target_modules all-linear لتطبيق LoRA على جميع مصفوفات الأوزان. في Python، يمكننا القيام بذلك على النحو التالي:
from peft import LoraConfig
peft_config = LoraConfig(target_modules="all-linear") 2. يحتاج المُكيّف إلى سعة كافية ليتعلم من مجموعة البيانات
توصي المقالة المنشورة على المدونة باستخدام رتبة LoRA كافية للتعلم من مجموعة البيانات. تحدد الرتبة عدد المعلمات القابلة للتدريب في مُكيّف LoRA. لذلك، “بالنسبة لمجموعات البيانات التي تتجاوز سعة LoRA، يكون أداء LoRA أقل من أداء FullFT”.

في سكريبت TRL، يمكننا استخدام --lora_r لضبط الرتبة (rank) وتكييفها بناءً على المهمة ومجموعة البيانات التي نتدرب عليها. يوصي المقال التالي بالرتب التالية اعتمادًا على حجم المهمة ومجموعة البيانات:
تتطلب مهام التعلم المعزز عادةً سعة أقل، لذا يمكن استخدام رتب LoRA أصغر. ويعود ذلك إلى أن خوارزميات تدرج السياسة تستخرج ما يقرب من ~1 بت من المعلومات لكل حلقة، مما يتطلب سعة معاملات دنيا.
يحدد منشور المدونة حجم مجموعة البيانات المثالي لـ LoRA لمطابقة الضبط الكامل على أنه “مقياس ما بعد التدريب”. والذي يمكننا استخدامه لتحديد الرتبة الموصى بها لـ LoRAs الخاصة بالضبط الإشرافي (SFT) والتعلم المعزز (RL) على النحو التالي:
| نوع المهمة | حجم مجموعة البيانات | الرتبة الموصى بها |
|---|---|---|
| SFT | مقياس ما بعد التدريب | 256 |
| التعلم المعزز | أي حجم | 1-32 |
3. “منحنى تعلّم FullFT وLoRAs ذات الرتبة العالية متشابه”
على عكس ما قد يتوقع المرء، يوصي المقال باستخدام معدل تعلّم أعلى من ذلك المستخدم في الضبط الكامل. في الجدول أعلاه، استخدمنا 1.0e-5 لـ LoRA و 1.0e-6 للضبط الكامل. في سكريبت TRL، يمكننا استخدام --learning_rate لتعيين معدل التعلّم. يؤدي التدرّج في LoRA إلى أن يكون معدل التعلّم الأمثل مستقلاً تقريباً عن الرتبة.

4. “في بعض السيناريوهات، يكون LoRA أقل تحمّلًا لحجم الدفعة الكبير مقارنةً بالتدريب الدقيق الكامل.”
توصي المقالة باستخدام حجم دفعة فعال < 32 لأن المؤلفين وجدوا أن LoRA أقل تحملاً لحجم الدفعة الكبير. ولم يكن من الممكن التخفيف من ذلك عن طريق زيادة رتبة LoRA. في سكريبت TRL، يمكننا استخدام --per_device_train_batch_size و--gradient_accumulation_steps لضبط حجم الدفعة.

الخلاصات
باستخدام TRL، يمكنك تنفيذ محولات LoRA بكفاءة لمطابقة أداء الضبط الكامل، مع تطبيق الرؤى الأساسية (استهداف جميع مصفوفات الأوزان، واختيار الرتبة المناسبة، وإدارة حجم الدفعة ومعدل التعلم) دون التكلفة الحسابية الثقيلة لـ FullFT.
الاستشهاد
@article{schulman2025lora,
title = {{LoRA Without Regret}},
author = {John Schulman and Thinking Machines Lab},
year = 2025,
journal = {Thinking Machines Lab: Connectionism},
doi = {10.64434/tml.20250929},
note = {https://thinkingmachines.ai/blog/lora/}
}