สร้างโมเดล Embedding เฉพาะทางในเวลาไม่ถึงวัน ด้วย GPU ตัวเดียว
เคยไหมที่อยากให้โมเดล AI เข้าใจบริบทเฉพาะทางของธุรกิจคุณอย่างแท้จริง? แทนที่จะใช้โมเดลทั่วไปที่อาจตีความคลาดเคลื่อน หรือต้องเสียเวลาติดป้ายกำกับข้อมูลเองจำนวนมาก วันนี้เรามีวิธีที่จะเปลี่ยนโมเดล Embedding ทั่วไปให้กลายเป็นผู้เชี่ยวชาญในโดเมนของคุณได้ เพียงใช้ GPU เพียงตัวเดียวและเวลาฝึกฝนไม่ถึงหนึ่งวัน!
NVIDIA ได้นำเสนอแนวทางที่ช่วยให้คุณเริ่มต้นได้อย่างรวดเร็ว พร้อมปล่อยชุดข้อมูลสังเคราะห์ที่สร้างขึ้นจากเอกสารสาธารณะของ NVIDIA โดยใช้กระบวนการนี้โดยเฉพาะ การใช้ข้อมูลนี้และสูตรสำเร็จที่นำเสนอ ทำให้เราเห็นการปรับปรุงทั้ง Recall@10 และ NDCG@10 มากกว่า 10% ยิ่งไปกว่านั้น Atlassian ได้นำสูตรนี้ไปปรับใช้กับชุดข้อมูล JIRA ของพวกเขา ส่งผลให้ Recall@60 เพิ่มขึ้นจาก 0.751 เป็น 0.951 หรือคิดเป็นการปรับปรุงถึง 26% โดยใช้ GPU เพียงตัวเดียวเท่านั้น
🔗 ลิงก์สำคัญสู่ชุดข้อมูลและโค้ด
- [ชุดข้อมูลสังเคราะห์จากเอกสารสาธารณะของ NVIDIA](ขอบคุณ แหล่งข้อมูล
https://huggingface.co/datasets/nvidia/domain-specific-embedding-finetune) - [สูตรสำเร็จสำหรับโครงการ Open Source](ขอบคุณ แหล่งข้อมูล
https://github.com/NVIDIA/NeMo/tree/main/examples/llm/domainspecificembeddings)
🧑💻 โครงการ Open Source ที่นำมาใช้
กระบวนการนี้ผสานรวมโครงการ Open Source ที่ทรงพลังหลายตัวเข้าด้วยกัน:
- NeMo Data Designer: สำหรับการสร้างข้อมูลสังเคราะห์
- NeMo Automodel: สำหรับการฝึกโมเดล Embedding
- BEIR: สำหรับการประเมินผลด้าน Information Retrieval
- NeMo Export-Deploy: สำหรับการแปลงโมเดลเป็น ONNX/TensorRT
- NVIDIA NIM: สำหรับการให้บริการ Inference ในระดับ Production
สิ่งที่คุณจะได้เรียนรู้จากบทความนี้:
- 📄 สร้างข้อมูลฝึกฝนจากเอกสารเฉพาะทาง: เรียนรู้วิธีสร้างข้อมูลสำหรับฝึกโมเดลโดยไม่ต้องติดป้ายกำกับเอง
- 🎯 ใช้ Hard Negative Mining: เทคนิคสำคัญในการฝึกแบบ Contrastive Training ให้มีประสิทธิภาพ
- 🔗 ปรับปรุงคุณภาพ Embedding: ด้วยการจัดการกับ Multi-hop Queries ที่ซับซ้อน
- ⚙️ Fine-tune โมเดล Bi-encoder: พัฒนาโมเดล Embedding ให้แม่นยำยิ่งขึ้น
- 📊 วัดผลการปรับปรุง: ประเมินว่าการ Fine-tune ช่วยเพิ่มประสิทธิภาพการค้นหาได้จริงหรือไม่
- 🚀 Deploy โมเดลที่ Fine-tune แล้ว: นำโมเดลไปใช้งานจริงใน Pipeline ของคุณ
🛠️ ขั้นตอนการสร้างโมเดล Embedding เฉพาะทาง
ในบทความนี้ เราจะใช้โมเดลพื้นฐาน Llama-Nemotron-Embed-1B-v2 ซึ่งเป็นโมเดล Embedding ขนาด 1 พันล้านพารามิเตอร์ ที่มีความสมดุลระหว่างคุณภาพและความคุ้มค่าในการ Inference หากต้องการเริ่มต้น โปรดทำตาม [คู่มือการตั้งค่า](ขอบคุณ แหล่งข้อมูล
https://docs.nvidia.com/deeplearning/nemo/user-guide/docs/en/stable/models/embedding/domainspecificembeddings.html)
📚 ขั้นตอนที่ 1: สร้างข้อมูลฝึกฝนจากเอกสาร
การ Fine-tune โมเดล Embedding จำเป็นต้องมีคู่ (Query, Document ที่เกี่ยวข้อง) นับพันคู่ ซึ่งส่วนใหญ่แล้วจะไม่มีข้อมูลเหล่านี้พร้อมใช้งาน การสร้างด้วยตนเองนั้นมีค่าใช้จ่ายสูง ใช้เวลานาน และอาจเกิดความลำเอียงจากการตีความของผู้ติดป้ายกำกับ
แทนที่จะติดป้ายกำกับด้วยมือ คุณสามารถใช้ LLM (เช่น nvidia/nemotron-3-nano-30b-a3b) เพื่ออ่านเอกสารของคุณและสร้างคู่คำถาม-คำตอบสังเคราะห์คุณภาพสูงได้โดยอัตโนมัติ
เบื้องหลัง กระบวนการนี้จะทำงานผ่าน NeMo Data Designer ที่มีไปป์ไลน์สร้างข้อมูลสังเคราะห์ 4 ขั้นตอน:
ตัวอย่างผลลัพธ์:
- ส่วนของเอกสารต้นฉบับ (Source document chunk):
> Thermal design power (TDP) ของ H100 GPU คือ 700W ในรูปแบบ SXM การระบายความร้อนต้องรักษาอุณหภูมิ Junction ให้อยู่ต่ำกว่า 83°C ภายใต้ปริมาณงานที่ต่อเนื่อง การระบายความร้อนด้วยของเหลวแนะนำสำหรับ Deployment ที่มีความหนาแน่นสูงเกิน 4 GPUs ต่อโหนด เนื่องจากระบบระบายความร้อนด้วยอากาศไม่สามารถกระจายความร้อนได้เพียงพอในคอนฟิกูเรชัน 2U chassis มาตรฐาน
- ตัวอย่างคำถาม-คำตอบ:
- คำถาม 1 (Lookup ง่าย): "What is the TDP of the H100 SXM?"
- คำตอบ 1: "The TDP of the H100 SXM is 700W."
- คำถาม 2 (Multi-hop Reasoning): "How does the H100's TDP relate to cooling requirements in dense deployments?"
- คำตอบ 2: "The H100's 700W TDP requires robust cooling solutions, especially in dense deployments where air cooling may be insufficient, necessitating liquid cooling for more than 4 GPUs per node."
ไปป์ไลน์นี้สามารถสร้างคำถามได้ทั้งแบบง่ายและแบบที่ต้องใช้การให้เหตุผลแบบหลายทอด (Multi-hop) โดยสามารถกำหนดระดับความซับซ้อน (2–5) และจำนวนทอด (1–3) ได้ จากนั้น คู่ QA แต่ละคู่จะผ่านการประเมินคุณภาพ โดยได้รับคะแนนย่อยสำหรับความเกี่ยวข้อง ความถูกต้อง การสนับสนุนจากบริบท และความชัดเจน พร้อมคะแนนรวม เฉพาะคู่ที่ผ่านเกณฑ์เท่านั้นที่จะถูกนำไปใช้ในการฝึก
⛏️ ขั้นตอนที่ 2: ทำ Hard Negative Mining (และเหตุผลที่สำคัญ)
หากคุณฝึกโมเดล Embedding ด้วยคู่บวก (Query + Document ที่ถูกต้อง) เท่านั้น โมเดลจะเรียนรู้ที่จะแยกแยะเอกสารที่แตกต่างกันอย่างชัดเจน แต่จะล้มเหลวในกรณีที่ยาก – คือ Passage ที่ดูเหมือนเกี่ยวข้องแต่ไม่ใช่คำตอบที่ถูกต้อง ในระบบ Retrieval จริง เอกสารที่เกือบจะใช่เหล่านี้คือสิ่งที่ทำให้เกิดคำตอบที่ไม่ดี
Hard Negative Mining คือการค้นหา Passage ที่ทำให้สับสนเหล่านี้ เพื่อให้โมเดลสามารถเรียนรู้ที่จะแยกแยะได้
คำสั่งด้านบนจะดำเนินการ 3 ขั้นตอนย่อยโดยอัตโนมัติ:
2a. การแบ่งข้อมูล Train / Validation / Test:
คู่ QA ที่สร้างขึ้นจะถูกแบ่งเป็นชุดฝึก (80%) และชุดทดสอบ (20%) ชุดทดสอบจะถูกจัดรูปแบบให้เข้ากันได้กับ BEIR เพื่อการประเมินที่เป็นมาตรฐานในขั้นตอนที่ 5
2b. Hard Negative Mining:
โดยใช้โมเดล Embedding พื้นฐาน ไปป์ไลน์จะ:
- ฝัง (Embed) ทุก Query และทุก Passage ในคลังข้อมูล
- คำนวณความคล้ายคลึงระหว่างแต่ละ Query กับ Passage ทั้งหมด
- ปิดบัง (Mask out) Document ที่เป็นบวกของแต่ละ Query
- ใช้ตัวกรอง Margin: Passage ที่ไม่ใช่บวกใดๆ ที่มีคะแนนสูงกว่า 95% ของคะแนนบวกขั้นต่ำจะถูกกำจัดออกไป เขตการยกเว้นนี้จะช่วยป้องกัน False Negatives – Passage ที่ไม่ได้ติดป้ายกำกับซึ่งอาจมีความเกี่ยวข้องจริงๆ
- จากผู้สมัครที่เหลือ เลือก Passage ที่มีคะแนนสูงสุด k อันดับแรกเป็น Hard Negatives (ค่าเริ่มต้นคือ 5 ต่อ Query)
ผลลัพธ์: Hard Negatives คือ Passage ที่ไม่ใช่บวกและมีความคล้ายคลึงมากที่สุด แต่ยังคงอยู่ต่ำกว่าเกณฑ์คะแนนของ Passage บวก มันคือ Passage ที่โมเดลปัจจุบันพิจารณาว่าเกี่ยวข้องอย่างมาก แต่ไม่ใช่คำตอบที่ติดป้ายกำกับไว้
ทำไมถึงได้ผล: การฝึกด้วย Negative ที่ง่าย (Passage ที่ไม่เกี่ยวข้องเลย) จะไม่สอนอะไรใหม่ให้โมเดล การฝึกด้วย Hard Negatives จะบังคับให้โมเดลเรียนรู้ความแตกต่างเล็กน้อยที่สำคัญในโดเมนของคุณ ตัวอย่างเช่น ในคลังข้อมูลทางการแพทย์ คำถามเกี่ยวกับ "ปริมาณยา Metformin สำหรับเบาหวานชนิดที่ 2" อาจมี Hard Negatives เกี่ยวกับ "ผลข้างเคียงของ Metformin" หรือ "ปริมาณยาอินซูลินสำหรับเบาหวานชนิดที่ 1" – ซึ่งใกล้เคียงแต่มีความแตกต่างอย่างยิ่ง เกณฑ์ Margin 95% ป้องกันไม่ให้ Miner เลือก Passage ที่ใกล้เคียงกับ Passage บวกมากเกินไป ซึ่งอาจเป็นคำตอบที่ถูกต้องแต่ไม่ได้ถูกติดป้ายกำกับระหว่าง SDG
2c. Multi-Hop Unrolling:
คำถามแบบ Multi-hop อ้างอิงถึง Document ที่เป็นบวกหลายฉบับ ตัวอย่างเช่น คำถามเช่น "ระบบจัดการความร้อนในส่วนที่ 3.2 เกี่ยวข้องกับข้อจำกัดด้านพลังงานที่อธิบายไว้ในส่วนที่ 5.1 อย่างไร?" มี Passage ที่เป็นบวกสองฉบับ การ Unrolling จะสร้าง Training Example หนึ่งรายการต่อ (Query, Document ที่เกี่ยวข้อง) หนึ่งคู่ ดังนั้น Contrastive Loss จะเห็นแต่ละ Passage ที่เป็นบวกแยกกัน คำถามที่มี 2 Passage ที่เป็นบวก จะกลายเป็น 2 Training Examples โดยแต่ละคู่จะมี Hard Negatives ชุดเดียวกัน แต่มี Passage ที่เป็นบวกแตกต่างกัน
ผลลัพธ์สุดท้ายคือไฟล์ JSON ที่พร้อมสำหรับการฝึก:
{
"query": "How does the H100's TDP relate to cooling requirements in dense deployments?",
"positive_document": "The thermal design power (TDP) of the H100 GPU is 700W in SXM form factor. The cooling solution must maintain junction temperature below 83°C under sustained workloads.",
"hard_negatives": [
"NVIDIA introduces the H100 Tensor Core GPU, delivering unprecedented end-to-end acceleration for AI and HPC workloads.",
"The A100 GPU features a 40GB or 80GB memory capacity and delivers up to 2x higher performance than the previous generation."
]
}🔍 ขั้นตอนที่ 3: ทำความเข้าใจ Multi-Hop Questions และเหตุผลที่ช่วยปรับปรุง Retrieval
การ Fine-tune โมเดล Embedding ทั่วไป จะสร้างคำถามหนึ่งข้อต่อหนึ่ง Passage และฝึกโมเดลให้จับคู่สิ่งเหล่านี้ ซึ่งใช้ได้ดีกับคำถามที่ต้องการข้อมูลตรงไปตรงมา แต่ผู้ใช้จริงมักถามคำถามที่ซับซ้อนซึ่งครอบคลุมหลายเอกสารหรือหลายส่วน หากโมเดลเห็นเฉพาะข้อมูลการฝึกแบบ Single-hop จะมีปัญหาในการดึง Passage ที่เกี่ยวข้องทั้งหมดสำหรับ Query ที่ซับซ้อนเหล่านี้
ไปป์ไลน์ SDG สร้างคำถามตั้งแต่ 1 ถึง 3 ทอดโดยค่าเริ่มต้น:
- 1-hop: "What is the TDP of the H100 SXM?" — ตอบได้ด้วย Passage เดียว
- 2-hop: "How does the H100's TDP relate to cooling requirements in dense deployments?" — ต้องเชื่อมโยงข้อมูลจากสอง Passage
- 3-hop: "Given the TDP, cooling constraints, and rack density limits, what is the maximum number of H100 GPUs deployable in a standard data center row?" — สังเคราะห์ข้อมูลจากสาม Passage
แต่ละทอดจะถูกติดตามด้วย Context Summary และ Segment IDs ของตัวเอง ดังนั้นข้อมูลการฝึกจะรักษาห่วงโซ่การให้เหตุผลทั้งหมด หลังจากการ Unrolling (ขั้นตอนที่ 2c) แต่ละคู่ (Question, Relevant Passage) จะกลายเป็นสัญญาณการฝึกอิสระ ซึ่งสอนให้โมเดลรู้ว่า Passage เหล่านี้ทั้งหมดเกี่ยวข้องกับ Multi-hop Query
โมเดลที่ Fine-tune แล้วจะเรียนรู้ที่จะดึงเอกสารที่เกี่ยวข้องตามบริบท ไม่ใช่แค่เอกสารที่เหมือนกันตามตัวอักษร
🧠 ขั้นตอนที่ 4: Fine-tune โมเดล Embedding
การทำงานของ Contrastive Learning:
การฝึกใช้สถาปัตยกรรม Bi-encoder พร้อม Contrastive Loss
from nemo.collections.nlp.models import TextEncodersModel
model = TextEncodersModel.from_pretrained(model_name="lmsys/vicuna-7b-v1.5")
# Replace with your model name
# Configure training parameters
trainer = Trainer(max_epochs=3, accelerator="gpu", devices=1)
# ... other trainer configurations
# Define the contrastive loss function
loss_fn = ContrastiveLoss(temperature=0.02)
# Aggressive temperature
# Train the model
model.fit(train_dl, val_dl, trainer=trainer, loss_fn=loss_fn)อุณหภูมิ (Temperature) ที่ 0.02 เป็นค่าที่ค่อนข้างสูง ซึ่งจะสร้างการกระจายตัวของความน่าจะเป็นที่คมชัดมาก ซึ่งเหมาะสำหรับ Hard Negatives ที่มีคุณภาพสูง ซึ่งเป็น Passage ที่ทำให้สับสนอย่างแท้จริงและโมเดลต้องการ Gradient ที่แข็งแกร่งเพื่อเรียนรู้ที่จะแยกแยะ
ความถี่ในการสร้าง Checkpoint:
หากไม่ได้ระบุ ckpteverysteps ในคอนฟิก ความถี่ในการสร้าง Checkpoint จะถูกตั้งค่าโดยอัตโนมัติ:
- Map-style datasets (ทราบความยาว): ค่าเริ่มต้นคือ 1 ครั้งต่อ Epoch
ขอบคุณ แหล่งข้อมูล
https://huggingface.co/blog/nvidia/domain-specific-embedding-finetune