نماذج اللغة الكبيرة (LLMs) المحلية في جيبك: هندسة الذكاء الاصطناعي على الأجهزة باستخدام MediaPipe و Expo
انقل استراتيجية الذكاء الاصطناعي الخاصة بك من واجهات برمجة تطبيقات (APIs) سحابية مكلفة إلى استدلال محلي عالي الأداء. يستكشف هذا الدليل رحلتي المعمارية في دمج MediaPipe LLM Inference في Expo للحصول على ذكاء خاص يعمل دون اتصال بالإنترنت.

نماذج اللغة الكبيرة (LLMs) المحلية في جيبك: هندسة الذكاء الاصطناعي على الأجهزة باستخدام MediaPipe و Expo
خلال العام الماضي، عشنا جميعاً في عالم الـ fetch('/api/generate'). إنه أمر مريح، لكنه بمثابة "قفص ذهبي". بين تكاليف الـ tokens المتصاعدة، ومخاوف الخصوصية، وواقع الـ "offline" الحتمي لمستخدمي الجوال، فإن الاعتماد الكلي على نماذج LLMs السحابية هو مخاطرة لم أكن مستعداً لخوضها في مشاريعي الأخيرة.
أردت أن أرى إلى أي مدى يمكننا دفع حدود الحوسبة الطرفية (the edge). كان هدفي: تشغيل نموذج LLM مكمم (quantized) مباشرة على الجهاز ضمن سير عمل مدار بواسطة Expo. بعد بعض المحاولات والخطأ، وجدت التوازن المثالي باستخدام MediaPipe LLM Inference API من Google. إليكم كيف قمت بسد الفجوة بين الأكواد الداخلية الثقيلة بلغة C++ وطبقة React Native.
معمارية الحوسبة الطرفية (The Architecture of the Edge)
تشغيل نموذج LLM على جهاز جوال لا يقتصر فقط على "تثبيت مكتبة". الأمر يتعلق بإدارة الذاكرة. إذا حاولت تحميل نموذج خام بـ 7 مليارات معامل (7B parameter)، سيقوم نظام iOS/Android بإغلاق عمليتك (kill process) قبل أن تتمكن حتى من قول "Hello World".
نحتاج لثلاثة أشياء لإنجاح ذلك في Expo:
- نموذج مكمم (Quantized Model): مثل Gemma 2B أو Phi-2، مضغوط إلى 4-bit (int4) ليتناسب مع ذاكرة الوصول العشوائي (RAM) للجوال.
- بيئة تشغيل MediaPipe Runtime: وتحديداً مهمة LLM Inference التجريبية التي تتعامل مع تسريع GPU/NPU.
- وحدة Expo مخصصة (Custom Expo Module): بما أن هذا يتطلب تكاملاً عميقاً مع النظام الأصلي (native integration)، نستخدم
expo-modules-sdkللتواصل مع منطق MediaPipe المكتوب بلغة C++.
وضع الأساسات
أولاً، كان عليّ الابتعاد عن عقلية "الويب أولاً" التقليدية. نحن نتعامل مع ملفات أوزان ثنائية (binary weights) بصيغة .bin أو .task. في تجربتي، أفضل طريقة للتعامل مع هذه الملفات في Expo هي عبر URI محلي للملف بعد تحميله لمرة واحدة، لأن تضمين نموذج بحجم 1.5 جيجابايت داخل ملف .ipa أو .apk هو وصفة مؤكدة لرفض المستخدمين للتطبيق.
الجسر الأصلي (The Native Bridge - Swift/Kotlin)
باستخدام Expo Module API، أنشأت غلافاً (wrapper) حول مهمة MediaPipe. إليكم نظرة مفاهيمية على كيفية تهيئة محرك الاستدلال (inference engine) في الجانب الأصلي:
تنفيذ الـ React Native
بمجرد الانتهاء من العمل الشاق في الجانب الأصلي، يصبح جانب TypeScript نظيفاً بشكل مدهش. وجدت أن تغليف الاستدلال في hook مخصص يوفر أفضل تجربة مستخدم (UX)، خاصة عند التعامل مع حالات "التحميل" لملفات النماذج الضخمة.
حقائق الأداء: ما تعلمته
- الاختناق الحراري (Thermal Throttling) حقيقي: تشغيل حلقة توليد مستمرة سيؤدي إلى تسخين جهاز iPhone 15 Pro بشكل ملحوظ. تعلمت تنفيذ فترات "تبريد" وتحديد الحد الأقصى للـ tokens لتجنب قيام نظام التشغيل بتعتيم الشاشة أو إغلاق التطبيق.
- التكميم (Quantization) غير قابل للتفاوض: نموذج Gemma 2B المكمم بـ 4-bit هو الخيار المثالي للجوال؛ فهو صغير بما يكفي للبقاء تحت حد ضغط الذاكرة البالغ 2 جيجابايت، ولكنه ذكي بما يكفي للتعامل مع استخراج بيانات JSON المنظمة أو الدردشة الأساسية.
- واجهة مستخدم غير متزامنة (Async UI): لا تقم أبداً بتشغيل الاستدلال على الخيط الرئيسي (Main Thread). صحيح أن MediaPipe يتعامل مع عمل GPU، لكن العبء الإضافي للجسر (bridge overhead) قد يسبب تعليقاً (jank) في واجهة المستخدم إذا لم تكن حذراً. تعامل دائماً مع الاستجابة كعملية غير متزامنة.
لماذا هذا الأمر مهم؟
من خلال نقل الاستدلال إلى الجهاز، قمنا بإلغاء ضريبة الـ 0.01 دولار لكل طلب. ولكن الأهم من ذلك، أننا أنشأنا تجربة خصوصية من الدرجة الأولى (Tier-1). بيانات مستخدميَّ لا تغادر أجهزتهم أبداً. في عصر تتزايد فيه الرقابة على البيانات، لا يعد هذا مجرد فوز تقني فحسب، بل هو ميزة تنافسية ضخمة للمنتج.
هندسة الذكاء الاصطناعي المحلي في Expo لا تهدف لاستبدال السحابة؛ بل تتعلق ببناء أنظمة هجينة مرنة، خاصة، وفعالة من حيث التكلفة. الأدوات أصبحت متوفرة أخيراً. حان الوقت للتوقف عن جلب البيانات (fetching) والبدء في الاستدلال (inferring).