Machine Learning trực tiếp trong PostgreSQL: Huấn luyện và dự báo bằng SQL

AI tutorial - IT technology blog
AI tutorial - IT technology blog

Những rào cản tiềm ẩn trong các Pipeline Machine Learning truyền thống

Việc thêm các tính năng AI vào ứng dụng thường bắt đầu bằng một vấn đề đau đầu quen thuộc. Bạn có một cơ sở dữ liệu PostgreSQL đang chạy (production) chứa đầy dữ liệu người dùng sạch sẽ, nhưng các mô hình ML của bạn lại nằm trong một môi trường Python riêng biệt hoặc trên một dịch vụ đám mây. Để kết nối chúng, bạn phải xây dựng các pipeline ETL (Trích xuất, Chuyển đổi, Tải) vốn thường xuyên bị lỗi ngay khi đồng nghiệp thay đổi cấu trúc bảng (schema).

Tôi đã từng dành cả cuối tuần để gỡ lỗi các pipeline bị hỏng khi dữ liệu huấn luyện không còn đồng bộ với dữ liệu thực tế. Vào thời điểm dữ liệu của bạn đến được mô hình Scikit-learn hoặc XGBoost thông qua truyền tải mạng, nó đã trở nên lỗi thời. Độ trễ này khiến các tính năng thời gian thực—như chặn một giao dịch thẻ tín dụng gian lận trong dưới 200ms—gần như không thể duy trì.

Tại sao việc di chuyển dữ liệu là nút thắt cổ chai thực sự

Vấn đề cốt lõi không nằm ở toán học đằng sau các mô hình; đó là “Trọng lực dữ liệu” (Data Gravity). Việc di chuyển các tập dữ liệu khổng lồ qua ranh giới mạng tạo ra ba điểm yếu cụ thể:

  • Độ trễ (Latency): Việc tuần tự hóa các hàng dữ liệu sang JSON, gửi chúng qua mạng và nạp vào Python DataFrame tạo ra chi phí vận hành đáng kể. Với một tập dữ liệu 100MB, việc này có thể dễ dàng gây ra độ trễ vài giây.
  • Rủi ro bảo mật: Mỗi khi dữ liệu rời khỏi cơ sở dữ liệu đã được mã hóa để nằm trong một bucket S3 hoặc tệp CSV cục bộ, bề mặt tấn công (attack surface) của bạn sẽ tăng lên.
  • Phình to hạ tầng: Bạn sẽ phải quản lý cơ sở dữ liệu, feature store, máy chủ huấn luyện và một API phục vụ mô hình như FastAPI.

Khi chúng ta tách biệt tính toán khỏi lưu trữ, chúng ta phải trả một khoản “thuế kiến trúc” đắt đỏ. Các cơ sở dữ liệu vốn đã được tối ưu hóa để quét hàng triệu dòng dữ liệu. Việc đưa mô hình đến gần dữ liệu thường nhanh hơn nhiều so với việc đưa dữ liệu đến mô hình.

So sánh các phương pháp: Python Script và ML trong cơ sở dữ liệu

Hầu hết các đội ngũ kỹ thuật thường chọn một trong ba con đường sau khi triển khai trí tuệ nhân tạo:

1. Phương pháp Python truyền thống

Các kỹ sư sử dụng psycopg2 để lấy dữ liệu và pickle để lưu mô hình. Mặc dù linh hoạt, phương pháp này đòi hỏi một lượng lớn “mã kết nối” (glue code) để giữ cho môi trường ổn định. Nếu phiên bản Python thay đổi, mô hình của bạn có thể không tải được nữa.

2. Phương pháp Cloud-Native (SageMaker/Vertex AI)

Các dịch vụ được quản lý (managed services) rất mạnh mẽ nhưng đi kèm với chi phí cao và bị phụ thuộc vào nhà cung cấp (vendor lock-in). Bạn vẫn phải đối mặt với vấn đề đồng bộ hóa: cơ sở dữ liệu và dịch vụ ML của bạn phải luôn nhất quán 24/7.

3. Phương pháp trong cơ sở dữ liệu (PostgresML)

Phương pháp này nhúng trực tiếp công cụ ML vào PostgreSQL. Thay vì gọi một API từ xa, bạn chỉ cần chạy SELECT pgml.predict(). Điều này loại bỏ hoàn toàn lớp ETL khỏi hệ thống của bạn.

Triển khai PostgresML

PostgresML là một tiện ích mở rộng (extension) mang Scikit-learn, XGBoost và LightGBM trực tiếp vào quy trình xử lý của cơ sở dữ liệu. Nó coi các mô hình ML như các đối tượng cơ sở dữ liệu chuẩn. Trong các thử nghiệm thực tế của tôi, thiết lập này đã giảm thời gian triển khai từ vài ngày xuống còn vài phút, đặc biệt là đối với các tác vụ dữ liệu có cấu trúc như chấm điểm khách hàng tiềm năng (lead scoring).

Thiết lập môi trường

Tránh rắc rối khi biên dịch các phụ thuộc C++ bằng cách sử dụng container Docker đã được cấu hình sẵn. Container này bao gồm sẵn PostgreSQL và tiện ích mở rộng PostgresML.

docker run \
  -it \
  -v postgresml_data:/var/lib/postgresql \
  -p 5432:5432 \
  -p 8000:8000 \
  ghcr.io/postgresml/postgresml:latest

Sau khi container khởi động, hãy kết nối bằng bất kỳ trình khách SQL (SQL client) nào và kích hoạt tiện ích mở rộng:

CREATE EXTENSION IF NOT EXISTS pgml;

Huấn luyện mô hình bằng SQL

Giả sử bạn có bảng user_activity. Bạn muốn dự đoán người dùng nào sẽ hủy đăng ký dựa trên tần suất đăng nhập. Thay vì xuất một tệp CSV 5GB, bạn chỉ cần chạy một câu truy vấn duy nhất:

SELECT * FROM pgml.train(
    'Mô hình dự báo rời bỏ',
    'classification',
    'user_activity_table',
    'churn_label',
    'xgboost'
);

PostgresML sẽ xử lý các công việc nặng nhọc. Nó chụp ảnh dữ liệu (snapshot), chia thành các tập huấn luyện và kiểm tra, sau đó lưu trữ trọng số mô hình trực tiếp trong một bảng hệ thống. Không cần đến các tệp tin bên ngoài.

Thực hiện dự báo thời gian thực

Sau khi được huấn luyện, mô hình của bạn đã sẵn sàng để sử dụng ngay lập tức. Bạn có thể lồng các dự báo trực tiếp vào các câu truy vấn hiện có của ứng dụng.

SELECT 
    email, 
    pgml.predict('Mô hình dự báo rời bỏ', ARRAY[login_count, support_tickets, days_active]) AS churn_probability
FROM users
WHERE user_id = 12345;

Vì việc dự báo diễn ra bên trong cơ sở dữ liệu, độ trễ mạng thực tế bằng không. Nếu ứng dụng của bạn cần hiển thị điểm rủi ro trên bảng điều khiển (dashboard), backend chỉ cần thực thi một câu lệnh SQL chuẩn. Nó không cần phải điều phối với một dịch vụ AI bên ngoài.

Xử lý Feature Engineering

Việc chuyển đổi dữ liệu thô thành các đặc trưng (features) thường chiếm 80% khối lượng công việc. PostgresML tận dụng các SQL view cho việc này. Bạn có thể định nghĩa logic của mình—như tính toán mức chi tiêu trung bình của người dùng trong 30 ngày—bằng SQL chuẩn, sau đó trỏ tác vụ huấn luyện vào view đó.

CREATE VIEW user_features AS
SELECT 
    user_id,
    extract(day from now() - created_at) as account_age,
    count(logs.id) as total_logins
FROM users
JOIN logs ON logs.user_id = users.id
GROUP BY users.id;

Hiệu suất và tính ổn định trong môi trường thực tế

Một nỗi sợ phổ biến là việc chạy ML sẽ làm sập cơ sở dữ liệu. Tuy nhiên, PostgresML chạy trong một không gian tiến trình riêng biệt trong khi vẫn chia sẻ trình quản lý bộ nhớ của PostgreSQL. Theo kinh nghiệm của tôi, một instance cơ sở dữ liệu 4 lõi tiêu chuẩn có thể xử lý hơn 5.000 dự báo mỗi giây với độ trễ dưới 10ms.

Để mở rộng quy mô hơn nữa, hãy sử dụng chiến lược read-replica. Thực hiện huấn luyện nặng trên node chính (primary) trong giờ thấp điểm, sau đó sao chép các bảng mô hình sang các instance chỉ đọc (read-only) để suy luận (inference) tốc độ cao trên toàn bộ cluster của bạn.

Lời kết

Đưa tính toán đến gần dữ liệu là một sự thay đổi lớn đối với các kỹ sư backend. Bằng cách sử dụng PostgresML, bạn có thể triển khai các mô hình cấp độ sản xuất mà không cần hạ tầng mong manh vốn thường ám ảnh các dự án AI. Nếu bạn có thể viết một câu lệnh SELECT, giờ đây bạn đã có thể xây dựng và triển khai machine learning.

Share: