- Skald được phát triển với mục tiêu trở thành một hệ thống RAG có thể tự lưu trữ hoàn toàn, không gửi dữ liệu cho bên thứ ba
- Các thành phần của RAG được chia thành cơ sở dữ liệu vector, mô hình embedding, LLM, reranker, trình phân tích tài liệu, và bài viết đưa ra các lựa chọn thay thế mã nguồn mở cho từng thành phần
- Stack cục bộ mặc định của Skald gồm Postgres+pgvector, Sentence Transformers, Docling, và LLM do người dùng tùy chỉnh
- Theo kết quả benchmark, mô hình chạy trên đám mây (Voyage+Claude) đạt trung bình 9.45 điểm, còn GPT-OSS 20B chạy hoàn toàn cục bộ đạt 7.10~8.63 điểm
- Cách tiếp cận này cho thấy có thể xây dựng RAG hiệu năng cao mà vẫn giữ được quyền riêng tư dữ liệu
Các thành phần của RAG và các lựa chọn thay thế mã nguồn mở
- RAG cơ bản gồm cơ sở dữ liệu vector, mô hình embedding, LLM, và có thể bổ sung thêm reranker cùng trình phân tích tài liệu
- Mỗi thành phần đều có thể được thay bằng giải pháp cục bộ thay cho SaaS
- Các lựa chọn thay thế được nêu trong bảng ví dụ
- Vector DB: Pinecone, Weaviate Cloud → Qdrant, Weaviate, Postgres+pgvector
- Embeddings: OpenAI, Cohere → Sentence Transformers, BGE, E5
- LLM: GPT, Claude → Llama, Mistral, GPT-OSS
- Reranker: Cohere → BGE Reranker, Sentence Transformers Cross-Encoder
- Document Parsing: Reducto → Docling
- Skald hướng đến một stack mã nguồn mở hoàn chỉnh, với từng thành phần đều chạy cục bộ
Cấu hình stack cục bộ của Skald
- Vector DB: dùng Postgres + pgvector
- Dễ tích hợp vào hạ tầng sẵn có và có thể xử lý tới hàng trăm nghìn tài liệu
- Vector Embeddings: mặc định là Sentence Transformers (all-MiniLM-L6-v2)
- Chỉ hỗ trợ tiếng Anh, cân bằng giữa tốc độ và hiệu quả truy xuất
- Mô hình bge-m3 (hỗ trợ đa ngôn ngữ) cũng đã được thử nghiệm
- LLM: không đi kèm sẵn, người dùng tự triển khai
- Trong thử nghiệm, GPT-OSS 20B được chạy trên EC2
- Reranker: mặc định là Sentence Transformers Cross-Encoder, cũng có thể dùng các mô hình đa ngôn ngữ như bge-reranker-v2-m3
- Document Parsing: dùng Docling, chạy qua docling-serve
Kết quả hiệu năng và triển khai
- Mất 8 phút để triển khai một instance production của Skald bao gồm toàn bộ stack
- Gồm Postgres, dịch vụ embedding và reranking, cùng Docling
- LLM được chạy riêng (dùng llama.cpp)
- Bộ dữ liệu thử nghiệm gồm nội dung website PostHog (khoảng 2000 tài liệu) và bộ câu hỏi-đáp tự tạo
- Thiết lập thí nghiệm
- Vector search topK=100, Reranking topK=50, Query rewriting=Off
- Tiêu chí đánh giá tập trung vào độ chính xác
So sánh kết quả benchmark
- Voyage + Claude (cấu hình đám mây)
- Điểm trung bình 9.45, mọi câu trả lời đều chính xác
- Voyage + GPT-OSS 20B (cục bộ một phần)
- Điểm trung bình 9.18, phần lớn chính xác nhưng thiếu một số thông tin
- Hoàn toàn cục bộ + GPT-OSS 20B
- Mô hình tiếng Anh cơ bản (all-MiniLM-L6-v2 + ms-marco-MiniLM-L6-v2) : trung bình 7.10
- Chính xác với truy vấn tiếng Anh, nhưng yếu ở truy vấn đa ngôn ngữ, truy vấn mơ hồ và tổng hợp từ nhiều tài liệu
- Mô hình đa ngôn ngữ (bge-m3 + mmarco-mMiniLMv2-L12-H384-v1) : trung bình 8.63
- Xử lý thành công truy vấn tiếng Bồ Đào Nha, nhưng vẫn bỏ sót một phần khi tổng hợp nhiều tài liệu
- Hạn chế chính là xử lý tổng hợp thông tin nằm rải rác trên nhiều tài liệu
- Mô hình đám mây bù đắp điều này bằng hiệu năng cao hơn, còn trong môi trường cục bộ thì cần thêm các kỹ thuật bổ sung
Kế hoạch sắp tới
- Skald có kế hoạch cải thiện hiệu năng RAG cục bộ và công khai benchmark của các mô hình mã nguồn mở
- Mục tiêu là cung cấp giải pháp cho các doanh nghiệp phải vận hành công cụ AI trong môi trường air-gapped
- Người muốn tham gia có thể cộng tác qua GitHub(skaldlabs/skald) hoặc cộng đồng Slack
7 bình luận
Ai nói rằng RAG nhất thiết phải cần vector DB vậy chứ…
Dù là vector DB hay gì đi nữa thì thật ra có lẽ chỉ cần triển khai phần tìm kiếm là được mà...
Gemini:
Vâng, việc sử dụng cơ sở dữ liệu vector (Vector Database) trong RAG (Retrieval-Augmented Generation) đã có nền tảng khái niệm từ khi bài báo liên quan đầu tiên được công bố vào năm 2020.
Về cơ bản, RAG là cách kết hợp giữa truy xuất (Retrieval) và sinh (Generation), trong đó ở giai đoạn truy xuất, embedding vector cùng với cơ sở dữ liệu vector dùng để lưu trữ và tìm kiếm chúng một cách hiệu quả đóng vai trò thiết yếu.
💡 Điểm khởi đầu của RAG và vector DB
Ý tưởng rằng RAG cần vector DB bắt nguồn từ các bài báo và khái niệm quan trọng sau.
Lý do nền tảng khiến cơ sở dữ liệu vector trở thành thành phần thiết yếu của RAG là như sau.
Tóm tắt: Vì sao cần vector DB
Để cho phép LLM tiếp cận tri thức mới nhất hoặc tri thức đặc thù theo miền mà mô hình chưa học, cần phải tìm thông tin dựa trên độ tương đồng ngữ nghĩa chứ không chỉ là đối sánh từ khóa đơn thuần (tìm kiếm truyền thống). Vector DB là công nghệ cốt lõi được tích hợp một cách tự nhiên vào framework RAG để thực hiện hiệu quả việc tìm kiếm dựa trên độ tương đồng ngữ nghĩa này.
Thực ra thứ cần cho RAG là chức năng tìm kiếm, còn việc tạo embedding bằng dense vector, đẩy vào vectorDB rồi tìm kiếm theo độ tương đồng cosine chỉ là một trong nhiều cách để triển khai công cụ tìm kiếm mà thôi... Không phải là không có lý do để dùng vectorDB, nhưng nếu hỏi có thực sự bắt buộc không thì tôi cũng hơi nghiêng đầu thắc mắc, vì đã có rất nhiều thuật toán công cụ tìm kiếm được dùng rất tốt từ lâu rồi.
Vì rẻ và hầu hết các LLM production đều dùng mà.
Thật ra web server cũng vậy thôi, nếu thêm các chức năng hạ tầng thì mọi thứ đều có thể làm hết từ đĩa, nên cũng chẳng cần DBMS đâu nhỉ haha
Đúng là cần một cơ sở dữ liệu cho kiểu tìm kiếm tương đồng/ngữ nghĩa, trong đó khóa là giá trị embedding (vector) của truy vấn người dùng. Vì khóa có dạng vector nên gọi là vector DB cũng đúng.
Ý kiến Hacker News
Khi xây dựng kiểu hệ thống này, tôi muốn khuyên là đừng quá ám ảnh với cơ sở dữ liệu vector hay embedding
Tìm kiếm toàn văn hoặc các công cụ như
grep/rgnhanh và rẻ hơn nhiều, lại không cần phải duy trì chỉ mụcNếu đưa cho một LLM tốt công cụ tìm kiếm, nó có thể tự tạo các truy vấn như “dog OR canine” và lặp lại để cải thiện dần
Hơn nữa, làm vậy cũng không cần phải giải quyết vấn đề chunking
Có thể xem tại Search Sensei
Lần tải đầu sẽ tải về khoảng 50MB trọng số mô hình và onnx runtime, nhưng sau đó hoạt động khá mượt
Ví dụ, BM25 không hiểu rằng “j lo” và “jlo” nghĩa là Jennifer Lopez, nhưng tìm kiếm dựa trên embedding xử lý tốt các lỗi gõ và bí danh như vậy
Tìm kiếm được thực hiện trên 1.000 bài báo giai đoạn 2016~2024
Tuy nhiên, khá tiếc là hiệu năng của riêng BM25 không được công bố
Trong các thử nghiệm nhỏ của tôi, có trường hợp embedding bỏ lỡ cả những trang có chứa nguyên xi từ trong truy vấn — rốt cuộc Ctrl+F lại thắng
Tìm kiếm lexical có precision cao nhưng recall thấp, còn tìm kiếm semantic thì nằm ở phía ngược lại
Tôi cảm thấy cần toán tử “NOT” hơn. Tôi cũng muốn tìm hiểu thêm về RAG
Tôi đã thấy một số công cụ kiểu agent tự động tạo những truy vấn như vậy, nhưng không rõ đó là do prompt dẫn dắt hay là hành vi mặc định
Một trong những lý do hiệu năng kém có thể là do thiếu semantic chunking
Nếu embedding cả tài liệu thì nhiều khái niệm bị trộn lẫn, làm giảm độ chính xác
Cần dùng công cụ như Spacy để chia theo đơn vị ý nghĩa, rồi thêm ngữ cảnh về vị trí của mỗi chunk trong tài liệu trước khi embedding
Cách tiếp cận contextual retrieval của Anthropic đã rất hiệu quả trong các hệ thống RAG
Có thể dùng mô hình GPT OSS 20B để sinh ngữ cảnh
Có lẽ có hiểu nhầm vì chúng tôi thử nghiệm bằng các câu hỏi đòi hỏi phải tổng hợp ngữ cảnh từ nhiều tài liệu
Tôi thắc mắc vì sao lại mặc định cho rằng tìm kiếm semantic vượt trội hơn lexical
Khi so với Tantivy (BM25) vào năm 2023, khác biệt về kết quả là không đáng kể
Dù có tăng recall đôi chút đi nữa, tôi cũng không chắc có đáng để dựng cả một cấu trúc phức tạp như vậy hay không
Trong test của lập trình viên thì recall là 90%, nhưng khi test với người dùng thực tế thì rơi xuống khoảng 30%
Người dùng không biết chính xác thuật ngữ trong tài liệu, nên chỉ tìm kiếm lexical là không đủ
Có thể chồng thêm agent lên, nhưng độ trễ (latency) tăng cao và làm giảm mức hài lòng của người dùng
Trong Wanderfugl, tìm kiếm semantic vẫn tìm ra tốt những đoạn có điểm BM25 thấp
Cuối cùng, có lẽ xếp hạng lai mới là đáp án
Rốt cuộc vẫn là phụ thuộc vào use case
Tôi đang tìm công cụ mã nguồn mở cho phép truy vấn toàn bộ dữ liệu như email, Slack, GDrive, code, wiki... theo cách cục bộ và ngoại tuyến
Tôi muốn tránh tự xây hoặc tùy biến, sẽ tốt hơn nếu có sẵn mặc định hợp lý và gợi ý mô hình tốt
Liên kết GitHub
Về cơ bản nó hỗ trợ CRUD, và nếu bật tìm kiếm vector thì sẽ embedding tài liệu hoặc ghi chú
Nó hỗ trợ Ollama và OpenAI làm nhà cung cấp embedding
Máy chủ MCP cung cấp cả tìm kiếm semantic + BM25 (qdrant fusion) và tạo câu trả lời thông qua MCP sampling
Bản thân máy chủ không sinh câu trả lời, nên có thể tích hợp với bất kỳ client LLM/MCP nào
Mẫu MCP sampling/RAG này rất mạnh, và nhiều khả năng sẽ sớm có các phiên bản mã nguồn mở tổng quát hơn cho những nguồn dữ liệu khác
Công cụ chúng tôi dùng là haiku.rag
Nó cung cấp mã Python thân thiện với lập trình viên và cấu trúc dựa trên pydantic-ai, cùng benchmark và tính năng trích dẫn nâng cao
Nó hỗ trợ agent nghiên cứu chuyên sâu và là một dự án mã nguồn mở thực thụ được duy trì lâu dài
Tôi đang dùng Sentence Transformers (all-MiniLM-L6-v2) làm mô hình embedding mặc định, nhưng nhận ra đây là mô hình chỉ dành cho tiếng Anh nên có thể gây vấn đề khi làm RAG tiếng Đức
Tôi tò mò không biết hiệu năng của các mô hình phi tiếng Anh ra sao
Hãy xem mục RTEB Multilingual hoặc RTEB German trong phần “Retrieval”
Nếu tự host trên CPU thì nên lọc các mô hình dưới 100M tham số
Tuy vậy, tiếng Đức có tương đối nhiều dữ liệu huấn luyện, và cũng có khá nhiều mô hình đa ngôn ngữ
Đặc biệt, đa số các mô hình dựa trên API thương mại đều hỗ trợ đa ngôn ngữ
Có thể tham khảo bài báo liên quan tại liên kết Springer
Vào thời GPT-4 (context 8K), tôi từng viết một script chia cả cuốn sách thành các chunk rồi đưa vào GPT-4 để truy xuất những đoạn liên quan
Khi đó mỗi lần tìm kiếm tốn cỡ 1 USD, nhưng giờ đã rẻ hơn nhiều
Ngay trong bài viết contextual retrieval của Anthropic cũng nói rằng nếu tài liệu đã vừa trong context thì thay vì RAG, cứ đưa thẳng vào sẽ tốt hơn
Tuy nhiên, khi context quá dài thì chất lượng giảm, và chi phí cùng tốc độ cũng thành vấn đề
Giờ thì có thể đưa cả cuốn sách vào context với chi phí chỉ ở mức 1 xu
Phần khó nhất của RAG là phân tích tài liệu
Nếu chỉ xử lý văn bản thì ổn, nhưng khi có bảng, bảng nhiều trang, biểu đồ, mục lục, chú thích cuối trang... thì độ chính xác giảm rất mạnh
Để cải thiện việc này có hướng tiếp cận như mẫu RAPTOR, nơi LLM tóm tắt và đặt câu hỏi về nội dung rồi lưu vào vector DB
Nhưng một pipeline RAG đa dụng hoạt động tốt trong mọi trường hợp vẫn là bài toán khó
Tôi cũng tò mò không biết vector DB xử lý tốt hơn với các nhóm văn bản dài hay dữ liệu dạng bảng
Tôi thấy thú vị với góc nhìn mới là áp dụng tìm kiếm toàn văn vào RAG
Những hiểu biết về vòng lặp công cụ kiểu agent và cách xử lý fuzzy search rất ấn tượng
Tôi tò mò không biết các bộ dữ liệu đánh giá cho hệ thống kiểu này có được chuẩn hóa hay không
Sẽ rất tốt nếu có benchmark gồm tập tài liệu và tập câu hỏi, trong đó tài liệu hoặc chunk cụ thể phải xuất hiện như kết quả liên quan nhất