1 điểm bởi GN⁺ 2024-09-16 | 1 bình luận | Chia sẻ qua WhatsApp
  • WordLlama là một bộ công cụ NLP nhanh và gọn nhẹ, tái sử dụng token embedding của LLM để thực hiện fuzzy deduplication, tính toán độ tương đồng, xếp hạng, phân cụm và semantic text splitting
  • Suy luận chủ yếu hoạt động dựa trên tra cứu token và average pooling, nhấn mạnh pipeline nhẹ có thể chạy chỉ với NumPy và tối ưu cho CPU
  • Mô hình mặc định có kích thước 256 chiều, 16MB, có thể giảm số chiều bằng biểu diễn Matryoshka, còn binary embedding hỗ trợ tính toán nhanh hơn bằng độ tương đồng Hamming
  • Trong bảng MTEB, WL64~WL1024 đạt điểm cao hơn GloVe 300d và Komninos ở nhiều chỉ số, nhưng nhìn chung thấp hơn all-MiniLM-L6-v2
  • Có thể dùng sau khi pip install wordllamaWordLlama.load(), còn .key(query) trả về một hàm callable có thể đưa vào các hàm thư viện chuẩn như sorted, min, max

WordLlama làm gì

  • WordLlama là bộ công cụ gọn nhẹ cho các tác vụ tiện ích NLP như fuzzy deduplication, tính toán độ tương đồng, xếp hạng, phân cụm và semantic text splitting
  • Nó trích xuất codebook token embedding từ các LLM hiện đại như LLaMA 2, LLaMA 3 70B để tạo ra compact word representation tương tự GloVe, Word2Vec và FastText
  • Khi suy luận, nó có ít phụ thuộc và được tối ưu cho phần cứng CPU, nên phù hợp để triển khai trong môi trường hạn chế tài nguyên
  • Nhờ tốc độ nhanh và kích thước nhỏ, nó có thể dùng cho các mục đích tiện ích như phân tích khám phá, bộ đánh giá đầu ra LLM, hoặc bước chuẩn bị cho multi-hop hay agentic workflow

Cài đặt và cách dùng cơ bản

  • Cài đặt bằng pip
pip install wordllama
  • Mô hình 256 chiều mặc định được nạp bằng WordLlama.load()
from wordllama import WordLlama

wl = WordLlama.load()
  • .key(query) trả về Callable[[str], float], cho phép sắp xếp các chuỗi ứng viên theo độ tương đồng với truy vấn hoặc chọn giá trị lớn nhất
query = "Machine learning methods"
candidates = [
    "Foundations of neural science",
    "Introduction to neural networks",
    "Cooking delicious pasta at home",
    "Introduction to philosophy: logic",
]

sim_key = wl.key(query)

sorted_candidates = sorted(candidates, key=sim_key, reverse=True)
best_candidate = max(candidates, key=sim_key)
  • Trong kết quả ví dụ, "Introduction to neural networks" là ứng viên có điểm cao nhất với số điểm 0.3414

Tính năng chính

  • Tạo embedding: tạo text embedding nhanh bằng tra cứu token đơn giản và average pooling
  • Tính độ tương đồng: tính cosine similarity giữa hai văn bản
  • Xếp hạng tài liệu: xếp thứ hạng dựa trên độ tương đồng giữa truy vấn và tài liệu ứng viên
  • Fuzzy deduplication: loại bỏ văn bản trùng lặp theo ngưỡng độ tương đồng
  • Phân cụm: nhóm tài liệu bằng KMeans
  • Lọc: chỉ giữ lại các tài liệu có độ tương đồng với truy vấn từ mức ngưỡng trở lên
  • Tìm kiếm Top-K: trả về K tài liệu giống truy vấn nhất
  • Semantic text splitting: chia văn bản thành các chunk gắn kết về mặt ngữ nghĩa
  • Binary embedding: hỗ trợ tính toán nhanh hơn bằng độ tương đồng Hamming
  • Biểu diễn Matryoshka: cắt số chiều embedding theo nhu cầu để điều chỉnh kích thước mô hình và hiệu năng

Kiến trúc mô hình và hiệu năng

  • WordLlama huấn luyện mô hình nhỏ không ngữ cảnh trong một framework embedding tổng quát
  • Mô hình mặc định có kích thước 256 chiều, 16MB
  • Bảng MTEB trong README so sánh WL64, WL128, WL256, WL512, WL1024 với GloVe 300d, Komninos và all-MiniLM-L6-v2
    • WL256 ghi nhận Clustering 33.25, Reranking 52.03, Classification 58.21, Pair Classification 78.22, STS 67.91, CQA DupStack 24.12, SummEval 30.99
    • GloVe 300d lần lượt ghi nhận 27.73, 43.29, 57.29, 70.92, 61.85, 15.47, 28.87
    • all-MiniLM-L6-v2 ghi nhận Clustering 42.35, Reranking 58.04, Classification 63.05, Pair Classification 82.37, STS 78.90, CQA DupStack 41.32, SummEval 30.81
  • l2_supercat là mô hình vocabulary LLaMA 2
    • Mô hình này được huấn luyện bằng cách nối các codebook từ nhiều mô hình như LLaMA 2 70B và phi 3 medium sau khi loại bỏ các special token bổ sung
    • Có thể huấn luyện bằng cách nối chung codebook của nhiều mô hình dùng tokenizer LLaMA 2
    • Nó cho hiệu năng tương tự huấn luyện trên codebook LLaMA 3 70B nhưng vocabulary nhỏ hơn 4 lần, 32k so với 128k
  • Mô hình dựa trên LLaMA 3 là l3_supercat
  • Kết quả bổ sung có trong Results

Semantic text splitting

  • .split() chia văn bản dài thành các chunk ngữ nghĩa
long_text = "Your very long text goes here... " * 100
chunks = wl.split(long_text, target_size=1536)

print(list(map(len, chunks)))

# Output: [1055, 1055, 1187]
  • target_size vừa là kích thước mục tiêu vừa là kích thước tối đa
  • Quá trình chia cố gắng giữ nguyên thứ tự văn bản, cấu trúc câu và nếu có thể thì cả cấu trúc đoạn văn
  • Nó dùng embedding của WordLlama để tìm chỉ số cắt tự nhiên hơn
  • Kích thước chunk đầu ra có thể thay đổi trong phạm vi không vượt quá target_size
  • Kích thước mục tiêu khuyến nghị là 512~2048 ký tự, mặc định là 1536
  • Nếu cần chunk lớn hơn, nên chia trước rồi gom nhiều semantic chunk lại theo lô
  • Xem thêm trong technical overview

Model2Vec và suy luận trực tiếp

  • Bản cập nhật 2025-01-04 bổ sung hỗ trợ Model2Vec static embeddings
  • Có thể nạp mô hình Model2Vec bằng WordLlama.load_m2v()
wl = WordLlama.list_configs()

wl = WordLlama.load_m2v("potion_base_8m")  # 256-dim model
wl = WordLlama.load_m2v("m2v_multilingual")  # multilingual model
  • Model2Vec là một cách khác để tạo static embedding bằng PCA
  • Phía Model2Vec đã tạo mô hình đa ngôn ngữ và mô hình dựa trên glove, đồng thời cho biết đạt điểm tốt ở bài toán word similarity
  • Có thể xem trên minishlab của Hugging Face
  • WordLlamaInference cho phép dùng trực tiếp một mảng static embedding dạng (n_vocab, dim) cùng tokenizer thay vì dùng loader
from wordllama import WordLlamaInference
from tokenizers import Tokenizer

tokenizer = Tokenizer.from_pretrained(...)
wl = WordLlamaInference(np_embeddings_ar, tokenizer)

Huấn luyện và trích xuất embedding

  • Mô hình binary embedding cho thấy mức cải thiện rõ hơn ở số chiều cao, và với binary embedding thì 512 hoặc 1024 chiều được khuyến nghị
  • Mô hình L2 Supercat được huấn luyện trong 12 giờ trên một GPU A100 duy nhất với batch size 512
  • Để trích xuất token embedding từ mô hình LLaMA, cần đồng ý với thỏa thuận người dùng và đăng nhập Hugging Face CLI
from wordllama.extract.extract_safetensors import extract_safetensors

extract_safetensors("llama3_70B", "path/to/saved/model-0001-of-00XX.safetensors")
  • Embedding thường nằm trong file safetensors đầu tiên, nhưng không phải lúc nào cũng vậy
    • Có thể có manifest
    • Có thể phải tự kiểm tra và tìm trực tiếp
  • Việc huấn luyện dùng các script trong kho mã nguồn, và cần thêm configuration file bằng cách sao chép hoặc chỉnh sửa cấu hình sẵn có
pip install wordllama[train]
python train.py train --config your_new_config
python train.py save --config your_new_config --checkpoint ... --outdir /path/to/weights/
  • Bước lưu sẽ lưu từng mô hình theo từng chiều Matryoshka

Cập nhật, lộ trình, giấy phép

  • Bản cập nhật 2025-02-01 bổ sung hỗ trợ callable có thể dùng với các hàm thư viện chuẩn như sorted, min, max
  • Bản cập nhật 2024-10-04 bổ sung semantic splitting inference algorithm
  • Lộ trình có kế hoạch bổ sung notebook ví dụ cho DSPy evaluator và Retrieval-Augmented Generation, tức pipeline RAG
  • Có các dự án cộng đồng như Gradio Demo HF SpaceCPU-ish RAG
  • Giấy phép của dự án là MIT License

1 bình luận

 
GN⁺ 2024-09-16
Ý kiến trên Hacker News
  • Mình rất thích kích thước nhỏ của nó. Nó đã có lợi thế so với mô hình nhỏ nhất của SBERT
    Tuy nhiên, về mặt kỹ thuật thì có vẻ là một cách tiếp cận khá cũ, và mình hiểu đây là sự đánh đổi với hiệu năng. Dù vậy, mình tò mò liệu nó có thể cung cấp khả năng chuyển đổi các loại độ tương đồng như độ tương đồng ngữ nghĩa, suy luận ngôn ngữ tự nhiên (NLI), hay trừu tượng hóa danh từ hay không
    Ví dụ, khi nhóm các bài báo vào những danh mục như “sự kiện môi trường cực đoan”, ta muốn “Freezing” và “Burning” được coi là rất giống nhau. Đây là trường hợp hoạt động giống MTEB/Sentence-Similarity hoặc Word2Vec/GloVe cổ điển. Nhưng nếu là bài viết về hóa học thì hai từ này nên gần như đối lập, và đôi khi ta cũng muốn dùng embedding suy luận ngôn ngữ tự nhiên để xem quan hệ nhân quả giữa hai sự vật
    Mình nghĩ hai loại embedding sau là các cách tương đối gần đây sau năm 2019 nên còn nhiều cơ hội kỹ thuật hơn. Dòng MTEB/độ tương đồng ngữ nghĩa cũ đã đủ tốt cho nhiều mục đích từ năm 2014, và được cải thiện đáng kể vào năm 2019 với mini-lm-v2, v.v.
    Ba loại embedding trên cũng có thể làm bằng SBERT, nhưng số chiều lớn và mô hình cũng lớn, nên nếu tải nhiều mô hình theo từng loại thì gánh nặng tài nguyên khá cao. Các mô hình embedding sinh, E5, hay mô hình suy luận ngôn ngữ tự nhiên thường lớn và đôi khi cần khoảng 6GB

    • Ý tưởng hay. Mình sẽ thử vài thí nghiệm và xem có khả thi không
      Mình muốn xem hiệu năng ra sao khi huấn luyện với một loại độ tương đồng duy nhất. Mình không chắc có cách nào khác để xử lý việc này mà không tính ngữ cảnh hay không. Có thể phải chuyển đổi mô hình, nhưng bản thân điều đó không phải vấn đề lớn
    • Đây là mô hình 17MB, và trong benchmark thì đương nhiên thấp hơn MiniLM v2, tức SBERT. Mình đang chạy V3 trên ONNX với mô hình 23MB trên gần như mọi nền tảng
      Không có ý chê bai, chỉ là cần hiểu những việc như thế này trong đúng bối cảnh. Ở đây, bối cảnh là khi tìm hiểu sâu về LLM, người ta phát hiện ra rằng LLM cũng có embedding; từ góc nhìn đó, việc thử nghịch các embedding ấy và tiến thêm một bước tự nhiên hơn là rà soát lại toàn bộ hiện trạng của lĩnh vực embedding
    • Nếu “embedding của ChatGPT” nghĩa là mô hình embedding của OpenAI, thì “burning” và “freezing” hoàn toàn không đối lập. Chạy với 1024 chiều của text-embedding-large-3 thì độ tương đồng cosine khoảng 0,46. Nếu là embedding hoàn toàn đối lập thì độ tương đồng phải là -1
      Nghĩ rằng các từ trái nghĩa sẽ có embedding trái ngược là một nhầm lẫn phổ biến. Thực tế, các từ trái nghĩa cũng có rất nhiều điểm chung. “burning” và “freezing” đều liên quan đến nhiệt độ và vật lý, đều là từ tiếng Anh, đều có thể dùng như động từ, danh từ, tính từ, và đều viết đúng chính tả. Tất cả những đặc điểm này đều đi vào embedding
  • Embedding chứa nhiều thông tin ngữ nghĩa tùy theo dữ liệu huấn luyện và hàm mục tiêu, và có thể được dùng độc lập cho nhiều tác vụ hữu ích
    Trước đây mình từng dùng embedding từ bộ mã hóa văn bản của mô hình CLIP để tăng cường prompt sao cho khớp tốt hơn với ảnh tương ứng. Ví dụ, nếu prompt có “building”, mình tìm các láng giềng gần nhất trong ma trận embedding như “concrete”, “underground” rồi thay thế hoặc thêm chúng sau từ đó. Trong các thử nghiệm hạn chế, recall tăng ở hầu hết truy vấn

    • Đúng vậy. Có thể huấn luyện các quan hệ ngữ cảnh trong miền như thế này vào mô hình embedding
      https://www.marqo.ai/blog/generalized-contrastive-learning-f...
    • Ý tưởng thật sự rất hay. Có vẻ cũng làm được với triển khai này, nên mình sẽ suy nghĩ thêm
      Nhìn vào độ lớn của token embedding trong wordllama, có lẽ nó cũng có thể giúp xác định các token quan trọng cần tăng cường. Tuy nhiên, nếu huấn luyện bằng dữ liệu được chọn lọc riêng cho tác vụ này thì có thể hoạt động tốt hơn nhiều
  • Mình tò mò có kế hoạch cho các ngôn ngữ ngoài tiếng Anh không. Có vẻ đây sẽ là công cụ hoàn hảo cho tiếng Pháp

    • Hoàn toàn có thể. Cần xây dựng một corpus để huấn luyện, nhưng mình không rõ tiếng Pháp có những nguồn dữ liệu nào
      Mình từng huấn luyện thử một chút với các mô hình họ Mistral, nên với corpus tiếng Pháp có lẽ mình sẽ thử hướng đó trước
      Nếu bạn mở issue, mình sẽ làm thử khi có thời gian
  • Với corpus lớn, ví dụ hơn 10.000 câu và xem mỗi câu như một tài liệu, việc phân cụm bằng k-means trên vector ma trận thưa TF-IDF cũng có thể cho kết quả tương tự
    Tuy nhiên công cụ này có vẻ có khá nhiều tiện ích để làm phần k-means nhanh hơn, chẳng hạn như nhị phân hóa. Mình định benchmark trong vài tuần tới

  • Vài năm trước mình từng tạo một bộ trò chơi ngôn ngữ dùng các hàm tương tự: https://github.com/Hellisotherpeople/Language-games

  • Mình tò mò không biết đã ai nghĩ đến việc dùng embedding để giải Little Alchemy chưa. #sample-use

  • Trông hay đấy. Mình tò mò nó có ưu điểm gì so với mô hình mini-lm không. Trong hầu hết tác vụ MTEB, mini-lm có vẻ tốt hơn, nên mình muốn biết liệu nó có điểm nào tốt hơn như tốc độ suy luận chẳng hạn không

    • Mini-lm là mô hình embedding tốt hơn. Mô hình này không thực hiện tính toán attention, và sau khi huấn luyện thì cũng không dùng framework deep learning. Vì vậy nó không có được lợi thế ngữ cảnh của mô hình transformer
      Nó cũng không nhắm tới hiệu năng tối tân nhất. Đây là mô hình đặt ra các ràng buộc khá nghiêm ngặt để giảm dependency, kích thước, yêu cầu phần cứng và tăng tốc độ
      Ngay cả khi xem như mô hình word embedding thì nó cũng khá nhẹ. Thường các mô hình kiểu đó có từ vựng lớn hơn nhiều và kích thước ở mức vài GB
    • Có vẻ là khác biệt về kích thước của chính mô hình. Nhẹ hơn và nhanh hơn. mini-lm là 80MB, còn mô hình nhỏ nhất ở đây là 16MB
  • Trông rất hữu ích cho phát triển game

  • Nó cho thấy rõ trong bản thân token có bao nhiêu nội dung ngữ nghĩa

  • Có thể làm thành extension PostgreSQL không?