انتقل إلى المحتوى الرئيسي

الوحدة 10 — نماذج الأساس وحديقة النماذج

طوال الوحدات التسع الماضية بنينا نموذج XGBoost تدريبًا خاصًّا. الفيل الأحمر ينمو الآن ويحتاج ميزة إضافيّة: تصنيف تعليقات المتنازعين. حين ترفض معاملة، يفتح العميل نزاعًا ويكتب فقرة عربيّة (أحيانًا بالفرنسيّة أو الإنجليزيّة) يشرح فيها ما جرى. الفريق يحتاج تصنيف كلّ تعليق إلى واحدة من: احتيال حقيقيّ، خطأ تاجر، رسوم غير معروفة، خدمة غير مقدَّمة. لا مبرِّر لتدريب مصنّف نصّ من الصفر: نموذج أساس من Model Garden يفعل ذلك بأمر واحد.

ما هو Model Garden

Model Garden هو كتالوج نماذج داخل Vertex يجمع:

  • نماذج Google المِلكيّة: عائلة gemini، text-embedding-*، image-generation-*.
  • نماذج مفتوحة المصدر متاحة النشر مباشرة: Llama، Mistral، Gemma، Stable Diffusion، Whisper.
  • نماذج شركاء (Anthropic Claude عبر Vertex، مثلًا).

بدلًا من التفاوض على مفاتيح API متعدّدة، وحاويات مبنيّة يدويًّا، ومكتبات مختلفة، Model Garden يُقدِّم:

  • واجهة موحّدة: نفس SDK google-cloud-aiplatform يستدعي أيّ نموذج.
  • فوتَرة موحّدة: تظهر في نفس فاتورة GCP.
  • IAM موحّد: حساب الخدمة نفسه، سياسات المشروع نفسها.
  • نشر مُدار: نماذج مفتوحة المصدر تنشر بضغطة على نقطة نهاية Vertex بلا إدارة بنية تحتيّة.

استدعاء نموذج مِلكيّ

لتصنيف تعليقات النزاعات نستعمل نموذج gemini-2.5-flash: خفيف، سريع، ملائم للتصنيف الوصفيّ. أوّل مكالمة:

from vertexai.generative_models import GenerativeModel
import vertexai

vertexai.init(project="fraud-detection-lab", location="europe-west1")

model = GenerativeModel("gemini-2.5-flash")

comment = """رفضت معاملة قدرها 340 دولارًا عند متجر بالسعوديّة يوم 3 أيلول.
لم أشترِ شيئًا من ذلك المتجر، ولا أعرف أحدًا هناك. أعتقد أنّ بطاقتي سُرِقت."""

prompt = f"""صنّف التعليق التالي إلى واحدة من الفئات فقط، بلا شرح إضافيّ:
- FRAUDE_REELLE
- ERREUR_MARCHAND
- FRAIS_INCONNUS
- SERVICE_NON_RENDU

التعليق: {comment}

الفئة:"""

response = model.generate_content(prompt, generation_config={"temperature": 0.0})
print(response.text.strip())
# FRAUDE_REELLE

temperature=0.0 يجعل المخرج شبه محدَّد (deterministic)، وهو ما نريده للتصنيف. 1.0 مناسب للتوليد الإبداعيّ، لا للقرار.

تحسين الاستدعاء: مثال بسيط

النموذج بدون توجيه يعطي نتائج مقبولة، لكن بضعة أمثلة (few-shot) ترفع الدقّة كثيرًا:

prompt = """صنّف التعليق التالي إلى واحدة من الفئات فقط:
FRAUDE_REELLE | ERREUR_MARCHAND | FRAIS_INCONNUS | SERVICE_NON_RENDU

أمثلة:
تعليق: «دفعت 50 دولارًا لدفتر جاهز فأرسلوا كتابًا مختلفًا» ⇒ ERREUR_MARCHAND
تعليق: «سُرقت بطاقتي وسُحبت في مطعم لم أزره» ⇒ FRAUDE_REELLE
تعليق: «رأيت رسمًا شهريًّا من 15 دولارًا لا أذكر اشتراكه» ⇒ FRAIS_INCONNUS
تعليق: «دفعت مقابل رحلة طيران أُلغيت ولم أتلقَّ استردادًا» ⇒ SERVICE_NON_RENDU

الآن:
تعليق: «""" + comment + """»
الفئة:"""

هذه الأمثلة الأربعة تُوجِّه النموذج على تعريف كلّ فئة بلا حاجة إلى تخصيص أو مجموعة تدريب. مسار الحلّ في هندسة التعليمات هو موضوع الدورة 17 كاملةً؛ نُشير هنا فقط إلى الحدّ الأدنى المُثمر.

التخصيص المُدار (Supervised Tuning)

حين لا يكفي «التعليم بالأمثلة» — مثلًا لأنّ لغة تعليقاتنا تحوي لهجات محلّية غير موصوفة جيّدًا في التدريب الأصليّ — نُخصّص النموذج على 500 إلى 5000 مثال موصوف. Vertex يُقدِّم هذا كخدمة مُدارة:

from vertexai.tuning import sft

job = sft.train(
source_model="gemini-2.5-flash-001",
train_dataset="gs://fraud-features-lab/tuning/comments-train.jsonl",
validation_dataset="gs://fraud-features-lab/tuning/comments-val.jsonl",
epochs=3,
learning_rate_multiplier=1.0,
tuned_model_display_name="gemini-fraud-comments-v1",
)
job.wait()
print(job.tuned_model_name)

بنية ملفّ jsonl:

{"contents": [
{"role": "user", "parts": [{"text": "صنّف: «سُرقت بطاقتي...»"}]},
{"role": "model", "parts": [{"text": "FRAUDE_REELLE"}]}
]}

النتيجة نموذج مُخصَّص خاصّ بمشروعنا، مُسجَّل تلقائيًّا في Model Registry، قابل للنشر على نقطة نهاية كأيّ نموذج آخر.

كلفة الاستدعاء بالرمز

نماذج الأساس تُفوتَر بالرمز (token)، بأسعار مختلفة للمُدخَل والمُخرَج (المُخرَج أغلى لأنّه يستوجب توليدًا متتاليًا).

أسعار تقريبية:

النموذجمُدخَل (لكلّ مليون رمز)مُخرَج (لكلّ مليون رمز)
gemini-2.5-flash0.15 دولار0.60 دولار
gemini-2.5-pro3 دولار15 دولار

لسيناريو الفيل الأحمر: 2000 نزاع في الشهر، كلّ تعليق نحو 100 رمز مُدخَل مع التعليمة، والإجابة رمز أو رمزان.

2000×100106×0,15+2000×2106×0,60=0,03+0,00240,03 دولار في الشهر2000 \times \frac{100}{10^6} \times 0{,}15 + 2000 \times \frac{2}{10^6} \times 0{,}60 = 0{,}03 + 0{,}0024 \approx 0{,}03 \text{ دولار في الشهر}

مقابل 3 سنتات في الشهر، لا نُدرِّب مصنّفًا خاصًّا. القرار الاقتصاديّ واضح.

بنموذج gemini-2.5-pro، الحساب نفسه يعطي نحو 0.60 دولار في الشهر. الفرق لا يُذكَر مقارنة براحة إدارة نموذج مِلكيّ يُدار بالكامل من المزوّد.

استرشاد الحجم: قبل الاستدعاء، احسب عدد الرموز التقريبيّ (4 أحرف ≈ 1 رمز بالإنجليزيّة، 2 أحرف ≈ 1 رمز بالعربيّة). تعليمة RAG قد تُدخِل 3000 رمزٍ في كلّ استدعاء (المستندات المُسترجَعة)، والفاتورة تنمو بذلك عشرة أضعاف بلا انتباه.

نشر نموذج مفتوح المصدر

للأنشطة الحسّاسة سرّيًّا، أو لتحويل الحمل الكبير إلى استضافة داخليّة، Model Garden يُتيح نشر Llama 3 أو Mistral مثلًا:

from vertexai.preview.language_models import TextGenerationModel

model_llama = TextGenerationModel.deploy(
publisher_model="publishers/meta/models/llama3-70b-instruct",
endpoint_display_name="llama3-fraud",
machine_type="a2-highgpu-1g",
accelerator_type="NVIDIA_TESLA_A100",
accelerator_count=2,
)

الفاتورة تختلف كليًّا: آلة A100 مزدوجة تكلّف نحو 6 دولارات في الساعة، أي 4300 دولار في الشهر عند التشغيل الدائم. مبرَّرة فقط لحمل كبير جدًّا (ملايين الاستدعاءات) أو التزام سرّيّ صارم يمنع إرسال البيانات إلى مزوّد.

اختيار النموذج

السيناريوالتوصية
تصنيف بسيط، حجم منخفضgemini-2.5-flash مع مثال أو مثالين
توليد أطول، جودة أعلىgemini-2.5-pro
لهجات محلّيّة نادرة، نتائج غير مُرضيةتخصيص gemini-2.5-flash بـ500 مثال
سرّيّة صارمة، حجم عالٍنشر Llama أو Mistral داخليًّا
رؤية أو صوتGemini متعدّد الأنواع أو Whisper مباشرة

القاعدة: ابدأ بأصغر نموذج، قِس، ثمّ رقِّ إن كانت الجودة غير كافية. الابتداء بالأقوى يعمّم فواتير لا تنعكس على الجودة.

الحدود التي يجب معرفتها

  • إجاباتها لا تُحمى: نموذج الأساس قد يهذي أو ينتج فئة خارج المجموعة. أضف تحقّقًا برمجيًّا: if response.text not in ALLOWED: response.text = "AUTRE".
  • البيانات الحسّاسة: مع النماذج المِلكيّة، البيانات المُرسَلة تخضع لسياسة المزوّد. اقرأ بنود الاستعمال لبيانات الإنتاج، خصوصًا لبيانات العملاء.
  • الاستجابة: نموذج أساس يعمل بحوالي 500 مللي ثانية لطلب صغير. للحاجات الأدنى من 100 مللي ثانية، النماذج الخاصّة الأخفّ (XGBoost على نقطة نهاية) تبقى الخيار.
تحقّق من الفئة بعد الاستجابة

لن تُخبرك API إن كانت الفئة خارج ما طلبت. أضِف: assert response.text.strip() in {"FRAUDE_REELLE", "ERREUR_MARCHAND", ...} وسجّل الحالات المخالفة. مع الوقت تظهر أنماط أخطاء يوجّهها تحسين التعليمة أو التخصيص.

قِسْ قبل التخصيص

يستغرق التخصيص المُدار ساعات ويكلّف عشرات الدولارات. قبله، جرّب few-shot بثمانية أمثلة مختارة بعناية وقِس دقّة على مجموعة اختبار من 200 تعليق موصوف. إن بلغت 92 % دقّة، التخصيص قد لا يضيف شيئًا يستحقّ الكلفة.

في الخلاصة

  • Model Garden كتالوج موحَّد لنماذج Google، مفتوحة المصدر، وشركاء.
  • الاستدعاء الفوريّ عبر GenerativeModel(...) مع few-shot هو نقطة البدء لمعظم مهام التصنيف والاستخراج.
  • التخصيص المُدار لتحسين الفئات الخاصّة بمجالك، مع بضع مئات من الأمثلة الموصوفة.
  • الفوتَرة بالرمز تجعل التصنيف بمقياس آلاف الاستدعاءات في الشهر رخيصًا جدًّا؛ تكاليف RAG أو استضافة داخليّة تحتاج حسابًا مفصَّلًا.

الوحدة التالية: مراجعة كاملة للدورة، مقارنة مع SageMaker وAzure ML، والاختبار النهائيّ.