Knowhere
Este tema presenta Knowhere, el motor central de ejecución vectorial de Milvus.
Visión general
Knowhere es el motor central de ejecución vectorial de Milvus, que incorpora varias bibliotecas de búsqueda de similitud vectorial, incluyendo Faiss, Hnswlib y Annoy. Knowhere también está diseñado para soportar computación heterogénea. Controla en qué hardware (CPU o GPU) ejecutar la creación de índices y las peticiones de búsqueda. Así es como Knowhere obtiene su nombre - sabiendo dónde ejecutar las operaciones. Más tipos de hardware incluyendo DPU y TPU serán soportados en futuras versiones.
Knowhere en la arquitectura Milvus
La siguiente figura ilustra la posición de Knowhere en la arquitectura Milvus.
Knowhere
La capa inferior es el hardware del sistema. Encima se encuentran las bibliotecas de índices de terceros. En la capa superior, Knowhere interactúa con el nodo de índice y el nodo de consulta a través de CGO, que permite que los paquetes Go llamen al código C.
Ventajas de Knowhere
Las siguientes son las ventajas de Knowhere sobre Faiss.
Soporte para BitsetView
Milvus introduce un mecanismo de conjunto de bits para realizar el "borrado suave". Un vector borrado suavemente aún existe en la base de datos pero no será computado durante una búsqueda o consulta de similitud de vectores.
Cada bit de un conjunto de bits corresponde a un vector indexado. Si un vector está marcado como "1" en el conjunto de bits, significa que se ha eliminado de forma suave y que no participará en la búsqueda de vectores. El parámetro bitset se aplica a todas las API de consulta de índice Faiss expuestas en Knowhere, incluidos los índices de CPU y GPU.
Para obtener más información sobre el mecanismo de bitset, consulte bitset.
Soporte para múltiples métricas de similitud para indexar vectores binarios
Knowhere soporta Hamming, Jaccard, Tanimoto, Superestructura y Subestructura. Jaccard y Tanimoto pueden utilizarse para medir la similitud entre dos conjuntos de muestras mientras que Superstructure y Substructure pueden utilizarse para medir la similitud de estructuras químicas.
Compatibilidad con el conjunto de instrucciones AVX512
Además de AArch64, SSE4.2 y AVX2, los conjuntos de instrucciones ya soportados por Faiss, Knowhere también soporta AVX512, que puede mejorar el rendimiento de la creación de índices y consultas entre un 20% y un 30% en comparación con AVX2.
Selección automática de instrucciones SIMD
Knowhere soporta la invocación automática de las instrucciones SIMD adecuadas (por ejemplo, SIMD SSE, AVX, AVX2 y AVX512) en cualquier procesador de CPU (tanto en plataformas locales como en la nube), por lo que los usuarios no necesitan especificar manualmente la bandera SIMD (por ejemplo, "-msse4") durante la compilación.
Knowhere se construye mediante la refactorización del código base de Faiss. Las funciones comunes (por ejemplo, el cálculo de similitudes) que dependen de las aceleraciones SIMD se eliminan. Luego, para cada función, se implementan cuatro versiones (es decir, SSE, AVX, AVX2, AVX512) y cada una se coloca en un archivo fuente separado. A continuación, los archivos fuente se compilan individualmente con el indicador SIMD correspondiente. Por lo tanto, en tiempo de ejecución, Knowhere puede elegir automáticamente las instrucciones SIMD más adecuadas basándose en las banderas actuales de la CPU y luego enlazar los punteros de función correctos utilizando hooking.
Otras optimizaciones de rendimiento
Lea Milvus: Un Sistema de Administración de Datos Vectoriales Hecho a Medida para más información sobre la optimización del rendimiento de Knowhere.
Estructura del código Knowhere
La computación en Milvus involucra principalmente operaciones vectoriales y escalares. Knowhere sólo maneja las operaciones de indexación de vectores.
Un índice es una estructura de datos independiente de los datos vectoriales originales. Generalmente, la indexación requiere cuatro pasos: crear un índice, entrenar datos, insertar datos y construir un índice. En algunas aplicaciones de IA, el entrenamiento de los conjuntos de datos se separa de la búsqueda de vectores. Los datos de los conjuntos de datos se entrenan primero y luego se insertan en una base de datos vectorial como Milvus para la búsqueda de similitudes. Por ejemplo, los conjuntos de datos abiertos sift1M y sift1B diferencian los datos para entrenamiento y los datos para pruebas.
Sin embargo, en Knowhere, los datos para el entrenamiento y para la búsqueda son los mismos. Knowhere entrena todos los datos en un segmento y luego inserta todos los datos entrenados y construye un índice para ellos.
DataObj
Clase base
DataObj
es la clase base de todas las estructuras de datos en Knowhere. Size()
es el único método virtual en DataObj
. La clase Index hereda de DataObj
con un campo llamado "size_". La clase Index también tiene dos métodos virtuales - Serialize()
y Load()
. La clase VecIndex
derivada de Index
es la clase base virtual para todos los índices vectoriales. VecIndex
proporciona métodos que incluyen Train()
, Query()
, GetStatistics()
, y ClearStatistics()
.
clase base
Algunos otros tipos de índices aparecen a la derecha en la figura anterior.
El índice Faiss tiene dos clases base:
FaissBaseIndex
para todos los índices sobre vectores en coma flotante, yFaissBaseBinaryIndex
para todos los índices sobre vectores binarios.GPUIndex
es la clase base para todos los índices GPU de Faiss.OffsetBaseIndex
es la clase base para todos los índices de desarrollo propio. Dado que en un archivo de índice sólo se almacenan los ID de los vectores, el tamaño del archivo para vectores de 128 dimensiones puede reducirse en 2 órdenes de magnitud.
IDMAP
Búsqueda por fuerza bruta
IDMAP
Técnicamente hablando, IDMAP
no es un índice, sino que se utiliza para la búsqueda por fuerza bruta. Cuando se insertan vectores en la base de datos, no es necesario ni el entrenamiento de los datos ni la construcción de índices. Las búsquedas se realizarán directamente sobre los datos vectoriales insertados.
Sin embargo, por coherencia del código, IDMAP
también hereda de la clase VecIndex
con todas sus interfaces virtuales. El uso de IDMAP
es el mismo que el de otros índices.
Índices IVF
IVF
Los índices IVF (archivo invertido) son los más utilizados. La clase IVF
se deriva de VecIndex
y FaissBaseIndex
, y se extiende a IVFSQ
y IVFPQ
. GPUIVF
se deriva de GPUIndex
y IVF
. A continuación, GPUIVF
se amplía a GPUIVFSQ
y GPUIVFPQ
.
IVFSQHybrid
es un índice híbrido de desarrollo propio. Un cuantificador grueso se ejecuta en la GPU mientras que la búsqueda en el cubo se realiza en la CPU. Este tipo de índice puede reducir el número de copias de memoria entre la CPU y la GPU aprovechando la potencia de cálculo de la GPU. IVFSQHybrid
tiene la misma tasa de recuperación que GPUIVFSQ
pero ofrece un mejor rendimiento.
La estructura de clases base de los índices binarios es relativamente más sencilla. BinaryIDMAP
y BinaryIVF
derivan de FaissBaseBinaryIndex
y VecIndex
.
Índices de terceros
índices de terceros
Actualmente, sólo se admiten dos tipos de índices de terceros aparte de Faiss: el índice basado en árboles Annoy
, y el índice basado en gráficos HNSW
. Estos dos índices de terceros, comunes y de uso frecuente, se derivan de VecIndex
.
Añadir índices a Knowhere
Si desea añadir nuevos índices a Knowhere, primero puede hacer referencia a los índices existentes:
Para añadir índices basados en cuantización, consulte
IVF_FLAT
.Para añadir índices basados en gráficos, consulte
HNSW
.Para añadir índices basados en árboles, consulte
Annoy
.
Después de referirse al índice existente, puede seguir los siguientes pasos para agregar un nuevo índice a Knowhere.
Añada el nombre del nuevo índice en
IndexEnum
. El tipo de datos es cadena.Agregue la comprobación de validación de datos en el nuevo índice en el archivo
ConfAdapter.cpp
. La comprobación de validación es principalmente para validar los parámetros para la formación de datos y consulta.Cree un nuevo archivo para el nuevo índice. La clase base del nuevo índice debe incluir
VecIndex
, y la interfaz virtual necesaria deVecIndex
.Añade la lógica de construcción del nuevo índice en
VecIndexFactory::CreateVecIndex()
.Añade la prueba unitaria en el directorio
unittest
.
Lo que sigue
Después de aprender cómo funciona Knowhere en Milvus, es posible que también desee:
Aprender sobre los distintos tipos de índices que soporta Milvus.
Aprender sobre el mecanismo de conjuntos de bits.
Comprender cómo se procesan los datos en Milvus.