Embedding คืออะไร?
- "Embedding" คือการแปลงคอนเทนต์ให้เป็น "อาร์เรย์ของตัวเลขทศนิยมแบบ floating-point"
- แก่นสำคัญของอาร์เรย์นี้คือ ไม่ว่า "ความยาวของคอนเทนต์" จะเป็นเท่าใด "ขนาดของอาร์เรย์" จะคงที่เสมอ
- ขนาดของอาร์เรย์จะถูกกำหนดโดยโมเดล embedding ที่ใช้ เช่น 300, 1000, 1536 เป็นต้น
- วิธีที่ดีที่สุดในการนึกภาพอาร์เรย์ตัวเลขนี้ คือมองมันเป็น "พิกัดในปริภูมิหลายมิติที่แปลกมาก"
- แล้วทำไมต้องนำคอนเทนต์ไปวางในปริภูมิหลายมิติ? เพราะเราสามารถเรียนรู้ข้อมูลที่น่าสนใจเกี่ยวกับคอนเทนต์นั้นได้จากตำแหน่งของมัน โดยเฉพาะเมื่อดูจากคอนเทนต์อื่นที่อยู่ใกล้กัน
- ตำแหน่งในปริภูมินี้สะท้อน "ความหมายเชิงความหมาย (Semantic Meaning)" ของคอนเทนต์ ตาม "ความเข้าใจโลกที่แปลกและส่วนใหญ่ก็อธิบายไม่ได้" ของโมเดล embedding
- คอนเทนต์ที่ถูก embed แล้วสามารถจับลักษณะอย่างสี รูปร่าง แนวคิด หรือคุณลักษณะประเภทอื่น ๆ ได้
- ไม่มีใครเข้าใจอย่างถ่องแท้ว่าตัวเลขแต่ละตัวหมายถึงอะไร แต่เรารู้ว่าตำแหน่งของมันสามารถใช้ค้นหาข้อมูลที่มีประโยชน์เกี่ยวกับคอนเทนต์นั้นได้
ใช้ Embedding เพื่อค้นหาคอนเทนต์ที่เกี่ยวข้อง
- ปัญหาแรกที่ฉันใช้ embedding แก้ คือการสร้างฟีเจอร์ "Related Content" สำหรับบล็อก TIL ของฉัน
- ฉันใช้โมเดล
text-embedding-ada-002 ของ OpenAI ซึ่งใช้งานได้ผ่าน API
- ตอนนี้ในเว็บไซต์ของฉันมีบทความ 472 ชิ้น และฉันคำนวณเวกเตอร์ embedding 1536 มิติ (อาร์เรย์ของตัวเลข floating-point) สำหรับแต่ละบทความ แล้วเก็บเวกเตอร์นั้นไว้ในฐานข้อมูล SQLite ของเว็บไซต์
- จากนั้นหากต้องการหาบทความที่เกี่ยวข้องกับบทความใดบทความหนึ่ง ก็แค่คำนวณ cosine similarity ระหว่างเวกเตอร์ embedding ของบทความนั้นกับบทความอื่น ๆ ในฐานข้อมูล แล้วคืนค่า 10 รายการที่ใกล้ที่สุดตามระยะทาง
- โค้ด Python ที่ใช้สำหรับ cosine similarity มีดังนี้
def cosine_similarity(a, b):
dot_product = sum(x * y for x, y in zip(a, b))
magnitude_a = sum(x * x for x in a) ** 0.5
magnitude_b = sum(x * x for x in b) ** 0.5
return dot_product / (magnitude_a * magnitude_b)
- API embedding ของ OpenAI ทั้งถูกมากและใช้งานง่าย
- ฉัน embed ไปประมาณ 400,000 โทเคนสำหรับเว็บไซต์ TIL ของฉัน คิดราคา $0.0001 ต่อ 1,000 โทเคน รวมแล้วเสียเพียง $0.04 เท่านั้น
- แค่ส่งข้อความด้วยคำขอ POST พร้อม API key ก็จะได้ JSON array ของตัวเลข floating-point กลับมา
- แต่สิ่งนี้เป็นโมเดลแบบปิด และเมื่อไม่กี่เดือนก่อน OpenAI ก็ยุติโมเดล embedding บางตัวไป
- นั่นหมายความว่าถ้าคุณเก็บ embedding จำนวนมากจากโมเดลนั้นไว้ พอมีโมเดลใหม่ก็ต้องคำนวณ embedding ใหม่ทั้งหมด
- OpenAI บอกว่าจะชดเชยค่าใช้จ่ายในการ re-embed ไปยังโมเดลใหม่ให้ แต่ก็ยังควรระวังเมื่อใช้โมเดลแบบปิด
- เรื่องนี้สามารถหลีกเลี่ยงได้ด้วยโมเดลโอเพนที่มีไลเซนส์แข็งแรง
มาดูว่าของพวกนี้ทำงานอย่างไรในโมเดล Word2Vec
- เมื่อ 10 ปีก่อน Google Research เผยแพร่งานวิจัยทรงอิทธิพลที่อธิบายโมเดล embedding ยุคแรกชื่อ Word2Vec
- คือบทความปี 2013 ชื่อ "Efficient Estimation of Word Representations in Vector Space" ซึ่งช่วยจุดกระแสความสนใจต่อ embedding
- Word2Vec เป็นโมเดลที่รับคำเดี่ยว ๆ แล้วแปลงเป็นรายการตัวเลข 300 ค่า โดยรายการตัวเลขนั้นเก็บข้อมูลเกี่ยวกับความหมายของคำที่เกี่ยวข้อง
- เมื่อค้นหาคำหนึ่งคำ ก็สามารถหาคำที่คล้ายกันได้โดยอิงจาก cosine distance ของตัวแทน Word2Vec ของคำนั้น
- ถ้าค้นหา "france" ก็อาจได้ค่าอย่าง "french : 0.70007~" "belgium: 0.69331~" "paris: 0.63349~" "germany: 0.62707~"
- ซึ่งเป็นการผสมกันระหว่างความเป็นฝรั่งเศสกับภูมิศาสตร์ยุโรป
- สิ่งที่น่าสนใจมากอีกอย่างคือ เราสามารถทำเลขคณิตกับเวกเตอร์เหล่านี้ได้
- ถ้านำเวกเตอร์ของ "germany" มาบวกกับ "paris" แล้วลบ "france" เวกเตอร์ผลลัพธ์จะใกล้กับ "berlin" มากที่สุด
- โมเดลนี้จับแนวคิดเรื่องสัญชาติและภูมิศาสตร์ไว้ได้ จนเราสามารถใช้เลขคณิตสำรวจข้อเท็จจริงเพิ่มเติมเกี่ยวกับโลกได้
- Word2Vec ถูกฝึกจากคอนเทนต์ 1.6 พันล้านคำ และโมเดล embedding ที่เราใช้กันในปัจจุบันถูกฝึกจากชุดข้อมูลที่ใหญ่กว่ามาก จึงจับความเข้าใจความสัมพันธ์พื้นฐานได้ลึกซึ้งยิ่งกว่า
คำนวณและค้นหา Embedding ด้วยเครื่องมือของฉัน
- ฉันกำลังสร้าง CLI และไลบรารี Python ที่ชื่อว่า LLM
- มันสามารถใช้เป็น CLI สำหรับโต้ตอบกับ LLM และเชื่อมต่อกับ OpenAPI ได้ด้วย
- เมื่อไม่กี่เดือนก่อน ฉันได้เพิ่มความสามารถให้เครื่องมือนี้รันโมเดล embedding ผ่านปลั๊กอินได้ด้วย (สามารถใช้ไลบรารี SentenceTransformers ได้)
- คุณสามารถเลือก embedding collection และทำการค้นหาเชิงความหมายแบบ Vibes-based เพื่อหาสิ่งที่คล้ายกันได้
- ฉันยังกำลังสร้างเครื่องมือ Symbex สำหรับค้นหา symbol ในโค้ดเบส Python ด้วย ซึ่งทำให้สามารถคำนวณ embedding ของฟังก์ชันในโค้ดและสร้างเสิร์ชเอนจินสำหรับโค้ดได้
- (ขอละรายละเอียดการติดตั้งใช้งานไว้)
ใช้ CLIP เพื่อ embed ทั้งข้อความและรูปภาพร่วมกัน
- ตอนนี้โมเดล embedding ที่ฉันชอบที่สุดคือ CLIP
- เป็นโมเดลที่ OpenAI เปิดตัวในเดือนมกราคม 2021 ซึ่งสามารถ embed ได้ทั้ง "ข้อความและรูปภาพ" และอยู่ในเวกเตอร์สเปซเดียวกัน
- ถ้าคุณ embed คำว่า "dog" คุณจะได้ตำแหน่งหนึ่งในปริภูมิ 512 มิติ (ขึ้นอยู่กับการตั้งค่าของ CLIP)
- ถ้า embed รูปสุนัข คุณก็จะได้ตำแหน่งในปริภูมิเดียวกัน ซึ่งจะอยู่ใกล้กับตำแหน่งของสตริง "dog"
- นั่นหมายความว่าคุณสามารถใช้ข้อความค้นหารูปภาพที่เกี่ยวข้อง หรือใช้รูปภาพค้นหาข้อความที่เกี่ยวข้องได้
- หากใส่รูปชายหาดเข้าไป ก็อาจได้คะแนนความคล้ายคลึงอย่าง "beach: 26.946%" "city: 19.839%" "sunshine: 24.146%"
ค้นหาก๊อกน้ำด้วย CLIP
- Drew Breunig สร้างเสิร์ชเอนจินสำหรับค้นหาก๊อกน้ำด้วยปลั๊กอิน llm-clip
- เขานำภาพก๊อกน้ำ 20,000 ภาพมารันผ่าน CLIP
- จากนั้นก็สามารถหาก๊อกน้ำที่คล้ายกับก๊อกน้ำอื่น ๆ และยังหาตัวเลือกที่คล้ายกันแต่ราคาถูกกว่าได้
ตอบคำถามด้วย RAG
- คำถามสุดท้ายของคนที่เคยลองใช้ ChatGPT มักจะเหมือนกันหมด
"จะทำอย่างไรให้มันตอบคำถามเกี่ยวกับโน้ตของฉันหรือเอกสารของบริษัทเราได้?"
- หลายคนคิดว่าต้องเสียเงินมหาศาลเพื่อฝึกโมเดลแบบคัสตอมด้วยคอนเทนต์เหล่านั้น
- แต่จริง ๆ แล้วไม่จำเป็น เพราะทำได้ด้วย LLM และ RAG (Retrieval Augmented Generation)
- แนวคิดหลักคือ "ผู้ใช้ถามคำถามเข้ามา"
- จากนั้นคุณไปค้นหาสิ่งที่เกี่ยวข้องกับคำถามนั้นจากเอกสารส่วนตัวของคุณ
- แล้วนำข้อความบางตอนจากคอนเทนต์นั้นใส่เข้าไปใน LLM พร้อมกับคำถามเดิม
- เท่านี้ LLM ก็สามารถตอบคำถามโดยอิงจากคอนเทนต์ที่คุณให้เพิ่มเติมได้
- กลเม็ดราคาถูกนี้ได้ผลอย่างน่าทึ่ง
- แต่การทำให้เวอร์ชันพื้นฐานที่รองรับงานแบบนี้ใช้งานได้จริงนั้นไม่ง่าย
- คุณต้องทำให้มันทำงานได้ดีพอเมื่อคำนึงถึงชุดคำถามที่ผู้ใช้อาจถามได้อย่างไร้ขีดจำกัด
- ปัญหาหลักของ RAG คือการหาว่าควรใส่ข้อความตอนใดลงในพรอมป์ต์ที่จะส่งให้ LLM
- การค้นหาเชิงความหมายแบบ 'Vibes-based' ที่ขับเคลื่อนด้วย embedding คือความสามารถที่จำเป็นในการรวบรวมคอนเทนต์ที่เกี่ยวข้องสูง ซึ่งจะช่วยตอบคำถามของผู้ใช้ได้
- ฉันสร้างเวอร์ชันสำหรับ "เนื้อหาในบล็อกของฉัน" แล้วเปิดให้ใช้งานสาธารณะ
- ผลลัพธ์คือ RAG สามารถทำได้ด้วย Bash script เพียงบรรทัดเดียว
5 ความคิดเห็น
ผมอ่านบทความนี้แล้วลองทำตามในช่วงสุดสัปดาห์ครับ ลองใช้โมเดลภาษาเกาหลีอยู่พักหนึ่งแต่ตั้งค่าสภาพแวดล้อมไม่ง่าย เลยใช้ ada v2 แทน และเสียค่าใช้จ่ายไปรวม 0.03 ดอลลาร์ครับ ถ้าเป็นผู้ใช้ใหม่ที่ยังไม่เคยใช้ chatgpt มาก่อน ก็น่าจะลองได้สบาย ๆ ด้วยเครดิตฟรี 5 ดอลลาร์ครับ
ผมลองคำนวณ cosine similarity เพื่อเปรียบเทียบด้วย ผลลัพธ์ก็ออกมาสมเหตุสมผลดีครับ ขอบคุณที่แชร์บทความครับ
สุดสัปดาห์นี้คงต้องลองทำตามดูสักครั้งแล้ว
ขอบคุณครับ~
ดูเหมือนว่าผมจะเริ่มเข้าใจขึ้นมาบ้างแล้ว
ขอบคุณครับ
ได้เข้าใจมากขึ้นเกี่ยวกับส่วนที่ปกติสงสัยอยู่แต่ยังไม่ค่อยรู้ ขอบคุณสำหรับคอนเทนต์ดี ๆ เสมอมาครับ