21 คะแนน โดย GN⁺ 2024-10-25 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • สามารถสร้าง "Hybrid Search" ในแอปพลิเคชันได้โดยใช้ส่วนขยาย Full-Text Search (FTS5) พื้นฐานของ SQLite ร่วมกับการค้นหาเชิงความหมายของ sqlite-vec
    • สามารถผสานผลลัพธ์ได้หลายวิธี เช่น ให้ความสำคัญกับคีย์เวิร์ดก่อน, จัดอันดับใหม่ตาม "semantic", หรือใช้ Reciprocal Rank Fusion
    • ที่สำคัญที่สุดคือทุกอย่างรวมอยู่ใน SQLite จึงทำให้การทดลองและการทำต้นแบบทำได้ง่ายและต้นทุนต่ำ โดยไม่ต้องพึ่งบริการภายนอก
  • กรณีใช้งานหลักของ sqlite-vec และเครื่องมือค้นหาเวกเตอร์อื่น ๆ คือการเพิ่ม "การค้นหาเชิงความหมาย" ให้กับข้อมูลข้อความ
    • การค้นหาแบบ Full-Text Search เพียงอย่างเดียว (การค้นหาด้วยคีย์เวิร์ด) ไม่ได้ให้ผลลัพธ์ที่ดีเสมอไป
      • เมื่อค้นหา "climate change" จะไม่คืนเอกสารอย่าง "global warming"
      • เมื่อใช้การค้นหาเชิงความหมาย จะสามารถค้นหาผลลัพธ์ตาม "ความหมายโดยรวม" และคืนผลลัพธ์ที่มีบริบทสมบูรณ์ยิ่งขึ้นได้
    • แต่การใช้เพียง "การค้นหาเชิงความหมาย" อย่างเดียวก็อาจส่งผลเสียต่อแอปพลิเคชันได้

เดโม: พาดหัวข่าว NBC News

  • ใช้ชุดข้อมูลที่มีพาดหัวมากกว่า 14,500 รายการ ตั้งแต่เดือนมกราคมถึงสิงหาคม 2024
  • ข้อมูลข้อความรวมมีขนาดเพียง 4.3MB เป็นชุดข้อมูลที่เล็กมาก

การสร้างตาราง FTS5

  • สร้างตารางเสมือนสำหรับ Full-Text Search ชื่อ fts_headlines
  • ประกาศคอลัมน์ headline
  • กำหนดค่าออปชัน content= และ content_rowid=
  • ทำ INSERT INTO โดยตรงจากตาราง articles หลัก
  • การคิวรีตาราง FTS5 ต้องใช้เพียงคำสั่ง SELECT เดียว

การสร้าง Vector Search ด้วย sqlite-vec

  • sqlite-vec มีความสามารถในการจัดเก็บเวกเตอร์และเปรียบเทียบเวกเตอร์ แต่ไม่ได้สร้าง embedding ให้เอง
  • ในตัวอย่างนี้ใช้ส่วนขยาย sqlite-lembed และ Snowflake Artic Embed 1.5 model
  • ฝังข้อความด้วย lembed() แล้วจัดเก็บไว้ในตารางเสมือน vec0
  • การทำ KNN query ต้องใช้เพียงคำสั่ง SELECT เดียว

แนวทางแบบไฮบริด 1: "คีย์เวิร์ดมาก่อน"

  • คืนผลลัพธ์จาก Full-Text Search ก่อน แล้วจึงเติมส่วนที่เหลือด้วยการค้นหาเวกเตอร์
  • สามารถทำได้ด้วย CTE
  • รวมผลลัพธ์ด้วย UNION ALL

แนวทางแบบไฮบริด 2: Reciprocal Rank Fusion (RRF)

  • จัดอันดับผลลัพธ์จาก FTS5 และ vector match
  • สามารถทำได้ด้วยคำสั่ง SELECT เดียวและ CTE
  • สามารถเปลี่ยนค่า :weight_fts หรือ :weight_vec เพื่อปรับอันดับผลลัพธ์ FTS5/เวกเตอร์ให้ต่างกันได้

แนวทางแบบไฮบริด 3: จัดอันดับใหม่ตามความหมาย

  • ทำเฉพาะการค้นหา FTS5 แต่จัดเรียงผลลัพธ์ใหม่ตามระยะห่างของเวกเตอร์
  • ยังคงได้เฉพาะผลลัพธ์ที่ตรงกับคีย์เวิร์ด แต่ผลลัพธ์ที่มีความหมายสอดคล้องดีกว่าจะถูกเลื่อนขึ้นมาอยู่ด้านบน
  • ช่วยแก้ข้อเสียของ BM25

ควรเลือกแนวทางไหน?

  • ขึ้นอยู่กับแอปพลิเคชันและกรณีใช้งาน
  • หากสร้าง search engine สำหรับกล่องจดหมายอีเมล การให้คีย์เวิร์ดมาก่อนจะเหมาะกว่า
  • หากสร้าง RAG สำหรับเอกสารภายในบริษัท RRF เป็นตัวเลือกที่ดี
  • หากสร้างฟีเจอร์ "โพสต์ซ้ำ" ในเว็บแอป การจัดอันดับใหม่ตามความหมายจะทำงานได้ดี

การปรับปรุงในอนาคต

  • คิวรี FTS5 สามารถแสดงส่วนที่ตรงกันในเอกสารด้วย "highlight" ได้ แต่ sqlite-vec คืนเพียงระยะ L2/โคไซน์ระหว่าง query vector กับเอกสาร
  • คิวรี FTS5 ยังมีความสามารถอื่น เช่น วลี, คิวรี NEAR และ boolean operator แต่เมื่อนำไปใช้กับ vector search จะดูไม่ค่อยลงตัว
  • การขยาย Hybrid Search ด้วย FTS5 + sqlite-vec อาจยังดูไม่ลื่นไหลนัก
  • ตาราง FTS5 จะค้นหาทั้งชุดข้อมูลทั้งหมดทุกครั้ง จึงไม่รองรับ metadata filtering หรือการรองรับดัชนี FTS5 เดียว
  • sqlite-vec ก็เช่นกัน แต่กำลังจะรองรับ partitioning และ metadata filtering ในเร็ว ๆ นี้

ความเห็นของ GN⁺

  • Hybrid Search บน SQLite ดูมีประโยชน์กับแอปพลิเคชันหลากหลายประเภท เพราะทดลองและทำต้นแบบได้ง่าย จุดเด่นคือข้อมูลถูกเก็บในไฟล์เดียว, สามารถทดสอบหลายคิวรีได้ด้วยคำสั่ง SELECT เดียว, ไม่มีค่าใช้จ่าย, ใช้งานได้กับทุกภาษาโปรแกรม และทำได้ง่ายด้วยโค้ดเพียงไม่กี่บรรทัด
  • อย่างไรก็ตาม ยังมีจุดที่ต้องปรับปรุงระหว่าง FTS5 กับ sqlite-vec อยู่บ้าง FTS5 สามารถเน้นส่วนที่ตรงกันในเอกสารได้ แต่ sqlite-vec คืนเพียงระยะห่างระหว่าง query vector กับเอกสารเท่านั้น นอกจากนี้ เมื่อใช้ความสามารถขั้นสูงของ FTS5 การนำมารวมกับ vector search อาจยังดูไม่ค่อยลงตัว
  • แม้มีข้อจำกัดเหล่านี้ Hybrid Search บน SQLite ก็ยังเป็นโซลูชันที่ทรงพลัง ซึ่งช่วยดึงข้อดีของทั้งการค้นหาด้วยคีย์เวิร์ดและการค้นหาเชิงความหมายมาใช้ได้ ไม่ว่าขนาดข้อมูลหรือประเภทของแอปพลิเคชันจะเป็นแบบใด
  • ในสถานการณ์ที่การสกัดข้อมูลจากข้อมูลไร้โครงสร้างและทำให้ค้นหาได้มีความสำคัญมากขึ้นเรื่อย ๆ การผสานการค้นหาด้วยคีย์เวิร์ดอย่าง FTS5 เข้ากับการค้นหาเวกเตอร์อย่าง sqlite-vec ทำให้สามารถค้นหาได้อย่างซับซ้อนขึ้น โดยพิจารณาทั้งความตรงกันของคีย์เวิร์ดและความเกี่ยวข้องตามบริบท
  • ไม่ว่าจะเป็นการเพิ่ม sqlite-vec เข้าไปในระบบค้นหาเดิม หรือพัฒนาแอปค้นหาใหม่ ก็ควรพิจารณา Hybrid Search บน SQLite โดยเฉพาะอย่างยิ่งความสามารถในการปรับแต่ง embedding model เองได้ ซึ่งเป็นข้อได้เปรียบอย่างมาก

1 ความคิดเห็น

 
halfenif 2024-10-27

ในโปรเจกต์ได้ทำงานใส่และประมวลผลข้อมูลมากกว่า 1 ล้านรายการลงใน sqlite

ถ้าปริมาณข้อมูลมาก ก็น่าจะต้องใช้ SSD ที่ดีพอสมควร (เพราะใช้ SATA SSD เลยรู้สึกว่าเวลาในการประมวลผลเพิ่มขึ้นพอสมควร)