8 ตุลาคม 2567

Published ตุลาคม 08, 2567 by with 0 comment

สร้างฐานข้อมูล vector search ด้วย sqlite-vec ในภาษา Python

ทุกวันนี้การสร้างระบบค้นคืนข้อมูล หรือ RAG กำลังเป็นที่นิยมในหมู่นักพัฒนาปัญญาประดิษฐ์ทั่วโลกที่ใช้งาน Gen AI หนึ่งในสิ่งที่สำคัญ คือ ฐานข้อมูลเวกเตอร์ สำหรับทำการจัดเก็บและสืบค้นเวกเตอร์ ให้มีความสะดวกรวดเร็ว หนึ่งในนั้นคือ sqlite-vec


sqlite-vec เป็นส่วนขยายของฐานข้อมูล SQLite เพื่อให้สามารถจัดเก็บเวกเตอร์และสามารถสืบค้นเวกเตอร์ได้ รองรับหลากหลายภาษารวมถึงภาษา Python


ก่อนที่เราจะไปเริ่มต้น หากผู้อ่านไม่เคยศึกษาฐานข้อมูล SQLite มาก่อน สามารถศึกษาได้ที่บทความ เชื่อมต่อกับฐานข้อมูล SQLite ใน Python 3


ก่อนอื่นให้ติดตั้งด้วยคำสั่ง pip: pip install sqlite-vec

เรามาเริ่มต้นกัน เริ่มจากก่อนอื่นให้ทำการโหลดส่วนขยายก่อนใช้งานฐานข้อมูล SQLite ทุกครั้งดังนี้

import sqlite3
import sqlite_vec



db = sqlite3.connect(":memory:") # จัดเก็บไว้ในหน่วยความจำ
db.enable_load_extension(True)
sqlite_vec.load(db)
db.enable_load_extension(False)
จะเห็นได้ว่า เมื่อต้องการเรียกใช้งานทุกครั้งอย่าลืม 

db.enable_load_extension(True)

sqlite_vec.load(db)

db.enable_load_extension(False)

เมื่อทำการโหลดเสร็จสิ้นแล้ว ต่อไปเรามาสร้างตารางข้อมูลสำหรับใช้จัดเก็บเวกเตอร์บนฐานข้อมูล SQLite

db.execute("""create virtual table vec_documents using vec0(
document_id integer primary key,
contents_embedding float[4]
);""")

db.commit()

สร้างตารางชื่อ vec_documents ขึ้นมาโดยมีฟิลด์ document_id สำหรับใช้เก็บไอดีของเอกสาร และ contents_embedding สำหรับใช้เวกเตอร์ โดยมีขนาด 4 ช่อง


ต่อไป เรามาเพิ่มข้อมูลเวกเตอร์ลงฐานข้อมูลกัน

from sqlite_vec import serialize_float32  # สำหรับแปลง list ให้สามารถบรรจุลงฐานข้อมูลได้

with db:
    db.execute(
            "INSERT INTO vec_documents(document_id, contents_embedding) VALUES(?, ?)",
            [1, serialize_float32([1.0,1.0,0.5,1.0])],
    )

เราทำการเพิ่มไอดี 1 โดยมีข้อมูล [1.0,1.0,0.5,1.0 เข้าไปในตารางชื่อ vec_documents หลังจากนี้เรามาลองเพิ่มข้อมูลกันเข้าไปอีก

with db:
    db.execute(
            "INSERT INTO vec_documents(document_id, contents_embedding) VALUES(?, ?)",
            [2, serialize_float32([-1.0,0.1,0.1,0.0])],
    )
    db.execute(
            "INSERT INTO vec_documents(document_id, contents_embedding) VALUES(?, ?)",
            [3, serialize_float32([-0.5,0.4,0.1,0.5])],
    )

จากนั้น มาทำการสืบค้นข้อมูลเวกเตอร์ด้วยฐานข้อมูลเวกเตอร์ SQLite ที่เราสร้างขึ้นมาเพื่อจัดเก็บเวกเตอร์

สำหรับการสืบค้น sqlite-vec รองรับการสืบค้นโดยใช้ K-nearest-neighbors (KNN) queries เราสามารถสืบค้นเวกเตอร์เพื่อนบ้านใกล้เคียงได้ โดยกำหนดค่า k เทียบกับเวกเตอร์ที่เราต้องการ ด้วยวิธีนี้ช่วยให้การสืบค้นเวกเตอร์เต็มไปด้วยประสิทธิภาพที่แม่นยำยิ่งขึ้น

สมมติว่า เราต้องการสืบค้นด้วยเวกเตอร์ [0.9,0.8,0.85,0.85] และกำหนดค่า k=1 สามารถสืบค้นด้วยคำสั่ง sql ตามนี้

with db:
    results = db.execute(
        "select document_id,distance from vec_documents where contents_embedding match ? and k = 1;",
        [serialize_float32([0.9,0.8,0.85,0.85])],
    ).fetchall()
    print(results)

ผลลัพธ์

[(1, 0.44158804416656494)]

จะเห็นได้ว่าเวกเตอร์เอกสารไอดี 1 มีความใกล้เคียงกับเวกเตอร์ [0.9,0.8,0.85,0.85] ที่เราต้องการมากที่สุด

อ่านเอกสารเพิ่มเติมได้ที่ https://github.com/asg017/sqlite-vec

0 ความคิดเห็น:

แสดงความคิดเห็น

แสดงความคิดเห็นได้ครับ :)