Los modelos de embeddings suelen resumir cada documento en un solo vector. Esa estrategia es rápida y práctica, pero también puede perder detalles importantes: un código de producto, un nombre propio o una condición específica dentro de un texto largo. Sentence Transformers busca resolver ese límite con MultiVectorEncoder, una nueva API para modelos de búsqueda basados en interacción tardía.
La propuesta integra modelos de estilo ColBERT, checkpoints de PyLate, modelos de Stanford-NLP y sistemas de recuperación visual como ColPali. ¿La ventaja? En lugar de comprimir todo el documento en una representación única, conserva un vector por token y compara las partes relevantes directamente.
Qué cambia frente a un embedding tradicional
Un modelo denso convierte un texto completo en un vector fijo, por ejemplo de 384, 768 o 1024 dimensiones. Después, la búsqueda compara el vector de la consulta con el vector de cada documento mediante un producto punto o una métrica similar.
Este enfoque funciona bien, pero obliga al modelo a mezclarlo todo en una sola representación. Imagina una búsqueda como sofá verde con patas de madera y cojines redondeados. Un embedding denso puede acercar también un sofá verde con patas metálicas, porque todos los conceptos terminan combinados en el mismo punto.
Los modelos multi-vector mantienen una matriz de vectores por documento. Un texto de nueve tokens puede representarse como una matriz de 9 x 128, en lugar de un único vector de 1 x 128. Cada token conserva una representación contextualizada y puede encontrar su mejor correspondencia dentro del documento.
La interacción tardía conserva la velocidad de indexar documentos por separado, pero permite una comparación mucho más detallada durante la búsqueda.
MaxSim: cómo se calcula la relevancia
La puntuación principal se llama MaxSim. Para cada token de la consulta, el sistema busca el token del documento con mayor similitud y después suma todos esos máximos.
En forma simplificada:
MaxSim(consulta, documento) =
suma del máximo de similitud de cada token de la consulta
Como los vectores se normalizan con norma L2, cada comparación equivale normalmente a una similitud coseno entre -1 y 1. La puntuación final depende de la cantidad de tokens de la consulta, por lo que no conviene comparar directamente valores producidos por modelos con configuraciones diferentes.
También es posible usar MeanMaxSim, que divide la suma entre el número de tokens de la consulta y genera una puntuación promedio más fácil de interpretar.
La correspondencia no tiene que ser literal. En una prueba con la consulta Where do penguins live? y el texto Penguins inhabit Antarctica, el token live encontró una relación fuerte con inhabit, aunque las palabras no comparten caracteres. Al mismo tiempo, un identificador exacto o un nombre propio puede conservar su propia señal sin quedar diluido entre todos los demás conceptos.
Uso con Sentence Transformers 6.0
La instalación mantiene el flujo conocido de la biblioteca:
pip install -U sentence-transformers
Para recuperación de documentos visuales se requieren las dependencias de imágenes:
pip install -U "sentence-transformers[image]"
La carga del modelo también sigue una API familiar:
from sentence_transformers import MultiVectorEncoder
model = MultiVectorEncoder("lightonai/LateOn")
La biblioteca puede detectar distintos formatos de checkpoints, incluyendo modelos de PyLate y ColBERT de Stanford-NLP:
model = MultiVectorEncoder("colbert-ir/colbertv2.0")
model = MultiVectorEncoder("answerdotai/answerai-colbert-small-v1")
model = MultiVectorEncoder("mixedbread-ai/mxbai-edge-colbert-v0-17m")
Para una consulta y un documento se deben usar métodos diferentes. No es un detalle menor: estos modelos suelen tener prefijos, límites de longitud y máscaras distintas para cada lado.
queries = ["¿Cuál es la capital de Francia?"]
documents = [
"París es la capital de Francia.",
"Berlín es la capital y la ciudad más grande de Alemania."
]
query_embeddings = model.encode_query(queries)
document_embeddings = model.encode_document(documents)
scores = model.similarity(query_embeddings, document_embeddings)
El resultado no es un tensor rectangular único. Cada entrada devuelve una matriz con tantos vectores como tokens conserve. Un documento largo puede tener una matriz más alta que uno corto.
Dos formas de llevarlo a producción
La búsqueda exhaustiva es útil para corpus pequeños. Se codifican los documentos una sola vez y luego se calcula MaxSim contra todos ellos. En una prueba con 4.874 pasajes de Natural Questions, el modelo produjo 608.414 vectores de tokens.
El proceso tardó aproximadamente 20 segundos en una RTX 3090 y cada consulta tomó cerca de 120 milisegundos mediante una comparación exacta. Es un resultado razonable para miles de documentos, pero el coste crece con la cantidad total de tokens, no solo con el número de documentos.
Para colecciones grandes hay dos alternativas principales:
- Índices nativos de interacción tardía: Qdrant, Weaviate, Vespa, LanceDB, VectorChord, Milvus y
fast-plaidofrecen distintas formas de almacenar y consultar vectores multi-vector. - Retrieve and rerank: un modelo denso recupera los primeros candidatos y el modelo multi-vector vuelve a ordenarlos con
MaxSim.
El segundo patrón es especialmente práctico. Puedes mantener un índice denso convencional y aplicar el modelo multi-vector solo sobre los 50 o 100 candidatos más prometedores. Así obtienes más precisión sin multiplicar el tamaño del índice.
El coste: más vectores, más almacenamiento
La mejora en calidad tiene un precio. Un modelo denso guarda un vector por documento, mientras que un modelo multi-vector guarda uno por token relevante.
En el ejemplo de Natural Questions, las representaciones ocuparon aproximadamente:
| Representación | Vectores | Dimensiones | Tamaño en float32 |
|---|---|---|---|
all-MiniLM-L6-v2 | 4.874 | 384 | 7,5 MB |
gte-modernbert-base | 4.874 | 768 | 15,0 MB |
LateOn multi-vector | 608.414 | 128 | 311,5 MB |
El índice multi-vector sin comprimir fue unas 42 veces mayor que el de MiniLM. Sin embargo, técnicas como PLAID reducen el almacenamiento mediante centroides y residuos cuantizados. En la misma prueba, el índice comprimido ocupó cerca de 92 MB.
La otra herramienta clave es HierarchicalTokenPooling. Esta técnica agrupa tokens cercanos y los reemplaza por una representación promedio. Con un factor de agrupación de 2, el índice puede reducirse aproximadamente a la mitad. En evaluaciones citadas por Hugging Face, la pérdida promedio de rendimiento fue pequeña, aunque siempre conviene medir el efecto con los datos propios.
from sentence_transformers.multi_vector_encoder.modules import HierarchicalTokenPooling
pooling = HierarchicalTokenPooling(pool_factor=2)
document_embeddings = model.encode_document(
documents,
token_pooling=pooling
)
Recuperación de documentos visuales sin OCR
Una de las aplicaciones más interesantes aparece cuando el documento no es texto plano. Los modelos de la familia ColPali pueden comparar una consulta escrita con la imagen completa de una página, incluyendo tablas, gráficos, diseño y posiciones visuales.
model = MultiVectorEncoder("vidore/colqwen2.5-v0.2")
queries = [
"¿Qué variable aparece en el eje vertical del gráfico?",
"¿En qué año fue mayor el gasto total?"
]
images = [
"https://ejemplo.com/pagina-1.jpg",
"https://ejemplo.com/pagina-2.jpg"
]
query_embeddings = model.encode_query(queries)
document_embeddings = model.encode_document(images)
scores = model.similarity(query_embeddings, document_embeddings)
Aquí los vectores del documento representan parches de imagen, no palabras. La consulta puede localizar información dentro de una tabla o un gráfico sin pasar primero por un sistema de reconocimiento óptico de caracteres.
Esto abre posibilidades para archivos financieros, reportes científicos, formularios, facturas y documentos históricos. También exige más memoria: una página puede generar cientos de vectores, frente a los cerca de 125 vectores promedio de los pasajes de texto usados en el ejemplo.
Audio, video e interpretabilidad
La misma idea puede extenderse a otras modalidades. vidore/colqwen-omni-v0.1 acepta texto, imágenes, audio y video mediante una interfaz común. Una consulta textual como medicina para las náuseas del automóvil puede recuperar una conversación donde la persona dice carsickness, sin necesidad de transcribir el audio previamente.
Con video hay que controlar el muestreo de fotogramas. Procesar cada cuadro consume demasiada memoria, por lo que conviene usar una frecuencia reducida, como 0,5 fotogramas por segundo, especialmente en clips largos.
Otra ventaja es la interpretabilidad. Como MaxSim asigna una parte concreta de la puntuación a cada token de la consulta y a su mejor coincidencia, es posible explicar por qué un documento quedó en determinada posición.
En imágenes, esa información puede convertirse en mapas de calor sobre la página. En texto, se puede mostrar que preliminary coincidió con el mismo término, mientras que when encontró una relación contextual con since. No es una explicación perfecta del razonamiento del modelo, pero sí una evidencia precisa de las coincidencias que impulsaron la puntuación.
Rendimiento y evaluación
Sentence Transformers incorpora soporte para PyTorch, ONNX y OpenVINO, además de precisión reducida, Flash Attention y torch.compile. En las pruebas descritas, float16 con Flash Attention alcanzó hasta 2,44 veces el rendimiento de float32 sin una pérdida medible de calidad en recuperación.
Hay una excepción importante: algunos checkpoints de ColBERT usan expansión de consultas con tokens [MASK] que necesitan atención. En esos casos, Flash Attention puede ser incompatible y conviene usar SDPA.
Para evaluar modelos, la biblioteca añade MultiVectorNanoBEIREvaluator, que permite ejecutar una versión compacta de 13 conjuntos de BEIR. En la comparación entre LateOn y DenseOn, ambos entrenados con el mismo backbone ModernBERT y 149 millones de parámetros, el modelo multi-vector obtuvo una media de NDCG@10 de 0.6868, frente a 0.6764 del modelo denso.
LateOn ganó en 9 de los 13 conjuntos, aunque no en todos. Perdió en ArguAna, FiQA2018, SCIDOCS y SciFact. ¿La lección? La interacción tardía ofrece una mejora promedio, pero no reemplaza la evaluación con consultas y documentos reales de tu aplicación.
Cuándo conviene usarlo
Un modelo multi-vector tiene sentido cuando la relevancia depende de detalles específicos, coincidencias parciales o varios requisitos simultáneos. También es una opción fuerte para documentos largos, dominios especializados y recuperación visual.
Una guía práctica sería:
- Usa embeddings densos si necesitas simplicidad, bajo consumo y búsquedas a gran escala.
- Usa multi-vector como reranker si ya tienes un buscador denso y quieres mejorar sus primeros resultados.
- Usa un índice multi-vector dedicado cuando la calidad de recuperación justifique el coste adicional de almacenamiento.
- Aplica token pooling cuando el número de vectores sea el principal problema.
- Evalúa siempre en tus propios datos, especialmente si trabajas con español, documentos técnicos o imágenes con diseños poco comunes.
La incorporación de MultiVectorEncoder no convierte a todos los sistemas de búsqueda en ColBERT de un día para otro. Lo importante es que reduce la fricción: cargar, codificar, comparar y evaluar estos modelos ahora sigue un flujo unificado dentro de Sentence Transformers.
La inteligencia artificial no está inventando una búsqueda mágica. Está conservando más pistas antes de decidir qué documento responde mejor. En muchas aplicaciones, esa diferencia entre resumir demasiado y mantener el detalle puede ser justo lo que separa un resultado correcto de uno meramente parecido.
