0

Kiến trúc ColBERT cho Retrieval-Augmented Generation (RAG)

Link đính kèm:

I. ColBERT v1

1. Tổng quan

Trong kiến trúc hệ thống tìm kiếm thông tin hiện đại, chúng ta đang chứng kiến một sự chuyển dịch mang tính bước ngoặt: từ tìm kiếm từ khóa (lexical search) dựa trên tần suất từ (BM25) sang tìm kiếm ngữ nghĩa (semantic search) dựa trên không gian vector. Trong hệ sinh thái Neural IR, ColBERT (Contextualized Late Interaction over BERT) đã xác lập vị thế là một trong những kiến trúc hiệu quả nhất nhờ cơ chế Late Interaction.

Điểm đổi mới cốt lõi của ColBERT là khả năng bảo toàn đặc tính ngữ nghĩa ở cấp độ token (token-level embeddings) thay vì nén toàn bộ văn bản vào một vector duy nhất (single-vector). Điều này giúp hệ thống đạt được độ chính xác tương đương các mô hình Cross-Encoder phức tạp nhưng vẫn duy trì được hiệu suất truy xuất ở quy mô lớn của các mô hình Bi-Encoder. Đối với các kỹ sư kiến trúc giải pháp AI, ColBERT mang lại 3 giá trị chiến lược cho hệ thống RAG (Retrieval-Augmented Generation):

  • Độ chính xác chi tiết (Fine-grained Precision): Khả năng nắm bắt các sắc thái ngôn ngữ nhỏ nhất, đặc biệt hiệu quả trong các truy vấn dài hoặc chứa các thuật ngữ chuyên môn sâu.
  • Hiệu suất lưu trữ đột phá: Với sự ra đời của phiên bản v2, các kỹ thuật nén phần dư (residual compression) đã cho phép triển khai trên hàng tỷ tài liệu mà không đòi hỏi tài nguyên RAM không tưởng.
  • Khả năng Grounding vượt trội: Cung cấp bằng chứng truy xuất mạnh mẽ để giảm thiểu hiện tượng hallucination trong các Pipeline Agentic RAG.

2. Kiến trúc Cốt lõi và Cơ chế Late Interaction

Sự khác biệt lớn nhất giữa ColBERT và các kiến trúc Dense Retrieval truyền thống nằm ở giai đoạn tương tác giữa Query (câu hỏi) và Document (tài liệu).

2.1 Phân tích sự đánh đổi về Performance

Các mô hình "Single-vector" truyền thống nén toàn bộ ngữ cảnh của một đoạn văn vào một vector duy nhất (thường là 768 chiều). Quy trình này tạo ra hiện tượng "nghẽn cổ chai thông tin", nơi các chi tiết cụ thể bị pha loãng. ColBERT phá bỏ giới hạn này bằng cách sử dụng Token-level embeddings. Mỗi token trong văn bản được ánh xạ thành một vector riêng biệt, cho phép mô hình giữ lại "dấu vết" ngữ nghĩa của từng từ trong mối tương quan với các từ xung quanh.

2.2 Kiến trúc mạng (Encoder Architecture)

ColBERT sử dụng một mô hình ngôn ngữ tiền huấn luyện (thường là BERT) nhưng cấu hình nó theo cách đặc biệt để tạo ra các Contextualized Token Embeddings.

2.2.1 Query Encoder (fQf_Q)

  1. Input: Câu hỏi q được thêm tiền tố đặc biệt [Q].

Cấu trúc Input: [CLS] [Q] q1 q2 ... ql [mask] [mask] ... [mask]

  • [Q] Token: Một token đặc biệt để báo cho BERT biết: "Đây là một câu hỏi, hãy xử lý nó theo kiểu truy vấn."
  • Query Augmentation (Dùng [mask]): ColBERT cung cấp hyperparameter chiều dài query là NqN_q. Nếu query có ít token hơn NqN_q, nó sẽ bù vào bằng các token [mask]. Ngược lại nếu nhiều token hơn NqN_q, nó sẽ chỉ giữ NqN_q tokens từ query.

💡 Tại sao lại dùng [mask]?

  • Cơ chế học "Mở rộng truy vấn" (Query Expansion): Các token [mask] này cho phép BERT sinh ra các embedding tại vị trí đó dựa trên ngữ cảnh của câu hỏi gốc, những từ tiềm năng có thể liên quan đến câu hỏi.
  • Học trọng số (Re-weighting): Thông qua các vị trí [mask], BERT có thể học cách nhấn mạnh hoặc giảm nhẹ tầm quan trọng của các từ có sẵn trong query để tối ưu hóa việc matching với document sau này.
  1. Processing: Đi qua BERT để lấy các hidden states
  2. Linear Bottleneck: Sau lớp BERT, ColBERT thêm một lớp Linear Layer (không có activations) để giảm số chiều xuống còn m chiều (thường m = 128).

💡 Linear Layer không có activation vì:

  • Bản chất là phép chiếu chứ không phải trích xuất (Extraction): BERT cực kỳ mạnh mẽ với hàng chục lớp Transformer và Activation (GELU). Nhiệm vụ của lớp Linear ở cuối không phải là học thêm các tính chất phi tuyến phức tạp, mà đơn giản là nén không gian vector từ 768 chiều xuống m chiều.
  • Bảo toàn thông tin và Hướng: Nếu thêm một activation như ReLU, sẽ vô tình triệt tiêu toàn bộ các giá trị âm. Trong không gian vector để tính Dot Product, các giá trị âm mang thông tin cực kỳ quan trọng về sự "đối lập" hoặc "khác biệt" giữa các từ. Việc giữ lớp Linear thuần túy giúp bảo toàn trọn vẹn đặc trưng mà BERT đã học được.
  • Tối ưu cho L2 Normalization: việc có một hàm Activation trước đó có thể làm biến dạng phân phối của các giá trị, khiến việc chuẩn hóa không còn phản ánh đúng tương quan ngữ nghĩa mà BERT tạo ra.

☝ Paper nhấn mạnh m chiều ảnh hưởng lớn:

  • Đối với Document: Lưu trữ hàng tỷ vector token tốn rất nhiều chỗ; m càng nhỏ, lưu trữ càng nhẹ.
  • Đối với Tốc độ: Khi chạy Ranking, hệ thống phải chuyển các vector từ RAM (CPU) lên GPU; m càng nhỏ, tốc độ truyền tải (transfer time) càng nhanh. Đây thường là bước tốn kém nhất trong quá trình Reranking với ColBERT.
  1. Normalization: Áp dụng L2 Normalization để mọi vector đều có độ dài bằng 1. Điều này giúp dot product sau này tương đương với Cosine Similarity.
  2. Output: Một ma trận Eq={q0,q1,q2,...,ql}E_q=\{q_0,q_1,q_2,...,q_l\}, trong đó NqmN_q * m là số lượng token trong query. Với # là token [mask]:

Eq:=Normalize(CNN(BERT("[Q] q0q1ql###")))E_q := \text{Normalize}\left( \text{CNN}\left( \text{BERT}(\text{"[Q] } q_0 q_1 \dots q_l \#\# \dots \#") \right) \right)

Thực tế: Trong mã nguồn và các giải thích sâu hơn của tác giả, CNN ở đây thường được hiểu là một lớp Convolution 1D với kernel size = 1 (nó tương đương với lớp Linear layer đề cập bên trên). Việc dùng kernel size 1 giúp nó xử lý từng token embedding một cách độc lập mà không làm trộn lẫn thông tin giữa các token lân cận (vì việc trộn lẫn đã được lớp Self-attention của BERT làm rồi).

2.2.2 Document Encoder (fDf_D)

  1. Input: Văn bản d được thêm tiền tố [D].

📌 Cấu trúc Input: [CLS] [D] d1 d2 ... dn (Không có [mask]).

  1. Processing: Tương tự Query Encoder nhưng có một bước cực kỳ quan trọng: Punctuation Filtering.

💡 Punctuation Filtering (Bộ lọc dấu câu):

  • Sau khi đi qua BERT và lớp Linear, ColBERT sẽ xóa bỏ các vector ứng với các dấu câu (., !, ?...).
  • Lý do: Các dấu câu dù có ngữ cảnh (contextualized) nhưng không đóng góp nhiều vào giá trị tìm kiếm thông tin. Việc loại bỏ chúng giúp giảm số lượng vector cần lưu trữ trên mỗi document, trực tiếp làm giảm dung lượng lưu trữ và tăng tốc độ truyền dữ liệu từ CPU lên GPU khi Ranking.
  1. Output: Một ma trận Ed={d0,d1,d2,...,dn}E_d=\{d_0,d_1,d_2,...,d_n\}, trong đó n là số lượng token hữu ích trong document.

Ed:=Filter(Normalize(CNN(BERT("[D] d0d1dn"))))E_d := \text{Filter}\left( \text{Normalize}\left( \text{CNN}\left( \text{BERT}(\text{"[D] } d_0 d_1 \dots d_n") \right) \right) \right)

2.3 Cơ chế Late Interaction với phép toán MaxSim (Maximum Similarity)

Đây là "linh hồn" của ColBERT, thứ giúp nó khác biệt hoàn toàn với Dense Retrieval truyền thống (như SBERT).

Thay vì nén cả ma trận EdE_d thành 1 vector, ColBERT giữ nguyên toàn bộ tập hợp các vector token. Khi tính toán độ liên quan giữa Query và Document, nó thực hiện toán tử MaxSim:

Score(q,d)=i=1Eqmaxj[1,Ed]  qidjT\text{Score}(q, d) = \sum_{i=1}^{|E_q|} \max_{j \in [1, |E_d|]} \; \mathbf{q}_i \cdot \mathbf{d}_j^{T}

💡 Dùng Dot-product vì các vector đã được L2-Normalized. Khi đó, Dot-product chính là Cosine Similarity, tính toán trên GPU nhanh hơn rất nhiều so với các hàm Cosine phức tạp.

💡 Cơ chế "Non-trainable Interaction":

  • Bản thân cơ chế MaxSim không có tham số nào để học (no trainable parameters). Nó chỉ là một phép toán cộng và tìm Max đơn thuần.
  • Ý nghĩa: Điều này giúp bước tương tác cực kỳ nhẹ về mặt tính toán, vì nó không phải chạy qua bất kỳ lớp Neural Network nào nữa.

Phân tích chi tiết bước này:

  1. Giải mã: Với mỗi token trong câu hỏi (qiq_i), hệ thống tìm kiếm trong toàn bộ văn bản để chọn ra token (djd_j) có độ tương đồng lớn nhất với nó.
  2. Tinh điểm: Nó cộng tất cả các giá trị tương đồng lớn nhất đó lại để ra điểm số cuối cùng.
  3. Ý nghĩa: Nó cho phép "Soft Keyword Matching": Vừa khớp từ khóa chính xác, vừa khớp ngữ nghĩa linh hoạt.

🗒️ Paper cung cấp thông tin Training Strategy:

  • Dữ liệu đầu vào: Một bộ ba (Triple) gồm: q (câu hỏi), d+d^+ (văn bản đúng/tích cực) và dd^- (văn bản sai/tiêu cực).
  • Mục tiêu (Loss Function): Sử dụng Pairwise Softmax Cross-entropy.
  • Logic: Mô hình sẽ cố gắng tối ưu sao cho điểm Sq,d+S_{q,d^+} phải lớn hơn hẳn điểm Sq,dS_{q,d^-} BERT sẽ phải tự học cách tạo ra các vector sao cho khi thực hiện phép toán MaxSim, văn bản đúng sẽ "khớp" với câu hỏi tốt hơn văn >bản sai.

3. Tính toán và lưu trữ Embedding Document (Offline Indexing)

Một trong những thách thức lớn nhất của kiến trúc Multi-vector là chi phí lưu trữ và tính toán. ColBERT giải quyết vấn đề này thông qua quy trình lập chỉ mục tách biệt hoàn toàn.

3.1 Triết lý Cách ly Tính toán (Isolation of Computation)

ColBERT được thiết kế để tách biệt quá trình mã hóa Query và Document. Điều này cho phép hệ thống tính toán và lưu trữ toàn bộ tập hợp embedding của tài liệu Offline. Khi có truy vấn, hệ thống chỉ cần tính toán duy nhất một ma trận EqE_q và thực hiện tra cứu trên các EdE_d đã có sẵn.

3.2 Lưu trữ Embedding (Storage)

  • Sau khi tính toán xong, các vector được lưu xuống đĩa (Disk).
  • Định dạng: Sử dụng giá trị 32-bit (float32) hoặc 16-bit (float16) cho mỗi chiều của vector.
  • Mục đích sử dụng:
    • Ranking: Load trực tiếp từ đĩa lên RAM/GPU để xếp hạng.
    • Vector-similarity search: Tiếp tục được đánh chỉ mục (index) để tìm kiếm bằng các thuật toán vector (như FAISS).

3.3 Tối ưu hóa hiệu suất Indexing

Để xử lý hàng triệu tài liệu, ColBERT áp dụng các kỹ thuật tối ưu hóa phần cứng và thuật toán:

  • Length-based Bucketing (BucketIterator):
    • Vấn đề: Các tài liệu trong cùng một batch có độ dài khác nhau dẫn đến lãng phí tài nguyên GPU do cơ chế Padding.
    • Giải pháp: Hệ thống gom nhóm tài liệu (ví dụ 100,000 bản ghi), sắp xếp theo độ dài, sau đó mới chia thành các batch nhỏ hơn để đưa vào GPU. Kỹ thuật này giảm thiểu tối đa lượng padding, giúp tăng băng thông xử lý của GPU.

💡 Cơ chế Padding: Trong một batch, nếu có 1 văn bản rất dài và nhiều văn bản rất ngắn, các văn bản ngắn sẽ phải "pad" (thêm các token trống) cho bằng văn bản dài nhất. Việc này làm GPU tốn bộ nhớ vô ích cho các token trống đó.

  • CPU-GPU Parallelism:
    • Việc xử lý tiền dữ liệu (WordPiece Tokenization) thường là bottleneck trên CPU. ColBERT thực hiện song song hóa quá trình này trên nhiều nhân CPU trong khi GPU thực hiện tính toán ma trận, đảm bảo luồng dữ liệu liên tục.

4. Luồng triển khai ColBERT với bài toán Re-ranking và Top-k Retrieval

ColBERT không chỉ là một mô hình học sâu, nó là một hệ thống tìm kiếm hai giai đoạn được tối ưu hóa cho hiệu suất thực tế. Có hai kịch bản triển khai chính:

4.1 Top-k Re-ranking

Trong kịch bản này, ColBERT được sử dụng để lọc lại kết quả từ một bộ tìm kiếm thô (thường là BM25). Mục tiêu là xếp hạng lại một tập nhỏ tài liệu (ví dụ: k = 1000) để đạt độ chính xác cao nhất.

Quy trình thực thi chi tiết:

  1. Query Encoding: Hệ thống nhận câu hỏi, chạy qua Query Encoder (BERT + Linear) duy nhất 1 lần để tạo ra ma trận embedding .
  2. Batch Gathering (Concurrently): đồng thời, hệ thống tải k ma trận embedding của k tài liệu ứng viên từ RAM CPU. Các ma trận này được gom lại thành một Tensor 3 chiều D*D*. Tensor này có kích thước k×doc_length×dimk×doc\_length×dim, cho phép GPU thực hiện phép nhân ma trận hàng loạt (batch dot-product) thay vì phải xử lý từng tài liệu một cách tuần tự.
  3. Data Transfer: Chuyển Tensor D*D* từ bộ nhớ hệ thống lên bộ nhớ GPU (VRAM). Đây là bước tốn kém nhất về mặt thời gian trong quá trình Re-ranking.
  4. Batch Dot-Product: Trên GPU, thực hiện phép nhân ma trận hàng loạt giữa EqE_q và Tensor D*D*. Kết quả trả về là một Tensor 3 chiều chứa các ma trận tương đồng (cross-match matrices) giữa query và từng tài liệu.
  5. MaxSim Reduction:
    • Max-pooling: Với mỗi tài liệu, thực hiện tìm giá trị lớn nhất trên các cột (đại diện cho các token của tài liệu) để lấy ra điểm tương đồng lớn nhất cho mỗi từ trong query.
    • Summation: Cộng dồn các giá trị Max này lại để ra điểm số cuối cùng cho tài liệu đó.
  6. Sorting: Sắp xếp  tài liệu dựa trên điểm số để trả về kết quả cuối cùng.

4.2 Top-k Retrieval (End-to-End)

Khi số lượng tài liệu N quá lớn (ví dụ: 10 000 000), việc tính toán MaxSim cho toàn bộ là không khả thi. ColBERT sử dụng quy trình Tìm kiếm hai giai đoạn (Two-stage procedure) dựa trên thư viện FAISS.

Giai đoạn 1: Approximate Stage - Filtering

Hệ thống coi mọi token embedding của mọi tài liệu là một thực thể độc lập trong không gian vector.

  • Indexing: Toàn bộ document embeddings được đưa vào một cấu trúc dữ liệu IVFPQ (Inverted File with Product Quantization) của Faiss.
    • IVF: Phân vùng không gian vector thành P vùng (cells) bằng K-means. Khi tìm kiếm, hệ thống chỉ quét qua p (hyperparameter) **vùng gần nhất.
    • PQ: Chia nhỏ mỗi vector thành các sub-vectors và nén chúng lại để tiết kiệm RAM.
  • Search: Với mỗi vector trong số NqN_q vectors của queryquery (EqE_q), hệ thống thực hiện truy vấn tìm kiếm vector-similarity đồng thời trên Faiss.
    • Mỗi vector query trả về kk^’ kết quả gần nhất.
    • Hệ thống ánh xạ (map) các vector này về ID tài liệu gốc của chúng.
    • Kết quả là một tập hợp K*K* tài liệu ứng viên (KNq×kK≤N_q×k^’).

Giai đoạn 2: Refinement Stage - Re-ranking

Sau khi có tập hợp KK tài liệu tiềm năng (thường nhỏ hơn rất nhiều so với NN), hệ thống thực hiện quy trình Re-ranking chi tiết (như mô tả ở phần 3.1). Bước này đảm bảo độ chính xác tối đa bằng cách tính toán MaxSim đầy đủ thay vì dựa trên các vector nén xấp xỉ của Faiss.

5. So sánh hiệu năng của ColBERT

📌 Các số liệu độ trễ được đo đạc trên cấu hình tiêu chuẩn:

  • GPU: 1x NVIDIA Tesla V100 (32GB VRAM).
  • CPU: Intel Xeon Gold 6132 (28 nhân vật lý).
  • RAM: 469 GiB.

📌 Chỉ số đánh giá:

  • MRR@10 (Mean Reciprocal Rank): Đánh giá khả năng đưa kết quả đúng lên vị trí đầu tiên. Điểm càng gần 1 càng tốt.
  • Recall@k: Đánh giá khả năng "vét" sạch tài liệu đúng trong kho dữ liệu vào Top k .
  • FLOPs (Floating Point Operations): Đại diện cho khối lượng công việc mà GPU phải xử lý. FLOPs thấp đồng nghĩa với tốc độ nhanh và chi phí vận hành rẻ.
  • Latency (ms): Thời gian phản hồi của hệ thống (tính bằng mili giây).

5.1 Hiệu năng Re-ranking trên tập dữ liệu MS MARCO

Trong thử nghiệm này, ColBERT được dùng để Re-rank top-1000 tài liệu được trả về từ mô hình truyền thống BM25 trên tập dữ liệu MS MARCO (8.8 triệu đoạn văn bản).

Nhận xét:

  • Accuracy-Efficiency Trade-off: Thông thường, các mô hình nhanh hơn sẽ kém chính xác hơn. Tuy nhiên, ColBERT đạt MRR@10 nhỉnh hơn cả BERT-base (34.9 vs 34.7) trong khi nhanh hơn gấp 175 lần. Điều này chứng minh cơ chế Late Interaction có khả năng biểu diễn ngữ nghĩa tương đương với Full Self-Attention của Cross-Encoder.
  • Tiết kiệm tài nguyên tính toán: Chỉ số FLOPs của ColBERT thấp hơn BERT-base tới 13,900 lần. Điều này cho thấy ColBERT cực kỳ thân thiện với phần cứng, cho phép triển khai trên các dòng GPU phổ thông thay vì các cụm máy chủ đắt đỏ.
  • Tối ưu cho Real-time: Với độ trễ 61ms, ColBERT đưa tìm kiếm Neural IR vào ngưỡng phản hồi thời gian thực (real-time), mở đường cho việc áp dụng AI vào các công cụ tìm kiếm quy mô lớn.

5.2 Hiệu năng Retrieval trên tập dữ liệu MS MARCO

Trong thử nghiệm này, ColBERT được dùng để Retrieval top-1000 tài liệu trực tiếp trên tập dữ liệu MS MARCO (8.8 triệu đoạn văn bản).

Nhận xét:

  • Đột phá về Recall: ColBERT đạt Recall@50 là 82.9%, con số này thậm chí còn cao hơn cả Recall@1000 của BM25 (81.4% theo bản ocial). Điều này cực kỳ quan trọng: Nó có nghĩa là ColBERT tìm thấy nhiều tài liệu liên quan trọng Top 50 hơn cả số lượng tài liệu mà BM25 tìm thấy trong tận Top 1000.
  • Vượt xa các mô hình mở rộng văn bản (Document Expansion): Ngay cả khi so sánh với docTTTTTquery (một mô hình dùng T5 để mở rộng từ khóa cực mạnh), ColBERT vẫn áp đảo về MRR@10 (36.0 vs 27.7). Điều này cho thấy việc lưu trữ đa vector (multi-vector) hiệu quả hơn hẳn việc cố gắng nén thông tin vào các từ khóa đơn lẻ.
  • Hiệu quả: Một insight thú vị từ paper là việc dùng ColBERT để tìm kiếm trực tiếp (End-to-End) cho kết quả (MRR 36.0) tốt hơn cả việc dùng ColBERT để Re-rank kết quả của BM25 (MRR 34.9).
    • Lý do: BM25 đôi khi "bỏ sót" những tài liệu có sự tương đồng ngữ nghĩa nhưng không trùng khớp từ khóa. Khi ColBERT tự mình đi tìm, nó không bị giới hạn bởi bộ lọc thô của BM25 và có thể "vớt" được những tài liệu quý giá đó ngay từ giai đoạn đầu.
  • Độ trễ chấp nhận được: 458ms cho việc tìm kiếm Neural trên 8.8 triệu tài liệu là tương đối cao, nhưng chất lượng kết quả mang lại (gần gấp đôi MRR) hoàn toàn xứng đáng cho các ứng dụng đòi hỏi độ chính xác cao như hệ thống hỏi đáp (QA) hay RAG chuyên sâu.

Kết luận

ColBERT v1 là mô hình tiên phong trong kiến trúc tương tác muộn (late interaction), cho phép mã hóa độc lập truy vấn và tài liệu thành các tập vector rồi tính điểm liên quan qua toán tử MaxSim,,. Phương pháp này giúp duy trì độ chính xác cao của BERT nhưng đạt tốc độ nhanh hơn 170 lần và giảm lượng tính toán 14.000 lần nhờ khả năng tính toán trước và lưu trữ tài liệu ngoại tuyến,.

Tuy nhiên, hạn chế lớn nhất của v1 là chiếm dụng không gian lưu trữ cực lớn (≥ 154 GiB cho tập dữ liệu MS MARCO), cao hơn gấp 10 lần so với các mô hình vector đơn,. Nguyên nhân là do v1 phải lưu trữ hàng tỷ vector chi tiết cho mọi token trong toàn bộ tập dữ liệu mà chưa có cơ chế nén hiệu quả

II. ColBERT v2: Tối ưu hóa Lưu trữ và Chất lượng Giám sát

1. Đặt vấn đề

Ở phiên bản v1, đặt ra một thách thức lớn về Không gian lưu trữ (Space Footprint), việc lưu trữ vector thô (16-bit/32-bit float) cho mỗi token khiến dung lượng Index phình to một cách khủng khiếp.

  • Ví dụ: Với 8.8 triệu đoạn văn của MS MARCO, v1 tốn 154 GiB - 286 GiB.
  • Hệ quả: Việc triển khai trên quy mô hàng tỷ tài liệu (Billion-scale) đòi hỏi tài nguyên RAM cực kỳ đắt đỏ, vượt quá khả năng của nhiều hệ thống.

Nếu ColBERT v1 là một "đột phá" với cơ chế Late Interaction, thì ColBERT v2 chính là lời giải cho bài toán thực tế, v2 tập trung giải quyết hai vấn đề chí mạng của v1: Dung lượng lưu trữ khổng lồ và Sự phụ thuộc vào chất lượng dữ liệu huấn luyện.

2. Chiến lược huấn luyện: Denoised Supervision

Trong khi ColBERT v1 dựa trên các cặp Triple (q,d+,d)(q,d^+,d^-) đơn giản từ tập dữ liệu MS MARCO, ColBERTv2 thực hiện một bước nhảy vọt về chất lượng thông qua cơ chế giám sát tinh vi. Mục tiêu của v2 là tạo ra các vector token chuẩn xác hơn, giúp chúng giữ được đặc trưng ngữ nghĩa ngay cả sau khi bị nén cực mạnh.

2.1 Distillation (Chưng cất tri thức từ Cross-Encoder)

  • Mô hình “giáo viên”: Sử dụng một Cross-Encoder mạnh (như MiniLM với 22 triệu tham số). Cross-Encoder cực kỳ chính xác vì nó cho phép câu hỏi và văn bản tương tác với nhau ngay từ lớp đầu tiên (Early Interaction).
  • Cơ chế học: Với mỗi Query, mô hình “giáo viên” sẽ chấm điểm một tập hợp các tài liệu (bao gồm cả tài liệu đúng và tài liệu sai tiềm năng).
  • Hàm Loss KL-Divergence: Thay vì dùng hàm Loss phân loại nhị phân (Đúng/Sai) như v1, ColBERTv2 sử dụng KL-Divergence để bắt chước hoàn toàn "phân phối điểm số" của Cross-Encoder.

LKL=iPteacher(diq)logPteacher(diq)Pstudent(diq)L_{KL} = \sum_{i} P_{teacher}(d_i \mid q)\log \frac{P_{teacher}(d_i \mid q)}{P_{student}(d_i \mid q)}

💡 Ở đây, PteacherP_{teacher} được tính bằng Softmax trên các Logits của Cross-Encoder. Nếu dd^- thực chất là một tài liệu tốt (False Negative), mô hình “giáo viên” (vốn rất thông minh và nhìn thấy cả qqdd cùng lúc) sẽ trả về một điểm số cao cho dd^-.

→ Vì không bị ép "bẻ cong" vector để thỏa mãn nhãn sai, các vector token sẽ hội tụ về các cụm (clusters) rất rõ ràng và ổn định dựa trên ý nghĩa thực của chúng.

2.2 Hard-Negative Mining (Khai thác mẫu âm khó)

Để mô hình thực sự tinh nhạy, nó cần được huấn luyện bởi những ví dụ Hard Negatives.

  • Quy trình: ColBERTv2 sử dụng chính Index đã nén của nó để thực hiện truy vấn trên tập huấn luyện và lấy ra Top-k kết quả.
  • Lựa chọn mẫu: Những tài liệu không phải là tài liệu đúng nhưng lại được ColBERTv2 chấm điểm cao chính là các Hard Negatives. Các mẫu này chứa rất nhiều từ khóa trùng khớp với query nhưng lại sai về bản chất ngữ nghĩa hoặc ngữ cảnh.
  • Độ khó tăng cường: v2 xây dựng các bộ dữ liệu huấn luyện lên tới 64-way tuples, Cụ thể, v2 sử dụng cấu trúc 64-way nghĩa là mỗi Query sẽ đi kèm với 1 tài liệu đúng (d+d^+)63 tài liệu sai (dd^-). Điều này buộc BERT phải học cách phân biệt các sắc thái ngữ nghĩa cực nhỏ ở cấp độ token để không bị đánh lừa.

💡 v1 (Triplets): 1 Pos + 1 Neg → Ranh giới phân loại rộng, dễ bị nhiễu bởi các tài liệu trùng từ khóa. v2 (64-way Tuples): 1 Pos + 63 Hard Negs → Ranh giới phân loại cực hẹp và sắc nét, tối ưu hóa khả năng phân biệt ngữ nghĩa tinh vi.

2.3 Khử nhiễu (Denoising)

Đây là phần giải thích cho cái tên "Denoised Supervision".

💡 Vấn đề của dữ liệu thô: Trong các tập dữ liệu lớn như MS MARCO, có rất nhiều tài liệu thực tế là đúng (Relevant) nhưng lại không được dán nhãn (Unlabeled). Trong huấn luyện truyền thống, nếu mô hình tìm thấy các tài liệu này, nó sẽ bị phạt (vì bị coi là False Negative). Đây chính là noise.

  • Cách v2 giải quyết: Nhờ có sự dẫn dắt của Cross-Encoder, nếu một tài liệu chưa dán nhãn nhưng được mô hình giáo viên chấm điểm cao, ColBERTv2 sẽ coi đó là một tín hiệu tích cực thay vì bị phạt.
  • Lợi ích: Quy trình này giúp mô hình ít bị ảnh hưởng bởi các nhãn dán thiếu sót trong tập dữ liệu, từ đó học được bản chất ngữ nghĩa thực sự của các token.

3. Cơ chế Nén thặng dư (Residual Compression)

Đây là cải tiến quan trọng nhất giúp giảm dung lượng Index từ 6 - 10 lần mà không đánh đổi độ chính xác.

3.1 Phân cụm dựa trên Tâm điểm (Centroid-based Clustering)

ColBERTv2 khai thác thực tế là các vector token luôn tập trung quanh các vùng ngữ nghĩa ổn định.

  • Centroids: Hệ thống xác định khoảng 2182^{18} (tương đương 262,144) tâm cụm trong không gian vector.
  • Phân vùng: Mỗi vector vv được gán cho một Centroid gần nhất CtC_t. Tại đây, CtC_t đóng vai trò là bộ khung mang ý nghĩa chung của cụm.

3.2 Biểu diễn phần dư (Residual Representation)

Thay vì lưu 128 số thực (float) cho mỗi vector v, v2 chỉ lưu:

  1. ID của Centroid: Mã số của tâm cụm gần nhất.
  2. Vector phần dư (r): r=vCtr = v - C_t. Đây là phần chênh lệch (khoảng cách và hướng) để tinh chỉnh vị trí của vector gốc từ tâm cụm.

3.3 Lượng tử hóa vô hướng (Scalar Quantization)

Phần dư rr thường có phân phối chuẩn và đối xứng quanh 0. V2 tận dụng điều này để nén rr xuống mức bit-level:

  • 1-bit Quantization: Chỉ lưu dấu (0 cho số âm, 1 cho số dương).
  • 2-bit Quantization: Chia dải giá trị của rr thành 4 khoảng dựa trên độ lệch chuẩn.
  • Kết quả: Mỗi từ từ 256 bytes (v1) giảm xuống chỉ còn 20 - 36 bytes (v2). Với tập MS MARCO, dung lượng RAM cần thiết giảm từ 154 GiB xuống 25 GiB.
  • Cấu trúc: Phần dư rr bảo toàn đầy đủ mm chiều của không gian vector. Kỹ thuật lượng tử hóa được áp dụng độc lập trên mỗi chiều.
  • Độ mịn dữ liệu: Việc sử dụng 2-bit (4 trạng thái) cho phép mô hình biểu diễn không chỉ hướng (âm/dương) mà cả cường độ (độ lệch mạnh/yếu) của vector token so với tâm cụm.
  • Hiệu ứng triệt tiêu sai số: Nhờ số lượng chiều lớn (thường m = 128), các sai số lượng tử hóa nhỏ ở từng chiều sẽ tự động triệt tiêu lẫn nhau trong phép tính tổng MaxSim (Score=MaxSimScore=∑MaxSim).

→ Điều này giải thích tại sao ColBERTv2 có thể nén dữ liệu cực mạnh mà vẫn duy trì được độ chính xác tương đương các mô hình Cross-Encoder không nén.

4. Quy trình Triển khai Indexing (Offline Indexing Pipeline)

Quy trình Index của v2 được thiết kế để tối ưu hóa bộ nhớ và tận dụng tối đa phần cứng thông qua 3 giai đoạn:

Bước 1: Centroid Selection (Chọn tâm cụm)

Để xây dựng bộ khung nén, ColBERTv2 cần xác định các Centroids CtC_t đại diện cho toàn bộ không gian ngữ nghĩa. Tuy nhiên, việc xử lý hàng tỷ vector token cùng lúc là bất khả thi về mặt tài nguyên RAM. Quy trình giải quyết gồm 2 bước tối ưu:

A. Lấy mẫu đại diện (Sampling)

Hệ thống không tính toán Centroid trên toàn bộ hàng tỷ vector (vì quá tốn RAM). Thay vào đó:

  • Nó lấy một mẫu (sample) đại diện từ kho dữ liệu. Đây là một quy tắc tối ưu được mượn từ thư viện FAISS (Facebook AI Similarity Search) mà ColBERTv2 áp dụng.
  • Công thức: Nếu tổng số vector trong kho dữ liệu là NN, thì số lượng mẫu cần lấy SS sẽ được tính theo công thức:

SHa˘ˋng soˆˊ×NS \approx \text{Hằng số} \times \sqrt{N}

💡 Tại sao lại là căn bậc hai?

  • Số lượng tâm cụm (Centroids) k thường cũng được thiết lập tỉ lệ với N\sqrt{N} (ví dụ: k=16×Nk = 16 \times \sqrt{N} ).
  • Để thuật toán K-means hoạt động ổn định và hội tụ tốt, mỗi tâm cụm cần có khoảng 256 đến 1024 điểm dữ liệu để huấn luyện.
  • Do đó, số mẫu S sẽ tỉ lệ với số tâm cụm kk, mà k lại tỉ lệ với N\sqrt{N}. Suy ra SS tỉ lệ với N\sqrt{N}.

B. Xác định số lượng tâm cụm (kk)

  • Quy tắc thiết lập: Số lượng tâm cụm kk được tính dựa trên quy mô của kho dữ liệu theo công thức: k16×N.k \approx 16 \times \sqrt{N}.
  • Tối ưu hóa FAISS: Sau khi có con số ước tính, hệ thống sẽ làm tròn lên lũy thừa của 2 gần nhất để tối ưu hóa việc tính toán trên GPU/CPU.

Ví dụ thực tế

  • Với tập dữ liệu MS MARCO (khoảng 226 triệu vector token), công thức:  k16×226,000,000k \approx 16 \times \sqrt{226,000,000} cho ra kết quả khoảng 240,528.
  • Lũy thừa của 2 gần nhất và lớn hơn con số này chính là 2182^{18}.
  • Với các kho dữ liệu lớn hơn hoặc nhỏ hơn, kk sẽ thay đổi tương ứng (2172^{17}, 2192^{19},…).

Bước 2: Passage Encoding & Compression

Quét qua toàn bộ tài liệu theo batch:

  1. BERT Encoding: Tạo ra các vector token 128 chiều (sau lớp Linear).
  2. Centroid Assignment: Với mỗi vector, tìm Centroid gần nhất trong bộ mã 2182^{18} tâm cụm.
  3. Residual Calculation: Tính toán r=vCtr = v - C_t và thực hiện lượng tử hóa (1-bit hoặc 2-bit).
  4. Storage: Lưu ID tâm cụm và phần dư đã nén xuống đĩa theo từng khối tài liệu.

Bước 3: Index Inversion (Lập danh sách đảo ngược)

Để hỗ trợ tìm kiếm thần tốc (End-to-End Retrieval):

  • Hệ thống gom tất cả các Embedding ID có chung một Centroid ID vào một danh sách gọi là Inverted List.
  • Khi có một Query, thay vì quét toàn bộ Index, ColBERTv2 thực hiện qua 2 bước:
    1. Candidate Generation (Lọc ứng viên):
      • Với mỗi token trong queryquery (qiq_i), hệ thống tìm nn tâm cụm (Centroids) gần nó nhất (thường 1, 2 hoặc 4).
      • Hệ thống chỉ truy cập vào các Inverted Lists của các Centroids này.
      • Hiệu quả: Việc này loại bỏ ngay lập tức 99.9% các vector không liên quan trong kho dữ liệu.
    2. Approximate MaxSim & Rerank:
      • Hệ thống giải nén các phần dư trong danh sách ứng viên, phục hồi lại vector xấp xỉ  v~=C+r^\tilde{v} = C + \hat{r}.
      • Tính điểm MaxSim xấp xỉ: tính tích vô hướng giữa queryquery vector (qiq_i) với tất cả các vector v~\tilde{v} của tài liệu đó. Điểm số này được gọi là một "Cận dưới" (Lower-bound) của điểm thực tế.
      • Từ đó lấy ra Top-K tài liệu ‘ứng viên’. Tiếp theo thực hiện tính MaxSim để trả ra kết quả tốt nhất cho người dùng.

Kết luận Indexing

Sự kết hợp giữa Inverted List và Residual Compression giúp ColBERTv2 đạt được hiệu quả tối ưu với Information Retrieval:

  1. Dung lượng thấp: Cạnh tranh trực tiếp với các mô hình Single-vector (Single-embedding).
  2. Tốc độ cao: Nhờ Inverted List loại bỏ 99.9% dữ liệu thừa, việc tra cứu Multi-vector không còn là gánh nặng.
  3. Độ chính xác không đổi: Việc nén dựa trên "khoảng cách tới tâm cụm" (Residual) thông minh hơn so với nén vector thô, giúp bảo toàn các sắc thái ngữ nghĩa của Late Interaction

5. Đánh giá Khả năng Tổng quát hóa: Benchmark LoTTE

LoTTE (viết tắt của Long-Tail Topic-stratified Evaluation for IR) là một bộ benchmark mới được giới thiệu cùng với ColBERTv2 nhằm đánh giá khả năng truy hồi thông tin trong các kịch bản ngoài miền dữ liệu huấn luyện (out-of-domain), đặc biệt tập trung vào các chủ đề ngách (long-tail topics) và các câu truy vấn thực tế của người dùng

5.1 Mục tiêu và Ý nghĩa

Khác với các bộ dữ liệu phổ biến như Wikipedia (thường tập trung vào các thực thể nổi tiếng), LoTTE nhắm vào các chủ đề ít phổ biến hơn mà các hệ thống IR thường gặp khó khăn,. Nó bổ sung cho benchmark BEIR bằng cách tập trung vào các câu hỏi tìm kiếm tự nhiên với ý định thực tế thay vì chỉ là các tác vụ tương đồng ngữ nghĩa,.

5.2 Cấu trúc và Quy mô dữ liệu

  • Nguồn dữ liệu: Các đoạn văn bản (passages) được thu thập từ các bài đăng trả lời trên các cộng đồng StackExchange,.
  • Phân loại chủ đề: Dữ liệu được chia thành 12 bộ thử nghiệm thuộc 5 lĩnh vực chính: Viết lách (Writing), Giải trí (Recreation), Khoa học (Science), Công nghệ (Technology) và Đời sống (Lifestyle),.
  • Số lượng: Mỗi bộ thử nghiệm chứa từ 500 đến 2.000 câu truy vấn và kho dữ liệu từ 100.000 đến 2 triệu đoạn văn bản.
  • Chế độ "Pooled": Bên cạnh việc đánh giá theo từng chủ đề, LoTTE còn có thiết lập "pooled" — gộp tất cả các chủ đề lại thành một kho dữ liệu lớn và đa dạng hơn để kiểm tra khả năng chuyển đổi miền của mô hình,.

5.3 Hai loại câu truy vấn chính

☝ Ví dụ về các truy vấn và đoạn trích ngắn của các câu trả lời từ LoTTE. Hai ví dụ đầu tiên thể hiện các truy vấn Search, trong khi hai ví dụ cuối là các truy vấn Forum. Các đoạn trích được rút ngắn để dễ trình bày.

LoTTE phân biệt rõ rệt giữa hai kiểu tìm kiếm:

  • Search Queries (Truy vấn tìm kiếm): Được lấy từ dữ liệu GooAQ (các câu hỏi tự động hoàn thành trên Google). Những câu hỏi này thường ngắn gọn, mang tính tìm kiếm kiến thức và phản ánh hành vi tìm kiếm tự nhiên của người dùng,.
  • Forum Queries (Truy vấn diễn đàn): Được trích xuất từ tiêu đề các bài đăng trên StackExchange. Những câu hỏi này thường mang tính mở hơn và đa dạng hơn so với các truy vấn tìm kiếm thông thường,.

5.4 Phương pháp đánh giá

  • Chỉ số: Sử dụng Success@5 (S@5). Một hệ thống sẽ ghi điểm nếu tìm thấy câu trả lời chính xác (được chấp nhận hoặc có điểm bình chọn ≥ 1) nằm trong 5 kết quả đầu tiên.
  • Ý nghĩa: Chỉ số này phản ánh khả năng của mô hình trong việc đưa ra những lựa chọn chất lượng nhất trong một không gian kết quả rất hẹp.

5.5 So sánh hiệu năng thực nghiệm

a. Khả năng Tổng quát hóa (Zero-shot) vượt trội

  • Insight: ColBERTv2 thiết lập kỷ lục SOTA mới trên tất cả 28 tập dữ liệu thử nghiệm ngoài miền huấn luyện (Wikipedia, LoTTE).
  • Ý nghĩa: Dù chỉ huấn luyện trên dữ liệu phổ thông (MS MARCO), v2 vẫn áp đảo các đối thủ ở các chủ đề Long-tail như Khoa học, Công nghệ. Điều này chứng minh cơ chế Late Interaction bền bỉ hơn hẳn các mô hình Single-vector khi đối mặt với thuật ngữ chuyên sâu và dữ liệu lạ.

b. Nghịch lý: Nén mạnh hơn nhưng Chính xác hơn

  • Insight: Mặc dù bị nén thặng dư (Residual Compression) tới 10 lần so với v1, ColBERTv2 vẫn đạt điểm số cao hơn phiên bản tiền nhiệm ở mọi hạng mục (ví dụ Science Search: 53.6 vs 56.7).
  • Ý nghĩa: Chiến lược Denoised Supervision đã tạo ra các vector token chất lượng cao đến mức dù bị lượng tử hóa xuống 1-bit/2-bit, chúng vẫn mang nhiều thông tin ngữ nghĩa hơn các vector thô của v1.

c. Ưu thế tuyệt đối trong các truy vấn phức tạp (Forum Queries)

  • Insight: Khoảng cách dẫn trước của ColBERTv2 so với các đối thủ (SPLADEv2, RocketQAv2) nới rộng nhất ở phần Forum Queries (truy vấn từ diễn đàn).
  • Ý nghĩa: Các câu hỏi trên diễn đàn thường dài, mang tính diễn đạt cá nhân và cấu trúc phức tạp. Việc khớp token-to-token giúp ColBERTv2 chính xác trong các câu hỏi dài dòng, điều mà các mô hình Single-vector thường gặp khó khăn.

6. Những hạn chế và Thách thức

Mặc dù sở hữu hiệu năng ấn tượng, ColBERTv2 vẫn tồn tại những rào cản kỹ thuật cần lưu ý:

  1. Chi phí huấn luyện (Training Overhead): Quy trình chưng cất tri thức (Distillation) từ Cross-Encoder và khai thác mẫu âm khó (Hard-negative mining) đòi hỏi tài nguyên tính toán và thời gian huấn luyện lớn hơn nhiều so với các mô hình Bi-Encoder đơn giản.
  2. Độ phức tạp hệ thống: Việc quản lý centroids, inverted lists và residual compression yêu cầu hạ tầng phần mềm phức tạp hơn so với các hệ thống tìm kiếm vector đơn lẻ (Vector DB truyền thống).
  3. Rào cản ngôn ngữ: Hầu hết các thực nghiệm và bộ tham số tối ưu hiện tại đều dựa trên tiếng Anh (MS MARCO). Việc mở rộng sang đa ngôn ngữ (Multilingual) yêu cầu dữ liệu huấn luyện tương ứng và cấu hình lại bộ Centroids để phù hợp với đặc thù của từng ngôn ngữ.
  4. Sự phụ thuộc vào phần cứng: Mặc dù đã tối ưu hóa, phép toán MaxSim vẫn đạt hiệu suất cao nhất trên GPU. Việc triển khai hoàn toàn trên CPU ở quy mô hàng tỷ tài liệu vẫn là một thách thức về mặt độ trễ nếu không có các kỹ thuật tối ưu hóa mã nguồn sâu hơn.

7. Kết luận

ColBERTv2 không chỉ là một bản cập nhật, mà là một lời giải toàn diện cho bài toán cân bằng giữa Độ chính xác (Accuracy)Tốc độ (Latency) và Dung lượng (Footprint).

  • Đột phá công nghệ: Bằng cách kết hợp chiến lược Denoised Supervision và Residual Compression, v2 đã đưa kiến trúc Late Interaction từ một mô hình lý thuyết nặng nề thành một giải pháp thực chiến mạnh mẽ.
  • Giá trị hệ thống: ColBERTv2 thiết lập tiêu chuẩn mới về khả năng tổng quát hóa (Zero-shot) trên các chủ đề Long-tail. Trong kỷ nguyên của RAG, đây là "bộ máy truy xuất" lý tưởng giúp giảm thiểu hallucination nhờ khả năng cung cấp bằng chứng chính xác tới từng token.
  • Hiệu quả kinh tế: Việc cắt giảm 10 lần dung lượng Index giúp các doanh nghiệp triển khai hệ thống tìm kiếm Neural IR quy mô hàng tỷ tài liệu với chi phí phần cứng tối thiểu, tiệm cận các mô hình Single-vector nhưng với độ chính xác vượt trội của Cross-Encoder.

II. Tổng kết & Sample với RAGatouille

1. So sánh: ColBERT v1 vs. ColBERT v2

Tiêu chí ColBERT v1 (Nền tảng) ColBERT v2 (Tối ưu hóa)
Kiến trúc Encoder BERT-base + Linear Layer (Nén xuống mm chiều) BERT-base + Linear Layer (Thừa hưởng từ v1)
Chiến lược Huấn luyện Pairwise Softmax Cross-entropy (dựa trên các cặp Triple d+d^+/dd^- đơn giản). Denoised Supervision: Distillation từ Cross-Encoder mạnh + Hard-negative mining.
Cấu trúc Indexing IVF đơn giản: Lưu trữ vector thô, tra cứu dựa trên tài liệu. MV-IVF + Centroid Pruning: Lập chỉ mục cấp độ Token với 2182^{18} tâm cụm.
Cơ chế Nén (Compression) Không nén: Lưu trữ giá trị thực (float32/float16). Residual Compression: Chỉ lưu ID tâm cụm + Phần dư (Residual) nén 1-bit/2-bit.
Dung lượng lưu trữ Rất cao: ~512 Bytes/token (với float32, 128d). Cực thấp: ~20 - 36 Bytes/token (Giảm 6 - 10 lần).
Độ trễ (Latency) Cao ở quy mô lớn: Nghẽn băng thông khi truyền tải tensor vector thô lên GPU. Thấp (Real-time): Dữ liệu nén nhỏ gọn giúp tăng tốc độ Gathering & Transfer lên GPU.
Khả năng tổng quát hóa Tốt trên tập dữ liệu huấn luyện (MS MARCO). SOTA (State-of-the-art): Đứng đầu 22/28 benchmark Zero-shot (BEIR, LoTTE).
Quy mô triển khai Phù hợp quy mô triệu tài liệu (Million-scale). Tối ưu quy mô hàng tỷ tài liệu (Billion-scale).

Sự chuyển dịch từ ColBERT v1 sang v2 không chỉ là một bản cập nhật phần mềm, mà là một cuộc cách mạng về tính thực dụng trong kiến trúc Neural IR:

  • ColBERT v1: Xác lập triết lý Late Interaction và phép toán MaxSim. Nó chứng minh rằng việc giữ lại đặc trưng ở cấp độ token (Multi-vector) sẽ mang lại độ chính xác vượt trội so với các mô hình nén vào một vector đơn (Single-vector). Tuy nhiên, rào cản lớn nhất là Storage Footprint quá lớn.
  • ColBERT v2: Giải quyết triệt để bài toán kinh tế. Thông qua Residual Compression (Nén thặng dư) và Denoised Supervision, v2 giảm dung lượng Index xuống 6-10 lần mà không làm mất đi độ chính xác, thậm chí còn đạt SOTA trên các benchmark ngoài miền dữ liệu (Zero-shot) như LoTTE.

2. Triển khai với RAGatouille (Source)

Trong thực tế triển khai doanh nghiệp, việc tự viết lại toàn bộ các bước chia cụm (Centroid), nén Residual hay quản lý Inverted List là cực kỳ phức tạp. RAGatouille ra đời như một "wrapper" chuẩn công nghiệp, giúp đơn giản hóa toàn bộ các công trình nghiên cứu của Stanford thành các hàm Python dễ sử dụng.

2.1 Chiến lược Inference tối ưu cho RAG

Tùy vào quy mô dữ liệu của doanh nghiệp, chúng ta có hai chiến lược triển khai chính với RAGatouille:

  • Chiến lược 1: Re-ranking Stage 2 (Khuyên dùng cho quy mô lớn)
    • Cơ chế: Kết hợp BM25 (Elasticsearch) lấy Top 100 → Dùng hàm .rerank() của RAGatouille để sắp xếp lại.
    • Ưu điểm: Tận dụng hạ tầng CPU sẵn có cho lọc thô, chỉ dùng GPU cho bước tính toán kỹ cuối cùng. Đây là cách tiếp cận cân bằng nhất giữa chi phí và hiệu năng.
from ragatouille import RAGPretrainedModel

RAG = RAGPretrainedModel.from_pretrained("colbert-ir/colbertv2.0")

query = "Cơ chế nén của ColBERT v2"
candidates = [
    "ColBERT v2 sử dụng Residual Compression để giảm dung lượng.",
    "Mô hình BERT truyền thống không có Late Interaction.",
    "RAG giúp giảm thiểu hiện tượng ảo giác thông tin."
]

# Thực hiện Re-rank
results = RAG.rerank(query=query, documents=candidates, k=1)

# --- GIẢI THÍCH KẾT QUẢ TRẢ RA (OUTPUT) ---
# 'results' là một danh sách các Dictionary. Mỗi Dictionary chứa:
# [
#   {
#     "content": "ColBERT v2 sử dụng Residual Compression để giảm dung lượng.", 
#     "score": 25.85, 
#     "rank": 1,
#     "result_index": 0
#   }
# ]

for res in results:
    print(f"--- PHÂN TÍCH RANK {res['rank']} ---")
    print(f"Nội dung: {res['content']}") # Văn bản gốc được khớp
    
    # SCORE: Đây là tổng điểm MaxSim (đơn vị: tích vô hướng/cosine).
    # Điểm càng cao (>15-20) nghĩa là các token khớp ngữ nghĩa cực mạnh.
    print(f"Điểm MaxSim: {res['score']}") 
    
    # RESULT_INDEX: Vị trí gốc của tài liệu trong danh sách 'candidates' truyền vào.
    # Giúp map lại với Database gốc của doanh nghiệp.
    print(f"Vị trí gốc: {res['result_index']}")
  • Chiến lược 2: End-to-End Retrieval (Khuyên dùng cho quy mô vừa và nhỏ)
    • Cơ chế: Dùng hàm .index() để tạo chỉ mục trực tiếp và .search() để truy xuất.
    • Ưu điểm: Loại bỏ sự phụ thuộc vào các Vector DB bên thứ ba, cung cấp trải nghiệm tìm kiếm "All-in-one" cực kỳ mạnh mẽ.
from ragatouille import RAGPretrainedModel

# 1. KHỞI TẠO MODEL (Load Checkpoint ColBERT v2)
RAG = RAGPretrainedModel.from_pretrained("colbert-ir/colbertv2.0")

# --- BƯỚC 1: OFFLINE INDEXING (EMBEDDING & LẬP CHỈ MỤC) ---
# Đây là giai đoạn "nạp kiến thức" vào hệ thống.
my_docs = [
    "ColBERT v2 sử dụng cơ chế nén Residual Compression để giảm dung lượng Index.",
    "Hệ thống RAG giúp giảm ảo giác (hallucination) bằng cách cung cấp bằng chứng thực tế.",
    "RAGatouille là thư viện Python giúp triển khai ColBERT một cách đơn giản nhất."
]

# Thực hiện Indexing: Mã hóa từng token, phân cụm (Centroid) và nén (Residual)
RAG.index(
    collection=my_docs, 
    index_name="my_enterprise_index", 
    max_document_length=180
)

# --- BƯỚC 2: ONLINE SEARCH (TRUY XUẤT TỪ ĐẦU ĐẾN CUỐI) ---
# Hệ thống tự tìm trong Index đã tạo ở bước 1 mà không cần bộ lọc nào khác.
query = "Cách ColBERT v2 tiết kiệm bộ nhớ?"
results = RAG.search(query=query, k=1)

# --- GIẢI THÍCH KẾT QUẢ TRẢ RA (OUTPUT ANNOTATION) ---
# 'results' trả về một danh sách các Dictionary (mỗi Dic là một đoạn văn khớp nhất).
# Ví dụ kết quả thực tế của results[0]:
# {
#    'content': 'ColBERT v2 sử dụng cơ chế nén Residual Compression để giảm dung lượng Index.',
#    'score': 24.15625,
#    'rank': 1,
#    'document_id': 'doc_0',
#    'passage_id': 0,
#    'document_metadata': {}
# }

for res in results:
    print(f"--- KẾT QUẢ SEARCH CHI TIẾT ---")
    
    # 1. CONTENT: Nội dung đoạn văn bản thô được tìm thấy.
    # Đây là kiến thức sẽ đưa vào Prompt cho LLM trả lời.
    print(f"Nội dung: {res['content']}")
    
    # 2. SCORE (Điểm MaxSim): Tổng độ tương đồng giữa các token Query và Document.
    # - Lưu ý: Score này không giới hạn 0-1. 
    # - Score > 15 thường là kết quả rất chất lượng.
    print(f"Điểm MaxSim: {res['score']:.2f}")
    
    # 3. RANK: Thứ tự ưu tiên của kết quả (1 là tốt nhất).
    # RAGatouille đã tự động sắp xếp kết quả theo điểm số giảm dần cho bạn.
    print(f"Xếp hạng: {res['rank']}")
    
    # 4. DOCUMENT_ID & PASSAGE_ID: 
    # - document_id: ID của tài liệu gốc bạn nạp vào lúc Index.
    # - passage_id: ID của đoạn văn nhỏ (chunk) sau khi hệ thống tự chia.
    # Dùng các ID này để truy vấn ngược lại database gốc nếu cần lấy thêm thông tin.
    print(f"ID định danh: {res['document_id']} (Đoạn số: {res['passage_id']})")
    
    # 5. DOCUMENT_METADATA: 
    # Các thông tin đi kèm (như Tác giả, Ngày tạo, URL nguồn...) 
    # Nếu lúc Index có truyền thêm metadata, nó sẽ xuất hiện ở đây.
    print(f"Dữ liệu kèm theo: {res['document_metadata']}")

All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.