<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[Sachin Frayne - Elasticsearch Labs]]></title>
    <description><![CDATA[Articles and tutorials from the Search team at Elastic]]></description>
    <copyright><![CDATA[© 2026. Elasticsearch B.V. All Rights Reserved]]></copyright>
    <image>
      <title><![CDATA[Sachin Frayne - Elasticsearch Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1121c0bf0e8a6e65/6a88da6340a1841030ef456f/search-labs-thumbnail.png</url>
      <link>https://www.elastic.co/es/search-labs/author/sachin-frayne</link>
    </image>
    <link>https://www.elastic.co/es/search-labs/author/sachin-frayne</link>
    <atom:link href="https://www.elastic.co/es/search-labs/rss/author/sachin-frayne.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[es]]></language>
    <lastBuildDate>Tue, 15 Sep 2026 05:45:30 GMT</lastBuildDate>
  <item>
    <title><![CDATA[La búsqueda de vectores de Elasticsearch es hasta 8 veces más rápida que OpenSearch]]></title>
    <description><![CDATA[Exploramos los puntos de referencia de búsqueda vectorial con filtrado entre OpenSearch y Elasticsearch, y por qué el rendimiento de la búsqueda vectorial es crucial para los sistemas diseñados en función del contexto.]]></description>
    <content:encoded><![CDATA[<h2>¿Por qué es importante la velocidad de búsqueda para los agentes de IA y la ingeniería de contexto?</h2><p>Nuestros benchmarks en un corpus de documentos de 20M muestran que Elasticsearch ofrece hasta 8 veces más rendimiento que OpenSearch para búsqueda vectorial filtrada, además de lograr mayores Recall@100 en las configuraciones que probamos. La ingeniería de contexto depende de más que la rápida recuperación de vectores. Los equipos también necesitan fuertes controles de relevancia, como búsqueda y filtrado híbridos, simplicidad operativa y rendimiento predecible, a medida que los flujos de trabajo se repiten. Pero como los agentes suelen ejecutar bucles de recuperación y razonamiento muchas veces por cada solicitud, la latencia de la recuperación se convierte en un factor multiplicador, por lo que las mejoras en este aspecto se traducen directamente en una mejor capacidad de respuesta de extremo a extremo y en un menor costo.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9daec868eed84658/6a170bef6234e0c322db1a19/d5a52a07773f0942c2baa732dacfe782aac0f415-1600x683.png" alt="OpenSearch vs. Elasticsearch: prueba de rendimiento para la búsqueda vectorial filtrada" /><p>En la ingeniería de contexto, la recuperación no es un paso único. Los agentes y las aplicaciones ejecutan bucles repetidamente, como recuperar → razonar → recuperar, para refinar consultas, verificar hechos, reunir contexto fundamentado y completar tareas. Este patrón es común en los flujos de trabajo agénticos y en la Retrieval-Augmented Generation (RAG) iterativa. Como la recuperación puede invocarse muchas veces por cada consulta del usuario, agrega demora a la respuesta o aumenta los costos de infraestructura.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt718c72fb858e4c98/6a170bf00e2e496e7241a132/54ac476ff20a3cf93484298c9ae47612c12fc110-800x417.png" alt="La ingeniería de contexto convierte un gran grupo de contexto en una ventana de contexto limitada del LLM." /><h2>¿Por qué es crítico el rendimiento de la búsqueda de vectores?</h2><p></p><p>Imagina un asistente de compras respondiendo la pregunta: "Necesito una mochila de equipaje de mano de menos de $60 que quepa una laptop de 15 pulgadas, sea resistente al agua y pueda llegar para el viernes".</p><p>En producción, el asistente rara vez emite una consulta vectorial y se detiene ahí. Ejecuta un ciclo de recuperación para crear el contexto correcto, y cada paso suele estar limitado por filtros, como disponibilidad, región, promesa de envío, reglas de marca y elegibilidad de políticas.</p><p><strong>Paso 1: Interpretar la intención y traducirla a restricciones.</strong></p><p>El agente convierte la solicitud en filtros estructurados y una consulta semántica, tales como:</p><ul><li><p>Filtros: En stock, entregable al código postal del usuario, entrega antes del viernes, precio inferior a $60, listado válido</p></li><li><p>Consulta vectorial: "Mochila de equipaje de mano computadora portátil de 15 pulgadas resistente al agua"</p></li></ul><p><strong>Paso 2: Recuperar candidatos y luego refinar la selección.</strong></p><p>A menudo repite la recuperación con variaciones para evitar perder buenas coincidencias:</p><ul><li><p>"mochila de viaje de equipaje de mano con funda para computadora portátil"</p></li><li><p>"mochila de viaje resistente al agua de 15 pulgadas"</p></li><li><p>“mochila de cabina ligera”</p></li></ul><p>Cada consulta utiliza los mismos filtros de elegibilidad, porque recuperar elementos irrelevantes o no disponibles es un desperdicio de contexto.</p><p><strong>Paso 3: Expandir para confirmar detalles y reducir el riesgo.</strong></p><p>A continuación, el agente vuelve a consultar para verificar los atributos clave que influyen en la respuesta final:</p><ul><li><p>Palabras utilizadas para describir los materiales y la resistencia al agua</p></li><li><p>Dimensiones y ajuste del compartimento de la computadora portátil</p></li><li><p>Restricciones de la garantía o política de devolución</p></li><li><p>Opciones alternativas si hay poco inventario</p></li></ul><p>Esto es ingeniería de contexto en múltiples pasos: recuperar, razonar, recuperar, ensamblar.</p><h2>¿Por qué la latencia y la recuperación son importantes para la ingeniería de contexto?</h2><p>Estas interacciones pueden implicar decenas de llamadas de recuperación filtradas por sesión de usuario. Eso hace que la latencia por llamada sea un multiplicador directo en el tiempo de respuesta de extremo a extremo, y la baja recuperación obliga a reintentos adicionales o hace que el agente pierda elementos elegibles, lo que degrada la calidad de la respuesta.</p><p>Conclusión: En sistemas diseñados con contexto, los vecinos más cercanos aproximados (ANN, por su sigla en inglés) filtrados no son una sola consulta. Es una operación repetida bajo restricciones, por lo que el rendimiento de la búsqueda vectorial se nota enseguida en la latencia, la capacidad de procesamiento y el costo, incluso cuando el modelo de lenguaje grande (LLM) es el componente más visible.</p><h2>Evaluación comparativa</h2><h3>Resultados</h3><p>En el grafo 2, cada punto representa una configuración de prueba. Los mejores resultados aparecen hacia la parte superior izquierda, lo que significa una mayor recuperación con menor latencia. Los resultados de Elasticsearch se sitúan sistemáticamente más cerca de la esquina superior izquierda que los de OpenSearch, lo que indica una mayor velocidad y precisión con los mismos ajustes de carga de trabajo.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb562b30a600cc8e1/6a170bf2cf4f253582b2d1b2/c50d1df00968cac18149a2799e6242fbe49b66a0-1600x990.png" alt=" Grafo 2: Recuperación versus latencia promedio (recalificación 1)." /><h4>Algunas ideas clave</h4><ul><li><p><code>s_n_r_value</code>: La abreviatura de <code>size_numCandidates_rescoreOversample</code> (k y numCandidates iguales a numCandidates en estas pruebas), por ejemplo, <code>100_500_1</code> significa tamaño=100, numCandidates=500 y k=500, rescore oversample=1</p></li><li><p>Recuperación: Mide Recall@100 para esa configuración</p></li><li><p>Latencia promedio (ms): Latencia de extremo a extremo promedio por consulta</p></li><li><p>Rendimiento: Búsquedas por segundo</p></li><li><p>Recall %: Mejora relativa de recuperación de Elasticsearch frente a OpenSearch (Elasticsearch menos OpenSearch)/OpenSearch</p></li><li><p>Latencia Xs: Latencia promedio de OpenSearch dividida por la latencia media de Elasticsearch</p></li><li><p>Rendimiento Xs: rendimiento de Elasticsearch dividido por el rendimiento de OpenSearch</p></li></ul><p>Motor</p><p>'s_n_r_value'</p><p>Recuperación</p><p>Latencia promedio (ms)</p><p>Rendimiento</p><p>Porcentaje de recuperación</p><p>Latencia Xs</p><p>Rendimiento Xs</p><p>Elasticsearch</p><p>100_250_1</p><p>0.7704</p><p>25</p><p>534.75</p><p>9.70 %</p><p>2.28</p><p>1.91</p><p>OpenSearch</p><p>100_250_1</p><p>0.7023</p><p>57.08</p><p>279.58</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_500_1</p><p>0.8577</p><p>25.42</p><p>524.14</p><p>7.20 %</p><p>2.4</p><p>2</p><p>OpenSearch</p><p>100_500_1</p><p>0.8001</p><p>60.9</p><p>262.12</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_750_1</p><p>0.8947</p><p>29.67</p><p>528.09</p><p>5.72 %</p><p>2.25</p><p>2.21</p><p>OpenSearch</p><p>100_750_1</p><p>0.8463</p><p>66.76</p><p>239.11</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_1000_1</p><p>0.9156</p><p>29.65</p><p>534.5</p><p>4.66 %</p><p>2.46</p><p>2.44</p><p>OpenSearch</p><p>100_1000_1</p><p>0.8748</p><p>72.88</p><p>219.01</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_1500_1</p><p>0.9386</p><p>31.84</p><p>497.3</p><p>3.38 %</p><p>2.71</p><p>2.68</p><p>OpenSearch</p><p>100_1500_1</p><p>0.9079</p><p>86.16</p><p>185.4</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_2000_1</p><p>0,9507</p><p>34.69</p><p>457.2</p><p>2.57 %</p><p>2.98</p><p>2.96</p><p>OpenSearch</p><p>100_2000_1</p><p>0.9269</p><p>103.36</p><p>154.55</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_2500_1</p><p>0.9582</p><p>37.9</p><p>418.43</p><p>1.99 %</p><p>3.28</p><p>3.26</p><p>OpenSearch</p><p>100_2500_1</p><p>0.9395</p><p>124.29</p><p>128.53</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_3000_1</p><p>0.9636</p><p>41.86</p><p>379.4</p><p>1.62 %</p><p>3.46</p><p>3.44</p><p>OpenSearch</p><p>100_3000_1</p><p>0.9482</p><p>144.67</p><p>110.34</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_4000_1</p><p>0.9705</p><p>50.28</p><p>316.21</p><p>1,06%</p><p>3.87</p><p>3.85</p><p>OpenSearch</p><p>100_4000_1</p><p>0.9603</p><p>194.36</p><p>82.22</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_5000_1</p><p>0.9749</p><p>58.77</p><p>270.91</p><p>0.73 %</p><p>4.43</p><p>4.41</p><p>OpenSearch</p><p>100_5000_1</p><p>0.9678</p><p>260.33</p><p>61.38</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_6000_1</p><p>0.9781</p><p>66.75</p><p>238.59</p><p>0.52 %</p><p>4.91</p><p>4.89</p><p>OpenSearch</p><p>100_6000_1</p><p>0.973</p><p>327.44</p><p>48.81</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_7000_1</p><p>0.9804</p><p>74.64</p><p>213.49</p><p>0.38 %</p><p>5.28</p><p>5.27</p><p>OpenSearch</p><p>100_7000_1</p><p>0.9767</p><p>394.24</p><p>40.53</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_8000_1</p><p>0.9823</p><p>82.28</p><p>193.59</p><p>0.27 %</p><p>6.86</p><p>6.83</p><p>OpenSearch</p><p>100_8000_1</p><p>0.9797</p><p>564.14</p><p>28.33</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_9000_1</p><p>0.9837</p><p>90.08</p><p>176.96</p><p>0.16 %</p><p>7.63</p><p>7.61</p><p>OpenSearch</p><p>100_9000_1</p><p>0.9821</p><p>687.25</p><p>23.25</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_10000_1</p><p>0.9848</p><p>97.64</p><p>163.31</p><p>0.08 %</p><p>8.38</p><p>8.36</p><p>OpenSearch</p><p>100_10000_1</p><p>0.984</p><p>818.64</p><p>19.53</p><p></p><p></p><p></p><p>Por ejemplo, en <code>100_9000_1</code>, OpenSearch tiene un promedio de 687 milisegundos por recuperación frente a 90 milisegundos en Elasticsearch, y en un bucle de recuperación de 10 pasos eso equivale a aproximadamente 10 × (687 - 90) = seis segundos de tiempo de espera adicional. </p><p>Consulta los <a href="https://github.com/elastic/competitive-benchmarking-studies/tree/main/es-9.3-vs-os-3.5-vector-search/jingra/results/20260220">resultados completos</a>.</p><h3>Metodología</h3><p>Al usar Python para enviar las consultas y rastrear el tiempo de respuesta y otras estadísticas, enviamos las siguientes consultas a los motores. Ten en cuenta que el rendimiento de cualquier motor de búsqueda vectorial depende de cómo ajustes sus parámetros núcleo: cuántos candidatos considerar, cuán agresivamente volver a puntuar y cuánto contexto devolver. Estos ajustes afectan directamente tanto la exhaustividad (la probabilidad de encontrar la respuesta correcta) como la latencia (la rapidez con la que obtienes los resultados).</p><p>En nuestras pruebas comparativas, empleamos la misma configuración de candidatos, repuntuación y tamaño de resultados que normalmente ajustarías en un bucle de recuperación basado en agentes, y medimos el rendimiento de Elasticsearch bajo esa carga de trabajo. Luego ejecutamos OpenSearch con la misma configuración como referencia.</p><p>OpenSearch</p>GET &lt;INDEX_NAME&gt;/_search
{
  "query": {
    "knn": {
      "&lt;DENSE_VECTOR_FIELD_NAME&gt;": {
        "vector": [...],
        "k": &lt;NUMBER_OF_CANDIDATES&gt;,
        "method_parameters": {
          "ef_search": &lt;NUMBER_OF_CANDIDATES&gt;
        },
        "rescore": {
          "oversample_factor": &lt;OVERSAMPLE&gt;
        },
        "filter": {
          &lt;SOME_FILTER&gt;
        }
      }
    }
  },
  "size": &lt;RESULT_SIZE&gt;,
  "_source": {
    "excludes": [
      "&lt;DENSE_VECTOR_FIELD_NAME&gt;"
    ]
  }
}<ul><li><p><code>"size": &lt;RESULT_SIZE&gt;</code>: Número de resultados devueltos al cliente. En esta prueba de rendimiento, el tamaño del conjunto de datos es 100 para calcular el Recall@100.</p></li><li><p><code>"k": &lt;NUMBER_OF_CANDIDATES&gt;</code>: El número de candidatos a vecinos más cercanos.</p></li><li><p><code>"ef_search": &lt;NUMBER_OF_CANDIDATES&gt;</code>: El número de vectores a examinar.</p></li><li><p><code>"oversample_factor": &lt;OVERSAMPLE&gt;</code>: ¿Cuántos vectores candidatos se recuperan antes de volver a calcular la puntuación?</p></li></ul><p>Elasticsearch</p>GET &lt;INDEX_NAME&gt;/_search
{
  "query": {
    "knn": {
      "field": "&lt;DENSE_VECTOR_FIELD_NAME&gt;",
      "query_vector": [...],
      "k": &lt;NUMBER_OF_CANDIDATES&gt;,
      "num_candidates": &lt;NUMBER_OF_CANDIDATES&gt;,
      "rescore_vector": {
        "oversample": &lt;OVERSAMPLE&gt;
      },
      "filter": {
        &lt;SOME_FILTER&gt;
      }
    }
  },
  "size": &lt;RESULT_SIZE&gt;,
  "_source": {
    "excludes": [
      "&lt;DENSE_VECTOR_FIELD_NAME&gt;"
    ]
  }
}<ul><li><p><code>"size": &lt;RESULT_SIZE&gt;</code>: Número de resultados devueltos al cliente. En esta prueba de rendimiento, el tamaño del conjunto de datos es 100 para calcular el Recall@100.</p></li><li><p><code>"k": &lt;NUMBER_OF_CANDIDATES&gt;</code>: Número de vecinos más cercanos que se debe devolver desde cada shard.</p></li><li><p><code>"num_candidates": &lt;NUMBER_OF_CANDIDATES&gt;</code>: Número de candidatos de vecinos más cercanos a considerar por shard mientras se realiza la búsqueda de <code>knn</code>.</p></li><li><p><code>"oversample": &lt;OVERSAMPLE&gt;</code>: ¿Cuántos vectores candidatos se recuperan antes de volver a calcular la puntuación?</p></li></ul><p>Ejemplo</p><p><code>Knn</code> la búsqueda, (<code>100_500_1</code>), sería de la siguiente manera:</p><p>OpenSearch</p>GET search_catalog_128/_search
{
  "query": {
    "knn": {
      "search_catalog_embedding": {
        "vector": [...],
        "k": 500,
        "method_parameters": {
          "ef_search": 500
        },
        "rescore": {
          "oversample_factor": 1
        },
        "filter": {
          "term": {
            "valid": true
          }
        }
      }
    }
  },
  "size": 100,
  "_source": {
    "excludes": [
      "search_catalog_embedding"
    ]
  }
}<p>Elasticsearch</p>GET search_catalog_128/_search
{
  "query": {
    "knn": {
      "field": "search_catalog_embedding",
      "query_vector": [...],
      "k": 500,
      "num_candidates": 500,
      "rescore_vector": {
        "oversample": 1
      },
      "filter": {
        "term": {
          "valid": true
        }
      }
    }
  },
  "size": 100,
  "_source": {
    "excludes": [
      "search_catalog_embedding"
    ]
  }
}<p>La configuración completa, junto con scripts de Terraform, manifiestos de Kubernetes y el código de benchmarking, está disponible en este <a href="https://github.com/elastic/competitive-benchmarking-studies">repositorio</a> en la carpeta <a href="https://github.com/elastic/competitive-benchmarking-studies/tree/main/es-9.3-vs-os-3.5-vector-search">es-9.3-vs-os-3.5-vector-search</a>.</p><h3>La configuración del cluster</h3><p>Ejecutamos nuestras pruebas en seis servidores cloud e2-standard-16, cada uno con 16 vCPUs y 64 GB de RAM. En cada servidor, asignamos 15 vCPUs y 56 GB de RAM a cada pod de Kubernetes que ejecutaba el nodo del motor de búsqueda, con 28 GB reservados para el heap de JVM.</p><p>Los clústeres ejecutaban Elasticsearch 9.3.0 y OpenSearch 3.5.0 (Lucene 10.3.2). Dado que ambos sistemas emplean la misma versión de Lucene en esta prueba comparativa, las diferencias de rendimiento y latencia que observamos no pueden atribuirse únicamente a Lucene, sino que reflejan diferencias en la forma en que cada motor integra y ejecuta la recuperación y recalculación filtradas del algoritmo k-vecinos más cercanos (kNN). Usamos un único índice con tres shards primarios y una réplica (es decir, 6 shards en total, 1 por nodo).</p><p>También usamos un servidor independiente en la misma región para ejecutar el cliente de pruebas de rendimiento y recopilar estadísticas de tiempos.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7c7bdd567395d5b7/6a170bf3c1e8a56ee2f882f6/f81002c9186e4c2d3e92f49d72418fee9860fc5e-761x401.png" alt="Configuración del clúster para las pruebas de rendimiento de Elasticsearch y OpenSearch" /><h3>El set de datos</h3><p></p><p>Para este benchmark, empleamos un set de datos de incrustación de catálogos de tipo comercio electrónico a gran escala con 20 millones de documentos, diseñado para reflejar la recuperación vectorial filtrada a escala del mundo real.</p><p></p><p>Cada documento representa un artículo del catálogo e incluye:</p><p></p><ul><li><p>Un vector denso incrustado de 128 dimensiones utilizado para la recuperación aproximada de kNN.</p></li><li><p>Campos estructurados de metadatos usados para filtrar (por ejemplo, validez y disponibilidad de artículos más otras restricciones del catálogo) que permiten el patrón común de producción de recuperar a los vecinos más cercanos, pero solo dentro de un subconjunto elegible.</p></li></ul><p></p><p>Elegimos este set de datos porque captura el núcleo del desafío principal de rendimiento que vemos en sistemas agentes y de estilo RAG en producción: la similitud vectorial por sí sola no es suficiente, la recuperación está frecuentemente limitada por filtros y el sistema debe mantener una alta recuperación a la vez que mantiene baja la latencia bajo esas restricciones. En comparación con sets de datos más pequeños de estilo QA, un corpus de 20M de documentos también refleja mejor la escala y la presión de los candidatos que enfrentan los sistemas de ANN filtrados en la práctica.</p><h2>Conclusión</h2><p>En las arquitecturas de IA modernas, especialmente aquellas construidas alrededor de la ingeniería de contexto, la velocidad de búsqueda vectorial no es un detalle de implementación menor. Es un multiplicador. Cuando los agentes y los flujos de trabajo iteran a través de recuperar → razonar → recuperar, el rendimiento de la recuperación da forma directamente a la latencia de extremo a extremo, al rendimiento y a la calidad del contexto que se introduce en el modelo.</p><p>En nuestras pruebas de referencia, Elasticsearch ofreció consistentemente una mayor recuperación con menor latencia que OpenSearch en escenarios donde la corrección depende de recuperar el documento correcto, no solo de un vector similar. En un set de datos controlado, la diferencia es clara, y en producción esos avances se acumulan a lo largo de grandes volúmenes de llamadas de recuperación, lo que mejora la capacidad de respuesta, aumenta el margen de capacidad y reduce los costos de infraestructura.</p><h3>Lecturas adicionales</h3><ol><li><p><a href="https://www.elastic.co/search-labs/blog/context-engineering-overview">¿Qué es la ingeniería de contexto?</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/series/context-engineering-hybrid-search-evolution">La evolución de la búsqueda híbrida y la ingeniería de contexto</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/context-engineering-relevance-ai-agents-elasticsearch">El impacto de la relevancia en la ingeniería de contexto para agentes de IA</a></p></li></ol>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/opensearch-vs-elasticsearch-filtered-vector-search</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/opensearch-vs-elasticsearch-filtered-vector-search</guid>
    <category><![CDATA[Base de datos vectorial]]></category>
    <dc:creator><![CDATA[Sachin Frayne]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4b38e5114bbf098c/6a170bf560084b3a6c3c459d/fb7ee623925ca6696d643e437ce8efe5fe749079-1280x720.png" length="0" type="image/png"/>
    <pubDate>Wed, 25 Feb 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Cómo implementar una Mejor Cuantización Binaria (BBQ) en tu caso de uso]]></title>
    <description><![CDATA[Explora por qué implementarías Better Binary Quantization (BBQ) en tu caso de uso y cómo hacerlo.]]></description>
    <content:encoded><![CDATA[<p>La búsqueda vectorial proporciona la base al implementar la búsqueda semántica de texto o la búsqueda de similitud de imágenes, videos o audio. Con la búsqueda vectorial, los vectores son representaciones matemáticas de datos que pueden ser enormes y, a veces, lentos. Better Binary Quantization (en lo sucesivo, BBQ) funciona como un método de compresión para vectores. Le permite encontrar las coincidencias correctas mientras reduce los vectores para que sean más rápidos de buscar y procesar. Este artículo cubrirá BBQ y rescore_vector, un campo solo disponible para índices cuantificados que vuelve a calificar automáticamente los vectores.</p><p>Todas las consultas y salidas completas mencionadas en este artículo se pueden encontrar en nuestro <a href="https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/how-and-why-bbq">repositorio de código de Elasticsearch Labs</a>.</p><h2>¿Por qué implementar Better Binary Quantization (BBQ) en tu caso de uso?</h2>Nota: para una comprensión profunda de cómo funcionan las matemáticas detrás del asado, consulte la <a href="https://www.elastic.co/es/search-labs/blog/bbq-implementation-into-use-case#further-learning">sección "Aprendizaje adicional"</a> a continuación. Para los propósitos de este blog, la atención se centra en la implementación.<p>Aunque las matemáticas son interesantes, son cruciales si quieres comprender completamente por qué tus búsquedas vectoriales siguen siendo precisas. En última instancia, todo esto se reduce a la compresión, ya que resulta que con los algoritmos actuales de búsqueda vectorial estás limitado por la velocidad de lectura de los datos. Por lo tanto, si puedes meter todos esos datos en la memoria, obtienes un aumento significativo de velocidad en comparación con leer desde el almacenamiento (<a href="https://sre.google/static/pdf/rule-of-thumb-latency-numbers-letter.pdf">la memoria es aproximadamente 200 veces más rápida que los SSD</a>).</p><p>Hay algunas cosas a tener en cuenta:</p><ul><li><p>Los índices basados en gráficos como <a href="https://arxiv.org/pdf/1603.09320">HNSW</a> (Hierarchical Navigable Small World) son los más rápidos para la recuperación de vectores.</p><ul><li><p>HNSW: Un algoritmo de búsqueda aproximado del vecino más cercano que construye una estructura de gráficos multicapa para permitir búsquedas eficientes de similitud de alta dimensión.</p></li></ul></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt760bd95c206bfa8f/6a17e2ad505ac393f7ad8a95/590f3b3c72a76023a38a0436cd9ff90a9f80e936-1964x1262.png" alt="HNSW: Un algoritmo de búsqueda aproximado del vecino más cercano que construye una estructura de gráficos multicapa para permitir búsquedas eficientes de similitud de alta dimensión." /><ul><li><p>HNSW está fundamentalmente limitado en velocidad por la velocidad de lectura de datos de la memoria o, en el peor de los casos, del almacenamiento.</p><ul><li><p>Idealmente, desea poder cargar todos sus vectores almacenados en la memoria.</p></li></ul></li><li><p>Los modelos de incrustación generalmente producen vectores con precisión float32, 4 bytes por número de punto flotante.</p></li><li><p>Y finalmente, dependiendo de cuántos vectores y / o dimensiones tenga, puede quedar sin memoria muy rápidamente para mantener todos sus vectores.</p></li></ul><p>Dando esto por sentado, ve que surge un problema rápidamente una vez que comienza a ingerir millones o incluso miles de millones de vectores, cada uno con potencialmente cientos o incluso miles de dimensiones. La sección titulada "<a href="https://www.elastic.co/es/search-labs/blog/bbq-implementation-into-use-case#approximate-numbers-on-the-compression-ratios">Números aproximados en las relaciones de compresión</a>" proporciona algunos números aproximados.</p><h2>¿Qué necesitas para empezar?</h2><p>Para comenzar, necesitará lo siguiente:</p><ul><li><p>Si usas Elastic Cloud o en las instalaciones, necesitarás una versión de Elasticsearch superior a la 8.18. Si bien BBQ se introdujo en 8.16, en este artículo, usará <code>vector_rescore</code>, que se introdujo en 8.18.</p></li><li><p>Además, también deberá cerciorar de que haya un <a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/8.18/ml-settings.html">nodo de aprendizaje automático (ML)</a> en el clúster. (Nota: se necesita un nodo de ML con un mínimo de 4 GB para cargar el modelo, pero es probable que necesite nodos mucho más grandes para cargas de trabajo de producción completas).</p></li><li><p>Si emplea Serverless, deberá seleccionar una instancia optimizada para vectores.</p></li><li><p>También necesitará un nivel básico de conocimiento sobre bases de datos vectoriales. Si aún no estás familiarizado con los conceptos de búsqueda vectorial en Elastic, es posible que desees consultar primero los siguientes recursos:</p><ul><li><p><a href="https://www.elastic.co/es/search-labs/blog/elastic-vector-database-practical-example">Navegación por una base de datos vectorial elástica</a></p></li><li><p><a href="https://www.elastic.co/es/blog/retrieval-augmented-generation-explained">Las grandes ideas detrás de la generación aumentada de recuperación</a></p></li></ul></li></ul><h2>Mejor implementación de cuantización binaria (BBQ)</h2><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt18df00df95ff2ca7/6a17e2af414c6411989450df/4d388078495566f0527e931e0c2e38facdce83c6-1503x748.png" alt="Implementación de asado con Elasticsearch." /><p>Para simplificar este blog, empleará funciones integradas cuando estén disponibles. En este caso, tienes el modelo de incrustación de vectores <a href="https://www.elastic.co/es/guide/en/machine-learning/8.17/ml-nlp-e5.html"><code>.multilingual-e5-small</code></a> que se ejecutará directamente dentro de Elasticsearch en un nodo de aprendizaje automático. Tenga en cuenta que puede reemplazar el modelo <code>text_embedding</code> con el incrustador de su elección (<a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/8.18/infer-service-openai.html">OpenAI,</a> <a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/8.18/infer-service-google-ai-studio.html">Google AI Studio</a>, <a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/8.18/infer-service-cohere.html">Cohere</a> y muchos más). Si su modelo preferido aún no está integrado, también puede <a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/8.18/bring-your-own-vectors.html">traer sus propias incrustaciones de vectores densos</a>).</p><p>En primer lugar, deberá crear un punto de enlace de inferencia para generar vectores para un fragmento de texto determinado. Ejecutarás todos estos comandos desde la <a href="https://www.elastic.co/es/guide/en/kibana/8.18/console-kibana.html">consola de herramientas de desarrollo de Kibana</a>. Este comando descargará el <code>.multilingual-e5-small</code>. Si aún no existe, configurará su punto final; Esto puede tardar un minuto en ejecutar. Puede ver la salida esperada en el <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/01-create-an-inference-endpoint-output.json">archivo 01-create-an-inference-endpoint-output.json</a> en la carpeta Salidas. </p>PUT _inference/text_embedding/my_e5_model
{
  "service": "elasticsearch",
  "service_settings": {
    "num_threads": 1,
    "model_id": ".multilingual-e5-small",
    "adaptive_allocations": {
      "enabled": true,
      "min_number_of_allocations": 1
    }
  }
}<p>Una vez que esto regresó, su modelo se configurará y podrá probar que el modelo funciona como se espera con el siguiente comando. Puede ver el resultado esperado en el <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/02-embed-text-output.json">archivo 02-embed-text-output.json</a> en la carpeta Salidas.</p>POST _inference/text_embedding/my_e5_model
{
  "input": "my awesome piece of text"
}<p>Si tiene problemas relacionados con el modelo capacitado que no se asigna a ningún nodo, es posible que deba iniciar el modelo manualmente.</p>POST _ml/trained_models/.multilingual-e5-small/deployment/_start<p>Ahora vamos a crear una nueva asignación con 2 propiedades, un campo de texto estándar (<code>my_field</code>) y un campo vectorial denso (<code>my_vector</code>) con 384 dimensiones para que coincida con la salida del modelo de incrustación. También anulará el <code>index_options.type to bbq_hnsw</code>. Puede ver el resultado esperado en el <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/03-create-byte-qauntized-index-output.json">archivo 03-create-byte-qauntized-index-output.json</a> en la carpeta Salidas.</p>PUT bbq-my-byte-quantized-index
{
  "mappings": {
    "properties": {
      "my_field": {
        "type": "text"
      },
      "my_vector": {
        "type": "dense_vector",
        "dims": 384,
        "index_options": {
          "type": "bbq_hnsw"
        }
      }
    }
  }
}<p>Para cerciorarte de que Elasticsearch genere tus vectores, puedes usar una <a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/8.18/ingest.html">canalización de ingesta</a>. Esta canalización requerirá 3 cosas: el punto final, (<code>model_id</code>), el <code>input_field</code> para el que desea crear vectores y el <code>output_field</code> en el que almacenar esos vectores. El primer comando siguiente creará una canalización de ingesta de inferencia, que usa el <a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/current/inference-apis.html">servicio de inferencia </a>en segundo plano, y el segundo probará que la canalización funciona correctamente. Puede ver la salida esperada en el <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/04-create-and-simulate-ingest-pipeline-output.json">archivo 04-create-and-simulate-ingest-pipeline-output.json</a> en la carpeta Salidas. </p>PUT _ingest/pipeline/my_inference_pipeline
{
  "processors": [
    {
      "inference": {
        "model_id": "my_e5_model",
        "input_output": [
          {
            "input_field": "my_field",
            "output_field": "my_vector"
          }
        ]
      }
    }
  ]
}

POST _ingest/pipeline/my_inference_pipeline/_simulate
{
  "docs": [
    {
      "_source": {
        "my_field": "my awesome text field"
      }
    }
  ]
}<p>Ahora está listo para agregar algunos documentos con los primeros 2 comandos a continuación y para probar que sus búsquedas funcionan con el 3er comando. Puede desproteger el resultado esperado en el <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/05-bbq-index-output.json">archivo 05-bbq-index-output.json</a> en la carpeta Salidas. </p>PUT bbq-my-byte-quantized-index/_doc/1?pipeline=my_inference_pipeline
{
    "my_field": "my awesome text field"
}

PUT bbq-my-byte-quantized-index/_doc/2?pipeline=my_inference_pipeline
{
    "my_field": "some other sentence"
}

GET bbq-my-byte-quantized-index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "knn": {
            "field": "my_vector",
            "query_vector_builder": {
              "text_embedding": {
                "model_id": "my_e5_model",
                "model_text": "my awesome search field"
              }
            },
            "k": 10,
            "num_candidates": 100
          }
        }
      ]
    }
  },
  "_source": [
    "my_field"
  ]
}<p>Como se recomienda en <a href="https://www.elastic.co/es/search-labs/blog/better-binary-quantization-lucene-elasticsearch#lucene-benchmarking">esta publicación</a>, se recomienda volver a puntuar y sobremuestrear cuando se escala a cantidades no triviales de datos porque ayudan a mantener una alta precisión de recuperación mientras se benefician de los beneficios de la compresión. A partir de la versión 8.18 de Elasticsearch, puedes hacerlo de esta manera usando <a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/8.18/knn-search.html#dense-vector-knn-search-rescoring">rescore_vector</a>. La salida esperada se encuentra en el <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/06-bbq-search-8-18-output.json">archivo 06-bbq-search-8-18-output.json</a> en la carpeta Outputs.</p>GET bbq-my-byte-quantized-index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "knn": {
            "field": "my_vector",
            "query_vector_builder": {
              "text_embedding": {
                "model_id": "my_e5_model",
                "model_text": "my awesome search field"
              }
            },
            "rescore_vector": {
              "oversample": 3
            },
            "k": 10,
            "num_candidates": 100
          }
        }
      ]
    }
  },
  "_source": [
    "my_field"
  ]
}<p>¿Cómo se comparan estos puntajes con los que obtendría por los datos sin procesar? Si vuelves a hacer todo lo anterior pero con <code>index_options.type: hnsw</code>, verás que los puntajes son muy comparables. Puede ver el resultado esperado en el <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/07-raw-vector-output.json">archivo 07-raw-vector-output.json</a> en la carpeta Salidas.</p>PUT my-raw-vector-index
{
  "mappings": {
    "properties": {
      "my_field": {
        "type": "text"
      },
      "my_vector": {
        "type": "dense_vector",
        "dims": 384,
        "index_options": {
          "type": "hnsw"
        }
      }
    }
  }
}

PUT my-raw-vector-index/_doc/1?pipeline=my_inference_pipeline
{
    "my_field": "my awesome text field"
}

PUT my-raw-vector-index/_doc/2?pipeline=my_inference_pipeline
{
    "my_field": "some other sentence"
}

GET my-raw-vector-index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "knn": {
            "field": "my_vector",
            "query_vector_builder": {
              "text_embedding": {
                "model_id": "my_e5_model",
                "model_text": "my awesome search field"
              }
            },
            "k": 10,
            "num_candidates": 100
          }
        }
      ]
    }
  },
  "_source": [
    "my_field"
  ]
}<h2>Números aproximados en las relaciones de compresión</h2><p>Los requisitos de almacenamiento y memoria pueden convertir rápidamente en un desafío importante cuando se trabaja con la búsqueda vectorial. El siguiente desglose ilustra cómo las diferentes técnicas de cuantificación reducen significativamente la huella de memoria de los datos vectoriales.</p><p>Vectores (V)</p><p>Dimensiones (D)</p><p>sin procesar (V x P x 4)</p><p>int8 (V x (D x 1 + 4))</p><p>int4 (V x (D x 0.5 + 4))</p><p>asado (V x (D x 0.125 + 4))</p><p>10,000,000</p><p>384</p><p>14,31 GB</p><p>3,61 GB</p><p>1,83 GB</p><p>0,58 GB</p><p>50,000,000</p><p>384</p><p>71,53 GB</p><p>18,07 GB</p><p>9,13 GB</p><p>2,89 GB</p><p>100,000,000</p><p>384</p><p>143,05 GB</p><p>36,14 GB</p><p>18,25 GB</p><p>5,77 GB</p><h2>Conclusión</h2><p>BBQ es una optimización que puede aplicar a sus datos vectoriales para la compresión sin sacrificar la precisión. Funciona convirtiendo vectores en bits, lo que le permite buscar los datos de manera efectiva y le permite escalar sus flujos de trabajo de IA para acelerar las búsquedas y optimizar el almacenamiento de datos.</p><h2>Aprendizaje adicional</h2><p>Si está interesado en obtener más información sobre el asado, cerciorar de consultar los siguientes recursos:</p><ul><li><p><a href="https://www.elastic.co/es/search-labs/blog/better-binary-quantization-lucene-elasticsearch">Cuantificación binaria (BBQ) en Lucene y Elasticsearch</a></p></li><li><p><a href="https://www.elastic.co/es/search-labs/blog/bit-vectors-elasticsearch-bbq-vs-pq">Mejor cuantización binaria (BBQ) frente a cuantificación de productos</a></p></li><li><p><a href="https://www.elastic.co/es/search-labs/blog/optimized-scalar-quantization-elasticsearch">Cuantización escalar optimizada: cuantificación binaria aún mejor</a></p></li><li><p><a href="https://www.youtube.com/watch?v=04NzMt2Nigc">Mejor cuantificación binaria (BBQ): De bytes a BBQ, el secreto para una mejor búsqueda vectorial por Ben Trent</a></p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/bbq-implementation-into-use-case</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/bbq-implementation-into-use-case</guid>
    <category><![CDATA[Base de datos vectorial]]></category>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Sachin Frayne,Jessica Garson]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3dd0495b536b2615/6a17e2b0414c6488459450e3/66842055367cdd795532b01c167f2a4b03dc65e3-1200x628.png" length="0" type="image/png"/>
    <pubDate>Wed, 23 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>