Tech Blog

วางตัวตัดสินความเกี่ยวข้องขนาดเล็กไว้หน้า RAG — ไม่ส่งทุกอย่างที่ค้นเจอผ่านไปทั้งหมด

RAG QLoRA Fine-tuning CRAG AI

บทนำ

ฉันใช้งานฐานความรู้ส่วนตัว (RAG) ที่เก็บบันทึกประจำวันและดึงออกมาด้วยการค้นหาเชิงความหมาย เรื่องการเพิ่มความแม่นยำในการค้นหาด้วยตัวเลขเองนั้น ฉันเขียนไว้ใน การปรับปรุงความแม่นยำการค้นหา RAG แบบขับเคลื่อนด้วยการวัดผล

แต่ต่อให้การค้นหาเก่งขึ้นแล้ว ก็ยังมีปัญหาที่เหลืออยู่ การค้นหาแบบเวกเตอร์จะดึง “สิ่งที่ใกล้เคียงกันในเชิงความหมาย” มาให้ แต่บางอย่างที่ใกล้เคียงกันก็ไม่เกี่ยวข้องกับคำถามจริงๆ นี่คืออีกด้านหนึ่งของความตรงไปตรงมาของ embedding ซึ่งฉันเขียนไว้ในอีกบทความหนึ่งด้วย (กับดักที่การค้นหาเวกเตอร์ปนหมวดหมู่อื่นเข้ามา)

ถ้าส่งทุกอย่างที่ดึงมาตรงไปให้ LLM ทั้งหมด ความทรงจำที่ไม่เกี่ยวข้องจะกลายเป็นสัญญาณรบกวนและทำให้คำตอบขุ่นมัว บทความนี้เป็นเรื่องการวางตัวตัดสินขนาดเล็กไว้ระหว่างการค้นหากับ LLM เพื่อตัดสินว่า “สิ่งนี้เกี่ยวข้องจริงหรือไม่”


ปัญหา: การค้นเจอ ≠ คำตอบที่ถูกต้อง

RAG แบบไร้เดียงสาจะยัดทุกอย่างที่ขึ้นอันดับบนสุดของการค้นหาลงใน prompt ของ LLM โดยตรง ไม่มีประตูคุณภาพคอยกรอง

คำถาม


การค้นหา (ดึงสิ่งที่ใกล้เคียงเชิงความหมายจากอันดับบนสุด)
  │  ← สิ่งที่แค่ใกล้เคียงแต่ "ไม่เกี่ยวข้อง" ก็ขึ้นมาปนด้วย

ส่งทุกอย่างที่ดึงมาให้ LLM ทั้งหมด  ← ความทรงจำที่ไม่เกี่ยวข้องทำให้คำตอบขุ่นมัว

“ใกล้เคียงเชิงความหมาย” ไม่ได้แปลว่า “เกี่ยวข้อง” เสมอไป เมื่อบันทึกที่แค่มีคำคล้ายกันแต่ไม่เกี่ยวข้องกับคำถามเลยปนเข้ามา LLM ก็จะถูกดึงไปตามนั้น


แนวคิด: วางตัวตัดสินไว้ระหว่างการค้นหากับ LLM (CRAG)

แกนของมาตรการนี้เรียบง่าย หลังจากค้นหาแล้ว ก่อนส่งให้ LLM ให้ตัดสิน “เกี่ยวข้องหรือไม่” ทีละรายการ ปล่อยให้เฉพาะที่เกี่ยวข้องผ่านไป ตัดสิ่งที่ไม่เกี่ยวข้องทิ้ง เพราะเป็นการแก้ไขคุณภาพหลังการค้นหา รูปแบบนี้จึงเรียกว่า CRAG (Corrective RAG)

คำถาม


การค้นหา (ดึงสิ่งที่ใกล้เคียงเชิงความหมายมา)


┌──────────────────────────────────────────────┐
│ ตัวตัดสิน: ความทรงจำนี้เกี่ยวข้องกับคำถามนี้หรือไม่? (ตัดสินแบบสองค่า) │
└──────────────────────────────────────────────┘

  ├─ เกี่ยวข้อง   ─▶ ส่งให้ LLM
  └─ ไม่เกี่ยวข้อง ─▶ ตัดทิ้ง (ไม่ทำให้คำตอบสกปรก)

ทำไมต้องเป็น “ตัวตัดสินขนาดเล็ก” ไม่ใช่ “LLM ขนาดใหญ่”

การตัดสินเองก็ทำได้ด้วย LLM ขนาดใหญ่เหมือนกัน แต่การถาม LLM ขนาดใหญ่ทีละรายการทุกครั้งที่ค้นหานั้นช้าและหนัก และถ้าส่งไปยัง API ภายนอก ก็เท่ากับส่งความทรงจำของตัวเองขึ้นคลาวด์ทุกครั้งด้วย

ฉันจึงเตรียมโมเดลขนาดเล็กที่เชี่ยวชาญเฉพาะการตัดสินเท่านั้น และไม่ใช่การตัดสินแบบทั่วไป แต่ปรับแต่งด้วย ข้อมูลฝึกที่ตรงกับโดเมนของ RAG ของตัวเอง เพราะงานของตัวตัดสินมีแค่สองค่า “ใช้/ไม่ใช้” โมเดลเล็กก็เพียงพอแล้ว

【ให้ LLM ขนาดใหญ่ตัดสินทุกครั้ง】
   ผลการค้นหา ─▶ โมเดลขนาดใหญ่ ─▶ ตัดสิน   … ช้า หนัก (ถ้าเป็นภายนอก) ส่งข้อมูลขึ้นคลาวด์

【ตัวตัดสินขนาดเล็กที่ปรับแต่งตามโดเมนของตัวเอง】
   ผลการค้นหา ─▶ โมเดลขนาดเล็ก (ในเครื่อง) ─▶ ใช้ / ไม่ใช้   … เร็ว เบา จบในเครื่อง

ข้อดีของการทำให้จบในเครื่องไม่ใช่แค่ความเร็ว ยังตัดสินได้โดยไม่ต้องส่งความทรงจำของตัวเองออกไปข้างนอกเลย (ความเป็นส่วนตัว) สำหรับ RAG ที่จัดการบันทึกส่วนตัว เรื่องนี้สำคัญมาก


สิ่งที่สร้างขึ้น (ผลวัดจริง)

ฐานคือโมเดลขนาดเล็กที่ผ่านการปรับแต่งตามคำสั่งแล้ว (Qwen2.5-3B) ฉันปรับแต่งโมเดลนี้ด้วย QLoRA (quantization 4bit + LoRA) ให้ตัดสินความเกี่ยวข้องแบบสองค่า การฝึกทำบน GPU โน้ตบุ๊กในเครื่อง (RTX 2070 Max-Q) ใช้เวลาประมาณ 1 ชั่วโมง 53 นาที loss สุดท้ายอยู่ที่ประมาณ 1.45 และความแม่นยำในการตัดสินแบบสองค่าอยู่ที่ประมาณ 76%

76% ไม่ใช่ความสมบูรณ์แบบ แต่หน้าที่ของตัวตัดสินคือ “ตัดสิ่งที่ไม่เกี่ยวข้องอย่างชัดเจนทิ้ง” ไม่ใช่การคัดกรองที่สมบูรณ์แบบ ในฐานะตะแกรงกรองด่านแรก มันทำงานได้เพียงพอแล้ว จริงๆ แล้วตอนนี้ตัวตัดสินนี้ทำงานทุกครั้งที่มีการค้นหา คอยตัดชิ้นส่วนที่มีความเกี่ยวข้องต่ำทิ้งอย่างเงียบๆ

แทนที่จะทำให้ตัวเลขดูดีเกินจริง ขอพูดตรงๆ เล็ก เร็ว จบในเครื่อง และตัดสัญญาณรบกวนที่ชัดเจนทิ้งได้ — นั่นคือเป้าหมาย และเป้าหมายนั้นก็บรรลุแล้ว


เพื่อไม่ให้การค้นเจอกลายเป็นคำตอบที่ถูกต้อง

การค้นเจอไม่ใช่คำตอบที่ถูกต้อง วางตัวตัดสินไว้ก่อนส่งผ่าน อย่าส่งทุกอย่างที่ขึ้นอันดับบนในการค้นหาให้ LLM ตรงๆ ทั้งหมด “ใกล้เคียงเชิงความหมาย” กับ “เกี่ยวข้อง” เป็นคนละเรื่อง ต้องแทรกด่านตรวจสอบความเกี่ยวข้องไว้หนึ่งชั้น

ตัวตัดสินไม่จำเป็นต้องพึ่งโมเดลขนาดใหญ่ สร้างให้เล็กและเฉพาะทางได้ สำหรับงานที่จำกัดอย่างการตัดสินแบบสองค่า การปรับแต่งโมเดลเล็กด้วยข้อมูลฝึกในโดเมนของตัวเองก็เพียงพอ เร็ว เบา และทำงานในเครื่องได้

ทำให้จบในเครื่อง อย่าส่งความทรงจำออกไปข้างนอก ถ้าจัดการบันทึกส่วนตัว ให้เลือกโครงสร้างที่ไม่ต้องส่งเนื้อหาขึ้นคลาวด์เพียงเพื่อการตัดสิน

การทำให้ค้นหาเร็วเป็นแค่ครึ่งหนึ่งของการปรับแต่ง การกรองสิ่งที่ดึงมาด้วยว่ามันเกี่ยวข้องจริงหรือไม่ — ต่อเมื่อมีตัวตัดสินนี้ RAG จึงจะเริ่มคืนสิ่งที่ “มีประโยชน์” ไม่ใช่แค่ “ใกล้เคียง”


บทความที่เกี่ยวข้อง

ส่งข้อความได้ตามสบาย

ไม่ว่าจะเป็นการว่าจ้างงาน แนะนำโปรเจกต์ ความคิดเห็น หรือคำถาม ยินดีรับทั้งหมด ผมหวังเป็นอย่างยิ่งว่าจะได้เชื่อมต่อกับผู้ที่มีอุดมการณ์อันสูงส่งเช่นเดียวกัน ผมจะมุ่งมั่นท้าทายในสิ่งที่ทุ่มเททั้งชีวิตต่อไป ขอขอบคุณและฝากเนื้อฝากตัวด้วยครับ