Armazenamento de Vetores, Indexação e Busca com MariaDB

Quando você desenvolve aplicativos de IA generativa, normalmente introduz três componentes adicionais à sua infraestrutura: um incorporador, um LLM e um banco de dados vetorial.

No entanto, se você está usando o MariaDB, não precisa introduzir um banco de dados adicional com seu próprio dialeto SQL — ou, ainda pior — sua própria API proprietária. Desde a versão 11.7 do MariaDB (e MariaDB Enterprise Server 11.4), você pode simplesmente armazenar suas incorporações (ou vetores) em qualquer coluna de qualquer tabela — sem precisar tornar seus aplicativos poliglotas em bancos de dados.

“Após anunciar a prévia da busca vetorial no MariaDB Server, a capacidade de busca vetorial agora foi adicionada à versão 11.7 do MariaDB Community Server,” escreve Ralf Gebhardt, Gerente de Produto do MariaDB Server na MariaDB. Isso inclui um novo tipo de dado (VECTOR), índice vetorial e um conjunto de funções para manipulação de vetores.

Por que os vetores são necessários em aplicativos de IA generativa?

Os vetores são necessários em aplicações de IA generativa porque eles incorporam significados complexos em uma matriz compacta de números de comprimento fixo (um vetor). Isso é mais claro no contexto da geração aumentada por recuperação (ou RAG). Essa técnica permite buscar dados relevantes de suas fontes (APIs, arquivos, bancos de dados) para aprimorar a entrada de um modelo de IA com os dados buscados, muitas vezes privados para o negócio.

Como suas fontes de dados podem ser vastas, você precisa de uma maneira de encontrar as partes relevantes, dado que os modelos de IA atuais têm uma janela de contexto finita – você não pode simplesmente adicionar todos os seus dados a uma solicitação. Criando pedaços de dados e executando esses pedaços de dados através de um modelo de IA especial chamado embedder, você pode gerar vetores e usar técnicas de busca de proximidade para encontrar informações relevantes a serem anexadas a uma solicitação.

Por exemplo, considere a seguinte entrada de um usuário em um chatbot de recomendação:

Plain Text

 

Como seu modelo de IA não foi treinado com os dados exatos contendo as informações do produto em sua loja online, você precisa recuperar os produtos mais relevantes e suas informações antes de enviar a solicitação para o modelo.

Para isso, você envia a entrada original do usuário para um embedder e obtém um vetor que você pode usar posteriormente para obter os 10 produtos mais próximos da entrada do usuário. Depois de obter essas informações (e veremos como fazer isso com o MariaDB mais tarde), você pode enviar a solicitação aprimorada para seu modelo de IA:

Plain Text

 

Isso resulta em previsões de IA que usam seus próprios dados.

Criando Tabelas para Armazenamento de Vetores

Para armazenar vetores no MariaDB, use o novo tipo de dado VECTOR. Por exemplo:

MariaDB SQL

 

CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    description TEXT,
    embedding VECTOR(2048)
);

Neste exemplo, a coluna embedding pode conter um vetor de 2048 dimensões. Você deve corresponder ao número de dimensões que seu embutidor gera.

Criando Índices de Vetor

Para desempenho de leitura, é importante adicionar um índice à sua coluna de vetor. Isso acelera as buscas por similaridade. Você pode definir o índice no momento da criação da tabela da seguinte forma:

MariaDB SQL

 

CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    description TEXT,
    embedding VECTOR(2048) NOT NULL,
    VECTOR INDEX (embedding)
);

Para maior controle, você pode especificar a função de distância que o servidor de banco de dados usará para construir o índice, assim como o M valor do Mundo Pequeno Navegável Hierárquico (HNSW) algoritmo usado pelo MariaDB. Por exemplo:

MariaDB SQL

 

CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    description TEXT,
    embedding VECTOR(2048) NOT NULL,
    VECTOR INDEX (embedding) M=8 DISTANCE=cosine
);

Consulte a documentação para mais informações sobre essas configurações.

Inserindo Vetores

Quando você passa dados (texto, imagem, áudio) por um embutidor, você obtém um vetor. Normalmente, isso é uma série de números em um array no formato JSON. Para inserir esse vetor em uma tabela do MariaDB, você pode usar a função VEC_FromText. Por exemplo:

MariaDB SQL

 

INSERT INTO products (name, embedding)
VALUES
  ("Alarm clock", VEC_FromText("[0.001, 0, ...]")),
  ("Cow figure", VEC_FromText("[1.0, 0.05, ...]")),
  ("Bicycle", VEC_FromText("[0.2, 0.156, ...]"));

Lembre-se de que os vetores inseridos devem ter o número correto de dimensões conforme definido na instrução CREATE TABLE.

Busca por Similaridade (Comparando Vetores)

Nas aplicações RAG, você envia a entrada do usuário para um incorporador para obter um vetor. Você pode então consultar os registros em seu banco de dados que estão mais próximos desse vetor. Vetores mais próximos representam dados semanticamente semelhantes. No momento em que este texto foi escrito, o MariaDB possui duas funções de distância que você pode usar para busca de similaridade ou proximidade:

  • VEC_DISTANCE_EUCLIDEAN: calcula a distância em linha reta entre dois vetores. É mais adequado para vetores derivados de dados brutos não normalizados ou em cenários onde a separação espacial se correlaciona diretamente com a similaridade, como comparar características posicionais ou numéricas. No entanto, é menos eficaz para incorporações de alta dimensão ou normalizadas, pois é sensível a diferenças na magnitude do vetor.
  • VEC_DISTANCE_COSINE: mede a diferença angular entre vetores. Bom para comparar incorporações normalizadas, especialmente em aplicações semânticas como texto ou recuperação de documentos. Excelente para capturar similaridade em significado ou contexto.

Lembre-se que a busca por similaridade usando as funções anteriores é apenas aproximada e depende muito da qualidade dos vetores calculados e, portanto, da qualidade do incorporador usado.

O seguinte exemplo encontra os 10 produtos mais similares a um vetor dado ($user_input_vector deve ser substituído pelo vetor real retornado pelo incorporador sobre a entrada do usuário):

MariaDB SQL

 

SELECT id, name, description
FROM products
ORDER BY VEC_DISTANCE_COSINE(
  VEC_FromText($user_input_vector),
  embedding
)
LIMIT 10;

As funções VEC_DISTANCE_COSINE e VEC_DISTANCE_EUCLIDEAN recebem dois vetores. No exemplo anterior, um dos vetores é o vetor calculado com base na entrada do usuário, e o outro é o vetor correspondente para cada registro na tabela products.

Um Exemplo Prático

Preparei um exemplo prático usando Java e sem frameworks de IA para que você realmente entenda o processo de criação de aplicações de IA generativa aproveitando as capacidades de busca vetorial do MariaDB. Você pode encontrar o código no GitHub.

Source:
https://dzone.com/articles/vector-storage-indexing-and-search-with-mariadb