¡El Día de la Comunidad de ML es el 9 de noviembre! Únase a nosotros para recibir actualizaciones de TensorFlow, JAX, y más Más información

Núcleo federado

Este documento presenta la capa central de la TFF que sirve como base para Federados de aprendizaje , y los posibles futuros algoritmos de aprendizaje no federados.

Para una introducción suave a Federated Core, lea los siguientes tutoriales, ya que presentan algunos de los conceptos fundamentales con ejemplos y demuestran paso a paso la construcción de un algoritmo de promediado federado simple.

También le alentamos a familiarizarse con Federados de aprendizaje y los tutoriales asociados en la clasificación de imágenes y la generación de texto , como los usos de la API federada Core (FC API) para el aprendizaje federados proporcionar un contexto importante para algunas de las decisiones que hemos tomado en diseñando esta capa.

Visión general

Objetivos, usos previstos y alcance

Federated Core (FC) se entiende mejor como un entorno de programación para implementar cálculos distribuidos, es decir, cálculos que involucran múltiples computadoras (teléfonos móviles, tabletas, dispositivos integrados, computadoras de escritorio, sensores, servidores de bases de datos, etc.) procesamiento trivial localmente y comunicarse a través de la red para coordinar su trabajo.

El término distribuida es muy genérico, y TFF no se dirige a todos los posibles tipos de algoritmos distribuidos por ahí, por lo que preferimos utilizar el cálculo federados menos genérico término para describir los tipos de algoritmos que se pueden expresar en este marco.

Al definir el cálculo federados término de una manera totalmente formal, está fuera del alcance de este documento, pensar en los tipos de algoritmos puede que vea los expresados en pseudocódigo en una publicación de investigación que describe un nuevo algoritmo de aprendizaje distribuido.

El objetivo de la FC, en un nusthell, es permitir la representación de manera similar compacta, en un nivel similar al pseudocódigo similar de abstracción, la lógica de programa que no es pseudocódigo, sino más bien, que es ejecutable en una variedad de entornos de destino.

La característica clave que define los tipos de algoritmos que FC está diseñado para expresar es que las acciones de los participantes del sistema se describen de manera colectiva. Por lo tanto, tienden a hablar acerca de cada dispositivo de transformación de forma local de datos, y los dispositivos de coordinar el trabajo por una radiodifusión coordinador centralizado, recogida, o la agregación de sus resultados.

Mientras TFF ha sido diseñado para ser capaz de ir más allá de las arquitecturas cliente-servidor simples, la noción de tratamiento colectivo es fundamental. Esto se debe a los orígenes de TFF en el aprendizaje federado, una tecnología diseñada originalmente para admitir cálculos sobre datos potencialmente confidenciales que permanecen bajo el control de los dispositivos del cliente y que no pueden simplemente descargarse en una ubicación centralizada por razones de privacidad. Si bien cada cliente en dichos sistemas aporta datos y poder de procesamiento para calcular un resultado del sistema (un resultado que generalmente esperaríamos que sea de valor para todos los participantes), también nos esforzamos por preservar la privacidad y el anonimato de cada cliente.

Por lo tanto, mientras que la mayoría de los marcos para la computación distribuida están diseñados para expresar el procesamiento desde la perspectiva de los participantes individuales, es decir, al nivel de los intercambios de mensajes individuales punto a punto y la interdependencia de las transiciones del estado local del participante con los mensajes entrantes y salientes. , de TFF Federados Core está diseñado para describir el comportamiento del sistema desde el punto de vista global de todo el sistema (de forma similar a, por ejemplo, MapReduce ).

En consecuencia, mientras que los marcos distribuidos para propósitos generales pueden ofrecer operaciones como enviar y recibir como bloques de construcción, FC proporciona bloques de construcción tales como tff.federated_sum , tff.federated_reduce o tff.federated_broadcast que encapsulan sencilla protocolos distribuidos.

Idioma

Interfaz de Python

TFF usa un lenguaje interno para representar cálculos federados, la sintaxis de los cuales se define por la representación serializable en computation.proto . Sin embargo, los usuarios de la API de FC generalmente no necesitarán interactuar con este lenguaje directamente. Más bien, se proporciona una API de Python (la tff espacio de nombres) que envuelve Arounds como una manera de definir los cálculos.

Específicamente, TFF proporciona decoradores función de Python como tff.federated_computation que traza los cuerpos de las funciones decoradas, y producir representaciones serializada de la lógica de cálculo federados en el idioma del TFF. Una función decorado con tff.federated_computation actúa como un portador de tal representación serializada, y puede incrustarlo como un bloque de construcción en el cuerpo de otro cálculo, o ejecutar en la demanda cuando se invoca.

Aquí hay solo un ejemplo; Más ejemplos se pueden encontrar en los algoritmos personalizados tutoriales.

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

Los lectores familiarizados con TensorFlow no ansiosos encontrarán este enfoque análogo a la escritura de código Python que las funciones de los usos tales como tf.add o tf.reduce_sum en una sección de código Python que define un gráfico TensorFlow. Aunque el código se expresa técnicamente en Python, su propósito es construir una representación serializable de un tf.Graph debajo, y es el gráfico, no el código Python, que está internamente ejecutado por el tiempo de ejecución TensorFlow. Del mismo modo, se puede pensar en tff.federated_mean como insertar un op federado en un cálculo federados representado por get_average_temperature .

Una parte de la razón por la que FC define un lenguaje tiene que ver con el hecho de que, como se señaló anteriormente, los cálculos federados especifican comportamientos colectivos distribuidos y, como tal, su lógica no es local. Por ejemplo, TFF proporciona operadores, cuyas entradas y salidas pueden existir en diferentes lugares de la red.

Esto requiere un lenguaje y un sistema de tipos que capture la noción de distribución.

Tipo de sistema

Federated Core ofrece las siguientes categorías de tipos. Al describir estos tipos, señalamos los constructores de tipos y también introducimos una notación compacta, ya que es una forma práctica de describir tipos de cálculos y operadores.

Primero, aquí están las categorías de tipos que son conceptualmente similares a las que se encuentran en los lenguajes convencionales existentes:

  • Tipos de tensor ( tff.TensorType ). Al igual que en TensorFlow, estos tienen dtype y shape . La única diferencia es que los objetos de este tipo no se limitan a tf.Tensor casos en Python que representan salidas de ops TensorFlow en un gráfico TensorFlow, pero también puede incluir unidades de datos que pueden ser producidos, por ejemplo, como una salida de un distribuido protocolo de agregación. Por lo tanto, el tipo de tensor TFF es simplemente una versión abstracta de una representación física concreta de ese tipo en Python o TensorFlow.

    La notación compacta para este tipo de tensor es dtype o dtype[shape] . Por ejemplo, int32 y int32[10] son los tipos de números enteros y vectores int, respectivamente.

  • Tipos de secuencia ( tff.SequenceType ). Estos son equivalentes abstracta de TFF del concepto concreto de TensorFlow de tf.data.Dataset s. Los elementos de las secuencias se pueden consumir de forma secuencial y pueden incluir tipos complejos.

    La representación compacta de tipos de secuencia es T* , donde T es el tipo de elementos. Por ejemplo int32* representa una secuencia de número entero.

  • Tipos de tupla con nombre ( tff.StructType ). Estos son manera de construir tuplas y diccionario-como las estructuras que tienen un número predefinido de elementos con tipos específicos, con o sin nombre de TFF. Es importante destacar que el concepto de tupla con nombre de TFF abarca el equivalente abstracto de las tuplas de argumentos de Python, es decir, colecciones de elementos de los cuales algunos, pero no todos, son nombrados y algunos son posicionales.

    La notación compacta para tuplas con nombre es <n_1=T_1, ..., n_k=T_k> , donde n_k son los nombres de elementos opcionales, y T_k son tipos de elementos. Por ejemplo, <int32,int32> es una notación compacta para un par de enteros sin nombre, y <X=float32,Y=float32> es una notación compacta para un par de flotadores llamado X y Y que puede representar un punto en un plano . Las tuplas se pueden anidar, así como mezclado con otros tipos, por ejemplo, <X=float32,Y=float32>* sería una notación compacta para una secuencia de puntos.

  • Tipos de función ( tff.FunctionType ). TFF es un marco de programación funcional, con funciones tratados como valores de primera clase . Las funciones tienen como máximo un argumento y exactamente un resultado.

    La notación compacta para las funciones es (T -> U) , donde T es el tipo de argumento, y U es el tipo del resultado, o ( -> U) si no hay un argumento (aunque funciona sin argumentos son un degenerado concepto que existe principalmente solo en el nivel de Python). Por ejemplo (int32* -> int32) es una notación para un tipo de funciones que reducen una secuencia de número entero a un único valor entero.

Los siguientes tipos abordan el aspecto de los sistemas distribuidos de los cálculos de TFF. A medida que estos conceptos son algo exclusivo de TFF, le recomendamos que consulte la algoritmos personalizados tutorial para comentarios y ejemplos adicionales.

  • Tipo de práctica. Este tipo aún no se expone en la API pública que no sea en forma de 2 literales tff.SERVER y tff.CLIENTS que se pueda imaginar como constantes de este tipo. Sin embargo, se usa internamente y se introducirá en la API pública en versiones futuras. La representación compacta de este tipo es placement .

    Una colocación representa un colectivo de los participantes del sistema que desempeñan una función en particular. La versión inicial se dirige a los cálculos cliente-servidor, en el que hay 2 grupos de participantes: clientes y un servidor (se puede pensar en esta última como un grupo Singleton). Sin embargo, en arquitecturas más elaboradas, podría haber otros roles, como agregadores intermedios en un sistema de múltiples niveles, que podrían estar realizando diferentes tipos de agregación o usar diferentes tipos de compresión / descompresión de datos que los usados ​​por el servidor o los clientes.

    El propósito principal de la definición de la noción de colocaciones es como una base para definir tipos federados.

  • Tipos federados ( tff.FederatedType ). Un valor de un tipo federados es uno que está alojado por un grupo de participantes en el sistema definido por una ubicación específica (tales como tff.SERVER o tff.CLIENTS ). Un tipo federados se define por el valor de colocación (por lo tanto, es un tipo dependiente ), el tipo de los constituyentes miembro (qué tipo de contenido de cada uno de los participantes tendrá lugar localmente), y el bit adicional all_equal que especifica si todos los participantes son localmente albergando el mismo artículo.

    La notación compacta para el tipo Federados de valores que incluyen artículos (constituyentes miembros) de tipo T , cada uno alojados por grupo (colocación) G es T@G o {T}@G con el all_equal conjunto de bits o no se establece, respectivamente.

    Por ejemplo:

    • {int32}@CLIENTS representa un valor federada que consiste en un conjunto de números enteros potencialmente distintos, uno por cada dispositivo cliente. Tenga en cuenta que estamos hablando de un solo valor federados que engloba varios elementos de los datos que aparecen en múltiples localizaciones a través de la red. Una forma de pensar en ello es como una especie de tensor con una "red" dimensión, aunque esta analogía no es perfecta porque TFF no permite el acceso aleatorio a los constituyentes miembros de un valor federado.

    • {<X=float32,Y=float32>*}@CLIENTS representa un conjunto de datos federada, un valor que se compone de múltiples secuencias de XY coordenadas, una secuencia por cada dispositivo cliente.

    • <weights=float32[10,5],bias=float32[5]>@SERVER representa una tupla con nombre de peso y sesgo tensores en el servidor. Como nos han caído las llaves, esto indica que el all_equal se establece bits, es decir, sólo hay una única tupla (independientemente del número de réplicas del servidor que puede haber en un clúster de alojamiento de este valor).

Bloques de construcción

El lenguaje de Federated Core es una forma de cálculo lambda , con algunos elementos adicionales.

Proporciona las siguientes abstracciones de programación expuestas actualmente en la API pública:

  • TensorFlow cálculos ( tff.tf_computation ). Estos son secciones de código TensorFlow envuelto como componentes reutilizables en TFF utilizando el tff.tf_computation decorador. Siempre tienen tipos funcionales y, a diferencia de las funciones de TensorFlow, pueden tomar parámetros estructurados o devolver resultados estructurados de un tipo de secuencia.

    Aquí está un ejemplo, un cálculo del TF del tipo (int32* -> int) que utiliza el tf.data.Dataset.reduce operador para calcular una suma de números enteros:

    @tff.tf_computation(tff.SequenceType(tf.int32))
    def add_up_integers(x):
      return x.reduce(np.int32(0), lambda x, y: x + y)
    
  • Intrínseco o operadores federados ( tff.federated_... ). Esta es una biblioteca de funciones tales como tff.federated_sum o tff.federated_broadcast que constituyen el grueso de FC API, la mayoría de los cuales representan distribuye operadores de comunicaciones para uso con TFF.

    Nos referimos a estos como los intrínsecos porque, algo así como funciones intrínsecas , que son un conjunto de composición abierta y extensible de operadores que se entiende por TFF, y compiló abajo en código de nivel inferior.

    La mayoría de estos operadores tienen parámetros y resultados de tipos federados y la mayoría son plantillas que se pueden aplicar a varios tipos de datos.

    Por ejemplo, tff.federated_broadcast puede ser pensado como un operador de plantilla de tipo funcional T@SERVER -> T@CLIENTS .

  • Las expresiones lambda ( tff.federated_computation ). Una expresión lambda en TFF es el equivalente de una lambda o def en Python; consta del nombre del parámetro y un cuerpo (expresión) que contiene referencias a este parámetro.

    En el código Python, estos pueden ser creados mediante la decoración de las funciones de Python con tff.federated_computation y la definición de una discusión.

    Aquí hay un ejemplo de una expresión lambda que ya mencionamos anteriormente:

    @tff.federated_computation(tff.type_at_clients(tf.float32))
    def get_average_temperature(sensor_readings):
      return tff.federated_mean(sensor_readings)
    
  • Los literales de colocación. Por ahora, sólo se tff.SERVER y tff.CLIENTS para permitir la definición de cálculos sencillos cliente-servidor.

  • Invocaciones de función ( __call__ ). Todo lo que tiene un tipo funcional se puede invocar utilizando el estándar de Python __call__ sintaxis. La invocación es una expresión, cuyo tipo es el mismo que el tipo del resultado de la función que se invoca.

    Por ejemplo:

    • add_up_integers(x) representa una invocación de la computación TensorFlow definido anteriormente en un argumento x . El tipo de esta expresión es int32 .

    • tff.federated_mean(sensor_readings) representa una invocación del operador de promediado federado en sensor_readings . El tipo de esta expresión es float32@SERVER (suponiendo contexto en el ejemplo anterior).

  • La formación de tuplas y la selección de sus elementos. Expresiones Python de la forma [x, y] , x[y] , o xy que aparecen en los cuerpos de funciones decorados con tff.federated_computation .