1 คะแนน โดย GN⁺ 3 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Ternlight ช่วยให้ทำ text embedding และการค้นหาความคล้ายกันภายในเบราว์เซอร์ได้โดยไม่ต้องเรียกเซิร์ฟเวอร์ ทำให้สร้าง semantic search ฝั่งไคลเอนต์ขนาดเล็กได้อย่างรวดเร็ว
  • แพ็กเกจพื้นฐานมีขนาด 7MB เมื่อรวมเอนจินและน้ำหนักโมเดล ส่วนรุ่น mini มีขนาด 5MB และทำงานบน CPU โดยไม่ต้องใช้ GPU
  • หลังติดตั้ง @ternlight/base แล้ว สามารถนำเข้า embed และ similar เพื่อสร้างโฟลว์การค้นหาเชิงความหมายได้ด้วยโค้ดเพียงประมาณ 3 บรรทัด
  • ตัวอย่างการเรียกใช้งานจะจัดอันดับผลลัพธ์ 3 อันดับแรกจากรายการสูตรอาหาร โดยเน้นความเร็วราว 5ms และไม่มีการเรียกเครือข่าย
  • เดโมค้นหาเอกสาร React จะค้นหาภายในเบราว์เซอร์เมื่อผู้ใช้ป้อนคำถาม และขับเคลื่อนด้วย @ternlight/mini ระดับ 5MB

embedding ที่จบในเบราว์เซอร์

  • Ternlight ชูจุดเด่นว่าเป็น “โมเดล embedding ขนาด 7MB” โดยทำ embedding ข้อความได้ในระดับมิลลิวินาทีและไม่เรียกเซิร์ฟเวอร์
  • คุณลักษณะการทำงาน

    • ไม่มีการเรียก API
    • เอนจิน + น้ำหนักโมเดล: 7MB
    • รุ่น mini: 5MB
    • embedding เร็ว: ประมาณ 5ms
    • ใช้ CPU เท่านั้น ไม่มี GPU

ตัวอย่างการติดตั้งและใช้งาน

  • ให้มาในรูปแบบ npm package เดียว และใช้งานได้โดยไม่ต้องมีขั้นตอนดาวน์โหลดโมเดลแยกหรือมีเซิร์ฟเวอร์
  • คำสั่งติดตั้งมีดังนี้
npm install @ternlight/base
  • นำเข้า embed, similar จาก @ternlight/base เพื่อรันการค้นหาเชิงความหมาย
import { embed, similar } from '@ternlight/base';

similar('easy weeknight dinner ideas', recipes, { topK: 3 });
// → ranked matches · ~5 ms · zero network
  • เดโมค้นหาเอกสาร React จะค้นหาภายในเบราว์เซอร์เมื่อผู้ใช้ป้อนคำถาม และทำงานด้วย @ternlight/mini ระดับ 5MB

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

 
GN⁺ 3 시간 전
ความคิดเห็นบน Hacker News
  • อยากลองรัน โมเดลที่ใช้งานได้จริงในเบราว์เซอร์ เป็นโปรเจกต์งานอดิเรก เลย distill ตัวเข้ารหัสประโยคขนาดเล็กจาก MiniLM และใช้การฝึกแบบรับรู้การ quantization แบบ ternary
    เขียน inference engine เองด้วย แล้วปล่อยเป็น Rust → WASM SIMD
    มันไม่ใช่ LLM แต่เป็นโมเดล embedding ดังนั้นเมื่อใส่ข้อความเข้าไปจะได้เวกเตอร์ 384 มิติ และใช้ cosine similarity ของเวกเตอร์สองตัวเพื่อตัดสินความเกี่ยวข้องของข้อความ ตัวอย่างเช่น "reset my password" กับ "I forgot my password" จะได้ประมาณ 0.88
    ใช้ได้กับการค้นหาเชิงความหมาย การจับคู่ FAQ/intent และการจัดกลุ่ม และเพราะรันในอุปกรณ์ จึงค้นหาเชิงความหมายได้เร็วทันทีหลังป้อนข้อมูลโดยไม่ต้องพึ่ง API
    เดโมค้นหาเอกสาร React 2,000 รายการทั้งหมดในอุปกรณ์: https://ternlight-demo.vercel.app
    บน npm มี 2 ระดับคือ @ternlight/base (7MB, ประมาณ 5ms ต่อ embedding, embedding คุณภาพดีกว่า) และ @ternlight/mini (ขนาดส่งผ่าน 5MB, ประมาณ 2.5ms ต่อ embedding) และ bundle ไว้สำหรับ Node กับเบราว์เซอร์
    repo มีรายละเอียดทางเทคนิค ไลเซนส์ MIT และ pipeline การฝึก: https://github.com/soycaporal/ternlight
    อยากรู้ว่า embedding ในอุปกรณ์มีประโยชน์จริงไหม และมี use case แบบไหนบ้าง

    • มีพจนานุกรมที่แมปคำกับแท็ก OpenStreetMap อยู่ หน้าตาประมาณ https://codeberg.org/cartes/web/src/branch/master/components...
      อยากรู้ว่าจะช่วยให้ผู้ใช้พิมพ์ "pancake" แล้วหา crêpe เจอได้ไหม โดยไม่ต้องเขียนรายการพจนานุกรมแบบชัดเจนว่า "pancake = crêpe"
      ถ้าเข้าใจถูก โครงสร้างคือไลบรารีจะดาวน์โหลด 5MB หนึ่งครั้งตอนแรก แล้วหลังจากนั้นก็ใช้งานเหมือนตอนนี้ที่ใช้ Fuse.js ใช่ไหม
      อยากรู้ด้วยว่าจัดการภาษาที่ไม่ใช่อังกฤษได้ดีแค่ไหน และเอาไปฝึกด้วย OpenStreetMap tag wiki ได้ไหม
    • สนใจมากจริง ๆ กับการใส่ semantic search แบบง่าย ๆ ลงในแอปเดสก์ท็อปแบบ native
      อยากรู้ว่ามีการเทียบกับโมเดล embedding ขนาดจิ๋วตัวอื่นไหม ยากจะตัดสินว่าเหตุผลที่เริ่มจาก MiniLM-L6 เป็นเพราะมันเป็นโมเดลที่ดีเป็นพิเศษในระดับเดียวกันหรือไม่ เพราะตัวชี้วัดที่ให้มามีแค่ "Retrieval (SciFact NDCG@10)"
      แต่ก็ยังต่างจากประสิทธิภาพที่อ้างไว้พอสมควร บน Firefox ของ i5-4570 ได้แค่ 35 embeddings ต่อวินาที ไม่ใช่ 400 ต่อวินาที สงสัยว่าอาจตกไปใช้ path ที่ไม่ใช่ SIMD และตั้งใจจะลอง native Rust binary ด้วย
    • เพิ่ง embedding เอกสาร django ทั้งหมด กับ knowledge base ภายในบริษัท ทำให้ค้นหาจากสองแหล่งได้ทันทีแล้ว
  • เจ๋งดี แต่ถ้ามีปุ่มเริ่มเดโมบน landing page น่าจะดีมาก เปิดเว็บปุ๊บได้ยิน เสียงพัดลมหมุนอย่างบ้าคลั่ง เลยค่อนข้างตกใจ

    • เห็นด้วย ขณะเดียวกันก็รู้สึกดีที่ทำให้นึกถึงยุคที่แค่ฟังเสียงคอมพิวเตอร์ก็รู้ได้อย่างคุ้นเคยว่าตอนนี้กำลังเกิดอะไรขึ้น
    • ตกใจที่พัดลมเริ่มหมุน แต่บางทีเครื่องปิ้งขนมปังก็ทำให้ตกใจเหมือนกัน
    • ใช้ CPU cycle แบบสุดขีด ใครบอกว่า GPU เท่านั้นที่พิเศษกันนะ
  • น่าจะทำเป็นปลั๊กอินสำหรับ Astro หรือ meta-framework ทั่วไป ให้ parse ไฟล์ HTML ที่สร้างทั้งหมดโดยอัตโนมัติแล้วสร้าง ฐานข้อมูล embedding ขนาดเล็ก
    ฝั่ง frontend สามารถ lazy-load สิ่งนี้ได้ และอาจเก็บ HNSW เป็น chunk เพื่อโหลดเฉพาะส่วนที่จำเป็นต่อ query การค้นหา
    ตัวอย่างเช่นคล้าย https://pagefind.app/ แต่เป็นรูปแบบที่ให้ static vector search แบบเต็มตัว

    • สำหรับ static site generator ของเราอยากใช้ sqlite-vec แต่ตอนเช็กล่าสุดดูเหมือนยังไม่ได้ implement HNSW หรือไม่ก็การรองรับ vector search ในเบราว์เซอร์ยังไม่ดีนัก น่าจะยัง scan ทั้งตารางอยู่
      ผ่านมาหลายเดือน หลายปีแล้ว ถ้ายังเป็นแบบนั้นก็ถือว่าค่อนข้างน่าผิดหวัง เพราะดูเหมือนเป็นสัญญาณว่าขาดความสามารถในการทำโปรเจกต์ให้เสร็จจริง ๆ ถึงขั้นที่ผมเคยเสนอโปรเจกต์นั้นเป็นผู้สมัครที่ดีสำหรับทุนที่ผมสมัคร แต่ฝั่งนั้นได้ทุน ส่วนผมไม่ผ่าน
      ถ้าใครรู้วิธีแก้ดี ๆ ในพื้นที่นี้ หรือถ้าผมเข้าใจ SQLite-vec ผิด ช่วยบอกที สำหรับ SSG ของเรา ตอนนี้เกือบตัดสินใจแล้วว่าจะไปทำโครงสร้างพื้นฐานอื่นสักสองสามเดือนก่อน แล้วถ้ายังไม่เสร็จก็จะทำเอง
  • น่าจะเป็นฟีเจอร์เสริมที่เจ๋งมากสำหรับโปรเจกต์ค้นหา DuckDB HNSW ที่เคยเห็นที่นี่: https://github.com/jasonjmcghee/portable-hnsw
    จุดที่น่าสนใจมากคือการค้นหาเกิดขึ้นกับไฟล์ Parquet ที่โฮสต์แบบ static โดยใช้ HTTP range requests
    มองว่าสิ่งเหล่านี้อาจเติบโตเป็นระบบนิเวศการค้นหาที่ค่อนข้างเปิดและกระจายศูนย์ ซึ่งไม่ได้ถูกควบคุมโดยบริษัทใหญ่

    • ไอเดียคล้ายกันคือการใช้ SQLite DB บน static host ผ่าน HTTP range requests กับ WASM ก็น่าสนใจได้
      https://news.ycombinator.com/item?id=27016630
    • ไอเดียเจ๋งมาก ชอบ format ที่ client สามารถสำรวจได้ผ่าน range requests และ static hosting จริง ๆ
  • อันนี้เจ๋งจริง และอาจเป็นชิ้นส่วนที่ขาดไปของสิ่งที่เคยอยากสร้าง
    ถ้าใช้ https://github.com/npiesco/absurder-sql จะสามารถ persist corpus ต้นฉบับทั้งหมดไว้ใน IndexedDB/SQLite ภายในเบราว์เซอร์ได้
    จากนั้นก็ใช้ Ternlight ทำ การสร้าง embedding และ cache ตามต้องการ โดยไม่ต้อง index ทุกอย่างล่วงหน้า เหมือน https://weaviate.io/blog/chunking-strategies-for-rag
    แบบนั้นก็จะทำ hybrid search ได้ด้วย Reciprocal Rank Fusion ที่รวม FTS5/BM25 ของ SQLite แบบ native กับ semantic search ของ Ternlight

  • ทำได้ดีมาก
    โปรโมตว่า 7MB แต่ก็มีเวอร์ชัน mini 5MB ด้วย
    ดูเหมือน mini จะใช้ เวกเตอร์ 256 องค์ประกอบ ภายในแทน 384 เพื่อลดพื้นที่ แล้วค่อย project กลับเป็น 384 ตอนท้ายเพื่อความเข้ากันได้
    ขนาดลดลงหนึ่งในสาม แต่ loss ไม่ได้เป็นเส้นตรง ดังนั้นแม้ใช้ data path ที่เล็กกว่า ก็ดูเหมือนสูญเสียข้อมูลน้อยกว่าหนึ่งในสาม

  • โปรเจกต์เจ๋งมาก
    เคยลองทำสิ่งคล้ายกันมาก่อน: http://sol.quipu-strands.com/
    อยากโหลดโมเดล embedding ในเบราว์เซอร์ แล้วจัดเรียงข้อความตามความหมาย
    ดึง ONNX weights (MPNet, MiniLM) จาก HuggingFace ใช้ Transformers.js ทำ embedding แล้วใช้ตัวจัดกลุ่มของ scikit-learn ที่รันผ่าน pyodide ในหน้าเว็บ ทั้งหมดทำงานฝั่ง client และแปลกใจที่มันทำงานได้สมบูรณ์แบบ

  • เดโมทำงานค่อนข้างแปลก ตัวอย่างเช่นถ้าค้นหา "how to use typescript with createContext" ผลลัพธ์อันดับต้น ๆ มีแต่ รายการ typescript เลยดูเหมือน similarity search ล้มเหลว

  • ขอบคุณ โมเดล local จะนำ ความเป็นส่วนตัว มาให้ในสักวัน และผมก็รู้ use case ที่ยอดเยี่ยมซึ่งเหมาะกับโมเดล embedding เล็ก ๆ แบบนี้อยู่แล้ว คือการค้นหาราคาถูกและรวดเร็วในฐานข้อมูลสินค้า
    ในกรณีของผม การพึ่ง CPU ก็เป็นข้อดีด้วย

    • ดีเลย ถ้ามีวิธีให้ช่วยสนับสนุน หรือมี use case เฉพาะที่ควรกล่าวถึงใน roadmap ก็บอกได้เลย
  • สามารถทำ การสร้าง embedding ที่ใช้เวลา 30 วินาทีไว้ล่วงหน้าแล้วส่งไปยังเบราว์เซอร์ได้ไหม
    หลังจากนั้น inference ก็เร็วและดี

    • ได้ รัน indexing ฝั่ง server เพียงครั้งเดียว แล้วส่งเฉพาะ embeddings ไปยัง frontend ก็พอ