تشغيل نماذج تعلم الآلة في المتصفح باستخدام Pyodide وWASM: أمثلة عملية لتحليل نص عربي دون سيرفر
مقدمة: لماذا تشغيل ML في المتصفح؟
تزايد الاهتمام بتشغيل مهام تعلم الآلة مباشرةً على جهاز المستخدم (client-side) لأسباب واضحة: تقليل زمن الاستجابة، تحسين الخصوصية لأن البيانات لا تُرسل إلى خوادم طرف ثالث، وخفض تكلفة البنية التحتية. تقنيات مثل WebAssembly تسمح بتشغيل لغات وأنظمة تقليدية (مثل CPython) داخل المتصفح، وPyodide هو مشروع يمكّن تشغيل بايثون و«مكتبات علمية» داخل صفحات الويب بدون سيرفر.
في هذا المقال سنعرض مقاربة عملية مكوّنة من: (1) معالجة ونمذجة نص عربي خفيفة عبر Pyodide (بايثون داخل المتصفح) و(2) استدعاء نموذج مُحوّل إلى شكل مناسب للتنفيذ على المتصفح باستخدام ONNX Runtime Web أو عبر واجهات تسريع الويب مثل WebNN — كل ذلك مع نصائح للأداء والأمن.
ملاحظة: Pyodide يجلب مفسّر CPython إلى المتصفح عبر WebAssembly ويدعم تثبيت حزم Python صافية (pure-Python) عبر micropip، لكنه لا يدعم بسهولة الحزم ذات الامتدادات الثنائية الكبيرة دون تعديلات. لاستخدام استدلالٍ سريعٍ يعتمد على العتاد (GPU أو مسرّعات ML) يفضّل استخدام ONNX Runtime Web أو الواجهات المعيارية مثل WebNN.
متى تختار Pyodide وحده ومتى تدمجه مع WASM/ONNX/WebNN؟
- Pyodide مفيدٌ لـ: تنفيذ خوارزميات معالجة نصية خفيفة (تنظيف، تطبيع، قواعد، تجزيء)، تحليلات تفاعلية، أو واجهات برمجية تعليمية/تجريبية داخل صفحات ثابتة.
- ONNX Runtime Web / WebNN مفيدانُ لـ: تنفيذ نماذج مُدرَّبة (خاصةً إذا حوّلت النموذج إلى ONNX أو بنية مدعومة) مع إمكانية الاستفادة من تسريع العتاد داخل المتصفح (GPU أو تسريع WebNN عندما يكون متاحاً).
- نصيحة هندسية: ابدأ ببايثون داخل المتصفح للـ preprocessing والـ prototyping، ثم انقل الاستدلال المكثف إلى ONNX/WebNN لتقليل أحمال الذاكرة وتحسين الأداء.
يمكن تشغيل Pyodide في مؤشر الصفحة العادي أو داخل Web Worker لمنع تجميد واجهة المستخدم (UI) أثناء عمليات حسابية طويلة؛ واستخدام Web Worker يُنصح له مع حِزمٍ أو عملياتٍ ثقيلةٍ.
أمثلة عملية
أ. مثال بسيط: معالجة نص عربي داخل المتصفح باستخدام Pyodide
الفكرة: تحميل Pyodide من CDN، تشغيل كود بايثون يقوم بتطبيع النص العربي (إزالة التشكيل، توحيد همزات، إزالة علامات الترقيم) ثم إرجاع النتائج إلى JavaScript لعرضها أو إرسالها إلى نموذج أخف لاحقًا.
هيكل الصفحة (HTML + JS مختصر):
<!-- تحميل Pyodide -->
<script src="https://cdn.jsdelivr.net/pyodide/v0.23.4/full/pyodide.js"></script>
<script>
async function startPyodide(){
const pyodide = await loadPyodide();
await pyodide.loadPackage('micropip');
// تنصيب حزمة خفيفة إن احتجنا
// await pyodide.runPythonAsync("import micropip; await micropip.install('some-pure-python')")
// تعريف دالة بايثون لمعالجة نص عربي
const pythonCode = `
import re
def normalize_ar(text):
# إزالة التشكيل
text = re.sub('[\u0610-\u061A\u064B-\u065F\u06D6-\u06ED]', '', text)
# توحيد الألف والهمزات
text = re.sub('[إأآا]', 'ا', text)
text = re.sub('ؤ', 'و', text)
text = re.sub('ئ', 'ي', text)
# إزالة علامات ترقيم أساسية
text = re.sub('[^\u0600-\u06FF\s]', ' ', text)
text = re.sub('\s+', ' ', text).strip()
return text
`;
pyodide.runPython(pythonCode);
// استدعاء الدالة من JS
const normalize = pyodide.globals.get('normalize_ar');
const res = normalize('قُلْ هُوَ اللَّهُ أَحَدٌ!');
console.log('Normalized:', res);
}
startPyodide();
</script>هذا المثال يبيّن كيف تستفيد من قدرات بايثون للتنظيف والتطبيع قبل إرسال البيانات لخطوة نمذجة أخف أو اقتراحات UI محلية.
ب. مثال: استدعاء نموذج مُحوّل إلى ONNX داخل المتصفح (بأداء أفضل)
إذا كان لديك نموذج صغير (كمثال: تصنيف نص خفيف أو نموذج خصائص)، يمكنك تحويله إلى ONNX ثم تشغيله باستخدام ONNX Runtime Web، الذي يوفر إصدارات WASM ويمكنه الاستفادة من WebNN أو WebGPU عندما تكون متاحة. الفائدة: تنفيذ أسرع وتقليل استخدام الذاكرة مقارنةً بتشغيل نموذج ثقيل ضمن بايثون كامل.
// تحميل ONNX Runtime Web (مثال مبسّط)
<script src="https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.min.js"></script>
<script>
async function runONNX(modelUrl, inputTensor){
// إنشاء جلسة استدلال
const session = await ort.InferenceSession.create(modelUrl, {executionProviders:['wasm']});
const feeds = { input_ids: new ort.Tensor('int32', inputTensor.data, inputTensor.dims) };
const results = await session.run(feeds);
console.log('ONNX result', results);
}
</script>ملاحظات عملية:
- حوّل نموذجك إلى ONNX مع تقنيات تقليص (quantization) لتقليل الحجم وزمن الاستدلال.
- أعد هندسة المدخلات (tokenization) بحيث تكون عملية التحويل إلى أرقام (ids) خفيفة ويمكن تنفيذها محلياً في JS أو Pyodide.
- إذا أردت تسريعًا إضافيًا واستخدمت WebNN، فسينتج عنه استفادة من مسرّعات الأجهزة المتاحة داخل المتصفح عند دعمها.