共用方式為

从存储中消除可选矢量实例

Azure AI 搜索会存储特定工作负载中使用的矢量字段的多个副本。 如果不需要支持特定行为,例如在查询响应中返回原始矢量,则可以在索引中设置属性以忽略该工作负载的存储空间。

移除存储是不可逆的,如果你之后想要恢复存储内容,则需要重新建立索引。

先决条件

  • 搜索索引中的矢量字段,通过vectorSearch配置可选分层导航小型世界(HNSW)或详尽 K-最近邻(KNN)算法,以及新的矢量描述。

如何存储矢量字段

对于每个矢量字段,最多可以有三个矢量副本,每个副本提供不同的用途:

实例 用法 受控使用
在文档索引过程中接收到的源矢量(JSON 数据) 用于通过 mergemergeOrUpload 索引操作进行增量数据刷新。 也用于在查询响应中返回“可检索”矢量。 矢量字段上的 stored 属性
原始全精度矢量(二进制数据) 用于内部索引操作,以及在较旧的 API 版本中进行详尽的 KNN 搜索。 对于压缩矢量,它还用于对从 ANN 搜索得到的过采样候选结果集进行 preserveOriginals 重新评分。 这适用于经历标量或二进制量化的矢量字段。 rescoringOptions.rescoreStorageMethod 中的 vectorSearch.compressions 属性。
HNSW 图中用于近似最近邻(ANN)搜索的向量,或用于详尽 K-最近邻(eKNN 索引)搜索的向量 用于查询执行。 包括全精度矢量(未应用压缩时)或量化矢量。 Essential。 没有用于移除该实例的参数。

可以设置相关属性,以永久丢弃矢量存储中的前两个实例(JSON 数据和二进制数据),但不能丢弃最后一个实例。

为了弥补 HNSW 的有损压缩带来的影响,可以保留第二个实例(二进制数据)用于重新评分,以提高 ANN 搜索质量。 对于 eKNN,仅支持标量量化,并且不提供重新评分选项。 在较新的 API 版本(如最新预览版)中,对于 eKNN 不保留第二个实例,因为第三个实例在 eKNN 索引中提供了全精度矢量。

使用 2024-11-01-preview 或更高版本 API 创建的索引

对于使用 2024-11-01-preview 或更高版本 API 且带有未压缩矢量字段创建的索引,作为我们降低成本措施的一部分,第二个和第三个实例(二进制数据和 HNSW 图)会合并在一起,从而减少总体存储量。 具有合并矢量的新一代索引在功能上与旧索引等效,但占用的存储空间更少。 物理数据结构是在创建索引请求时建立的,因此必须删除并重新创建索引才能实现存储量减少。

如果选择矢量压缩,人工智能搜索会压缩(量化)矢量索引的内存部分。 由于内存通常是矢量索引的主要限制因素,这种做法使你能够在相同的搜索服务中存储更多矢量。 然而,有损压缩意味着索引中的信息减少,这可能会影响搜索质量。

为了减轻信息损失,可以启用“重新评分”和“过度采样”选项来帮助保持搜索质量。 其效果是从压缩索引中检索出更大的候选文档集,并使用原始矢量或点积重新计算相似度分数。 为了使重新评分起作用,在某些情况下必须在存储中保留原始矢量。 因此,尽管量化会减少内存使用量(矢量索引大小的使用),但由于同时存储了压缩矢量和原始矢量,它会略微增加存储需求。 额外的存储量大约等于压缩索引的大小。

移除源矢量(JSON 数据)

stored 属性是矢量字段定义中的一个布尔属性,它决定是否为在索引过程中获取的可检索矢量字段内容(源实例)分配存储。 默认情况下,stored 属性为 true。 如果查询响应中不需要原始矢量内容,则可以通过将 stored 更改为 false 来为每个字段节省最多 50% 的存储空间。

stored 设置为 false 的注意事项:

  • 由于矢量不是人类可读的,因此可在 RAG 方案中在发送到 LLM 的结果中省略这些标量,并在搜索页面上呈现的结果中省略它们。 然而,如果在使用矢量内容的下游进程中使用矢量,请保留它们。

  • 但是,如果索引策略包括部分文档更新,例如现有文档上的“merge”或“mergeOrUpload”,则设置 stored=false 可阻止在合并期间对这些字段进行内容更新。 在对搜索文档的每个“merge”或“mergeOrUpload”操作中,必须完整提供矢量字段,以及要更新的非矢量字段,否则将删除矢量。

重要

设置 stored=false 属性是不可逆的。 只能在创建索引时设置此属性,并且仅在矢量字段上允许此属性。 使用新矢量字段更新现有索引不能将此属性设置为 false。 如果以后需要可检索的矢量内容,则必须删除并重新生成索引,或创建并加载具有新属性的新字段。

对于搜索索引中的新矢量字段,请将 stored 设置为 false 以永久删除矢量字段的可检索存储。 以下示例显示了具有 stored 属性的矢量字段定义。

PUT https://[service-name].search.azure.cn/indexes/demo-index?api-version=2024-07-01 
  Content-Type: application/json  
  api-key: [admin key]  

    { 
      "name": "demo-index", 
      "fields": [ 
        { 
          "name": "vectorContent", 
          "type": "Collection(Edm.Single)", 
          "retrievable": false, 
          "stored": false, 
          "dimensions": 1536, 
          "vectorSearchProfile": "vectorProfile" 
        } 
      ] 
    } 

要点总结

  • 适用于具有矢量数据类型的字段。

  • 影响磁盘上的存储,而不是内存,并且对查询没有影响。 查询执行使用不受 stored 属性影响的单独矢量索引,因为始终会存储矢量的副本。

  • stored 属性是在矢量字段上创建索引期间设置的,并且是不可逆的。 如果以后想要检索内容,则必须删除并重建索引,或者创建并加载具有新属性的新字段。

  • 默认情况下,stored 设置为 true,retrievable 设置为 false。 在默认配置中,会存储可检索的副本,但不会在结果中自动返回。 当 stored 为 true 时,可以随时在 true 和 false 之间切换可检索 retrievable,而无需重建索引。 当 stored 为 false 时,retrievable 也必须为 false 并且不能更改。

移除全精度矢量(二进制数据)

注释

此功能目前处于公开预览状态。 此预览版未随附服务级别协议,建议不要用于生产工作负载。 某些功能可能不受支持或者受限。 有关详细信息,请参阅适用于 Azure 预览版的补充使用条款

使用标量量化或二进制量化来压缩矢量时,查询将基于量化后的矢量执行。 在这种情况下,只有当你想要重新评分时,才需要原始的全精度矢量(二进制数据)。

如果你使用较新的预览版 API 并且采用二进制量化,则可以放心地丢弃全精度矢量,因为现在的重新评分策略使用二进制嵌入的点积,无需参考索引中的全精度矢量就能生成高质量的搜索结果。

rescoreStorageMethod 属性用于控制是否存储全精度矢量。 关于是否保留全精度矢量的指导原则如下:

  • 对于标量量化,应在索引中保留原始全精度矢量,因为重新评分时需要用到它们。
  • 对于二进制量化,要实现最高质量的重新评分,则保留原始全精度矢量;如果希望基于二进制嵌入的点积进行重新评分,可以丢弃全精度矢量(需要 2025-03-01-preview)。

在过去的几个版本中,矢量存储策略一直在不断发展。 索引创建日期和 API 版本决定了存储选项。

API 版本 适用于 移除原始全精度矢量
2024-07-01 及更早版本 不適用。 没有移除全精度矢量的机制。
2024-11-01-preview 二进制嵌入 使用 rescoreStorageMethod.discardOriginals 可移除全精度矢量,但这样做会导致无法重新评分。 如果原始矢量已被移除,则 enableRescoring 必须为 false。
2025-03-01-预览版 二进制嵌入 使用 rescoreStorageMethod.discardOriginals 可在索引中移除全精度矢量,同时仍保留重新评分的选项。 在此预览版中,重新评分是可行的,因为技术已发生变化。 重新评分时使用二进制嵌入的点积,生成的高质量搜索结果等同于或优于早期基于全精度矢量的技术。

请注意,表格中未列出标量量化。 如果使用标量量化,并且想要重新评分,则必须保留原始全精度矢量。

vectorSearch.compressions 中,rescoreStorageMethod 属性默认设置为 preserveOriginals,该属性保留用于过度采样和重新记录功能的全精度矢量,以减少对 HNSW 图的丢失压缩的影响。 如果不需要全精度矢量,可以通过将 rescoreStorageMethod 设置为 discardOriginals 来减少矢量存储。

重要

设置 rescoreStorageMethod 属性是不可逆的,并且可能会对搜索质量产生不利影响,尽管影响程度取决于压缩方法以及应用的任何缓解措施。

要设置此属性,请执行以下操作:

  1. 使用创建索引(预览版)创建或更新索引(预览版) REST API,或提供该功能的 Azure SDK beta 包。

  2. 使用配置文件、算法和压缩将 vectorSearch 部分添加到索引。

  3. vectorSearch.compressions 下,添加 rescoringOptions,并将 enableRescoring 设置为 true,defaultOversampling 设置为正整数,对于二进制量化,将 rescoreStorageMethod 设置为 discardOriginals;对于标量量化,将其设置为 preserveOriginals

    PUT https://[service-name].search.azure.cn/indexes/demo-index?api-version=2025-03-01-preview
    
    {
        "name": "demo-index",
        "fields": [. . . ],
        . . .
        "vectorSearch": {
            "profiles": [
                {
                "name": "myVectorProfile-1",
                "algorithm": "myHnsw",
                "compression": "myScalarQuantization"
                },
                {
                "name": "myVectorProfile-2",
                "algorithm": "myHnsw",
                "compression": "myBinaryQuantization"
                }
            ],
            "algorithms": [
              {
                "name": "myHnsw",
                "kind": "hnsw",
                "hnswParameters": {
                  "metric": "cosine",
                  "m": 4,
                  "efConstruction": 400,
                  "efSearch": 500
                },
                "exhaustiveKnnParameters": null
              }
            ],
            "compressions": [
                {
                    "name": "myScalarQuantization",
                    "kind": "scalarQuantization",
                    "rescoringOptions": {
                        "enableRescoring": true,
                        "defaultOversampling": 10,
                        "rescoreStorageMethod": "preserveOriginals"
                    },
                    "scalarQuantizationParameters": {
                        "quantizedDataType": "int8"
                    },
                    "truncationDimension": null
                },
                {
                    "name": "myBinaryQuantization",
                    "kind": "binaryQuantization",
                    "rescoringOptions": {
                        "enableRescoring": true,
                        "defaultOversampling": 10,
                        "rescoreStorageMethod": "discardOriginals"
                    },
                    "truncationDimension": null
                }
            ]
        }
    }