Triển khai Server AI cục bộ với Ollama và Open WebUI trên Docker: Tự host RAG và Tìm kiếm Web

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

So sánh các phương pháp tiếp cận: Bare-Metal vs. AI cục bộ trên Docker

Chạy các mô hình ngôn ngữ lớn (LLM) trên phần cứng homelab thường quy về một câu hỏi: bạn muốn dành cả ngày cuối tuần để gỡ lỗi các dependency của CUDA, hay thực sự xây dựng các quy trình làm việc với trợ lý AI của mình? Đối với việc tự host inference, có ba kiến trúc chính nổi bật:

  • llama.cpp thuần / Binary CLI: Biên dịch trực tiếp llama.cpp trên máy chủ mang lại thông lượng tối đa và mức tiêu tốn bộ nhớ tối thiểu. Nhưng việc quản lý thủ công các trọng số GGUF, tự viết API shim và ghép nối frontend sẽ biến việc bảo trì cơ bản thành một công việc tẻ nhạt.
  • Production Engine (vLLM / TGI): Các framework hiệu năng cao phát huy tối đa sức mạnh trong môi trường production đa người dùng nhờ PagedAttention và continuous batching. Tuy nhiên, trong môi trường homelab một người dùng, vLLM mặc định cấp phát trước rất nhiều—lên đến 90% VRAM của bạn và thiếu giao diện người dùng tích hợp sẵn.
  • Ollama + Open WebUI trên Docker: Ollama đảm nhận việc lượng tử hóa (quantization), GPU offloading và tải model qua một REST API gọn gàng. Đóng gói cả Ollama và Open WebUI trong các container Docker giúp hệ điều hành máy chủ luôn sạch sẽ. Bạn có ngay tính năng xác thực đa người dùng, lịch sử trò chuyện, RAG tài liệu và tìm kiếm trực tiếp mà không cần cấu hình phức tạp.

Với hầu hết các hệ thống homelab, việc container hóa Ollama cùng với Open WebUI là sự kết hợp hoàn hảo giữa tốc độ xử lý và khả năng bảo trì dễ dàng.

Đánh đổi khi tự vận hành một Private AI Stack

Việc tự host mang lại sự riêng tư tuyệt đối, nhưng giới hạn phần cứng thực tế sẽ quyết định những gì bạn có thể chạy được.

Ưu điểm

  • Bảo mật dữ liệu tuyệt đối: Prompt, tài liệu công ty, mã nguồn độc quyền và lịch sử trò chuyện được lưu trữ hoàn toàn bên trong mạng LAN nội bộ của bạn.
  • Không mất phí token: Khi đã đầu tư phần cứng, việc xử lý 500.000 token mỗi ngày chỉ tốn tiền điện mà cỗ máy tiêu thụ—thường từ 30W đến 250W khi tải nặng.
  • Hoạt động offline: Trợ lý viết code, tóm tắt nội dung và cơ sở tri thức nội bộ vẫn hoạt động bình thường ngay cả khi mất kết nối Internet.
  • Kiểm soát chi tiết: Bạn có toàn quyền thiết lập kích thước context window, sampling temperature, chunk overlap và model vector embedding theo ý muốn.

Nhược điểm

  • VRAM quyết định kích thước model: Một model 8B đã lượng tử hóa cần khoảng 5.5 GB đến 6 GB VRAM cho trọng số kèm theo context. Việc nâng cấp lên các model 70B đòi hỏi ít nhất 40 GB đến 48 GB VRAM trên nhiều GPU.
  • Hiệu năng chậm chạp khi chạy fallback trên CPU: Card RTX 3060 12GB đạt tốc độ khoảng 35–45 token/giây trên Llama 3.1 8B (Q4_K_M). Nhưng trên CPU 8 nhân không có tăng tốc GPU, tốc độ đó tụt dốc chỉ còn 3–6 token/giây.

Tự host có thể không sánh bằng các frontier model trên đám mây về khả năng suy luận phức tạp nhiều bước, nhưng đổi lại bạn không tốn phí thuê bao, có độ trễ ổn định và toàn quyền kiểm soát dữ liệu của mình.

Cấu hình phần cứng khuyến nghị

Để đảm bảo tốc độ inference mượt mà trong khi vẫn chạy các pipeline embedding ngầm, bạn nên hướng tới mốc cấu hình phần cứng sau:

  • Hệ điều hành máy chủ: Ubuntu Server 24.04 LTS hoặc Debian 12 (bookworm).
  • GPU: Card NVIDIA với 8GB đến 16GB VRAM. RTX 3060 12GB, RTX 4060 Ti 16GB hoặc RTX 3090 24GB cũ có thể chạy mượt mà các model 8B (Llama 3.1, Mistral 7B, DeepSeek-R1-Distill-Qwen-8B). RAM hệ thống DDR5 thế hệ mới có thể đáp ứng các model nhỏ 1B–3B, nhưng GPU vẫn mang lại trải nghiệm tốt nhất.
  • Bộ nhớ RAM: Tối thiểu 32GB RAM để tránh lỗi tràn bộ nhớ (OOM) khi vừa nhúng tài liệu vừa đánh chỉ mục vector đồng thời.
  • Ổ cứng lưu trữ: SSD NVMe tốc độ cao với ít nhất 100GB dung lượng trống. Mỗi file trọng số model chiếm từ 4GB đến 15GB, cộng thêm dung lượng lưu trữ cho ChromaDB vector store của Open WebUI.
  • Runtime: Docker Engine 24.0+ cùng với NVIDIA Container Toolkit.

Hướng dẫn triển khai từng bước

Chúng ta sẽ thiết lập một stack gồm 3 container sử dụng Docker Compose: Ollama có tăng tốc GPU, Open WebUI làm frontend và SearXNG để tìm kiếm web bảo vệ quyền riêng tư.

Bước 1: Cài đặt NVIDIA Container Toolkit

Nếu bạn sử dụng GPU NVIDIA, hãy cài đặt container toolkit để Docker có thể giao tiếp trực tiếp với CUDA:

# Thêm kho lưu trữ NVIDIA Container Toolkit
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
  && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
    sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

# Cài đặt toolkit và cấu hình Docker
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

Bước 2: Viết cấu hình Docker Compose

Tạo thư mục dự án cho stack và tạo file cấu hình compose:

mkdir -p ~/homelab/local-ai && cd ~/homelab/local-ai
nano docker-compose.yml

Thêm cấu hình các service sau vào file:

services:
  ollama:
    image: ollama/ollama:latest
    container_name: ollama
    restart: unless-stopped
    ports:
      - "11434:11434"
    volumes:
      - ./ollama_data:/root/.ollama
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

  searxng:
    image: searxng/searxng:latest
    container_name: searxng
    restart: unless-stopped
    ports:
      - "8080:8080"
    environment:
      - SEARXNG_BASE_URL=http://searxng:8080/
    volumes:
      - ./searxng_data:/etc/searxng

  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    restart: unless-stopped
    ports:
      - "3000:8080"
    environment:
      - OLLAMA_BASE_URL=http://ollama:11434
      - WEBUI_SECRET_KEY=tao_chuoi_bi_mat_ngau_nhien_32_ky_tu_o_day
      - ENABLE_RAG_WEB_SEARCH=True
      - RAG_WEB_SEARCH_ENGINE=searxng
      - SEARXNG_QUERY_URL=http://searxng:8080/search?q=<query>&format=json
    volumes:
      - ./open_webui_data:/app/backend/data
    depends_on:
      - ollama
      - searxng

Bước 3: Khởi chạy Container và tải Model

Khởi chạy stack ở chế độ chạy ngầm (background):

docker compose up -d

Tiếp theo, tải một model chat 8B và một model embedding chuyên dụng vào Ollama:

# Tải model Llama 3.1 8B (~4.7 GB)
docker exec -it ollama ollama pull llama3.1:8b

# Tải model embedding để truy xuất tài liệu (~274 MB)
docker exec -it ollama ollama pull nomic-embed-text

Bước 4: Cấu hình cài đặt trên Open WebUI

  1. Mở trình duyệt và truy cập vào http://<your-server-ip>:3000.
  2. Đăng ký tài khoản quản trị (admin). Người dùng đầu tiên đăng ký sẽ tự động nhận toàn quyền quản trị hệ thống.
  3. Điều hướng tới Admin Panel > Settings > Documents. Đặt Embedding Model Engine thành ollama và chọn nomic-embed-text từ danh sách thả xuống. Việc này giúp chuyển tác vụ chia nhỏ tài liệu (chunking) sang một model chuyên biệt thay vì làm lãng phí tài nguyên tính toán của model chính.
  4. Đi tới Admin Panel > Settings > Web Search. Kiểm tra xem tính năng tìm kiếm đã được bật hay chưa với công cụ tìm kiếm được đặt thành SearXNG và URL truy vấn được định cấu hình thành http://searxng:8080/search?q=<query>&format=json.

Bước 5: Thử nghiệm RAG tài liệu và tìm kiếm Web trực tiếp

Bắt đầu một cuộc trò chuyện mới để kiểm tra cả hai tính năng:

  • Truy xuất tài liệu (RAG): Nhấp vào biểu tượng đính kèm (+) và tải lên file PDF, file văn bản hoặc bản xuất mã nguồn dự án (ví dụ: tài liệu hướng dẫn máy chủ dài 20 trang). Đặt các câu hỏi chi tiết về nội dung của tài liệu. Open WebUI sẽ nhúng các đoạn dữ liệu, truy vấn cơ sở dữ liệu vector cục bộ và chèn trực tiếp các đoạn trích điểm cao nhất vào context của prompt.
  • Tìm kiếm Web theo thời gian thực: Bật biểu tượng quả địa cầu trên thanh trò chuyện và yêu cầu thông tin mới nhất, ví dụ: “Các cảnh báo bảo mật mới nhất dành cho Debian 12 là gì?”. Open WebUI sẽ truy vấn SearXNG, phân tích kết quả tìm kiếm và trích dẫn nguồn trực tiếp trong câu trả lời.
Share: