أداة Daft: ما كان يجب أن تكون عليه Pandas لخطوط معالجة بيانات الذكاء الاصطناعي
تستخدم معظم خطوط معالجة RAG وتعلم الآلة (ML) مكتبة Pandas أو سكربتات مخصصة لتجهيز البيانات. ولكن عند العمل بنطاق واسع، ينهار هذا الأسلوب. Daft هو محرك dataframe موزع ومكتوب بلغة Rust، مصمم خصيصاً لأعباء عمل الذكاء الاصطناعي — متعدد الوسائط (multimodal)، ويدعم الـ GPU، وقادر على معالجة البيتابايت.
المشكلة ليست فقط في بطء Pandas. بل تكمن في أنها تنهار تماماً عندما تحاول استخدامها لبناء خطوط معالجة (pipelines) جادة لبيانات الذكاء الاصطناعي. ستصطدم بحدود الذاكرة (memory walls)، وستبقى معالجات الرسوميات (GPUs) لديك خاملة بلا عمل، وستتحول استراتيجية معالجة البيانات بأكملها إلى سلسلة من السكربتات المرقعة. نرى هذا طوال الوقت في Verel Systems. يأتي إلينا العملاء بمشاريع تجريبية (pilot projects) عالقة في مرحلة انتقالية – أنظمة RAG لا يمكنها التوسع لأكثر من بضعة آلاف من المستندات، ونماذج متعددة الوسائط (multimodal models) تختنق ببياناتها الخاصة، وعمليات تضمين (embedding) تنهار بسبب خطأ OutOfMemoryError كل يومين. هذا هو "دين الذكاء الاصطناعي" (AI debt) بكل وضوح: كود بمستوى العرض التجريبي (demo-quality) يُدفع به إلى بيئة الإنتاج، مما يكلف الشركات ملايين الدولارات في موارد الحوسبة المهدرة والمبادرات المهجورة.
على الرغم من فائدة Pandas الكبيرة في تحليل البيانات الاستكشافي ومجموعات البيانات الصغيرة والمتوسطة، إلا أنها لم تُصمم أبداً لتلائم واقع الذكاء الاصطناعي الحديث. إنها أداة تعمل على جهاز واحد وتعتمد بالكامل على الذاكرة العشوائية (in-memory). هذا الخيار التصميمي، الذي كان يوماً ما نقطة قوة، أصبح الآن ثغرة حرجة لأي شيء يتضمن عمليات تضمين (embeddings) واسعة النطاق، أو بيانات متعددة الوسائط، أو معالجة موزعة (distributed processing).
عيوب Pandas القاتلة عند التوسع في الذكاء الاصطناعي
دعنا نكون صريحين بشأن أسباب فشل Pandas في أعباء عمل الذكاء الاصطناعي:
- ▸نفاد الذاكرة أمر حتمي: جرب معالجة دفعة من 100,000 مستند لنظام RAG، حيث يحتاج كل مستند إلى تقسيمه إلى مقاطع (chunks) ثم تضمينه (embedded). أو فكر في مجموعة بيانات بحجم 50 جيجابايت من الصور. تقوم Pandas بتحميل كل شيء في الذاكرة العشوائية (RAM). سينفد مخزون الذاكرة في جهازك الذي يحتوي على 64 جيجابايت أو حتى 128 جيجابايت بسرعة، خاصة عند التعامل مع المتجهات عالية الأبعاد التي تنتجها عمليات التضمين. فمثلاً، تضمين
text-embedding-3-largeالنموذجي لمقطع يحتوي على 512 رمزاً (tokens) يتكون من 3072 قيمة عشرية (floats). اضرب ذلك في مئات الآلاف أو الملايين من المقاطع، وستجد نفسك أمام تيرابايت من البيانات. ببساطة، لا يمكن لـ Pandas التعامل مع هذا دون إدارة يدوية مستمرة للذاكرة – مما يعني كتابة المزيد من الأكواد المعقدة وغير المنظمة (spaghetti code). - ▸غياب الدعم الأصلي لمعالجات الرسوميات (GPU): تعد الـ GPUs هي العمود الفقري للذكاء الاصطناعي. بالنسبة للاستنتاج على دفعات (batch inference)، أو الضبط الدقيق (fine-tuning)، أو حتى مجرد عمليات قواعد بيانات المتجهات، فأنت بحاجة إلى دفع البيانات إلى الـ GPU وتنفيذ العمليات هناك. لكن Pandas مقيدة بالمعالج المركزي (CPU-bound). إذا كان لديك dataframe يحتوي على مسارات صور وتريد تشغيلها عبر نموذج vision transformer، فستضطر إلى جلب كل صورة، وتحميلها، وإرسالها إلى الـ GPU، والحصول على المخرجات، ثم إعادة دمجها يدوياً في الـ dataframe الخاص بك. هذا الأسلوب غير فعال للغاية، ويعمل بشكل تسلسلي، ويهدر العتاد المصمم خصيصاً لتسريع مهام الذكاء الاصطناعي الخاصة بك. ستبقى بطاقات A100 أو H100 الباهظة الثمن خاملة بينما يستهلك المعالج المركزي طاقتك في تشغيل حلقات Python التكرارية.
- ▸عنق زجاجة في عمليات ETL أحادية المسار (Single-Threaded): غالباً ما تتضمن عمليات تحميل البيانات وتنظيفها وتحويلها للذكاء الاصطناعي عمليات كثيفة الإدخال والإخراج (I/O-heavy) مثل القراءة من S3، وتحليل ملفات JSON، وتغيير حجم الصور، أو عمليات مكثفة حوسبياً مثل التعبيرات النمطية المعقدة (regex) والترميز (tokenization). تنفذ Pandas هذه العمليات على نواة معالج مركزي واحدة. حتى مع استخدام
applyأوmap، فإن المحرك الأساسي لا يستغل جميع النوى المتاحة بكفاءة للوظائف المعقدة التي يحددها المستخدم. هذا يعني أن خط معالجة استيراد البيانات (data ingestion pipeline) لنظام RAG، والذي يعالج أكثر من 100,000 مستند، قد يستغرق ساعات بدلاً من دقائق، مما يخلق عنق زجاجة كبيراً في دورات التطوير والنشر الخاصة بك. - ▸غياب الدعم الأساسي لأنواع البيانات متعددة الوسائط (Multimodal): لم يعد الذكاء الاصطناعي يقتصر على الجداول المنظمة فقط. نحن نتعامل الآن مع الصور، والصوت، والفيديو، وسحب النقاط (point clouds). لا تملك Pandas فهماً أصلياً أو تمثيلاً فعالاً لأنواع البيانات هذه. ستقوم بتخزين مسارات الملفات، أو ربما البايتات الخام كـ blobs، لكن لا يمكنك إجراء عمليات مثل "تغيير حجم جميع الصور"، أو "استخراج ميزات الصوت"، أو "فك تشفير إطارات الفيديو" مباشرة على عمود Pandas DataFrame بأي درجة من الكفاءة. هذا يجبر المطورين على إدارة هذه التحويلات خارج إطار الـ dataframe، مما يؤدي إلى قواعد كود مفككة وصعبة الصيانة ويستحيل تحسينها.
هذه القيود هي السبب وراء فشل 80-95% من مشاريع الذكاء الاصطناعي وبقائها حبيسة المراحل التجريبية. أنت تبني نموذجاً تجريبياً يعمل على عينة صغيرة، ثم تصطدم بعقبات هندسة البيانات الأساسية هذه عندما تحاول التوسع.
Daft: ما كان يجب أن تكون عليه Pandas للذكاء الاصطناعي
هنا يأتي دور Daft. إذا كانت Pandas قد صُممت للتحليل الجدولي على جهاز واحد، فإن Daft قد صُممت من الصفر لخطوط معالجة بيانات الذكاء الاصطناعي الموزعة ومتعددة الوسائط. إنها محرك البيانات الذي تحتاجه لنقل مشاريع الذكاء الاصطناعي من مرحلة الأكواد العشوائية (spaghetti code) إلى بيئة الإنتاج الفعلية.
في جوهرها، تعد Daft مكتبة dataframe موزعة وعالية الأداء مكتوبة بلغة Rust. هذا ليس مجرد تفصيل تقني في التنفيذ؛ بل هو خيار أساسي يتيح كل الميزات الأخرى:
- ▸نواة بلغة Rust وتقنية Apache Arrow Zero-Copy: تم بناء طبقة البيانات بالكامل في Daft بلغة Rust، مع الاستفادة من Apache Arrow لتمثيل البيانات في الذاكرة. هذا يعني أن العمليات سريعة للغاية، وتخطيطات الذاكرة مخصصة للمعالجة العمودية (columnar processing). والأهم من ذلك، تستخدم Daft خصائص zero-copy الخاصة بـ Arrow. عندما تنتقل البيانات بين عمليات Daft أو حتى إلى مكتبات أخرى متوافقة مع Arrow (مثل PyTorch أو Polars)، فإنها غالباً لا تحتاج إلى نسخ، بل يتم الإشارة إليها فقط. هذا يقلل بشكل كبير من استهلاك الذاكرة الإضافي (memory overhead) ويحسن معدل الإنتاجية (throughput). لقد رأينا Daft تستهلك ذاكرة أقل بـ 5 مرات مقارنة بالبدائل الأخرى في العمليات المعقدة، وهو أمر بالغ الأهمية عند معالجة دفعات التضمين الكبيرة.
- ▸التقييم الكسول (Lazy Evaluation) لتحقيق الكفاءة: على عكس Pandas، تستخدم Daft التقييم الكسول. عندما تقوم بربط العمليات متتالية (
filter().map().select())، لا تقوم Daft بتنفيذها على الفور. بدلاً من ذلك، تبني خطة تنفيذ محسنة. وفقط عندما تطلب النتائج صراحة (مثلdf.collect())، تقوم بتنفيذ المخطط بالكامل. يتيح ذلك لـ Daft دمج العمليات، وتصفية البيانات مبكراً (push down predicates)، وتحسين استخدام الذاكرة عبر خط المعالجة. هذا يعني أيضاً حصولك على تكرار محلي في أقل من ثانية على جهازك المحمول أثناء التطوير، حتى عند العمل مع مجموعات بيانات بمقياس البيتابايت. يمكنك اختبار منطق الكود الخاص بك وتعديله بسرعة دون انتظار فحص كامل لمجموعة البيانات. - ▸التنفيذ الموزع (من المحمول إلى العنقود البرمجي): تم تصميم واجهة برمجة تطبيقات Daft لتكون متطابقة تماماً سواء كنت تقوم بالتشغيل على جهازك المحلي ببضع نوى أو على عنقود Kubernetes ضخم يضم مئات العقد (nodes). نفس استدعاء
df.map_batches()الذي يعمل محلياً سيتوسع بسلاسة عبر العنقود الخاص بك. تكتب خط المعالجة مرة واحدة، وتتولى Daft مهام التوزيع، والجدولة، ومقاومة الأعطال (fault tolerance). هذا يمثل تحولاً جذرياً للانتقال من مرحلة إثبات المفهوم (POC) إلى الإنتاج، مما يلغي الحاجة لإعادة كتابة الكود لبيئات مختلفة. - ▸جدولة GPU أصلية للاستنتاج على دفعات (Batch Inference): هذا هو الجانب الذي تتفوق فيه Daft حقاً في مجال الذكاء الاصطناعي. يمكن لـ Daft جدولة المهام مباشرة على معالجات الرسوميات (GPUs). يمكنك تحديد وظيفة تقوم باستنتاج GPU (مثل تشغيل دفعة من الصور عبر نموذج رؤية) وتطبيقها على Daft DataFrame. ستقوم Daft تلقائياً بإدارة تقسيم الدفعات، ونقل البيانات من وإلى الـ GPU، والتنفيذ المتوازي عبر عدة معالجات رسوميات إذا كانت متوفرة. هذا يعني أنه يمكنك أخيراً استخدام موارد الـ GPU المكلفة بكفاءة لعمليات التضمين على دفعات، واستخراج الميزات متعددة الوسائط، ومهام الاستنتاج الأخرى، ودمجها بشكل نظيف في خط معالجة البيانات الخاص بك.
- ▸دعم أساسي لأنواع البيانات متعددة الوسائط: تفهم Daft الصور والصوت والفيديو كأنواع بيانات أصلية، وليس مجرد ملفات ثنائية (blobs) أو مسارات ملفات. يمكنك تطبيق عمليات مثل
df["image_col"].image.decode()أوdf["video_col"].video.decode_frames()مباشرة. يتيح لك هذا بناء خطوط معالجة متعددة الوسائط متكاملة (end-to-end) داخل واجهة الـ dataframe، بدءاً من ملفات الوسائط الخام وحتى الميزات المعالجة، دون اللجوء إلى سكربتات خارجية معقدة.
إن Daft ليست مجرد نسخة أسرع من Pandas؛ بل هي نهج مختلف تماماً لمعالجة البيانات، تم بناؤه لتلبية المتطلبات الفريدة للذكاء الاصطناعي على نطاق واسع.
أين نستخدم Daft في Verel Systems
في Verel Systems، نقوم ببناء أنظمة ذكاء اصطناعي جاهزة للإنتاج. هذا يعني إنقاذ مشاريع إثبات المفهوم (POCs) الفاشلة، والتخلص من ديون الذكاء الاصطناعي، وتقديم حلول تعمل بالفعل في بيئات المؤسسات. تعد Daft أداة بالغة الأهمية في ترسانتنا لعدة مجالات رئيسية:
- ▸خطوط معالجة استيراد RAG لأكثر من 100 ألف مستند: بالنسبة للعملاء الذين يبنون أنظمة RAG متقدمة، غالباً ما يكون خط معالجة الاستيراد (ingestion pipeline) هو أول عنق زجاجة يواجههم. نحن نستخدم Daft لمعالجة مئات الآلاف، وأحياناً الملايين من المستندات.
- ▸التنظيف والتهيئة (Cleaning and Normalization): نقوم بقراءة ملفات PDF أو HTML أو Markdown الخام، واستخراج النصوص، ثم استخدام Daft لتطبيق سلسلة من وظائف التن
