AI

Ollama + RAGFlow 构建个人知识库

Marimo_z
2025-04-22 / 0 评论 / 54 阅读 / 正在检测是否收录...
基于 Ollama + RAGFlow 以 DeepSeek 为例在 Windows 环境构建个人知识库并启用GPU加速优化。

一、环境准备与硬件要求

  1. 系统基础

    • 操作系统:Windows 10 及以上
    • 硬件配置

      • GPU:NVIDIA显卡(如 RTX 3060 及以上,显存 ≥ 8GB 支持更大模型)
      • 内存:≥ 16GB(推荐 32GB 以运行 14B 以上模型)
      • 存储:≥ 20GB可用空间(用于模型文件与知识库数据)
  2. 依赖工具安装

    • Docker Desktop:用于容器化部署 RAGFlow,需启用 WSL2
    • CUDA Toolkit:确保 GPU 驱动支持 CUDA(NVIDIA 用户必装)

二、Ollama部署与模型配置

Ollama官网:https://ollama.com
GitHub仓库:https://github.com/ollama/ollama
  1. 安装与自定义路径

    • 下载对应系统的安装程序:选择Windows的安装包,点击“Download for Windows(Preview)”下载。

      方式一:点击 OllamaSetup.exe 直接安装。

      方式二:通过命令行指定安装路径(避免占用系统盘)

      OllamaSetup.exe /DIR="D:\Ollama" 
    • 安装完成,打开cmd命令窗口,输入ollama命令,若显示ollama相关信息就证明安装已经成功了!

      Usage:
        ollama [flags]
        ollama [command]
      
      Available Commands:
        serve       Start ollama
        create      Create a model from a Modelfile
        show        Show information for a model
        run         Run a model
        stop        Stop a running model
        pull        Pull a model from a registry
        push        Push a model to a registry
        list        List models
        ps          List running models
        cp          Copy a model
        rm          Remove a model
        help        Help about any command
      
      Flags:
        -h, --help      help for ollama
        -v, --version   Show version information
      
      Use "ollama [command] --help" for more information about a command.
    • 环境变量配置

      默认模型存储路径:C:\Users\<username>\.ollama\models

      若要更改Ollama模型的存放位置,可以按照以下步骤操作:

      # 右键“此电脑”或“我的电脑”,选择“属性” → 查看高级系统设置 → 环境变量 → 创建系统变量或用户变量(若已存在则修改) → 重启Ollama相关应用程序
      
      OLLAMA_MODELS: 'D:\Ollama\Models' # 指定模型存储路径
      OLLAMA_HOST: '0.0.0.0:11434' # 允许跨容器访问
  2. 下载AI模型(以DeepSeek为例)

    • 根据硬件选择模型版本(如deepseek-r1:7bdeepseek-r1:14b):

      ollama pull deepseek-r1:7b 
    • 验证模型是否下载成功:

      ollama list

      查看列表是否存在模型:

      NAMEIDSIZEMODIFIED
      deepseek-r1:7b0a8c266910234.7 GBAbout a minute ago
    • 验证模型运行:

      cmd命令窗口启动模型(ollama run <模型名称>),若能与AI畅谈就证明运行成功!

      如果无法访问,可能是本机防火墙拦截了端口 11434,请放行端口(PS:若不想直接暴露11434端口,可以通过SSH端口转发实现)。

      ollama run deepseek-r1:7b
    • 验证GPU调用:

      执行ollama run deepseek-r1:7b后,输入一个较为复杂问题,通过任务管理器检查GPU占用。

      若GPU占用升高则证明启用了GPU加速优化。

    • Ollama常用命令:

      命令说明
      ollama pull <模型名称>从远程仓库下载模型到本地(若已存在则更新)。
      ollama run <模型名称>运行指定模型并进入交互对话模式。
      ollama list列出本地已下载的所有模型及其版本信息。
      ollama rm <模型名称>删除本地存储的指定模型。
      ollama create -f Modelfile根据 Modelfile 配置文件创建自定义模型。
      ollama ps查看当前正在运行的模型实例及其资源占用状态。
      ollama serve启动 Ollama 后台服务(通常自动运行,无需手动调用)。
      ollama help查看所有命令的详细帮助文档。
      Ctrl + d or /bye关闭当前模型并退出交互对话模式。

三、Docker安装与配置

  1. Docker安装:Docker官网

    Download Docker Desktop → Download for Windows - AMD64 → 下载并安装

    Docker镜像包含了所有运行RAGFlow所需的依赖、库和配置。

  2. 验证Docker是否安装成功:

    cmd命令窗口输入docker命令,查看是否显示Docker相关信息。

  3. 配置国内镜像源(如华为云、阿里云)以加速下载:

    Docker Desktop → Settings → Docker Engine → 配置国内镜像源并保存

    // 配置参考
    
    {
      "builder": {
        "gc": {
          "defaultKeepStorage": "20GB",
          "enabled": true
        }
      },
      "experimental": false,
      "features": {
        "buildkit": true
      },
      "registry-mirrors": [
        // 镜像源
        "https://registry.docker-cn.com",
        "https://docker.xuanyuan.me",
        "https://docker.1ms.run"
      ]
    }
  4. Docker GPU支持配置

    • 前置条件:

      • 操作系统 Windows 10及以上
      • 支持 NVIDIA GPU 并安装了 NVIDIA 驱动程序。
      • 安装了 Docker 19.03 或更新版本。
      • 安装了 NVIDIA Container Toolkit。
    • 安装 WSL 2(官方安装文档):

      • 检查是否已经安装 WSL(若正确打印出信息,则跳过安装)

        $ wsl -l -v
      • 安装(默认 WSL 2)

        $ wsl --install
    • 安装Linux子系统:

      • 通过微软商店系统镜像完成安装【例:Ubuntu 20.04 LTSCentOS7
      • 命令窗口通过上方标签页打开Linux子系统窗口
      • 设置用户名和密码 或 使用root登录

        root登录(默认没有密码),管理员权限打开powershell命令窗口,输入以下命令:

        ubuntu2004.exe config --default-user root

        再次打开时默认登录用户为root

      • 终端工具(可选,便于Linux操作):MobaXterm
      • docker配置ubuntu20.04 LTS

        Docker Desktop → Settings → General → 勾选 Use the WSL 2 based engine

        Docker Desktop → Settings → Resources→ 开启Linux子系统(Ubuntu 20.04 LTS

        保存配置(Apply & restart)

      • 测试子系统中使用 docker

        docker -v
    • 安装 NVIDIA 驱动程序:

      确保系统上安装了适用于您 GPU 的 NVIDIA 驱动程序。可以从 NVIDIA 官方网站 下载适用于您的操作系统和 GPU 的驱动程序。

      检查 NVIDIA 驱动程序是否正确安装:输入以下命令,显示有关 GPU 的信息(驱动程序版本和 GPU 使用情况)

      nvidia-smi
    • 在 WSL 中启用 NVIDIA CUDA(官网文档):

      下载并安装支持 NVIDIA CUDA 的 WSL 驱动程序,以便与现有 CUDA ML 工作流一起使用。 有关要安装哪个驱动程序的详细信息,请参阅:

      在Linux子系统中测试一下是否可以使用GPU:

      nvidia-smi

      验证 Docker 环境下 GPU 和 CUDA 驱动是否正常配置:CUDA 示例程序(测试 GPU 加速的 N 体模拟计算性能)

      docker run --gpus all nvcr.io/nvidia/k8s/cuda-sample:nbody nbody -gpu -benchmark

      若不成功请尝试更新Windows版本

四、RAGFlow本地化部署

  1. RAGFlow下载与配置

    • 下载RAGFlow源码(GitHub仓库)并解压
    • 推荐使用完整版镜像:

      RAGFlow image tagImage size (GB)Has embedding models?Stable?
      v0.17.2≈9✔️Stable release
      v0.17.2-slim≈2Stable release
      nightly≈9✔️Unstable nightly build
      nightly-slim≈2Unstable nightly build

      RAGFlow默认下载轻量版,没有embedding大模型,需要手动调用本地或者在线的embedding大模型(复杂)

      进入docker目录修改.env文件,使用完整版RAGFlow(推荐):

      # 注释84行的slim版,启用87行的完整版,保存文件:
      
      # RAGFLOW_IMAGE=infiniflow/ragflow:v0.17.2-slim
      RAGFLOW_IMAGE=infiniflow/ragflow:v0.17.2
  2. 启动RAGFlow容器

    • 启动Docker服务(确保 配置了国内镜像源使用科学上网工具
    • 进入docker文件夹,利用提前编译好的Docker镜像启动服务器:

      $ cd ragflow/docker
      
      # 方式一:使用 CPU 进行嵌入和 DeepDoc 任务:
      $ docker compose -f docker-compose.yml up -d
      
      # 方式二:使用 GPU 加速嵌入和 DeepDoc 任务:
      $ docker compose -f docker-compose-gpu.yml up -d
    • 在浏览器中输入服务器的IP地址localhost:80(默认运行在80端口),完成注册与登录。
    • 502 Bad Gateway 解决办法:

      在服务器启动并运行后检查服务器状态

      $ docker logs -f ragflow-server

      下面的输出确认系统成功启动

            ____   ___    ______ ______ __
           / __ \ /   |  / ____// ____// /____  _      __
          / /_/ // /| | / / __ / /_   / // __ \| | /| / /
         / _, _// ___ |/ /_/ // __/  / // /_/ /| |/ |/ /
        /_/ |_|/_/  |_|\____//_/    /_/ \____/ |__/|__/
      
       * Running on all addresses (0.0.0.0)

      额外启动一些Base服务

      # 切换到 ragflow/docker 目录执行以下命令
      $ docker compose -f docker-compose-base.yml --profile infinity up -d

五、模型接入与知识库构建

  1. 语言设置:右上角可以切换简体中文
  2. RAGFlow模型配置

    • 添加Ollama模型:(右上角“我的” → 模型提供商 → 添加Ollama模型)

      • 模型类型:根据需求选择chat(DeepSeek)或embedding(如nomic-embed-text
      • 模型名称:deepseek-r1:7b(根据自己模型填写)
      • 基础URL:填写http://host.docker.internal:11434(宿主机Ollama服务地址)
      • API-Key:忽略(本地运行无需填写)
      • 最大token数:100000(本地运行随意填写)
    • 系统模型设置

      • 聊天模型deepseek-r1:7b(选择需要使用的模型)
      • 嵌入模型BAAI/bge-large-zh-v1.5(选择RAGFlow自带或本地部署的模型)
    • 扩展(添加线上模型)

      • 使用对应平台获取的API-Key模型提供商添加线上模型(注:线上模型可能有额外费用)
  3. 知识库创建与文件解析

    • 创建知识库:知识库 → 创建知识库 → 更改配置(一般保持默认即可)
    • 解析参数建议:分块大小建议512 tokens,相似度阈值≥0.75
    • 知识注入:上传文档(PDF/TXT等格式),点击解析,RAGFlow会自动分块并向量化存储
    • 配置助理:(聊天 → 新建助理 → 聊天配置)
    • 对话测试:确保 DockerOllamaRAGFlow保持运行

六、调用 RAGFlow 模型服务

  1. RAGFlow API 核心接口概览

    接口类型端点方法功能描述
    用户认证/v1/user/loginPOST获取访问令牌
    知识库管理/v1/knowledge-basePOST创建/管理知识库
    文档上传/v1/rag/documentPOST上传文档到指定知识库
    问答查询/v1/rag/chat-streamPOST发起问答请求(流式/非流式)
  2. Vue3 前端调用实现

    • 安装依赖

      npm install axios @vueuse/core  # 推荐使用useFetch组合式API
    • 封装API请求层(src/api/ragflow.js

      import axios from 'axios';
      
      const API_BASE = 'http://ragflow-host:port/v1';  // 替换实际部署地址
      const API_KEY = 'your_api_key_here';  // 从RAGFlow后台获取
      
      const ragflowClient = axios.create({
        baseURL: API_BASE,
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${API_KEY}`
        }
      });
      
      // 示例:文档上传接口
      export const uploadDocument = async (file, knowledgeBaseId) => {
        const formData = new FormData();
        formData.append('file', file);
        formData.append('knowledge_base_id', knowledgeBaseId);
      
        return ragflowClient.post('/rag/document', formData, {
          headers: { 'Content-Type': 'multipart/form-data' }
        });
      };
      
      // 示例:问答接口(流式)
      export const streamChat = async (query, knowledgeBaseId) => {
        return fetch(`${API_BASE}/rag/chat-stream`, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${API_KEY}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            query: query,
            knowledge_base_id: knowledgeBaseId,
            stream: true
          })
        });
      };
    • 组件调用示例(ChatComponent.vue

      <script setup>
      import { ref } from 'vue';
      import { useFetch } from '@vueuse/core';
      import { streamChat } from '@/api/ragflow';
       
      const query = ref('');
      const response = ref('');
       
      const handleQuery = async () => {
        const { data } = await useFetch(
          () => streamChat(query.value, 'your_kb_id'),
          { refetch: true }
        ).json();
       
        // 流式数据处理
        const reader = data.value.getReader();
        const decoder = new TextDecoder();
       
        while(true) {
          const { done, value } = await reader.read();
          if(done) break;
          response.value += decoder.decode(value);
        }
      };
      </script>
       
      <template>
        <input v-model="query" @keyup.enter="handleQuery" />
        <div>{{ response }}</div>
      </template>
  3. Python 后端调用实现

    • 安装依赖

      pip install requests python-dotenv
    • 环境配置(.env

      RAGFLOW_API_KEY=your_api_key
      RAGFLOW_BASE_URL=http://ragflow-host:port/v1
    • 核心工具类(ragflow_client.py

      import os
      import requests
      from dotenv import load_dotenv
       
      load_dotenv()
       
      class RagFlowClient:
          def __init__(self):
              self.base_url = os.getenv("RAGFLOW_BASE_URL")
              self.headers = {
                  "Authorization": f"Bearer {os.getenv('RAGFLOW_API_KEY')}",
                  "Content-Type": "application/json"
              }
       
          def chat(self, query: str, kb_id: str, stream: bool = False):
              payload = {
                  "query": query,
                  "knowledge_base_id": kb_id,
                  "stream": stream
              }
              response = requests.post(
                  f"{self.base_url}/rag/chat-stream",
                  headers=self.headers,
                  json=payload,
                  stream=stream
              )
       
              if stream:
                  for chunk in response.iter_content(chunk_size=1024):
                      yield chunk.decode('utf-8')
              else:
                  return response.json()
       
      # 使用示例
      if __name__ == "__main__":
          client = RagFlowClient()
          # 非流式调用
          print(client.chat("什么是量子计算?", "kb_123"))
          # 流式调用
          for chunk in client.chat("解释Transformer架构", "kb_456", stream=True):
              print(chunk, end='')
  4. Spring Boot 后端调用实现

    • 添加依赖(pom.xml

      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-webflux</artifactId> <!-- 支持流式响应 -->
      </dependency>
      <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
      </dependency>
    • 配置类(RagFlowConfig.java

      @Configuration
      public class RagFlowConfig {
          @Value("${ragflow.api.key}")
          private String apiKey;
      
          @Value("${ragflow.base.url}")
          private String baseUrl;
      
          @Bean
          public WebClient ragflowClient() {
              return WebClient.builder()
                      .baseUrl(baseUrl)
                      .defaultHeader("Authorization", "Bearer " + apiKey)
                      .build();
          }
      }
    • 服务层(RagFlowService.java

      @Service
      public class RagFlowService {
          private final WebClient webClient;
      
          public RagFlowService(WebClient ragflowClient) {
              this.webClient = ragflowClient;
          }
      
          // 非流式问答
          public Mono<String> simpleChat(String query, String kbId) {
              return webClient.post()
                      .uri("/rag/chat-stream")
                      .bodyValue(Map.of(
                          "query", query,
                          "knowledge_base_id", kbId,
                          "stream", false
                      ))
                      .retrieve()
                      .bodyToMono(String.class);
          }
      
          // 流式问答(SSE)
          public Flux<String> streamChat(String query, String kbId) {
              return webClient.post()
                      .uri("/rag/chat-stream")
                      .bodyValue(Map.of(
                          "query", query,
                          "knowledge_base_id", kbId,
                          "stream", true
                      ))
                      .retrieve()
                      .bodyToFlux(String.class)
                      .map(data -> data.replace("\n", "<br/>")); // 示例数据处理
          }
      }
    • 控制器(RagFlowController.java

      @RestController
      @RequestMapping("/api/rag")
      public class RagFlowController {
          private final RagFlowService service;
       
          public RagFlowController(RagFlowService service) {
              this.service = service;
          }
       
          @PostMapping("/chat")
          public Mono<String> chat(@RequestBody ChatRequest request) {
              return service.simpleChat(request.query(), request.kbId());
          }
       
          @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
          public Flux<String> streamChat(@RequestParam String query, 
                                       @RequestParam String kbId) {
              return service.streamChat(query, kbId);
          }
       
          record ChatRequest(String query, String kbId) {}
      }
  5. 关键注意事项

    • 跨域问题(CORS)

      • 在RAGFlow的Nginx配置中添加:

        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type';
    • 流式传输优化

      • 前端使用EventSourcefetch+ReadableStream处理SSE
      • Spring Boot需启用spring-boot-starter-webflux
    • 安全增强

      # application.yml(Spring Boot)
      ragflow:
        api:
          key: ${RAGFLOW_API_KEY}  # 从环境变量读取
        base:
          url: http://ragflow-host:port/v1
    • 性能监控

      # Python装饰器示例
      def log_perf(func):
          def wrapper(*args, **kwargs):
              start = time.time()
              result = func(*args, **kwargs)
              print(f"{func.__name__} took {time.time()-start:.2f}s")
              return result
          return wrapper

七、GPU加速优化与问题排查

  1. 性能调优

    • 显存分配:通过.wslconfig限制WSL内存使用,避免资源耗尽
    • 模型选择:根据显存选择参数量(如8B模型需4GB显存,14B需8GB)
  2. 常见问题解决

    • GPU未被调用:检查CUDA安装、Docker GPU配置及Ollama环境变量
    • 镜像下载失败:替换镜像源或使用科学上网工具
    • Ollama服务不可达:确认防火墙放行端口11434,并检查环境变量OLLAMA_HOST
    • Docker Desktop内存不足

      • 命令窗口输入%UserProfile%,进入用户文件夹
      • 在用户文件夹下创建一个新文件,改名为 .wslconfig,内容如下:

        [wsl2]
        memory=16GB          # 分配的内存(≤设备内存)
        processors=12        # 处理器核心数量,考虑超线程(≤设备处理器核心数量)
        swap=0
        localhostForwarding=true
      • 退出docker,任务管理器中确保无docker相关进程
      • 命令窗口输入wsl --shutdown关闭 WSL
      • 重启 docker 和 WSL
    • RAGFlow报错ERROR: [Errno 111] Connection refused

      • 浏览器访问http://host.docker.internal:11434/是否显示Ollama is running
      • Ollama未成功运行 或 Docker相关服务未全部启动
      • Docker Desktop内存不足

八、进阶应用

  • 多模型切换:在Ollama中部署其他模型(如Llama 3、Qwen),按需调用
  • 知识库扩展:结合AnythingLLMNextJS-Ollama-UI实现可视化管理与浏览器集成
  • 私有化部署:通过内网穿透工具(如frp)实现远程访问
6

评论 (0)

取消