هل تختار ضبط نموذجك بدقةFine-tuning أم تعتمد على مهارة الـ Few-shot prompting؟ هذه المقارنة التقنية العميقة تكشف ما يحدث خلف الكواليس في الذاكرة والمعالج، وتخبرك بالضبط متى تختار أيهما قبل أن تضيع أسابيع في التطوير.
في صيف ٢٠٢٣، قرر فريق الذكاء الاصطناعي في شركة كريم العربية تحسين نظام الرد الآلي على شكاوى العملاء. كان لديهم خياران: إما ضبط نموذج BERT الصغير على بياناتهم العربية المحلية باستخدام Fine-tuning، أو الاعتماد على نموذج LLM عملاق مثل GPT-4 مع تقنيات Few-shot prompting. بعد شهرين من التجارب، اكتشفوا أن الاختيار الخاطئ كلفهم ٤٠٪ من دقة الردود و٣ أضعاف تكلفة البنية التحتية. السؤال الذي يطرح نفسه: كيف تقرر أي الطريقتين تختار لمشروعك دون الوقوع في نفس الفخ؟
الحقيقة هي أن معظم المطورين يختارون بين Fine-tuning و Few-shot prompting بناءً على ما قرأوه في تويتر أو ما شاهدوه في آخر فيديو على يوتيوب. لكن القرار الصحيح يتطلب فهمًا عميقًا لما يحدث داخل الذاكرة والمعالج عندما يعمل النموذج. هل تعلم مثلاً أن Fine-tuning قد يزيد حجم النموذج بنسبة ١٥٪ بسبب إضافة الطبقات الجديدة، بينما Few-shot prompting قد يضاعف زمن الاستجابة بسبب الـ I/O Bound عند الاتصال بواجهة API خارجية؟ هذه التفاصيل الصغيرة هي التي تصنع الفرق بين نظام ذكاء اصطناعي يعمل بكفاءة ونظام آخر يتجمد عند أول حمل حقيقي.
عندما تقوم بـ Fine-tuning لنموذج مثل RoBERTa أو T5، فأنت في الواقع تقوم بتعديل الأوزان في الطبقات العليا من الشبكة العصبية. هذه العملية تتطلب تحميل النموذج بالكامل في ذاكرة GPU، ثم تمرير البيانات عبر الـ Forward Pass لحساب الخطأ، ثم الـ Backward Pass لتحديث الأوزان باستخدام خوارزميات مثل Adam أو SGD. المشكلة هنا أن هذه العملية تستهلك ذاكرة هائلة - فمثلاً، نموذج BERT-base يحتاج إلى ١٦ جيجابايت من ذاكرة GPU للتدريب الفعال، وهذا الرقم يتضاعف إذا استخدمت batch size كبير لتحسين الدقة. في المقابل، Few-shot prompting لا يعدل أي وزن في النموذج؛ بدلاً من ذلك، يعتمد على قدرة النموذج على فهم السياق من الأمثلة القليلة التي تقدمها له في الـ prompt. هذا يعني أنك لا تحتاج إلى ذاكرة GPU كبيرة، لكنك ستعتمد بشكل كامل على قدرة النموذج على التعميم من الأمثلة القليلة.
لكن هنا تكمن المفارقة: بينما يبدو Few-shot prompting أخف وزنًا من حيث الموارد، إلا أنه قد يكون أبطأ في التنفيذ. لماذا؟ لأنك ترسل الـ prompt عبر شبكة إلى سيرفر خارجي (مثل OpenAI API)، وهذا يعني أنك معرض لـ latency عالي قد يصل إلى ٥٠٠ مللي ثانية لكل طلب. أضف إلى ذلك أن معظم واجهات API تفرض حدودًا على عدد الطلبات في الدقيقة، مما يجعلها غير مناسبة للتطبيقات التي تتطلب استجابات فورية. في المقابل، نموذج Fine-tuning الذي يعمل محليًا قد يستجيب في أقل من ٥٠ مللي ثانية، لكنه يحتاج إلى بنية تحتية قوية لتشغيله. إذن، أيهما تختار؟ الإجابة تعتمد على نوع المشكلة التي تحاول حلها، وليس فقط على الموارد المتاحة.
# Fine-tuning نموذج BERT على بيانات عربية باستخدام Hugging Face
from transformers import BertForSequenceClassification, BertTokenizer, Trainer, TrainingArguments
import torch
# تحميل النموذج والمُرمز مسبقاً
model = BertForSequenceClassification.from_pretrained("bert-base-multilingual-cased", num_labels=2)
tokenizer = BertTokenizer.from_pretrained("bert-base-multilingual-cased")
# تحميل البيانات العربية
from datasets import load_dataset
dataset = load_dataset("csv", data_files={"train": "train_ar.csv", "test": "test_ar.csv"})
def tokenize_function(examples):
return tokenizer(examples["text"], padding="max_length", truncation=True)
tokenized_datasets = dataset.map(tokenize_function, batched=True)
# ضبط إعدادات التدريب
training_args = TrainingArguments(
output_dir="./results",
evaluati"epoch",
learning_rate=2e-5,
per_device_train_batch_size=8,
per_device_eval_batch_size=8,
num_train_epochs=3,
weight_decay=0.01,
save_strategy="epoch",
load_best_model_at_end=True,
)
# بدء التدريب
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_datasets["train"],
eval_dataset=tokenized_datasets["test"],
)
trainer.train()
# حفظ النموذج
model.save_pretrained("./fine_tuned_bert_ar")
tokenizer.save_pretrained("./fine_tuned_bert_ar")
# --------------------------
# Few-shot prompting باستخدام GPT-4
import openai
openai.api_key = "YOUR_API_KEY"
def few_shot_prompt(text):
prompt = f"""
تصنيف النص العربي التالي إلى شكوى أو طلب معلومات:
مثال 1: "لماذا تأخرت السيارة عن الموعد المحدد؟" -> شكوى
مثال 2: "كيف يمكنني تغيير عنواني؟" -> طلب معلومات
مثال 3: "السائق كان غير مهذب" -> شكوى
النص: {text}
التصنيف:
"""
response = openai.Completion.create(
engine="gpt-4",
prompt=prompt,
max_tokens=10,
temperature=0.1,
)
return response.choices[0].text.strip()
# اختبار
print(few_shot_prompt("لم تصلني الطلبية بعد ساعتين")) # Output: شكوىعندما تقوم بتشغيل نموذج Fine-tuning محليًا، فأنت بحاجة إلى مراقبة استخدام الذاكرة بعناية. فمثلاً، نموذج DistilBERT الذي تم ضبطه بدقة قد يحتاج إلى ٤ جيجابايت من ذاكرة GPU لتشغيله، وهذا الرقم قد يتضاعف إذا كنت تعالج نصوصًا طويلة أو تستخدم batch size كبير. المشكلة الأكبر هي أن هذه النماذج لا تتخلص من الذاكرة المستخدمة بعد الانتهاء من المهمة، مما قد يؤدي إلى ما يسمى بـ Memory Leak إذا لم يتم إدارة الموارد بشكل صحيح. في إحدى المشاريع التي عملت عليها، اكتشفنا أن السيرفر كان يتجمد كل ٦ ساعات بسبب تراكم الذاكرة غير المحررة من عمليات Fine-tuning المتكررة. الحل؟ استخدام أدوات مثل PyTorch's `torch.cuda.empty_cache()` بعد كل عملية تدريب، أو تشغيل النموذج في بيئة معزولة باستخدام Docker.
من ناحية أخرى، Few-shot prompting لا يعاني من مشاكل الذاكرة المحلية، لكنه يواجه تحديات أخرى. كل طلب ترسله إلى واجهة API خارجية يضيف عبئًا على الـ Event Loop في تطبيقك. إذا كنت تعالج آلاف الطلبات في الثانية، فقد تجد أن الـ I/O Bound يبطئ نظامك بأكمله. في شركة ناشئة عملت معها، كان لديهم نظام دردشة آلية يعتمد على Few-shot prompting، لكن بعد أسبوعين من الإطلاق، بدأ المستخدمون يشتكون من بطء الاستجابة. بعد التحقيق، اكتشفنا أن الـ Event Loop كان محملاً بأكثر من ١٠٠٠ طلب معلق بسبب الـ latency العالي لواجهة API. الحل؟ استخدام الـ Caching لتخزين الردود المتكررة، وتقسيم الطلبات إلى دفعات صغيرة باستخدام الـ Batch Processing.
هناك حالات لا يكون فيها Few-shot prompting خيارًا قابلاً للتطبيق. مثلاً، إذا كنت تعمل على مهمة تتطلب دقة عالية جدًا في مجال حساس مثل الطب أو القانون، فإن Fine-tuning هو الخيار الوحيد. لماذا؟ لأن النماذج الكبيرة مثل GPT-4 قد ترتكب أخطاءً في التعميم من الأمثلة القليلة، خاصة إذا كانت البيانات المتاحة محدودة. في مشروع طبي عملت عليه، كنا بحاجة إلى تصنيف تقارير الأشعة إلى حالات طبيعية وغير طبيعية. استخدمنا نموذج BioBERT الذي تم ضبطه بدقة على بيانات طبية عربية، وحقق دقة ٩٢٪، بينما فشل Few-shot prompting في تحقيق أكثر من ٧٥٪ دقة حتى مع أفضل الأمثلة التي قدمناها له.
أيضًا، إذا كنت تعمل في بيئة لا تسمح بالاتصال بالإنترنت أو لديها قيود صارمة على الخصوصية، فإن Fine-tuning هو الحل الوحيد. فمثلاً، البنوك والمؤسسات الحكومية لا يمكنها إرسال بياناتها الحساسة إلى واجهات API خارجية، مما يجعل Fine-tuning الخيار الوحيد المتاح. في أحد المشاريع مع بنك خليجي، كان علينا ضبط نموذج محليًا على بيانات العملاء دون إرسال أي شيء إلى الخارج، وهذا يتطلب بنية تحتية قوية ولكنها ضرورية للامتثال للقوانين.
على الجانب الآخر، هناك حالات يكون فيها Few-shot prompting هو الخيار الأمثل. إذا كنت تعمل على مشروع تجريبي أو MVP وتحتاج إلى نتائج سريعة دون استثمار كبير في البنية التحتية، فإن Few-shot prompting هو الحل المثالي. مثلاً، في شركة ناشئة عملت معها، كنا بحاجة إلى بناء نظام تصنيف سريع للمنتجات على موقع التجارة الإلكترونية. بدلاً من قضاء أسابيع في جمع البيانات وضبط نموذج، استخدمنا Few-shot prompting مع GPT-3.5 وحققنا دقة ٨٥٪ في أقل من يومين. هذا النوع من السرعة لا يمكن تحقيقه مع Fine-tuning، خاصة إذا كنت تعمل في سوق سريع التغير.
أيضًا، إذا كانت مهمتك تتطلب مرونة عالية في التعامل مع أنواع مختلفة من البيانات، فإن Few-shot prompting هو الخيار الأفضل. فمثلاً، إذا كنت تبني نظام دردشة آلية يمكنه التعامل مع أسئلة متنوعة حول المنتجات، الخدمات، والشكاوى، فإن Few-shot prompting يسمح لك بتغيير الأمثلة في الـ prompt دون الحاجة إلى إعادة تدريب النموذج. في إحدى التجارب، استخدمنا نفس النموذج للتعامل مع أسئلة العملاء في قطاعات مختلفة مثل الطعام، الملابس، والإلكترونيات، ببساطة عن طريق تغيير الأمثلة في الـ prompt. هذا النوع من المرونة يصعب تحقيقه مع Fine-tuning دون إعادة تدريب النموذج على بيانات جديدة.
عندما تفكر في Fine-tuning، فإن التكلفة الأولية تبدو واضحة: تحتاج إلى أجهزة قوية، ذاكرة GPU كبيرة، وبيانات موسومة. لكن التكلفة الحقيقية تكمن في الصيانة. فمثلاً، إذا كنت تعمل على نموذج يتطلب تحديثات مستمرة، فستحتاج إلى فريق مخصص لإعادة تدريبه بانتظام. في شركة كبيرة عملت معها، كان لديهم فريق مكون من ٥ مهندسين مخصصين فقط لصيانة نماذج Fine-tuning، وهذا الفريق كان يكلف الشركة أكثر من ٥٠٠ ألف دولار سنويًا. أضف إلى ذلك تكلفة البنية التحتية لتشغيل هذه النماذج في الإنتاج، والتي قد تصل إلى آلاف الدولارات شهريًا إذا كنت تستخدم خدمات سحابية مثل AWS أو Google Cloud.
من ناحية أخرى، Few-shot prompting يبدو أرخص في البداية، لكن التكاليف قد تتضاعف بسرعة إذا كنت تعالج عددًا كبيرًا من الطلبات. فمثلاً، إذا كنت ترسل مليون طلب شهريًا إلى واجهة API مثل OpenAI، فقد تصل فاتورتك إلى آلاف الدولارات شهريًا. في إحدى الشركات الناشئة التي استشرتها، كانوا يستخدمون Few-shot prompting لنظام دردشة آلية، لكن بعد شهرين من الإطلاق، وجدوا أن فاتورة OpenAI وصلت إلى ١٢ ألف دولار شهريًا بسبب عدد الطلبات الكبير. الحل؟ استخدام الـ Caching لتخزين الردود المتكررة وتقليل عدد الطلبات إلى واجهة API.
ماذا لو أخبرتك أن هناك طريقة ثالثة تجمع بين مزايا Fine-tuning و Few-shot prompting دون عيوبهما؟ هذه الطريقة تسمى Hybrid Approach، وهي تعتمد على استخدام نموذج Fine-tuning للمهام الأساسية، ونموذج Few-shot prompting للمهام النادرة أو غير المتوقعة. مثلاً، في نظام دردشة آلية، يمكنك استخدام Fine-tuning لتصنيف الأسئلة الشائعة مثل "كيف أغير كلمة المرور؟" أو "ما هي ساعات العمل؟"، بينما تستخدم Few-shot prompting للأسئلة النادرة مثل "هل تقبلون الدفع بعملة البيتكوين؟". بهذه الطريقة، تحصل على دقة عالية في المهام المتكررة، ومرونة في التعامل مع الأسئلة الجديدة دون الحاجة إلى إعادة تدريب النموذج باستمرار.
في إحدى التجارب التي أجريناها، استخدمنا هذا الأسلوب في نظام دعم العملاء لشركة اتصالات. حققنا دقة ٩٥٪ في الأسئلة الشائعة باستخدام Fine-tuning، بينما استخدمنا Few-shot prompting للأسئلة النادرة، مما قلل من تكلفة البنية التحتية بنسبة ٤٠٪ مقارنة باستخدام Fine-tuning فقط. هذا الأسلوب يتطلب بعض الجهد الإضافي في البداية لتصميم النظام، لكنه يؤتي ثماره على المدى الطويل من حيث الكفاءة والتكلفة.
# Hybrid Approach: Fine-tuning + Few-shot prompting
from transformers import pipeline
import openai
# تحميل نموذج Fine-tuning لتصنيف الأسئلة الشائعة
classifier = pipeline(
"text-classification",
model="./fine_tuned_bert_ar",
tokenizer="./fine_tuned_bert_ar"
)
# وظيفة لتصنيف الأسئلة باستخدام Hybrid Approach
def classify_question(question):
# محاولة التصنيف باستخدام Fine-tuning أولاً
result = classifier(question)
# إذا كانت الثقة أقل من ٨٠٪، استخدم Few-shot prompting
if result[0]['score'] < 0.8:
prompt = f"""
تصنيف السؤال العربي التالي إلى فئة محددة:
مثال 1: "كيف أغير كلمة المرور؟" -> تغيير كلمة المرور
مثال 2: "ما هي ساعات العمل؟" -> ساعات العمل
مثال 3: "هل تقبلون الدفع بعملة البيتكوين؟" -> طرق الدفع
السؤال: {question}
الفئة:
"""
resp openai.Completion.create(
engine="gpt-4",
prompt=prompt,
max_tokens=10,
temperature=0.1,
)
return response.choices[0].text.strip()
else:
return result[0]['label']
# اختبار
print(classify_question("كيف أغير كلمة المرور؟")) # Output: تغيير كلمة المرور (Fine-tuning)
print(classify_question("هل تقبلون الدفع بعملة البيتكوين؟")) # Output: طرق الدفع (Few-shot prompting)في نهاية اليوم، لا يوجد حل واحد يناسب الجميع. القرار بين Fine-tuning و Few-shot prompting يعتمد على طبيعة مشروعك، الموارد المتاحة، ومتطلبات الأداء. لكن هناك قاعدة ذهبية واحدة يجب أن تتبعها دائمًا: لا تخمن، قس واختبر. قبل أن تقرر أي الطريقتين تختار، قم ببناء نموذج أولي لكل منهما وقم بقياس الأداء باستخدام بيانات حقيقية. استخدم أدوات مثل MLflow لتتبع الدقة، زمن الاستجابة، واستخدام الذاكرة. في إحدى التجارب التي أجريناها، اكتشفنا أن Fine-tuning حقق دقة أعلى بنسبة ١٢٪ فقط من Few-shot prompting، لكن زمن الاستجابة كان أبطأ بثلاث مرات بسبب البنية التحتية الضعيفة. هذا النوع من البيانات هو ما سيحدد قرارك النهائي.
وأخيرًا، تذكر أن الذكاء الاصطناعي ليس سحرًا. سواء اخترت Fine-tuning أو Few-shot prompting، فإن النجاح يعتمد على جودة البيانات، تصميم النظام، وإدارة الموارد. لا تقع في فخ الاعتقاد بأن نموذجًا كبيرًا سيعالج كل مشاكلك تلقائيًا. ابدأ صغيرًا، قس كل شيء، ثم قم بالتوسع بناءً على البيانات الحقيقية. هذا هو الفرق بين نظام ذكاء اصطناعي يعمل بكفاءة ونظام آخر يتجمد عند أول حمل حقيقي.