생성 AI 애플리케이션을 개발할 때, 일반적으로 인프라에 세 가지 추가 구성 요소를 도입합니다: 임베더, LLM, 그리고 벡터 데이터베이스.
하지만 MariaDB를 사용하는 경우, 고유한 SQL 방언과 함께 추가 데이터베이스를 도입할 필요가 없으며 — 더 나쁘게는 — 고유한 독점 API를 도입할 필요도 없습니다. MariaDB 버전 11.7(그리고 MariaDB Enterprise Server 11.4)부터는 임베딩(또는 벡터)을 어떤 테이블의 어떤 열에든 간단히 저장할 수 있으며, 애플리케이션을 데이터베이스 다국어 지원 형태로 만들 필요가 없습니다.
“MariaDB Server에서 벡터 검색의 미리보기를 발표한 후, 이제 벡터 검색 기능이 MariaDB Community Server 11.7 릴리스에 추가되었습니다,” Ralf Gebhardt, MariaDB의 MariaDB Server 제품 관리자, 가 씁니다. 여기에는 새로운 데이터 타입(VECTOR
), 벡터 인덱스, 그리고 벡터 조작을 위한 함수 세트가 포함됩니다.
생성 AI 애플리케이션에서 벡터가 필요한 이유는 무엇인가요?
벡터는 생성적 AI 애플리케이션에서 필요합니다. 왜냐하면 벡터는 복잡한 의미를 압축된 고정 길이의 숫자 배열(벡터)로 포함하기 때문입니다. 이는 검색 보강 생성(RAG)의 맥락에서 더 명확해집니다. 이 기술은 API, 파일, 데이터베이스와 같은 소스에서 관련 데이터를 가져와 AI 모델 입력을 비즈니스에 종종 비공식적인 데이터로 향상시킬 수 있게 해줍니다.
당신의 데이터 소스는 방대할 수 있으므로, 현재 AI 모델이 유한한 컨텍스트 윈도우를 가지고 있다는 점을 고려할 때, 관련 데이터를 찾을 수 있는 방법이 필요합니다. 모든 데이터를 프롬프트에 간단히 추가할 수는 없습니다. 데이터를 청크로 나누고 이 청크를 임베더라는 특별한 AI 모델을 통해 실행하면, 벡터를 생성하고 근접 검색 기술을 사용하여 프롬프트에 추가할 관련 정보를 찾을 수 있습니다.
예를 들어, 추천 챗봇에서 사용자가 다음과 같은 입력을 했다고 가정해 보겠습니다:
I need a good case for my iPhone 15 pro.
당신의 AI 모델이 온라인 상점의 제품 정보를 포함하는 정확한 데이터로 훈련되지 않았기 때문에, 모델에 프롬프트를 전송하기 전에 가장 관련성이 높은 제품과 그 정보를 검색해야 합니다.
이를 위해 사용자의 원래 입력을 임베더에 전송하고, 이후에 사용자 입력에 대해 가장 가까운 10개의 제품을 얻기 위해 사용할 수 있는 벡터를 얻습니다. 이 정보를 얻으면(나중에 MariaDB를 사용하여 이를 수행하는 방법을 살펴보겠습니다), 향상된 프롬프트를 AI 모델에 전송할 수 있습니다:
I need a good case for my iPhone 15 pro. Which of the following products better suit my needs?
1. ProShield Ultra Case for iPhone 15 Pro - $29.99: A slim, shock-absorbing case with raised edges for screen protection and a sleek matte finish.
2. EcoGuard Bio-Friendly Case for iPhone 15 Pro - $24.99: Made from 100% recycled materials, offering moderate drop protection with an eco-conscious design.
3. ArmorFlex Max Case for iPhone 15 Pro - $39.99: Heavy-duty protection with military-grade durability, including a built-in kickstand for hands-free use.
4. CrystalClear Slim Case for iPhone 15 Pro - $19.99: Ultra-thin and transparent, showcasing the phone's design while providing basic scratch protection.
5. LeatherTouch Luxe Case for iPhone 15 Pro - $49.99: Premium genuine leather construction with a soft-touch feel and an integrated cardholder for convenience.
이로 인해 AI 예측은 귀하의 데이터를 사용하게 됩니다.
벡터 저장을 위한 테이블 만들기
MariaDB에 벡터를 저장하려면 새 VECTOR
데이터 유형을 사용하십시오. 예를 들어:
CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(100),
description TEXT,
embedding VECTOR(2048)
);
이 예에서 embedding
열은 2048 차원의 벡터를 보유할 수 있습니다. 임베더가 생성하는 차원 수와 일치해야 합니다.
벡터 인덱스 생성
읽기 성능을 위해 벡터 열에 인덱스를 추가하는 것이 중요합니다. 이는 유사성 검색을 가속화합니다. 다음과 같이 테이블 생성 시 인덱스를 정의할 수 있습니다:
CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(100),
description TEXT,
embedding VECTOR(2048) NOT NULL,
VECTOR INDEX (embedding)
);
더 많은 제어를 위해 데이터베이스 서버가 인덱스를 구축하는 데 사용할 거리 함수 및 MariaDB에서 사용하는 M 값인 계층적 탐색 가능한 작은 세상 (HNSW) 알고리즘을 지정할 수 있습니다. 예를 들어:
CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(100),
description TEXT,
embedding VECTOR(2048) NOT NULL,
VECTOR INDEX (embedding) M=8 DISTANCE=cosine
);
이러한 구성에 대한 자세한 내용은 문서를 확인하십시오.
벡터 삽입
데이터(텍스트, 이미지, 오디오)를 임베더를 통해 전달하면 벡터를 받게 됩니다. 일반적으로 이는 JSON 형식의 배열 내 숫자 시리즈입니다. MariaDB 테이블에 이 벡터를 삽입하려면 VEC_FromText
함수를 사용할 수 있습니다. 예를 들어:
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, ...]"));
삽입된 벡터는 CREATE TABLE
문에서 정의된 올바른 차원 수를 가져야 합니다.
유사성 검색 (벡터 비교)
RAG 애플리케이션에서 사용자 입력을 임베더에 보내 벡터를 생성합니다. 그런 다음 해당 벡터에 더 가까운 데이터베이스의 레코드를 쿼리할 수 있습니다. 더 가까운 벡터는 의미적으로 유사한 데이터를 나타냅니다. 본 문서를 작성하는 시점에서 MariaDB는 유사성 또는 근접성 검색에 사용할 수 있는 두 가지 거리 함수를 제공합니다:
VEC_DISTANCE_EUCLIDEAN
: 두 벡터 간의 직선 거리를 계산합니다. 원시 비정규화 데이터에서 파생된 벡터나 공간적 분리가 유사성과 직접적으로 연관되는 시나리오(예: 위치 또는 숫자 특징 비교)에 가장 적합합니다. 그러나 고차원 또는 정규화된 임베딩에는 덜 효과적이며, 벡터의 크기 차이에 민감합니다.VEC_DISTANCE_COSINE
: 벡터 간의 각도 차이를 측정합니다. 텍스트 또는 문서 검색과 같은 의미론적 애플리케이션에서 정규화된 임베딩을 비교하는 데 적합합니다. 의미나 맥락의 유사성을 포착하는 데 뛰어납니다.
이전 함수들을 사용한 유사성 검색은 언제나 근사적이며, 계산된 벡터의 품질과 따라서 사용된 임베더의 품질에 크게 의존한다는 점을 명심하세요.
다음 예시는 주어진 벡터에 대해 가장 유사한 상위 10개 제품을 찾습니다($user_input_vector
는 사용자 입력에 대해 임베더가 반환한 실제 벡터로 대체되어야 합니다):
SELECT id, name, description
FROM products
ORDER BY VEC_DISTANCE_COSINE(
VEC_FromText($user_input_vector),
embedding
)
LIMIT 10;
VEC_DISTANCE_COSINE
및 VEC_DISTANCE_EUCLIDEAN
함수는 두 개의 벡터를 사용합니다. 이전 예제에서 하나의 벡터는 사용자 입력을 기반으로 계산된 벡터이고, 다른 하나는 products
테이블의 각 레코드에 대한 해당 벡터입니다.
실용적인 예제
Java를 사용하여 AI 프레임워크 없이 실용적인 예제를 준비했습니다. 이를 통해 MariaDB의 벡터 검색 기능을 활용한 생성 AI 애플리케이션을 만드는 과정을 진정으로 이해할 수 있습니다. 코드는 GitHub에서 확인할 수 있습니다.
Source:
https://dzone.com/articles/vector-storage-indexing-and-search-with-mariadb