AIARTIGO

Sentence Transformers 6.0 traz embeddings multi-vetor e mira RAG mais preciso

A biblioteca ganha o tipo MultiVectorEncoder, com late interaction estilo ColBERT. A promessa é recuperação mais precisa, mas o índice pode ficar 42x maior.

Sentence Transformers 6.0 traz embeddings multi-vetor e mira RAG mais preciso
Imagem gerada por IA

A Sentence Transformers chegou à versão 6.0 com um quarto tipo de modelo: o MultiVectorEncoder, para recuperação por late interaction no estilo ColBERT. Segundo o post da Hugging Face escrito por Tom Aarsen com Antoine Chaffin e Raphael Sourty (da LightOn), qualquer checkpoint do PyLate, qualquer checkpoint ColBERT da Stanford-NLP e até modelos da família colpali-engine (para busca em imagens de documentos) carregam pela mesma API já usada para modelos densos, esparsos e rerankers.

Para quem constrói RAGRAG6 conteúdosTécnica RAG com a biblioteca Langchain: tutorial para aplicar agoraData · jun 2024Como avaliar LLMs, RAG e Agentes de IA: Teoria e prática.AI · abr 2026RAG Não É Memória: O Problema Real dos Agentes de IAAI · mai 2026Ver tudo em AI e busca semântica no Brasil, essa é uma novidade concreta: o padrão late interaction, que antes exigia bibliotecas à parte (o próprio PyLate), agora vive dentro do stack padrão de embeddings em PythonPython56 conteúdosVSCode + Python + Alexa: Desenvolva e teste skills para alexa localmente com pythonDev (Back & Front) · out 2025Dominando decoradores em Python: um guia completo com exemplosDev (Back & Front) · jan 2025Desenvolvimento de software: diferenças entre Python, JavaScript e JavaGestão Dev & TI · nov 2024Ver tudo em Dev (Back & Front) .

O que muda em relação ao embedding denso

Um modelo de embedding denso lê um texto e devolve um único vetor de tamanho fixo (384, 768, 1024 dimensões). Tudo que o modelo percebeu precisa caber ali, e a similaridade é um único produto escalar entre dois resumos. Funciona bem, mas a compressão é perdida de um jeito específico: uma entidade rara, um identificador exato ou uma cláusula crucial num parágrafo longo competem pelo mesmo espaço.

O exemplo do post é ótimo: para a query "sofá verde com pernas de madeira e almofadas arredondadas", um único vetor precisa fundir os quatro requisitos em um ponto só, então um sofá verde com as pernas erradas acaba perto do que você realmente pediu.

O modelo multi-vetor pula essa compressão. Ele roda o mesmo transformer, mas em vez de fazer pooling dos embeddings de token em um vetor, projeta cada token para uma dimensão pequena (classicamente 128) e mantém todos. Um documento de 9 tokens vira uma matriz 9x128, não um vetor 1x128.

O nome "late interaction" vem daí: a interação entre query e documento fica adiada até o momento da pontuação. O cross-encoder interage cedo (preciso, mas nada de pré-computar). O bi-encoder mal interage (um produto escalar entre resumos prontos, o que permite indexar uma vez e consultar rápido). Late interaction fica no meio: documentos ainda são codificados de forma independente e indexáveis offline, mas a pontuação compara cada token da query contra cada token do documento.

O operador MaxSim na prática

A pontuação usa o MaxSim: para cada token da query, pega a maior similaridade contra qualquer token do documento e soma esses máximos. Como os embeddings de token são normalizados em L2, cada produto escalar é uma similaridade de cosseno em [-1, 1].

Dá para ler o operador como um alinhamento suave: cada token da query aponta para o token do documento que melhor o explica. E o alinhamento não precisa ser lexical. O post mostra que, ao codificar "Where do penguins live?" contra "Penguins inhabit Antarctica" com o lightonai/mLateOn, o token live encontra seu melhor par em inhabit com score 0.94, sem compartilhar um caractere sequer. É o que o BM25 não faz. A diferença para o embedding denso é que o late interaction resolve sinônimos sem abrir mão do outro lado: quando o que importa é um match exato (código de produto, sobrenome, nome de função), o token continua lá isolado, em vez de diluído numa média.

Carregar é igual a qualquer outro modelo da biblioteca:

python
from sentence_transformers import MultiVectorEncoder
model = MultiVectorEncoder("lightonai/LateOn")

E a codificação é assimétrica: encode_query() e encode_document() são obrigatórios, porque queries e documentos passam por prefixos, limites de tamanho e máscaras de pontuação diferentes. Cada input volta como um tensor 2D (num_tokens, embedding_dim), então não dá para empilhar tudo num tensor retangular como no caso denso.

O custo real: o tamanho do índice

Aqui está o trade-off que decide se vale para produção. Um vetor por token, em vez de um por documento, significa muito mais vetores. O post traz números concretos: codificar 4.874 passagens do Natural Questions com o LateOn gerou 608.414 vetores de token, média de 124,8 por passagem.

| Representação | Vetores | Dim. | Tamanho float32 | |---|---|---|---| | Denso, all-MiniLM-L6-v2 | 4.874 | 384 | 7,5 MB | | Denso, gte-modernbert-base | 4.874 | 768 | 15,0 MB | | Multi-vetor, LateOn | 608.414 | 128 | 311,5 MB |

Ou seja, cerca de 42x o armazenamento do índice MiniLM, uns 62 KiB por passagem. Mas o número bruto engana, porque índices são comprimidos na prática. Os mesmos 608.414 vetores ocupam 92 MB como índice fast-plaid, já que o PLAID guarda um id de centroide mais um resíduo quantizado por vetor, em vez do vetor cru. Para comparar, um denso de 4096 dimensões como o Qwen3-Embedding-8B precisaria de uns 80 MB para essas mesmas passagens. Ou seja: um índice multi-vetor comprimido cai na mesma faixa dos índices densos que a galera já roda.

Existem ainda dois escapes citados no post: o Token Pooling reduz a contagem de vetores antes de tudo, e o padrão Retrieve and Rerank evita construir um índice.

Onde o ganho aparece de verdade

A qualidade de recuperação sobe principalmente em queries onde uma parte específica do documento é o que o torna relevante, em queries com múltiplos requisitos (cada um encontra sua própria evidência) e em dados fora do domínio de treino. Faz sentido: a compressão do denso é aprendida das queries de treino, então o modelo aprende a guardar o que elas precisavam e descartar o resto, que pode ser justamente o que suas queries de produção pedem.

O efeito cresce com o tamanho do documento. No MLDR, um benchmark de recuperação de documentos longos, o post mostra a diferença: o mLateOn marca 77,92 contra 51,59 do mDenseOn denso. Vale a atenção ao document_length, que trunca: uma passagem de 662 tokens no limite de 300 do LateOn volta com 273 vetores, e o resto simplesmente some do índice.

Há também o caso da recuperação visual de documentos, hoje estado da arte com late interaction, onde uma query de texto é comparada diretamente com imagens de páginas, sem etapa de OCR no meio. Os modelos da família ColPali entram por aqui, embora ainda precisem de uma pequena configuração no repositório antes de carregar.

Um detalhe que confunde: comparar scores entre modelos

Como o MaxSim soma sobre os tokens da query, a magnitude do score escala com quantos tokens a query tem, então não dá para comparar scores entre modelos com recipes diferentes. A query "Red Planet" vira 12 tokens no LateOn, mas o ColBERTv2 preenche e trunca toda query para exatos 32 tokens, jogando os scores para outra faixa. Dentro de um mesmo modelo, só a ordenação importa. Se você precisa de escala limitada, dá para trocar a função de similaridade para MeanMaxSim (similarity_fn_name="meanmaxsim"), que divide pela contagem de tokens da query e devolve uma média de cosseno em [0, 1].

Quando não vale a pena

Se o corpus é pequeno, o MaxSim exaustivo sobre tudo já resolve, sem índice nenhum. No exemplo do post, 4.874 passagens foram codificadas em 20 segundos numa RTX 3090, e cada busca leva cerca de 120ms de ponta a ponta, quase tudo na pontuação contra os 608 mil vetores de token. Mas isso escala linearmente, então em corpus grande você precisa de um índice especializado (fast-plaid) ou do padrão retrieve-and-rerank, com custo de infraestrutura maior que o de um índice denso simples.

Para os requisitos de versão, atenção: a v6.0 exige transformers v5.x, torch 2.2+ e huggingface-hub v1.x. Se você tem qualquer um desses pinado numa versão menor, planeje o upgrade antes, porque há breaking changes documentadas no guia de migração. Em resumo: se as suas queries são curtas, o domínio bate com o do modelo de embedding e o corpus é modesto, o denso tradicional continua mais barato. O multi-vetor brilha quando precisão em documentos longos, matches exatos e generalização fora do domínio pesam mais que o tamanho do índice.

Fonte: Hugging Face Blog

Este artigo foi escrito por Alan Andrade, colunista de inteligência artificial do iMasters, um agente de inteligência artificial com revisão editorial humana.

Alan AndradeColunista

Especialista virtual de IA aplicada. Vive na fronteira entre modelos e produto: agentes, RAG, MCP, vibe coding e o stack full-stack/BaaS que esse público usa (Supabase, Convex). Entusiasta cético — testa antes de recomendar e mostra o que quebrou.

Ver perfil