Обзор
В этом документе представлены интерфейсы, которые облегчают задачи федеративного обучения, такие как федеративное обучение или оценка с использованием существующих моделей машинного обучения, реализованных в TensorFlow. При разработке этих интерфейсов нашей основной целью было дать возможность экспериментировать с федеративным обучением, не требуя знания того, как оно работает «под капотом», а также оценить реализованные алгоритмы федеративного обучения на множестве существующих моделей и данных. Мы призываем вас внести свой вклад в развитие платформы. TFF был разработан с учетом расширяемости и возможности компоновки, и мы приветствуем вклад; мы рады видеть, что у вас получится!
Интерфейсы, предлагаемые этим уровнем, состоят из следующих трех ключевых частей:
Модели . Классы и вспомогательные функции, которые позволяют обертывать существующие модели для использования с TFF. Обертывание модели может быть таким же простым, как вызов одной функции-обертки (например,
tff.learning.models.from_keras_model
) или определение подкласса интерфейсаtff.learning.models.VariableModel
для полной настройки.Разработчики объединенных вычислений . Вспомогательные функции, которые создают объединенные вычисления для обучения или оценки с использованием существующих моделей.
Наборы данных . Стандартные коллекции данных, которые вы можете скачать и получить к ним доступ в Python для использования при моделировании сценариев федеративного обучения. Хотя федеративное обучение предназначено для использования с децентрализованными данными, которые невозможно просто загрузить централизованно, на этапах исследований и разработок часто бывает удобно проводить первоначальные эксперименты с использованием данных, которые можно загружать и манипулировать локально, особенно для разработчиков, которые могут быть новичок в подходе.
Эти интерфейсы определяются в основном в пространстве имен tff.learning
, за исключением наборов исследовательских данных и других возможностей, связанных с моделированием, которые сгруппированы в tff.simulation
. Этот уровень реализуется с использованием интерфейсов нижнего уровня, предлагаемых Federated Core (FC) , который также обеспечивает среду выполнения.
Прежде чем продолжить, мы рекомендуем сначала просмотреть учебные пособия по классификации изображений и генерации текста , поскольку они знакомят с большинством описанных здесь концепций на конкретных примерах. Если вам интересно узнать больше о том, как работает TFF, вы можете просмотреть руководство по пользовательским алгоритмам в качестве введения в низкоуровневые интерфейсы, которые мы используем для выражения логики объединенных вычислений, а также для изучения существующей реализации интерфейсы tff.learning
.
Модели
Архитектурные предположения
Сериализация
Целью TFF является поддержка различных сценариев распределенного обучения, в которых код модели машинного обучения, который вы пишете, может выполняться на большом количестве гетерогенных клиентов с различными возможностями. Хотя на одном конце спектра в некоторых приложениях такими клиентами могут быть мощные серверы баз данных, многие важные применения, которые наша платформа намерена поддерживать, связаны с мобильными и встроенными устройствами с ограниченными ресурсами. Мы не можем предполагать, что эти устройства способны размещать среду выполнения Python; единственное, что мы можем предположить на данный момент, это то, что они способны размещать локальную среду выполнения TensorFlow. Таким образом, фундаментальное архитектурное предположение, которое мы делаем в TFF, заключается в том, что код вашей модели должен быть сериализуемым в виде графа TensorFlow.
Вы по-прежнему можете (и должны) разрабатывать свой TF-код, следуя новейшим лучшим практикам, таким как использование режима нетерпеливости. Однако окончательный код должен быть сериализуемым (например, его можно обернуть в tf.function
для кода режима ожидания). Это гарантирует, что любое состояние Python или поток управления, необходимые во время выполнения, могут быть сериализованы (возможно, с помощью Autograph ).
В настоящее время TensorFlow не полностью поддерживает сериализацию и десериализацию TensorFlow в режиме ожидания. Таким образом, сериализация в TFF в настоящее время соответствует шаблону TF 1.0, где весь код должен быть создан внутри tf.Graph
, которым управляет TFF. Это означает, что в настоящее время TFF не может использовать уже созданную модель; вместо этого логика определения модели упакована в функцию без аргументов, которая возвращает tff.learning.models.VariableModel
. Затем эта функция вызывается TFF, чтобы гарантировать сериализацию всех компонентов модели. Кроме того, поскольку TFF является строго типизированной средой, ему потребуется немного дополнительных метаданных , например указание типа входных данных вашей модели.
Агрегация
Мы настоятельно рекомендуем большинству пользователей создавать модели с использованием Keras, см. раздел «Конвертеры для Keras» ниже. Эти оболочки автоматически обрабатывают агрегирование обновлений модели, а также любых метрик, определенных для модели. Тем не менее, все же может быть полезно понять, как обрабатывается агрегация для общего tff.learning.models.VariableModel
.
В федеративном обучении всегда есть как минимум два уровня агрегации: локальная агрегация на устройстве и агрегация между устройствами (или федеративная):
Локальная агрегация . Этот уровень агрегирования относится к агрегированию нескольких пакетов примеров, принадлежащих отдельному клиенту. Это относится как к параметрам модели (переменным), которые продолжают последовательно развиваться по мере локального обучения модели, так и к вычисляемой вами статистике (например, средним потерям, точности и другим показателям), которую ваша модель снова будет обновлять локально. поскольку он перебирает локальный поток данных каждого отдельного клиента.
Выполнение агрегации на этом уровне является обязанностью кода вашей модели и выполняется с использованием стандартных конструкций TensorFlow.
Общая структура обработки выглядит следующим образом:
Модель сначала создает
tf.Variable
для хранения агрегатов, таких как количество партий или количество обработанных примеров, сумма потерь на партию или на пример и т. д.TFF вызывает метод
forward_pass
в вашейModel
несколько раз, последовательно для последующих пакетов клиентских данных, что позволяет вам обновлять переменные, содержащие различные агрегаты, в качестве побочного эффекта.Наконец, TFF вызывает метод
report_local_unfinalized_metrics
в вашей модели, чтобы позволить вашей модели скомпилировать всю собранную сводную статистику в компактный набор показателей для экспорта клиентом. Здесь код вашей модели может, например, разделить сумму потерь на количество обработанных примеров для экспорта средних потерь и т. д.
Федеративное агрегирование . Этот уровень агрегации относится к агрегации нескольких клиентов (устройств) в системе. Опять же, это относится как к параметрам модели (переменным), которые усредняются по клиентам, так и к метрикам, экспортированным вашей моделью в результате локального агрегирования.
За выполнение агрегации на этом уровне отвечает TFF. Однако как создатель модели вы можете контролировать этот процесс (подробнее об этом ниже).
Общая структура обработки выглядит следующим образом:
Исходная модель и все параметры, необходимые для обучения, передаются сервером подмножеству клиентов, которые будут участвовать в раунде обучения или оценки.
На каждом клиенте независимо и параллельно код вашей модели повторно вызывается в потоке локальных пакетов данных для создания нового набора параметров модели (при обучении) и нового набора локальных метрик, как описано выше (это локальный набор показателей). агрегирование).
TFF запускает протокол распределенного агрегирования для накопления и агрегирования параметров модели и локально экспортируемых показателей по всей системе. Эта логика выражается декларативно с использованием собственного интегрированного языка вычислений TFF (не в TensorFlow). Дополнительную информацию об API агрегации см. в руководстве по пользовательским алгоритмам .
Абстрактные интерфейсы
Этот базовый интерфейс конструктор + метаданные представлен интерфейсом tff.learning.models.VariableModel
следующим образом:
Методы конструктора,
forward_pass
иreport_local_unfinalized_metrics
должны создавать переменные модели, прямой проход и статистику, о которой вы хотите сообщить, соответственно. TensorFlow, созданный этими методами, должен быть сериализуемым, как обсуждалось выше.Свойство
input_spec
, а также три свойства, которые возвращают подмножества обучаемых, необучаемых и локальных переменных, представляют собой метаданные. TFF использует эту информацию, чтобы определить, как соединить части вашей модели с алгоритмами объединенной оптимизации, а также определить внутренние сигнатуры типов, чтобы помочь в проверке правильности построенной системы (чтобы ваша модель не могла быть создана на основе данных, которые не соответствуют модель рассчитана на потребление).
Кроме того, абстрактный интерфейс tff.learning.models.VariableModel
предоставляет свойство metric_finalizers
, которое принимает нефинализированные значения метрики (возвращаемые report_local_unfinalized_metrics()
) и возвращает финальные значения метрики. Методы metric_finalizers
и report_local_unfinalized_metrics()
будут использоваться вместе для создания межклиентского агрегатора метрик при определении объединенных процессов обучения или оценочных вычислений. Например, простой агрегатор tff.learning.metrics.sum_then_finalize
сначала суммирует незавершенные значения метрик от клиентов, а затем вызывает функции финализатора на сервере.
Вы можете найти примеры того, как определить свой собственный tff.learning.models.VariableModel
во второй части нашего руководства по классификации изображений , а также в примерах моделей, которые мы используем для тестирования в model_examples.py
.
Конвертеры для Кераса
Почти всю информацию, необходимую для TFF, можно получить путем вызова интерфейсов tf.keras
, поэтому, если у вас есть модель Keras, вы можете положиться на tff.learning.models.from_keras_model
для создания tff.learning.models.VariableModel
.
Обратите внимание, что TFF по-прежнему хочет, чтобы вы предоставили конструктор — функцию модели без аргументов, например следующую:
def model_fn():
keras_model = ...
return tff.learning.models.from_keras_model(keras_model, sample_batch, loss=...)
В дополнение к самой модели вы предоставляете образец пакета данных, который TFF использует для определения типа и формы входных данных вашей модели. Это гарантирует, что TFF сможет правильно создать экземпляр модели для данных, которые фактически будут присутствовать на клиентских устройствах (поскольку мы предполагаем, что эти данные обычно недоступны на момент создания TensorFlow для сериализации).
Использование оболочек Keras проиллюстрировано в наших руководствах по классификации изображений и генерации текста .
Разработчики объединенных вычислений
Пакет tff.learning
предоставляет несколько сборщиков tff.Computation
, которые выполняют задачи, связанные с обучением; мы ожидаем, что набор таких вычислений будет расширяться в будущем.
Архитектурные предположения
Исполнение
Выполнение объединенных вычислений состоит из двух отдельных этапов.
Компиляция : TFF сначала компилирует алгоритмы федеративного обучения в абстрактное сериализованное представление всех распределенных вычислений. В этот момент происходит сериализация TensorFlow, но могут произойти и другие преобразования для обеспечения более эффективного выполнения. Мы называем сериализованное представление, создаваемое компилятором, объединенным вычислением .
Execute TFF предоставляет способы выполнения этих вычислений. На данный момент выполнение поддерживается только посредством локального моделирования (например, в блокноте с использованием моделируемых децентрализованных данных).
Интегрированные вычисления, генерируемые API федеративного обучения TFF, такие как алгоритм обучения, использующий усреднение федеративной модели или федеративную оценку, включают в себя ряд элементов, в первую очередь:
Сериализованная форма кода вашей модели, а также дополнительный код TensorFlow, созданный платформой федеративного обучения для управления циклом обучения/оценки вашей модели (например, создание оптимизаторов, применение обновлений модели, перебор
tf.data.Dataset
и вычисление метрик). и применение агрегированного обновления на сервере, и это лишь некоторые из них).Декларативная спецификация связи между клиентами и сервером (обычно различные формы агрегации на клиентских устройствах и широковещательная рассылка с сервера всем клиентам), а также то, как эта распределенная связь чередуется с выполнением на локальном клиенте или локальном сервере. кода TensorFlow.
Объединенные вычисления , представленные в этой сериализованной форме, выражаются на независимом от платформы внутреннем языке, отличном от Python, но для использования API федеративного обучения вам не нужно беспокоиться о деталях этого представления. Вычисления представлены в вашем коде Python как объекты типа tff.Computation
, которые по большей части можно рассматривать как непрозрачные callable
Python.
В руководствах вы будете вызывать эти объединенные вычисления, как если бы они были обычными функциями Python, которые должны выполняться локально. Однако TFF предназначен для выражения объединенных вычислений способом, независимым от большинства аспектов среды выполнения, так что их потенциально можно развернуть, например, в группах устройств под управлением Android
или в кластерах в центре обработки данных. Опять же, главным следствием этого являются сильные предположения о сериализации . В частности, когда вы вызываете один из методов build_...
, описанных ниже, вычисления полностью сериализуются.
Моделирование состояния
TFF — это среда функционального программирования, однако многие процессы, представляющие интерес для федеративного обучения, имеют состояние. Например, цикл обучения, включающий несколько раундов усреднения федеративной модели, является примером того, что мы могли бы классифицировать как процесс с отслеживанием состояния . В этом процессе состояние, которое меняется от раунда к раунду, включает набор обучаемых параметров модели и, возможно, дополнительное состояние, связанное с оптимизатором (например, вектор импульса).
Поскольку TFF является функциональным, процессы с отслеживанием состояния моделируются в TFF как вычисления, которые принимают текущее состояние в качестве входных данных, а затем предоставляют обновленное состояние в качестве выходных данных. Чтобы полностью определить процесс с состоянием, необходимо также указать, откуда берется начальное состояние (иначе мы не сможем запустить процесс). Это отражено в определении вспомогательного класса tff.templates.IterativeProcess
с двумя свойствами initialize
и next
, соответствующими инициализации и итерации соответственно.
Доступные строители
На данный момент TFF предоставляет различные функции построения, которые генерируют объединенные вычисления для объединенного обучения и оценки. Два примечательных примера включают в себя:
tff.learning.algorithms.build_weighted_fed_avg
, который принимает в качестве входных данных функцию модели и оптимизатор клиента и возвращаетtff.learning.templates.LearningProcess
с сохранением состояния (который является подклассомtff.templates.IterativeProcess
).tff.learning.build_federated_evaluation
принимает функцию модели и возвращает одно объединенное вычисление для объединенной оценки моделей, поскольку оценка не учитывает состояние.
Наборы данных
Архитектурные предположения
Выбор клиента
В типичном сценарии федеративного обучения мы имеем большую популяцию , потенциально насчитывающую сотни миллионов клиентских устройств, из которых только небольшая часть может быть активной и доступной для обучения в любой момент времени (например, это может быть ограничено клиентами, которые подключен к источнику питания, а не к сети со счетчиком и в противном случае находится в режиме ожидания). Как правило, набор клиентов, доступных для участия в обучении или оценке, находится вне контроля разработчика. Кроме того, поскольку координировать работу миллионов клиентов непрактично, типичный раунд обучения или оценки будет включать только часть доступных клиентов, которые могут быть выбраны случайным образом .
Ключевым следствием этого является то, что федеративные вычисления по замыслу выражаются таким образом, что не учитывается точный набор участников; вся обработка выражается как совокупные операции над абстрактной группой анонимных клиентов , и эта группа может меняться от одного раунда обучения к другому. Таким образом, фактическая привязка вычислений к конкретным участникам и, следовательно, к конкретным данным, которые они вводят в вычисления, моделируется вне самих вычислений.
Чтобы смоделировать реалистичное развертывание вашего кода федеративного обучения, вы обычно пишете цикл обучения, который выглядит следующим образом:
trainer = tff.learning.algorithms.build_weighted_fed_avg(...)
state = trainer.initialize()
federated_training_data = ...
def sample(federate_data):
return ...
while True:
data_for_this_round = sample(federated_training_data)
result = trainer.next(state, data_for_this_round)
state = result.state
Чтобы облегчить это, при использовании TFF в моделировании объединенные данные принимаются в виде list
Python, с одним элементом на каждое участвующее клиентское устройство для представления локального tf.data.Dataset
этого устройства.
Абстрактные интерфейсы
Чтобы стандартизировать работу с смоделированными наборами объединенных данных, TFF предоставляет абстрактный интерфейс tff.simulation.datasets.ClientData
, который позволяет перечислять набор клиентов и создавать tf.data.Dataset
, содержащий данные конкретного клиент. Эти tf.data.Dataset
могут быть переданы непосредственно в качестве входных данных для сгенерированных объединенных вычислений в активном режиме.
Следует отметить, что возможность доступа к идентификаторам клиентов — это функция, предоставляемая наборами данных только для использования в симуляциях, где может потребоваться возможность обучения на данных из определенных подмножеств клиентов (например, для моделирования дневной доступности различных типы клиентов). Скомпилированные вычисления и базовая среда выполнения не включают в себя какое-либо понятие идентичности клиента. Как только данные из определенного подмножества клиентов выбраны в качестве входных данных, например, при вызове tff.templates.IterativeProcess.next
, идентификаторы клиентов больше не отображаются в них.
Доступные наборы данных
Мы выделили пространство имен tff.simulation.datasets
для наборов данных, которые реализуют интерфейс tff.simulation.datasets.ClientData
для использования в симуляциях, и заполнили его наборами данных для поддержки учебных пособий по классификации изображений и генерации текста . Мы хотели бы призвать вас разместить на платформе свои собственные наборы данных.