يعمل TensorFlow.js في المتصفح وNode.js، ويوجد في كلا النظامين العديد من التكوينات المختلفة المتاحة. تحتوي كل منصة على مجموعة فريدة من الاعتبارات التي ستؤثر على طريقة تطوير التطبيقات.
في المتصفح، يدعم TensorFlow.js الأجهزة المحمولة بالإضافة إلى أجهزة سطح المكتب. يحتوي كل جهاز على مجموعة محددة من القيود، مثل واجهات برمجة تطبيقات WebGL المتاحة، والتي يتم تحديدها وتكوينها تلقائيًا لك.
في Node.js، يدعم TensorFlow.js الارتباط المباشر بواجهة برمجة تطبيقات TensorFlow أو التشغيل مع تطبيقات وحدة المعالجة المركزية الأبطأ.
البيئات
عند تنفيذ برنامج TensorFlow.js، يُطلق على التكوين المحدد اسم البيئة. تتكون البيئة من واجهة خلفية عالمية واحدة بالإضافة إلى مجموعة من العلامات التي تتحكم في الميزات الدقيقة لـ TensorFlow.js.
الواجهات الخلفية
يدعم TensorFlow.js العديد من الواجهات الخلفية المختلفة التي تنفذ تخزين الموتر والعمليات الرياضية. في أي وقت، تكون الواجهة الخلفية واحدة فقط نشطة. في معظم الأحيان، سيختار TensorFlow.js تلقائيًا أفضل واجهة خلفية لك في ظل البيئة الحالية. ومع ذلك، في بعض الأحيان يكون من المهم معرفة الواجهة الخلفية المستخدمة وكيفية تبديلها.
للعثور على الواجهة الخلفية التي تستخدمها:
console.log(tf.getBackend());
إذا كنت تريد تغيير الواجهة الخلفية يدويًا:
tf.setBackend('cpu');
console.log(tf.getBackend());
الواجهة الخلفية لـ WebGL
تعد الواجهة الخلفية لـ WebGL، "webgl"، حاليًا أقوى واجهة خلفية للمتصفح. هذه الواجهة الخلفية أسرع بما يصل إلى 100 مرة من الواجهة الخلفية لوحدة المعالجة المركزية الفانيليا. يتم تخزين Tensors كأنسجة WebGL ويتم تنفيذ العمليات الرياضية في تظليل WebGL. فيما يلي بعض الأشياء المفيدة التي يجب معرفتها عند استخدام هذه الواجهة الخلفية: \
تجنب حظر مؤشر ترابط واجهة المستخدم
عندما يتم استدعاء عملية، مثل tf.matMul(a, b)، يتم إرجاع tf.Tensor الناتج بشكل متزامن، ولكن حساب ضرب المصفوفة قد لا يكون جاهزًا بعد. وهذا يعني أن tf.Tensor الذي تم إرجاعه هو مجرد مؤشر للعملية الحسابية. عند استدعاء x.data()
أو x.array()
، سيتم حل القيم عند اكتمال الحساب فعليًا. هذا يجعل من المهم استخدام الأساليب غير المتزامنة x.data()
و x.array()
على نظيراتها المتزامنة x.dataSync()
و x.arraySync()
لتجنب حظر مؤشر ترابط واجهة المستخدم أثناء اكتمال الحساب.
إدارة الذاكرة
أحد التحذيرات عند استخدام الواجهة الخلفية WebGL هو الحاجة إلى إدارة واضحة للذاكرة. WebGLTextures، حيث يتم تخزين بيانات Tensor في النهاية، لا يتم جمعها تلقائيًا بواسطة المتصفح.
لتدمير ذاكرة tf.Tensor
، يمكنك استخدام dispose()
:
const a = tf.tensor([[1, 2], [3, 4]]);
a.dispose();
من الشائع جدًا ربط عمليات متعددة معًا في التطبيق. يمكن أن يؤدي الاحتفاظ بمرجع إلى كافة المتغيرات الوسيطة للتخلص منها إلى تقليل إمكانية قراءة التعليمات البرمجية. لحل هذه المشكلة، يوفر TensorFlow.js التابع tf.tidy()
الذي ينظف جميع عناصر tf.Tensor
التي لا تُرجعها دالة بعد تنفيذها، على غرار الطريقة التي يتم بها تنظيف المتغيرات المحلية عند تنفيذ دالة:
const a = tf.tensor([[1, 2], [3, 4]]);
const y = tf.tidy(() => {
const result = a.square().log().neg();
return result;
});
دقة
على الأجهزة المحمولة، قد يدعم WebGL فقط زخارف الفاصلة العائمة ذات 16 بت. ومع ذلك، يتم تدريب معظم نماذج التعلم الآلي باستخدام أوزان وتنشيطات النقطة العائمة 32 بت. يمكن أن يسبب هذا مشكلات في الدقة عند نقل نموذج لجهاز محمول حيث أن الأرقام العائمة ذات 16 بت يمكن أن تمثل فقط أرقامًا في النطاق [0.000000059605, 65504]
. وهذا يعني أنه يجب عليك الحذر من أن الأوزان وعمليات التنشيط في النموذج الخاص بك لا تتجاوز هذا النطاق. للتحقق مما إذا كان الجهاز يدعم مواد 32 بت، تحقق من قيمة tf.ENV.getBool('WEBGL_RENDER_FLOAT32_CAPABLE')
، إذا كان هذا خطأ، فإن الجهاز يدعم فقط مواد الفاصلة العائمة 16 بت. يمكنك استخدام tf.ENV.getBool('WEBGL_RENDER_FLOAT32_ENABLED')
للتحقق مما إذا كان TensorFlow.js يستخدم حاليًا مواد 32 بت.
تجميع تظليل وتحميل الملمس
ينفذ TensorFlow.js العمليات على وحدة معالجة الرسومات عن طريق تشغيل برامج تظليل WebGL. يتم تجميع هذه التظليلات وتجميعها بتكاسل عندما يطلب المستخدم تنفيذ عملية ما. يتم تجميع التظليل على وحدة المعالجة المركزية على الخيط الرئيسي ويمكن أن يكون بطيئًا. سيقوم TensorFlow.js بالتخزين المؤقت للتظليلات المجمعة تلقائيًا، مما يجعل الاستدعاء الثاني لنفس العملية باستخدام موترات الإدخال والإخراج من نفس الشكل أسرع بكثير. عادةً، ستستخدم تطبيقات TensorFlow.js نفس العمليات عدة مرات طوال عمر التطبيق، وبالتالي فإن المرور الثاني عبر نموذج التعلم الآلي يكون أسرع بكثير.
يقوم TensorFlow.js أيضًا بتخزين بيانات tf.Tensor على هيئة WebGLTextures. عند إنشاء tf.Tensor
، لا نقوم بتحميل البيانات على الفور إلى وحدة معالجة الرسومات، بل نحتفظ بالبيانات على وحدة المعالجة المركزية حتى يتم استخدام tf.Tensor
في العملية. إذا تم استخدام tf.Tensor
مرة أخرى، فإن البيانات موجودة بالفعل على وحدة معالجة الرسومات، لذا لا توجد تكلفة تحميل. في نموذج التعلم الآلي النموذجي، يعني هذا أنه يتم تحميل الأوزان أثناء التنبؤ الأول من خلال النموذج وسيكون المرور الثاني عبر النموذج أسرع بكثير.
إذا كنت تهتم بأداء التنبؤ الأول من خلال نموذجك أو كود TensorFlow.js، فنوصيك بتسخين النموذج عن طريق تمرير Tensor المدخلات بنفس الشكل قبل استخدام البيانات الحقيقية.
على سبيل المثال:
const model = await tf.loadLayersModel(modelUrl);
// Warmup the model before using real data.
const warmupResult = model.predict(tf.zeros(inputShape));
warmupResult.dataSync();
warmupResult.dispose();
// The second predict() will be much faster
const result = model.predict(userData);
الواجهة الخلفية Node.js TensorFlow
في الواجهة الخلفية لـ TensorFlow Node.js، "العقدة"، يتم استخدام واجهة برمجة التطبيقات TensorFlow C لتسريع العمليات. سيستخدم هذا تسريع الأجهزة المتوفرة بالجهاز، مثل CUDA، إذا كان متاحًا.
في هذه الواجهة الخلفية، تمامًا مثل واجهة WebGL الخلفية، تُرجع العمليات tf.Tensor
s بشكل متزامن. ومع ذلك، على عكس الواجهة الخلفية لـ WebGL، تكتمل العملية قبل استعادة الموتر. هذا يعني أن استدعاء tf.matMul(a, b)
سيحظر مؤشر ترابط واجهة المستخدم.
لهذا السبب، إذا كنت تنوي استخدام هذا في تطبيق إنتاج، فيجب عليك تشغيل TensorFlow.js في سلاسل العمليات حتى لا يتم حظر الخيط الرئيسي.
لمزيد من المعلومات حول Node.js، راجع هذا الدليل.
الواجهة الخلفية WASM
يوفر TensorFlow.js واجهة WebAssembly الخلفية ( wasm
)، والتي توفر تسريع وحدة المعالجة المركزية (CPU) ويمكن استخدامها كبديل للواجهات الخلفية لـ JavaScript CPU ( cpu
) وWebGL المتسارع ( webgl
). لاستخدامه:
// Set the backend to WASM and wait for the module to be ready.
tf.setBackend('wasm');
tf.ready().then(() => {...});
إذا كان خادمك يقدم ملف .wasm
على مسار مختلف أو باسم مختلف، فاستخدم setWasmPath
قبل تهيئة الواجهة الخلفية. راجع قسم "استخدام المجمعات" في الملف التمهيدي لمزيد من المعلومات:
import {setWasmPath} from '@tensorflow/tfjs-backend-wasm';
setWasmPath(yourCustomPath);
tf.setBackend('wasm');
tf.ready().then(() => {...});
لماذا واسم؟
تم تقديم WASM في عام 2015 كتنسيق ثنائي جديد قائم على الويب، مما يوفر برامج مكتوبة بلغة JavaScript وC وC++ وما إلى ذلك كهدف تجميعي للتشغيل على الويب. يتم دعم WASM بواسطة Chrome وSafari وFirefox وEdge منذ عام 2017، ويدعمه 90% من الأجهزة حول العالم.
أداء
تستفيد الواجهة الخلفية WASM من مكتبة XNNPACK من أجل التنفيذ الأمثل لمشغلي الشبكات العصبية.
مقابل JavaScript : تعد ثنائيات WASM بشكل عام أسرع بكثير من حزم JavaScript التي يمكن للمتصفحات تحميلها وتحليلها وتنفيذها. تتم كتابة جافا سكريبت ديناميكيًا ويتم جمع البيانات المهملة، مما قد يتسبب في حدوث تباطؤ في وقت التشغيل.
مقابل WebGL : يعد WebGL أسرع من WASM بالنسبة لمعظم الطرز، ولكن بالنسبة للنماذج الصغيرة، يمكن أن يتفوق WASM على WebGL بسبب التكاليف العامة الثابتة لتنفيذ تظليل WebGL. يناقش قسم "متى يجب أن أستخدم WASM" أدناه الأساليب الاستدلالية لاتخاذ هذا القرار.
قابلية النقل والاستقرار
يحتوي WASM على حساب عائم محمول 32 بت، مما يوفر تكافؤًا دقيقًا عبر جميع الأجهزة. من ناحية أخرى، فإن WebGL خاص بالأجهزة ويمكن أن تتمتع الأجهزة المختلفة بدقة متفاوتة (على سبيل المثال، الرجوع إلى عوامات 16 بت على أجهزة iOS).
مثل WebGL، يتم دعم WASM رسميًا بواسطة جميع المتصفحات الرئيسية. على عكس WebGL، يمكن تشغيل WASM في Node.js، ويمكن استخدامه من جانب الخادم دون الحاجة إلى تجميع المكتبات الأصلية.
متى يجب علي استخدام WASM؟
حجم النموذج والطلب الحسابي
بشكل عام، يعد WASM خيارًا جيدًا عندما تكون الطرز أصغر حجمًا أو عندما تهتم بالأجهزة ذات المواصفات المنخفضة التي تفتقر إلى دعم WebGL (امتداد OES_texture_float
) أو التي تحتوي على وحدات معالجة رسومات أقل قوة. يوضح الرسم البياني أدناه أوقات الاستدلال (اعتبارًا من TensorFlow.js 1.5.2) في Chrome على جهاز MacBook Pro لعام 2018 لخمسة من الطرز المدعومة رسميًا عبر واجهات WebGL وWASM ووحدة المعالجة المركزية الخلفية:
نماذج أصغر
نموذج | ويب جي إل | واسم | وحدة المعالجة المركزية | ذاكرة |
---|---|---|---|---|
بليزفيس | 22.5 مللي ثانية | 15.6 مللي ثانية | 315.2 مللي ثانية | .4 ميجابايت |
FaceMesh | 19.3 مللي ثانية | 19.2 مللي ثانية | 335 مللي ثانية | 2.8 ميجا بايت |
نماذج أكبر
نموذج | ويب جي إل | واسم | وحدة المعالجة المركزية | ذاكرة |
---|---|---|---|---|
بوز نت | 42.5 مللي ثانية | 173.9 مللي ثانية | 1514.7 مللي ثانية | 4.5 ميجا بايت |
BodyPix | 77 مللي ثانية | 188.4 مللي ثانية | 2683 مللي ثانية | 4.6 ميجابايت |
موبايل نت v2 | 37 مللي ثانية | 94 مللي ثانية | 923.6 مللي ثانية | 13 ميجا بايت |
يوضح الجدول أعلاه أن WASM أسرع بمقدار 10 إلى 30 مرة من الواجهة الخلفية لوحدة المعالجة المركزية JS العادية عبر النماذج، ويتنافس مع WebGL للنماذج الأصغر مثل BlazeFace ، وهو خفيف الوزن (400 كيلو بايت)، ولكنه يحتوي على عدد لا بأس به من العمليات (~ 140). نظرًا لأن برامج WebGL لها تكلفة عامة ثابتة لكل عملية تنفيذ، فإن هذا يفسر سبب كون النماذج مثل BlazeFace أسرع على WASM.
ستختلف هذه النتائج حسب جهازك. أفضل طريقة لتحديد ما إذا كان WASM مناسبًا لتطبيقك هي اختباره على واجهاتنا الخلفية المختلفة.
الاستدلال مقابل التدريب
لمعالجة حالة الاستخدام الأساسية لنشر النماذج المدربة مسبقًا، سيعطي تطوير الواجهة الخلفية لـ WASM الأولوية للاستدلال على دعم التدريب . اطلع على قائمة محدثة للعمليات المدعومة في WASM وأخبرنا إذا كان النموذج الخاص بك يحتوي على عملية غير مدعومة. بالنسبة لنماذج التدريب، نوصي باستخدام الواجهة الخلفية Node (TensorFlow C++) أو الواجهة الخلفية WebGL.
الواجهة الخلفية لوحدة المعالجة المركزية
الواجهة الخلفية لوحدة المعالجة المركزية، 'cpu'، هي الواجهة الخلفية الأقل أداءً، ولكنها الأبسط. يتم تنفيذ كافة العمليات في JavaScript الفانيليا، مما يجعلها أقل قابلية للتوازي. كما يقومون أيضًا بحظر مؤشر ترابط واجهة المستخدم.
يمكن أن تكون هذه الواجهة الخلفية مفيدة جدًا للاختبار، أو على الأجهزة التي لا يتوفر فيها WebGL.
أعلام
يحتوي TensorFlow.js على مجموعة من علامات البيئة التي يتم تقييمها تلقائيًا وتحديد أفضل تكوين في النظام الأساسي الحالي. معظم هذه العلامات داخلية، ولكن يمكن التحكم في عدد قليل من العلامات العالمية باستخدام واجهة برمجة التطبيقات العامة.
-
tf.enableProdMode():
تمكين وضع الإنتاج، الذي سيؤدي إلى إزالة التحقق من صحة النموذج، وفحوصات NaN، وعمليات التحقق الأخرى من الصحة لصالح الأداء. -
tf.enableDebugMode()
: يمكّن وضع التصحيح، الذي سيقوم بتسجيل كل عملية يتم تنفيذها إلى وحدة التحكم، بالإضافة إلى معلومات أداء وقت التشغيل مثل مساحة الذاكرة وإجمالي وقت تنفيذ kernel. لاحظ أن هذا سيؤدي إلى إبطاء تطبيقك بشكل كبير، فلا تستخدمه في الإنتاج.