Dimensionar para lidar com mais usuários inscritos

Atenção

O acesso ao serviço presencial é limitado com base em critérios de elegibilidade e uso, a fim de apoiar nossos princípios de IA responsável. O serviço Face só está disponível para clientes e parceiros geridos pela Microsoft. Use o formulário de admissão de Reconhecimento Facial para solicitar acesso. Para obter mais informações, consulte a página Acesso limitado Face.

Este guia mostra como escalar de objetos PersonGroup e FaceList existentes para objetos LargePersonGroup e LargeFaceList, respectivamente. Os PersonGroups podem acomodar até 1000 pessoas no nível gratuito e 10.000 no nível pago, enquanto os LargePersonGroups podem acomodar até um milhão de pessoas no nível pago.

Importante

A estrutura de dados mais recente PersonDirectory é recomendada para novos desenvolvimentos. Pode conter até 75 milhões de identidades e não requer treinamento manual. Para obter mais informações, consulte o guia PersonDirectory.

Este guia demonstra o processo de migração. Ele pressupõe uma familiaridade básica com objetos PersonGroup e FaceList, a operação Train e as funções de reconhecimento facial. Para saber mais sobre esses assuntos, consulte o guia conceitual de reconhecimento facial.

LargePersonGroup e LargeFaceList são coletivamente referidos como operações de grande escala. LargePersonGroup pode conter até 1 milhão de pessoas, cada uma com um máximo de 248 rostos. LargeFaceList pode conter até 1 milhão de rostos. As operações em grande escala são semelhantes às convencionais PersonGroup e FaceList , mas têm algumas diferenças por causa da nova arquitetura.

Os exemplos são escritos em C# usando a biblioteca de cliente do Azure AI Face.

Nota

Para habilitar o desempenho de pesquisa de rosto para Identificação e FindSimilar em grande escala, introduza uma operação Train para pré-processar o LargeFaceList e o LargePersonGroup. O tempo de treinamento varia de segundos a cerca de meia hora com base na capacidade real. Durante o período de treinamento, é possível realizar Identificação e FindSimilar se uma operação de treinamento bem-sucedida foi feita antes. A desvantagem é que as novas pessoas e rostos adicionados não aparecem no resultado até que um novo pós-migração para treinamento em larga escala seja concluído.

Etapa 1: Inicializar o objeto cliente

Quando você usa a biblioteca do cliente Face, a chave e o ponto de extremidade da assinatura são passados pelo construtor da classe FaceClient. Consulte o início rápido para obter instruções sobre como criar um objeto de cliente Face.

Etapa 2: Migração de código

Esta seção se concentra em como migrar a implementação de PersonGroup ou FaceList para LargePersonGroup ou LargeFaceList. Embora LargePersonGroup ou LargeFaceList difira de PersonGroup ou FaceList em design e implementação interna, as interfaces de API são semelhantes para compatibilidade com versões anteriores.

A migração de dados não é suportada. Em vez disso, recrie o LargePersonGroup ou LargeFaceList .

Migrar um PersonGroup para um LargePersonGroup

A migração de um PersonGroup para um LargePersonGroup é simples. Eles compartilham exatamente as mesmas operações em nível de grupo.

Para PersonGroup ou implementação relacionada a pessoas, é necessário alterar apenas os caminhos da API ou classe/módulo SDK para LargePersonGroup e LargePersonGroup Person.

Adicione todos os rostos e pessoas do PersonGroup ao novo LargePersonGroup. Para obter mais informações, consulte Adicionar rostos.

Migrar uma FaceList para uma LargeFaceList

APIs do FaceList APIs LargeFaceList
Criar Criar
Eliminar Delete
Get Obtenção
Listagem Listagem
Atualizar Atualizar
- Treinar
- Obter Estado do Treino

A tabela anterior é uma comparação de operações de nível de lista entre FaceList e LargeFaceList. Como é mostrado, o LargeFaceList vem com novas operações, Train and Get Training Status, quando comparado com o FaceList. Treinar o LargeFaceList é uma pré-condição da operação FindSimilar . O treinamento não é necessário para o FaceList. O trecho a seguir é uma função auxiliar para aguardar o treinamento de uma LargeFaceList:

/// <summary>
/// Helper function to train LargeFaceList and wait for finish.
/// </summary>
/// <remarks>
/// The time interval can be adjusted considering the following factors:
/// - The training time which depends on the capacity of the LargeFaceList.
/// - The acceptable latency for getting the training status.
/// - The call frequency and cost.
///
/// Estimated training time for LargeFaceList in different scale:
/// -     1,000 faces cost about  1 to  2 seconds.
/// -    10,000 faces cost about  5 to 10 seconds.
/// -   100,000 faces cost about  1 to  2 minutes.
/// - 1,000,000 faces cost about 10 to 30 minutes.
/// </remarks>
/// <param name="largeFaceListId">The Id of the LargeFaceList for training.</param>
/// <param name="timeIntervalInMilliseconds">The time interval for getting training status in milliseconds.</param>
/// <returns>A task of waiting for LargeFaceList training finish.</returns>
private static async Task TrainLargeFaceList(
    string largeFaceListId,
    int timeIntervalInMilliseconds = 1000)
{
    // Trigger a train call.
    await FaceClient.LargeTrainLargeFaceListAsync(largeFaceListId);

    // Wait for training finish.
    while (true)
    {
        Task.Delay(timeIntervalInMilliseconds).Wait();
        var status = await faceClient.LargeFaceList.TrainAsync(largeFaceListId);

        if (status.Status == Status.Running)
        {
            continue;
        }
        else if (status.Status == Status.Succeeded)
        {
            break;
        }
        else
        {
            throw new Exception("The train operation is failed!");
        }
    }
}

Anteriormente, um uso típico do FaceList com rostos adicionados e FindSimilar era semelhante ao seguinte:

// Create a FaceList.
const string FaceListId = "myfacelistid_001";
const string FaceListName = "MyFaceListDisplayName";
const string ImageDir = @"/path/to/FaceList/images";
faceClient.FaceList.CreateAsync(FaceListId, FaceListName).Wait();

// Add Faces to the FaceList.
Parallel.ForEach(
    Directory.GetFiles(ImageDir, "*.jpg"),
    async imagePath =>
        {
            using (Stream stream = File.OpenRead(imagePath))
            {
                await faceClient.FaceList.AddFaceFromStreamAsync(FaceListId, stream);
            }
        });

// Perform FindSimilar.
const string QueryImagePath = @"/path/to/query/image";
var results = new List<SimilarPersistedFace[]>();
using (Stream stream = File.OpenRead(QueryImagePath))
{
    var faces = faceClient.Face.DetectWithStreamAsync(stream).Result;
    foreach (var face in faces)
    {
        results.Add(await faceClient.Face.FindSimilarAsync(face.FaceId, FaceListId, 20));
    }
}

Ao migrá-lo para LargeFaceList, torna-se o seguinte:

// Create a LargeFaceList.
const string LargeFaceListId = "mylargefacelistid_001";
const string LargeFaceListName = "MyLargeFaceListDisplayName";
const string ImageDir = @"/path/to/FaceList/images";
faceClient.LargeFaceList.CreateAsync(LargeFaceListId, LargeFaceListName).Wait();

// Add Faces to the LargeFaceList.
Parallel.ForEach(
    Directory.GetFiles(ImageDir, "*.jpg"),
    async imagePath =>
        {
            using (Stream stream = File.OpenRead(imagePath))
            {
                await faceClient.LargeFaceList.AddFaceFromStreamAsync(LargeFaceListId, stream);
            }
        });

// Train() is newly added operation for LargeFaceList.
// Must call it before FindSimilarAsync() to ensure the newly added faces searchable.
await TrainLargeFaceList(LargeFaceListId);

// Perform FindSimilar.
const string QueryImagePath = @"/path/to/query/image";
var results = new List<SimilarPersistedFace[]>();
using (Stream stream = File.OpenRead(QueryImagePath))
{
    var faces = faceClient.Face.DetectWithStreamAsync(stream).Result;
    foreach (var face in faces)
    {
        results.Add(await faceClient.Face.FindSimilarAsync(face.FaceId, largeFaceListId: LargeFaceListId));
    }
}

Como mostrado anteriormente, o gerenciamento de dados e a parte FindSimilar são quase os mesmos. A única exceção é que uma nova operação de trem de pré-processamento deve ser concluída no LargeFaceList antes que o FindSimilar funcione.

Passo 3: Sugestões de comboios

Embora a operação do trem acelere o FindSimilar e o Identification, o tempo de treinamento sofre, especialmente quando se trata de grande escala. O tempo estimado de treinamento em diferentes escalas está listado na tabela a seguir.

Escala para rostos ou pessoas Tempo estimado de treinamento
1,000 1-2 seg
10.000 5-10 seg
100.000 1-2 minutos
1.000.000 10-30 minutos

Para utilizar melhor o recurso em grande escala, recomendamos as seguintes estratégias.

Etapa 3a: Personalizar o intervalo de tempo

Como é mostrado no TrainLargeFaceList(), há um intervalo de tempo em milissegundos para atrasar o processo infinito de verificação do status do treinamento. Para LargeFaceList com mais faces, usar um intervalo maior reduz a contagem de chamadas e o custo. Personalize o intervalo de tempo de acordo com a capacidade esperada do LargeFaceList.

A mesma estratégia também se aplica ao LargePersonGroup. Por exemplo, quando você treina um LargePersonGroup com 1 milhão de pessoas, pode ser 60.000, timeIntervalInMilliseconds que é um intervalo de 1 minuto.

Etapa 3b: Buffer de pequena escala

Pessoas ou rostos em um LargePersonGroup ou um LargeFaceList são pesquisáveis somente depois de serem treinados. Em um cenário dinâmico, novas pessoas ou rostos são constantemente adicionados e devem ser imediatamente pesquisáveis, mas o treinamento pode levar mais tempo do que o desejado.

Para atenuar esse problema, use um LargePersonGroup ou LargeFaceList extra de pequena escala como um buffer apenas para as entradas recém-adicionadas. Este buffer leva menos tempo para treinar devido ao tamanho menor. A capacidade de pesquisa imediata neste buffer temporário deve funcionar. Use esse buffer em combinação com o treinamento no mestre LargePersonGroup ou LargeFaceList executando o treinamento mestre em um intervalo mais esparso. Os exemplos são no meio da noite e diariamente.

Exemplo de fluxo de trabalho:

  1. Crie um mestre LargePersonGroup ou LargeFaceList, que é a coleção master. Crie um buffer LargePersonGroup ou LargeFaceList, que é a coleção de buffer. A coleção de buffer é apenas para pessoas ou rostos recém-adicionados.
  2. Adicione novas pessoas ou rostos à coleção master e à coleção buffer.
  3. Treine apenas a coleção de buffer com um curto intervalo de tempo para garantir que as entradas recém-adicionadas entrem em vigor.
  4. Identificação de chamada ou FindSimilar na coleção mestre e na coleção de buffer. Mescle os resultados.
  5. Quando o tamanho da coleção de buffer aumentar para um limite ou em um momento ocioso do sistema, crie uma nova coleção de buffer. Acione a operação Train na coleção principal.
  6. Exclua a coleção de buffer antiga depois que a operação Train terminar na coleção mestre.

Passo 3c: Formação autónoma

Se uma latência relativamente longa for aceitável, não é necessário acionar a operação Train logo após adicionar novos dados. Em vez disso, a operação do trem pode ser separada da lógica principal e acionada regularmente. Esta estratégia é adequada para cenários dinâmicos com latência aceitável. Pode ser aplicado a cenários estáticos para reduzir ainda mais a frequência do comboio .

Suponha que haja uma TrainLargePersonGroup função semelhante a TrainLargeFaceList. Uma implementação típica do treinamento autônomo em um LargePersonGroup invocando a Timer classe em System.Timers é:

private static void Main()
{
    // Create a LargePersonGroup.
    const string LargePersonGroupId = "mylargepersongroupid_001";
    const string LargePersonGroupName = "MyLargePersonGroupDisplayName";
    faceClient.LargePersonGroup.CreateAsync(LargePersonGroupId, LargePersonGroupName).Wait();

    // Set up standalone training at regular intervals.
    const int TimeIntervalForStatus = 1000 * 60; // 1-minute interval for getting training status.
    const double TimeIntervalForTrain = 1000 * 60 * 60; // 1-hour interval for training.
    var trainTimer = new Timer(TimeIntervalForTrain);
    trainTimer.Elapsed += (sender, args) => TrainTimerOnElapsed(LargePersonGroupId, TimeIntervalForStatus);
    trainTimer.AutoReset = true;
    trainTimer.Enabled = true;

    // Other operations like creating persons, adding faces, and identification, except for Train.
    // ...
}

private static void TrainTimerOnElapsed(string largePersonGroupId, int timeIntervalInMilliseconds)
{
    TrainLargePersonGroup(largePersonGroupId, timeIntervalInMilliseconds).Wait();
}

Para obter mais informações sobre gerenciamento de dados e implementações relacionadas à identificação, consulte Adicionar rostos.

Resumo

Neste guia, você aprendeu como migrar o código PersonGroup ou FaceList existente, não dados, para LargePersonGroup ou LargeFaceList:

  • LargePersonGroup e LargeFaceList funcionam de forma semelhante a PersonGroup ou FaceList, exceto que a operação de trem é exigida por LargeFaceList.
  • Adote a estratégia Train adequada para atualização dinâmica de dados para conjuntos de dados em grande escala.

Próximos passos

Siga um guia de instruções para saber como adicionar rostos a um PersonGroup ou escrever um script para executar a operação Identificar em um PersonGroup.