TRL documentation
التدريب باستخدام المهام
التدريب باستخدام المهام
يعمل Hugging Face Jobs على تشغيل التدريب الخاص بك على وحدات معالجة الرسوميات (GPUs) لدى Hugging Face. تختار العتاد لكل عملية تشغيل وتدفع فقط مقابل الثواني التي تستغرقها. باستخدام --push_to_hub، يتم رفع النموذج المُدرَّب إلى Hub في النهاية.
في هذا الدليل، ستتعلم كيفية:
- شغّل سكربت تدريب TRL بأمر واحد
- تتبّع تشغيلًا وشاهد منحنيات فقدانه
- شغّل سكربتك الخاص، مع إعدادات العتاد في الملف
- حافظ على نقاط التفتيش واستأنف تشغيلًا مُقاطَعًا
- التدريب على عدة وحدات معالجة رسومية
لمعرفة كيفية عمل Jobs بشكل عام، بما في ذلك الأجهزة والأسعار، راجع توثيق Jobs.
المتطلبات
- حساب Hugging Face برصيد إيجابي. تُحسب تكلفة المهام حسب الاستخدام: تدفع فقط مقابل الثواني التي تستخدمها.
- تم تسجيل الدخول إلى Hugging Face Hub (
hf auth login)
أول تشغيل
يعمل هذا الأمر على ضبط Qwen2-0.5B-Instruct على مجموعة بيانات المحادثة Capybara باستخدام سكريبت TRL SFT، ثم يدفع النموذج إلى حسابك:
hf jobs uv run \
--flavor a10g-small \
--timeout 30m \
--secrets HF_TOKEN \
-- \
https://raw.githubusercontent.com/huggingface/trl/refs/heads/main/trl/scripts/sft.py \
--model_name_or_path Qwen/Qwen2-0.5B-Instruct \
--dataset_name trl-lib/Capybara \
--max_steps 100 \
--output_dir Qwen2-0.5B-SFT \
--push_to_hubfrom huggingface_hub import run_uv_job
run_uv_job(
"https://raw.githubusercontent.com/huggingface/trl/refs/heads/main/trl/scripts/sft.py",
flavor="a10g-small",
timeout="30m",
secrets={"HF_TOKEN": "hf_..."},
script_args=[
"--model_name_or_path", "Qwen/Qwen2-0.5B-Instruct",
"--dataset_name", "trl-lib/Capybara",
"--max_steps", "100",
"--output_dir", "Qwen2-0.5B-SFT",
"--push_to_hub",
],
)يستغرق الأمر بضع دقائق وتكلفته أقل بكثير من 1 دولار على a10g-small. الخيارات قبل -- مخصصة للمهام: العتاد، وحد زمني، والرمز المستخدم لدفع النموذج. --secrets HF_TOKEN يرسل الرمز الذي سجّلت به الدخول. في Python، مرّر الرمز نفسه. الحُجج التي تأتي بعد عنوان URL الخاص بالسكريبت تُمرَّر إلى السكريبت. hf jobs uv run يشغّل سكريبت Python باستخدام uv. sft.py يُدرج تبعياته في ترويسة أعلى الملف، لذا تُثبّت المهام TRL قبل بدء السكريبت. تتوقف المهمة عند خروج السكريبت، ويتوقف الفوترة معها.
يحافظ --max_steps 100 على قصر هذه الجولة الأولى. احذفه للتشغيل الكامل: ثلاث فترات تدريب، وهو الافتراضي في السكربت، تستغرق بضع ساعات على a10g-small، لذا ارفع --timeout ليتناسب مع ذلك، على سبيل المثال --timeout 3h. يوقف Jobs التشغيل عند بلوغه مهلة الانتهاء، وهي 30 دقيقة افتراضيًا. تُنهي بطاقة GPU أكبر مثل a100-large العملية في وقت أقصر. راجع Hardware لمعرفة الأنواع وأسعارها.
تابع التشغيل
hf jobs uv run يبث السجلات ويُبقي الطرفية مفتوحة حتى انتهاء التشغيل. اضغط على Ctrl+C لإيقاف بث السجلات فقط: يستمر التشغيل في العمل. أضف --detach للحصول على معرّف التشغيل فورًا، ثم:
hf jobs logs -f <job_id> # stream the logs
hf jobs ps # list your running Jobs
hf jobs inspect <job_id> # status, and the error message if it failed
hf jobs cancel <job_id> # stop itراجع إدارة المهام لمزيد من التفاصيل.
من أجل منحنيات الخسارة، يسجّل TRL البيانات في Trackio. أضف --env TRACKIO_SPACE_ID=<your-username>/trackio قبل -- لتسمية مساحة (Space) للوحة المعلومات، وأضف --report_to trackio بعد عنوان URL الخاص بالسكريبت. يقوم Trackio بإنشاء المساحة، وحاوية (bucket) للمقاييس، إذا لم تكن موجودة. كلاهما عام افتراضيًا. تعمل أيضًا أدوات التتبع الأخرى التي يدعمها Transformers. بالنسبة إلى Weights & Biases، أضف --with wandb --secrets WANDB_API_KEY قبل -- وأضف --report_to wandb بعد عنوان URL الخاص بالسكريبت. يقرأ --secrets WANDB_API_KEY القيمة من WANDB_API_KEY في بيئة النظام المحلية. راجع متغيرات البيئة والأسرار لمعرفة طرق أخرى لتمريرها.
تشغيل سكربت خاص بك
اكتب كود التدريب الخاص بك في ملف بايثون (على سبيل المثال، train.py). اذكر تبعياته في أعلى الملف، في ترويسة السكربت، بنفس الطريقة التي تتبناها سكربتات TRL. يقوم Jobs بتثبيتها قبل بدء السكربت:
# /// script
# dependencies = [
# "trl",
# "peft",
# ]
# ///
from datasets import load_dataset
from peft import LoraConfig
from trl import SFTConfig, SFTTrainer
dataset = load_dataset("trl-lib/Capybara", split="train")
trainer = SFTTrainer(
model="Qwen/Qwen2.5-0.5B",
train_dataset=dataset,
peft_config=LoraConfig(),
args=SFTConfig(output_dir="Qwen2.5-0.5B-SFT", max_steps=100),
)
trainer.train()
trainer.push_to_hub()ثم شغّله باستخدام واجهة سطر الأوامر hf jobs أو واجهة برمجة التطبيقات بلغة بايثون:
hf jobs uv run \
--flavor a10g-small \
--timeout 30m \
--secrets HF_TOKEN \
train.pyfrom huggingface_hub import run_uv_job
run_uv_job(
"train.py",
flavor="a10g-small",
timeout="30m",
secrets={"HF_TOKEN": "hf_..."},
)بالنسبة إلى سكربت لا يحتوي على ترويسة، اذكر الاعتماديات عند التشغيل بدلاً من ذلك باستخدام --with، مرة واحدة لكل حزمة: --with trl --with peft (dependencies=["trl", "peft"] في Python). كما يمكن أن يكون السكربت رابط URL، مثل رابط خام من GitHub، أو Gist، أو ملف في مستودع عام على Hub.
يمكن أن تُوضع إعدادات الإطلاق أيضًا داخل السكربت. جدول [tool.hf-jobs] في الترويسة يحدد العتاد، والوقت الأقصى، والأسرار:
# /// script
# dependencies = [
# "trl",
# "peft",
# ]
#
# [tool.hf-jobs]
# flavor = "a10g-small"
# timeout = "30m"
# secrets = ["HF_TOKEN"]
# ///hf jobs uv run train.py لا يحتاج إلى خيارات بعد الآن، والخيار الذي تمرره لا يزال يتجاوز إعدادات السكربت. يحمل السكربت كل ما يحتاجه للتشغيل، لذا يمكنك مشاركته، أو العودة إليه لاحقًا، دون الحاجة إلى تذكر بطاقة الـ GPU ومهلة الإيقاف التي يحتاجها. يعرض hf jobs uv run --dry-run train.py الإعدادات المُحلَّلة ويحدد القيم القادمة من السكربت. تُقرأ الجدولة بواسطة hf CLI فقط: يتجاهل run_uv_job() الجدولة. راجع تعريف إعدادات الإقلاع في السكربت.
تشغيل أي سكريبت TRL
يتبع هذا النمط نفسه كل سكربتات مدرّبي TRL (SFT وDPO وGRPO ونمذجة المكافآت وغيرها) وكذلك الأمثلة المستقلة .py في فهرس الأمثلة. يُصرّح كل سكربت بتبعياته في ترويسة السكربت. يحتاج المثال الذي يقرأ ملفات أخرى مجاورة له إلى تركيب مجلده داخل المهمة. راجع المجلدات المحلية. لا يمكن إرسال الأمثلة المخصصة للدفاتر فقط بهذه الطريقة. حُجج السكربت هي نفسها عند تشغيل السكربت محليًا.
حافظ على نقاط التفتيش
يتم حذف القرص الخاص بالمهمة (Job) عند انتهائها، بما في ذلك عند بلوغها مهلة الانتهاء أو عند فشلها. في حال التشغيل لفترات طويلة، احفظ نقاط التفتيش (checkpoints) خارج المهمة حتى تبقى محفوظة بعد انتهائها.
أبسط طريقة هي دفع كل نقطة تحقق إلى مستودع النموذج الإخراجي عند حفظها:
hf jobs uv run \
--flavor a10g-small \
--timeout 3h \
--secrets HF_TOKEN \
-- \
https://raw.githubusercontent.com/huggingface/trl/refs/heads/main/trl/scripts/sft.py \
--model_name_or_path Qwen/Qwen2-0.5B-Instruct \
--dataset_name trl-lib/Capybara \
--output_dir Qwen2-0.5B-SFT \
--push_to_hub \
--save_steps 500 \
--hub_strategy checkpointfrom huggingface_hub import run_uv_job
run_uv_job(
"https://raw.githubusercontent.com/huggingface/trl/refs/heads/main/trl/scripts/sft.py",
flavor="a10g-small",
timeout="3h",
secrets={"HF_TOKEN": "hf_..."},
script_args=[
"--model_name_or_path", "Qwen/Qwen2-0.5B-Instruct",
"--dataset_name", "trl-lib/Capybara",
"--output_dir", "Qwen2-0.5B-SFT",
"--push_to_hub",
"--save_steps", "500",
"--hub_strategy", "checkpoint",
],
)مع --hub_strategy checkpoint، يُحفظ أحدث نقطة تفتيش، بما في ذلك حالة المُحسِّن، في مجلد last-checkpoint ضمن المستودع. لاستئناف تشغيلٍ مُقاطَع، اربط المستودع بوظيفة جديدة واستأنف من ذلك المجلد: شغّل الأمر نفسه مع --volume hf://<your-username>/Qwen2-0.5B-SFT:/previous قبل -- و--resume_from_checkpoint /previous/last-checkpoint بعد عنوان URL الخاص بالسكريبت.
لإبقاء عدة نقاط تحقق خارج مستودع النموذج، اكتبها في Storage Bucket بدلاً من ذلك. أنشئ واحداً باستخدام hf buckets create <your-username>/checkpoints --private، ثم اربطه بالمهمة وجعل --output_dir يشير إليه:
hf jobs uv run \
--flavor a10g-small \
--timeout 3h \
--secrets HF_TOKEN \
--volume hf://buckets/<your-username>/checkpoints:/checkpoints \
-- \
https://raw.githubusercontent.com/huggingface/trl/refs/heads/main/trl/scripts/sft.py \
--model_name_or_path Qwen/Qwen2-0.5B-Instruct \
--dataset_name trl-lib/Capybara \
--output_dir /checkpoints/Qwen2-0.5B-SFT \
--save_steps 500from huggingface_hub import Volume, run_uv_job
run_uv_job(
"https://raw.githubusercontent.com/huggingface/trl/refs/heads/main/trl/scripts/sft.py",
flavor="a10g-small",
timeout="3h",
secrets={"HF_TOKEN": "hf_..."},
volumes=[Volume(type="bucket", source="<your-username>/checkpoints", mount_path="/checkpoints")],
script_args=[
"--model_name_or_path", "Qwen/Qwen2-0.5B-Instruct",
"--dataset_name", "trl-lib/Capybara",
"--output_dir", "/checkpoints/Qwen2-0.5B-SFT",
"--save_steps", "500",
],
)للمتابعة من تشغيلٍ مُقاطَع، شغّل الأمر نفسه مرة أخرى مع --resume_from_checkpoint /checkpoints/Qwen2-0.5B-SFT/checkpoint-<step>. راجع الكتابة إلى الدلو أثناء التقدم لمزيد من التفاصيل، وVolumes لخيارات التركيب.
تحتوي كل نقطة تحقق على حالة النموذج والمُحسِّن، بحجم يتجاوز حجم النموذج عدة مرات. أضف
--save_total_limit 2للاحتفاظ بالأحدث فقط. إذا مررت أيضًا--push_to_hub، فعيّن--hub_model_id، أو يُسمّى المستودع باسم الجزء الأخير من مسار الإخراج.
بطاقات رسومات متعددة
يُسرّع استخدام نكهة تحتوي على عدة وحدات معالجة رسومية (GPU) من زمن التشغيل. ولتحقيق ذلك، استخدم hf jobs run، الذي يشغّل أمرًا داخل صورة Docker بدلاً من سكربت، مع استخدام صورة huggingface/trl التي تم تثبيت TRL وAccelerate فيها. ثم ابدأ عملية واحدة لكل وحدة معالجة رسومية. يعمل هذا النهج مع سكربتات TRL ومع كود التدريب الخاص بك.
تسريع سكريبت TRL
تشغيل SFT من بداية هذا الدليل، على أربعة وحدات معالجة رسومية (GPU):
hf jobs run \
--flavor l4x4 \
--timeout 30m \
--secrets HF_TOKEN \
huggingface/trl \
-- \
trl sft --nproc_per_node 4 \
--model_name_or_path Qwen/Qwen2-0.5B-Instruct \
--dataset_name trl-lib/Capybara \
--max_steps 100 \
--output_dir Qwen2-0.5B-SFT \
--push_to_hubfrom huggingface_hub import run_job
run_job(
image="huggingface/trl",
command=[
"trl", "sft", "--nproc_per_node", "4",
"--model_name_or_path", "Qwen/Qwen2-0.5B-Instruct",
"--dataset_name", "trl-lib/Capybara",
"--max_steps", "100",
"--output_dir", "Qwen2-0.5B-SFT",
"--push_to_hub",
],
flavor="l4x4",
timeout="30m",
secrets={"HF_TOKEN": "hf_..."},
)يقوم سطر أوامر trl بتمرير --nproc_per_node إلى torchrun. اضبطه على عدد وحدات معالجة الرسومات في الباقة، وهنا أربع وحدات L4. يأخذ كل عملية دفعتها الخاصة، لذا فإن حجم الدفعة الفعلي هو أربعة أضعاف حجم الدفعة في تشغيل وحدة معالجة رسومات واحدة. يستغرق هذا التشغيل بضع دقائق. بدون --max_steps، تستغرق الفترات الثلاث الكاملة تقريباً ساعة واحدة، لذا ارفع قيمة --timeout، على سبيل المثال إلى 2h.
سكربتك الخاص
لستَ مقيدًا بسكربتات TRL. فأي كود تدريب يعمل محليًا باستخدام torchrun سيعمل بالطريقة نفسها على Jobs، ما دام أن الصورة تحتوي على الحزم التي يحتاجها. على سبيل المثال، احفظ سكربت GRPO مع دالة المكافأة الخاصة بك باسم train_grpo.py في مجلد، ثم اربط المجلد بـ Job. يقوم Jobs برفع المجلد إلى دلو خاص ويربطه للقراءة فقط:
hf jobs run \
--flavor l4x4 \
--timeout 30m \
--secrets HF_TOKEN \
--volume ./my-project:/code \
huggingface/trl \
-- \
torchrun --nproc_per_node 4 /code/train_grpo.pyfrom huggingface_hub import run_job, sync_job_volume
code = sync_job_volume("./my-project", "/code")
run_job(
image="huggingface/trl",
command=["torchrun", "--nproc_per_node", "4", "/code/train_grpo.py"],
flavor="l4x4",
timeout="30m",
secrets={"HF_TOKEN": "hf_..."},
volumes=[code],
)يعمل السكربت مع TRL المثبت في الصورة، لذا لا يحتاج إلى ترويسة سكربت. يولّد GRPOTrainer الإكمالات باستخدام transformers افتراضيًا، لذا يعمل هذا في مهمة واحدة دون خادم vLLM. للحصول على توليد أسرع، راجع تكامل vLLM. يشرح القسم التالي كيف يستخدم hf jobs run الصورة.
صور Docker
تشغّل Jobs سكربت الخاص بك باستخدام uv، والذي يقوم بتثبيت التبعيات المُعلَنة في ترويسة # /// script الخاصة به داخل بيئة جديدة. وبالتالي، فإن نسخة TRL التي يستوردها سكربتك تأتي من تلك الترويسة وليس من الصورة، ولا تحتاج أمثلة hf jobs uv run المذكورة أعلاه إلى --image على الإطلاق.
يتوفر صورة Docker مع TRL مثبتة مسبقًا في huggingface/trl. عند تمريرها إلى hf jobs uv run، يحصل المهمة على الطبقة النظامية للصورة، مثل سلسلة أدوات CUDA، وهو أمر مهم للتعتمدات التي تُترجم ضدها:
hf jobs uv run \
--flavor a100-large \
--secrets HF_TOKEN \
--image huggingface/trl \
train.pyfrom huggingface_hub import run_uv_job
run_uv_job(
"train.py",
flavor="a100-large",
secrets={"HF_TOKEN": "hf_..."},
image="huggingface/trl",
)لتشغيل TRL المثبت في الصورة، استخدم hf jobs run بدلاً من ذلك. فهو يشغّل أمرًا داخل الصورة مباشرة، دون ترويسة سكربت يجب حلها، لذا فإن TRL الخاص بالصورة هو ما يُنفَّذ. يفصل -- بين الأمر وخيارات Jobs، وهو أمر مطلوب كلما كان الأمر نفسه يتخذ خيارات:
hf jobs run \
--flavor a100-large \
--secrets HF_TOKEN \
huggingface/trl \
-- \
trl sft --model_name_or_path Qwen/Qwen2-0.5B-Instruct --dataset_name trl-lib/Capybara --output_dir Qwen2-0.5B-SFTfrom huggingface_hub import run_job
run_job(
image="huggingface/trl",
command=[
"trl", "sft",
"--model_name_or_path", "Qwen/Qwen2-0.5B-Instruct",
"--dataset_name", "trl-lib/Capybara",
"--output_dir", "Qwen2-0.5B-SFT",
],
flavor="a100-large",
secrets={"HF_TOKEN": "hf_..."},
)تُنشر الصورة تحت ثلاثة أنواع من الوسوم:
| وسم | المحتويات |
|---|---|
X.Y.Z | إصدار TRL لذلك الإصدار، الذي يُبنى عند إصدار ذلك الإصدار |
latest | أحدث إصدار |
dev | فرع main، يُعاد بناؤه مع كل عملية دمج |
استخدم dev لتشغيل نسخة التطوير، وهو أمر مفيد لتجربة إصلاح تم دمجه في main لكنه لم يُصدر بعد:
hf jobs run \
--flavor a100-large \
--secrets HF_TOKEN \
huggingface/trl:dev \
-- \
trl sft --model_name_or_path Qwen/Qwen2-0.5B-Instruct --dataset_name trl-lib/Capybara --output_dir Qwen2-0.5B-SFTfrom huggingface_hub import run_job
run_job(
image="huggingface/trl:dev",
command=[
"trl", "sft",
"--model_name_or_path", "Qwen/Qwen2-0.5B-Instruct",
"--dataset_name", "trl-lib/Capybara",
"--output_dir", "Qwen2-0.5B-SFT",
],
flavor="a100-large",
secrets={"HF_TOKEN": "hf_..."},
)تحدد الوسوم فقط ما هو مثبّت في الصورة، لذا فهي مهمة لـ hf jobs run. أما مع hf jobs uv run، فيأتي الإصدار من ترويسة السكربت بدلاً من ذلك، ولا يؤثر الوسم على أي إصدار من TRL يتم استيراده.
يجمع بين الأمرين بحيث يحل uv ترويسة السكربت بينما تبقى بعض الاستيرادات قادمة من الصورة، يتطلب ذلك أعلامًا إضافية. راجع إعادة استخدام حزم الصورة وإضافة تبعيات باستخدام UV لهذا الشكل والمسارات التي يتطلبها.
يعمل Jobs على صورة Docker من Hugging Face Spaces أو Docker Hub، لذا يمكنك أيضًا تحديد أي صورة مخصصة:
hf jobs uv run \
--flavor a100-large \
--secrets HF_TOKEN \
--image <docker-image> \
train.pyfrom huggingface_hub import run_uv_job
run_uv_job(
"train.py",
flavor="a100-large",
secrets={"HF_TOKEN": "hf_..."},
image="<docker-image>",
)Update on GitHubيطلق غلاف TRL Jobs سكربتات TRL على Jobs مع إعدادات مسبقة لبعض النماذج، على سبيل المثال
trl-jobs sft --model_name Qwen/Qwen3-0.6B --dataset_name trl-lib/Capybara.