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

Quando você desenvolve aplicações de IA generativa, geralmente introduz três componentes adicionais em sua infraestrutura: um incorporador, um LLM e um banco de dados vetorial.

No entanto, se você estiver usando MariaDB, não precisa introduzir um banco de dados adicional com seu próprio dialeto SQL — ou, pior ainda — 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 necessidade de tornar suas aplicações 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 ao lançamento do MariaDB Community Server 11.7,” 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 aplicações de IA generativa?

Os vetores são necessários em aplicações de IA generativa porque eles incorporam significados complexos em um array fixo de números (um vetor). Isso fica mais claro no contexto de geração aumentada por recuperação (ou RAG). Essa técnica permite que você busque dados relevantes de suas fontes (APIs, arquivos, bancos de dados) para melhorar a entrada do modelo de IA com os dados recuperados, muitas vezes privados da empresa.

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 um prompt. Ao criar pedaços de dados e executar esses pedaços de dados através de um modelo de IA especial chamado incorporador, você pode gerar vetores e usar técnicas de busca de proximidade para encontrar informações relevantes a serem anexadas a um prompt.

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 o prompt para o modelo.

Para isso, você envia a entrada original do usuário para um incorporador e obtém um vetor que você pode usar posteriormente para encontrar os 10 produtos mais próximos da entrada do usuário. Assim que você obtém essa informação (e veremos como fazer isso com o MariaDB mais tarde), você pode enviar o prompt aprimorado para o 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 gerador de embeddings gera.

Criando Índices de Vetor

Pela performance 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 Hierárquico Navegável (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 gerador de embeddings, 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 de Similaridade (Comparando Vetores)

Em 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 que são semanticamente semelhantes. No momento da redação deste texto, 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 cenários onde a separação espacial 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 recuperação de texto ou documentos. Ele se destaca em capturar similaridade em significado ou contexto.

Tenha em mente que a busca de similaridade usando as funções anteriores é apenas aproximada e depende muito da qualidade dos vetores calculados e, portanto, da qualidade do incorporador utilizado.

O seguinte exemplo encontra os 10 produtos mais semelhantes 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 a 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