الموحدة الأساسية

يقدم هذا المستند الطبقة الأساسية لـ TFF التي تعمل كأساس للتعلم الموحد والخوارزميات الموحدة غير التعليمية المحتملة في المستقبل.

للحصول على مقدمة لطيفة عن Federated Core، يرجى قراءة البرامج التعليمية التالية، حيث أنها تقدم بعض المفاهيم الأساسية عن طريق المثال وتوضح خطوة بخطوة إنشاء خوارزمية متوسط ​​متحدة بسيطة.

نود أيضًا أن نشجعك على التعرف على التعلم الموحد والبرامج التعليمية المرتبطة به حول تصنيف الصور وإنشاء النص ، حيث أن استخدامات واجهة برمجة التطبيقات الأساسية الموحدة (FC API) للتعلم الموحد توفر سياقًا مهمًا لبعض الاختيارات التي قمنا بها في تصميم هذه الطبقة .

ملخص

الأهداف والاستخدامات المقصودة والنطاق

من الأفضل فهم النظام الأساسي الموحد (FC) على أنه بيئة برمجة لتنفيذ الحسابات الموزعة، أي الحسابات التي تتضمن أجهزة كمبيوتر متعددة (الهواتف المحمولة، والأجهزة اللوحية، والأجهزة المدمجة، وأجهزة الكمبيوتر المكتبية، وأجهزة الاستشعار، وخوادم قواعد البيانات، وما إلى ذلك) التي قد يؤدي كل منها أداءً غير- معالجة تافهة محليا، والتواصل عبر الشبكة لتنسيق عملهم.

المصطلح الموزع عام جدًا، ولا يستهدف TFF جميع الأنواع الممكنة من الخوارزميات الموزعة الموجودة هناك، لذلك نفضل استخدام المصطلح الأقل عمومية "الحساب الموحد" لوصف أنواع الخوارزميات التي يمكن التعبير عنها في هذا الإطار.

على الرغم من أن تعريف مصطلح الحساب الموحد بطريقة رسمية بالكامل هو خارج نطاق هذا المستند، فكر في أنواع الخوارزميات التي قد تراها معبرًا عنها بالكود الزائف في منشور بحثي يصف خوارزمية تعلم موزعة جديدة.

هدف FC، باختصار، هو تمكين تمثيل مضغوط مماثل، بمستوى تجريد مماثل يشبه الكود الكاذب، لمنطق البرنامج الذي ليس كودًا زائفًا، ولكنه قابل للتنفيذ في مجموعة متنوعة من البيئات المستهدفة.

السمة المميزة الرئيسية لأنواع الخوارزميات التي تم تصميم FC للتعبير عنها هي أن تصرفات المشاركين في النظام يتم وصفها بطريقة جماعية. ومن ثم فإننا نميل إلى الحديث عن كل جهاز يقوم بتحويل البيانات محليًا، والأجهزة التي تقوم بتنسيق العمل بواسطة منسق مركزي يبث أو يجمع أو يجمع نتائجها.

في حين تم تصميم TFF ليكون قادرًا على تجاوز بنيات خادم العميل البسيطة، فإن فكرة المعالجة الجماعية أمر أساسي. ويرجع ذلك إلى أصول TFF في التعلم الموحد، وهي تقنية مصممة في الأصل لدعم العمليات الحسابية على البيانات التي يحتمل أن تكون حساسة والتي تظل تحت سيطرة الأجهزة العميلة، والتي قد لا يتم تنزيلها ببساطة إلى موقع مركزي لأسباب تتعلق بالخصوصية. في حين أن كل عميل في مثل هذه الأنظمة يساهم بالبيانات وقوة المعالجة من أجل حساب النتيجة بواسطة النظام (وهي نتيجة نتوقع عمومًا أن تكون ذات قيمة لجميع المشاركين)، فإننا نسعى أيضًا للحفاظ على خصوصية كل عميل وعدم الكشف عن هويته.

وهكذا، في حين أن معظم أطر الحوسبة الموزعة مصممة للتعبير عن المعالجة من وجهة نظر المشاركين الأفراد - أي على مستوى تبادل الرسائل الفردية من نقطة إلى نقطة، والترابط بين انتقالات الحالة المحلية للمشاركين مع الرسائل الواردة والصادرة ، تم تصميم النواة الموحدة لـ TFF لوصف سلوك النظام من منظور عالمي على مستوى النظام (على غرار MapReduce على سبيل المثال).

وبالتالي، في حين أن الأطر الموزعة للأغراض العامة قد تقدم عمليات مثل الإرسال والاستقبال ككتل بناء، فإن FC توفر كتل بناء مثل tff.federated_sum أو tff.federated_reduce أو tff.federated_broadcast التي تحتوي على بروتوكولات موزعة بسيطة.

لغة

واجهة بايثون

يستخدم TFF لغة داخلية لتمثيل الحسابات الموحدة، والتي يتم تعريف تركيبها من خلال التمثيل القابل للتسلسل في computation.proto . ومع ذلك، لن يحتاج مستخدمو FC API بشكل عام إلى التفاعل مع هذه اللغة بشكل مباشر. بدلاً من ذلك، نحن نوفر واجهة برمجة تطبيقات Python (مساحة الاسم tff ) التي تلتف حولها كوسيلة لتحديد العمليات الحسابية.

على وجه التحديد، يوفر TFF أدوات تزيين وظائف Python مثل tff.federated_computation التي تتبع أجسام الوظائف المزخرفة، وتنتج تمثيلات متسلسلة لمنطق الحساب الموحد في لغة TFF. تعمل الدالة المزينة بـ tff.federated_computation كحامل لهذا التمثيل المتسلسل، ويمكن تضمينها ككتلة بناء في نص عملية حسابية أخرى، أو تنفيذها عند الطلب عند استدعائها.

هنا مثال واحد فقط؛ يمكن العثور على المزيد من الأمثلة في البرامج التعليمية للخوارزميات المخصصة .

@tff.federated_computation(tff.FederatedType(np.float32, tff.CLIENTS))
def get_average_temperature(sensor_readings):
  return tff.federated_mean(sensor_readings)

سيجد القراء غير المتحمسين لـ TensorFlow هذا الأسلوب مشابهًا لكتابة كود Python الذي يستخدم وظائف مثل tf.add أو tf.reduce_sum في قسم من كود Python الذي يحدد رسم TensorFlow. على الرغم من أن الكود يتم التعبير عنه تقنيًا في بايثون، إلا أن الغرض منه هو إنشاء تمثيل قابل للتسلسل لـ tf.Graph أسفله، وهو الرسم البياني، وليس كود بايثون، الذي يتم تنفيذه داخليًا بواسطة وقت تشغيل TensorFlow. وبالمثل، يمكن للمرء أن يفكر في tff.federated_mean على أنه إدراج عملية متحدة في حساب متحد يمثله get_average_temperature .

جزء من سبب تعريف FC للغة يتعلق بحقيقة أنه، كما هو مذكور أعلاه، تحدد الحسابات الموحدة السلوكيات الجماعية الموزعة، وعلى هذا النحو، فإن منطقها غير محلي. على سبيل المثال، يوفر TFF المشغلين، الذين قد توجد مدخلاتهم ومخرجاتهم في أماكن مختلفة في الشبكة.

وهذا يتطلب لغة ونظام كتابة يجسد فكرة التوزيع.

نوع النظام

يقدم Federated Core الفئات التالية من الأنواع. في وصف هذه الأنواع، نشير إلى مُنشئات النوع بالإضافة إلى تقديم تدوين مضغوط، حيث إنها طريقة سهلة أو تصف أنواع الحسابات والعوامل.

أولاً، فيما يلي فئات الأنواع المشابهة من الناحية المفاهيمية لتلك الموجودة في اللغات السائدة الحالية:

  • أنواع الموتر ( tff.TensorType ). تمامًا كما هو الحال في TensorFlow، تحتوي هذه العناصر على dtype و shape . والفرق الوحيد هو أن الكائنات من هذا النوع لا تقتصر على tf.Tensor مثيلات في Python التي تمثل مخرجات TensorFlow ops في رسم بياني TensorFlow، ولكنها قد تتضمن أيضًا وحدات من البيانات التي يمكن إنتاجها، على سبيل المثال، كمخرجات موزعة بروتوكول التجميع. وبالتالي، فإن نوع موتر TFF هو ببساطة نسخة مجردة من تمثيل مادي ملموس لهذا النوع في Python أو TensorFlow.

    يمكن أن تكون TensorTypes الخاصة بـ TFF أكثر صرامة في معالجتها (الثابتة) للأشكال من TensorFlow. على سبيل المثال، يتعامل نظام الكتابة الخاص بـ TFF مع موتر ذي رتبة غير معروفة على أنه قابل للتخصيص من أي موتر آخر من نفس dtype ، ولكنه غير قابل للتخصيص لأي موتر ذي رتبة ثابتة. تمنع هذه المعالجة بعض حالات الفشل في وقت التشغيل (على سبيل المثال، محاولة إعادة تشكيل موتر ذو رتبة غير معروفة إلى شكل يحتوي على عدد غير صحيح من العناصر)، وذلك على حساب صرامة أكبر فيما يتعلق بالحسابات التي يقبلها TFF على أنها صالحة.

    الترميز المضغوط لأنواع الموتر هو dtype أو dtype[shape] . على سبيل المثال، int32 و int32[10] هما نوعان من الأعداد الصحيحة ومتجهات int، على التوالي.

  • أنواع التسلسل ( tff.SequenceType ). هذه هي المعادل التجريدي لـ TFF لمفهوم TensorFlow الملموس لـ tf.data.Dataset s. يمكن استهلاك عناصر التسلسل بطريقة تسلسلية، ويمكن أن تشمل أنواعًا معقدة.

    التمثيل المضغوط لأنواع التسلسل هو T* ، حيث T هو نوع العناصر. على سبيل المثال، يمثل int32* تسلسلًا صحيحًا.

  • أنواع الصف المسماة ( tff.StructType ). هذه هي طريقة TFF في إنشاء صفوف وهياكل شبيهة بالقاموس تحتوي على عدد محدد مسبقًا من العناصر بأنواع محددة، مسماة أو غير مسماة. الأهم من ذلك، أن مفهوم الصف المسمى في TFF يشتمل على المعادل المجرد لصفوف وسيطات بايثون، أي مجموعات من العناصر التي تم تسمية بعضها، ولكن ليس كلها، وبعضها موضعي.

    الترميز المضغوط للصفوف المسماة هو <n_1=T_1, ..., n_k=T_k> ، حيث n_k هي أسماء عناصر اختيارية، و T_k هي أنواع العناصر. على سبيل المثال، <int32,int32> هو تدوين مضغوط لزوج من الأعداد الصحيحة غير المسماة، و <X=float32,Y=float32> هو تدوين مضغوط لزوج من الأعداد المسمى X و Y والتي قد تمثل نقطة على المستوى . يمكن تداخل الصفوف بالإضافة إلى مزجها مع أنواع أخرى، على سبيل المثال، <X=float32,Y=float32>* سيكون تدوينًا مضغوطًا لسلسلة من النقاط.

  • أنواع الوظائف ( tff.FunctionType ). TFF هو إطار برمجة وظيفي، حيث يتم التعامل مع الوظائف كقيم من الدرجة الأولى . تحتوي الوظائف على وسيطة واحدة على الأكثر ونتيجة واحدة بالضبط.

    الترميز المضغوط للدوال هو (T -> U) ، حيث T هو نوع الوسيطة، و U هو نوع النتيجة، أو ( -> U) إذا لم يكن هناك وسيطة (على الرغم من أن الدوال التي لا تحتوي على وسيطة هي منحلة المفهوم الموجود في الغالب على مستوى بايثون فقط). على سبيل المثال (int32* -> int32) هو تدوين لنوع من الوظائف التي تقلل تسلسل عدد صحيح إلى قيمة عدد صحيح واحد.

تتناول الأنواع التالية جانب الأنظمة الموزعة لحسابات TFF. نظرًا لأن هذه المفاهيم فريدة إلى حد ما بالنسبة لـ TFF، فإننا نشجعك على الرجوع إلى البرنامج التعليمي للخوارزميات المخصصة للحصول على تعليقات وأمثلة إضافية.

  • نوع الموضع . لم يتم الكشف عن هذا النوع بعد في واجهة برمجة التطبيقات العامة بخلاف شكلين حرفيين tff.SERVER و tff.CLIENTS التي يمكنك اعتبارها ثوابت من هذا النوع. ومع ذلك، يتم استخدامه داخليًا، وسيتم تقديمه في واجهة برمجة التطبيقات العامة في الإصدارات المستقبلية. التمثيل المضغوط لهذا النوع هو placement .

    يمثل الموضع مجموعة من المشاركين في النظام الذين يلعبون دورًا معينًا. يستهدف الإصدار الأولي حسابات خادم العميل، حيث توجد مجموعتان من المشاركين: العملاء والخادم (يمكنك التفكير في الأخير كمجموعة فردية). ومع ذلك، في البنى الأكثر تفصيلاً، قد تكون هناك أدوار أخرى، مثل المجمعين الوسيطين في نظام متعدد المستويات، الذين قد يقومون بأنواع مختلفة من التجميع، أو يستخدمون أنواعًا مختلفة من ضغط/إلغاء ضغط البيانات عن تلك التي يستخدمها الخادم أو الزبائن.

    الغرض الأساسي من تعريف مفهوم المواضع هو كأساس لتعريف الأنواع الموحدة .

  • الأنواع الموحدة ( tff.FederatedType ). قيمة النوع المتحد هي تلك التي تتم استضافتها بواسطة مجموعة من المشاركين في النظام يتم تعريفهم بواسطة موضع محدد (مثل tff.SERVER أو tff.CLIENTS ). يتم تعريف النوع الموحد من خلال قيمة الموضع (وبالتالي، فهو نوع تابع )، ونوع مكونات الأعضاء (نوع المحتوى الذي يستضيفه كل مشارك محليًا)، والبت الإضافي all_equal الذي يحدد ما إذا كان جميع المشاركين محليين أم لا استضافة نفس العنصر.

    التدوين المضغوط لنوع القيم الموحد الذي يتضمن عناصر (مكونات الأعضاء) من النوع T ، كل منها مستضاف بواسطة المجموعة (الموضع) G هو T@G أو {T}@G مع تعيين البتات all_equal أو عدم تعيينها، على التوالي.

    على سبيل المثال:

    • {int32}@CLIENTS قيمة موحدة تتكون من مجموعة من الأعداد الصحيحة المحتملة، واحد لكل جهاز عميل. لاحظ أننا نتحدث عن قيمة موحدة واحدة تشمل عناصر متعددة من البيانات التي تظهر في مواقع متعددة عبر الشبكة. إحدى طرق التفكير في الأمر هي أنه نوع من الموتر ذو بُعد "الشبكة"، على الرغم من أن هذا التشبيه ليس مثاليًا لأن TFF لا يسمح بالوصول العشوائي إلى المكونات الأعضاء ذات القيمة الموحدة.

    • {<X=float32,Y=float32>*}@CLIENTS مجموعة بيانات موحدة ، وهي قيمة تتكون من تسلسلات متعددة لإحداثيات XY ، وتسلسل واحد لكل جهاز عميل.

    • <weights=float32[10,5],bias=float32[5]>@SERVER مجموعة محددة من الوزن وموترات التحيز على الخادم. نظرًا لأننا أسقطنا الأقواس المتعرجة، فهذا يشير إلى أن البت all_equal قد تم تعيينه، أي أنه لا يوجد سوى صف واحد (بغض النظر عن عدد النسخ المتماثلة للخادم التي قد تكون موجودة في مجموعة تستضيف هذه القيمة).

اللبنات

لغة الأساسية الموحدة هي شكل من أشكال حساب التفاضل والتكامل لامدا ، مع بعض العناصر الإضافية.

وهو يوفر تجريدات البرمجة التالية المعروضة حاليًا في واجهة برمجة التطبيقات العامة:

  • حسابات TensorFlow ( tff.tf_computation ). هذه أقسام من كود TensorFlow ملفوفة كمكونات قابلة لإعادة الاستخدام في TFF باستخدام مصمم الديكور tff.tf_computation . لديهم دائمًا أنواع وظيفية، وعلى عكس الوظائف في TensorFlow، يمكنهم أخذ معلمات منظمة أو إرجاع نتائج منظمة لنوع تسلسل.

    فيما يلي مثال واحد، حساب TF من النوع (int32* -> int) الذي يستخدم عامل التشغيل tf.data.Dataset.reduce لحساب مجموع الأعداد الصحيحة:

    @tff.tf_computation(tff.SequenceType(np.int32))
    def add_up_integers(x):
      return x.reduce(np.int32(0), lambda x, y: x + y)
    
  • العوامل الداخلية أو العوامل الموحدة ( tff.federated_... ). هذه مكتبة من الوظائف مثل tff.federated_sum أو tff.federated_broadcast التي تشكل الجزء الأكبر من FC API، والتي يمثل معظمها مشغلي الاتصالات الموزعة للاستخدام مع TFF.

    نشير إليها على أنها جوهرية لأنها، مثل الوظائف الجوهرية إلى حد ما، عبارة عن مجموعة مفتوحة وقابلة للتوسيع من العوامل التي يفهمها TFF، ويتم تجميعها في كود المستوى الأدنى.

    تحتوي معظم عوامل التشغيل هذه على معلمات ونتائج من الأنواع الموحدة، ومعظمها عبارة عن قوالب يمكن تطبيقها على أنواع مختلفة من البيانات.

    على سبيل المثال، يمكن اعتبار tff.federated_broadcast عامل تشغيل قالب من النوع الوظيفي T@SERVER -> T@CLIENTS .

  • تعبيرات لامدا ( tff.federated_computation ). تعبير lambda في TFF يعادل تعبير lambda أو def في Python؛ يتكون من اسم المعلمة، ونص (تعبير) يحتوي على مراجع لهذه المعلمة.

    في كود بايثون، يمكن إنشاؤها عن طريق تزيين دوال بايثون باستخدام tff.federated_computation وتحديد وسيطة.

    فيما يلي مثال لتعبير لامدا الذي ذكرناه سابقًا:

    @tff.federated_computation(tff.FederatedType(np.float32, tff.CLIENTS))
    def get_average_temperature(sensor_readings):
      return tff.federated_mean(sensor_readings)
    
  • حرفية الموضع . في الوقت الحالي، فقط tff.SERVER و tff.CLIENTS يسمحان بتعريف حسابات خادم العميل البسيطة.

  • استدعاءات الوظائف ( __call__ ). يمكن استدعاء أي شيء له نوع وظيفي باستخدام بناء جملة Python __call__ القياسي. الاستدعاء هو تعبير، نوعه هو نفس نوع نتيجة الوظيفة التي يتم استدعاؤها.

    على سبيل المثال:

    • يمثل add_up_integers(x) استدعاء لحساب TensorFlow المحدد مسبقًا في الوسيطة x . نوع هذا التعبير هو int32 .

    • يمثل tff.federated_mean(sensor_readings) استدعاء لمشغل المتوسط ​​الموحد على sensor_readings . نوع هذا التعبير هو float32@SERVER (بافتراض السياق من المثال أعلاه).

  • تكوين الصفوف واختيار عناصرها. تعبيرات بايثون بالصيغة [x, y] أو x[y] أو xy التي تظهر في نصوص الدوال المزينة بـ tff.federated_computation .