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

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

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

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

Обзор

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

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

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

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

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

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

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

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

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

Язык

Интерфейс Python

TFF использует внутренний язык для представления объединенных вычислений, синтаксис которого определяется сериализуемым представлением в вычислений.proto . Однако пользователям FC API обычно не требуется напрямую взаимодействовать с этим языком. Вместо этого мы предоставляем Python API (пространство имен 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. Хотя код технически выражен на Python, его цель — создать сериализуемое представление tf.Graph , находящегося под ним, и именно граф, а не код Python, внутренне выполняется средой выполнения TensorFlow. Аналогично, можно думать о tff.federated_mean как о вставке объединенной операции в объединенное вычисление, представленное get_average_temperature .

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

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

Тип системы

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

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

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

    TensorTypes TFF могут быть более строгими в своей (статической) обработке фигур, чем TensorFlow. Например, система типов TFF рассматривает тензор с неизвестным рангом как присваиваемый из любого другого тензора того же dtype , но не присваиваемый какому-либо тензору с фиксированным рангом. Такая обработка предотвращает определенные сбои во время выполнения (например, попытку преобразовать тензор неизвестного ранга в форму с неправильным числом элементов) за счет большей строгости в том, какие вычисления TFF принимает как действительные.

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

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

    Компактное представление типов последовательностей — 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 .

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

    Основная цель определения понятия размещений — создание основы для определения объединенных типов .

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

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

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

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

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

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

    @tff.tensorflow.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 , которые составляют основную часть API FC, большинство из которых представляют операторы распределенной связи для использования с 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.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 (при условии контекста из примера выше).

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