Chunking là gì? Late Chunking và cách sử dụng nó cài đặt RAG nâng cao

Chunking là gì?

Nếu bạn từng cố gắng ăn hết một chiếc bánh pizza siêu to khổng lồ và cuối cùng phải thừa nhận là "Thôi, cắt ra miếng nhỏ ăn cho dễ", thì bạn đã hiểu ngay được bản chất của kỹ thuật chunking rồi đấy! Trong Machine Learning, AI cũng cần phải "chia miếng" giống như chúng ta khi đối mặt với chiếc pizza quá cỡ đó!

Chunking chính là chia nhỏ dữ liệu thành từng phần dễ tiêu hóa hơn. Thay vì bắt máy tính "nhai" cả tấn dữ liệu trong một lần, chúng ta nhẹ nhàng chia nhỏ mọi thứ thành các phần vừa phải để AI có thể "nhấm nháp" từng miếng. Đúng vậy, cả AI cũng cần nghỉ ngơi và ăn từ tốn!

Ví dụ:

Hãy tưởng tượng bạn có một file tài liệu siêu dài cỡ 100 trang. Nếu bạn đưa cả tài liệu này cho LLM xử lý, nó sẽ nhìn bạn kiểu: "Giỡn mặt hả bro, đưa nhiêu đây đọc sao cho nổi?" Để nó đỡ nổi giận và xâm chiếm trái đất thì chúng ta cần phải chia tài liệu thành những câu hoặc đoạn văn ngắn hơn. Lúc đó thì nó mới có thể xử lý hiệu quả được nguồn thông tin khổng lồ mà bạn đưa vào

Hay khi bạn có một tấm ảnh chất lượng 4K siêu sắc nét, và bạn muốn đưa hết tấm ảnh đó vào AI để nó edit theo ý bạn. Vậy thì chẳng khác nào bắt nó đứng trước một bức tranh khổng lồ và đòi hỏi phân tích từng chi tiết cùng lúc. Chunking sẽ giúp chia nhỏ bức ảnh thành từng mảnh, để AI có thể phân tích từ từ, không bị "nghẹn".

Chunking đơn giản là chia nhỏ dữ liệu thành từng "khối" (chunks) có kích thước vừa phải. Thay vì xử lý toàn bộ dữ liệu lớn cùng một lúc, LLMs chỉ cần xử lý các phần nhỏ hơn, giúp mô hình hoạt động "bớt căng thẳng" hơn và tối ưu hơn về mặt tính toán.

Late Chunking là gì?

Tóm tắt: Thay vì chia nhỏ tài liệu trước, Late Chunking xử lý toàn bộ văn bản trước khi tạo embeddings cho từng chunk. Điều này giúp embedding của mỗi chunk sẽ giàu ngữ cảnh của toàn bộ tài liệu, giữ được những liên kết quan trọng giữa các phần thông tin.

Chunking cơ bản ở trong RAG:

Trong Retrieval-Augmented Generation (RAG), chunking là quá trình chia một tài liệu dài thành các "chunks" nhỏ hơn (mỗi chunk chứa khoảng 512 token). Điều này rất quan trọng vì các LLMs thường bị giới hạn về lượng văn bản có thể xử lý cùng một lúc. Bằng cách chia tài liệu thành các chunk nhỏ, mỗi phần có thể được lưu trữ riêng lẻ trong Vector Database.

Trong quá trình truy xuất, khi người dùng đưa ra một câu hỏi, Embedding Model sẽ mã hóa câu hỏi đó thành một vector. Vector này sau đó được sử dụng để tìm và truy xuất các chunks văn bản phù hợp nhất từ Vector Database. Những chunk được truy xuất này, đại diện cho các phần liên quan nhất của tài liệu gốc, sau đó sẽ được đưa vào LLM để tổng hợp một câu trả lời dựa trên thông tin chứa trong các chunks đó. Điều này đảm bảo rằng câu trả lời được đưa ra dựa trên các phần có liên quan nhất của văn bản.

Các bước trong hệ thống RAG cơ bản (source)


Hạn chế của kỹ thuật chunking cơ bản là gì?

Các phương pháp chunking truyền thống khi chia văn bản thành các chunks nhỏ thường dẫn đến việc làm mất đi các kết nối quan trọng giữa các phần khác nhau của văn bản. Tại vì khi bạn cắt tài liệu ra những đoạn nhỏ, thì những đoạn đó sẽ bị cô lập và mất đi mối quan hệ tới các đoạn khác. Embedding vector của những đoạn bị cô lập đó sẽ chỉ tổng hợp được thông tin nội bộ trong đoạn, nhưng không tổng hợp được thông tin liên quan giữa các đoạn khác nhau. 

Trong hình dưới đây, một bài viết trên Wikipedia được chia thành nhiều đoạn câu. Bạn có thể thấy các từ như "its" và "the city" đều ám chỉ "Berlin", nhưng "Berlin" chỉ được nhắc đến ở câu đầu tiên. Nếu giờ bạn cắt đoạn văn ra các câu riêng lẻ thì ngữ cảnh của các từ "its" và "the city" sẽ không còn nữa.

Ngữ nghĩa bị cắt mất khi ta dùng kỹ thuật chunking cơ bản (source)

Điều này có nghĩa là, nếu chúng ta chia một bài viết dài thành các câu như trong ví dụ ở trên, RAG có thể gặp khó khăn khi trả lời câu hỏi kiểu "Dân số của Berlin là bao nhiêu?" Vì tên thành phố và số dân không xuất hiện cùng nhau trong một câu, và khi không có ngữ cảnh đầy đủ của cả tài liệu, một LLM chỉ được cung cấp một trong các đoạn này sẽ không thể giải quyết được các tham chiếu như "it" hay "the city".

Có một số phương pháp heuristic để giảm thiểu vấn đề này, chẳng hạn như resampling lại với sliding window, sử dụng nhiều context window lengths, và thực hiện quét tài liệu nhiều lần. Tuy nhiên, giống như tất cả các phương pháp heuristic khác, những cách tiếp cận này có tính may rủi; chúng có thể hiệu quả trong một số trường hợp, nhưng không có gì đảm bảo về mặt lý thuyết rằng chúng luôn thành công.

Giải pháp: Late Chunking

Một phương pháp encoding "ngây thơ" (ảnh bên trái) là sử dụng các câu, đoạn văn, hoặc giới hạn độ dài tối đa để chia nhỏ văn bản trước. Sau đó, một embedding model sẽ được áp dụng lặp đi lặp lại trên các chunks đã được chia. Để tạo ra một embedding duy nhất cho mỗi chunk, nhiều embedding models sử dụng mean pooling trên các embeddings ở cấp độ token để xuất ra một embedding vector duy nhất.

So sánh giữa "Naive Chunking" và "Late Chunking" (source)

Ngược lại, Late Chunking sẽ áp dụng một transformer layer của embedding model lên toàn bộ văn bản hoặc càng nhiều phần của văn bản càng tốt trước. Điều này tạo ra một chuỗi các vector biểu diễn cho mỗi token (là cái cục "token emb" ở trong hình), đã được bao gồm thông tin từ toàn bộ văn bản. Sau đó, mean pooling được áp dụng cho từng đoạn của chuỗi "token emb" này, tạo ra các embedding vector cho mỗi chunk (ở trong hình là chunk1 embedding, chunk2 embedding, ...) với sự cân nhắc đến ngữ cảnh của toàn bộ văn bản. Khác "Naive Chunking", phương pháp tạo ra các embedding vector độc lập và phân phối giống hệt nhau (independent and identically distributed - i.i.d), "Late Chunking" tạo ra một tập hợp các embedding vectors mà mỗi vector đều được ảnh hưởng bởi những vector trước đó, nhờ vậy mã hóa được nhiều thông tin ngữ cảnh hơn cho từng đoạn.

Rõ ràng, để áp dụng hiệu quả Late Chunking, chúng ta cần các embedding models hỗ trợ ngữ cảnh dài (long-context embedding models), ví dụ như "jina-embeddings-v2-base-en", có khả năng xử lý tối đa 8192 token, tương đương khoảng mười trang văn bản tiêu chuẩn. 

Kết quả thử nghiệm

Cách cài đặt Late Chunking, các bạn có thể tham khảo trong GitHub repo, hoặc Colab Notebook này.

Khi áp dụng Late Chunking vào ví dụ Wikipedia ở trên, bạn có thể thấy ngay sự cải thiện về độ tương đồng ngữ nghĩa. Ví dụ, trong cụm từ "the city" và "Berlin", các vector biểu diễn cho "the city" giờ đây chứa các thông tin của "Berlin" được nhắc đến trước đó.

Bảng trên so sánh độ tương đồng cosine giữa embedding vector của từ "Berlin" và các câu khác nhau trong bài viết có liên quan tới Berlin. Cột "Sim. on naive chunking" hiển thị các giá trị tương đồng giữa embedding vector của truy vấn "Berlin" và các embedding vector sử dụng phương pháp Naive Chunking, còn cột "Sim. on late chunking" biểu thị kết quả với phương pháp Late Chunking

Kết luận

Trong bài viết này, chúng ta đã tìm hiểu kỹ thuật "Late Chunking" để mã hóa các đoạn ngắn bằng cách tận dụng sức mạnh của các long-context embedding models. Chúng ta thấy rằng các phương pháp chunking truyền thống không giữ được thông tin ngữ cảnh, dẫn đến việc truy xuất không hiệu quả. Late Chunking cung cấp một giải pháp đơn giản nhưng hiệu quả để duy trì thông tin ngữ cảnh trong mỗi đoạn. 

Post a Comment

0 Comments