RAG và CAG
Retrieval-Augmented Generation (RAG) là một phương pháp phổ biến trong lĩnh vực trí tuệ nhân tạo, đặc biệt trong việc tăng cường khả năng của các mô hình ngôn ngữ lớn (LLMs) bằng cách truy xuất thông tin từ các nguồn dữ liệu bên ngoài để tạo ra câu trả lời chính xác và cập nhật hơn. Tuy nhiên, RAG không phải là giải pháp duy nhất và hoàn hảo cho mọi tình huống.
- Độ trễ cao: RAG yêu cầu một bước truy xuất dữ liệu từ các nguồn bên ngoài trước khi tạo ra câu trả lời. Quá trình này có thể làm tăng thời gian phản hồi, đặc biệt trong các ứng dụng yêu cầu phản hồi nhanh như chatbot hoặc trợ lý ảo.
- Độ phức tạp hệ thống: Việc triển khai RAG đòi hỏi xây dựng và duy trì các hệ thống truy xuất, cơ sở dữ liệu vector, và pipeline tích hợp giữa các thành phần. Điều này làm tăng độ phức tạp và chi phí vận hành.
- Phụ thuộc vào chất lượng dữ liệu truy xuất: Nếu hệ thống truy xuất không hiệu quả hoặc dữ liệu không đáng tin cậy, mô hình có thể tạo ra câu trả lời không chính xác hoặc gây hiểu lầm.
- Khó khăn trong việc xử lý dữ liệu lớn: Khi làm việc với các tập dữ liệu lớn hoặc liên tục cập nhật, RAG có thể gặp khó khăn trong việc đảm bảo tính nhất quán và độ chính xác của thông tin truy xuất.
Để khắc phục những hạn chế của RAG, Cache-Augmented Generation (CAG) là một phương pháp thay thế hiệu quả. CAG hoạt động bằng cách tiền xử lý và lưu trữ thông tin cần thiết trong bộ nhớ đệm, cho phép mô hình tái sử dụng thông tin này khi cần thiết mà không phải truy xuất lại từ nguồn bên ngoài.
🧠 Ví dụ: Trợ lý ảo trong công ty
Hãy tưởng tượng bạn đang triển khai một trợ lý ảo cho nhân viên trong công ty, với mục tiêu trả lời các câu hỏi liên quan đến chính sách nội bộ như nghỉ phép, bảo hiểm, và quy trình làm việc.
Với RAG, mỗi khi nhân viên đặt câu hỏi, hệ thống phải tìm kiếm thông tin từ các tài liệu hoặc cơ sở dữ liệu bên ngoài. Quá trình này có thể gây ra độ trễ và đôi khi dẫn đến việc truy xuất thông tin không chính xác nếu hệ thống tìm kiếm không hoạt động hiệu quả.
Trong khi đó, với CAG, trước khi triển khai, bạn tiền xử lý và lưu trữ toàn bộ thông tin cần thiết (như chính sách công ty) vào bộ nhớ đệm của mô hình. Khi nhân viên đặt câu hỏi, mô hình sử dụng thông tin đã lưu trữ để trả lời ngay lập tức, không cần truy xuất dữ liệu bên ngoài.
Lợi ích của CAG trong trường hợp này:
-
Phản hồi nhanh chóng: Giảm độ trễ do không cần truy xuất dữ liệu thời gian thực.
-
Giảm rủi ro truy xuất thông tin sai lệch: Sử dụng thông tin đã được kiểm duyệt và lưu trữ sẵn.
-
Hệ thống đơn giản hơn: Không cần tích hợp các công cụ tìm kiếm phức tạp.
Cơ chế của CAG
Một số hệ thống CAG đã áp dụng cơ chế bộ nhớ đệm Key-Value (KV-cache). Vậy, 🔑 Key và 📦 Value là gì?
→ Nếu bạn đã quen với Transformer, chắc hẳn bạn còn nhớ bộ ba ma trận K (Key), V (Value), và Q (Query) dùng trong cơ chế Self-Attention:
- Q (Query): đại diện cho token hiện tại đang tính toán → nó "đi hỏi" các token khác.
- K (Key): đại diện cho "đặc trưng" của từng token trong ngữ cảnh → cho phép các token khác so sánh với nó.
- V (Value): chứa nội dung thông tin thật sự mà mô hình muốn "truyền" qua attention.
Hình 2: Ba ma trận K, V, Q để tính toán Self-Attention trong Transformer (Nguồn: jalammar.github.io)
Cùng ôn lại về các ma trận này một chút nhé:
- Khi có một chuỗi đầu vào, và cần dự đoán token tiếp theo. Ví dụ:
Thủ đô Việt Nam là Hà …
-
Mô hình tính toán Key (K) và Value (V) lần lượt cho từng token: “Thủ”, “đô”, “Việt”, “Nam”, “là”, “Hà”.
Các ma trận Key và Value này được cố định ngay sau khi tính toán, vì việc tạo ra K và V đơn giản là lấy embedding của từng token và nhân với các ma trận trọng số W_K và W_V tương ứng. Các ma trận trọng số này đã được tối ưu và điều chỉnh sẵn trong quá trình tiền huấn luyện (pretraining), nên khi sinh token mới, mô hình không cần cập nhật lại K và V của các token đã có trước đó.
- Đối với token cuối cùng trong chuỗi ("Hà"), mô hình:
- Tính Query (Q) mới cho "Hà" = Lấy embedding của token hiện tại → nhân với ma trận W_Q đã học trước đó
- Thực hiện dot product (nhân chấm) giữa Q(Hà) và tất cả các Key của các token đã xuất hiện trước đó (bao gồm cả chính "Hà") để tính toán attention scores. - Các attention scores này sẽ được sử dụng để tổng hợp thông tin từ các Value vectors tương ứng, tạo thành Attention Output.
- Sau đó, Attention Output đi qua các lớp tiếp theo (ví dụ: Linear, Projection), sinh ra một vector logits có kích thước bằng số lượng từ trong từ vựng. Mô hình chọn token có logits cao nhất làm token tiếp theo – trong trường hợp này, đó là "Nội".
Bạn có nhận ra:
-
Các Key và Value của các token cũ không cần tính lại, vì nội dung của chúng đã cố định ngay khi token đó được xử lý lần đầu tiên.
-
Chỉ có Query (Q) là cần tính mới mỗi lần sinh token tiếp theo, vì nó phụ thuộc vào token hiện tại đang xét.
Các bước tính toán trên (tính Query mới → Attention với toàn bộ Key trước đó → tổng hợp Value → sinh token mới) sẽ lặp đi lặp lại mỗi lần mô hình sinh ra một token.
Vậy bạn có nhận ra: toàn bộ các Key và Value đã được lưu lại và tái sử dụng liên tục trong quá trình sinh văn bản — đó chính là cơ chế hoạt động của K-V Cache (Key-Value Cache).
Từ cốt lõi cơ chế KV-cache đến CAG:
Trong CAG, việc nạp tri thức vào hệ thống không diễn ra theo cách tìm kiếm tức thời như RAG, mà theo hướng tiền xử lý (preload) toàn bộ kiến thức vào bộ nhớ đệm KV-cache. Cụ thể, khi đưa vào một văn bản chứa kiến thức, chẳng hạn như mô tả sản phẩm, tài liệu nội bộ, hoặc nội dung chuyên ngành. Văn bản này sẽ được token hóa và đưa qua mô hình Transformer đã được huấn luyện trước đó (pretrained). Mỗi token sẽ đi qua mô hình và được gán một cặp vector Key (K) và Value (V) thông qua các ma trận trọng số W_K và W_V mà mô hình đã học.
Sau quá trình forward pass này, tất cả các K và V được sinh ra từ văn bản sẽ được lưu vào bộ nhớ đệm KV-cache. Đây chính là cách mô hình “ghi nhớ” kiến thức nền tảng để sử dụng sau này.
Nói cách khác, bạn chỉ cần chạy forward pass một lần duy nhất để trích xuất và lưu trữ toàn bộ kiến thức dưới dạng toán học (các vectors K/V). Các vector này đại diện cho cách mô hình hiểu và mã hóa ngữ nghĩa của văn bản theo tri thức đã học trong quá trình pretraining.
Khi có một câu hỏi mới, không cần phải nạp lại kiến thức hay tìm kiếm văn bản gốc. Thay vào đó, chỉ cần truyền câu hỏi mới vào mô hình kèm theo KV-cache đã lưu. Mô hình sẽ:
- Tính Query (Q) mới cho từng token trong câu hỏi.
- Tính Attention giữa Q và các Key đã lưu trong cache (đại diện cho kiến thức).
- Sử dụng attention scores để tổng hợp thông tin từ các Value tương ứng.
- Sinh ra câu trả lời hoàn chỉnh dựa trên ngữ cảnh đã có.
Đây chính là cách CAG hoạt động: biến tri thức tĩnh thành một bộ nhớ toán học có thể truy cập nhanh chóng, giúp mô hình trả lời câu hỏi mà không cần truy xuất lại dữ liệu gốc.
[Kiến thức nền]
↓ Tokenize
[Chuỗi tokens]
↓ Forward pass qua mô hình (pretrained Transformer, use_cache=True)
[KV-cache (Key-Value Vectors)]
↓
(Câu hỏi người dùng mới)
↓ Tokenize
[Câu hỏi tokens]
↓ Tính Q mới
↓
Attention (Q câu hỏi với K trong KV-cache)
↓
Tổng hợp Value theo attention scores
↓
Attention Output
↓
Linear Layer → Logits
↓
Chọn token tiếp theo
↓
Sinh câu trả lời
Khi lựa chọn giữa RAG và CAG, điều quan trọng là phải cân nhắc nhu cầu cụ thể: cập nhật tri thức động hay tối ưu phản hồi nhanh từ một kho tri thức tĩnh?
Hiểu rõ bản chất của từng phương pháp sẽ giúp bạn thiết kế hệ thống AI hiệu quả, chính xác và bền vững hơn.
Các bài viết thuộc chuỗi RAG Pattern Series
- Baseline RAG: Tìm Hiểu Về Basic Retriever
- Parent-Child Retriever: Mô Hình Truy Xuất Thông Tin với Ngữ Cảnh Rộng hơn
- Hypothetical Question Retriever (HQR) trong RAG
- Cải tiến Retriever bằng Hypothetical Document Embeddings HyDE