Bagikan melalui


Menskalakan untuk menangani lebih banyak pengguna terdaftar

Perhatian

Akses layanan Face dibatasi berdasarkan kelayakan dan kriteria penggunaan untuk mendukung prinsip AI kami yang Bertanggung Jawab. Layanan Face hanya tersedia untuk pelanggan dan mitra terkelola Microsoft. Gunakan formulir pengambilan Pengenalan Wajah untuk mengajukan akses. Untuk informasi selengkapnya, lihat halaman Akses terbatas Wajah.

Panduan ini menunjukkan kepada Anda cara meningkatkan skala dari objek PersonGroup dan FaceList yang ada ke objek LargePersonGroup dan LargeFaceList. PersonGroups dapat menampung hingga 1000 orang di tingkat gratis dan 10.000 di tingkat berbayar, sementara LargePersonGroups dapat menampung hingga satu juta orang di tingkat berbayar.

Penting

Struktur data yang lebih baru PersonDirectory direkomendasikan untuk pengembangan baru. Ini dapat menyimpan hingga 75 juta identitas dan tidak memerlukan pelatihan manual. Untuk informasi selengkapnya, lihat panduan PersonDirectory.

Panduan ini menunjukkan proses migrasi. Ini mengasumsikan keakraban dasar dengan objek PersonGroup dan FaceList , operasi Latih , dan fungsi pengenalan wajah. Untuk mempelajari subjek ini lebih lanjut, lihat panduan konseptual pengenal wajah.

LargePersonGroup dan LargeFaceList secara kolektif disebut sebagai operasi skala besar. LargePersonGroup dapat berisi hingga 1 juta orang, masing-masing dengan maksimum 248 wajah. LargeFaceList dapat berisi hingga 1 juta wajah. Operasi skala besar mirip dengan PersonGroup dan FaceList konvensional tetapi memiliki beberapa perbedaan karena arsitektur baru.

Sampel ditulis dalam C#.

Catatan

Untuk mengaktifkan performa pencarian Wajah untuk Identifikasi dan FindSimilar dalam skala besar, perkenalkan operasi Latih untuk memproses largeFaceList dan LargePersonGroup. Waktu pelatihan bervariasi dari detik hingga sekitar setengah jam berdasarkan kapasitas aktual. Selama periode pelatihan, Anda dapat melakukan Identifikasi dan FindSimilar jika operasi pelatihan yang berhasil dilakukan sebelumnya. Kekurangannya adalah bahwa orang dan wajah baru yang ditambahkan tidak muncul dalam hasil sampai migrasi pos baru ke pelatihan skala besar selesai.

Langkah 1: Migrasi kode

Bagian ini berfokus pada cara memigrasikan implementasi PersonGroup atau FaceList ke LargePersonGroup atau LargeFaceList. Meskipun LargePersonGroup atau LargeFaceList berbeda dari PersonGroup atau FaceList dalam desain dan implementasi internal, antarmuka API mirip untuk kompatibilitas mundur.

Migrasi data tidak didukung. Anda membuat ulang LargePersonGroup atau LargeFaceList sebagai gantinya.

Memigrasikan PersonGroup ke LargePersonGroup

Migrasi dari PersonGroup ke LargePersonGroup sederhana. PersonGroup dan LargePersonGroup berbagi operasi tingkat grup yang persis sama.

Untuk PersonGroup atau implementasi terkait orang, perlu untuk mengubah hanya jalur API atau kelas/modul SDK menjadi LargePersonGroup dan LargePersonGroup Person.

Tambahkan semua wajah dan orang dari PersonGroup ke LargePersonGroup baru. Untuk informasi selengkapnya, lihat Menambahkan wajah.

Memigrasikan FaceList ke LargeFaceList

API FaceList API LargeFaceList
Buat Buat
Hapus Hapus
Dapatkan Dapatkan
List List
Pembaruan Pembaruan
- Berlatih
- Dapatkan Status Pelatihan

Tabel sebelumnya adalah perbandingan operasi tingkat daftar antara FaceList dan LargeFaceList. Seperti yang ditunjukkan, LargeFaceList hadir dengan operasi baru, Melatih dan Mendapatkan Status Pelatihan, jika dibandingkan dengan FaceList. Melatih LargeFaceList adalah prasyarat operasi FindSimilar. Pelatihan tidak diperlukan untuk FaceList. Cuplikan berikut adalah fungsi pembantu untuk menunggu pelatihan 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)
{
    HttpClient httpClient = new HttpClient();
    httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", SUBSCRIPTION_KEY);

    // Trigger a train call.
    await httpClient.PostAsync($"{ENDPOINT}/face/v1.0/largefacelists/{largeFaceListId}/train", null);

    // Wait for training finish.
    while (true)
    {
        await Task.Delay(timeIntervalInMilliseconds);
        string? trainingStatus = null;
        using (var response = await httpClient.GetAsync($"{ENDPOINT}/face/v1.0/largefacelists/{largeFaceListId}/training"))
        {
            string contentString = await response.Content.ReadAsStringAsync();
            trainingStatus = (string?)(JsonConvert.DeserializeObject<Dictionary<string, object>>(contentString)?["status"]);
        }

        if ("running".Equals(trainingStatus))
        {
            continue;
        }
        else if ("succeeded".Equals(trainingStatus))
        {
            break;
        }
        else
        {
            throw new Exception("The train operation is failed!");
        }
    }
}

Sebelumnya, penggunaan umum FaceList dengan wajah yang ditambahkan dan FindSimilar terlihat seperti berikut ini:

// Create a FaceList.
const string FaceListId = "myfacelistid_001";
const string FaceListName = "MyFaceListDisplayName";
const string ImageDir = @"/path/to/FaceList/images";
using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new Dictionary<string, object> { ["name"] = FaceListName, ["recognitionModel"] = "recognition_04" }))))
{
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    await httpClient.PutAsync($"{ENDPOINT}/face/v1.0/facelists/{FaceListId}", content);
}

// Add Faces to the FaceList.
Parallel.ForEach(
    Directory.GetFiles(ImageDir, "*.jpg"),
    async imagePath =>
    {
        using (Stream stream = File.OpenRead(imagePath))
        {
            using (var content = new StreamContent(stream))
            {
                content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                await httpClient.PostAsync($"{ENDPOINT}/face/v1.0/facelists/{FaceListId}/persistedfaces?detectionModel=detection_03", content);
            }
        }
    });

// Perform FindSimilar.
const string QueryImagePath = @"/path/to/query/image";
var results = new List<HttpResponseMessage>();
using (Stream stream = File.OpenRead(QueryImagePath))
{
    var response = await faceClient.DetectAsync(BinaryData.FromStream(stream), FaceDetectionModel.Detection03, FaceRecognitionModel.Recognition04, returnFaceId: true);
    var faces = response.Value;
    foreach (var face in faces)
    {
        using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new Dictionary<string, object> { ["faceId"] = face.FaceId, ["faceListId"] = FaceListId }))))
        {
            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            results.Add(await httpClient.PostAsync($"{ENDPOINT}/face/v1.0/findsimilars", content));
        }
    }
}

Saat memigrasikannya ke LargeFaceList, itu menjadi hal berikut:

// Create a LargeFaceList.
const string LargeFaceListId = "mylargefacelistid_001";
const string LargeFaceListName = "MyLargeFaceListDisplayName";
const string ImageDir = @"/path/to/FaceList/images";
using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new Dictionary<string, object> { ["name"] = LargeFaceListName, ["recognitionModel"] = "recognition_04" }))))
{
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    await httpClient.PutAsync($"{ENDPOINT}/face/v1.0/largefacelists/{LargeFaceListId}", content);
}

// Add Faces to the LargeFaceList.
Parallel.ForEach(
    Directory.GetFiles(ImageDir, "*.jpg"),
    async imagePath =>
    {
        using (Stream stream = File.OpenRead(imagePath))
        {
            using (var content = new StreamContent(stream))
            {
                content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                await httpClient.PostAsync($"{ENDPOINT}/face/v1.0/largefacelists/{LargeFaceListId}/persistedfaces?detectionModel=detection_03", content);
            }
        }
    });

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

// Perform FindSimilar.
const string QueryImagePath = @"/path/to/query/image";
var results = new List<HttpResponseMessage>();
using (Stream stream = File.OpenRead(QueryImagePath))
{
    var response = await faceClient.DetectAsync(BinaryData.FromStream(stream), FaceDetectionModel.Detection03, FaceRecognitionModel.Recognition04, returnFaceId: true);
    var faces = response.Value;
    foreach (var face in faces)
    {
        using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new Dictionary<string, object> { ["faceId"] = face.FaceId, ["largeFaceListId"] = LargeFaceListId }))))
        {
            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            results.Add(await httpClient.PostAsync($"{ENDPOINT}/face/v1.0/findsimilars", content));
        }
    }
}

Seperti yang ditunjukkan sebelumnya, manajemen data dan bagian FindSimilar hampir sama. Satu-satunya pengecualian adalah bahwa operasi Latih prapemrosesan baru harus diselesaikan di LargeFaceList sebelum FindSimilar berfungsi.

Langkah 2: Melatih saran

Meskipun operasi Latih mempercepat FindSimilar dan Identifikasi, waktu pelatihan menderita, terutama ketika datang ke skala besar. Perkiraan waktu pelatihan dalam skala yang berbeda tercantum dalam tabel berikut.

Skala untuk wajah atau orang Estimasi waktu pelatihan
1,000 1-2 detik
10,000 5-10 detik
100.000 1-2 menit
1\.000.000 10-30 menit

Untuk memanfaatkan fitur skala besar dengan lebih baik, kami sarankan strategi berikut.

Langkah 2a: Menyesuaikan interval waktu

Seperti yang ditunjukkan di TrainLargeFaceList(), ada interval waktu dalam milidetik untuk menunda proses pemeriksaan status pelatihan tanpa batas. Untuk LargeFaceList dengan lebih banyak wajah, menggunakan interval yang lebih besar mengurangi jumlah panggilan dan biaya. Sesuaikan interval waktu sesuai dengan kapasitas yang diharapkan dari LargeFaceList.

Strategi yang sama juga berlaku untuk LargePersonGroup. Misalnya, ketika Anda melatih LargePersonGroup dengan 1 juta orang, timeIntervalInMilliseconds mungkin 60.000, yang merupakan interval 1 menit.

Langkah 2b: Buffer skala kecil

Orang atau wajah dalam LargePersonGroup atau LargeFaceList hanya dapat dicari setelah dilatih. Dalam skenario dinamis, orang atau wajah baru terus ditambahkan dan harus segera dicari, namun pelatihan mungkin memakan waktu lebih lama dari yang diinginkan.

Untuk mengurangi masalah ini, gunakan LargePersonGroup atau LargeFaceList skala kecil ekstra sebagai buffer hanya untuk entri yang baru ditambahkan. Buffer ini membutuhkan waktu yang lebih singkat untuk melatih karena ukurannya yang lebih kecil. Kemampuan pencarian langsung pada buffer sementara ini akan berfungsi. Gunakan buffer ini dalam kombinasi dengan pelatihan pada master LargePersonGroup atau LargeFaceList dengan menjalankan pelatihan master pada interval sparser. Contohnya adalah di tengah malam dan setiap hari.

Contoh alur kerja:

  1. Buat master LargePersonGroup atau LargeFaceList, yang merupakan koleksi master. Buat buffer LargePersonGroup atau LargeFaceList, yang merupakan koleksi buffer. Koleksi buffer hanya untuk orang atau wajah yang baru ditambahkan.
  2. Tambahkan orang atau wajah baru ke koleksi master dan koleksi buffer.
  3. Latih koleksi buffer hanya dengan interval waktu yang singkat untuk memastikan bahwa entri yang baru ditambahkan berlaku.
  4. Identifikasi Panggilan atau FindSimilar terhadap koleksi master dan koleksi buffer. Gabungkan hasilnya.
  5. Saat ukuran koleksi buffer meningkat ke ambang batas atau pada waktu sistem tidak aktif, buat koleksi buffer baru. Picu operasi Latih pada koleksi master.
  6. Hapus koleksi buffer lama setelah operasi Latih selesai pada koleksi master.

Langkah 2c: Pelatihan mandiri

Jika latensi yang relatif panjang dapat diterima, tidak perlu memicu operasi Latih tepat setelah Anda menambahkan data baru. Sebagai gantinya , operasi Latih dapat dibagi dari logika utama dan dipicu secara teratur. Strategi ini cocok untuk skenario dinamis dengan latensi yang dapat diterima. Ini dapat diterapkan ke skenario statis untuk mengurangi frekuensi Kereta lebih lanjut.

Misalkan ada fungsi TrainLargePersonGroup yang mirip dengan TrainLargeFaceList. Implementasi khas pelatihan mandiri pada LargePersonGroup dengan memanggil Timer kelas adalah System.Timers :

private static void Main()
{
    // 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("mylargepersongroupid_001", 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();
}

Untuk informasi selengkapnya tentang manajemen data dan penerapan terkait identifikasi, lihat Menambahkan wajah.

Ringkasan

Dalam panduan ini, Anda mempelajari cara memigrasikan kode PersonGroup atau FaceList yang ada, bukan data, ke LargePersonGroup atau LargeFaceList:

  • LargePersonGroup dan LargeFaceList berfungsi mirip dengan PersonGroup atau FaceList, kecuali bahwa operasi Latih diperlukan oleh LargeFaceList.
  • Ambil strategi Latih yang tepat untuk pembaruan data dinamis untuk himpunan data skala besar.

Langkah berikutnya

Ikuti panduan cara untuk mempelajari cara menambahkan wajah ke PersonGroup atau menulis skrip untuk melakukan operasi Identifikasi pada PersonGroup.