1. Cài đặt extension pgvector cho PostgreSQL
1.1. Tải và biên dịch pgvector
PostgreSQL trên Ubuntu 24.04 chưa bao gồm sẵn extension pgvector trong repository mặc định. Chúng ta cần tải source code từ GitHub, biên dịch và cài đặt thủ công để có đầy đủ các hàm vector.
Tải mã nguồn, cài đặt các dependency cần thiết cho việc build (gcc, postgresql-server-dev), sau đó chạy lệnh make để biên dịch.
cd /tmp
git clone https://github.com/pgvector/pgvector.git
cd pgvector
apt-get update
apt-get install -y postgresql-server-dev-16
make
Kết quả mong đợi: Quá trình biên dịch hoàn tất, xuất hiện thông báo "make: Nothing to be done for 'all'" hoặc "make: Leaving directory..." mà không có lỗi (error).
1.2. Cài đặt extension vào cluster
Sử dụng lệnh make install để copy các file shared object (.so) và extension script (.sql) vào thư mục module của PostgreSQL.
sudo make install
Kết quả mong đợi: Các file được copy vào thư mục /usr/lib/postgresql/16/lib/ và /usr/share/postgresql/16/extension/.
1.3. Khởi động lại PostgreSQL và kích hoạt extension
Để PostgreSQL nhận diện extension mới, cần khởi động lại service. Sau đó, đăng nhập vào database và tạo extension pgvector.
sudo systemctl restart postgresql
sudo -u postgres psql -c "CREATE EXTENSION vector;"
Kết quả mong đợi: Xuất hiện thông báo "CREATE EXTENSION" xác nhận extension đã được tạo thành công.
1.4. Verify kết quả cài đặt
Kiểm tra xem type vector đã xuất hiện trong database chưa bằng lệnh \dt+ hoặc query trực tiếp.
sudo -u postgres psql -c "\dx vector"
Kết quả mong đợi: Danh sách các extension hiển thị dòng "vector" với version hiện tại (ví dụ: 0.5.1 hoặc cao hơn).
2. Tạo bảng chứa dữ liệu văn bản và vector nhúng
2.1. Xác định kích thước vector
LlamaIndex thường sử dụng các model embedding có độ dài vector cố định. Phổ biến nhất là 1536 chiều (như text-embedding-ada-002) hoặc 768 chiều (như BERT). Ở đây ta chuẩn bị cho vector 1536 chiều.
Tạo một schema mới để quản lý các bảng RAG, sau đó tạo bảng chứa ID, nội dung văn bản (text), và cột vector.
sudo -u postgres psql -c "CREATE SCHEMA IF NOT EXISTS rag_data;"
sudo -u postgres psql -c "
CREATE TABLE rag_data.documents (
id SERIAL PRIMARY KEY,
text_content TEXT NOT NULL,
embedding vector(1536)
);"
Kết quả mong đợi: Thông báo "CREATE SCHEMA" và "CREATE TABLE" thành công.
2.2. Chèn dữ liệu mẫu (Mock Data)
Để test chức năng tìm kiếm, ta cần chèn một vài bản ghi mẫu vào bảng vừa tạo. Vector ở đây là mảng số float được đóng gói trong hàm vector().
sudo -u postgres psql -c "
INSERT INTO rag_data.documents (text_content, embedding)
VALUES
('PostgreSQL là một hệ quản trị cơ sở dữ liệu mã nguồn mở mạnh mẽ.',
vector(array[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0])),
('LlamaIndex là framework để xây dựng ứng dụng AI.',
vector(array[0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0]));"
Kết quả mong đợi: Thông báo "INSERT 0 2" xác nhận đã chèn 2 dòng dữ liệu.
2.3. Verify kết quả bảng
Tra cứu dữ liệu vừa chèn để đảm bảo cột vector lưu trữ đúng định dạng.
sudo -u postgres psql -c "SELECT id, text_content, embedding FROM rag_data.documents LIMIT 2;"
Kết quả mong đợi: Hiển thị 2 dòng với nội dung text và chuỗi vector tương ứng.
3. Cấu hình chỉ mục HNSW để tối ưu hóa tìm kiếm vector
3.1. Hiểu về chỉ mục HNSW
HNSW (Hierarchical Navigable Small World) là thuật toán chỉ mục giúp tìm kiếm tương tự (approximate nearest neighbor) nhanh hơn nhiều so với quét toàn bộ bảng (brute-force). Đây là lựa chọn mặc định cho pgvector khi làm việc với lượng dữ liệu lớn.
Ta sẽ tạo chỉ mục HNSW trên cột embedding. Tham số m và ef_construction ảnh hưởng đến tốc độ build và độ chính xác.
sudo -u postgres psql -c "
CREATE INDEX documents_embedding_idx ON rag_data.documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);"
Kết quả mong đợi: Thông báo "CREATE INDEX" thành công. Lệnh này có thể mất vài giây tùy số lượng dữ liệu.
3.2. Giải thích tham số chỉ mục
- vector_cosine_ops: Sử dụng khoảng cách Cosine Similarity, phù hợp nhất cho các vector embedding từ model ngôn ngữ lớn (LLM).
- m = 16: Số lượng kết nối trong mỗi nút của graph, ảnh hưởng đến độ chính xác.
- ef_construction = 64: Tham số ảnh hưởng đến thời gian build chỉ mục và chất lượng của graph.
3.3. Test tìm kiếm vector
Thực hiện một query tìm kiếm vector gần nhất với một vector mẫu. Sử dụng toán tử <-> để tính khoảng cách Cosine.
sudo -u postgres psql -c "
SELECT text_content, 1 - (embedding vector(array[0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0])) AS similarity
FROM rag_data.documents
ORDER BY embedding vector(array[0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0])
LIMIT 1;"
Kết quả mong đợi: Trả về dòng "LlamaIndex là framework..." với độ tương tự (similarity) cao hơn dòng PostgreSQL.
3.4. Verify kết quả chỉ mục
Kiểm tra xem chỉ mục đã được tạo và đang được sử dụng (visible trong catalog) chưa.
sudo -u postgres psql -c "\di rag_data.*"
Kết quả mong đợi: Danh sách chỉ mục hiển thị dòng "documents_embedding_idx" với loại "hnsw".
4. Kiểm tra kết nối từ ứng dụng Python đến PostgreSQL
4.1. Cài đặt thư viện psycopg2-binary
Ứng dụng Python cần thư viện để giao tiếp với PostgreSQL. Ta sử dụng psycopg2-binary để đơn giản hóa việc cài đặt driver C.
pip install psycopg2-binary
Kết quả mong đợi: Thông báo "Successfully installed psycopg2-binary..." mà không có lỗi.
4.2. Viết script kiểm tra kết nối và query vector
Tạo file Python để thực hiện: (1) Kết nối DB, (2) Tạo vector, (3) Thực hiện query tìm kiếm vector, (4) Đóng kết nối.
Lưu file dưới đường dẫn /home/ubuntu/test_vector_conn.py với nội dung sau:
import psycopg2
from psycopg2.extras import execute_values
# Cấu hình kết nối
conn = psycopg2.connect(
host="localhost",
port="5432",
dbname="postgres",
user="postgres",
password="" # Mặc định postgres trên Ubuntu không có password nếu dùng sudo -u
)
cursor = conn.cursor()
# Vector mẫu để tìm kiếm (giả lập vector của từ "AI")
# Trong thực tế, vector này sẽ được LlamaIndex sinh ra
query_vector = [0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0]
# Query tìm kiếm vector gần nhất sử dụng chỉ mục HNSW
sql = """
SELECT text_content, 1 - (embedding %s::vector) AS similarity
FROM rag_data.documents
ORDER BY embedding %s::vector
LIMIT 3
"""
cursor.execute(sql, (query_vector, query_vector))
results = cursor.fetchall()
print("Kết quả tìm kiếm vector từ Python:")
for row in results:
print(f"Text: {row[0]} | Similarity: {row[1]:.4f}")
cursor.close()
conn.close()
print("Kết nối đã đóng thành công.")
Kết quả mong đợi: Script chạy, in ra danh sách các văn bản cùng độ tương tự, và thông báo đóng kết nối.
4.3. Chạy script kiểm tra
Chạy script bằng Python để xác nhận pipeline từ ứng dụng đến Database hoạt động trơn tru.
python3 /home/ubuntu/test_vector_conn.py
Kết quả mong đợi: Xuất hiện output tương tự như khi chạy trực tiếp trên psql, xác nhận Python có thể truy vấn cột vector đã index.
4.4. Verify kết quả kết nối
Nếu script chạy không báo lỗi (No Traceback) và in ra dữ liệu, chứng tỏ:
1. PostgreSQL đang chạy và lắng nghe cổng 5432.
2. Extension pgvector đã được load đúng.
3. Chỉ mục HNSW đang hoạt động.
4. Python driver (psycopg2) tương thích với phiên bản DB.
Điều hướng series:
Mục lục: Series: Triển khai Database AI với LlamaIndex và PostgreSQL trên Ubuntu 24.04
« Phần 1: Chuẩn bị môi trường Ubuntu 24.04 và cài đặt PostgreSQL
Phần 3: Thiết lập môi trường Python và cài đặt LlamaIndex »