Embedding là gì?
- "Embedding" là việc chuyển đổi nội dung thành một "mảng số thực dấu phẩy động"
- Điểm cốt lõi của mảng này là bất kể "độ dài nội dung" ra sao thì "kích thước mảng" luôn giữ nguyên
- Kích thước mảng được quyết định bởi mô hình embedding đang dùng: 300, 1000, 1536, v.v.
- Cách tốt nhất để hình dung mảng số này là xem nó như "tọa độ trong một không gian đa chiều rất kỳ lạ"
- Tại sao lại đặt nội dung vào không gian đa chiều? Vì từ vị trí của nội dung, đặc biệt là những nội dung ở gần nó, ta có thể học được nhiều thông tin thú vị về nội dung đó
- Vị trí trong không gian biểu thị "ý nghĩa ngữ nghĩa (semantic meaning)" của nội dung theo "cách hiểu kỳ lạ và phần lớn không thể diễn giải về thế giới" của mô hình embedding
- Nội dung đã được embedding có thể nắm bắt màu sắc, hình dạng, khái niệm hoặc nhiều loại đặc tính khác
- Không ai thực sự hiểu đầy đủ từng con số riêng lẻ này có nghĩa gì, nhưng ta biết vị trí của chúng có thể được dùng để tìm ra thông tin hữu ích về nội dung
Tìm nội dung liên quan bằng embedding
- Bài toán đầu tiên tôi giải bằng embedding là tạo tính năng "Related Content" cho blog TIL của mình
- Tôi dùng mô hình
text-embedding-ada-002 của OpenAI, có thể sử dụng qua API
- Hiện nay website của tôi có 472 bài viết, và với mỗi bài tôi tính một vector embedding 1536 chiều (một mảng số thực dấu phẩy động), rồi lưu vector đó vào cơ sở dữ liệu SQLite của site
- Giờ nếu muốn tìm bài liên quan cho một bài cụ thể, chỉ cần tính độ tương đồng cosine (cosine similarity) giữa vector embedding của bài đó và các bài khác trong DB, sau đó trả về 10 kết quả khớp gần nhất theo khoảng cách
- Đoạn mã Python tôi dùng cho cosine similarity như sau
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 của OpenAI rất rẻ và dễ dùng
- Tôi đã embedding khoảng 400 nghìn token cho website TIL của mình, với giá $0.0001 cho mỗi 1.000 token nên tổng cộng chỉ tốn $0.04
- Chỉ cần gửi
POST kèm API key và nội dung văn bản, nó sẽ trả về một JSON Array gồm các số thực dấu phẩy động
- Tuy vậy đây là mô hình độc quyền, và vài tháng trước OpenAI đã ngừng một số mô hình embedding
- Nghĩa là nếu bạn đã lưu một lượng lớn embedding từ mô hình đó, thì với mô hình mới bạn sẽ phải tính lại embedding
- OpenAI có nói sẽ bù chi phí cho việc re-embedding sang mô hình mới, nhưng vẫn cần cẩn trọng với mô hình độc quyền
- Có thể tránh điều này bằng các mô hình giấy phép mở mạnh mẽ
Tìm hiểu cách những thứ này hoạt động trong mô hình Word2Vec
- Google Research đã công bố một bài báo có ảnh hưởng lớn cách đây 10 năm, mô tả một mô hình embedding sơ khai tên là Word2Vec
- Bài báo năm 2013 có tên "Efficient Estimation of Word Representations in Vector Space" đã khơi dậy sự quan tâm tới embedding
- Word2Vec là mô hình lấy một từ đơn lẻ và biến nó thành danh sách 300 con số. Danh sách số đó nắm bắt thông tin về ý nghĩa của các từ liên quan
- Nếu tra cứu một từ, bạn có thể tìm được các từ tương tự dựa trên khoảng cách cosine với biểu diễn Word2Vec của từ đó
- Nếu tra "france" bạn có thể nhận được các giá trị như "french: 0.70007~", "belgium: 0.69331~", "paris: 0.63349~", "germany: 0.62707~"
- Đây là sự pha trộn giữa những thứ thuộc về nước Pháp (
french) và địa lý châu Âu
- Điều thật sự thú vị ở đây là có thể thực hiện phép toán số học trên các vector này
- Nếu lấy vector của "germany", cộng thêm "paris" rồi trừ đi "france", thì vector kết quả sẽ gần nhất với "berlin"
- Mô hình này đã nắm bắt được những ý tưởng về quốc tịch và địa lý, cho thấy có thể dùng số học để khám phá thêm các sự thật về thế giới
- Word2Vec được huấn luyện trên 1,6 tỷ từ nội dung, còn các mô hình embedding ngày nay được huấn luyện trên tập dữ liệu lớn hơn rất nhiều và nắm bắt sự hiểu biết phong phú hơn nhiều về các quan hệ nền tảng
Tính toán và tìm kiếm embedding bằng các công cụ của tôi
- Tôi đang xây dựng một CLI và thư viện Python tên là LLM
- Nó có thể dùng như một CLI để tương tác với các LLM, đồng thời cũng có thể tích hợp OpenAPI
- Vài tháng trước, tôi cũng đã bổ sung khả năng chạy mô hình embedding thông qua plugin cho công cụ này (có thể dùng thư viện SentenceTransformers)
- Có thể chọn một collection embedding và thực hiện tìm kiếm semantic kiểu "Vibes-based" để tìm những thứ tương tự
- Tôi cũng đang xây dựng công cụ Symbex để tìm symbol trong codebase Python. Nhờ đó có thể tính embedding cho các hàm trong mã nguồn và xây dựng công cụ tìm kiếm code
- (Phần triển khai chi tiết được lược bỏ)
Embedding đồng thời văn bản và hình ảnh bằng CLIP
- Mô hình embedding tôi thích nhất hiện nay là CLIP
- Đây là mô hình OpenAI phát hành vào tháng 1 năm 2021, có thể embedding cả "văn bản và hình ảnh" và đặt chúng trong cùng một không gian vector
- Nếu embedding "dog", bạn sẽ có một vị trí trong không gian 512 chiều (tùy cấu hình CLIP)
- Nếu embedding một bức ảnh con chó, bạn cũng sẽ có một vị trí trong cùng không gian đó, và nó sẽ ở gần vị trí của chuỗi "dog"
- Tức là bạn có thể dùng văn bản để tìm ảnh liên quan, hoặc dùng ảnh để tìm văn bản liên quan
- Nếu đưa vào một bức ảnh bãi biển, bạn có thể nhận được các điểm tương đồng như "beach: 26.946%", "city: 19.839%", "sunshine: 24.146%"
Tìm vòi nước bằng CLIP
- Drew Breunig đã xây dựng một công cụ tìm kiếm vòi nước bằng plugin
llm-clip
- Anh ấy lấy 20.000 ảnh vòi nước và chạy CLIP
- Sau đó có thể tìm những chiếc vòi tương tự với một chiếc vòi khác, rồi từ đó tìm các lựa chọn vừa giống vừa rẻ hơn
Trả lời câu hỏi bằng RAG
- Câu hỏi cuối cùng của hầu hết những người từng dùng ChatGPT đều giống nhau:
"Làm thế nào để nó có thể trả lời dựa trên ghi chú của tôi hoặc tài liệu của công ty chúng tôi?"
- Mọi người thường cho rằng phải bỏ ra chi phí khổng lồ để huấn luyện một mô hình tùy biến dựa trên nội dung đó,
- nhưng thực ra không cần. Có thể làm được điều đó với LLM và RAG (Retrieval Augmented Generation)
- Ý tưởng cốt lõi là: "người dùng đặt một câu hỏi"
- Sau đó tìm những nội dung liên quan đến câu hỏi đó trong tài liệu riêng của bạn
- Rồi đưa các đoạn trích của nội dung đó vào LLM cùng với câu hỏi gốc
- Khi đó LLM sẽ có thể trả lời câu hỏi dựa trên phần nội dung bổ sung mà bạn đã cung cấp
- Mánh giá rẻ này hiệu quả đến mức đáng ngạc nhiên
- Nhưng để làm cho phiên bản cơ bản nhất của cách này hoạt động được thì không hề dễ
- Bạn cần làm cho nó hoạt động tốt nhất có thể trước tập câu hỏi vô hạn mà người dùng có thể đặt ra
- Vấn đề chính của RAG là xác định đoạn nội dung trích dẫn nào là tốt nhất để đưa vào prompt gửi tới LLM
- Semantic search kiểu "Vibes-based" chạy bằng embedding là khả năng cần thiết để thu thập nội dung liên quan có giá trị cao, giúp trả lời câu hỏi của người dùng
- Tôi đã xây dựng và công khai một phiên bản cho "nội dung blog" của mình
- Kết quả là có thể làm RAG chỉ bằng một Bash script một dòng
5 bình luận
Tôi đã đọc bài này và thử làm vào cuối tuần. Tôi định thử mô hình tiếng Hàn nhưng việc thiết lập môi trường không hề dễ, nên đã dùng ada v2 và tổng cộng tốn 0,03 USD. Nếu là người dùng mới chưa từng dùng ChatGPT, có lẽ chỉ với 5 USD credit miễn phí là cũng đủ để thử rồi hehe.
Tôi còn tính cả độ tương đồng cosine để so sánh, và kết quả khá thuyết phục. Cảm ơn bạn đã chia sẻ bài viết.
Cuối tuần này mình phải thử làm theo một lần mới được.
Cảm ơn~
Có vẻ như tôi đã hiểu được phần nào.
Cảm ơn bạn.
Tôi đã hiểu thêm rất nhiều về những phần mà trước giờ vẫn thấy tò mò nhưng chưa nắm rõ. Luôn cảm ơn vì những nội dung hay.