Сохраните дату! Google I / O возвращается 18-20 мая Зарегистрируйтесь сейчас
Эта страница переведена с помощью Cloud Translation API.
Switch to English

Федеративное ядро

В этом документе представлен базовый уровень TFF, служащий основой для федеративного обучения , а также возможные будущие федеративные алгоритмы без обучения.

Для мягкого введения в Федеративное ядро, пожалуйста, прочитайте следующие руководства, поскольку они представляют некоторые фундаментальные концепции на примерах и демонстрируют пошаговое построение простого алгоритма федеративного усреднения.

Мы также рекомендуем вам ознакомиться с Федеративным обучением и соответствующими руководствами по классификации изображений и генерации текста , поскольку использование Федеративного Core API (FC API) для федеративного обучения обеспечивает важный контекст для некоторых вариантов, которые мы сделали в проектируя этот слой.

Обзор

Цели, предполагаемое использование и объем

Федеративное ядро ​​(FC) лучше всего понимать как среду программирования для реализации распределенных вычислений, т. Е. Вычислений, в которых задействовано несколько компьютеров (мобильные телефоны, планшеты, встроенные устройства, настольные компьютеры, датчики, серверы баз данных и т. Д.), Каждый из которых может не выполнять своих функций. тривиальная обработка локально и общение по сети для координации своей работы.

Термин « распределенные» является очень общим, и TFF не нацелен на все возможные типы распределенных алгоритмов, поэтому мы предпочитаем использовать менее общий термин « федеративные вычисления» для описания типов алгоритмов, которые могут быть выражены в этой структуре.

Хотя определение термина « федеративные вычисления» полностью формально выходит за рамки этого документа, подумайте о типах алгоритмов, которые вы могли бы увидеть выраженными в псевдокоде в исследовательской публикации , описывающей новый алгоритм распределенного обучения.

Короче говоря, цель FC - обеспечить аналогичное компактное представление на аналогичном псевдокодовом уровне абстракции программной логики, которая не является псевдокодом, а исполняется в различных целевых средах.

Ключевой определяющей характеристикой типов алгоритмов, которые призван выражать FC, является то, что действия участников системы описываются коллективно. Таким образом, мы склонны говорить о каждом устройстве, локально преобразующем данные, и об устройствах, координирующих работу с помощью централизованного координатора, транслирующего , собирая или агрегируя свои результаты.

Хотя TFF был разработан, чтобы иметь возможность выйти за рамки простых архитектур клиент-сервер , понятие коллективной обработки является фундаментальным. Это связано с происхождением TFF ​​в федеративном обучении, технологии, изначально разработанной для поддержки вычислений с потенциально конфиденциальными данными, которые остаются под контролем клиентских устройств и которые не могут быть просто загружены в централизованное место по соображениям конфиденциальности. Хотя каждый клиент в таких системах предоставляет данные и вычислительную мощность для вычисления результата системой (результат, который, как мы обычно ожидаем, будет ценным для всех участников), мы также стремимся сохранить конфиденциальность и анонимность каждого клиента.

Таким образом, в то время как большинство структур для распределенных вычислений предназначены для выражения обработки с точки зрения отдельных участников, то есть на уровне обмена отдельными сообщениями точка-точка и взаимозависимости локальных переходов состояния участника с входящими и исходящими сообщениями Федеративное ядро ​​TFF разработано для описания поведения системы с точки зрения глобальной системы (аналогично, например, MapReduce ).

Следовательно, в то время как распределенные структуры для общих целей могут предлагать такие операции, как отправка и получение, в качестве строительных блоков, FC предоставляет стандартные блоки, такие как tff.federated_sum , tff.federated_reduce или tff.federated_broadcast которые инкапсулируют простые распределенные протоколы.

Язык

Интерфейс Python

TFF использует внутренний язык для представления объединенных вычислений, синтаксис которых определяется сериализуемым представлением в computation.proto . Однако пользователям FC API обычно не нужно напрямую взаимодействовать с этим языком. Скорее, мы предоставляем Python API (пространство имен tff ), которое обтекает его как способ определения вычислений.

В частности, TFF предоставляет декораторы функций Python, такие как tff.federated_computation которые отслеживают тела декорированных функций и создают сериализованные представления логики объединенных вычислений на языке TFF. Функция, украшенная tff.federated_computation действует как носитель такого сериализованного представления и может встроить его в качестве строительного блока в тело другого вычисления или выполнить по запросу при вызове.

Вот только один пример; другие примеры можно найти в руководствах по пользовательским алгоритмам .

@tff.federated_computation(tff.type_at_clients(tf.float32))
def get_average_temperature(sensor_readings):
  return tff.federated_mean(sensor_readings)

Читатели, знакомые с tf.add tf.reduce_sum найдут этот подход аналогом написания кода Python, который использует такие функции, как tf.add или tf.reduce_sum в разделе кода Python, который определяет граф TensorFlow. Хотя код технически выражен на Python, его цель состоит в том, чтобы построить сериализуемое представление tf.Graph под ним, и tf.Graph выполнения tf.Graph внутренне выполняет именно график, а не код Python. Точно так же можно думать о tff.federated_mean как о вставке объединенной операции в объединенное вычисление, представленное get_average_temperature .

Частично причина, по которой FC определяет язык, связана с тем фактом, что, как отмечалось выше, федеративные вычисления задают распределенное коллективное поведение, и поэтому их логика нелокальна. Например, TFF предоставляет операторов, входы и выходы которых могут находиться в разных местах сети.

Это требует языка и системы типов, отражающих понятие распределенности.

Тип Система

Federated Core предлагает следующие категории типов. При описании этих типов мы указываем на конструкторы типов, а также вводим компактные обозначения, поскольку это удобный способ описания типов вычислений и операторов.

Во-первых, вот категории типов, концептуально похожие на те, которые встречаются в существующих основных языках:

  • Тензорные типы ( tff.TensorType ). Как и в TensorFlow, у них есть dtype и shape . Единственное отличие состоит в том, что объекты этого типа не ограничиваются экземплярами tf.Tensor в Python, которые представляют выходные данные операций TensorFlow в графе TensorFlow, но могут также включать единицы данных, которые могут быть созданы, например, как выход распределенного протокол агрегации. Таким образом, тензорный тип TFF - это просто абстрактная версия конкретного физического представления такого типа в Python или TensorFlow.

    Компактная запись для тензорных типов - dtype или dtype[shape] . Например, int32 и int32[10] - это типы целых чисел и векторов int соответственно.

  • Типы последовательностей ( tff.SequenceType ). Это абстрактный эквивалент TFF конкретной концепцииtf.data.Dataset s. Элементы последовательностей могут потребляться последовательно и могут включать сложные типы.

    Компактное представление типов последовательностей - это T* , где T - тип элементов. Например, int32* представляет собой целочисленную последовательность.

  • Именованные типы кортежей ( tff.StructType ). Это способ TFF построения кортежей и структур, подобных словарю, которые имеют предопределенное количество элементов с определенными типами, именованными или безымянными. Важно отметить, что концепция именованных кортежей TFF охватывает абстрактный эквивалент кортежей аргументов Python, т. Е. Коллекции элементов, некоторые из которых, но не все, имеют имена, а некоторые являются позиционными.

    Компактная запись для именованных кортежей - <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) если аргумента нет (хотя функции без аргументов являются вырожденными концепция, которая существует в основном только на уровне Python). Например (int32* -> int32) - это обозначение для типа функций, которые сокращают целочисленную последовательность до единственного целочисленного значения.

Следующие типы обращаются к аспекту распределенных систем вычислений TFF. Поскольку эти концепции в некоторой степени уникальны для TFF, мы рекомендуем вам обратиться к руководству по пользовательским алгоритмам для получения дополнительных комментариев и примеров.

  • Тип размещения . Этот тип еще не представлен в общедоступном API, кроме как в виде двух литералов tff.SERVER и tff.CLIENTS , которые можно рассматривать как константы этого типа. Однако он используется внутри компании и будет представлен в общедоступном API в будущих выпусках. Компактное представление этого типа - placement .

    Размещение представляет собой коллектив участников системы, играющих определенную роль. Первоначальный выпуск ориентирован на вычисления клиент-сервер, в которых есть 2 группы участников: клиенты и сервер (вы можете думать о последнем как о группе синглтонов). Однако в более сложных архитектурах могут быть другие роли, такие как промежуточные агрегаторы в многоуровневой системе, которые могут выполнять разные типы агрегации или использовать другие типы сжатия / распаковки данных, чем те, которые используются сервером или клиентов.

    Основная цель определения понятия размещения - это основа для определения федеративных типов .

  • Федеративные типы ( 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 бит all_equal , т. all_equal Существует только один кортеж (независимо от того, сколько реплик сервера может быть в кластере, содержащем это значение).

Строительные блоки

Язык Federated Core - это форма лямбда-исчисления с несколькими дополнительными элементами.

Он предоставляет следующие абстракции программирования, которые в настоящее время доступны в общедоступном API:

  • TensorFlow вычисления ( tff.tf_computation ). Это разделы кода tff.tf_computation в TFF как повторно используемые компоненты с помощью декоратора tff.tf_computation . У них всегда есть функциональные типы, и в отличие от функций в TensorFlow, они могут принимать структурированные параметры или возвращать структурированные результаты типа последовательности.

    Вот один пример, вычисление TF типа (int32* -> int) которое использует оператор tf.data.Dataset.reduce для вычисления суммы целых чисел:

    @tff.tf_computation(tff.SequenceType(tf.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 ). Выражение лямбда в TFF является эквивалентом lambda или def в Python; он состоит из имени параметра и тела (выражения), которое содержит ссылки на этот параметр.

    В коде Python их можно создать, украсив функции Python с помощью tff.federated_computation и определив аргумент.

    Вот пример лямбда-выражения, которое мы уже упоминали ранее:

    @tff.federated_computation(tff.type_at_clients(tf.float32))
    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 (при условии контекста из приведенного выше примера).

  • Формирование кортежей и выбор их элементов. Выражения Python в форме [x, y] , x[y] или xy которые появляются в телах функций, украшенных tff.federated_computation .