Docs Menu
Docs Home
/ /

Cómo realizar cuantificación automática con incrustaciones de Voyage AI

Las aplicaciones de IA suelen comenzar con costos de computación, datos y monetarios reducidos. A medida que las aplicaciones de producción escalan debido a la mayor participación del usuario, factores clave como el costo asociado con el almacenamiento y la recuperación de grandes volúmenes de datos se convierten en oportunidades de optimización cruciales. Estos desafíos pueden abordarse centrándose en:

  • Algoritmos eficientes de búsqueda vectorial

  • Procesos de cuantificación automatizados

  • Estrategias de incrustación optimizadas

Tanto la Generación Aumentada por Recuperación (RAG) como los sistemas basados ​​en agentes se basan en datos vectoriales (representaciones numéricas de objetos de datos como imágenes, vídeos y texto) para realizar búsquedas de similitud semántica. Los sistemas que utilizan RAG o flujos de trabajo basados ​​en agentes deben gestionar eficientemente conjuntos de datos masivos y de alta dimensión para mantener tiempos de respuesta rápidos, minimizar la latencia de recuperación y controlar los costes de infraestructura.

Este tutorial le proporciona las técnicas necesarias para diseñar, implementar y administrar cargas de trabajo de IA avanzadas a escala, garantizando un rendimiento óptimo y una rentabilidad óptima.

En concreto, en este tutorial aprenderás a:

  • Generar incrustaciones utilizando Voyage AI voyage-3-large, un modelo de incrustación multilingüe de propósito general que también tiene en cuenta la cuantificación y los incorpora a una base de datos MongoDB.

  • Cuantifique automáticamente las incrustaciones para reducir los tipos de datos de precisión, optimizando tanto el uso de memoria como la latencia de consulta.

  • Ejecute una consulta que compare incrustaciones float32, int8 y binarias, sopesando la precisión del tipo de datos frente a la eficiencia y la precisión de recuperación.

  • Mida la recuperación (también denominada retención) de las incrustaciones cuantificadas, que evalúa la eficacia con la que se cuantifican La búsquedaANN recupera los mismos documentos que una búsqueda ENN de precisión completa.

Nota

  • La cuantificación binaria es óptima para escenarios que exigen un menor consumo de recursos, aunque puede requerir una nueva pasada de puntuación para abordar cualquier pérdida de precisión.

  • La cuantificación escalar ofrece un punto medio práctico, adecuado para la mayoría de los casos de uso que necesitan equilibrar el rendimiento y la precisión.

  • Float32 asegura la máxima fidelidad, pero conlleva la mayor sobrecarga de rendimiento y memoria, lo que lo hace menos ideal para sistemas de gran escala o sensibles a la latencia.

Para completar este tutorial, debes tener lo siguiente:

  • Un clúster M20 o superior con 2 o más nodos de búsqueda que utilizan High-CPU S20 o un nivel de búsqueda superior.

  • Un entorno para ejecutar cuadernos interactivos de Python como VS Codeo Colab.

1
  1. Cree un cuaderno de Python interactivo guardando un archivo con la extensión .ipynb.

  2. Instalar las bibliotecas.

    Para este tutorial, debes importar las siguientes bibliotecas:

    PyMongo

    Controlador Python de MongoDB para conectarse a su clúster, crear índices y ejecutar consultas.

    voyageai

    Cliente Python de Voyage AI para generar las incrustaciones para los datos.

    pandas

    Herramienta de manipulación y análisis de datos para cargar los datos y prepararlos para la búsqueda vectorial.

    conjuntos de datos

    Biblioteca Hugging Face que proporciona acceso a conjuntos de datos listos para usar.

    matplotlib

    Para instalar las bibliotecas, ejecute lo siguiente:

    pip install --quiet -U pymongo voyageai pandas datasets matplotlib
  3. Obtenga y configure variables de entorno de forma segura.

    La siguiente set_env_securely función auxiliar obtiene y establece variables de entorno de forma segura. Copie, pegue y ejecute el siguiente código y, cuando se le solicite, establezca valores secretos como su clave de API de Voyage AI y la cadena de conexión del clúster.

    1import getpass
    2import os
    3import voyageai
    4
    5# Function to securely get and set environment variables
    6def set_env_securely(var_name, prompt):
    7 value = getpass.getpass(prompt)
    8 os.environ[var_name] = value
    9
    10# Environment Variables
    11set_env_securely("VOYAGE_API_KEY", "Enter your Voyage API Key: ")
    12set_env_securely("MONGO_URI", "Enter your MongoDB URI: ")
    13MONGO_URI = os.environ.get("MONGO_URI")
    14if not MONGO_URI:
    15 raise ValueError("MONGO_URI not set in environment variables.")
    16
    17# Voyage Client
    18voyage_client = voyageai.Client()
2

En este paso, cargará hasta 250000 documentos de los siguientes conjuntos de datos:

  1. Define las funciones para cargar los datos en tu clúster.

    Copia, pega y ejecuta el siguiente código en tu notebook. El código de ejemplo define las siguientes funciones:

    • generate_bson_vector para convertir las incrustaciones en el conjunto de datos en vectores binarios BSON para un almacenamiento y procesamiento eficiente de sus vectores.

    • get_mongo_client para obtener la cadena de conexión de su clúster.

    • insert_dataframe_into_collection para ingerir datos en el clúster.

    1import pandas as pd
    2from datasets import load_dataset
    3from bson.binary import Binary, BinaryVectorDtype
    4import pymongo
    5
    6# Connect to Cluster
    7def get_mongo_client(uri):
    8 """Connect to MongoDB and confirm the connection."""
    9 client = pymongo.MongoClient(uri)
    10 if client.admin.command("ping").get("ok") == 1.0:
    11 print("Connected to MongoDB successfully.")
    12 return client
    13 print("Failed to connect to MongoDB.")
    14 return None
    15
    16# Generate BSON Vector
    17def generate_bson_vector(array, data_type):
    18 """Convert an array to BSON vector format."""
    19 array = [float(val) for val in eval(array)]
    20 return Binary.from_vector(array, BinaryVectorDtype(data_type))
    21
    22# Load Datasets
    23def load_and_prepare_data(dataset_name, amount):
    24 """Load and prepare streaming datasets for DataFrame."""
    25 data = load_dataset(dataset_name, streaming=True, split="train").take(amount)
    26 return pd.DataFrame(data)
    27
    28# Insert datasets into MongoDB Collection
    29def insert_dataframe_into_collection(df, collection):
    30 """Insert Dataset records into MongoDB collection."""
    31 collection.insert_many(df.to_dict("records"))
    32 print(f"Inserted {len(df)} records into '{collection.name}' collection.")
  2. Cargue los datos en su clúster.

    Copie, pegue y ejecute el siguiente código en su notebook para cargar el conjunto de datos en su clúster. Este código realiza las siguientes acciones:

    • Recupera los conjuntos de datos.

    • Convierte las incrustaciones al formato BSON.

    • Crea colecciones en su clúster e inserta los datos.

    1import pandas as pd
    2from bson.binary import Binary, BinaryVectorDtype
    3from pymongo.errors import CollectionInvalid
    4
    5wikipedia_data_df = load_and_prepare_data("MongoDB/wikipedia-22-12-en-voyage-embed", amount=250000)
    6wikipedia_annotation_data_df = load_and_prepare_data("MongoDB/wikipedia-22-12-en-annotation", amount=250000)
    7wikipedia_annotation_data_df.drop(columns=["_id"], inplace=True)
    8
    9# Convert embeddings to BSON format
    10wikipedia_data_df["embedding"] = wikipedia_data_df["embedding"].apply(
    11 lambda x: generate_bson_vector(x, BinaryVectorDtype.FLOAT32)
    12)
    13
    14# MongoDB Setup
    15mongo_client = get_mongo_client(MONGO_URI)
    16DB_NAME = "testing_datasets"
    17db = mongo_client[DB_NAME]
    18
    19collections = {
    20 "wikipedia-22-12-en": wikipedia_data_df,
    21 "wikipedia-22-12-en-annotation": wikipedia_annotation_data_df,
    22}
    23
    24# Create Collections and Insert Data
    25for collection_name, df in collections.items():
    26 if collection_name not in db.list_collection_names():
    27 try:
    28 db.create_collection(collection_name)
    29 print(f"Collection '{collection_name}' created successfully.")
    30 except CollectionInvalid:
    31 print(f"Error creating collection '{collection_name}'.")
    32 else:
    33 print(f"Collection '{collection_name}' already exists.")
    34
    35 # Clear collection and insert fresh data
    36 collection = db[collection_name]
    37 collection.delete_many({})
    38 insert_dataframe_into_collection(df, collection)
    Connected to MongoDB successfully.
    Collection 'wikipedia-22-12-en' created successfully.
    Inserted 250000 records into 'wikipedia-22-12-en' collection.
    Collection 'wikipedia-22-12-en-annotation' created successfully.
    Inserted 87200 records into 'wikipedia-22-12-en-annotation' collection.

    IMPORTANTE: Puede llevar algún tiempo convertir las incrustaciones en vectores BSON e ingerir los conjuntos de datos en su clúster.

  3. Verifique que los conjuntos de datos se hayan cargado correctamente iniciando sesión en su clúster e inspeccionando visualmente las colecciones en Explorador de datos.

3

En este paso, creará los siguientes tres índices en el campo embedding:

Índice cuantificado escalar

Utilizar el método de cuantificación escalar para cuantificar las incrustaciones.

Índice cuantificado binario

Utilizar el método de cuantificación binaria para cuantificar las incrustaciones.

Float32 ANN Index

Utilizar el método32 ANN float para cuantificar las incrustaciones.

  1. Define la función para crear el índice de búsqueda vectorial de MongoDB.

    Copie, pegue y ejecute lo siguiente en su cuaderno:

    1import time
    2from pymongo.operations import SearchIndexModel
    3
    4def setup_vector_search_index(collection, index_definition, index_name="vector_index"):
    5 new_vector_search_index_model = SearchIndexModel(
    6 definition=index_definition, name=index_name, type="vectorSearch"
    7 )
    8
    9 # Create the new index
    10 try:
    11 result = collection.create_search_index(model=new_vector_search_index_model)
    12 print(f"Creating index '{index_name}'...")
    13
    14 # Wait for initial sync to complete
    15 print("Polling to check if the index is ready. This may take a couple of minutes.")
    16 predicate=None
    17 if predicate is None:
    18 predicate = lambda index: index.get("queryable") is True
    19 while True:
    20 indices = list(collection.list_search_indexes(result))
    21 if len(indices) and predicate(indices[0]):
    22 break
    23 time.sleep(5)
    24 print(f"Index '{index_name}' is ready for querying.")
    25 return result
    26
    27 except Exception as e:
    28 print(f"Error creating new vector search index '{index_name}': {e!s}")
    29 return None
  2. Definir los índices.

    Las siguientes configuraciones de índices implementan una estrategia diferente de cuantificación:

    vector_index_definition_scalar_quantized

    Esta configuración utiliza cuantificación escalar (int8), que:

    • Reduce cada dimensión vectorial de un valor flotante de 32bits a un valor entero de 8bits

    • Mantiene un buen equilibrio entre precisión y eficiencia de memoria.

    • Es adecuado para la mayoría de los casos de uso de producción donde se necesita optimización de memoria.

    vector_index_definition_binary_quantized

    Esta configuración utiliza cuantificación binaria (int1), que:

    • Reduce cada dimensión vectorial a un solo bit

    • Proporciona la máxima eficiencia de memoria

    • Es ideal para implementaciones a gran escala donde las limitaciones de memoria son críticas.

    La cuantización automática se realiza de manera transparente cuando se crean estos índices, y la Búsqueda Vectorial de MongoDB gestiona la conversión de float32 al formato cuantizado especificado durante la creación de índices y las operaciones de búsqueda.

    La configuración del índice vector_index_definition_float32_ann indexa vectores de fidelidad completa de 1024 dimensiones mediante la función de similitud cosine.

    1# Scalar Quantization
    2vector_index_definition_scalar_quantized = {
    3 "fields": [
    4 {
    5 "type": "vector",
    6 "path": "embedding",
    7 "quantization": "scalar",
    8 "numDimensions": 1024,
    9 "similarity": "cosine",
    10 }
    11 ]
    12}
    13# Binary Quantization
    14vector_index_definition_binary_quantized = {
    15 "fields": [
    16 {
    17 "type": "vector",
    18 "path": "embedding",
    19 "quantization": "binary",
    20 "numDimensions": 1024,
    21 "similarity": "cosine",
    22 }
    23 ]
    24}
    25# Float32 Embeddings
    26vector_index_definition_float32_ann = {
    27 "fields": [
    28 {
    29 "type": "vector",
    30 "path": "embedding",
    31 "numDimensions": 1024,
    32 "similarity": "cosine",
    33 }
    34 ]
    35}
  3. Cree los índices escalares, binarios y flotantes32 utilizando la función setup_vector_search_index.

    1. Establezca los nombres de colección e índice para los índices.

      wiki_data_collection = db["wikipedia-22-12-en"]
      wiki_annotation_data_collection = db["wikipedia-22-12-en-annotation"]
      vector_search_scalar_quantized_index_name = "vector_index_scalar_quantized"
      vector_search_binary_quantized_index_name = "vector_index_binary_quantized"
      vector_search_float32_ann_index_name = "vector_index_float32_ann"
    2. Cree los índices de búsqueda vectorial de MongoDB.

      1setup_vector_search_index(
      2 wiki_data_collection,
      3 vector_index_definition_scalar_quantized,
      4 vector_search_scalar_quantized_index_name,
      5)
      6setup_vector_search_index(
      7 wiki_data_collection,
      8 vector_index_definition_binary_quantized,
      9 vector_search_binary_quantized_index_name,
      10)
      11setup_vector_search_index(
      12 wiki_data_collection,
      13 vector_index_definition_float32_ann,
      14 vector_search_float32_ann_index_name,
      15)
      Creating index 'vector_index_scalar_quantized'...
      Polling to check if the index is ready. This may take a couple of minutes.
      Index 'vector_index_scalar_quantized' is ready for querying.
      Creating index 'vector_index_binary_quantized'...
      Polling to check if the index is ready. This may take a couple of minutes.
      Index 'vector_index_binary_quantized' is ready for querying.
      Creating index 'vector_index_float32_ann'...
      Polling to check if the index is ready. This may take a couple of minutes.
      Index 'vector_index_float32_ann' is ready for querying.
      vector_index_float32_ann'

      IMPORTANTE: La operación puede tardar unos minutos en completarse. Los índices deben estar en Ready estado para poder usarlos en las consultas.

    3. Verifique que la creación del índice se haya realizado correctamente iniciando sesión en su clúster e inspeccionando visualmente los índices en Atlas Search.

4

Este código define las siguientes funciones:

  • La función get_embedding() genera incrustaciones de dimensión 1024 para el texto dado utilizando el modelo de incrustación voyage-3-large de Voyage AI.

  • La función custom_vector_search toma los siguientes parámetros de entrada y devuelve los resultados de la operación de búsqueda vectorial.

    user_query

    string de texto de query para la que se desea generar incrustaciones.

    collection

    Colección MongoDB para buscar.

    embedding_path

    Campo de la colección que contiene las incrustaciones.

    vector_search_index_name

    Nombre del índice a utilizar en la consulta.

    top_k

    Número de documentos principales en los resultados a devolver.

    num_candidates

    Número de candidatos a considerar.

    use_full_precision

    Bandera para realizar False Truebúsqueda ANN, si, o ENN, si.

    El use_full_precision valor se establece en False de forma predeterminada para una búsqueda ANN. Establezca el use_full_precision valor en True para realizar una búsqueda ENN.

    En concreto, esta función realiza las siguientes acciones:

    • Genera las incrustaciones para el texto de la consulta.

    • Construye la $vectorSearch etapa

    • Configura el tipo de búsqueda

    • Especifica los campos de la colección que se devolverán

    • Ejecuta la canalización después de recopilar estadísticas de rendimiento

    • Devuelve los resultados

1def get_embedding(text, task_prefix="document"):
2 """Fetch embedding for a given text using Voyage AI."""
3 if not text.strip():
4 print("Empty text provided for embedding.")
5 return []
6 result = voyage_client.embed([text], model="voyage-3-large", input_type=task_prefix)
7 return result.embeddings[0]
8
9def custom_vector_search(
10 user_query,
11 collection,
12 embedding_path,
13 vector_search_index_name="vector_index",
14 top_k=5,
15 num_candidates=25,
16 use_full_precision=False,
17):
18
19 # Generate embedding for the user query
20 query_embedding = get_embedding(user_query, task_prefix="query")
21
22 if query_embedding is None:
23 return "Invalid query or embedding generation failed."
24
25 # Define the vector search stage
26 vector_search_stage = {
27 "$vectorSearch": {
28 "index": vector_search_index_name,
29 "queryVector": query_embedding,
30 "path": embedding_path,
31 "limit": top_k,
32 }
33 }
34
35 # Add numCandidates only for approximate search
36 if not use_full_precision:
37 vector_search_stage["$vectorSearch"]["numCandidates"] = num_candidates
38 else:
39 # Set exact to true for exact search using full precision float32 vectors and running exact search
40 vector_search_stage["$vectorSearch"]["exact"] = True
41
42 project_stage = {
43 "$project": {
44 "_id": 0,
45 "title": 1,
46 "text": 1,
47 "wiki_id": 1,
48 "url": 1,
49 "score": {
50 "$meta": "vectorSearchScore"
51 },
52 }
53 }
54
55 # Define the aggregate pipeline with the vector search stage and additional stages
56 pipeline = [vector_search_stage, project_stage]
57
58 # Execute the explain command
59 explain_result = collection.database.command(
60 "explain",
61 {"aggregate": collection.name, "pipeline": pipeline, "cursor": {}},
62 verbosity="executionStats",
63 )
64
65 # Extract the execution time
66 vector_search_explain = explain_result["stages"][0]["$vectorSearch"]
67 execution_time_ms = vector_search_explain["explain"]["query"]["stats"]["context"][
68 "millisElapsed"
69 ]
70
71 # Execute the actual query
72 results = list(collection.aggregate(pipeline))
73
74 return {"results": results, "execution_time_ms": execution_time_ms}
5

La siguiente consulta realiza búsquedas vectoriales con diferentes estrategias de cuantificación, midiendo métricas de rendimiento para vectores de cuantificación escalar, cuantificación binaria y precisión completa (float32), a la vez que captura mediciones de latencia en cada nivel de precisión y estandariza el formato de los resultados para su comparación analítica. Utiliza incrustaciones generadas con Voyage AI para la cadena de consulta "¿Cómo puedo aumentar mi productividad para obtener el máximo rendimiento?".

La consulta almacena indicadores de rendimiento esenciales clave en la variable results, incluido el nivel de precisión (escalar, binario, flotante32), el tamaño del conjunto de resultados (top_k), la latencia de la consulta en milisegundos y el contenido del documento recuperado, lo que proporciona métricas integrales para evaluar el rendimiento de la búsqueda en diferentes estrategias de cuantificación.

1vector_search_indices = [
2 vector_search_float32_ann_index_name,
3 vector_search_scalar_quantized_index_name,
4 vector_search_binary_quantized_index_name,
5]
6
7# Random query
8user_query = "How do I increase my productivity for maximum output"
9test_top_k = 5
10test_num_candidates = 25
11
12# Result is a list of dictionaries with the following headings: precision, top_k, latency_ms, results
13results = []
14
15for vector_search_index in vector_search_indices:
16 # Conduct a vector search operation using scalar quantized
17 vector_search_results = custom_vector_search(
18 user_query,
19 wiki_data_collection,
20 embedding_path="embedding",
21 vector_search_index_name=vector_search_index,
22 top_k=test_top_k,
23 num_candidates=test_num_candidates,
24 use_full_precision=False,
25 )
26 # Include the precision in the results
27 precision = vector_search_index.split("vector_index")[1]
28 precision = precision.replace("quantized", "").capitalize()
29
30 results.append(
31 {
32 "precision": precision,
33 "top_k": test_top_k,
34 "num_candidates": test_num_candidates,
35 "latency_ms": vector_search_results["execution_time_ms"],
36 "results": vector_search_results["results"][0], # Just taking the first result, modify this to include more results if needed
37 }
38 )
39
40# Conduct a vector search operation using full precision
41precision = "Float32_ENN"
42vector_search_results = custom_vector_search(
43 user_query,
44 wiki_data_collection,
45 embedding_path="embedding",
46 vector_search_index_name="vector_index_scalar_quantized",
47 top_k=test_top_k,
48 num_candidates=test_num_candidates,
49 use_full_precision=True,
50)
51
52results.append(
53 {
54 "precision": precision,
55 "top_k": test_top_k,
56 "num_candidates": test_num_candidates,
57 "latency_ms": vector_search_results["execution_time_ms"],
58 "results": vector_search_results["results"][0], # Just taking the first result, modify this to include more results if needed
59 }
60)
61
62# Convert the results to a pandas DataFrame with the headings: precision, top_k, latency_ms
63results_df = pd.DataFrame(results)
64results_df.columns = ["precision", "top_k", "num_candidates", "latency_ms", "results"]
65
66# To display the results:
67results_df.head()
precision top_k num_candidates latency_ms results
0 _float32_ann 5 25 1659.498601 {'title': 'Henry Ford', 'text': 'Ford had deci...
1 _scalar_ 5 25 951.537687 {'title': 'Gross domestic product', 'text': 'F...
2 _binary_ 5 25 344.585193 {'title': 'Great Depression', 'text': 'The fir...
3 Float32_ENN 5 25 0.231693 {'title': 'Great Depression', 'text': 'The fir...

Las métricas de rendimiento de los resultados muestran diferencias de latencia entre los distintos niveles de precisión. Esto demuestra que, si bien la cuantificación proporciona mejoras sustanciales en el rendimiento, existe una clara compensación entre la precisión y la velocidad de recuperación, ya que las operaciones float32 de precisión completa requieren un tiempo de cálculo considerablemente mayor que sus contrapartes cuantificadas.

6

La siguiente consulta introduce un marco sistemático de medición de latencia que evalúa el rendimiento de la búsqueda vectorial con diferentes niveles de precisión y escalas de recuperación. El parámetro top-k no solo determina el número de resultados a devolver, sino que también establece el numCandidates parámetro en la búsqueda de grafos HNSW de MongoDB.

El numCandidates valor influye en la cantidad de nodos que MongoDB Vector Search explora en el grafo HNSW durante la búsqueda de ANN. En este caso, un valor más alto aumenta la probabilidad de encontrar los vecinos más cercanos, pero requiere más tiempo de cálculo.

  1. Define la función para formatear latency_ms en un formato legible para humanos.

    1from datetime import timedelta
    2
    3def format_time(ms):
    4 """Convert milliseconds to a human-readable format"""
    5 delta = timedelta(milliseconds=ms)
    6
    7 # Extract minutes, seconds, and milliseconds with more precision
    8 minutes = delta.seconds // 60
    9 seconds = delta.seconds % 60
    10 milliseconds = round(ms % 1000, 3) # Keep 3 decimal places for milliseconds
    11
    12 # Format based on duration
    13 if minutes > 0:
    14 return f"{minutes}m {seconds}.{milliseconds:03.0f}s"
    15 elif seconds > 0:
    16 return f"{seconds}.{milliseconds:03.0f}s"
    17 else:
    18 return f"{milliseconds:.3f}ms"
  2. Define la función para medir la latencia de la consulta de búsqueda vectorial.

    La siguiente función toma como entrada los valores user_query, collection, vector_search_index_name, use_full_precision, top_k_values y num_candidates_values y devuelve los resultados de la búsqueda vectorial. Anote lo siguiente:

    • La latencia aumenta a medida que aumentan los valores top_k y num_candidates porque la operación de búsqueda vectorial utiliza una mayor cantidad de documentos y hace que la búsqueda tarde más.

    • La latencia es mayor para la búsqueda de fidelidad total (use_full_precision=True) que para la búsqueda aproximada (use_full_precision=False) porque la búsqueda de fidelidad total toma más tiempo que la búsqueda aproximada ya que busca en todo el conjunto de datos, utilizando vectores float32 de precisión total.

    • La latencia de la búsqueda cuantificada es menor que la búsqueda de fidelidad completa porque la búsqueda cuantificada utiliza la búsqueda aproximada y los vectores cuantificados.

    1def measure_latency_with_varying_topk(
    2 user_query,
    3 collection,
    4 vector_search_index_name="vector_index_scalar_quantized",
    5 use_full_precision=False,
    6 top_k_values=[5, 10, 100],
    7 num_candidates_values=[25, 50, 100, 200, 500, 1000, 2000, 5000, 10000],
    8):
    9 results_data = []
    10
    11 # Conduct vector search operation for each (top_k, num_candidates) combination
    12 for top_k in top_k_values:
    13 for num_candidates in num_candidates_values:
    14 # Skip scenarios where num_candidates < top_k
    15 if num_candidates < top_k:
    16 continue
    17
    18 # Construct the precision name
    19 precision_name = vector_search_index_name.split("vector_index")[1]
    20 precision_name = precision_name.replace("quantized", "").capitalize()
    21
    22 # If use_full_precision is true, then the precision name is "_float32_"
    23 if use_full_precision:
    24 precision_name = "_float32_ENN"
    25
    26 # Perform the vector search
    27 vector_search_results = custom_vector_search(
    28 user_query=user_query,
    29 collection=collection,
    30 embedding_path="embedding",
    31 vector_search_index_name=vector_search_index_name,
    32 top_k=top_k,
    33 num_candidates=num_candidates,
    34 use_full_precision=use_full_precision,
    35 )
    36
    37 # Extract the execution time (latency)
    38 latency_ms = vector_search_results["execution_time_ms"]
    39
    40 # Store results
    41 results_data.append(
    42 {
    43 "precision": precision_name,
    44 "top_k": top_k,
    45 "num_candidates": num_candidates,
    46 "latency_ms": latency_ms,
    47 }
    48 )
    49
    50 return results_data
  3. Ejecuta la consulta de búsqueda vectorial de MongoDB para medir la latencia.

    La operación de evaluación de latencia realiza un análisis integral del rendimiento ejecutando búsquedas a través de todas las estrategias de cuantización, probando múltiples tamaños de conjuntos de resultados, capturando métricas de rendimiento estandarizadas y agregando los resultados para un análisis comparativo, lo que permite una evaluación detallada del comportamiento de búsqueda vectorial bajo diferentes configuraciones y cargas de recuperación.

    1# Run the measurements
    2user_query = "How do I increase my productivity for maximum output"
    3top_k_values = [5, 10, 50, 100]
    4num_candidates_values = [25, 50, 100, 200, 500, 1000, 2000, 5000, 10000]
    5
    6latency_results = []
    7
    8for vector_search_index in vector_search_indices:
    9 latency_results.append(
    10 measure_latency_with_varying_topk(
    11 user_query,
    12 wiki_data_collection,
    13 vector_search_index_name=vector_search_index,
    14 use_full_precision=False,
    15 top_k_values=top_k_values,
    16 num_candidates_values=num_candidates_values,
    17 )
    18 )
    19
    20# Conduct vector search operation using full precision
    21latency_results.append(
    22 measure_latency_with_varying_topk(
    23 user_query,
    24 wiki_data_collection,
    25 vector_search_index_name="vector_index_scalar_quantized",
    26 use_full_precision=True,
    27 top_k_values=top_k_values,
    28 num_candidates_values=num_candidates_values,
    29 )
    30)
    31
    32# Combine all results into a single DataFrame
    33all_latency_results = pd.concat([pd.DataFrame(latency_results)])
    Top-K: 5, NumCandidates: 25, Latency: 1672.855906 ms, Precision: _float32_ann
    ...
    Top-K: 100, NumCandidates: 10000, Latency: 184.905389 ms, Precision: _float32_ann
    Top-K: 5, NumCandidates: 25, Latency: 828.45855 ms, Precision: _scalar_
    ...
    Top-K: 100, NumCandidates: 10000, Latency: 214.199836 ms, Precision: _scalar_
    Top-K: 5, NumCandidates: 25, Latency: 400.160243 ms, Precision: _binary_
    ...
    Top-K: 100, NumCandidates: 10000, Latency: 360.908558 ms, Precision: _binary_
    Top-K: 5, NumCandidates: 25, Latency: 0.239107 ms, Precision: _float32_ENN
    ...
    Top-K: 100, NumCandidates: 10000, Latency: 0.179203 ms, Precision: _float32_ENN

    Las mediciones de latencia revelan una clara jerarquía de rendimiento entre los tipos de precisión, donde la cuantificación binaria presenta los tiempos de recuperación más rápidos, seguida de la cuantificación escalar. Las operaciones de32 ANN float de precisión completa muestran latencias significativamente mayores. La diferencia de rendimiento entre las búsquedas cuantificadas y las de precisión completa se acentúa a medida que aumentan los valores Top-K. Las32 operaciones de ENN float son las más lentas, pero ofrecen los resultados de mayor precisión.

  4. Grafique la latencia de búsqueda en función de varios valores top-k.

    1import matplotlib.pyplot as plt
    2
    3# Map your precision field to the labels and colors you want in the legend
    4precision_label_map = {
    5 "_scalar_": "scalar",
    6 "_binary_": "binary",
    7 "_float32_ann": "float32_ann",
    8 "_float32_ENN": "float32_ENN",
    9}
    10
    11precision_color_map = {
    12 "_scalar_": "orange",
    13 "_binary_": "red",
    14 "_float32_ann": "blue",
    15 "_float32_ENN": "purple",
    16}
    17
    18# Flatten all measurements and find the unique top_k values
    19all_measurements = [m for precision_list in latency_results for m in precision_list]
    20unique_topk = sorted(set(m["top_k"] for m in all_measurements))
    21
    22# For each top_k, create a separate plot
    23for k in unique_topk:
    24 plt.figure(figsize=(10, 6))
    25
    26 # For each precision type, filter out measurements for the current top_k value
    27 for measurements in latency_results:
    28 # Filter measurements with top_k equal to the current k
    29 filtered = [m for m in measurements if m["top_k"] == k]
    30 if not filtered:
    31 continue
    32
    33 # Extract x (num_candidates) and y (latency) values
    34 x = [m["num_candidates"] for m in filtered]
    35 y = [m["latency_ms"] for m in filtered]
    36
    37 # Determine the precision, label, and color from the first measurement in this filtered list
    38 precision = filtered[0]["precision"]
    39 label = precision_label_map.get(precision, precision)
    40 color = precision_color_map.get(precision, "blue")
    41
    42 # Plot the line for this precision type
    43 plt.plot(x, y, marker="o", color=color, label=label)
    44
    45 # Label axes and add title including the top_k value
    46 plt.xlabel("Number of Candidates")
    47 plt.ylabel("Latency (ms)")
    48 plt.title(f"Search Latency vs Num Candidates for Top-K = {k}")
    49
    50 # Add a legend and grid, then show the plot
    51 plt.legend()
    52 plt.grid(True)
    53 plt.show()

    El código devuelve los siguientes gráficos de latencia, que ilustran cómo funciona la recuperación de documentos de búsqueda vectorial con diferentes tipos de precisión de incrustación, binario, escalar y flotante32, a medida que aumenta top-k (la cantidad de resultados recuperados):

7

La siguiente consulta mide la eficacia con la que MongoDB Vector Search recupera documentos relevantes del conjunto de datos de datos de campo. Se calcula como la proporción de documentos relevantes encontrados correctamente respecto al número total de documentos relevantes en el conjunto de datos de campo (Encontrados/Total). Por ejemplo, si una consulta tiene 5 documentos relevantes en el conjunto de datos de campo y MongoDB Vector Search encuentra 4, la recuperación sería de 0.8 o 80%.

  1. Defina una función para medir la capacidad de representación y la retención de la operación de búsqueda vectorial. Esta función realiza lo siguiente:

    1. Crea la búsqueda de línea base utilizando32 vectores float de precisión completa y búsqueda ENN.

    2. Crea la búsqueda cuantificada utilizando los vectores cuantificados y la búsqueda ANN.

    3. Calcula la retención de la búsqueda cuantificada en comparación con la búsqueda de referencia.

    La retención debe mantenerse dentro de un rango razonable para la búsqueda cuantificada. Si la capacidad de representación es baja, significa que la búsqueda vectorial no puede capturar el significado semántico de la consulta y que los resultados podrían no ser precisos. Esto indica que la cuantificación no es efectiva y que el modelo de incrustación inicial utilizado no es eficaz para el proceso de cuantificación. Recomendamos utilizar modelos de incrustación que tengan en cuenta la cuantificación, es decir, que durante el proceso de entrenamiento, el modelo se optimice específicamente para producir incrustaciones que mantengan sus propiedades semánticas incluso después de la cuantificación.

    1def measure_representational_capacity_retention_against_float_enn(
    2 ground_truth_collection,
    3 collection,
    4 quantized_index_name, # This is used for both the quantized search and (with use_full_precision=True) for the baseline.
    5 top_k_values, # List/array of top-k values to test.
    6 num_candidates_values, # List/array of num_candidates values to test.
    7 num_queries_to_test=1,
    8):
    9retention_results = {"per_query_retention": {}}
    10overall_retention = {} # overall_retention[top_k][num_candidates] = [list of retention values]
    11
    12# Initialize overall retention structure
    13for top_k in top_k_values:
    14 overall_retention[top_k] = {}
    15 for num_candidates in num_candidates_values:
    16 if num_candidates < top_k:
    17 continue
    18 overall_retention[top_k][num_candidates] = []
    19
    20# Extract and store the precision name from the quantized index name.
    21precision_name = quantized_index_name.split("vector_index")[1]
    22precision_name = precision_name.replace("quantized", "").capitalize()
    23retention_results["precision_name"] = precision_name
    24retention_results["top_k_values"] = top_k_values
    25retention_results["num_candidates_values"] = num_candidates_values
    26
    27# Load ground truth annotations
    28ground_truth_annotations = list(
    29 ground_truth_collection.find().limit(num_queries_to_test)
    30)
    31print(f"Loaded {len(ground_truth_annotations)} ground truth annotations")
    32
    33# Process each ground truth annotation
    34for annotation in ground_truth_annotations:
    35 # Use the ground truth wiki_id from the annotation.
    36 ground_truth_wiki_id = annotation["wiki_id"]
    37
    38 # Process only queries that are questions.
    39 for query_type, queries in annotation["queries"].items():
    40 if query_type.lower() not in ["question", "questions"]:
    41 continue
    42
    43 for query in queries:
    44 # Prepare nested dict for this query
    45 if query not in retention_results["per_query_retention"]:
    46 retention_results["per_query_retention"][query] = {}
    47
    48 # For each valid combination of top_k and num_candidates
    49 for top_k in top_k_values:
    50 if top_k not in retention_results["per_query_retention"][query]:
    51 retention_results["per_query_retention"][query][top_k] = {}
    52 for num_candidates in num_candidates_values:
    53 if num_candidates < top_k:
    54 continue
    55
    56 # Baseline search: full precision using ENN (Float32)
    57 baseline_result = custom_vector_search(
    58 user_query=query,
    59 collection=collection,
    60 embedding_path="embedding",
    61 vector_search_index_name=quantized_index_name,
    62 top_k=top_k,
    63 num_candidates=num_candidates,
    64 use_full_precision=True,
    65 )
    66 baseline_ids = {
    67 res["wiki_id"] for res in baseline_result["results"]
    68 }
    69
    70 # Quantized search:
    71 quantized_result = custom_vector_search(
    72 user_query=query,
    73 collection=collection,
    74 embedding_path="embedding",
    75 vector_search_index_name=quantized_index_name,
    76 top_k=top_k,
    77 num_candidates=num_candidates,
    78 use_full_precision=False,
    79 )
    80 quantized_ids = {
    81 res["wiki_id"] for res in quantized_result["results"]
    82 }
    83
    84 # Compute retention for this combination
    85 if baseline_ids:
    86 retention = len(
    87 baseline_ids.intersection(quantized_ids)
    88 ) / len(baseline_ids)
    89 else:
    90 retention = 0
    91
    92 # Store the results per query
    93 retention_results["per_query_retention"][query].setdefault(
    94 top_k, {}
    95 )[num_candidates] = {
    96 "ground_truth_wiki_id": ground_truth_wiki_id,
    97 "baseline_ids": sorted(baseline_ids),
    98 "quantized_ids": sorted(quantized_ids),
    99 "retention": retention,
    100 }
    101 overall_retention[top_k][num_candidates].append(retention)
    102
    103 print(
    104 f"Query: '{query}' | top_k: {top_k}, num_candidates: {num_candidates}"
    105 )
    106 print(f" Ground Truth wiki_id: {ground_truth_wiki_id}")
    107 print(f" Baseline IDs (Float32): {sorted(baseline_ids)}")
    108 print(
    109 f" Quantized IDs: {precision_name}: {sorted(quantized_ids)}"
    110 )
    111 print(f" Retention: {retention:.4f}\n")
    112
    113# Compute overall average retention per combination
    114avg_overall_retention = {}
    115for top_k, cand_dict in overall_retention.items():
    116 avg_overall_retention[top_k] = {}
    117 for num_candidates, retentions in cand_dict.items():
    118 if retentions:
    119 avg = sum(retentions) / len(retentions)
    120 else:
    121 avg = 0
    122 avg_overall_retention[top_k][num_candidates] = avg
    123 print(
    124 f"Overall Average Retention for top_k {top_k}, num_candidates {num_candidates}: {avg:.4f}"
    125 )
    126
    127retention_results["average_retention"] = avg_overall_retention
    128return retention_results
  2. Evalúe y compare el rendimiento de sus índices de búsqueda vectorial de MongoDB.

    1overall_recall_results = []
    2top_k_values = [5, 10, 50, 100]
    3num_candidates_values = [25, 50, 100, 200, 500, 1000, 5000]
    4num_queries_to_test = 1
    5
    6for vector_search_index in vector_search_indices:
    7 overall_recall_results.append(
    8 measure_representational_capacity_retention_against_float_enn(
    9 ground_truth_collection=wiki_annotation_data_collection,
    10 collection=wiki_data_collection,
    11 quantized_index_name=vector_search_index,
    12 top_k_values=top_k_values,
    13 num_candidates_values=num_candidates_values,
    14 num_queries_to_test=num_queries_to_test,
    15 )
    16 )
    Loaded 1 ground truth annotations
    Query: 'What happened in 2022?' | top_k: 5, num_candidates: 25
    Ground Truth wiki_id: 69407798
    Baseline IDs (Float32): [52251217, 60254944, 64483771, 69094871]
    Quantized IDs: _float32_ann: [60254944, 64483771, 69094871]
    Retention: 0.7500
    ...
    Query: 'What happened in 2022?' | top_k: 5, num_candidates: 5000
    Ground Truth wiki_id: 69407798
    Baseline IDs (Float32): [52251217, 60254944, 64483771, 69094871]
    Quantized IDs: _float32_ann: [52251217, 60254944, 64483771, 69094871]
    Retention: 1.0000
    Query: 'What happened in 2022?' | top_k: 10, num_candidates: 25
    Ground Truth wiki_id: 69407798
    Baseline IDs (Float32): [52251217, 60254944, 64483771, 69094871, 69265870]
    Quantized IDs: _float32_ann: [60254944, 64483771, 65225795, 69094871, 70149799]
    Retention: 1.0000
    ...
    Query: 'What happened in 2022?' | top_k: 10, num_candidates: 5000
    Ground Truth wiki_id: 69407798
    Baseline IDs (Float32): [52251217, 60254944, 64483771, 69094871, 69265870]
    Quantized IDs: _float32_ann: [52251217, 60254944, 64483771, 69094871, 69265870]
    Retention: 1.0000
    Query: 'What happened in 2022?' | top_k: 50, num_candidates: 50
    Ground Truth wiki_id: 69407798
    Baseline IDs (Float32): [25391, 832774, 8351234, 18426568, 29868391, 52241897, 52251217, 60254944, 63422045, 64483771, 65225795, 69094871, 69265859, 69265870, 70149799, 70157964]
    Quantized IDs: _float32_ann: [25391, 8351234, 29868391, 40365067, 52241897, 52251217, 60254944, 64483771, 65225795, 69094871, 69265859, 69265870, 70149799, 70157964]
    Retention: 0.8125
    ...
    Query: 'What happened in 2022?' | top_k: 50, num_candidates: 5000
    Ground Truth wiki_id: 69407798
    Baseline IDs (Float32): [25391, 832774, 8351234, 18426568, 29868391, 52241897, 52251217, 60254944, 63422045, 64483771, 65225795, 69094871, 69265859, 69265870, 70149799, 70157964]
    Quantized IDs: _float32_ann: [25391, 832774, 8351234, 18426568, 29868391, 52241897, 52251217, 60254944, 63422045, 64483771, 65225795, 69094871, 69265859, 69265870, 70149799, 70157964]
    Retention: 1.0000
    Query: 'What happened in 2022?' | top_k: 100, num_candidates: 100
    Ground Truth wiki_id: 69407798
    Baseline IDs (Float32): [16642, 22576, 25391, 547384, 737930, 751099, 832774, 8351234, 17742072, 18426568, 29868391, 40365067, 52241897, 52251217, 52851695, 53992315, 57798792, 60163783, 60254944, 62750956, 63422045, 64483771, 65225795, 65593860, 69094871, 69265859, 69265870, 70149799, 70157964]
    Quantized IDs: _float32_ann: [22576, 25391, 243401, 547384, 751099, 8351234, 17742072, 18426568, 29868391, 40365067, 47747350, 52241897, 52251217, 52851695, 53992315, 57798792, 60254944, 64483771, 65225795, 69094871, 69265859, 69265870, 70149799, 70157964]
    Retention: 0.7586
    ...
    Query: 'What happened in 2022?' | top_k: 100, num_candidates: 5000
    Ground Truth wiki_id: 69407798
    Baseline IDs (Float32): [16642, 22576, 25391, 547384, 737930, 751099, 832774, 8351234, 17742072, 18426568, 29868391, 40365067, 52241897, 52251217, 52851695, 53992315, 57798792, 60163783, 60254944, 62750956, 63422045, 64483771, 65225795, 65593860, 69094871, 69265859, 69265870, 70149799, 70157964]
    Quantized IDs: _float32_ann: [16642, 22576, 25391, 547384, 737930, 751099, 832774, 8351234, 17742072, 18426568, 29868391, 40365067, 52241897, 52251217, 52851695, 53992315, 57798792, 60163783, 60254944, 62750956, 63422045, 64483771, 65225795, 65593860, 69094871, 69265859, 69265870, 70149799, 70157964]
    Retention: 1.0000
    Overall Average Retention for top_k 5, num_candidates 25: 0.7500
    ...

    La salida muestra los resultados de retención para cada consulta en el conjunto de datos de datos de campo. La retención se expresa como un decimal entre 0 y 1, donde 1.0 significa que se conservan los ID de datos de campo y 0.25 que solo se conserva el 25% de los mismos.

  3. Grafique la capacidad de retención de los diferentes tipos de precisión.

    1import matplotlib.pyplot as plt
    2
    3# Define colors and labels for each precision type
    4precision_colors = {"_scalar_": "orange", "_binary_": "red", "_float32_": "green"}
    5
    6if overall_recall_results:
    7 # Determine unique top_k values from the first result's average_retention keys
    8 unique_topk = sorted(list(overall_recall_results[0]["average_retention"].keys()))
    9
    10 for k in unique_topk:
    11 plt.figure(figsize=(10, 6))
    12 # For each precision type, plot retention vs. number of candidates at this top_k
    13 for result in overall_recall_results:
    14 precision_name = result.get("precision_name", "unknown")
    15 color = precision_colors.get(precision_name, "blue")
    16 # Get candidate values from the average_retention dictionary for top_k k
    17 candidate_values = sorted(result["average_retention"][k].keys())
    18 retention_values = [
    19 result["average_retention"][k][nc] for nc in candidate_values
    20 ]
    21
    22 plt.plot(
    23 candidate_values,
    24 retention_values,
    25 marker="o",
    26 label=precision_name.strip("_"),
    27 color=color,
    28 )
    29
    30 plt.xlabel("Number of Candidates")
    31 plt.ylabel("Retention Score")
    32 plt.title(f"Retention vs Number of Candidates for Top-K = {k}")
    33 plt.legend()
    34 plt.grid(True)
    35 plt.show()
    36
    37 # Print detailed average retention results
    38 print("\nDetailed Average Retention Results:")
    39 for result in overall_recall_results:
    40 precision_name = result.get("precision_name", "unknown")
    41 print(f"\n{precision_name} Embedding:")
    42 for k in sorted(result["average_retention"].keys()):
    43 print(f"\nTop-K: {k}")
    44 for nc in sorted(result["average_retention"][k].keys()):
    45 ret = result["average_retention"][k][nc]
    46 print(f" NumCandidates: {nc}, Retention: {ret:.4f}")

    El código devuelve los gráficos de retención para lo siguiente:

    Para las incrustaciones float32_ann, scalar y binary, el código también devuelve resultados de retención promedio detallados similares a los siguientes:

    Detailed Average Retention Results:
    _float32_ann Embedding:
    Top-K: 5
    NumCandidates: 25, Retention: 1.0000
    NumCandidates: 50, Retention: 1.0000
    NumCandidates: 100, Retention: 1.0000
    NumCandidates: 200, Retention: 1.0000
    NumCandidates: 500, Retention: 1.0000
    NumCandidates: 1000, Retention: 1.0000
    NumCandidates: 5000, Retention: 1.0000
    Top-K: 10
    NumCandidates: 25, Retention: 1.0000
    NumCandidates: 50, Retention: 1.0000
    NumCandidates: 100, Retention: 1.0000
    NumCandidates: 200, Retention: 1.0000
    NumCandidates: 500, Retention: 1.0000
    NumCandidates: 1000, Retention: 1.0000
    NumCandidates: 5000, Retention: 1.0000
    Top-K: 50
    NumCandidates: 50, Retention: 0.8125
    NumCandidates: 100, Retention: 0.8750
    NumCandidates: 200, Retention: 0.8750
    NumCandidates: 500, Retention: 1.0000
    NumCandidates: 1000, Retention: 1.0000
    NumCandidates: 5000, Retention: 1.0000
    Top-K: 100
    NumCandidates: 100, Retention: 0.7586
    NumCandidates: 200, Retention: 0.7241
    NumCandidates: 500, Retention: 0.9655
    NumCandidates: 1000, Retention: 0.9655
    NumCandidates: 5000, Retention: 1.0000
    _scalar_ Embedding:
    Top-K: 5
    NumCandidates: 25, Retention: 0.2500
    NumCandidates: 50, Retention: 0.5000
    NumCandidates: 100, Retention: 0.7500
    NumCandidates: 200, Retention: 1.0000
    NumCandidates: 500, Retention: 1.0000
    NumCandidates: 1000, Retention: 1.0000
    NumCandidates: 5000, Retention: 1.0000
    Top-K: 10
    NumCandidates: 25, Retention: 0.4000
    NumCandidates: 50, Retention: 0.6000
    NumCandidates: 100, Retention: 0.8000
    NumCandidates: 200, Retention: 1.0000
    NumCandidates: 500, Retention: 1.0000
    NumCandidates: 1000, Retention: 1.0000
    NumCandidates: 5000, Retention: 1.0000
    Top-K: 50
    NumCandidates: 50, Retention: 0.7500
    NumCandidates: 100, Retention: 0.8125
    NumCandidates: 200, Retention: 0.8750
    NumCandidates: 500, Retention: 0.9375
    NumCandidates: 1000, Retention: 0.9375
    NumCandidates: 5000, Retention: 1.0000
    Top-K: 100
    NumCandidates: 100, Retention: 0.8276
    NumCandidates: 200, Retention: 0.8276
    NumCandidates: 500, Retention: 0.8621
    NumCandidates: 1000, Retention: 0.8966
    NumCandidates: 5000, Retention: 0.9310
    _binary_ Embedding:
    Top-K: 5
    NumCandidates: 25, Retention: 0.2500
    NumCandidates: 50, Retention: 0.2500
    NumCandidates: 100, Retention: 0.7500
    NumCandidates: 200, Retention: 0.7500
    NumCandidates: 500, Retention: 1.0000
    NumCandidates: 1000, Retention: 1.0000
    NumCandidates: 5000, Retention: 1.0000
    Top-K: 10
    NumCandidates: 25, Retention: 0.2000
    NumCandidates: 50, Retention: 0.2000
    NumCandidates: 100, Retention: 0.8000
    NumCandidates: 200, Retention: 0.8000
    NumCandidates: 500, Retention: 1.0000
    NumCandidates: 1000, Retention: 1.0000
    NumCandidates: 5000, Retention: 1.0000
    Top-K: 50
    NumCandidates: 50, Retention: 0.2500
    NumCandidates: 100, Retention: 0.5625
    NumCandidates: 200, Retention: 0.6250
    NumCandidates: 500, Retention: 0.7500
    NumCandidates: 1000, Retention: 0.8125
    NumCandidates: 5000, Retention: 1.0000
    Top-K: 100
    NumCandidates: 100, Retention: 0.4483
    NumCandidates: 200, Retention: 0.5517
    NumCandidates: 500, Retention: 0.7586
    NumCandidates: 1000, Retention: 0.8621
    NumCandidates: 5000, Retention: 1.0000

    Los resultados de la recuperación demuestran patrones de rendimiento distintos en los tres tipos de incrustación.

    La cuantificación escalar muestra una mejora constante, lo que indica una alta precisión de recuperación a valores K más altos. La cuantificación binaria, si bien comienza con valores más bajos, mejora en Top-K 50 y 100, lo que sugiere un equilibrio entre la eficiencia computacional y el rendimiento de recuperación. Las incrustaciones float32 muestran el mejor rendimiento inicial y alcanzan la misma recuperación máxima que la cuantificación escalar en Top-K 50 y 100.

    Esto sugiere que, si bien float32 proporciona una mejor recuperación con valores Top-K más bajos, la cuantificación escalar puede lograr un rendimiento equivalente con valores Top-K más altos, a la vez que ofrece una mayor eficiencia computacional. La cuantificación binaria, a pesar de su menor límite de recuperación, podría ser útil en escenarios donde las limitaciones de memoria y computacionales superan la necesidad de una precisión de recuperación máxima.

Volver

Cuantificación vectorial