Este documento apresenta a camada central do TFF que serve como base para o Aprendizado Federado e possíveis futuros algoritmos federados de não aprendizado.
Para uma introdução suave ao Federated Core, leia os tutoriais a seguir, pois eles apresentam alguns dos conceitos fundamentais por exemplo e demonstram passo a passo a construção de um algoritmo simples de média federada.
Algoritmos Federados Personalizados, Parte 1: Introdução ao Núcleo Federado .
Algoritmos Federados Personalizados, Parte 2: Implementando Média Federada .
Também recomendamos que você se familiarize com o Federated Learning e os tutoriais associados sobre classificação de imagens e geração de texto , pois os usos da Federated Core API (FC API) para aprendizado federado fornecem um contexto importante para algumas das escolhas que fizemos em projetando esta camada.
Visão geral
Metas, usos pretendidos e escopo
Federated Core (FC) é melhor entendido como um ambiente de programação para implementar computações distribuídas, ou seja, computações que envolvem vários computadores (telefones celulares, tablets, dispositivos embarcados, computadores desktop, sensores, servidores de banco de dados, etc.) que podem, cada um, executar tarefas não operacionais. processamento trivial localmente e se comunicar através da rede para coordenar seu trabalho.
O termo distribuído é muito genérico e o TFF não se destina a todos os tipos possíveis de algoritmos distribuídos existentes, por isso preferimos usar o termo menos genérico computação federada para descrever os tipos de algoritmos que podem ser expressos nesta estrutura.
Embora a definição do termo computação federada de maneira totalmente formal esteja fora do escopo deste documento, pense nos tipos de algoritmos que você pode ver expressos em pseudocódigo em uma publicação de pesquisa que descreve um novo algoritmo de aprendizado distribuído.
O objetivo do FC, em poucas palavras, é permitir uma representação compacta semelhante, em um nível de abstração semelhante ao pseudocódigo, da lógica do programa que não é pseudocódigo, mas sim executável em uma variedade de ambientes de destino.
A principal característica definidora dos tipos de algoritmos que o FC foi projetado para expressar é que as ações dos participantes do sistema são descritas de maneira coletiva. Assim, tendemos a falar sobre cada dispositivo que transforma dados localmente, e os dispositivos que coordenam o trabalho de um coordenador centralizado que transmite , coleta ou agrega seus resultados.
Embora o TFF tenha sido projetado para ir além das simples arquiteturas cliente-servidor , a noção de processamento coletivo é fundamental. Isto deve-se às origens do TFF na aprendizagem federada, uma tecnologia originalmente concebida para suportar cálculos em dados potencialmente sensíveis que permanecem sob controlo de dispositivos clientes e que não podem ser simplesmente descarregados para um local centralizado por razões de privacidade. Embora cada cliente em tais sistemas contribua com dados e poder de processamento para calcular um resultado pelo sistema (um resultado que geralmente esperamos que seja de valor para todos os participantes), também nos esforçamos para preservar a privacidade e o anonimato de cada cliente.
Assim, embora a maioria das estruturas para computação distribuída sejam projetadas para expressar o processamento da perspectiva de participantes individuais - isto é, no nível de trocas individuais de mensagens ponto a ponto e a interdependência das transições de estado local do participante com mensagens recebidas e enviadas , o Federated Core do TFF é projetado para descrever o comportamento do sistema a partir da perspectiva global do sistema (semelhante a, por exemplo, MapReduce ).
Conseqüentemente, embora estruturas distribuídas para fins gerais possam oferecer operações como envio e recebimento como blocos de construção, o FC fornece blocos de construção como tff.federated_sum
, tff.federated_reduce
ou tff.federated_broadcast
que encapsulam protocolos distribuídos simples.
Linguagem
Interface Python
O TFF usa uma linguagem interna para representar computações federadas, cuja sintaxe é definida pela representação serializável em computation.proto . Porém, os usuários da API FC geralmente não precisarão interagir diretamente com essa linguagem. Em vez disso, fornecemos uma API Python (o namespace tff
) que a envolve como uma forma de definir cálculos.
Especificamente, o TFF fornece decoradores de funções Python, como tff.federated_computation
, que rastreiam os corpos das funções decoradas e produzem representações serializadas da lógica de computação federada na linguagem do TFF. Uma função decorada com tff.federated_computation
atua como portadora de tal representação serializada e pode incorporá-la como um bloco de construção no corpo de outra computação ou executá-la sob demanda quando invocada.
Aqui está apenas um exemplo; mais exemplos podem ser encontrados nos tutoriais de algoritmos personalizados .
@tff.federated_computation(tff.FederatedType(np.float32, tff.CLIENTS))
def get_average_temperature(sensor_readings):
return tff.federated_mean(sensor_readings)
Os leitores não familiarizados com o TensorFlow acharão essa abordagem análoga a escrever código Python que usa funções como tf.add
ou tf.reduce_sum
em uma seção de código Python que define um gráfico do TensorFlow. Embora o código seja tecnicamente expresso em Python, seu objetivo é construir uma representação serializável de um tf.Graph
subjacente, e é o gráfico, e não o código Python, que é executado internamente pelo tempo de execução do TensorFlow. Da mesma forma, pode-se pensar em tff.federated_mean
como a inserção de uma operação federada em uma computação federada representada por get_average_temperature
.
Uma parte da razão para o FC definir uma linguagem tem a ver com o fato de que, como observado acima, as computações federadas especificam comportamentos coletivos distribuídos e, como tal, sua lógica é não local. Por exemplo, a TFF fornece operadores, cujas entradas e saídas podem existir em diferentes locais da rede.
Isso exige uma linguagem e um sistema de tipos que capturem a noção de distribuição.
Tipo Sistema
Federated Core oferece as seguintes categorias de tipos. Ao descrever esses tipos, apontamos para os construtores de tipo e também introduzimos uma notação compacta, pois é uma forma prática de descrever tipos de cálculos e operadores.
Primeiro, aqui estão as categorias de tipos que são conceitualmente semelhantes aos encontrados nas linguagens convencionais existentes:
Tipos de tensor (
tff.TensorType
). Assim como no TensorFlow, eles possuemdtype
eshape
. A única diferença é que objetos desse tipo não estão limitados a instânciastf.Tensor
em Python que representam saídas de operações do TensorFlow em um gráfico do TensorFlow, mas também podem incluir unidades de dados que podem ser produzidas, por exemplo, como uma saída de um arquivo distribuído. protocolo de agregação. Assim, o tipo de tensor TFF é simplesmente uma versão abstrata de uma representação física concreta desse tipo em Python ou TensorFlow.TensorTypes
do TFF podem ser mais rígidos no tratamento (estático) das formas do que o TensorFlow. Por exemplo, o sistema de tipos do TFF trata um tensor com classificação desconhecida como atribuível a qualquer outro tensor do mesmodtype
, mas não atribuível a qualquer tensor com classificação fixa. Este tratamento evita certas falhas de tempo de execução (por exemplo, tentativa de remodelar um tensor de classificação desconhecida em uma forma com número incorreto de elementos), ao custo de maior rigor nos cálculos que o TFF aceita como válidos.A notação compacta para tipos de tensor é
dtype
oudtype[shape]
. Por exemplo,int32
eint32[10]
são os tipos de inteiros e vetores int, respectivamente.Tipos de sequência (
tff.SequenceType
). Esses são o equivalente abstrato do TFF ao conceito concreto detf.data.Dataset
s do TensorFlow. Elementos de sequências podem ser consumidos de maneira sequencial e podem incluir tipos complexos.A representação compacta dos tipos de sequência é
T*
, ondeT
é o tipo de elementos. Por exemploint32*
representa uma sequência inteira.Tipos de tupla nomeados (
tff.StructType
). Essa é a maneira do TFF construir tuplas e estruturas semelhantes a dicionários que possuem um número predefinido de elementos com tipos específicos, nomeados ou não. É importante ressaltar que o conceito de tupla nomeada do TFF abrange o equivalente abstrato das tuplas de argumento do Python, ou seja, coleções de elementos dos quais alguns, mas não todos, são nomeados, e alguns são posicionais.A notação compacta para tuplas nomeadas é
<n_1=T_1, ..., n_k=T_k>
, onden_k
são nomes de elementos opcionais eT_k
são tipos de elementos. Por exemplo,<int32,int32>
é uma notação compacta para um par de números inteiros sem nome e<X=float32,Y=float32>
é uma notação compacta para um par de pontos flutuantes chamadosX
eY
que podem representar um ponto em um plano . Tuplas podem ser aninhadas e também misturadas com outros tipos, por exemplo,<X=float32,Y=float32>*
seria uma notação compacta para uma sequência de pontos.Tipos de função (
tff.FunctionType
). TFF é um framework de programação funcional, com funções tratadas como valores de primeira classe . As funções têm no máximo um argumento e exatamente um resultado.A notação compacta para funções é
(T -> U)
, ondeT
é o tipo de um argumento eU
é o tipo do resultado, ou( -> U)
se não houver argumento (embora funções sem argumento sejam degeneradas conceito que existe principalmente apenas no nível Python). Por exemplo(int32* -> int32)
é uma notação para um tipo de função que reduz uma sequência inteira a um único valor inteiro.
Os tipos a seguir abordam o aspecto de sistemas distribuídos dos cálculos TFF. Como esses conceitos são exclusivos do TFF, recomendamos que você consulte o tutorial de algoritmos personalizados para obter comentários e exemplos adicionais.
Tipo de posicionamento . Este tipo ainda não está exposto na API pública, exceto na forma de 2 literais
tff.SERVER
etff.CLIENTS
que você pode considerar como constantes desse tipo. No entanto, ele é usado internamente e será introduzido na API pública em versões futuras. A representação compacta deste tipo éplacement
.Uma colocação representa um coletivo de participantes do sistema que desempenham uma função específica. A versão inicial tem como alvo cálculos cliente-servidor, nos quais existem 2 grupos de participantes: clientes e um servidor (você pode pensar neste último como um grupo singleton). No entanto, em arquiteturas mais elaboradas, pode haver outras funções, como agregadores intermediários em um sistema multicamadas, que podem executar diferentes tipos de agregação ou usar tipos diferentes de compactação/descompactação de dados daqueles usados pelo servidor ou pelo servidor. os clientes.
O objetivo principal da definição da noção de canais é servir de base para a definição de tipos federados .
Tipos federados (
tff.FederatedType
). Um valor de tipo federado é aquele hospedado por um grupo de participantes do sistema definido por um posicionamento específico (comotff.SERVER
outff.CLIENTS
). Um tipo federado é definido pelo valor do posicionamento (portanto, é um tipo dependente ), pelo tipo de constituintes do membro (que tipo de conteúdo cada um dos participantes hospeda localmente) e pelo bit adicionalall_equal
que especifica se todos os participantes estão localmente hospedando o mesmo item.A notação compacta para tipos federados de valores que incluem itens (constituintes de membros) do tipo
T
, cada um hospedado pelo grupo (posicionamento)G
éT@G
ou{T}@G
com o bitall_equal
definido ou não definido, respectivamente.Por exemplo:
{int32}@CLIENTS
representa um valor federado que consiste em um conjunto de números inteiros potencialmente distintos, um por dispositivo cliente. Observe que estamos falando de um único valor federado que abrange vários itens de dados que aparecem em vários locais da rede. Uma maneira de pensar nisso é como uma espécie de tensor com dimensão de “rede”, embora esta analogia não seja perfeita porque o TFF não permite acesso aleatório aos constituintes membros de um valor federado.{<X=float32,Y=float32>*}@CLIENTS
representa um conjunto de dados federado , um valor que consiste em diversas sequências de coordenadasXY
, uma sequência por dispositivo cliente.<weights=float32[10,5],bias=float32[5]>@SERVER
representa uma tupla nomeada de tensores de peso e polarização no servidor. Como eliminamos as chaves, isso indica que o bitall_equal
está definido, ou seja, há apenas uma única tupla (independentemente de quantas réplicas de servidor possam existir em um cluster que hospeda esse valor).
Blocos de construção
A linguagem do Federated Core é uma forma de cálculo lambda , com alguns elementos adicionais.
Ele fornece as seguintes abstrações de programação atualmente expostas na API pública:
Cálculos do TensorFlow (
tff.tensorflow.computation
). Estas são seções de código do TensorFlow agrupadas como componentes reutilizáveis no TFF usando o decoradortff.tensorflow.computation
. Eles sempre têm tipos funcionais e, diferentemente das funções do TensorFlow, podem receber parâmetros estruturados ou retornar resultados estruturados de um tipo de sequência.Aqui está um exemplo, um cálculo TF do tipo
(int32* -> int)
que usa o operadortf.data.Dataset.reduce
para calcular uma soma de inteiros:@tff.tensorflow.computation(tff.SequenceType(np.int32)) def add_up_integers(x): return x.reduce(np.int32(0), lambda x, y: x + y)
Operadores intrínsecos ou federados (
tff.federated_...
). Esta é uma biblioteca de funções comotff.federated_sum
outff.federated_broadcast
que constituem a maior parte da API FC, a maioria das quais representa operadores de comunicação distribuída para uso com TFF.Nós nos referimos a eles como intrínsecos porque, assim como as funções intrínsecas , eles são um conjunto aberto e extensível de operadores que são compreendidos pelo TFF e compilados em código de nível inferior.
A maioria desses operadores possui parâmetros e resultados de tipos federados e a maioria são modelos que podem ser aplicados a vários tipos de dados.
Por exemplo,
tff.federated_broadcast
pode ser pensado como um operador de modelo de tipo funcionalT@SERVER -> T@CLIENTS
.Expressões lambda (
tff.federated_computation
). Uma expressão lambda em TFF é equivalente alambda
oudef
em Python; consiste no nome do parâmetro e em um corpo (expressão) que contém referências a esse parâmetro.No código Python, eles podem ser criados decorando funções Python com
tff.federated_computation
e definindo um argumento.Aqui está um exemplo de expressão lambda que já mencionamos anteriormente:
@tff.federated_computation(tff.FederatedType(np.float32, tff.CLIENTS)) def get_average_temperature(sensor_readings): return tff.federated_mean(sensor_readings)
Literais de posicionamento . Por enquanto, apenas
tff.SERVER
etff.CLIENTS
permitem definir cálculos cliente-servidor simples.Invocações de função (
__call__
). Qualquer coisa que tenha um tipo funcional pode ser invocada usando a sintaxe__call__
padrão do Python. A invocação é uma expressão cujo tipo é igual ao tipo do resultado da função que está sendo invocada.Por exemplo:
add_up_integers(x)
representa uma invocação do cálculo do TensorFlow definido anteriormente em um argumentox
. O tipo desta expressão éint32
.tff.federated_mean(sensor_readings)
representa uma invocação do operador de média federado emsensor_readings
. O tipo desta expressão éfloat32@SERVER
(assumindo o contexto do exemplo acima).
Formando tuplas e selecionando seus elementos. Expressões Python no formato
[x, y]
,x[y]
ouxy
que aparecem nos corpos das funções decoradas comtff.federated_computation
.