{ "cells": [ { "cell_type": "markdown", "id": "e49ba9a1", "metadata": {}, "source": [ "# الجلسة 4 – مقارنة بين SLM و LLM\n", "\n", "قارن بين زمن الاستجابة وجودة العينات الناتجة بين نموذج لغة صغير ونموذج أكبر يعمل عبر Foundry Local.\n" ] }, { "cell_type": "markdown", "id": "18d9330f", "metadata": {}, "source": [ "## ⚡ البداية السريعة\n", "\n", "**إعداد مُحسّن للذاكرة (مُحدّث):**\n", "1. النماذج تختار تلقائيًا إصدارات CPU (تعمل على أي جهاز)\n", "2. يستخدم `qwen2.5-3b` بدلاً من 7B (يوفر حوالي 4 جيجابايت من الذاكرة)\n", "3. الكشف التلقائي عن المنافذ (لا حاجة للإعداد اليدوي)\n", "4. إجمالي الذاكرة المطلوبة: يُوصى بـ ~8 جيجابايت (النماذج + نظام التشغيل)\n", "\n", "**إعداد الطرفية (30 ثانية):**\n", "```bash\n", "foundry service start\n", "foundry model run phi-4-mini\n", "foundry model run qwen2.5-3b\n", "```\n", "\n", "ثم قم بتشغيل هذا الدفتر! 🚀\n" ] }, { "cell_type": "markdown", "id": "9941ea8c", "metadata": {}, "source": [ "### شرح: تثبيت التبعيات\n", "يتم تثبيت الحد الأدنى من الحزم (`foundry-local-sdk`, `openai`, `numpy`) اللازمة لطلبات التوقيت والدردشة. يمكن إعادة تشغيله بأمان دون تأثير متكرر.\n" ] }, { "cell_type": "markdown", "id": "4690c7c7", "metadata": {}, "source": [ "# السيناريو\n", "قارن بين نموذج لغة صغير (SLM) ونموذج أكبر باستخدام موجه واحد لتوضيح المزايا والعيوب:\n", "- **فرق زمن الاستجابة** (بالثواني الفعلية)\n", "- **استخدام الرموز** (إذا كان متاحًا) كمؤشر على الإنتاجية\n", "- **عينة من المخرجات النوعية** لتقييم سريع\n", "- **حساب التسريع** لتحديد مكاسب الأداء\n", "\n", "**المتغيرات البيئية:**\n", "- `SLM_ALIAS` - نموذج اللغة الصغير (الإعداد الافتراضي: phi-4-mini، ~4GB RAM)\n", "- `LLM_ALIAS` - نموذج اللغة الأكبر (الإعداد الافتراضي: qwen2.5-7b، ~7GB RAM)\n", "- `COMPARE_PROMPT` - الموجه المستخدم للمقارنة\n", "- `COMPARE_RETRIES` - عدد محاولات الإعادة لضمان الاستقرار (الإعداد الافتراضي: 2)\n", "- `FOUNDRY_LOCAL_ENDPOINT` - تجاوز نقطة نهاية الخدمة (يتم اكتشافها تلقائيًا إذا لم يتم تحديدها)\n", "\n", "**كيف يعمل (نمط SDK الرسمي):**\n", "1. يقوم **FoundryLocalManager** بتهيئة وإدارة خدمة Foundry Local\n", "2. يتم تشغيل الخدمة تلقائيًا إذا لم تكن قيد التشغيل (لا حاجة لإعداد يدوي)\n", "3. يتم تحويل أسماء النماذج إلى معرفات محددة تلقائيًا\n", "4. يتم اختيار النسخ المحسّنة للأجهزة (CUDA، NPU، أو CPU)\n", "5. يقوم العميل المتوافق مع OpenAI بتنفيذ إكمال المحادثات\n", "6. يتم جمع المقاييس: زمن الاستجابة، الرموز، جودة المخرجات\n", "7. يتم مقارنة النتائج لحساب نسبة التسريع\n", "\n", "هذه المقارنة المصغرة تساعد في اتخاذ القرار بشأن متى يكون من المبرر استخدام نموذج أكبر لحالتك.\n", "\n", "**مرجع SDK:** \n", "- Python SDK: https://github.com/microsoft/Foundry-Local/tree/main/sdk/python/foundry_local\n", "- أدوات الورشة: تستخدم النمط الرسمي من ../samples/workshop_utils.py\n", "\n", "**الفوائد الرئيسية:**\n", "- ✅ اكتشاف الخدمة وتهيئتها تلقائيًا\n", "- ✅ تشغيل الخدمة تلقائيًا إذا لم تكن قيد التشغيل\n", "- ✅ حل النماذج وتخزينها مؤقتًا تلقائيًا\n", "- ✅ تحسين الأجهزة (CUDA/NPU/CPU)\n", "- ✅ توافق مع SDK الخاص بـ OpenAI\n", "- ✅ معالجة الأخطاء بشكل قوي مع محاولات الإعادة\n", "- ✅ استنتاج محلي (لا حاجة إلى واجهات برمجة تطبيقات السحابة)\n" ] }, { "cell_type": "markdown", "id": "ea4813a6", "metadata": {}, "source": [ "## 🚨 المتطلبات الأساسية: يجب تشغيل Foundry Local!\n", "\n", "**قبل تشغيل هذا الدفتر**، تأكد من إعداد خدمة Foundry Local:\n", "\n", "### أوامر البدء السريع (تشغيل في الطرفية):\n", "\n", "```bash\n", "# 1. Start the Foundry Local service\n", "foundry service start\n", "\n", "# 2. Load the default models used in this comparison (CPU-optimized)\n", "foundry model run phi-4-mini\n", "foundry model run qwen2.5-3b\n", "\n", "# 3. Verify models are loaded\n", "foundry model ls\n", "\n", "# 4. Check service health\n", "foundry service status\n", "```\n", "\n", "### نماذج بديلة (إذا لم تكن الإعدادات الافتراضية متوفرة):\n", "\n", "```bash\n", "# Even smaller alternatives (if memory is very limited)\n", "foundry model run phi-3.5-mini\n", "foundry model run qwen2.5-0.5b\n", "\n", "# Or update the environment variables in this notebook:\n", "# SLM_ALIAS = 'phi-3.5-mini'\n", "# LLM_ALIAS = 'qwen2.5-1.5b' # Or qwen2.5-0.5b for minimum memory\n", "```\n", "\n", "⚠️ **إذا قمت بتجاوز هذه الخطوات**، ستظهر لك رسالة `APIConnectionError` عند تشغيل خلايا الدفتر أدناه.\n" ] }, { "cell_type": "code", "execution_count": 29, "id": "e8ea63f9", "metadata": {}, "outputs": [], "source": [ "# Install dependencies\n", "!pip install -q foundry-local-sdk openai numpy requests" ] }, { "cell_type": "markdown", "id": "eb3d2ae1", "metadata": {}, "source": [ "### شرح: الواردات الأساسية\n", "يجلب أدوات التوقيت وعملاء Foundry Local / OpenAI المستخدمين لجلب معلومات النموذج وتنفيذ إكمال المحادثات.\n" ] }, { "cell_type": "code", "execution_count": 30, "id": "b1233c05", "metadata": {}, "outputs": [], "source": [ "import os, time, json\n", "from foundry_local import FoundryLocalManager\n", "from openai import OpenAI\n", "import sys\n", "sys.path.append('../samples')\n", "from workshop_utils import get_client, chat_once" ] }, { "cell_type": "markdown", "id": "03b6aa79", "metadata": {}, "source": [ "### شرح: الأسماء المستعارة وإعداد المطالبات \n", "يحدد أسماء مستعارة قابلة للتكوين حسب البيئة للنموذج الصغير مقابل النموذج الأكبر بالإضافة إلى مطالبة مقارنة. قم بتعديل متغيرات البيئة لتجربة عائلات نماذج أو مهام مختلفة.\n" ] }, { "cell_type": "code", "execution_count": 31, "id": "f46b14ab", "metadata": {}, "outputs": [], "source": [ "# Default to CPU models for better memory efficiency\n", "SLM = os.getenv('SLM_ALIAS', 'phi-4-mini') # Auto-selects CPU variant\n", "LLM = os.getenv('LLM_ALIAS', 'qwen2.5-3b') # Smaller LLM, more memory-friendly\n", "PROMPT = os.getenv('COMPARE_PROMPT', 'List 5 benefits of local AI inference.')\n", "# Endpoint is now managed by FoundryLocalManager - it auto-detects or can be overridden\n", "ENDPOINT = os.getenv('FOUNDRY_LOCAL_ENDPOINT', None)" ] }, { "cell_type": "markdown", "id": "c29375d5", "metadata": {}, "source": [ "### 💡 إعداد مُحسّن للذاكرة\n", "\n", "**يستخدم هذا الدفتر نماذج فعّالة من حيث استهلاك الذاكرة بشكل افتراضي:**\n", "- `phi-4-mini` → ~4GB RAM (يختار Foundry Local تلقائيًا إصدار CPU)\n", "- `qwen2.5-3b` → ~3GB RAM (بدلاً من 7B الذي يحتاج إلى ~7GB+)\n", "\n", "**الكشف التلقائي عن المنافذ:**\n", "- قد يستخدم Foundry Local منافذ مختلفة (غالبًا 55769 أو 59959)\n", "- الخلية التشخيصية أدناه تكتشف المنفذ الصحيح تلقائيًا\n", "- لا حاجة لإعداد يدوي!\n", "\n", "**إذا كانت لديك ذاكرة محدودة (<8GB)، استخدم نماذج أصغر:**\n", "```python\n", "SLM = 'phi-3.5-mini' # ~2GB\n", "LLM = 'qwen2.5-0.5b' # ~500MB\n", "```\n" ] }, { "cell_type": "code", "execution_count": 32, "id": "1c17fc01", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "CURRENT CONFIGURATION\n", "============================================================\n", "SLM Model: phi-4-mini\n", "LLM Model: qwen2.5-7b\n", "SDK Pattern: FoundryLocalManager (official)\n", "Endpoint: Auto-detect\n", "Test Prompt: List 5 benefits of local AI inference....\n", "Retry Count: 2\n", "============================================================\n", "\n", "💡 Using official Foundry SDK pattern from workshop_utils\n", " → FoundryLocalManager handles service lifecycle\n", " → Automatic model resolution and hardware optimization\n", " → OpenAI-compatible API for inference\n" ] } ], "source": [ "# Display current configuration\n", "print(\"=\"*60)\n", "print(\"CURRENT CONFIGURATION\")\n", "print(\"=\"*60)\n", "print(f\"SLM Model: {SLM}\")\n", "print(f\"LLM Model: {LLM}\")\n", "print(f\"SDK Pattern: FoundryLocalManager (official)\")\n", "print(f\"Endpoint: {ENDPOINT or 'Auto-detect'}\")\n", "print(f\"Test Prompt: {PROMPT[:50]}...\")\n", "print(f\"Retry Count: 2\")\n", "print(\"=\"*60)\n", "print(\"\\n💡 Using official Foundry SDK pattern from workshop_utils\")\n", "print(\" → FoundryLocalManager handles service lifecycle\")\n", "print(\" → Automatic model resolution and hardware optimization\")\n", "print(\" → OpenAI-compatible API for inference\")" ] }, { "cell_type": "markdown", "id": "e638df58", "metadata": {}, "source": [ "### شرح: أدوات تنفيذ (نمط Foundry SDK)\n", "يستخدم النمط الرسمي لـ Foundry Local SDK كما هو موثق في عينات ورش العمل:\n", "\n", "**النهج:**\n", "- **FoundryLocalManager** - يقوم بتهيئة وإدارة خدمة Foundry Local\n", "- **الاكتشاف التلقائي** - يكتشف النقاط النهائية تلقائيًا ويتعامل مع دورة حياة الخدمة\n", "- **حل النماذج** - يحل الأسماء المستعارة إلى معرفات النماذج الكاملة (مثل phi-4-mini → phi-4-mini-instruct-cpu)\n", "- **تحسين الأجهزة** - يختار أفضل إصدار للأجهزة المتاحة (CUDA، NPU، أو CPU)\n", "- **عميل OpenAI** - يتم تكوينه باستخدام نقطة النهاية الخاصة بالمدير للوصول إلى واجهة برمجة التطبيقات المتوافقة مع OpenAI\n", "\n", "**ميزات المرونة:**\n", "- منطق إعادة المحاولة مع زيادة تدريجية (قابل للتكوين عبر البيئة)\n", "- بدء تشغيل الخدمة تلقائيًا إذا لم تكن قيد التشغيل\n", "- التحقق من الاتصال بعد التهيئة\n", "- التعامل مع الأخطاء بسلاسة مع تقديم تقارير تفصيلية عن الأخطاء\n", "- تخزين النماذج مؤقتًا لتجنب التهيئة المتكررة\n", "\n", "**هيكل النتائج:**\n", "- قياس زمن التأخير (وقت الساعة الحائطية)\n", "- تتبع استخدام الرموز (إذا كان متاحًا)\n", "- عينة من المخرجات (مختصرة لسهولة القراءة)\n", "- تفاصيل الأخطاء للطلبات الفاشلة\n", "\n", "يعتمد هذا النمط على وحدة workshop_utils التي تتبع النمط الرسمي لـ SDK.\n", "\n", "**مرجع SDK:**\n", "- المستودع الرئيسي: https://github.com/microsoft/Foundry-Local\n", "- Python SDK: https://github.com/microsoft/Foundry-Local/tree/main/sdk/python/foundry_local\n", "- أدوات ورشة العمل: ../samples/workshop_utils.py\n" ] }, { "cell_type": "code", "execution_count": 39, "id": "5e646fa6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "✅ Execution helpers defined: setup(), run()\n", " → Uses workshop_utils for proper SDK integration\n", " → setup() initializes with FoundryLocalManager\n", " → run() executes inference via OpenAI-compatible API\n", " → Token counting: Uses API data or estimates if unavailable\n" ] } ], "source": [ "def setup(alias: str, endpoint: str = None, retries: int = 3):\n", " \"\"\"\n", " Initialize a Foundry Local model connection using official SDK pattern.\n", " \n", " This follows the workshop_utils pattern which uses FoundryLocalManager\n", " to properly initialize the Foundry Local service and resolve models.\n", " \n", " Args:\n", " alias: Model alias (e.g., 'phi-4-mini', 'qwen2.5-3b')\n", " endpoint: Optional endpoint override (usually auto-detected)\n", " retries: Number of connection attempts (default: 3)\n", " \n", " Returns:\n", " tuple: (manager, client, model_id, metadata) or (None, None, alias, error_metadata) if failed\n", " \"\"\"\n", " import time\n", " \n", " last_err = None\n", " current_delay = 2 # seconds\n", " \n", " for attempt in range(1, retries + 1):\n", " try:\n", " print(f\"[Init] Connecting to '{alias}' (attempt {attempt}/{retries})...\")\n", " \n", " # Use the workshop utility which follows the official SDK pattern\n", " manager, client, model_id = get_client(alias, endpoint=endpoint)\n", " \n", " print(f\"[OK] Connected to '{alias}' -> {model_id}\")\n", " print(f\" Endpoint: {manager.endpoint}\")\n", " \n", " return manager, client, model_id, {\n", " 'endpoint': manager.endpoint,\n", " 'resolved': model_id,\n", " 'attempts': attempt,\n", " 'status': 'success'\n", " }\n", " \n", " except Exception as e:\n", " last_err = e\n", " error_msg = str(e)\n", " \n", " # Provide helpful error messages\n", " if \"Connection error\" in error_msg or \"connection refused\" in error_msg.lower():\n", " print(f\"[ERROR] Cannot connect to Foundry Local service\")\n", " print(f\" → Is the service running? Try: foundry service start\")\n", " print(f\" → Is the model loaded? Try: foundry model run {alias}\")\n", " elif \"not found\" in error_msg.lower():\n", " print(f\"[ERROR] Model '{alias}' not found in catalog\")\n", " print(f\" → Available models: Run 'foundry model ls' in terminal\")\n", " print(f\" → Download model: Run 'foundry model download {alias}'\")\n", " else:\n", " print(f\"[ERROR] Setup failed: {type(e).__name__}: {error_msg}\")\n", " \n", " if attempt < retries:\n", " print(f\"[Retry] Waiting {current_delay:.1f}s before retry...\")\n", " time.sleep(current_delay)\n", " current_delay *= 2 # Exponential backoff\n", " \n", " # All retries failed - provide actionable guidance\n", " print(f\"\\n❌ Failed to initialize '{alias}' after {retries} attempts\")\n", " print(f\" Last error: {type(last_err).__name__}: {str(last_err)}\")\n", " print(f\"\\n💡 Troubleshooting steps:\")\n", " print(f\" 1. Ensure Foundry Local service is running:\")\n", " print(f\" → foundry service status\")\n", " print(f\" → foundry service start (if not running)\")\n", " print(f\" 2. Ensure model is loaded:\")\n", " print(f\" → foundry model run {alias}\")\n", " print(f\" 3. Check available models:\")\n", " print(f\" → foundry model ls\")\n", " print(f\" 4. Try alternative models if '{alias}' isn't available\")\n", " \n", " return None, None, alias, {\n", " 'error': f\"{type(last_err).__name__}: {str(last_err)}\",\n", " 'endpoint': endpoint or 'auto-detect',\n", " 'attempts': retries,\n", " 'status': 'failed'\n", " }\n", "\n", "\n", "def run(client, model_id: str, prompt: str, max_tokens: int = 180, temperature: float = 0.5):\n", " \"\"\"\n", " Run inference with the configured model using OpenAI SDK.\n", " \n", " Args:\n", " client: OpenAI client instance (configured for Foundry Local)\n", " model_id: Model identifier (resolved from alias)\n", " prompt: Input prompt\n", " max_tokens: Maximum response tokens (default: 180)\n", " temperature: Sampling temperature (default: 0.5)\n", " \n", " Returns:\n", " dict: Response with timing, tokens, and content\n", " \"\"\"\n", " import time\n", " \n", " start = time.time()\n", " \n", " try:\n", " response = client.chat.completions.create(\n", " model=model_id,\n", " messages=[{\"role\": \"user\", \"content\": prompt}],\n", " max_tokens=max_tokens,\n", " temperature=temperature\n", " )\n", " \n", " elapsed = time.time() - start\n", " \n", " # Extract response details\n", " content = response.choices[0].message.content\n", " \n", " # Try to extract token usage from multiple possible locations\n", " usage_info = {}\n", " if hasattr(response, 'usage') and response.usage:\n", " usage_info['prompt_tokens'] = getattr(response.usage, 'prompt_tokens', None)\n", " usage_info['completion_tokens'] = getattr(response.usage, 'completion_tokens', None)\n", " usage_info['total_tokens'] = getattr(response.usage, 'total_tokens', None)\n", " \n", " # Calculate approximate token count if API doesn't provide it\n", " # Rough estimate: ~4 characters per token for English text\n", " if not usage_info.get('total_tokens'):\n", " estimated_prompt_tokens = len(prompt) // 4\n", " estimated_completion_tokens = len(content) // 4\n", " estimated_total = estimated_prompt_tokens + estimated_completion_tokens\n", " usage_info['estimated_tokens'] = estimated_total\n", " usage_info['estimated_prompt_tokens'] = estimated_prompt_tokens\n", " usage_info['estimated_completion_tokens'] = estimated_completion_tokens\n", " \n", " return {\n", " 'status': 'success',\n", " 'content': content,\n", " 'elapsed_sec': elapsed,\n", " 'tokens': usage_info.get('total_tokens') or usage_info.get('estimated_tokens'),\n", " 'usage': usage_info,\n", " 'model': model_id\n", " }\n", " \n", " except Exception as e:\n", " elapsed = time.time() - start\n", " return {\n", " 'status': 'error',\n", " 'error': f\"{type(e).__name__}: {str(e)}\",\n", " 'elapsed_sec': elapsed,\n", " 'model': model_id\n", " }\n", "\n", "\n", "print(\"✅ Execution helpers defined: setup(), run()\")\n", "print(\" → Uses workshop_utils for proper SDK integration\")\n", "print(\" → setup() initializes with FoundryLocalManager\")\n", "print(\" → run() executes inference via OpenAI-compatible API\")\n", "print(\" → Token counting: Uses API data or estimates if unavailable\")" ] }, { "cell_type": "markdown", "id": "18ba23b5", "metadata": {}, "source": [ "### شرح: اختبار ذاتي قبل التشغيل\n", "يجري فحص اتصال خفيف باستخدام FoundryLocalManager لكلا النموذجين. هذا الفحص يتحقق من:\n", "- إمكانية الوصول إلى الخدمة\n", "- إمكانية تهيئة النماذج\n", "- حل الأسماء المستعارة إلى معرفات النماذج الفعلية\n", "- استقرار الاتصال قبل إجراء المقارنة\n", "\n", "تستخدم وظيفة setup() النمط الرسمي لـ SDK من workshop_utils.\n" ] }, { "cell_type": "code", "execution_count": 34, "id": "e251bd89", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Diagnostic] Checking Foundry Local service...\n", "\n", "❌ Foundry Local service not found!\n", "\n", "💡 To fix this:\n", " 1. Open a terminal\n", " 2. Run: foundry service start\n", " 3. Run: foundry model run phi-4-mini\n", " 4. Run: foundry model run qwen2.5-3b\n", " 5. Re-run this notebook\n", "\n", "⚠️ No service detected - FoundryLocalManager will attempt to start it\n" ] } ], "source": [ "# Simplified diagnostic: Just verify service is accessible\n", "import requests\n", "\n", "def check_foundry_service():\n", " \"\"\"Quick diagnostic to verify Foundry Local is running.\"\"\"\n", " # Try common ports\n", " endpoints_to_try = [\n", " \"http://localhost:59959\",\n", " \"http://127.0.0.1:59959\", \n", " \"http://localhost:55769\",\n", " \"http://127.0.0.1:55769\",\n", " ]\n", " \n", " print(\"[Diagnostic] Checking Foundry Local service...\")\n", " \n", " for endpoint in endpoints_to_try:\n", " try:\n", " response = requests.get(f\"{endpoint}/health\", timeout=2)\n", " if response.status_code == 200:\n", " print(f\"✅ Service is running at {endpoint}\")\n", " \n", " # Try to list models\n", " try:\n", " models_response = requests.get(f\"{endpoint}/v1/models\", timeout=2)\n", " if models_response.status_code == 200:\n", " models_data = models_response.json()\n", " model_count = len(models_data.get('data', []))\n", " print(f\"✅ Found {model_count} models available\")\n", " if model_count > 0:\n", " print(\" Models:\", [m.get('id', 'unknown') for m in models_data.get('data', [])[:5]])\n", " except Exception as e:\n", " print(f\"⚠️ Could not list models: {e}\")\n", " \n", " return endpoint\n", " except requests.exceptions.ConnectionError:\n", " continue\n", " except Exception as e:\n", " print(f\"⚠️ Error checking {endpoint}: {e}\")\n", " \n", " print(\"\\n❌ Foundry Local service not found!\")\n", " print(\"\\n💡 To fix this:\")\n", " print(\" 1. Open a terminal\")\n", " print(\" 2. Run: foundry service start\")\n", " print(\" 3. Run: foundry model run phi-4-mini\")\n", " print(\" 4. Run: foundry model run qwen2.5-3b\")\n", " print(\" 5. Re-run this notebook\")\n", " return None\n", "\n", "# Run diagnostic\n", "discovered_endpoint = check_foundry_service()\n", "\n", "if discovered_endpoint:\n", " print(f\"\\n✅ Service detected (will be managed by FoundryLocalManager)\")\n", "else:\n", " print(f\"\\n⚠️ No service detected - FoundryLocalManager will attempt to start it\")" ] }, { "cell_type": "code", "execution_count": 35, "id": "35317769", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "⚠️ The commands above are commented out.\n", "Uncomment them if you want to start the service from the notebook.\n", "\n", "💡 Recommended: Run these commands in a separate terminal instead:\n", " foundry service start\n", " foundry model run phi-4-mini\n", " foundry model run qwen2.5-3b\n" ] } ], "source": [ "# Quick Fix: Start service and load models from notebook\n", "# Uncomment the commands you need:\n", "\n", "# !foundry service start\n", "# !foundry model run phi-4-mini\n", "# !foundry model run qwen2.5-3b\n", "# !foundry model ls\n", "\n", "print(\"⚠️ The commands above are commented out.\")\n", "print(\"Uncomment them if you want to start the service from the notebook.\")\n", "print(\"\")\n", "print(\"💡 Recommended: Run these commands in a separate terminal instead:\")\n", "print(\" foundry service start\")\n", "print(\" foundry model run phi-4-mini\")\n", "print(\" foundry model run qwen2.5-3b\")" ] }, { "cell_type": "markdown", "id": "0de2d0a5", "metadata": {}, "source": [ "### 🛠️ إصلاح سريع: بدء تشغيل Foundry Local من دفتر الملاحظات (اختياري)\n", "\n", "إذا أظهر التشخيص أعلاه أن الخدمة لا تعمل، يمكنك محاولة تشغيلها من هنا:\n", "\n", "**ملاحظة:** هذا يعمل بشكل أفضل على نظام Windows. على الأنظمة الأخرى، استخدم أوامر الطرفية.\n" ] }, { "cell_type": "markdown", "id": "781c0bd2", "metadata": {}, "source": [ "### ⚠️ استكشاف أخطاء اتصال الخدمة وإصلاحها\n", "\n", "إذا كنت ترى `APIConnectionError`، فقد تكون خدمة Foundry Local غير قيد التشغيل أو النماذج غير محملة. جرب الخطوات التالية:\n", "\n", "**1. تحقق من حالة الخدمة:**\n", "```bash\n", "# In a terminal (not in notebook):\n", "foundry service status\n", "```\n", "\n", "**2. قم بتشغيل الخدمة (إذا لم تكن قيد التشغيل):**\n", "```bash\n", "foundry service start\n", "```\n", "\n", "**3. قم بتحميل النماذج المطلوبة:**\n", "```bash\n", "# Load the models needed for comparison\n", "foundry model run phi-4-mini\n", "foundry model run qwen2.5-7b\n", "\n", "# Or use alternative models:\n", "foundry model run phi-3.5-mini\n", "foundry model run qwen2.5-3b\n", "```\n", "\n", "**4. تحقق من توفر النماذج:**\n", "```bash\n", "foundry model ls\n", "```\n", "\n", "**المشاكل الشائعة:**\n", "- ❌ الخدمة غير قيد التشغيل → قم بتشغيل `foundry service start`\n", "- ❌ النماذج غير محملة → قم بتشغيل `foundry model run `\n", "- ❌ تعارض المنافذ → تحقق مما إذا كانت خدمة أخرى تستخدم المنفذ\n", "- ❌ جدار الحماية يحظر → تأكد من السماح بالاتصالات المحلية\n", "\n", "**إصلاح سريع:** قم بتشغيل خلية التشخيص أدناه قبل التحقق المبدئي.\n" ] }, { "cell_type": "code", "execution_count": 36, "id": "8a607078", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Init] Connecting to 'phi-4-mini' (attempt 1/2)...\n", "[OK] Connected to 'phi-4-mini' -> Phi-4-mini-instruct-cuda-gpu:4\n", " Endpoint: http://127.0.0.1:59959/v1\n", "[Init] Connecting to 'qwen2.5-7b' (attempt 1/2)...\n", "[OK] Connected to 'qwen2.5-7b' -> qwen2.5-7b-instruct-cuda-gpu:3\n", " Endpoint: http://127.0.0.1:59959/v1\n", "\n", "[Pre-flight Check]\n", " ✅ phi-4-mini: success - Phi-4-mini-instruct-cuda-gpu:4\n", " ✅ qwen2.5-7b: success - qwen2.5-7b-instruct-cuda-gpu:3\n" ] }, { "data": { "text/plain": [ "{'phi-4-mini': {'endpoint': 'http://127.0.0.1:59959/v1',\n", " 'resolved': 'Phi-4-mini-instruct-cuda-gpu:4',\n", " 'attempts': 1,\n", " 'status': 'success'},\n", " 'qwen2.5-7b': {'endpoint': 'http://127.0.0.1:59959/v1',\n", " 'resolved': 'qwen2.5-7b-instruct-cuda-gpu:3',\n", " 'attempts': 1,\n", " 'status': 'success'}}" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "preflight = {}\n", "retries = 2 # Number of retry attempts\n", "\n", "for a in (SLM, LLM):\n", " mgr, c, mid, info = setup(a, endpoint=ENDPOINT, retries=retries)\n", " # Keep the original status from info (either 'success' or 'failed')\n", " preflight[a] = info\n", "\n", "print('\\n[Pre-flight Check]')\n", "for alias, details in preflight.items():\n", " status_icon = '✅' if details['status'] == 'success' else '❌'\n", " print(f\" {status_icon} {alias}: {details['status']} - {details.get('resolved', details.get('error', 'unknown'))}\")\n", "\n", "preflight" ] }, { "cell_type": "markdown", "id": "ec76741a", "metadata": {}, "source": [ "### ✅ التحقق المسبق: توفر النموذج\n", "\n", "تتحقق هذه الخلية من إمكانية الوصول إلى كلا النموذجين عند نقطة النهاية المُعدة قبل تشغيل المقارنة.\n" ] }, { "cell_type": "markdown", "id": "a22961df", "metadata": {}, "source": [ "### شرح: مقارنة التشغيل وجمع النتائج\n", "يقوم بالتكرار على كلا الاسمين المستعارين باستخدام نمط SDK الرسمي لـ Foundry:\n", "1. تهيئة كل نموذج باستخدام setup() (يستخدم FoundryLocalManager)\n", "2. تشغيل الاستدلال باستخدام واجهة برمجة التطبيقات المتوافقة مع OpenAI\n", "3. تسجيل زمن الاستجابة، الرموز، وعينة من المخرجات\n", "4. إنتاج ملخص JSON مع تحليل مقارن\n", "\n", "هذا يتبع نفس النمط الموجود في عينات الورشة في session04/model_compare.py.\n" ] }, { "cell_type": "code", "execution_count": 40, "id": "a6f12b99", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Init] Connecting to 'phi-4-mini' (attempt 1/2)...\n", "[OK] Connected to 'phi-4-mini' -> Phi-4-mini-instruct-cuda-gpu:4\n", " Endpoint: http://127.0.0.1:59959/v1\n", "[Init] Connecting to 'qwen2.5-7b' (attempt 1/2)...\n", "[OK] Connected to 'qwen2.5-7b' -> qwen2.5-7b-instruct-cuda-gpu:3\n", " Endpoint: http://127.0.0.1:59959/v1\n", "[Init] Connecting to 'qwen2.5-7b' (attempt 1/2)...\n", "[OK] Connected to 'qwen2.5-7b' -> qwen2.5-7b-instruct-cuda-gpu:3\n", " Endpoint: http://127.0.0.1:59959/v1\n", "[\n", " {\n", " \"alias\": \"phi-4-mini\",\n", " \"status\": \"success\",\n", " \"content\": \"1. Reduced Latency: Local AI inference can significantly reduce latency by processing data closer to the source, which is particularly beneficial for real-time applications such as autonomous vehicles or augmented reality.\\n\\n2. Enhanced Privacy: By keeping data processing local, sensitive information is less likely to be exposed to external networks, thereby enhancing privacy and security.\\n\\n3. Lower Bandwidth Usage: Local AI inference reduces the need for data transmission over the network, which can save bandwidth and reduce the risk of network congestion.\\n\\n4. Improved Reliability: Local processing can be more reliable, as it is less dependent on network connectivity. This is particularly important in scenarios where network connectivity is unreliable or intermittent.\\n\\n5. Scalability: Local AI inference can be easily scaled by adding more local processing units, making it easier to handle increasing data volumes or more complex AI models.\",\n", " \"elapsed_sec\": 51.97519612312317,\n", " \"tokens\": 247,\n", " \"usage\": {\n", " \"estimated_tokens\": 247,\n", " \"estimated_prompt_tokens\": 9,\n", " \"estimated_completion_tokens\": 238\n", " },\n", " \"model\": \"Phi-4-mini-instruct-cuda-gpu:4\"\n", " },\n", " {\n", " \"alias\": \"qwen2.5-7b\",\n", " \"status\": \"success\",\n", " \"content\": \"Local AI inference offers several advantages over cloud-based or remote inference solutions. Here are five key benefits:\\n\\n1. **Latency Reduction**: Local AI inference reduces latency because the data does not need to be sent to a remote server for processing. This is particularly important in applications where real-time response is critical, such as autonomous vehicles, medical imaging, and real-time analytics.\\n\\n2. **Data Privacy and Security**: Processing data locally can enhance privacy and security by keeping sensitive information within the user's control. This is especially important in industries like healthcare, finance, and government where data breaches can have severe consequences.\\n\\n3. **Cost Efficiency**: For certain applications, local inference can be more cost-effective than cloud inference. While initial setup costs for hardware might be higher, ongoing costs for cloud services can add up over time, especially for high-frequency or large-scale operations.\\n\\n4. **Offline Capabilities**: Devices\",\n", " \"elapsed_sec\": 329.4796121120453,\n", " \"tokens\": 264,\n", " \"usage\": {\n", " \"estimated_tokens\": 264,\n", " \"estimated_prompt_tokens\": 9,\n", " \"estimated_completion_tokens\": 255\n", " },\n", " \"model\": \"qwen2.5-7b-instruct-cuda-gpu:3\"\n", " }\n", "]\n", "\n", "================================================================================\n", "COMPARISON SUMMARY\n", "================================================================================\n", "Alias Status Latency(s) Tokens \n", "--------------------------------------------------------------------------------\n", "✅ phi-4-mini success 51.975 ~247 (est.) \n", "✅ qwen2.5-7b success 329.480 ~264 (est.) \n", "--------------------------------------------------------------------------------\n", "\n", "Detailed Token Usage:\n", "\n", " phi-4-mini:\n", " Estimated prompt: 9\n", " Estimated completion: 238\n", " Estimated total: 247\n", " (API did not provide token counts - using ~4 chars/token estimate)\n", "\n", " qwen2.5-7b:\n", " Estimated prompt: 9\n", " Estimated completion: 255\n", " Estimated total: 264\n", " (API did not provide token counts - using ~4 chars/token estimate)\n", "\n", "================================================================================\n", "\n", "💡 SLM is 6.34x faster than LLM for this prompt\n", " SLM throughput: 4.8 tokens/sec\n", " LLM throughput: 0.8 tokens/sec\n" ] }, { "data": { "text/plain": [ "[{'alias': 'phi-4-mini',\n", " 'status': 'success',\n", " 'content': '1. Reduced Latency: Local AI inference can significantly reduce latency by processing data closer to the source, which is particularly beneficial for real-time applications such as autonomous vehicles or augmented reality.\\n\\n2. Enhanced Privacy: By keeping data processing local, sensitive information is less likely to be exposed to external networks, thereby enhancing privacy and security.\\n\\n3. Lower Bandwidth Usage: Local AI inference reduces the need for data transmission over the network, which can save bandwidth and reduce the risk of network congestion.\\n\\n4. Improved Reliability: Local processing can be more reliable, as it is less dependent on network connectivity. This is particularly important in scenarios where network connectivity is unreliable or intermittent.\\n\\n5. Scalability: Local AI inference can be easily scaled by adding more local processing units, making it easier to handle increasing data volumes or more complex AI models.',\n", " 'elapsed_sec': 51.97519612312317,\n", " 'tokens': 247,\n", " 'usage': {'estimated_tokens': 247,\n", " 'estimated_prompt_tokens': 9,\n", " 'estimated_completion_tokens': 238},\n", " 'model': 'Phi-4-mini-instruct-cuda-gpu:4'},\n", " {'alias': 'qwen2.5-7b',\n", " 'status': 'success',\n", " 'content': \"Local AI inference offers several advantages over cloud-based or remote inference solutions. Here are five key benefits:\\n\\n1. **Latency Reduction**: Local AI inference reduces latency because the data does not need to be sent to a remote server for processing. This is particularly important in applications where real-time response is critical, such as autonomous vehicles, medical imaging, and real-time analytics.\\n\\n2. **Data Privacy and Security**: Processing data locally can enhance privacy and security by keeping sensitive information within the user's control. This is especially important in industries like healthcare, finance, and government where data breaches can have severe consequences.\\n\\n3. **Cost Efficiency**: For certain applications, local inference can be more cost-effective than cloud inference. While initial setup costs for hardware might be higher, ongoing costs for cloud services can add up over time, especially for high-frequency or large-scale operations.\\n\\n4. **Offline Capabilities**: Devices\",\n", " 'elapsed_sec': 329.4796121120453,\n", " 'tokens': 264,\n", " 'usage': {'estimated_tokens': 264,\n", " 'estimated_prompt_tokens': 9,\n", " 'estimated_completion_tokens': 255},\n", " 'model': 'qwen2.5-7b-instruct-cuda-gpu:3'}]" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "results = []\n", "retries = 2 # Number of retry attempts\n", "\n", "for alias in (SLM, LLM):\n", " mgr, client, mid, info = setup(alias, endpoint=ENDPOINT, retries=retries)\n", " if client:\n", " r = run(client, mid, PROMPT)\n", " results.append({'alias': alias, **r})\n", " else:\n", " # If setup failed, record error\n", " results.append({\n", " 'alias': alias,\n", " 'status': 'error',\n", " 'error': info.get('error', 'Setup failed'),\n", " 'elapsed_sec': 0,\n", " 'tokens': None,\n", " 'model': alias\n", " })\n", "\n", "# Display results\n", "print(json.dumps(results, indent=2))\n", "\n", "# Quick comparative view\n", "print('\\n' + '='*80)\n", "print('COMPARISON SUMMARY')\n", "print('='*80)\n", "print(f\"{'Alias':<20} {'Status':<15} {'Latency(s)':<15} {'Tokens':<15}\")\n", "print('-'*80)\n", "\n", "for row in results:\n", " status = row.get('status', 'unknown')\n", " status_icon = '✅' if status == 'success' else '❌'\n", " latency_str = f\"{row.get('elapsed_sec', 0):.3f}\" if row.get('elapsed_sec') else 'N/A'\n", " \n", " # Handle token display - show if available or indicate estimated\n", " tokens = row.get('tokens')\n", " usage = row.get('usage', {})\n", " if tokens:\n", " if 'estimated_tokens' in usage:\n", " tokens_str = f\"~{tokens} (est.)\"\n", " else:\n", " tokens_str = str(tokens)\n", " else:\n", " tokens_str = 'N/A'\n", " \n", " print(f\"{status_icon} {row['alias']:<18} {status:<15} {latency_str:<15} {tokens_str:<15}\")\n", "\n", "print('-'*80)\n", "\n", "# Show detailed token breakdown if available\n", "print(\"\\nDetailed Token Usage:\")\n", "for row in results:\n", " if row.get('status') == 'success' and row.get('usage'):\n", " usage = row['usage']\n", " print(f\"\\n {row['alias']}:\")\n", " if 'prompt_tokens' in usage and usage['prompt_tokens']:\n", " print(f\" Prompt tokens: {usage['prompt_tokens']}\")\n", " print(f\" Completion tokens: {usage['completion_tokens']}\")\n", " print(f\" Total tokens: {usage['total_tokens']}\")\n", " elif 'estimated_tokens' in usage:\n", " print(f\" Estimated prompt: {usage['estimated_prompt_tokens']}\")\n", " print(f\" Estimated completion: {usage['estimated_completion_tokens']}\")\n", " print(f\" Estimated total: {usage['estimated_tokens']}\")\n", " print(f\" (API did not provide token counts - using ~4 chars/token estimate)\")\n", "\n", "print('\\n' + '='*80)\n", "\n", "# Calculate speedup if both succeeded\n", "if len(results) == 2 and all(r.get('status') == 'success' and r.get('elapsed_sec') for r in results):\n", " speedup = results[1]['elapsed_sec'] / results[0]['elapsed_sec']\n", " print(f\"\\n💡 SLM is {speedup:.2f}x faster than LLM for this prompt\")\n", " \n", " # Compare token throughput if available\n", " slm_tokens = results[0].get('tokens', 0)\n", " llm_tokens = results[1].get('tokens', 0)\n", " if slm_tokens and llm_tokens:\n", " slm_tps = slm_tokens / results[0]['elapsed_sec']\n", " llm_tps = llm_tokens / results[1]['elapsed_sec']\n", " print(f\" SLM throughput: {slm_tps:.1f} tokens/sec\")\n", " print(f\" LLM throughput: {llm_tps:.1f} tokens/sec\")\n", " \n", "elif any(r.get('status') == 'error' for r in results):\n", " print(f\"\\n⚠️ Some models failed - check errors above\")\n", " print(\" Ensure Foundry Local is running: foundry service start\")\n", " print(\" Ensure models are loaded: foundry model run \")\n", "\n", "results" ] }, { "cell_type": "markdown", "id": "592d052c", "metadata": {}, "source": [ "### تفسير النتائج\n", "\n", "**المقاييس الرئيسية:**\n", "- **زمن الاستجابة**: كلما كان أقل، كان أفضل - يشير إلى سرعة الاستجابة\n", "- **الرموز**: معدل أعلى = معالجة المزيد من الرموز\n", "- **المسار**: يؤكد أي نقطة نهاية API تم استخدامها\n", "\n", "**متى تستخدم SLM مقابل LLM:**\n", "- **SLM (نموذج اللغة الصغيرة)**: استجابات سريعة، استخدام أقل للموارد، مناسب للمهام البسيطة\n", "- **LLM (نموذج اللغة الكبير)**: جودة أعلى، تفكير أفضل، يُستخدم عندما تكون الجودة هي الأهم\n", "\n", "**الخطوات التالية:**\n", "1. جرب مطالبات مختلفة لترى كيف تؤثر التعقيدات على المقارنة\n", "2. قم بتجربة أزواج نماذج أخرى\n", "3. استخدم عينات التوجيه من ورشة العمل (الجلسة 06) لتوجيه المهام بذكاء بناءً على تعقيدها\n" ] }, { "cell_type": "code", "execution_count": 38, "id": "e8caed5a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "======================================================================\n", "VALIDATION SUMMARY\n", "======================================================================\n", "✅ SLM Model: phi-4-mini\n", "✅ LLM Model: qwen2.5-7b\n", "✅ Using Foundry SDK Pattern: workshop_utils with FoundryLocalManager\n", "✅ Pre-flight passed: True\n", "✅ Comparison completed: True\n", "✅ Both models responded: True\n", "======================================================================\n", "🎉 ALL CHECKS PASSED! Notebook completed successfully.\n", " SLM (phi-4-mini) vs LLM (qwen2.5-7b) comparison completed.\n", " Performance: SLM is 5.14x faster\n", "======================================================================\n" ] } ], "source": [ "# Final Validation Check\n", "print(\"=\"*70)\n", "print(\"VALIDATION SUMMARY\")\n", "print(\"=\"*70)\n", "print(f\"✅ SLM Model: {SLM}\")\n", "print(f\"✅ LLM Model: {LLM}\")\n", "print(f\"✅ Using Foundry SDK Pattern: workshop_utils with FoundryLocalManager\")\n", "print(f\"✅ Pre-flight passed: {all(v['status'] == 'success' for v in preflight.values()) if 'preflight' in dir() else 'Not run yet'}\")\n", "print(f\"✅ Comparison completed: {len(results) == 2 if 'results' in dir() else 'Not run yet'}\")\n", "print(f\"✅ Both models responded: {all(r.get('status') == 'success' for r in results) if 'results' in dir() and results else 'Not run yet'}\")\n", "print(\"=\"*70)\n", "\n", "# Check for common configuration issues\n", "issues = []\n", "if 'LLM' in dir() and LLM not in ['qwen2.5-3b', 'qwen2.5-0.5b', 'qwen2.5-1.5b', 'qwen2.5-7b', 'phi-3.5-mini']:\n", " issues.append(f\"⚠️ LLM is '{LLM}' - expected qwen2.5-3b for memory efficiency\")\n", "if 'preflight' in dir() and not all(v['status'] == 'success' for v in preflight.values()):\n", " issues.append(\"⚠️ Pre-flight check failed - models not accessible\")\n", "if 'results' in dir() and results and not all(r.get('status') == 'success' for r in results):\n", " issues.append(\"⚠️ Comparison incomplete - check for errors above\")\n", "\n", "if not issues and 'results' in dir() and results and all(r.get('status') == 'success' for r in results):\n", " print(\"🎉 ALL CHECKS PASSED! Notebook completed successfully.\")\n", " print(f\" SLM ({SLM}) vs LLM ({LLM}) comparison completed.\")\n", " if len(results) == 2:\n", " speedup = results[1]['elapsed_sec'] / results[0]['elapsed_sec'] if results[0]['elapsed_sec'] > 0 else 0\n", " print(f\" Performance: SLM is {speedup:.2f}x faster\")\n", "elif issues:\n", " print(\"\\n⚠️ Issues detected:\")\n", " for issue in issues:\n", " print(f\" {issue}\")\n", " print(\"\\n💡 Troubleshooting:\")\n", " print(\" 1. Ensure service is running: foundry service start\")\n", " print(\" 2. Load models: foundry model run phi-4-mini && foundry model run qwen2.5-7b\")\n", " print(\" 3. Check model list: foundry model ls\")\n", "else:\n", " print(\"\\n💡 Run all cells above first, then re-run this validation.\")\n", "print(\"=\"*70)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n---\n\n**إخلاء المسؤولية**: \nتم ترجمة هذا المستند باستخدام خدمة الترجمة بالذكاء الاصطناعي [Co-op Translator](https://github.com/Azure/co-op-translator). بينما نسعى لتحقيق الدقة، يرجى العلم أن الترجمات الآلية قد تحتوي على أخطاء أو معلومات غير دقيقة. يجب اعتبار المستند الأصلي بلغته الأصلية المصدر الرسمي. للحصول على معلومات حاسمة، يُوصى بالاستعانة بترجمة بشرية احترافية. نحن غير مسؤولين عن أي سوء فهم أو تفسيرات خاطئة ناتجة عن استخدام هذه الترجمة.\n" ] } ], "metadata": { "kernelspec": { "display_name": "demo", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.15" }, "coopTranslator": { "original_hash": "8220e33feaffbd35ece0f93e8214c24f", "translation_date": "2025-10-09T07:19:55+00:00", "source_file": "Workshop/notebooks/session04_model_compare.ipynb", "language_code": "ar" } }, "nbformat": 4, "nbformat_minor": 5 }