Mengonfigurasi kuantisasi vektor dan mengurangi penyimpanan untuk vektor yang lebih kecil di Azure AI Search

Penting

Fitur-fitur ini berada dalam pratinjau publik di bawah Ketentuan Penggunaan Tambahan. REST API Pratinjau 2024-03-01 menyediakan jenis data baru, properti kompresi vektor, dan stored properti .

Artikel ini menjelaskan kuantisasi vektor dan teknik lain untuk mengompresi indeks vektor di Azure AI Search.

Mengevaluasi opsi

Sebagai langkah pertama, tinjau tiga opsi untuk mengurangi jumlah penyimpanan yang digunakan oleh bidang vektor. Opsi ini tidak saling eksklusif.

Kami merekomendasikan kuantisasi skalar karena mengompresi ukuran vektor dalam memori dan pada disk dengan upaya minimal, dan yang cenderung memberikan manfaat paling besar dalam sebagian besar skenario. Sebaliknya, jenis sempit (kecuali untuk ) memerlukan upaya khusus untuk Float16membuatnya, dan stored menghemat penyimpanan disk, yang tidak semahal memori.

Pendekatan Mengapa menggunakan opsi ini
Menetapkan jenis data primitif yang lebih kecil ke bidang vektor Jenis data sempit, seperti Float16, , Int16dan Int8, menghabiskan lebih sedikit ruang dalam memori dan pada disk, tetapi Anda harus memiliki model penyematan yang menghasilkan vektor dalam format data sempit. Atau, Anda harus memiliki logika kuantisasi kustom yang menghasilkan data kecil. Kasus penggunaan ketiga yang membutuhkan lebih sedikit upaya adalah memprakirakan ulang penyematan asli Float32 yang dihasilkan oleh sebagian besar model ke Float16.
Menghilangkan penyimpanan opsional vektor yang dapat diambil Vektor yang dikembalikan dalam respons kueri disimpan secara terpisah dari vektor yang digunakan selama eksekusi kueri. Jika Anda tidak perlu mengembalikan vektor, Anda dapat menonaktifkan penyimpanan yang dapat diambil, mengurangi penyimpanan disk per bidang secara keseluruhan hingga 50 persen.
Menambahkan kuantisasi skalar Gunakan kuantisasi skalar bawaan untuk mengompres penyematan asli Float32 ke Int8. Opsi ini mengurangi penyimpanan dalam memori dan pada disk tanpa penurunan performa kueri. Jenis data yang lebih kecil seperti Int8 menghasilkan indeks vektor yang kurang kaya konten daripada yang Float32 memiliki penyematan. Untuk mengimbangi kehilangan informasi, kompresi bawaan mencakup opsi untuk pemrosesan pasca-kueri menggunakan penyematan yang tidak dikompresi dan pengambilan sampel berlebih untuk mengembalikan hasil yang lebih relevan. Reranking dan oversampling adalah fitur khusus dari kuantisasi skalar bawaan Float32 atau Float16 bidang dan tidak dapat digunakan pada penyematan yang mengalami kuantisasi kustom.

Semua opsi ini didefinisikan pada indeks kosong. Untuk mengimplementasikan salah satunya, gunakan REST API pratinjau portal Azure, 2024-03-01, atau paket Azure SDK beta.

Setelah indeks ditentukan, Anda dapat memuat dan mengindeks dokumen sebagai langkah terpisah.

Opsi 1: Tetapkan jenis data sempit ke bidang vektor

Bidang vektor menyimpan penyematan vektor, yang dinyatakan sebagai array angka. Saat Anda menentukan jenis bidang, Anda menentukan jenis data primitif dasar yang digunakan untuk menahan setiap angka dalam array ini. Jenis data memengaruhi berapa banyak ruang yang dibutuhkan setiap angka.

Dengan menggunakan API pratinjau, Anda dapat menetapkan jenis data primitif sempit untuk mengurangi persyaratan penyimpanan bidang vektor.

  1. Tinjau jenis data untuk bidang vektor:

    • Collection(Edm.Single) Titik mengambang 32-bit (default)
    • Collection(Edm.Half) Titik mengambang 16-bit
    • Collection(Edm.Int16) Bilangan bulat bertanda tangan 16-bit
    • Collection(Edm.SByte) Bilangan bulat bertanda tangan 8-bit

    Catatan

    Jenis data biner saat ini tidak didukung.

  2. Pilih jenis data yang valid untuk output model penyematan Anda, atau untuk vektor yang menjalani kuantisasi kustom.

    Sebagian besar model penyematan menghasilkan angka titik mengambang 32-bit, tetapi jika Anda menerapkan kuantisasi kustom, output Anda mungkin Int16 atau Int8. Sekarang Anda dapat menentukan bidang vektor yang menerima format yang lebih kecil.

    Model penyematan teks memiliki format output asli dari Float32, yang dipetakan ke Collection(Edm.Single) dalam Azure AI Search. Anda tidak dapat memetakan output tersebut ke Int8 karena transmisi dari float ke int dilarang. Namun, Anda dapat melemparkan dari Float32 ke Float16 (atau Collection(Edm.Half)), dan ini adalah cara mudah untuk menggunakan jenis data sempit tanpa pekerjaan tambahan.

    Tabel berikut ini menyediakan tautan ke beberapa model penyematan yang menggunakan jenis data sempit.

    Model penyematan Output asli Jenis yang valid di Azure AI Search
    text-embedding-ada-002 Float32 Collection(Edm.Single) atau Collection(Edm.Half)
    text-embedding-3-small Float32 Collection(Edm.Single) atau Collection(Edm.Half)
    text-embedding-3-large Float32 Collection(Edm.Single) atau Collection(Edm.Half)
    Model penyematan Cohere V3 dengan int8 embedding_type Int8 Collection(Edm.SByte)
  3. Pastikan Anda memahami tradeoff dari jenis data yang sempit. Collection(Edm.Half) memiliki lebih sedikit informasi, yang menghasilkan resolusi yang lebih rendah. Jika data Anda homogen atau padat, kehilangan detail atau nuansa tambahan dapat menyebabkan hasil yang tidak dapat diterima pada waktu kueri karena ada lebih sedikit detail yang dapat digunakan untuk membedakan vektor terdekat terpisah.

  4. Tentukan dan buat indeks. Anda dapat menggunakan portal Azure, 2024-03-01-preview, atau paket Azure SDK beta untuk langkah ini.

  5. Periksa hasilnya. Dengan asumsi bidang vektor ditandai sebagai dapat diambil, gunakan Search explorer atau REST API untuk memverifikasi konten bidang yang cocok dengan jenis data. Pastikan untuk menggunakan versi API yang benar 2024-03-01-preview untuk kueri, jika tidak, properti baru tidak ditampilkan.

Untuk memeriksa ukuran indeks vektor, gunakan portal Azure atau pratinjau 2024-03-01.

Catatan

Jenis data bidang digunakan untuk membuat struktur data fisik. Jika Anda ingin mengubah jenis data nanti, hilangkan dan bangun ulang indeks, atau buat bidang kedua dengan definisi baru.

Opsi 2: Atur stored properti untuk menghapus penyimpanan yang dapat diambil

Properti stored adalah boolean baru pada definisi bidang vektor yang menentukan apakah penyimpanan dialokasikan untuk konten bidang vektor yang dapat diambil. Jika Anda tidak memerlukan konten vektor dalam respons kueri, Anda bisa menyimpan penyimpanan hingga 50 persen per bidang dengan mengatur stored ke false.

Karena vektor tidak dapat dibaca manusia, vektor biasanya dihilangkan dalam respons kueri yang dirender di halaman pencarian. Namun, jika Anda menggunakan vektor dalam pemrosesan hilir, seperti meneruskan hasil kueri ke model atau proses yang menggunakan konten vektor, Anda harus tetap stored diatur ke true dan memilih teknik yang berbeda untuk meminimalkan ukuran vektor.

Contoh berikut menunjukkan kumpulan bidang indeks pencarian. Atur stored ke false untuk menghapus penyimpanan yang dapat diambil secara permanen untuk bidang vektor.

PUT https://[service-name].search.windows.net/indexes/[index-name]?api-version=2024-03-01-preview  
   Content-Type: application/json  
   api-key: [admin key]  
 
     { 
       "name": "myindex", 
       "fields": [ 
         { 
           "name": "myvector", 
           "type": "Collection(Edm.Single)", 
           "retrievable": false, 
           "stored": false, 
           "dimensions": 1536, 
           "vectorSearchProfile": "vectorProfile" 
         } 
       ] 
     } 

Poin utama:

  • Hanya berlaku untuk bidang vektor.

  • Mempengaruhi penyimpanan pada disk, bukan memori, dan tidak berpengaruh pada kueri. Eksekusi kueri menggunakan indeks vektor terpisah yang tidak terpengaruh oleh stored properti .

  • Properti stored diatur selama pembuatan indeks pada bidang vektor dan tidak dapat diubah. Jika Anda ingin mengambil konten nanti, Anda harus menghilangkan dan membangun kembali indeks, atau membuat dan memuat bidang baru yang memiliki atribusi baru.

  • Default diatur stored ke true dan retrievable diatur ke false. Dalam konfigurasi default, salinan yang dapat diambil disimpan, tetapi tidak dikembalikan secara otomatis dalam hasil. Ketika stored benar, Anda dapat beralih retrievable antara true dan false kapan saja tanpa harus membangun ulang indeks. Ketika stored salah, retrievable harus false dan tidak dapat diubah.

Opsi 3: Mengonfigurasi kuantisasi skalar

Kuantisasi skalar bawaan direkomendasikan karena mengurangi persyaratan penyimpanan memori dan disk, dan menambahkan reranking dan oversampling untuk mengimbangi efek indeks yang lebih kecil. Kuantisasi skalar bawaan dapat diterapkan ke bidang vektor yang berisi Float32 atau Float16 data.

Untuk menggunakan kompresi vektor bawaan:

  • Tambahkan vectorSearch.compressions ke indeks pencarian. Algoritma kompresi yang didukung dalam pratinjau ini adalah kuantisasi skalar.
  • Atur properti opsional untuk mengurangi efek pengindeksan lossy. Baik rerankWithOriginalVectors dan defaultOversampling berikan pengoptimalan selama eksekusi kueri.
  • Tambahkan vectorSearch.profiles.compression ke profil vektor baru.
  • Tetapkan profil vektor baru ke bidang vektor baru.

Menambahkan pengaturan pemadatan dan mengatur properti opsional

Dalam definisi indeks yang dibuat menggunakan REST API pratinjau 2024-03-01, tambahkan compressions bagian . Gunakan JSON berikut sebagai templat.

"compressions": [

      {  
        "name": "my-scalar-quantization",  
        "kind": "scalarQuantization",  
        "rerankWithOriginalVectors": true,  (optional)
        "defaultOversampling": 10.0,  (optional)
        "scalarQuantizationParameters": {  (optional)
             "quantizedDataType": "int8",  (optional)
        }
      }  
   ]

Poin utama:

  • kind harus diatur ke scalarQuantization. Ini adalah satu-satunya metode kuantisasi yang didukung saat ini.

  • rerankWithOriginalVectors menggunakan vektor asli yang tidak dikompresi untuk menghitung ulang kesamaan dan mererank hasil teratas yang dikembalikan oleh kueri pencarian awal. Vektor yang tidak dikompresi ada di indeks pencarian meskipun stored salah. Properti ini bersifat opsional. Default-nya adalah true.

  • defaultOversampling mempertimbangkan serangkaian hasil potensial yang lebih luas untuk mengimbangi pengurangan informasi dari kuantisasi. Rumus untuk hasil potensial terdiri dari k dalam kueri, dengan pengali sampel berlebih. Misalnya, jika kueri menentukan k 5, dan oversampling adalah 20, maka kueri secara efektif meminta 100 dokumen untuk digunakan dalam reranking, menggunakan vektor asli yang tidak dikompresi untuk tujuan tersebut. Hanya hasil reranked teratas k yang dikembalikan. Properti ini bersifat opsional. Defaultnya adalah 4.

  • quantizedDataType harus diatur ke int8. Ini adalah satu-satunya jenis data primitif yang didukung saat ini. Properti ini bersifat opsional. Defaultnya adalah int8.

Menambahkan pengaturan kompresi ke profil vektor

Kuantisasi skalar ditentukan sebagai properti di profil vektor baru . Pembuatan profil vektor baru diperlukan untuk membangun indeks terkompresi dalam memori.

Dalam profil, Anda harus menggunakan algoritma Hierarkis Navigable Small Worlds (HNSW). Kuantisasi bawaan tidak didukung dengan KNN lengkap.

  1. Buat profil vektor baru dan tambahkan properti kompresi.

    "profiles": [
       {
          "name": "my-vector-profile",
          "compression": "my-scalar-quantization", 
          "algorithm": "my-hnsw-vector-config-1",
          "vectorizer": null
       }
     ]
    
  2. Tetapkan profil vektor ke bidang vektor baru . Kuantisasi skalar mengurangi konten menjadi Int8, jadi pastikan konten Anda adalah Float32 atau Float16.

    Dalam Pencarian Azure AI, Model Data Entitas (EDM) yang setara dengan jenis Float32 dan Float16 adalah Collection(Edm.Single) dan Collection(Edm.Half), masing-masing.

    {
       "name": "DescriptionVector",
       "type": "Collection(Edm.Single)",
       "searchable": true,
       "retrievable": true,
       "dimensions": 1536,
       "vectorSearchProfile": "my-vector-profile"
    }
    
  3. Muat indeks menggunakan pengindeks untuk pengindeksan model penarikan, atau API untuk pengindeksan model pendorongan.

Kuantisasi skalar mengurangi resolusi setiap angka dalam setiap penyematan vektor. Alih-alih menjelaskan setiap angka sebagai angka titik mengambang 32-bit, angka tersebut menggunakan bilangan bulat 8-bit. Ini mengidentifikasi rentang angka (biasanya minimum persentil ke-99 dan maksimum) dan membaginya menjadi jumlah tingkat atau bin terbatas, menetapkan setiap bin pengidentifikasi. Dalam kuantisasi skalar 8-bit, ada 2^8, atau 256, kemungkinan bin.

Setiap komponen vektor dipetakan ke nilai perwakilan terdekat dalam set tingkat kuantisasi ini dalam proses yang mirip dengan pembulatan angka riil ke bilangan bulat terdekat. Dalam vektor 8-bit yang dikuantisasi, nomor pengidentifikasi berdiri sebagai pengganti nilai asli. Setelah kuantisasi, setiap vektor diwakili oleh array pengidentifikasi untuk bin tempat komponennya berada. Vektor kuantisasi ini membutuhkan lebih sedikit bit untuk disimpan dibandingkan dengan vektor asli, sehingga mengurangi persyaratan penyimpanan dan jejak memori.

Contoh indeks dengan vectorCompression, jenis data, dan properti tersimpan

Berikut adalah contoh komposit indeks pencarian yang menentukan jenis data sempit, penyimpanan yang dikurangi, dan pemadatan vektor.

  • "HotelNameVector" menyediakan contoh jenis data sempit, memprakirakan ulang nilai asli Float32 ke Float16, yang dinyatakan seperti Collection(Edm.Half) dalam indeks pencarian.
  • "HotelNameVector" juga telah stored diatur ke false. Penyematan tambahan yang digunakan dalam respons kueri tidak disimpan. Ketika stored salah, retrievable juga harus salah.
  • "DescriptionVector" menyediakan contoh kompresi vektor. Kompresi vektor didefinisikan dalam indeks, direferensikan dalam profil, lalu ditetapkan ke bidang vektor. "DescriptionVector" juga telah stored diatur ke false.
### Create a new index
POST {{baseUrl}}/indexes?api-version=2024-03-01-preview  HTTP/1.1
    Content-Type: application/json
    api-key: {{apiKey}}

{
    "name": "hotels-vector-quickstart",
    "fields": [
        {
            "name": "HotelId", 
            "type": "Edm.String",
            "searchable": false, 
            "filterable": true, 
            "retrievable": true, 
            "sortable": false, 
            "facetable": false,
            "key": true
        },
        {
            "name": "HotelName", 
            "type": "Edm.String",
            "searchable": true, 
            "filterable": false, 
            "retrievable": true, 
            "sortable": true, 
            "facetable": false
        },
        {
            "name": "HotelNameVector",
            "type": "Collection(Edm.Half)",
            "searchable": true,
            "retrievable": false,
            "dimensions": 1536,
            "stored": false,
            "vectorSearchProfile": "my-vector-profile-no-compression"
        },
        {
            "name": "Description", 
            "type": "Edm.String",
            "searchable": true, 
            "filterable": false, 
            "retrievable": false, 
            "sortable": false, 
            "facetable": false
        },
        {
            "name": "DescriptionVector",
            "type": "Collection(Edm.Single)",
            "searchable": true,
            "retrievable": false,
            "dimensions": 1536,
            "stored": false,
            "vectorSearchProfile": "my-vector-profile-with-compression"
        },
        {
            "name": "Category", 
            "type": "Edm.String",
            "searchable": true, 
            "filterable": true, 
            "retrievable": true, 
            "sortable": true, 
            "facetable": true
        },
        {
            "name": "Tags",
            "type": "Collection(Edm.String)",
            "searchable": true,
            "filterable": true,
            "retrievable": true,
            "sortable": false,
            "facetable": true
        },
        {
            "name": "Address", 
            "type": "Edm.ComplexType",
            "fields": [
                {
                    "name": "City", "type": "Edm.String",
                    "searchable": true, "filterable": true, "retrievable": true, "sortable": true, "facetable": true
                },
                {
                    "name": "StateProvince", "type": "Edm.String",
                    "searchable": true, "filterable": true, "retrievable": true, "sortable": true, "facetable": true
                }
            ]
        },
        {
            "name": "Location",
            "type": "Edm.GeographyPoint",
            "searchable": false, 
            "filterable": true, 
            "retrievable": true, 
            "sortable": true, 
            "facetable": false
        }
    ],
"vectorSearch": {
    "compressions": [
        {
            "name": "my-scalar-quantization",
            "kind": "scalarQuantization",
            "rerankWithOriginalVectors": true,
            "defaultOversampling": 10.0,
                "scalarQuantizationParameters": {
                    "quantizedDataType": "int8"
                }
        }
    ],
    "algorithms": [
        {
            "name": "my-hnsw-vector-config-1",
            "kind": "hnsw",
            "hnswParameters": 
            {
                "m": 4,
                "efConstruction": 400,
                "efSearch": 500,
                "metric": "cosine"
            }
        },
        {
            "name": "my-hnsw-vector-config-2",
            "kind": "hnsw",
            "hnswParameters": 
            {
                "m": 4,
                "metric": "euclidean"
            }
        },
        {
            "name": "my-eknn-vector-config",
            "kind": "exhaustiveKnn",
            "exhaustiveKnnParameters": 
            {
                "metric": "cosine"
            }
        }
    ],
    "profiles": [      
        {
            "name": "my-vector-profile-with-compression",
            "compression": "my-scalar-quantization",
            "algorithm": "my-hnsw-vector-config-1",
            "vectorizer": null
        },
        {
            "name": "my-vector-profile-no-compression",
            "compression": null,
            "algorithm": "my-eknn-vector-config",
            "vectorizer": null
        }
    ]
},
    "semantic": {
        "configurations": [
            {
                "name": "my-semantic-config",
                "prioritizedFields": {
                    "titleField": {
                        "fieldName": "HotelName"
                    },
                    "prioritizedContentFields": [
                        { "fieldName": "Description" }
                    ],
                    "prioritizedKeywordsFields": [
                        { "fieldName": "Tags" }
                    ]
                }
            }
        ]
    }
}

Mengkueri bidang vektor terkuantisasi menggunakan pengambilan sampel berlebih

Sintaks kueri dalam contoh ini berlaku untuk bidang vektor menggunakan kuantisasi skalar bawaan. Secara default, bidang vektor yang menggunakan kuantisasi skalar juga menggunakan rerankWithOriginalVectors dan defaultOversampling untuk mengurangi efek indeks vektor yang lebih kecil. Pengaturan tersebut ditentukan dalam indeks pencarian.

Pada kueri, Anda bisa mengambil alih nilai default oversampling. Misalnya, jika defaultOversampling adalah 10.0, Anda dapat mengubahnya menjadi sesuatu yang lain dalam permintaan kueri.

Anda dapat mengatur parameter oversampling meskipun indeks tidak secara eksplisit memiliki rerankWithOriginalVectors definisi atau defaultOversampling . oversampling Menyediakan pada waktu kueri mengambil alih pengaturan indeks untuk kueri tersebut dan menjalankan kueri dengan efektif rerankWithOriginalVectors sebagai true.

POST https://[service-name].search.windows.net/indexes/[index-name]/docs/search?api-version=2024-03-01-Preview   
  Content-Type: application/json   
  api-key: [admin key]   

    {    
       "vectorQueries": [
            {    
                "kind": "vector",    
                "vector": [8, 2, 3, 4, 3, 5, 2, 1],    
                "fields": "myvector",
                "oversampling": 12.0,
                "k": 5   
            }
      ]    
    }

Poin utama:

  • Berlaku untuk bidang vektor yang mengalami kompresi vektor, sesuai penetapan profil vektor.

  • Mengambil alih defaultOversampling nilai atau memperkenalkan pengambilan sampel berlebih pada waktu kueri, bahkan jika konfigurasi pemadatan indeks tidak menentukan opsi pengambilan sampel atau reranking berlebihan.

Lihat juga