Ứng Dụng Đơn Mô Hình LLM Cho Hệ Thống RAG Toàn Diện

Bài viết này bắt nguồn từ một nhiệm vụ học tập tôi giao cho thực tập sinh vài ngày trước: sử dụng cơ chế suy luận ollama để triển khai một hệ thống RAG nhẹ nhàng trên máy tính cục bộ.

Khi kiểm tra kết quả, cuộc hội thoại sau đã diễn ra: "Anh đã sử dụng mô hình embedding nào?" "Mistral-nemo" "Vậy mô hình embedding thì sao?" "Mistral-nemo" "Anh vừa nói về mô hình LLM, anh đang hỏi về mô hình embedding" "Chính xác là mô hình này" "..."

Tôi hoàn toàn bối rối. Liệu LLM còn có thể tạo vector嵌入? Mặc dù các mô hình chủ đạo hiện nay đều sử dụng kiến trúc transformer decoder, nhưng không thể trực tiếp xuất vector trong quá trình suy luận được. Sau nhiều năm làm việc với agent sử dụng LLM, tôi chưa bao giờ thấy cách làm này.

Mặc dù cảm thấy kỳ lạ, nhưng demo của thực tập sinh đã hoạt động hoàn hảo, các trường kiểm tra khác nhau cũng đều tìm thấy thành công sau khi vector hóa.

Tôi đã tham khảo ChatGPT:

Tại sao ollama có thể gọi phương pháp embedding của mô hình mistral nemo để tính toán vector văn bản?

Kết luận ngắn gọn trước, sau đó giải thích cơ chế:
👉 Ollama có thể gọi embedding của Mistral-Nemo vì:
Ollama tại chỗ tiết lộ một lớp "API trừu tượng năng lực mô hình" thống nhất, trong khi Mistral-Nemo bản thân có các biểu hiện lớp ẩn có thể dùng để嵌入 (embeddings), Ollama chỉ đóng gói khả năng này thành giao diện tiêu chuẩn để bạn gọi.
Dưới đây là giải thích phân tầng về tính khả thi kỹ thuật + tại sao bạn "cảm giác" nó giống như một mô hình embedding chuyên dụng.
...

GPT dùng ảo tưởng để lừa dối tôi không phải là một hai lần, tôi cần xác minh sâu hơn khả năng này của Ollama, sau đó tôi đã phân tích mã nguồn của Ollama: Lưu ý: Điều tra sau đây dựa trên Ollama commit 099a0f18ef29a95d8d6c4fe1343e48e0d9f4cdd7 (2026.2.7)

  1. Điểm vào API — EmbedHandler server\routes.go line 692 Tham số thứ ba của scheduleRunner là danh sách năng lực trống []model.Capability{}. Điều này có nghĩa là giao diện embed không yêu cầu mô hình có khả năng embedding, bất kỳ mô hình nào cũng có thể được lập lịch.
  2. Tạo chuỗi embedding-only runner\llamarunner\runner.go line 759 Tham số cuối cùng được đặt vào trường embeddingOnly của chuỗi: embeddingOnly: params.embedding
  3. Suy luận tiến trước của mô hình — tensor t_embd quan trọng Lấy mô hình Llama làm ví dụ, trong quá trình lan truyền tiến trước ở lớp C++: llama\llama.cpp\src\models\llama.cpp line 139
    cur = inpL;

    cur = build_norm(cur,
            model.output_norm, NULL,
            LLM_NORM_RMS, -1);

    cb(cur, "result_norm", -1);
    res->t_embd = cur;

    // lm_head
    cur = build_lora_mm(model.output, cur);

    cb(cur, "result_output", -1);
    res->t_logits = cur;

  • inpL là trạng thái ẩn sau khi đi qua tất cả các lớp Transformer
  • Đầu tiên thực hiện RMSNorm (build_norm)
  • Kết quả sau RMSNorm được gán cho res->t_embd — đây chính là tensor embedding Sau đó đi qua lm_head (ma trận đầu ra) để có được t_logits — dùng cho sinh văn bản Nói cách khác, embedding chính là trạng thái ẩn sau LayerNorm và trước lm_head.

Như vậy đã được xác minh, Ollama thực sự có thể xuất embedding trực tiếp từ mô hình LLM. Lại mất thời gian học được một kiến thức nhỏ không mấy hữu dụng o.O

Thẻ: RAG LLM ollama embedding models mistral-nemo

Đăng vào ngày 6 tháng 6 lúc 22:06