Esta proposta está sujeita ao processo de inscrição e aos atestados do Sandbox de privacidade. Para mais informações sobre os atestados, consulte o link de atestado fornecido. As próximas atualizações desta proposta vão descrever os requisitos para ter acesso a esse sistema.
Os anúncios de instalação de apps para dispositivos móveis, também conhecidos como anúncios de aquisição de usuários, são um tipo de publicidade para dispositivos móveis criada para incentivar os usuários a fazer o download de um app. Normalmente, esses anúncios são veiculados aos usuários com base nos interesses e informações demográficas, e costumam aparecer em outros apps para dispositivos móveis, como jogos, mídias sociais e apps de notícias. Quando um usuário clica em um anúncio de instalação de apps, ele é direcionado diretamente à app store para fazer o download.
Por exemplo, um anunciante que está tentando gerar instalações de um novo app de entrega de comida para dispositivos móveis nos Estados Unidos pode segmentar os anúncios para usuários localizados no país e que já interagiram com outros apps de serviço de entrega de comida.
Isso geralmente é implementado com a inclusão de indicadores contextuais, próprios e de terceiros entre as adtechs para criar perfis de usuário com base nos IDs de publicidade. Os modelos de machine learning de adtech usam essas informações como entradas para escolher anúncios relevantes para o usuário e com maior probabilidade de resultar em uma conversão.
As seguintes APIs foram propostas para oferecer suporte a anúncios eficazes de instalação de apps que melhoram a privacidade do usuário, eliminando a dependência de identificadores de usuários entre partes diferentes:
- API Protected App Signals: é centrada no armazenamento e na criação de recursos de engenharia de adtech que representam os possíveis interesses de um usuário. As adtechs armazenam indicadores de eventos por app autodefinidos, como instalações de apps, primeiros acessos, ações do usuário (nível no jogo, conquistas), atividades de compra ou tempo no app. Os indicadores são gravados e armazenados no dispositivo para evitar o vazamento de dados e só são disponibilizados para a lógica da adtech que armazenou o indicador durante um leilão protegido executado em um ambiente seguro.
- API Ad Selection: fornece uma API para configurar e executar um leilão protegido em execução em um ambiente de execução confiável (TEE), em que as adtechs recuperam candidatos de anúncios, executam inferência, calculam lances e fazem classificação para escolher um anúncio "vencedor" usando os indicadores de apps protegidos e informações contextuais em tempo real fornecidas pelo editor.
Confira uma visão geral de alto nível sobre como os indicadores de apps protegidos oferecem suporte a anúncios de instalação de apps relevantes. As seções a seguir deste documento dão mais detalhes sobre cada uma dessas etapas.
- Seleção de indicadores: à medida que os usuários usam apps para dispositivos móveis, as adtechs selecionam os indicadores armazenando eventos de apps definidos pelas adtechs para veicular anúncios relevantes usando a API Protected App Signals. Esses eventos são armazenados em um armazenamento protegido no dispositivo, semelhante às audiências personalizadas, e são criptografados antes de serem enviados do dispositivo. Assim, apenas os serviços de lances e leilões executados em ambientes de execução confiáveis com o controle de segurança e privacidade adequados podem descriptografá-los para lances e pontuação de anúncios.
- Codificação de indicadores: os indicadores são preparados em uma cadência programada, por uma lógica personalizada de adtech. Um job em segundo plano do Android executa essa lógica para realizar a codificação no dispositivo e gerar um payload de indicadores de apps protegidos que pode ser usado posteriormente em tempo real para a seleção de anúncios durante um leilão protegido. O payload é armazenado com segurança no dispositivo até que seja enviado para um leilão.
- Seleção de anúncios: para selecionar anúncios relevantes para o usuário, os SDKs do vendedor
enviam um payload criptografado dos indicadores de apps protegidos e configuram um
leilão protegido. No leilão, a lógica personalizada do comprador prepara os indicadores de apps protegidos
com os dados contextuais fornecidos pelo editor (dados
normalmente compartilhados em uma solicitação de anúncio de RTB aberto) para criar
recursos destinados à seleção de anúncios (recuperação de anúncios, inferência e geração de
lances). Assim como em um público protegido, os compradores enviam anúncios ao
vendedor para pontuação final em um leilão protegido.
- Recuperação de anúncios: os compradores usam indicadores de apps protegidos e dados contextuais fornecidos pelo editor para criar recursos relevantes para os interesses do usuário. Esses recursos são usados para corresponder a anúncios que atendam aos critérios de segmentação. Os anúncios que não estão dentro do orçamento são filtrados. Em seguida, os principais anúncios são selecionados para lances.
- Lances: a lógica de lances personalizados dos compradores prepara os dados contextuais fornecidos pelo editor e os indicadores de apps protegidos para criar recursos. Eles são usados como entrada para modelos do machine learning do comprador para inferência e lances em anúncios candidatos dentro de limites confiáveis que preservam a privacidade. O comprador vai retornar o anúncio escolhido ao vendedor.
- Pontuação do vendedor: a lógica personalizada dos vendedores pontua os anúncios enviados pelos compradores participantes e escolhe um anúncio vencedor que será enviado de volta ao app para renderização.
- Relatórios: os participantes do leilão recebem os relatórios de vitórias e de perdas aplicáveis. Estamos analisando mecanismos que preservam a privacidade para incluir dados para o treinamento de modelo no relatório vencedor.
Cronograma
Prévia para desenvolvedores | Beta | |||
---|---|---|---|---|
Recurso | 4º trimestre de 2023 | 1º trimestre de 2024 | 2º trimestre de 2024 | 3º trimestre de 2024 |
APIs Signal Curation | APIs de armazenamento no dispositivo |
Lógica da cota de armazenamento no dispositivo Atualizações diárias da lógica personalizada no dispositivo |
N/A | Disponível para 1% dos dispositivos T+ |
Servidor de recuperação de anúncios em um TEE | MVP |
Disponível no GCP Suporte à produção de UDFs Top-K |
Disponível na AWS Depuração consentida, métricas e monitoramento |
|
Serviço de inferência em um TEE Suporte à execução de modelos de ML e ao uso deles para dar lances em um TEE |
Em desenvolvimento |
Disponível no GCP Capacidade de implantar e criar protótipos de modelos estáticos de ML usando o Tensorflow e o PyTorch |
Disponível na AWS Implantação de modelo em produção para modelos do Tensorflow e do PyTorch Telemetria, depuração consentida e monitoramento |
|
Suporte a lances e leilões em um TEE |
Disponível no GCP |
Integração de recuperação de anúncios PAS-B&A e TEE (com criptografia gRPC e TEE<>TEE) Suporte à recuperação de anúncios pelo caminho contextual (inclui suporte a B&A<>K/V no TEE) |
Disponível na AWS Relatórios de depuração Depuração consentida, métricas e monitoramento |
Selecionar indicadores de apps protegidos
Um indicador é uma representação das várias interações do usuário em um app. Elas são determinadas pela adtech como úteis para veicular anúncios relevantes. Um app ou o SDK integrado pode armazenar ou excluir os indicadores protegidos definidos por adtechs com base na atividade do usuário, como aberturas de app, conquistas, atividade de compra ou tempo no app. Os indicadores protegidos são armazenados com segurança no dispositivo e são criptografados antes de serem enviados do dispositivo para que apenas os serviços de lances e leilões executados em ambientes de execução confiáveis com segurança e controle de privacidade adequados possam descriptografá-los para lances e pontuação de anúncios. Assim como na API Custom Audience, os indicadores armazenados em um dispositivo não podem ser lidos ou inspecionados por apps ou SDKs. Não há API para ler valores de indicadores, e as APIs são projetadas para evitar vazamentos de presença. A lógica personalizada de adtech protege o acesso aos indicadores selecionados a fim de criar recursos que servem como base para a seleção de anúncios em um leilão protegido.
API Protected App Signals
A API Protected App Signals oferece suporte para o gerenciamento de indicadores usando um mecanismo de delegação semelhante ao usado para públicos-alvo personalizados. A API Protected App Signals permite o armazenamento de indicadores na forma de um único valor escalar ou como uma série temporal. Indicadores de série temporal podem ser usados para armazenar itens como a duração da sessão do usuário. Os indicadores de série temporal oferecem um utilitário para aplicar uma determinada duração usando uma regra de remoção por ordem de chegada. O tipo de dado de um indicador escalar ou cada um dos elementos de um indicador de série temporal é uma matriz de bytes. Cada valor é aprimorado com o nome do pacote do aplicativo que armazenou o indicador e o carimbo de data/hora de criação da chamada de API de armazenamento de indicadores. Essas informações extras estão disponíveis no JavaScript de codificação de indicadores. Este exemplo mostra a estrutura dos indicadores de uma determinada adtech:
Este exemplo demonstra um indicador escalar e um de série temporal associados
a adtech1.com
:
- Um indicador escalar com a chave de valor base64 "
A1c
" e o valor "c12Z
". O armazenamento de indicadores foi acionado porcom.google.android.game_app
em 1º de junho de 2023. - Uma lista de indicadores com a chave "
dDE
" que foram criados por dois aplicativos diferentes.
As adtechs recebem uma determinada quantidade de espaço para armazenar indicadores no dispositivo. Os indicadores terão um TTL máximo, a ser determinado.
Os indicadores de apps protegidos serão removidos do armazenamento se o aplicativo gerador for desinstalado, impedido de usar a API Protected App Signals ou se os dados do app forem apagados pelo usuário.
A API Protected App Signals é composta pelas seguintes partes:
- APIs Java e JavaScript para adicionar, atualizar ou remover indicadores.
- Uma API JavaScript para processar os indicadores persistentes e prepará-los para mais engenharia de atributos em tempo real durante um leilão protegido em execução em um ambiente de execução confiável (TEE).
Adicionar, atualizar ou remover indicadores
As adtechs podem adicionar, atualizar ou remover indicadores com a API fetchSignalUpdates()
.
Essa API oferece suporte para a delegação semelhante à delegação de público-alvo personalizado da API Protected Audience.
Para adicionar um indicador, as adtechs do comprador que não têm uma presença em relação a SDK em apps precisam
colaborar com aquelas que têm uma presença no dispositivo, como parceiros de medição
para dispositivos móveis (MMPs, na sigla em inglês) e plataformas de fornecimento (SSPs). O objetivo da API Protected App
Signals é oferecer suporte a essas adtechs, fornecendo soluções flexíveis para o
gerenciamento de indicadores de apps protegidos, permitindo que os autores de chamadas no dispositivo invoquem
a criação desses indicadores em nome dos compradores. Esse processo é chamado
de delegação e usa a API fetchSignalUpdates()
. fetchSignalUpdates()
usa um URI e recupera uma lista de atualizações de indicador. Para ilustrar,
fetchSignalUpdates()
emite uma solicitação GET para o URI fornecido para recuperar a
lista de atualizações que vão ser aplicadas ao armazenamento de indicador local. O endpoint do URL, de propriedade
do comprador, responde com uma lista JSON de comandos.
Os comandos JSON aceitos são:
- put: insere ou substitui um valor escalar para a chave especificada.
- put_if_not_present: insere um valor escalar para a chave especificada, se nenhum valor estiver armazenado. Essa opção pode ser útil, por exemplo, ao definir um ID do experimento para um determinado usuário e evitar a substituição caso ele já tenha sido definido por outro aplicativo.
- append: adiciona um elemento à série temporal associada à chave especificada. O parâmetro maxSignals especifica o número máximo de indicadores na série temporal. Se o tamanho for excedido, os elementos anteriores serão removidos. Se a chave contiver um valor escalar, ela será automaticamente transformada em uma série temporal.
- remove: remove o conteúdo associado à chave especificada.
{
"put": {
"A1c": "c12Z",
"dDE": "d23d",
},
"put_if_not_present": {
"aA9": "a1zfC3"
}
"append": {
"bB1": {"values": ["gh12D", "d45g"], "maxSignals": 20}
},
"remove": ["c0D"]
}
Todas as chaves e valores são expressos em Base64.
Os comandos listados acima visam fornecer semânticas de inserção, substituição e exclusão para indicadores escalares, além de inserção, anexação e substituição completa de séries para indicadores de séries temporais. A semântica de exclusão e substituição em elementos específicos de um indicador de série temporal precisa ser gerenciada durante o processo de codificação e compactação. Por exemplo, durante a codificação, ignore valores em uma série temporal que são substituídos ou corrigidos por erros mais recentes e os exclua durante o processo de compactação.
Os indicadores armazenados são automaticamente associados ao aplicativo que executa a solicitação de busca e ao responsável da solicitação (o "site" ou a "origem" de uma adtech registrada), além do horário de criação da solicitação. Todos os indicadores estão sujeitos ao armazenamento em nome de uma adtech registrada no Sandbox de privacidade. O "site"ou a "origem" do URI precisa corresponder aos dados de uma adtech inscrita. Se a adtech solicitante não estiver inscrita, a solicitação será rejeitada.
Cota de armazenamento e remoção
Cada adtech tem um espaço limitado no dispositivo do usuário para armazenar indicadores. Essa cota é definida por adtech. Portanto, os indicadores selecionados de diferentes apps compartilham a cota. Se a cota for excedida, o sistema vai liberar espaço removendo valores de indicadores anteriores por ordem de chegada. Para evitar que a remoção seja executada com muita frequência, o sistema implementa uma lógica de lote para permitir uma quantidade limitada de cotas excedente e liberar algum espaço extra quando a lógica de remoção for acionada.
Codificação no dispositivo para transmissão de dados
Para preparar os indicadores para a seleção de anúncios, a lógica personalizada por comprador tem acesso protegido aos indicadores e eventos armazenados por app. Um job em segundo plano do sistema Android é realizado de hora em hora para executar a lógica de codificação personalizada por comprador, que é transferida por download para o dispositivo. A lógica de codificação personalizada por comprador codifica os indicadores por app e, em seguida, compacta esses indicadores em um payload que esteja em conformidade com a cota por comprador. O payload é criptografado dentro dos limites do armazenamento do dispositivo protegido e transmitido para os serviços de lances e leilões.
As adtechs definem o nível de processamento de indicador processado pela própria lógica personalizada. Por exemplo, é possível instrumentar sua solução para descartar indicadores anteriores e agregar os semelhantes ou de reforço de aplicativos diferentes em novos indicadores que usam menos espaço.
Se um comprador não tiver registrado um codificador, os indicadores não serão preparados, e nenhum dos indicadores selecionados no dispositivo será enviado aos serviços de lances e leilões.
Mais detalhes sobre armazenamento, payload e cotas de solicitação serão disponibilizados em uma atualização futura. Além disso, vamos apresentar mais informações sobre como fornecer funções personalizadas.
Fluxo de trabalho de seleção de anúncios
Com essa proposta, o código personalizado de adtechs só pode acessar os indicadores de apps em um leilão protegido (API Ad Selection) em execução em um TEE. Para atender ainda mais às necessidades do caso de uso de instalação do app, os anúncios candidatos são buscados durante o leilão protegido em tempo real. Isso contrasta com o caso de uso de remarketing, em que os anúncios candidatos são conhecidos antes do leilão.
Esta proposta usa um fluxo de trabalho de seleção de anúncios semelhante ao da proposta da API Protected Audience com atualizações para oferecer suporte ao caso de uso de instalação de apps. Para oferecer suporte aos requisitos de computação da engenharia de atributos e da seleção de anúncios em tempo real, os leilões de anúncios de instalação de apps precisam ser executados em serviços de lances e leilões em execução em TEEs. O acesso a indicadores de apps protegidos durante um leilão protegido não tem suporte em leilões no dispositivo.
O fluxo de trabalho de seleção de anúncios é o seguinte:
- O SDK do vendedor envia o payload criptografado dos indicadores de app protegido no dispositivo.
- O servidor do vendedor cria uma configuração de leilão e a envia ao serviço de lances e leilões confiáveis do vendedor, junto com o payload criptografado, para iniciar um fluxo de trabalho de seleção de anúncios.
- O serviço de lances e leilões do vendedor transmite o payload para os servidores de front-end dos compradores confiáveis participantes.
- O serviço de lances do comprador executa a lógica de seleção de anúncios do lado do comprador
- A lógica de pontuação da venda é executada.
- O anúncio é renderizado e a geração de relatórios é iniciada.
Iniciar o fluxo de trabalho da seleção de anúncios
Quando um aplicativo está pronto para mostrar um anúncio, o SDK de adtechs (normalmente SSPs)
inicia o fluxo de trabalho de seleção de anúncios enviando todos os dados contextuais relevantes
do editor e os payloads criptografados por comprador a serem incluídos na
solicitação de envio ao leilão protegido usando a chamada getAdSelectionData
. Essa é
a mesma API usada para o fluxo de trabalho de remarketing e descrita na proposta
Integração de lances e
leilões para Android.
Para iniciar a seleção de anúncios, o vendedor transmite uma lista de compradores participantes
e o payload criptografado dos indicadores de apps protegidos no dispositivo. Com essas
informações, o servidor de anúncios do lado do vendedor prepara uma SelectAdRequest
para o
serviço SellerFrontEnd confiável.
O vendedor define o seguinte:
- O payload recebido do
getAdSelectionData
, que contém os indicadores de apps protegidos. Os indicadores de contexto que usam:
auction_config.auction_signals
(para informações sobre o leilão)auction_config.seller_signals
(para os indicadores do vendedor)auction_config.per_buyer_config["buyer"].buyer_signals
(para os indicadores dos compradores)
É a lista de compradores incluída nos leilões que usam o campo
buyer_list
.
Execução da lógica de seleção de anúncios de compra
Em um alto nível, a lógica personalizada do comprador usa dados contextuais fornecidos pelo editor e pelos indicadores de apps protegidos para selecionar e aplicar um lance aos anúncios relevantes para a solicitação de anúncio. A plataforma permite que os compradores restrinjam um grande conjunto de anúncios disponíveis aos mais relevantes (os Top-K), para os quais os lances são calculados antes dos anúncios serem retornados ao vendedor para a seleção final.
Antes de dar lances, os compradores começam com um grande conjunto de anúncios. Calcular um lance para cada anúncio é muito lento. Por isso, os compradores precisam selecionar os candidatos Top-K do grande conjunto. Em seguida, os compradores precisam calcular os lances para cada um desses candidatos Top-K. Então, esses anúncios e lances são retornados ao vendedor para a seleção final.
- O serviço BuyerFrontEnd recebe uma solicitação de anúncio.
- O serviço BuyerFrontEnd envia uma solicitação ao serviço de lances do comprador.
O serviço de lances do comprador executa uma UDF chamada
prepareDataForAdRetrieval()
, que cria uma solicitação para receber os candidatos Top-K do serviço de recuperação de anúncios. O serviço de lances envia essa solicitação para o endpoint do servidor de recuperação configurado. - O serviço de extração de anúncios executa a UDF
getCandidateAds()
, que filtra até o conjunto dos anúncios Top-K candidatos, que são enviados ao serviço de lances do comprador. - O serviço de lances do comprador executa a UDF
generateBid()
, que escolhe o melhor candidato, calcula o lance e o retorna ao serviço BuyerFrontEnd. - O serviço BuyerFrontEnd retorna os anúncios e os lances ao vendedor.
Há vários detalhes importantes sobre esse fluxo, especialmente em relação a como as peças se comunicam entre si e como a plataforma fornece recursos como a capacidade de fazer previsões de machine learning para recuperar os anúncios Top-K e calcular os lances.
Antes de analisarmos mais detalhadamente as partes, há algumas observações importantes sobre a arquitetura dos TEEs no diagrama acima.
O serviço de lances do comprador contém internamente um serviço de inferência. As adtechs podem fazer upload de modelos de machine learning para o serviço de lances do comprador. Vamos fornecer APIs JavaScript para que as adtechs façam previsões ou gerem embeddings desses modelos nas UDFs em execução no serviço de lances do comprador. Ao contrário do serviço de recuperação de anúncios, o serviço de lances do comprador não tem um serviço de chave-valor para armazenar metadados de anúncios.
O serviço de recuperação de anúncios inclui internamente um serviço de chave-valor. As adtechs podem materializar pares de chave-valor nesse serviço usando os próprios servidores, fora do limite de privacidade. Vamos fornecer uma API JavaScript para que as adtechs leiam esse serviço de chave-valor nas UDFs em execução no serviço de recuperação de anúncios. Ao contrário do serviço de lances do comprador, o serviço de recuperação de anúncios não contém um serviço de inferência.
Uma pergunta central que esse design aborda é como fazer previsões no momento da recuperação e do lance. A resposta para ambos pode envolver uma solução chamada fatoração de modelo.
Fatoração de modelos
A fatoração de modelos é uma técnica que permite dividir um único modelo em várias partes e, em seguida, combiná-las em uma previsão. No caso de uso de instalação de apps, os modelos geralmente usam três tipos de dados: dados do usuário, contextuais e de anúncios.
No caso não fatorado, um único modelo é treinado nos três tipos de dados. No caso fatorado, dividimos o modelo em várias partes. Apenas a parte que contém os dados do usuário é confidencial. Isso significa que apenas o modelo com a parte do usuário precisa ser executado dentro do limite de confiança, no serviço de inferência do serviço de lances do comprador.
Isso possibilita o seguinte design:
- Dividir o modelo em uma parte particular (os dados do usuário) e uma ou mais partes não particulares (os dados contextuais e do anúncio).
- Transmitir algumas ou todas as partes não particulares como argumentos para uma UDF
que precisa fazer previsões. Por exemplo, os embeddings contextuais são
transmitidos para UDFs no
per_buyer_signals
. - As adtechs podem criar modelos para partes não particulares e materializar os embeddings desses modelos no armazenamento de chave-valor do serviço de recuperação de anúncios. As UDFs no serviço de recuperação de anúncios podem buscar esses embeddings no ambiente de execução.
- Para fazer uma previsão durante uma UDF, combine embeddings particulares do serviço de inferência com embeddings não particulares de argumentos de função da UDF ou do armazenamento de chave-valor com uma operação como um produto escalar. Esta é a previsão final.
Com isso explicado, podemos analisar cada UDF em mais detalhes. Vamos explicar o que elas fazem, como se integram e como podem fazer as previsões necessárias para escolher os anúncios Top-K e calcular os lances.
A UDF prepareDataForAdRetrieval()
A prepareDataForAdRetrieval()
em execução no serviço de lances do comprador é
responsável por criar o payload da solicitação que será enviado ao serviço
de recuperação de anúncios para buscar os anúncios candidatos Top-K.
A prepareDataForAdRetrieval()
recebe as seguintes informações:
- O payload por comprador recebido de
getAdSelectionData
. Esse payload contém os indicadores de apps protegidos. - O
auction_signals
dos indicadores de contexto (para informações sobre o leilão) e obuyer_signals
(para campos de indicadores dos compradores).
A prepareDataForAdRetrieval()
faz duas coisas:
- Caracterização: se a inferência no tempo de recuperação for necessária, ela vai transformar os indicadores de entrada em atributos para uso durante chamadas ao serviço de inferência e receber embeddings particulares para recuperação.
- Calcula embeddings particulares para recuperação: se as previsões de recuperação forem necessárias, ela faz a chamada no serviço de inferência usando os recursos acima e recebe um embedding particular para previsões de tempo de recuperação.
A prepareDataForAdRetrieval()
retorna:
- Indicadores de apps protegidos: payload de indicadores selecionados por adtechs.
- Indicadores específicos de leilão: indicadores do vendedor específicos da plataforma e
informações contextuais, como
auction_signals
eper_buyer_signals
, (incluindo embeddings contextuais) deSelectAdRequest
. Isso é semelhante à API Protected Audience. - Indicadores adicionais: informações extras, como embeddings particulares recuperados do serviço de inferência.
Essa solicitação é enviada ao serviço de recuperação de anúncios, que faz a correspondência de candidatos
e executa a UDF getCandidateAds()
.
A UDF getCandidateAds()
A getCandidateAds()
é executada no serviço de recuperação de anúncios. Recebe a solicitação
criada por prepareDataForAdRetrieval()
no serviço de lances do comprador. O
serviço executa getCandidateAds()
, que busca os candidatos Top-K para
lances convertendo a solicitação em uma série de consultas definidas, buscas de dados
e executando lógica de negócios personalizada e outra lógica de recuperação personalizada.
A getCandidateAds()
recebe as seguintes informações:
- Indicadores de apps protegidos: payload de indicadores selecionados por adtechs.
- Indicadores específicos de leilão: indicadores do vendedor específicos da plataforma e
informações contextuais, como
auction_signals
eper_buyer_signals
, (incluindo embeddings contextuais) deSelectAdRequest
. Isso é semelhante à API Protected Audience. - Indicadores adicionais: informações extras, como embeddings particulares recuperados do serviço de inferência.
A getCandidateAds()
realiza as seguintes ações:
- Buscar um conjunto inicial de candidatos de anúncios: buscados usando critérios de segmentação, como idioma, região geográfica, tipo e tamanho do anúncio ou orçamento, para filtrar os candidatos.
- Busca de embedding de recuperação: se os embeddings do serviço de chave-valor forem necessários para fazer uma previsão do tempo de recuperação para a seleção do Top-K, eles precisarão ser recuperados do serviço de chave-valor.
- Seleção de candidato Top-K: calcule uma pontuação leve para o conjunto filtrado de candidatos de anúncios com base nos metadados buscados no armazenamento de chave-valor e nas informações enviadas do serviço de lances do comprador para escolher os candidatos Top-K com base nessa pontuação. Por exemplo, a pontuação pode ser a chance de instalar um app de acordo com o anúncio.
- Busca de embedding de lances: se os embeddings do serviço de chave-valor forem necessários para o código de lances para fazer previsões no momento do lance, eles poderão ser recuperados do serviço de chave-valor.
A pontuação de um anúncio pode ser o resultado de um modelo preditivo, que, por
exemplo, prevê a probabilidade de um usuário instalar um app. Esse tipo de geração de
pontuação envolve um tipo de fatoração do modelo: como
getCandidateAds()
é executada no serviço de recuperação de
anúncios e ela não tem um serviço de inferência, as previsões podem ser geradas
com a combinação de:
- Embeddings contextuais transmitidos usando a entrada de indicadores específicos do leilão.
- Os embeddings particulares são transmitidos usando a entrada de indicadores adicionais.
- Todas as adtechs de embedding não particulares se materializaram dos próprios servidores no serviço de chave-valor do serviço de recuperação de anúncios.
A UDF generateBid()
executada no serviço de lances do comprador também
pode aplicar o próprio tipo de fatoração de modelos para fazer previsões
de lances. Caso seja necessário algum embedding de um serviço de chave-valor para fazer isso,
ele precisa ser buscado agora.
A getCandidateAds()
retorna:
- Anúncios candidatos: os anúncios Top-K a serem transmitidos para a
generateBid()
. Cada anúncio é composto pelo seguinte:- URL de renderização: o endpoint para renderizar o criativo do anúncio.
- Metadados: metadados de anúncios para compra específicos de tecnologias de publicidade. Por exemplo, isso pode incluir informações sobre a campanha publicitária e critérios de segmentação, como local e idioma. Os metadados podem incluir embeddings opcionais usados quando a fatoração do modelo for necessária para executar a inferência durante os lances.
- Indicadores adicionais: opcionalmente, o serviço de recuperação de anúncios pode incluir
informações extras, como embeddings adicionais ou indicadores de spam a serem usados
na
generateBid()
.
Estamos investigando outros métodos para fornecer anúncios que recebem pontuação, incluindo
a disponibilização deles como parte da chamada SelectAdRequest
. Esses anúncios podem ser
recuperados com uma solicitação de lance de RTB. Nesses casos, os anúncios precisam ser
recuperados sem os indicadores de apps protegidos. As adtechs vão
avaliar as compensações antes de escolher a melhor opção, incluindo o tamanho do payload da resposta,
a latência, o custo e a disponibilidade dos indicadores.
A UDF generateBid()
Depois de recuperar o conjunto de anúncios candidatos e os embeddings durante
a recuperação, é possível prosseguir para os lances, que são executados no serviço de lances do
comprador. Esse serviço executa a UDF generateBid()
fornecida pelo comprador
para selecionar o anúncio para dar lances no Top-K e o retornar com o lance.
A generateBid()
recebe as seguintes informações:
- Anúncios candidatos: os anúncios Top-K retornados pelo serviço de recuperação de anúncios.
- Indicadores específicos de leilão: indicadores do vendedor específicos da plataforma e
informações contextuais, como
auction_signals
eper_buyer_signals
, (incluindo embeddings contextuais) deSelectAdRequest
. - Indicadores adicionais: informações extras a serem usadas no momento dos lances.
A implementação da generateBid()
do comprador faz três coisas:
- Caracterização: transforma indicadores em atributos para uso durante a inferência.
- Inferência: gera previsões usando modelos de machine learning para calcular valores como taxas de cliques e de conversão previstas.
- Lances: combinação de valores inferidos com outras entradas para calcular o lance de um anúncio candidato.
A generateBid()
retorna:
- O anúncio candidato.
- O valor do lance calculado.
A generateBid()
usada para anúncios de instalação de apps e o usado para
anúncios de remarketing são diferentes.
As seções a seguir descrevem a funcionalidades, a inferência e os lances em mais detalhes.
Caracterização
Os indicadores de leilão podem ser preparados em recursos pela generateBid()
. Esses recursos
podem ser usados durante a inferência para prever coisas como taxas de
cliques e conversão. Também estamos analisando mecanismos de preservação de privacidade para
transmitir alguns deles no relatório de ganhos para uso no treinamento de modelo.
Inferência
Ao calcular um lance, é comum realizar inferências em um ou mais modelos de machine learning. Por exemplo, cálculos de eCPM eficazes geralmente usam modelos para prever as taxas de cliques e de conversão.
Os clientes podem fornecer vários modelos de machine learning com a
implementação da generateBid()
. Também vamos fornecer uma API JavaScript na generateBid()
para que os clientes possam realizar inferência no momento da execução.
A inferência é executada no serviço de lances do comprador. Isso pode afetar a latência e o custo de inferência, especialmente porque os aceleradores ainda não estão disponíveis nos TEEs. Alguns clientes vão perceber que as necessidades deles foram atendidas com modelos individuais em execução no serviço de lances do comprador. Outros clientes, por exemplo, aqueles com modelos muito grandes, podem querer considerar opções como fatoração de modelos para minimizar o custo de inferência e a latência no momento do lance.
Mais informações sobre recursos de inferência, como formatos de modelo com suporte e tamanhos máximos, serão fornecidas em uma atualização futura.
Implementar fatoração de modelos
Anteriormente, explicamos a fatoração de modelos. No momento do lance, a abordagem específica é:
- Dividir o modelo único em uma parte particular (os dados do usuário) e uma ou mais partes não particulares (os dados contextuais e do anúncio).
- Transmitir partes não particulares para
generateBid()
. Elas podem vir deper_buyer_signals
ou de embeddings que as adtechs calculam externamente, se materializam no armazenamento de chave-valor do serviço de recuperação, buscam no momento da recuperação e retornam como parte dos indicadores. Isso não inclui embeddings particulares, porque eles não podem ser provenientes de fora do limite de privacidade. - Em
generateBid()
:- Realizar a inferência em modelos para receber embeddings particulares do usuário.
- Combinar embeddings particulares de usuários com contextuais de
per_buyer_signals
ou anúncios não particulares e embeddings contextuais do serviço de recuperação usando uma operação como um produto escalar. Essa é a previsão final que pode ser usada para calcular lances.
Com essa abordagem, é possível realizar inferências no momento do lance em modelos que seriam muito grandes ou lentos para execução no serviço de lances do comprador.
Lógica de pontuação de venda
Nessa etapa, os anúncios com lances recebidos de todos os compradores participantes são
pontuados. O resultado da generateBid()
é transmitido ao serviço de leilão do vendedor
para executar scoreAd()
e que scoreAd()
considera apenas um anúncio por vez. Com base
na pontuação, o vendedor escolhe um anúncio vencedor para retornar ao dispositivo para
renderização.
A lógica de pontuação é a mesma usada para o fluxo de remarketing da API Protected Audience, e consegue selecionar um vencedor entre os candidatos à instalação de apps e remarketing. A função é chamada uma vez para cada anúncio candidato enviado no leilão protegido. Consulte a explicação sobre Lances e leilão para mais detalhes.
Tempo de execução do código de seleção de anúncios
Na proposta, o código de seleção de anúncios para instalação de apps é especificado da mesma forma que o fluxo de remarketing da API Protected Audience. Para mais detalhes, consulte a Configuração de lances e leilões. O código de lances vai ficar disponível no mesmo local de armazenamento em nuvem que o usado para remarketing.
Relatórios
Essa proposta usa as mesmas APIs Reporting que a proposta de geração de relatórios da API
Protected Audience (por exemplo, reportImpression()
, que aciona a plataforma para
enviar relatórios de compradores e vendedores).
Um caso de uso comum para relatórios do lado do comprador é receber os dados de treinamento dos modelos usados durante a seleção de anúncios. Além das APIs atuais, a plataforma vai oferecer um mecanismo específico para a saída de dados de eventos da plataforma para servidores de adtech. Esses payloads de saída podem incluir determinados dados do usuário.
A longo prazo, estamos investigando soluções que preservam a privacidade para lidar com o treinamento de modelos com dados usados em leilões protegidos sem enviar dados do usuário no nível do evento para fora dos serviços executados em TEEs. Vamos compartilhar mais detalhes em uma atualização futura.
No curto prazo, vamos oferecer uma maneira temporária de enviar dados com ruídos de
generateBid()
. Nossa proposta inicial para isso está abaixo, e vamos melhorá-la
(incluindo possíveis mudanças incompatíveis com versões anteriores) em resposta ao feedback
do setor.
Tecnicamente, isso funciona da seguinte maneira:
- As adtechs definem um esquema para os dados que querem transmitir.
- Em
generateBid()
, eles criam o payload de saída desejado. - A plataforma valida a carga de trabalho de saída em relação ao esquema e aplica limites de tamanho.
- A plataforma adiciona ruído ao payload de saída.
- O payload de saída é incluído no relatório de vitória em formato de transmissão, recebido em servidores de adtech, decodificado e usado para treinamento de modelo.
Como definir o esquema de payloads de saída
Para que a plataforma aplique os requisitos de privacidade em evolução, os payloads de saída precisam ser estruturados de uma forma que a plataforma possa entender. As adtechs vão definir a estrutura dos payloads de saída fornecendo um arquivo JSON de esquema. Esse esquema será processado pela plataforma e mantido em sigilo pelos serviços de lances e leilão usando os mesmos mecanismos que outros recursos de adtech, como UDFs e modelos.
Vamos fornecer um arquivo CDDL que define a estrutura desse JSON. O arquivo CDDL vai incluir um conjunto de tipos de elementos aceitos (por exemplo, elementos que são booleanos, números inteiros, buckets e assim por diante). O arquivo CDDL e o esquema fornecido vão ser versionados.
Por exemplo, um payload de saída que consiste em um único atributo booleano seguido por um atributo de bucket de tamanho dois seria mais ou menos assim:
egressPayload = {
features : [
{
type: "boolean_feature",
value: false
},
{
type: "bucket_feature",
size: 2,
value: [
{
value: false
},
{
value: true
}
]
}
]
}
Os detalhes sobre o conjunto de tipos de recursos compatíveis estão disponíveis no GitHub.
Criar payloads de saída em generateBid()
Todos os indicadores de apps protegidos de um determinado comprador estão disponíveis para o
UDF generateBid()
dele. Depois que esses recursos são ativados, as adtechs criam o payload no
formato JSON. Esse payload de saída será incluído no relatório de vitória do comprador para transmissão aos servidores de adtechs.
Uma alternativa a esse design é que o cálculo do vetor de saída aconteça em
reportWin()
em vez de generateBid()
. Há vantagens e desvantagens para cada
abordagem, e vamos finalizar essa decisão em resposta ao feedback do setor.
Validar o payload de saída
A plataforma vai validar qualquer payload de saída criado pela adtech. A validação garante que os valores do recurso sejam válidos para os tipos, que as restrições de tamanho sejam atendidas e que agentes maliciosos não tentem burlar os controles de privacidade empacotando informações adicionais nos payloads de saída.
Se um payload de saída for inválido, ele será descartado silenciosamente das entradas enviadas para o relatório de vitória. Isso ocorre porque não queremos fornecer informações de depuração a usuários de má-fé que tentam burlar a validação.
Vamos fornecer uma API JavaScript para que as adtechs garantam que o payload de saída que elas
criam em generateBid()
passe na validação da plataforma:
validate(payload, schema)
Essa API JavaScript é totalmente destinada aos autores de chamadas para determinar se um payload específico
passará pela validação da plataforma. A validação real precisa ser feita na plataforma para
proteger contra UDFs generateBid()
maliciosos.
Gerar ruído no payload de saída
A plataforma vai gerar ruído nos payloads de saída antes de incluí-los no relatório de vitória. O limite inicial de ruído será de 1%, e esse valor pode evoluir com o tempo. A plataforma não vai indicar se um payload de saída específico foi ou não ruído.
O método de ruído é:
- A plataforma carrega a definição do esquema para o payload de saída.
- 1% dos payloads de saída serão escolhidos para gerar ruído.
- Se um payload de saída não for escolhido, o valor original será mantido.
- Se um payload de saída for escolhido, o valor de cada elemento será substituído por um valor válido aleatório para esse tipo de elemento (por exemplo,
0
ou1
para um elemento booleano).
Transmitir, receber e decodificar o payload de saída para o treinamento de modelos
O payload de saída validado e com ruído será incluído nos argumentos para
reportWin()
e transmitido aos servidores de adtech do comprador fora do limite de
privacidade para o treinamento do modelo. O payload de saída vai estar no formato de transmissão.
Os detalhes sobre o formato de transmissão de todos os tipos de recurso e do próprio payload de saída estão disponíveis no GitHub.
Determinar o tamanho do payload de saída
O tamanho do payload de saída em bits equilibra a utilidade e a minimização de dados. Vamos trabalhar com o setor para determinar o tamanho adequado por meio de testes. Enquanto esses experimentos estiverem em andamento, os dados serão enviados temporariamente sem limitação de tamanho de bit. Esses dados de saída adicionais sem limitação de tamanho de bits serão removidos quando os experimentos forem concluídos.
O método para determinar o tamanho é:
- Inicialmente, vamos oferecer suporte a dois payloads de saída em
generateBid()
:egressPayload
: o payload de saída com tamanho limitado que descrevemos até agora neste documento. Inicialmente, o tamanho do payload de saída será de 0 bits, o que significa que ele sempre será removido durante a validação.temporaryUnlimitedEgressPayload
: um payload de saída de tamanho ilimitado temporário para experimentos de tamanho. A formatação, criação e processamento desse payload de saída usam os mesmos mecanismos deegressPayload
.
- Cada um desses payloads de saída terá o próprio arquivo JSON de esquema:
egress_payload_schema.json
etemporary_egress_payload_schema.json
. - Fornecemos um protocolo de experimento e um conjunto de métricas para determinar a utilidade do modelo em vários tamanhos de payload de saída (por exemplo, 5, 10, ... bits).
- Com base nos resultados do experimento, determinamos o tamanho do payload de saída com as compensações corretas de utilidade e privacidade.
- Definimos o tamanho de
egressPayload
de 0 bits para o novo tamanho. - Após um período de migração definido, removemos
temporaryUnlimitedEgressPayload
, deixando apenasegressPayload
com o novo tamanho.
Estamos investigando outros limites técnicos para gerenciar essa mudança,
por exemplo, criptografando egressPayload
quando aumentamos o tamanho de 0 bits.
Esses detalhes, além do tempo do experimento e da remoção de
temporaryUnlimitedEgressPayload
, serão incluídos em uma atualização futura.
A seguir, vamos explicar um possível protocolo de experimento para finalizar o tamanho de
egressPayload
. Nosso objetivo é trabalhar com o setor para encontrar um tamanho que equilibre
a utilidade e a minimização de dados. O artefato que esses experimentos vão produzir é um
gráfico em que o eixo x é o tamanho do payload de treinamento em bits, e o
eixo y é a porcentagem de receita gerada por um modelo nesse tamanho em comparação
com uma linha de base ilimitada.
Vamos supor que estamos treinando um modelo de pInstall, e nossas fontes de dados de treinamento
são nossos registros e o conteúdo dos temporaryUnlimitedegressPayload
s que
recebemos quando ganhamos os leilões. O protocolo para adtechs envolve primeiro experimentos
off-line:
- Determinar a arquitetura dos modelos que serão usados com os sinais de app protegido. Por exemplo, eles precisam determinar se vão usar ou não a fatoração de modelos.
- Defina uma métrica para medir a qualidade do modelo. As métricas sugeridas são perda de AUC e perda de registro.
- Definir o conjunto de recursos que eles vão usar durante o treinamento do modelo.
- Usando essa arquitetura de modelo, a métrica de qualidade e o conjunto de recursos de treinamento,
execute estudos de ablação para determinar a utilidade fornecida por bit para cada
modelo que você quer usar na PAS. O protocolo sugerido para o estudo de ablação
é:
- Treine o modelo com todos os recursos e meça a utilidade. Esse é o valor de referência para comparação.
- Para cada atributo usado para produzir a referência, treine o modelo com todos os atributos exceto esse atributo.
- Meça a utilidade resultante. Divida a delta pelo tamanho do recurso em bits. Esse é o utilitário esperado por bit para esse recurso.
- Determine os tamanhos de payload de treinamento de interesse para a experimentação. Sugerimos
[5, 10, 15, ...,
size_of_all_training_features_for_baseline
] bits. Cada um deles representa um tamanho possível paraegressPayload
que o experimento vai avaliar. - Para cada tamanho possível, selecione um conjunto de recursos menor ou igual a esse tamanho que maximize a utilidade por bit, usando os resultados do estudo de ablação.
- Treine um modelo para cada tamanho possível e avalie a utilidade dele como uma porcentagem da utilidade do modelo de referência treinado em todos os recursos.
- Represente os resultados em um gráfico em que o eixo x é o tamanho do payload de treinamento em bits, e o eixo y é a porcentagem da receita gerada por esse modelo em comparação com a linha de base.
Em seguida, as adtechs podem repetir as etapas de 5 a 8 em experimentos de tráfego ativo, usando os dados de recursos enviados por temporaryUnlimitedEgressPayload
. As adtechs podem compartilhar
os resultados dos experimentos de tráfego off-line e real com o Sandbox de privacidade
para informar a decisão sobre o tamanho de egressPayload
.
O cronograma desses experimentos, bem como o cronograma para definir o tamanho
de egressPayload
para o valor resultante, está fora do escopo deste documento
e será incluído em uma atualização futura.
Medidas de proteção de dados
Vamos aplicar várias proteções aos dados de saída, incluindo:
egressPayload
etemporaryUnlimitedEgressPayload
vão ter ruídos.- Para a minimização e proteção de dados,
temporaryUnlimitedEgressPayload
vai estar disponível apenas durante os experimentos de tamanho, em que vamos determinar o tamanho correto paraegressPayload
.
Permissões
Controle do usuário
- A proposta tem o objetivo de oferecer aos usuários acesso à lista de apps instalados que armazenaram pelo menos um indicador de app protegido ou um público-alvo personalizado.
- Os usuários podem bloquear e remover apps dessa lista. O bloqueio e a remoção fazem o
seguinte:
- Limpa todos os indicadores de apps protegidos e públicos-alvo personalizados associados ao app.
- Impedem que os apps armazenem novos públicos-alvo personalizados e indicadores de app protegidos.
- Os usuários podem redefinir completamente os indicadores de apps protegidos e a API Protected Audience. Quando isso acontece, todos os indicadores de apps protegidos e públicos-alvo personalizados no dispositivo são excluídos.
- Os usuários podem desativar completamente o Sandbox de privacidade do
Android, que inclui a API Protected App Signals e a API Protected Audience. Quando esse é o caso, as APIs Protected Audience e Protected App Signals
retornam uma mensagem de exceção padrão:
SECURITY_EXCEPTION
.
Permissões e controle do app
A proposta tem como objetivo oferecer aos apps controle sobre os indicadores de apps protegidos:
- Um app pode gerenciar as próprias associações com os indicadores de apps protegidos.
- Um app pode conceder permissões a plataformas de adtech terceirizadas para gerenciar indicadores de apps protegidos em nome do app.
Controle da plataforma de adtech
Esta proposta descreve maneiras que as adtechs podem usar para controlar os indicadores de apps protegidos:
- Todas as adtechs precisam se inscrever no Sandbox de privacidade e fornecer um domínio "site" ou "origem" que corresponda a todos os URLs para indicadores de apps protegidos.
- As adtechs podem fazer parcerias com apps ou SDKs para fornecer tokens de verificação usados para conferir a criação de indicadores de apps protegidos. Quando esse processo é delegado a um parceiro, a criação de indicadores de apps protegidos pode ser configurada para exigir confirmação da adtech.