<?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[Chris Hegarty - 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[Chris Hegarty - 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/chris-hegarty</link>
    </image>
    <link>https://www.elastic.co/es/search-labs/author/chris-hegarty</link>
    <atom:link href="https://www.elastic.co/es/search-labs/rss/author/chris-hegarty.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[es]]></language>
    <lastBuildDate>Mon, 21 Sep 2026 03:49:31 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Cómo creamos Elasticsearch simdvec para hacer una de las búsquedas vectoriales más rápidas del mundo]]></title>
    <description><![CDATA[Cómo construimos Elasticsearch SIMDvec, la biblioteca del kernel SIMD ajustada a mano detrás de cada consulta de búsqueda vectorial en Elasticsearch.]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch simdvec es el motor detrás de cada cálculo de distancia vectorial en Elasticsearch. Proporciona kerneles AVX-512 y NEON ajustados manualmente para cada tipo de vector que admite Elasticsearch. Su arquitectura de scoring masivo oculta la latencia de memoria mediante la precarga de datos explícita en x86 y las cargas intercaladas en ARM, por lo que muestra un rendimiento hasta 4 veces mayor que bibliotecas como FAISS y jvector cuando los datos exceden la caché de la CPU. En esta publicación, explicamos por qué lo creamos, qué contiene y cómo hace que la búsqueda vectorial de Elasticsearch sea una de las más rápidas del mundo.</p><h2>Cómo construimos Elasticsearch SIMDvec</h2><p>Cada consulta de búsqueda vectorial en Elasticsearch, ya sea un recorrido de <a href="https://arxiv.org/abs/1603.09320">mundo pequeño jerárquico navegable (HNSW)</a>, un escaneo de archivo invertido (IVF) o una pasada de reclasificación, se reduce al mismo problema: calcular distancias entre vectores, millones de veces por búsqueda. Elasticsearch admite una amplia gama de tipos de datos y estrategias de cuantificación, desde float32 hasta int8, bfloat16, binario y Mejor cuantificación binaria (BBQ). Cada una tiene distintas compensaciones entre memoria, rendimiento y recuperación. Detrás de todo esto hay un único motor: simdvec.</p><p>Creamos simdvec para que cada cálculo de distancia sea tan rápido como el hardware lo permita. En esta publicación, explicamos por qué lo creamos, qué contiene y dónde produce el mayor impacto.</p><h3>Creado como un auto de carreras</h3><p>Como aficionados a la Fórmula 1, y dado que uno de nosotros trabajó anteriormente con el equipo Ferrari de Fórmula 1, vemos un claro paralelismo. Un auto de Fórmula 1 está diseñado con un solo propósito: lograr el mejor tiempo de vuelta. La potencia del motor, la aerodinámica y el diseño del chasis solo importan en la medida en que contribuyen a ese resultado. Lo mismo ocurre con una base de datos vectorial, donde el rendimiento de indexación, la latencia de búsqueda y la recuperación definen el éxito.</p><p>Aunque lo que importa es el resultado final, para alcanzar los máximos niveles de rendimiento es necesario que cada componente funcione a la perfección. No puede ser solo <em>lo suficientemente bueno</em>, tiene que ser <em>el mejor </em>en su categoría. Simdvec está construido con esa mentalidad, que se enfoca en una parte fundamental del sistema: el motor. Es una biblioteca de kernel optimizada para <a href="https://en.wikipedia.org/wiki/Single_instruction,_multiple_data">una sola instrucción y múltiples datos</a> (SIMD) diseñada específicamente, que proporciona funciones nativas de distancia en C++ ajustadas a mano, llamadas desde Java a través de la interfaz para funciones externas (FFI) de <a href="https://openjdk.org/projects/panama/">Panamá</a>. Admite evaluación masiva, precarga de líneas de caché y todos los tipos de vectores y diseños utilizados en Elasticsearch.</p><p>Ese es el motor que hay detrás de cada búsqueda.</p><h3>Por qué creamos nuestro propio motor</h3><p>Comenzamos en 2023 con la API Panama Vector en Apache Lucene. Funcionaba bien para productos punto float32, pero las necesidades de Elasticsearch superaron rápidamente lo que podía ofrecer. Elasticsearch admite una amplia gama de tipos de vectores cuantificados: int8, int4, bfloat16, de un solo bit y BBQ asimétrico. Cada uno tiene diferentes estrategias SIMD, diseños de empaquetado y requisitos de acumulador. Más allá de la cobertura de tipos, las rutas de puntuación de Elasticsearch exigen algo más que un rendimiento de un solo par: HNSW necesita puntuar varios vecinos del grafo en una sola pasada, IVF necesita puntuar en masa miles de candidatos con precarga y la puntuación basada en disco debe funcionar directamente en la memoria mapeada con mmap sin necesidad de copiar. Examinamos lo que estaba disponible y nada abarcaba el conjunto completo.</p><p>Así que construimos simdvec: kerneles C++ nativos ajustados a mano llamados desde Java a través de FFI, con puntuación masiva, precarga y soporte para cada tipo de vector que usa Elasticsearch. Al ser propietarios de la biblioteca, controlamos el stack completo. Cuando añadimos un nuevo tipo de cuantificación, como BBQ, se le asigna un kernel SIMD optimizado que se integra en todo el sistema. No esperamos a que una biblioteca upstream le de soporte y no comprometemos el rendimiento para ningún tipo. Cada consulta vectorial en Elasticsearch, ya sea HNSW, IVF, reranking o híbrida, se ejecuta en este motor, construido en torno a las operaciones y los tipos que realmente usamos.</p><p>Simdvec tiene bibliotecas nativas separadas para x86 y ARM, cada una con múltiples niveles de arquitectura de conjunto de instrucciones (ISA) seleccionados al inicio. La sobrecarga de llamadas desde Java vía FFI es muy baja, con <a href="https://github.com/ldematte/simsimd-benchmarks/blob/main/COMPARISON.md#ffm-downcall-overhead-measurements">nanosegundos de un solo dígito</a>.</p><h3>El panorama</h3><p>No somos los únicos que construimos kerneles de distancia vectorial optimizados para SIMD. El ecosistema es rico y queríamos comprender cómo se desempeña simdvec. No para clasificar proyectos, sino para proporcionar contexto y explicar dónde se encuentra el motor de Elasticsearch. Seleccionamos tres proyectos como puntos de referencia, cada uno representando un enfoque diferente:</p><ul><li><p><strong>jvector:</strong> Una biblioteca de Java de vecino más cercano aproximado (ANN) que emplea la API Panama Vector para el cálculo vectorizado de distancias, con aceleración nativa en C opcional en x86.</p></li><li><p><strong>FAISS:</strong> Un marco de trabajo de búsqueda vectorial de open source ampliamente desplegado, con kerneles AVX2/AVX-512 ajustados a mano.</p></li><li><p><strong>NumKong</strong> (anteriormente SimSIMD): un conjunto completo de más de 2 000 kerneles SIMD ajustados a mano que abarcan funciones de distancia, operaciones matrices y computación geoespacial.</p></li></ul><p>Cada proyecto cumple un propósito diferente y realiza diferentes concesiones. Incluimos números de referencia de ellos para dar contexto al rendimiento de simdvec en las operaciones específicas que Elasticsearch necesita.</p><h3>Cómo medimos</h3><p>Las evaluaciones de simdvec y <a href="https://github.com/ChrisHegarty/jvector-kernel-benchmarks">jvector</a> están escritos en Java con JMH, la microevaluación estándar de JVM, lo que incluye la sobrecarga de FFI. Para <a href="https://github.com/ldematte/simsimd-benchmarks">las evaluaciones de NumKong</a> y <a href="https://github.com/ChrisHegarty/faiss-kernel-benchmarks">las evaluaciones de FAISS</a>, escribimos pequeños marcos de prueba de C/C++ con Google Benchmark, que es el marco de trabajo estándar para microevaluaciones de C++. Ambos marcos de trabajo reportan nanosegundos por operación con calibración de calentamiento e iteración. Verificamos mediante contadores de rendimiento de hardware que todas las bibliotecas usan SIMD en ambas plataformas. Todo el código de evaluación está disponible públicamente en los repositorios enlazados de GitHub (y, en el caso de simdvec, en el repositorio <a href="https://github.com/elastic/elasticsearch">elasticsearch</a>).</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt90a7d66553be3c9d/6a1701d166c4f942caf8bea5/aee116772df161cf86b7668f575ac34c733a23c5-1580x238.png" alt="Tabla en la que se enumeran dos plataformas: x86 con AMD EPYC Turin (Zen 5), AVX2 y AVX-512, AWS c8a.4xlarge; y ARM con Graviton 4 (Neoverse V2), NEON y SVE2, AWS c8g.4xlarge." /><p><strong>Software:</strong> JDK 25.0.2, JMH 1.37, GCC 14, Google Benchmark (última versión).</p><h2>Un vector a la vez</h2><p>La operación más básica en la búsqueda vectorial es calcular la distancia entre dos vectores. Cada evaluación de un vecino de HNSW, cada puntaje de un candidato a IVF, cada comparación de reclasificación se reduce a este bucle interno.</p><p>Medimos el rendimiento de un solo par en 1024 dimensiones en ambas plataformas, empezando por float32, el tipo base y el donde el ecosistema es más competitivo. Comparamos simdvec con FAISS y jvector; hemos excluido NumKong porque utiliza acumuladores float64 para float32, lo que lo hace entre 3,2 y 5,3 veces más lento (dependiendo de la plataforma), ya que prioriza la precisión numérica por encima del rendimiento. Para mantener la comparación de igual a igual, evaluamos NumKong en int8 en su lugar, donde utiliza la misma estrategia de acumulador que simdvec.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte3bc2ecaf3ad2b61/6a1701d2ab7f08039ddb9d0f/352cfa0fc18f123140f746d843404f80127fb1b7-1500x675.png" alt="Gráfico de barras horizontal titulado “Float32 Dot Product — AMD Turin” que compara cinco implementaciones: FAISS AVX‑512 a 23,2 ns/op, ES simdvec AVX‑512 a 28,3 ns/op, FAISS AVX2 a 36,4 ns/op, ES simdvec AVX2 a 38,9 ns/op y jvector a 43,9 ns/op." /><p>En la arquitectura x86, FAISS AVX-512 es el kernel de par único más rápido, con un tiempo de ejecución de 23 ns. A continuación, se ejecuta Simdvec AVX-512 a los 28 ns, un intervalo que refleja la sobrecarga de la llamada FFI. Ambos emplean FMA de 512 bits con desenrollado de múltiples acumuladores. A nivel AVX2, los dos valores son mucho más similares, 36 ns y 39 ns respectivamente, ambos limitados por el ancho de carga de memoria y registro de 256 bits. jvector tarda 44 ns usando la API de Java Panama Vector. Panamá genera buen código SIMD, pero las funciones intrínsecas de C++ ajustadas manualmente siguen teniendo ventaja.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcbbbe442631a575d/6a1701d42b835f81bcf4b083/95e44d9767f21ec4bccaed835e3c99aa180431ee-1500x495.png" alt="Gráfico de barras horizontal llamado “float32 Dot Product — Graviton 4 (ARM)” que muestra ES simdvec en 70.2 ns/op, jvector en 110.0 ns/op y FAISS en 155.6 ns/op." /><p>En ARM, simdvec lidera a 70 ns, muy por delante de jvector a 110 ns y FAISS a 156 ns. Simdvec tiene kernels NEON ajustados a mano para aarch64. Jvector no tiene código ARM nativo y depende de Panama. FAISS se basa en la auto-vectorización del compilador en lugar de en las intrínsecas NEON explícitas, lo que explica la mayor brecha. Esto refleja una ventaja práctica de poseer la biblioteca del kernel: cuando Elasticsearch se expandió a Graviton, agregamos kerneles NEON especialmente diseñados. Ni jvector ni FAISS priorizaron el código nativo de ARM en la misma medida.</p><p>Sin embargo, Elasticsearch no solo puntúa float32. La cuantificación <strong>Int8</strong> reduce la memoria en 4x, bfloat16 en 2x y BBQ en 32x. Cada tipo necesita su propia estrategia SIMD, y simdvec proporciona kernels nativos ajustados a mano para todos ellos.</p><p>De todas las bibliotecas que comparamos, solo NumKong tiene kernels comparables para int8. Medimos el producto escalar int8, la distancia euclidiana al cuadrado y el coseno en 1024 dimensiones.</p><p><strong>Puntuación de par único Int8 (1024 dimensiones, ns/vec op — cuanto más bajo, mejor)</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3ac255d158e93504/6a1701d5a292997e48d00eb1/a0b852fd5f51d57bd2488886600472ee65ab64da-1594x378.png" alt="Tabla que compara el rendimiento de x86 y ARM en el producto punto, distancia euclidiana al cuadrado y similitud del coseno; muestra los valores de ES, NumKong y diff para cada operación en ambas arquitecturas." /><p>En ambas arquitecturas, NumKong es igual o más rápido en dimensiones pequeñas y medias, donde la diferencia se debe en gran parte a una menor sobrecarga de llamadas (llamada C directa vs FFI en Java). En dimensiones mayores, simdvec se pone al día, donde la implementación más eficiente del kernel (que emplea desenrollamiento en cascada) amortiza el costo de llamada: a medida que aumenta la dimensión, <a href="https://github.com/ldematte/simsimd-benchmarks/blob/main/COMPARISON.md#single-pair-i8-nsop-2">esta brecha se cierra y finalmente se revierte</a>. El cruce está en dimensiones entre 768 y 1536, dependiendo de la función y la arquitectura.</p><p>A pesar de la sobrecarga ligeramente mayor de Java FFI, simdvec está a la par con las bibliotecas altamente optimizadas de C/C++. No solo es la única librería con kernels optimizados tanto para float32 <em>como para </em> int8, sino que también lidera en ARM y solo está ligeramente por detrás de FAISS en x86 (para float32), y muy cerca de NumKong en ambas arquitecturas (para int8). Y en el caso de bfloat16, int4, binary y BBQ, aunque existen alternativas, simdvec se distingue por su SIMD ajustado manualmente y adaptado a la estructura de datos de cada tipo.</p><p>Pero un motor de búsqueda en producción no califica un vector a la vez; califica miles por consulta. La siguiente pregunta es qué sucede a esa escala.</p><h3>Miles a la vez</h3><p>El rendimiento de un solo par es solo una parte del panorama. Lo que importa en la práctica es cómo se comportan los sistemas bajo carga. Una sola consulta HNSW puede puntuar cientos de vecinos de grafos. Un escaneo de IVF puede puntuar miles de entradas en la lista de publicaciones. Un paso de reclasificación puede puntuar decenas de miles de candidatos. El rendimiento por par individual es importante, pero lo que más importa es la rapidez con la que puedes puntuar muchos vectores, y cómo se degrada el rendimiento de forma gradual a medida que el conjunto de trabajo se desborda de las cachés de la CPU.</p><p>Simdvec proporciona evaluación masiva para todos los tipos de datos. No son solo bucles sobre kernels de un solo par; usan bucles internos de varios acumuladores que cargan el vector de búsqueda una vez por paso de dimensión y lo comparten entre varios vectores de documentos, con precarga explícita de líneas de caché para el siguiente batch. Ni jvector ni FAISS ofrecen un equivalente (en el momento de redacción de esta publicación). Jvector no tiene una API de bulk, así que quien llama puntúa un par a la vez en un bucle. FAISS expone <code>fvec_inner_products_ny</code> que, en el momento de redacción de esta publicación, está implementado como un bucle sobre su función de distancia de un solo par, sin amortización de la búsqueda ni precarga.</p><p><strong>Float32.</strong> Para medir el impacto a nivel del kernel, puntuamos una sola consulta contra un número creciente de vectores de documentos float32 de 1024 dimensiones con patrones de acceso aleatorio que simulan búsquedas de vecinos de grafos dispersos similares a HNSW. Los tres tamaños de sets de datos, 32, 625 y 32 500 vectores, se eligen para que el conjunto de trabajo supere la caché L1, L2 y L3, respectivamente.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2df64ec77a1921ae/6a1701d714b270393ae3c4de/1d90267be1c63ac82b8ba588617ebedb0be0d1b6-1334x558.png" alt="Dos gráficos de barras que comparan los tiempos de puntuaciones en producto escalar de Float32 en masa para Elasticsearch simdvec, FAISS y jvector en AMD Turin (x86, AVX-512) y Graviton 4 (ARM, NEON) en tres tamaños: 32 vectores, 625 vectores y 32 500 vectores." /><p>Cuando los datos caben en la caché, simdvec es el más rápido en ambas plataformas, pero las diferencias son modestas, ya que predomina la aritmética del kernel. La separación real se nota cuando el conjunto de trabajo supera el tamaño de L3. En x86, simdvec alcanza los 95 ns por vector, mientras que FAISS necesita 165 ns y jvector 412 ns. En ARM, la tendencia es la misma: simdvec se mantiene en 162 ns, mientras que FAISS sube a 347 ns y jvector a 476 ns. La precarga y la amortización de búsquedas en simdvec mantienen la latencia de memoria oculta de una manera que un bucle simple sobre kerneles de par único no puede coincidir y el beneficio se amplía precisamente donde operan las cargas de búsqueda reales, en lo profundo de la memoria principal.</p><p><strong>Int8.</strong> Lo mismo ocurre con los tipos cuantificados. Medimos el rendimiento del cálculo del producto escalar int8 en 1024 dimensiones con sets de datos de un tamaño tal que superaran los límites de las cachés L1, L2 y L3, en comparación con el cálculo en bloque de simdvec con el cálculo de pares individuales de NumKong en un bucle.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcda85e10007188d0/6a1701d9cf4f25d722b2cff7/9ee97d98b40d13b19370b76b33e67ea66bfb3250-1580x338.png" alt=" Tabla llamada &quot;x86 — puntuación masiva, producto punto int8 (ns/op, menor es mejor)&quot; que compara ES simdvec y NumKong en tres tamaños de vector: 128, 2 500 y 130 000, con los valores correspondientes de ns/op y las proporciones de aceleración." /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt972c311b7d08ba73/6a1701dadc55dec02ee00c87/601f50a03fa3e6263cbac9700281dfe3e511de60-1580x338.png" alt="Tabla llamada “ARM — Puntuación masiva, producto punto int8 (ns/op, menor es mejor)” comparación de ES simdvec y NumKong a través de tres tamaños de vector—128, 2 500 y 130 000—con los valores correspondientes de ns/op y las ratios de aceleración" /><p>En x86, simdvec es entre 1,2 y 1,9 veces más rápido, impulsado por la combinación de precarga explícita y procesamiento por lotes. En ARM, simdvec gana de nuevo (1,7 a 1,9 veces más rápido) en todos los tamaños de sets de datos. La ventaja radica en el procesamiento por lotes de cuatro vectores a la vez, lo que proporciona paralelismo a nivel de memoria mediante un patrón de acceso intercalado. En ambos casos, el resultado más llamativo es lo que ocurre en el mayor tamaño de set de datos, donde más importa.</p><p>Los resultados para la distancia al cuadrado y el coseno muestran un patrón similar, con aceleraciones de 1,4 a 1,8 veces para ARM, y de 1,3 a 3,0 veces para x86 (detalles <a href="https://github.com/ldematte/simsimd-benchmarks/blob/main/COMPARISON.md">aquí</a>).</p><h3>Cuando la memoria importa</h3><p>Los índices de vectores de producción normalmente no caben en la caché de la CPU. Un índice de 10M-vectores int8 a 1024 dimensiones es de 10 GB. La evaluación de candidatos implica el procesamiento en flujo continuo de datos desde la DRAM y ahí es donde la arquitectura de evaluación masiva marca la diferencia.</p><p>Usamos contadores de rendimiento de hardware para medir lo que sucede dentro de la CPU durante la puntuación masiva y descubrimos que ocultar la latencia de la memoria requiere dos estrategias fundamentalmente diferentes, una por arquitectura.</p><p><strong>En x86, la precarga explícita elimina los fallos de caché. </strong>El kernel masivo procesa los vectores secuencialmente, uno completamente calculado antes del siguiente, mientras emite instrucciones de precarga para el siguiente batch. Los datos futuros se cargan en la L1 antes de que la CPU los necesite.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt368f29b5143d0f5a/6a1701dcc1e8a51780f8817b/a39548f8060c2a4a5154521a4047dd92d8cd77be-1580x309.png" alt="Tabla titulada «x86 (AMD Turín) — contadores de hardware por operación int8» comparando modos individuales y masivos para fallos de caché L1, IPC y fallos de dTLB, con los factores de mejora correspondientes." /><p>En ARM, el mismo enfoque secuencial tuvo un rendimiento deficiente, incluso con precarga. En cambio, <strong>el kernel masivo entrelaza las cargas</strong> de cuatro vectores en cada posición de zancada, lo que proporciona al motor fuera de orden cuatro flujos de memoria independientes. La CPU no recoge datos más rápido, sino que espera menos al tener siempre algo más que calcular mientras las solicitudes de memoria están en curso. Puedes encontrar un análisis detallado en <a href="https://github.com/elastic/elasticsearch/issues/145412">este ticket de GitHub</a>.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8751ac5b20b75508/6a1701deab7f08db83db9d13/832de3bc0d556a493b7bf3f250196018acfc1585-1580x238.png" alt="Tabla llamada “ARM (Graviton 4): contadores de hardware por operación int8” que compara los modos individual y masivo para los errores de caché L1 y los bloqueos de backend, con las notas de mejora correspondientes" /><p>Los números cuentan dos historias diferentes:</p><ol><li><p>En x86, la precarga convierte 139K fallos de caché en 19K y las instrucciones por ciclo (IPC) se duplican más de dos veces. La ventaja de masa crece con el tamaño de los sets de datos, de 1,2 veces en L2 a 2,8 veces más allá de L3, porque la precarga oculta progresivamente viajes de ida y vuelta de DRAM más costosos.</p></li><li><p>En ARM, los fallos de caché apenas cambian. Lo que cambia es la utilización: las interrupciones del backend disminuyen un 40 % porque el patrón de acceso intercalado mantiene el pipeline alimentado. Esta ventaja se mantiene en un consistente 1,8 veces independientemente del tamaño del sets de datos, porque el paralelismo a nivel de memoria se aplica tanto si los datos provienen de la caché como de la DRAM.</p></li></ol><p>Dos arquitecturas, dos estrategias y un resultado: a escala de producción, simdvec mantiene la pipeline de la CPU ocupada incluso cuando los vectores están dispersos por la memoria principal.</p><h2>Qué significa esto para los usuarios de Elasticsearch</h2><p>Estas capacidades a nivel de kernel se potencian entre sí. Una única consulta de búsqueda vectorial puede calcular millones de operaciones de distancia: recorrido del grafo HNSW, puntuación de candidatos, reclasificación. En miles de búsquedas concurrentes, los nanosegundos por operación se traducen directamente en latencia de búsqueda y rendimiento del cluster. Tanto si usas float32, int8, bfloat16 o BBQ, tanto si tu índice está en la memoria como en el disco, simdvec es el motor subyacente, y cada una de esas operaciones pasa por el mismo motor, lo que optimiza hasta el último nanosegundo.</p><p>La conclusión clave es que, a escala de producción, el rendimiento de la búsqueda vectorial no está determinado principalmente por el rendimiento bruto de SIMD. Lo que marca la diferencia es la eficiencia con la que el sistema oculta la latencia de la memoria mientras mantiene el rendimiento computacional en millones de operaciones pequeñas.</p><p>Los kerneles de simdvec mejoran prácticamente con cada versión de Elasticsearch. Cuando surgen nuevos tipos de cuantización y plataformas de hardware, reciben kerneles ajustados desde el primer día. Y los tipos existentes siguen ganando velocidad a medida que perfeccionamos las implementaciones que ya están disponibles.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-vector-search-simdvec-engine</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-vector-search-simdvec-engine</guid>
    <category><![CDATA[Base de datos vectorial]]></category>
    <category><![CDATA[Dentro de Elastic]]></category>
    <dc:creator><![CDATA[Chris Hegarty,Lorenzo Dematte,Simon Cooper]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta18088409621369b/6a1701dfdc55de7297e00c8b/df9646091bafbbf0a6dfd212ff8a6bd1e8589708-1280x720.png" length="0" type="image/png"/>
    <pubDate>Thu, 23 Apr 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Estadísticas ES|QL más rápidas con tablas hash de estilo suizo]]></title>
    <description><![CDATA[Cómo el hashing inspirado en Suiza y el diseño compatible con SIMD ofrecen mejoras consistentes y medibles en el lenguaje de búsqueda de Elasticsearch (ES|QL).]]></description>
    <content:encoded><![CDATA[<p>Recientemente reemplazamos partes clave de la implementación de tablas hash de Elasticsearch por un diseño de estilo suizo y observamos tiempos de construcción e iteración hasta 2–3 veces más rápidos en cargas de trabajo uniformes y de alta cardinalidad. El resultado es una latencia más baja, un mejor rendimiento y un desempeño más predecible para las operaciones de estadísticas y análisis del lenguaje de búsqueda de Elasticsearch (ES|QL).</p><h2>¿Por qué importa esto?</h2><p>La mayoría de los flujos de trabajo analíticos típicos acaban reduciéndose a agrupar datos. Ya sea para calcular el promedio de bytes por host, contar eventos por usuario o agregar métricas en diferentes dimensiones, la operación de núcleo es la misma: asignar claves a grupos y actualizar los agregados en ejecución.</p><p>A pequeña escala, casi cualquier tabla hash razonable funciona bien. A gran escala (cientos de millones de documentos y millones de grupos distintos), los detalles empiezan a importar. Los factores de carga, la estrategia de sondeo, el diseño de la memoria y el comportamiento de la memoria caché pueden marcar la diferencia entre un rendimiento lineal y una barrera de fallos de caché.</p><p>Elasticsearch ha soportado estas cargas de trabajo durante años, pero siempre estamos buscando oportunidades para modernizar los algoritmos de núcleo. Por lo tanto, evaluamos un enfoque más reciente inspirado en las tablas suizas y lo aplicamos a cómo ES|QL calcula las estadísticas.</p><h2>¿Qué son realmente las tablas suizas?</h2><p>Las tablas suizas son una familia de tablas hash modernas popularizadas por la SwissTable de Google y posteriormente adoptadas en Abseil y otras bibliotecas.</p><p>Las tablas hash tradicionales pasan mucho tiempo persiguiendo punteros o cargando claves solo para descubrir que no coinciden. La característica definitoria de las tablas suizas es la capacidad de rechazar la mayoría de las sondas usando una pequeña estructura de matriz residente en caché, almacenada separadamente de las claves y valores, llamadas <em>bytes de control</em>, para reducir significativamente el tráfico de memoria.</p><p>Cada byte de control representa un solo slot y, en nuestro caso, codifica dos cosas: si el slot está vacío y una huella corta derivada del hash. Estos bytes de control están dispuestos de forma continua en la memoria, típicamente en grupos de 16, lo que los hace ideales para el <a href="https://en.wikipedia.org/wiki/Single_instruction,_multiple_data">procesamiento de una sola instrucción y múltiples datos</a> (SIMD).</p><p>En lugar de sondear una ranura a la vez, las tablas suizas escanean todo un bloque de bytes de control utilizando instrucciones vectoriales. En una sola operación, la CPU compara la huella digital de la clave entrante con 16 ranuras y filtra las entradas vacías. Solo los pocos candidatos que sobreviven a esta ruta rápida requieren cargar y comparar las claves reales.</p><p>Este diseño intercambia una pequeña cantidad de metadatos adicionales por una mejor localización de caché y muchas menos cargas aleatorias. A medida que la tabla crece y las cadenas de sonda se alargan, esas propiedades se vuelven cada vez más valiosas.</p><h2>SIMD en el centro</h2><p>La verdadera estrella del espectáculo es SIMD.</p><p>Los bytes de control no solo son compactos, sino que también están diseñados explícitamente para ser procesados con instrucciones vectoriales. Una sola comparación SIMD puede verificar 16 huellas dactilares a la vez, lo que convierte lo que normalmente sería un bucle en un puñado de operaciones amplias. Por ejemplo:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1f710e87dd749ab3/6a170cc46234e052dadb1a49/bd418778f0c6144f8f5f18419f6220ac0c935c7a-903x407.png" alt="SIMD en el centro de Elasticsearch" /><p>En la práctica, esto significa:</p><ul><li><p>Menos ramas.</p></li><li><p>Cadenas de sondeo más cortas.</p></li><li><p>Menos cargas de la memoria de claves y valores.</p></li><li><p>Mucho mejor utilización de las unidades de ejecución de la CPU.</p></li></ul><p>La mayoría de las búsquedas nunca pasan del escaneo de bytes de control. Cuando lo hacen, el trabajo restante es enfocado y previsible. Este es precisamente el tipo de carga de trabajo en el que destacan las CPU modernas.</p><h2>SIMD bajo el capó</h2><p>Para los lectores a quienes les gusta echar un vistazo por dentro, aquí está lo que sucede al insertar una nueva clave en la tabla. Utilizamos la API Panama Vector con vectores de 128 bits, por lo que opera en 16 bytes de control en paralelo.</p><p>El siguiente fragmento muestra el código generado en un Intel Rocket Lake con AVX-512. Aunque las instrucciones reflejan ese entorno, el diseño no depende de AVX-512. Las mismas operaciones vectoriales de alto nivel se emiten en otras plataformas usando instrucciones equivalentes (por ejemplo, AVX2, SSE o NEON).</p>; Load 16 control bytes from the control block
vmovdqu xmm0, XMMWORD PTR [r9+r10*1+0x10]

; Broadcast the 7-bit fingerprint of the new key across the vector
vpbroadcastb xmm1, r11d

; Compare all 16 control bytes to the new fingerprint
vpcmpeqb k7, xmm0, xmm1
kmovq rbx, k7

; Check if any matches were found
test rbx, rbx
jne &lt;handle_match&gt;<p>Cada instrucción tiene una función clara en el proceso de inserción:</p><ul><li><p><code>vmovdqu</code>: Carga 16 bytes de control consecutivos en el registro <code>xmm0</code> de 128 bits.</p></li><li><p><code>vpbroadcastb</code>:Replica la huella digital de 7 bits de la nueva clave en todos los carriles del registro <code>xmm1</code>.</p></li><li><p><code>vpcmpeqb</code>: Compara cada byte de control con la huella digital transmitida, lo que genera una máscara de posibles coincidencias.</p></li><li><p><code>kmovq</code> + <code>test</code>: Mueve la máscara a un registro de propósito general y comprueba rápidamente si existe una coincidencia.</p></li></ul><p>Finalmente, decidimos sondear grupos de 16 bytes de control a la vez, ya que las pruebas de rendimiento mostraron que expandirse a 32 o 64 bytes con registros más amplios no proporcionaba ningún beneficio de rendimiento medible.</p><h2>Integración en ES|QL</h2><p>Adoptar el hash al estilo suizo en Elasticsearch no fue solo un reemplazo inmediato. ES|QL tiene exigencias estrictas en cuanto a contabilidad de memoria, seguridad e integración con el resto del motor de cálculo.</p><p>Integramos la nueva tabla hash estrechamente con la gestión de memoria de Elasticsearch, que incluye el reciclador de páginas y la contabilidad del interruptor de circuito, lo que garantiza que las asignaciones permanezcan visibles y limitadas. Las agregaciones de Elasticsearch se almacenan densamente y se indexan por un ID de grupo, lo que mantiene el diseño de memoria compacto y rápido para la iteración, además de habilitar ciertas optimizaciones de rendimiento al permitir el acceso aleatorio.</p><p>Para las claves de bytes de longitud variable, almacenamos en caché el hash completo junto con el ID del grupo. Esto evita la recomputación de costosos códigos hash durante el sondeo y mejora la localidad de la caché al mantener los metadatos relacionados juntos. Durante el reprocesamiento, podemos confiar en el hash en caché y en los bytes de control sin inspeccionar los valores en sí, lo que mantiene bajos los costos de redimensionamiento.</p><p>Una simplificación importante en nuestra implementación es que las entradas nunca se eliminan. Esto elimina la necesidad de <em>marcadores</em> (marcadores para identificar ranuras previamente ocupadas) y permite que las ranuras vacías permanezcan verdaderamente vacías, lo que mejora aún más el comportamiento de la sonda y mantiene eficientes los escaneos de bytes de control.</p><p>El resultado es un diseño que se ajusta naturalmente al modelo de ejecución de Elasticsearch a la vez que preserva las características de rendimiento que hacen atractivas a las tablas suizas.</p><h2>¿Cómo funciona?</h2><p>En cardinalidades pequeñas, las tablas suizas rinden aproximadamente al mismo nivel que la implementación existente. Esto es lo que se espera: cuando las tablas son pequeñas, los efectos de la caché tienen menos importancia y hay poco que optimizar.</p><p>A medida que aumenta la cardinalidad, la imagen cambia rápidamente.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt09b13af2fe162f59/6a170cc66f7f04485c9148b8/24900afc47ab07b0e9933f6117b99d0f4613f794-962x599.png" alt="Estadísticas ES|QL con tablas hash de estilo suizo" /><p>El mapa de calor anterior traza los factores de mejora del tiempo para diferentes tamaños de clave (8, 32, 64 y 128 bytes) en cardinalidades desde 1,000 hasta 10,000,000 de grupos. A medida que aumenta la cardinalidad, el factor de mejora aumenta constantemente, y llega a hasta 2–3x para distribuciones uniformes.</p><p>Esta tendencia es exactamente lo que predice el diseño. Una cardinalidad más alta conduce a cadenas de sondeo más largas en las tablas hash tradicionales, mientras que el sondeo de estilo suizo continúa resolviendo la mayoría de las búsquedas dentro de los bloques de bytes de control amigables con SIMD.</p><h2>El comportamiento de la caché cuenta la historia</h2><p>Para comprender mejor las aceleraciones, ejecutamos el mismo JMH <a href="https://github.com/elastic/elasticsearch/pull/139343/files#diff-d0e0cc91a7495bf36b2d44eacce95f5185d01879e5f6c38089ac7a89aad17da7"><code>benchmarks</code></a> en Linux <code>perf</code> y capturamos estadísticas de caché y TLB.</p><p>En comparación con la implementación original, la versión suiza realiza aproximadamente un 60% menos de referencias de caché en general. Las cargas de la caché de último nivel disminuyen más de 4 veces, y los fallos de carga de la LLC caen en más de 6 veces. Dado que las omisiones de LLC a menudo se traducen directamente en accesos a la memoria principal, esta reducción por sí sola explica una gran parte de la mejora de extremo a extremo.</p><p>Más cerca de la CPU, vemos menos pérdidas de caché de datos L1 y casi 6 veces menos pérdidas TLB de datos, lo que apunta a una localidad espacial más estrecha y patrones de acceso a la memoria más predecibles.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb987a5bd98c0d7eb/6a170cc8a929cf9655ae0a25/6e49b7609fba83e33692cb9834552b6ca7e42a83-998x499.png" alt="Comportamiento de la caché: Estadísticas originales frente a ES|QL con tablas hash al estilo suizo" /><p>Esta es la recompensa práctica de los bytes de control compatibles con SIMD. En lugar de cargar repetidamente claves y valores desde ubicaciones de memoria dispersas, la mayoría de las pruebas se resuelven escaneando una estructura compacta residente en la caché. Menos memoria afectada significa menos fallos, y menos fallos significan consultas más rápidas.</p><h2>Resumen</h2><p>Al adoptar un diseño de tabla hash al estilo suizo y al inclinarnos por el sondeo amigable con SIMD, logramos una velocidad de 2 a 3 veces mayor para cargas de trabajo de estadísticas ES|QL de alta cardinalidad, junto con un rendimiento más estable y predecible.</p><p>Este trabajo destaca cómo las estructuras de datos modernas con conocimiento de CPU pueden desbloquear ganancias sustanciales, incluso para problemas bien conocidos, como las tablas hash. Hay más para explorar aquí, como especializaciones adicionales de tipo primitivo y el uso en otras rutas de alta cardinalidad, como las uniones, que son solo parte del esfuerzo más amplio y continuo para modernizar continuamente los internos de Elasticsearch.</p><p>Si te interesan los detalles o quieres seguir el trabajo, echa un vistazo a esta <a href="https://github.com/elastic/elasticsearch/pull/139343">solicitud de extracción</a> y <a href="https://github.com/elastic/elasticsearch/issues/138799">problema meta</a> en Github.</p><p>¡Feliz hash!</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/esql-swiss-hash-stats</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/esql-swiss-hash-stats</guid>
    <category><![CDATA[ES|QL]]></category>
    <dc:creator><![CDATA[Chris Hegarty,Matthew Alp,Nik Everett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf76dd688c5b737e6/6a170cc9839dfa7fc7dcff40/21036e031070f14faccb2b53b22723de2750c391-1280x720.png" length="0" type="image/png"/>
    <pubDate>Mon, 19 Jan 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Indexación vectorial hasta 12 veces más rápida en Elasticsearch con NVIDIA cuVS: aceleración por GPU, capítulo 2]]></title>
    <description><![CDATA[Descubre cómo Elasticsearch logra un rendimiento de indexación casi 12 veces mayor. Esto lo consigue con la indexación vectorial acelerada por GPU y NVIDIA cuVS.]]></description>
    <content:encoded><![CDATA[<p>A principios de este año, Elastic anunció la <a href="https://ir.elastic.co/news/news-details/2025/Elastic-Brings-Enterprise-Data-to-NVIDIA-AI-Factories/default.aspx">colaboración</a> con NVIDIA para llevar la aceleración por GPU a Elasticsearch, integrándola con <a href="https://developer.nvidia.com/cuvs">NVIDIA cuVS</a>, como se detalló en una <a href="https://www.nvidia.com/en-us/on-demand/session/gtc25-S71286/">sesión en NVIDIA GTC</a> y en varios <a href="https://www.elastic.co/search-labs/blog/gpu-accelerated-vector-search-elasticsearch-nvidia">blogs</a>. Esta publicación es una actualización sobre el esfuerzo de co-ingeniería con el equipo de búsqueda de vectores de NVIDIA.</p><h2>Resumen</h2><p>Primero, pongámonos al día. Elasticsearch se consolidó como una poderosa base de datos vectorial, que ofrece un amplio conjunto de características y un sólido rendimiento para la búsqueda de similitudes a gran escala. Con capacidades como la cuantificación escalar, Better Binary Quantization (<a href="https://www.elastic.co/search-labs/blog/better-binary-quantization-lucene-elasticsearch">BBQ</a>), operaciones vectoriales <a href="https://www.elastic.co/blog/accelerating-vector-search-simd-instructions">SIMD</a> y algoritmos más eficientes en disco como <a href="https://www.elastic.co/search-labs/blog/diskbbq-elasticsearch-introduction">DiskBBQ</a>, ya ofrece opciones eficientes y flexibles para gestionar cargas de trabajo vectoriales.</p><p>Al integrar NVIDIA cuVS como un módulo invocable para tareas de búsqueda vectorial, nuestro objetivo es ofrecer beneficios significativos en el rendimiento y la eficiencia de la indexación vectorial para soportar mejor las cargas de trabajo vectoriales a gran escala.</p><h2>El desafío</h2><p>Uno de los mayores desafíos al construir una base de datos vectorial de alto rendimiento es construir el índice vectorial: el grafo <a href="https://arxiv.org/abs/1603.09320">HNSW</a>. La construcción de índices se ve dominada con rapidez por millones o incluso miles de millones de operaciones aritméticas a medida que cada vector se compara con muchos otros. Además, las operaciones del ciclo de vida del índice, como la compactación y las fusiones, pueden aumentar aún más la sobrecarga total de cálculo de la indexación. A medida que los volúmenes de datos y las incrustaciones vectoriales asociadas crecen de manera exponencial, las GPU de cómputo acelerado, diseñadas para el paralelismo masivo y las matemáticas de alto rendimiento, se posicionan idealmente para manejar estas cargas de trabajo.</p><h2>Ingresa al plugin Elasticsearch-GPU</h2><p><a href="https://developer.nvidia.com/cuvs">NVIDIA cuVS</a> es una biblioteca open source de CUDA-X para la búsqueda vectorial acelerada por GPU y la agrupación de datos, que permite una rápida construcción de índices y recuperación de incrustaciones para cargas de trabajo de AI y de sistemas de recomendación.</p><p>Elasticsearch utiliza cuVS a través de <a href="https://mvnrepository.com/artifact/com.nvidia.cuvs/cuvs-java">cuvs-java</a>, una biblioteca open source desarrollada por la comunidad y que mantiene NVIDIA. La biblioteca cuvs-java es ligera, se basa en la <a href="https://docs.rapids.ai/api/cuvs/nightly/c_api/">API C de cuVS</a> y usa la función externa del <a href="https://openjdk.org/projects/panama/">Proyecto Panamá</a> para exponer las características de cuVS de una manera idiomática en Java, al tiempo que es moderna y presenta un alto rendimiento.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc7fd7361099da05a/6a17e920be608670af00477f/5f6daa1eb07f704a6707d9e6b7ccb81d0abaa8c9-566x419.png" alt="Cómo funciona Elasticsearch con NVIDIA cuVS, CPU e indexación con GPU" /><p>La biblioteca cuvs-java está integrada en un <a href="https://github.com/elastic/elasticsearch/pull/135545">nuevo plugin de Elasticsearch</a>; por lo tanto, la indexación vectorial en la GPU puede ocurrir en el mismo nodo y proceso de Elasticsearch, sin la necesidad de provisionar ningún código o hardware externo. Durante la construcción del índice, si se instala la biblioteca cuVS y hay una GPU presente y configurada, Elasticsearch usará la GPU para acelerar el proceso de indexación vectorial. Los vectores se asignan a la GPU, que construye un grafo <a href="https://arxiv.org/abs/2308.15136">CAGRA</a>. Este grafo se convierte entonces al formato HNSW, y hace que esté disponible de inmediato para la búsqueda vectorial en la CPU. El formato final del grafo construido es el mismo que el que se construiría en la CPU; esto permite a Elasticsearch aprovechar las GPU para indexar vectores de alto rendimiento cuando el hardware subyacente lo admite, al tiempo que libera poder de la CPU para otras tareas (búsqueda simultánea, procesamiento de datos, etc.).</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt485f55f29d6df5c4/6a17e922be6086dcf3004785/3ea255bd9bfd7983f78143c5eba999d2149d72be-671x356.png" alt="" /><h2>Aceleración en la generación de índices</h2><p>Como parte de la integración de la aceleración de GPU en Elasticsearch, se realizaron varias mejoras en cuvs-java, centradas en la entrada/salida eficiente de datos y la invocación de funciones. Una mejora clave es el uso de <a href="https://github.com/rapidsai/cuvs/blob/2cf5fa7666d703dccbe655f8214656b0952bb69b/java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java">cuVSMatrix</a> para modelar vectores de forma transparente, ya sea que residan en la memoria heap de Java, fuera de la memoria heap o en la memoria de la GPU. Esto permite que los datos se muevan de manera eficiente entre la memoria y la GPU, lo que evita copias innecesarias de potencialmente miles de millones de vectores.</p><p>Gracias a esta abstracción subyacente de copia cero, tanto la transferencia a la memoria de la GPU como la recuperación del grafo se pueden realizar directamente. Durante la indexación, los vectores se almacenan primero en búfer en la memoria heap de Java, y luego se envían a la GPU para construir el grafo CAGRA. Después, el grafo se recupera de la GPU, se convierte al formato HNSW y se mantiene en el disco.</p><p>En el momento de la fusión, los vectores ya están almacenados en disco, sin pasar por la memoria heap de Java. Los archivos de índice se mapean en memoria, y los datos se transfieren directamente a la memoria de la GPU. El diseño también se adapta fácilmente a diferentes anchos de bits, como float32 o int8, y se extiende de forma natural a otros esquemas de cuantificación.</p><h2>Redoble de tambores… entonces, ¿cómo se funciona?</h2><p>Antes de entrar en los números, un poco de contexto es útil. La fusión de segmentos en Elasticsearch suele ejecutarse automáticamente en segundo plano durante la indexación, lo que dificulta hacer benchmarks de forma aislada. Para obtener resultados reproducibles, utilizamos la fusión forzosa para activar explícitamente la combinación de segmentos en un experimento controlado. Dado que la fusión forzosa hace las mismas operaciones de fusión subyacentes que la fusión en segundo plano, su rendimiento sirve como un indicador útil de las mejoras esperadas, aunque las ganancias exactas pueden diferir en las cargas de trabajo de indexación del mundo real.</p><p>Ahora, veamos los números.</p><p>Nuestros resultados iniciales de evaluaciones comparativas son muy prometedores. Ejecutamos la evaluación comparativa en una instancia de AWS <code>g6.4xlarge</code> con almacenamiento NVMe conectado a nivel local. Se configuró un único nodo de Elasticsearch para que use el número predeterminado y óptimo de subprocesos de indexación (8, uno por cada núcleo físico) y deshabilite <a href="https://www.elastic.co/docs/reference/elasticsearch/index-settings/merge">la limitación de la fusión</a> (que es menos aplicable con discos NVMe rápidos).</p><p>Para el conjunto de datos, utilizamos 2,6 millones de vectores con 1536 dimensiones del <a href="https://github.com/elastic/rally-tracks/blob/master/openai_vector/README.md">vector de pista de Rally de OpenAI</a>, codificados como <a href="https://github.com/elastic/elasticsearch/pull/137072">cadenas de texto base64</a> e indexados como float32 <em>hnsw</em>. En todos los escenarios, los grafos construidos alcanzan niveles de recuperación de hasta el 95 %. A continuación, presentamos nuestros hallazgos:</p><ul><li><p><strong>Rendimiento de indexación:</strong> al trasladar la construcción de grafos a la GPU durante los vaciados de búferes en memoria, aumentamos el rendimiento en aproximadamente 12 veces.</p></li><li><p><strong>Fusión forzada:</strong> una vez que finaliza la indexación, la GPU continúa acelerando la fusión de segmentos, lo que acelera la fase de fusión forzada en alrededor de 7 veces.</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfea4ee13b5a3b10d/6a17e923e9ea879c6aa9c616/f60ea9ee5996e456f393ffd195ee7eada6e5a7c2-948x387.png" alt="" /><ul><li><p><strong>Uso de la CPU:</strong> descargar la construcción de grafos a la GPU reduce de manera significativa el uso promedio y máximo de la CPU. Los grafos a continuación ilustran el uso de la CPU durante la indexación y la fusión, y permiten ver cuánto menor es cuando estas operaciones se ejecutan en la GPU. Un menor uso de la CPU durante la indexación por GPU libera ciclos de CPU que pueden redirigirse para mejorar el rendimiento de la búsqueda.</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt80ff9c53f9b6884a/6a17e925445de9ee4b4d0187/5e680a5fc41700a877f3d8b2e5ce18ebd3f37a0b-1600x562.png" alt="" /><ul><li><p><strong>Recuperación:</strong> la precisión se mantiene prácticamente igual entre las ejecuciones de CPU y GPU, y el grafo construido por la GPU alcanza una recuperación un poco mayor.</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5cbe084eca27b8e4/6a17e926faa913317093c8b7/48a2b7758606bd321712b7d8378cd2640e652a4e-1384x544.png" alt="" /><h2>Comparación en otra dimensión: el precio</h2><p>La comparación anterior utilizaba intencionalmente hardware idéntico, y la única diferencia era si se usaba la GPU durante la indexación o no. Esa configuración es útil para aislar los efectos de la computación en bruto, pero también podemos analizar la comparación desde una perspectiva de costos.</p><p>A un precio horario similar al de la configuración acelerada por GPU, se puede provisionar una configuración de solo CPU con aproximadamente el doble de recursos comparables de CPU y memoria: 32 vCPUs (AMD EPYC) y 64 GB de RAM, lo que permite duplicar el número de hilos de indexación a 16.</p><p>Para mantener la comparación justa y consistente, ejecutamos este experimento solo de CPU en una instancia AWS g6.8xlarge, con la GPU explícitamente desactivada. Esto nos permitió mantener constantes todas las demás características del hardware mientras evaluábamos la compensación entre costo y rendimiento de la aceleración de GPU frente al indexado solo con CPU.</p><p>Como era de esperar, la instancia de CPU más potente sí muestra un mejor rendimiento en comparación con las evaluaciones comparativas de la sección anterior. Sin embargo, cuando comparamos esta instancia de CPU más potente con los resultados acelerados por GPU originales, la GPU aún ofrece beneficios sustanciales en cuanto al rendimiento: <strong>~ 5 veces</strong> de mejora en el rendimiento de indexación y <strong>~ 6 veces </strong>en la fusión forzada, todo ello mientras se construyen grafos que alcanzan niveles de recuperación de hasta un <strong>95 %.</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt94b5eb6f95ba307d/6a17e928abe0f255d4dfea35/8ffa58cae3ad175ef2932a351aeef4c34a1407b9-948x394.png" alt="" /><h2>Conclusión</h2><p>En escenarios completos, la aceleración por GPU con NVIDIA cuVS ofrece una mejora de casi 12 veces en el rendimiento de la indexación y una disminución de 7 veces en la latencia de fusión forzada, con un uso de CPU significativamente menor. Esto demuestra que la indexación vectorial y las cargas de trabajo de fusión se benefician de manera significativa de la aceleración por GPU. En una comparación ajustada por costos, la aceleración por GPU continúa mostrando beneficios sustanciales en cuanto al rendimiento, con alrededor de 5 veces más rendimiento de indexación y 6 veces más rapidez en las operaciones de fusión forzada.</p><p>La indexación vectorial acelerada por GPU tiene planificada hoy en día una vista previa técnica en Elasticsearch 9.3, cuyo lanzamiento está programado para principios de 2026.</p><p>Mantente atento a lo que viene.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-gpu-accelerated-vector-indexing-nvidia</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-gpu-accelerated-vector-indexing-nvidia</guid>
    <category><![CDATA[Base de datos vectorial]]></category>
    <dc:creator><![CDATA[Chris Hegarty,Hemant Malik,Corey Nolet,Manas Singh,Mithun Radhakrishnan,Mayya Sharipova,Lorenzo Dematte,Ben Frederickson]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1248d51633bd75d9/6a17e92ae9ea8714b3a9c61a/08f7469a4daaf67b7c5999585aae179b6680c78d-896x746.png" length="0" type="image/png"/>
    <pubDate>Wed, 03 Dec 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Explorando la búsqueda vectorial acelerada por GPU en Elasticsearch con NVIDIA: Capítulo I]]></title>
    <description><![CDATA[Con tecnología NVIDIA cuVS, la colaboración busca proporcionar a los desarrolladores aceleramiento de GPU para la búsqueda vectorial en Elasticsearch.]]></description>
    <content:encoded><![CDATA[<p>En la organización de Elastic Engineering estuvimos ocupados optimizando el rendimiento de la base de datos vectorial desde hace un tiempo. Nuestra misión: hacer de Lucene y Elasticsearch la mejor base de datos vectorial. A través de <a href="https://www.elastic.co/es/blog/accelerating-vector-search-simd-instructions">instrucciones SIMD de CPU</a> aceleradas por hardware, introduciendo nuevas innovaciones de compresión de datos vectoriales (<a href="https://www.elastic.co/es/search-labs/blog/better-binary-quantization-lucene-elasticsearch">Better Binary Quantization, también conocido como BBQ</a>), y luego superando las expectativas actualizando el enfoque algorítmico de BBQ para obtener aún más beneficios, y también <a href="https://www.elastic.co/es/search-labs/blog/filtered-hnsw-knn-search">haciendo que Filtered HNSW sea más rápido</a>. Entiendes la esencia: estamos construyendo un sistema más rápido, mejor, eficiente (¿más?) para los desarrolladores mientras resuelven esos problemas RAG-gedy!</p><p>Como parte de nuestra misión de no dejar atrás la eficiencia, estamos explorando oportunidades de aceleramiento con estos curiosos chips de computadora, de los que quizás oíste hablar: ¡las GPU NVIDIA! (En serio, ¿no es así?).</p><p>Cuando nos obsesionamos con el rendimiento, tenemos varios espacios problemáticos para explorar: cómo indexar exponencialmente más datos, cómo recuperar información de ellos y cómo hacerlo cuando sus modelos de ML están involucrados. Debería poder obtener hasta el último beneficio disponible cuando tenga GPU.</p><p>En esta publicación, nos sumergimos en nuestra colaboración con el equipo de búsqueda vectorial de NVIDIA mientras exploramos la búsqueda vectorial acelerada por GPU en Elasticsearch. Este trabajo allana el camino para casos de uso en los que los desarrolladores podrían usar una combinación de GPU y CPU para aplicaciones con tecnología de Elasticsearch del mundo real. ¡Tiempos emocionantes!</p><h2>GPU de Elasticsearch</h2><p>Nos complace compartir que el equipo de ingeniería de Elasticsearch está ayudando a crear la experiencia de la API de Java cuVS de código abierto para desarrolladores, que expone enlaces para algoritmos de búsqueda vectorial. Este trabajo aprovecha nuestra experiencia previa con Panama FFI. Elasticsearch y Apache Lucene emplean la API NVIDIA cuVS para crear el gráfico durante la indexación. Bien, estamos saltando hacia adelante; Rebobinemos un poco.</p><p><a href="https://developer.nvidia.com/cuvs">NVIDIA cuVS,</a> una biblioteca de C++ de código abierto, está en el corazón de esta colaboración. Su objetivo es llevar el aceleramiento de GPU a la búsqueda vectorial al proporcionar un mayor rendimiento, menor latencia y tiempos de compilación de índices más rápidos. Pero Elasticsearch y Apache Lucene están escritos en Java; ¿Cómo funcionará esto?</p><p>Ingrese <a href="https://github.com/SearchScale/lucene-cuvs">lucene-cuvs</a> y la colaboración Elastic-NVIDIA-SearchScale para llevarlo al ecosistema de Lucene para explorar la búsqueda vectorial acelerada por GPU en Elasticsearch. En la reciente versión 25.02 de NVIDIA cuVS, agregamos una API de Java para cuVS. La nueva API es experimental y seguirá evolucionando, pero actualmente está disponible para su uso. Puede surgir la pregunta: ¿no son lentas las llamadas de Java a funciones nativas? ¡Ya no! Estamos usando la nueva <a href="https://openjdk.org/projects/panama/">FFI</a> (interfaz de funciones externas) de Panamá para los enlaces, que tiene una sobrecarga mínima para Java a las llamadas descendentes nativas.</p><p>Estuvimos usando <a href="https://www.elastic.co/es/search-labs/blog/lucene-and-java-moving-forward-together">Panama FFI en Elasticsearch y Lucene</a> desde hace un tiempo. ¡Es asombroso! Pero... Siempre hay un "pero", ¿no? FFI tiene desafíos de disponibilidad en todas las versiones de Java. Superamos esto compilando la API de cuVS en Java 21 y encapsulando la implementación dentro de un jar de varias versiones dirigido a Java 22. Esto permite el uso de cuVS Java directamente en Lucene y Elasticsearch.</p><p>Ok, ahora que tenemos la API de Java de cuVS, ¿qué más necesitaríamos?</p><h2>Una historia de dos algoritmos para CPU</h2><p>Elasticsearch admite el <a href="https://arxiv.org/abs/1603.09320">algoritmo HNSW</a> para una búsqueda KNN aproximada escalable. Sin embargo, para sacar el máximo provecho de la GPU, empleamos un algoritmo diferente, <a href="https://arxiv.org/pdf/2308.15136">CAGRA [</a><a href="https://arxiv.org/pdf/2308.15136"><strong>C</strong></a><a href="https://arxiv.org/pdf/2308.15136"><em>UDA</em></a> <a href="https://arxiv.org/pdf/2308.15136"><strong>A</strong></a><a href="https://arxiv.org/pdf/2308.15136"><em>NN</em></a> <a href="https://arxiv.org/pdf/2308.15136"><strong>GRA</strong></a><a href="https://arxiv.org/pdf/2308.15136"><em>ph</em></a><a href="https://arxiv.org/pdf/2308.15136">],</a> que fue diseñado específicamente para los altos niveles de paralelismo que ofrece la GPU.</p><p>Antes de entrar en cómo buscamos agregar soporte para CAGRA, veamos cómo Elasticsearch y Lucene acceden a los datos del índice a través de un "formato de códec". Consiste en</p><ol><li><p>la representación en disco,</p></li><li><p>las interfaces para leer y escribir datos,</p></li><li><p>y la maquinaria para lidiar con la arquitectura basada en segmentos de Lucene.</p></li></ol><p>Estamos implementando un nuevo <a href="https://lucene.apache.org/core/10_1_0/core/org/apache/lucene/codecs/KnnVectorsFormat.html">formato vectorial</a> KNN (k-vecinos más cercanos) que emplea internamente la API de Java de cuVS para indexar y buscar en la GPU. A partir de aquí, "sondeamos" este tipo de códec a través de las asignaciones de Elasticsearch a un tipo de campo en el índice. Como resultado, las consultas KNN existentes siguen funcionando independientemente de si el índice de respaldo emplea un gráfico CAGRA o HNSW. Por supuesto, esto pasa por alto muchos detalles, que planeamos cubrir en un blog futuro. La siguiente es la arquitectura de alto nivel para un Elasticsearch acelerado por GPU.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb6197b631a34f8b6/6a170b0da6c2b9e60ce7970b/be6b7356c03df4dee7230625c2c9af3b019f93be-756x510.png" alt="" /><p>Este nuevo formato de códec tiene como valor predeterminado CAGRA. Sin embargo, también admite la conversión de un gráfico CAGRA en un gráfico HNSW para la búsqueda en la CPU.</p><h2>Indexación y búsqueda en la GPU: Tomar algunas decisiones "básicas"</h2><p>Con la <a href="https://www.elastic.co/es/search-labs/blog/stateless-your-new-state-of-find-with-elasticsearch">arquitectura</a> sin estado de Elasticsearch Serverless, que separa la indexación y la búsqueda, ahora hay una clara delimitación de responsabilidades. Elegimos el mejor perfil de hardware para cumplir con cada una de estas responsabilidades independientes.</p><p>Anticipamos que los usuarios considerarán dos estrategias de implementación principales:</p><ol><li><p>Indexación y búsqueda en la GPU: durante la indexación, cree un gráfico CAGRA y empléelo durante la búsqueda, ideal cuando se requiere una búsqueda de latencia extremadamente baja.</p></li><li><p>Indexar en GPU y buscar en CPU: durante la indexación, cree un gráfico CAGRA y conviértalo en un gráfico HNSW. El gráfico HNSW se almacena en el índice, que luego se puede usar en la CPU para la búsqueda.</p></li></ol><p>Esta flexibilidad proporciona diferentes modelos de implementación, ofreciendo compensaciones entre costo y rendimiento. Por ejemplo, un servicio de indexación podría usar GPU para compilar y combinar gráficos de manera eficiente de manera oportuna mientras usa una CPU de menor potencia para la búsqueda.</p><h2>Así que aquí está el plan para la búsqueda vectorial acelerada por GPU en Elasticsearch</h2><p>Esperamos brindar ganancias de rendimiento y flexibilidad con estrategias de implementación a los usuarios, ofreciendo varias perillas para equilibrar el costo y el rendimiento. <a href="https://www.nvidia.com/gtc/session-catalog/?tab.catalogallsessionstab=16566177511100015Kus&amp;search=Lucene#/">Aquí está la sesión de NVIDIA GTC 2025</a> donde se presentó este trabajo en detalle.</p><p>Nos gustaría agradecer a los equipos de ingeniería de NVIDIA y SearchScale por su fantástica colaboración. En un próximo blog, exploraremos los detalles de implementación y el análisis de rendimiento con mayor profundidad. ¡Agárrate a tus sombreros de 🎩 curiosidad!</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/gpu-accelerated-vector-search-elasticsearch-nvidia</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/gpu-accelerated-vector-search-elasticsearch-nvidia</guid>
    <category><![CDATA[Base de datos vectorial]]></category>
    <dc:creator><![CDATA[Chris Hegarty,Hemant Malik]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt298e839e708ca11c/6a170b0fb339d560c2769fc2/38bc0377a6adce7eae0099f61902fdbbe644eb4a-1440x960.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 19 Mar 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Lucene Wrapped 2024]]></title>
    <description><![CDATA[2024 fue otro año importante para Apache Lucene. En este blog, exploraremos los puntos clave más destacados.]]></description>
    <content:encoded><![CDATA[<p>Apache Lucene tuvo una actividad significativa en 2024, con numerosos lanzamientos, incluida la primera gran actualización en tres años, repleta de mejoras emocionantes y nuevas funciones. Vamos a explorar algunos de los puntos clave.</p><h2>Lucene y la comunidad</h2><p>Un proyecto solo es tan fuerte como la comunidad que lo apoya. A pesar de más de 20 años de desarrollo, el proyecto Lucene sigue siendo vibrante y prospera gracias a sus colaboradores apasionados y activos.</p><p>En 2024, el proyecto Lucene recibió más de 2.000 commits de 98 colaboradores únicos y casi 800 pull requests. El número de colaboradores sigue creciendo, con nuevos comprometedores y afiliados a PMC que se unen al proyecto y contribuyen a su éxito.</p><h2>Lucene 10</h2><p>En 2024 se produjo el primer gran lanzamiento en casi 3 años: Lucene 10, con más de 2.000 commits de 185 colaboradores únicos. Aunque el modelo de desarrollo que sigue Lucene permite ofrecer muchas mejoras y características en lanzamientos menores, un lanzamiento importante ofrece la oportunidad de aportar funciones y modernizaciones más grandes. Por ejemplo, Lucene 10 requiere un mínimo de Java 21. Aumentar la versión mínima de Java garantiza que Lucene pueda seguir aprovechando las mejoras que ofrece Java moderno.</p><p>El objetivo principal de Lucene 10 es aprovechar mejor el hardware sobre el que se ejecuta. Echemos un vistazo rápido a algunos de los principales puntos destacados:</p><ul><li><p><strong>Más paralelismo en la búsqueda</strong> : aunque la ejecución de búsqueda ya está paralelizada entre segmentos, ahora vamos más allá, paralelizando dentro de los segmentos. Esto desacopla la representación en disco del rendimiento de ejecución, permitiendo que incluso segmentos individuales se beneficien del número de núcleos en sistemas modernos.</p></li><li><p><strong>Mejor paralelismo de E/S</strong> : el modelo sincrónico de E/S sencillo que emplea Lucene fue mejorado con una etapa de prelectura. Esto informa al sistema operativo de que se necesitará una región de un archivo índice en un futuro muy próximo, sin bloquear el hilo que llama.</p></li><li><p><strong>Mejor eficiencia de CPU y almacenamiento con indexación dispersa</strong> - Lucene 10 introduce soporte para indexación dispersa, a veces llamada indexación de clave primaria o indexación por zonas en otros almacenes de datos.</p></li></ul><p>Para más información sobre Lucene 10, consulta el <a href="https://www.elastic.co/search-labs/blog/apache-lucene-10-release-highlights">artículo</a> dedicado a Lucene 10.</p><h2>Investigación e innovación de Lucene</h2><p>En 2024, Lucene experimentó un auge de investigación e innovación, especialmente en las áreas de integración de aprendizaje automático, búsqueda vectorial y optimización para conjuntos de datos a gran escala, con 10 artículos y publicaciones <a href="https://scholar.google.com/scholar?as_ylo=2024&amp;q=lucene&amp;hl=en&amp;as_sdt=0,5">de</a> investigación de referencia separados. Algunas de las áreas y desarrollos clave de investigación incluyen:</p><ul><li><p><strong>Soporte para búsqueda vectorial e incrustación</strong> - Lucene ofrece una solución poderosa y escalable para la búsqueda basada en vectores, permitiendo la recuperación semántica a gran escala. Aprovechando la robusta infraestructura de indexación y búsqueda de Lucene, los usuarios pueden combinar lo mejor de la búsqueda tradicional de texto con las avanzadas capacidades de la búsqueda vectorial moderna, convirtiendo Lucene en una solución integral para una amplia gama de tareas de búsqueda y recuperación de información.</p></li><li><p><strong>Modelos de búsqueda híbrida</strong> - La investigación también profundizó en técnicas de búsqueda híbrida, donde Lucene combina la búsqueda tradicional basada en palabras clave con la recuperación moderna basada en vectores. Al combinar índices basados en términos con representaciones vectoriales densas, Lucene puede ofrecer resultados de búsqueda más precisos y contextualmente relevantes, cerrando la brecha entre la precisión de los motores de búsqueda tradicionales y la flexibilidad de la búsqueda semántica.</p></li></ul><p>Los esfuerzos de investigación en curso en 2024 demuestran la adaptabilidad de Lucene a las necesidades cambiantes de las tecnologías de búsqueda modernas, especialmente en el contexto de la IA, la búsqueda semántica y las aplicaciones de big data. El proyecto sigue creciendo como una plataforma poderosa, flexible y eficiente tanto para casos de búsqueda tradicionales como de vanguardia.</p><h2>Lanzamientos de Lucene en 2024</h2><p>Aunque no es un reflejo exacto, el gran volumen de lanzamientos pone de manifiesto la dedicación y energía continua de la comunidad. Estas actualizaciones incluyen mejoras importantes en el rendimiento y eficiencia de la búsqueda vectorial, soporte para madvise, optimizaciones para la decodificación de listas de anuncios, mejoras de velocidad adicionales mediante SIMD y mucho más.</p><p>Aquí tienes la lista completa de lanzamientos:</p><ul><li><p><a href="https://lucene.apache.org/core/corenews.html#apache-lucenetm-1010-available">10.1.0</a> (2024-12-20)</p></li><li><p><a href="https://lucene.apache.org/core/corenews.html#apache-lucenetm-9121-available">9.12.1</a> (2024-12-13)</p></li><li><p><a href="https://lucene.apache.org/core/corenews.html#apache-lucenetm-1000-available">10.0.0</a> (2024-10-14)</p></li><li><p><a href="https://lucene.apache.org/core/corenews.html#apache-lucenetm-9120-available">9.12.0</a> (28-09-2024)</p></li><li><p><a href="https://lucene.apache.org/core/corenews.html#apache-lucenetm-8114-available">8.11.4</a> (2024-09-24)</p></li><li><p><a href="https://lucene.apache.org/core/corenews.html#apache-lucenetm-9111-available">9.11.1</a> (27-06-2024)</p></li><li><p><a href="https://lucene.apache.org/core/corenews.html#apache-lucenetm-9110-available">9.11.0</a> (2024-06-06)</p></li><li><p><a href="https://lucene.apache.org/core/corenews.html#apache-lucenetm-9100-available">9.10.0</a> (2024-02-20)</p></li><li><p><a href="https://lucene.apache.org/core/corenews.html#apache-lucenetm-8113-available">8.11.3</a> (2024-02-08)</p></li><li><p><a href="https://lucene.apache.org/core/corenews.html#apache-lucenetm-992-available">9.9.2</a> (29-01-2024)</p></li></ul><p>Puedes encontrar más información y notas de lanzamiento en la página <a href="https://projects.apache.org/project.html?lucene-core">de Lucene Core</a> . Además, existen ediciones <a href="https://projects.apache.org/project.html?lucene-pylucene">equivalentes de PyLucene</a> .</p><h2>Concluyendo</h2><p>A medida que Lucene madura, sigue prosperando gracias a su comunidad dedicada y vibrante. Como vimos, 2024 fue un año increíblemente productivo, y ahora miramos hacia adelante los emocionantes desarrollos que traerá 2025.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/apache-lucene-wrapped-2024</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/apache-lucene-wrapped-2024</guid>
    <category><![CDATA[Lucene]]></category>
    <dc:creator><![CDATA[Chris Hegarty]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt901211870015335c/6a17ddf6a292998b08d02b93/29a02c89b3c5adb37a5f900de634ff09cb63fdd9-1792x1024.jpg" length="0" type="image/jpeg"/>
    <pubDate>Fri, 03 Jan 2025 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>