GraphRAG如何使用ollama提供的llm model 和Embedding model服务构建本地知识库

使用GraphRAG踩坑无数

在GraphRAG的使用过程中将需要踩的坑都踩了一遍(不得不吐槽下,官方代码有很多遗留问题,他们自己也承认工作重心在算法的优化而不是各种模型和框架的兼容性适配性上),经过了大量的查阅各种资料以及debug过程(Indexing的过程有点费机器),最终成功运行了GraphRAG项目。先后测试了两种方式,都成功了:

  1. 使用ollama提供本地llm model和Embedding model服务
  2. 使用ollama提供llm model服务,使用lm-studio提供embedding model服务

之所以要使用ollama同时提供llm和Embedding模型服务,是因为ollama实在是太优雅了,使用超级简单,响应速度也超级快。

使用ollama提供服务的方式如下:

1、安装GraphRAG:

pip install graphrag -i https://pypi.tuna.tsinghua.edu.cn/simple
  1. 创建一个文件路径:./ragtest/input

    mkdir -p ./ragtest/input

  2. 将语料文本文件放在这个路径下, 文件格式为txt, 注意:txt文件必须是utf-8编码的,可以用记事本打开另存为得到。

  3. 使用命令python -m graphrag.index --init --root ./ragtest初始化工程:

    python -m graphrag.index --init --root ./ragtest

  4. 修改.env文件内容如下:

    GRAPHRAG_API_KEY=ollama
    GRAPHRAG_CLAIM_EXTRACTION_ENABLED=True

注意:必须加上参数GRAPHRAG_CLAIM_EXTRACTION_ENABLED=True,否则无法生成协变量covariates, 在Local Search时会出错。

  1. 修改.setting.yaml文件,内容如下:

    encoding_model: cl100k_base
    skip_workflows: []
    llm:
    api_key: ollama
    type: openai_chat # or azure_openai_chat
    model: qwen2
    model_supports_json: true # recommended if this is available for your model.

    max_tokens: 4000

    request_timeout: 180.0

    api_base: http://localhost:11434/v1/

    api_version: 2024-02-15-preview

    organization: <organization_id>

    deployment_name: <azure_model_deployment_name>

    tokens_per_minute: 150_000 # set a leaky bucket throttle

    requests_per_minute: 10_000 # set a leaky bucket throttle

    max_retries: 10

    max_retry_wait: 10.0

    sleep_on_rate_limit_recommendation: true # whether to sleep when azure suggests wait-times

    concurrent_requests: 25 # the number of parallel inflight requests that may be made

    parallelization:
    stagger: 0.3

    num_threads: 50 # the number of threads to use for parallel processing

    async_mode: threaded # or asyncio

    embeddings:

    parallelization: override the global parallelization settings for embeddings

    async_mode: threaded # or asyncio
    llm:
    api_key: ollama
    type: openai_embedding # or azure_openai_embedding
    model: nomic-embed-text
    api_base: http://localhost:11434/api
    # api_version: 2024-02-15-preview
    # organization: <organization_id>
    # deployment_name: <azure_model_deployment_name>
    # tokens_per_minute: 150_000 # set a leaky bucket throttle
    # requests_per_minute: 10_000 # set a leaky bucket throttle
    # max_retries: 10
    # max_retry_wait: 10.0
    # sleep_on_rate_limit_recommendation: true # whether to sleep when azure suggests wait-times
    # concurrent_requests: 25 # the number of parallel inflight requests that may be made
    # batch_size: 16 # the number of documents to send in a single request
    # batch_max_tokens: 8191 # the maximum number of tokens to send in a single request
    # target: required # or optional

  2. 使用ollama启动llm和Embedding服务,其中embedding 模型是nomic-embed-text:

    ollama pull qwen2
    ollama pull nomic-embed-text
    ollama serve

  3. 修改文件:D:ProgramDataminiconda3envsgraphRAGLibsite-packagesgraphragllmopenaiopenai_embeddings_llm.py内容(根据大家自己安装GraphRAG的路径查找),调用ollama服务:

    import ollama

    class OpenAIEmbeddingsLLM(BaseLLM[EmbeddingInput, EmbeddingOutput]):
    “”“A text-embedding generator LLM.”“”

    _client: OpenAIClientTypes
    _configuration: OpenAIConfiguration
    
    def __init__(self, client: OpenAIClientTypes, configuration: OpenAIConfiguration):
        self.client = client
        self.configuration = configuration
    
    async def _execute_llm(
        self, input: EmbeddingInput, **kwargs: Unpack[LLMInput]
    ) -> EmbeddingOutput | None:
        args = {
            "model": self.configuration.model,
            **(kwargs.get("model_parameters") or {}),
        }
        '''
        embedding = await self.client.embeddings.create(
            input=input,
            **args,
        )
        return [d.embedding for d in embedding.data]
        '''
        embedding_list = []
        for inp in input:
            embedding = ollama.embeddings(model="nomic-embed-text",prompt=inp)
            embedding_list.append(embedding["embedding"])
        return embedding_list
    

上面注释部分为官方原始代码,增加的代码是:

        embedding_list = []
        for inp in input:
            embedding = ollama.embedding(model="nomic-embed-text",prompt=inp)
            embedding_list.append(embedding["embedding"])
        return embedding_list
  1. 修改文件:D:ProgramDataminiconda3envsgraphRAGLibsite-packagesgraphragqueryllmoaiembedding.py, 调用ollama提供的模型服务, 代码位置在:

    import ollama
    #…

    embedding = ollama.embeddings(model=‘nomic-embed-text’, prompt=chunk)[‘embedding’]

在这里插入图片描述
上面注释的是官方代码,箭头指向的是要新增的代码。

  1. 修改文件:D:ProgramDataminiconda3envsgraphRAGLibsite-packagesgraphragqueryllm ext_utils.py里关于chunk_text()函数的定义:
def chunk_text(
    text: str, max_tokens: int, token_encoder: tiktoken.Encoding | None = None
):
    """Chunk text by token length."""
    if token_encoder is None:
        token_encoder = tiktoken.get_encoding("cl100k_base")
    tokens = token_encoder.encode(text)  # type: ignore
    tokens = token_encoder.decode(tokens) # 将tokens解码成字符串

    chunk_iterator = batched(iter(tokens), max_tokens)
    yield from chunk_iterator

增加的语句是:

tokens = token_encoder.decode(tokens) # 将tokens解码成字符串

这里应该是GraphRAG官方代码里的bug,开发人员忘记将分词后的token解码成字符串,导致在后续Embedding处理过程中会报错:ZeroDivisionError: Weights sum to zero, can't be normalized

(graphrag) D:LearnGraphRAG>python -m graphrag.query --root ./newTest12 --method local "谁是叶文洁"


INFO: Reading settings from newTest12settings.yaml
creating llm client with {'api_key': 'REDACTED,len=6', 'type': "openai_chat", 'model': 'qwen2', 'max_tokens': 4000, 'temperature': 0.0, 'top_p': 1.0, 'n': 1, 'request_timeout': 180.0, 'api_base': 'http://localhost:11434/v1/', 'api_version': None, 'organization': None, 'proxy': None, 'cognitive_services_endpoint': None, 'deployment_name': None, 'model_supports_json': True, 'tokens_per_minute': 0, 'requests_per_minute': 0, 'max_retries': 10, 'max_retry_wait': 10.0, 'sleep_on_rate_limit_recommendation': True, 'concurrent_requests': 25}
creating embedding llm client with {'api_key': 'REDACTED,len=9', 'type': "openai_embedding", 'model': 'nomic-ai/nomic-embed-text-v1.5/nomic-embed-text-v1.5.Q8_0.gguf', 'max_tokens': 4000, 'temperature': 0, 'top_p': 1, 'n': 1, 'request_timeout': 180.0, 'api_base': 'http://localhost:1234/v1', 'api_version': None, 'organization': None, 'proxy': None, 'cognitive_services_endpoint': None, 'deployment_name': None, 'model_supports_json': None, 'tokens_per_minute': 0, 'requests_per_minute': 0, 'max_retries': 10, 'max_retry_wait': 10.0, 'sleep_on_rate_limit_recommendation': True, 'concurrent_requests': 1}
Error embedding chunk {'OpenAIEmbedding': 'Error code: 400 - {'error': "'input' field must be a string or an array of strings"}'}
Traceback (most recent call last):
  File "D:ProgramDataminiconda3envsgraphraglib
unpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "D:ProgramDataminiconda3envsgraphraglib
unpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "D:ProgramDataminiconda3envsgraphraglibsite-packagesgraphragquery__main__.py", line 76, in <module>
    run_local_search(
  File "D:ProgramDataminiconda3envsgraphraglibsite-packagesgraphragquerycli.py", line 153, in run_local_search
    result = search_engine.search(query=query)
  File "D:ProgramDataminiconda3envsgraphraglibsite-packagesgraphragquerystructured_searchlocal_searchsearch.py", line 118, in search
    context_text, context_records = self.context_builder.build_context(
  File "D:ProgramDataminiconda3envsgraphraglibsite-packagesgraphragquerystructured_searchlocal_searchmixed_context.py", line 139, in build_context
    selected_entities = map_query_to_entities(
  File "D:ProgramDataminiconda3envsgraphraglibsite-packagesgraphragquerycontext_builderentity_extraction.py", line 55, in map_query_to_entities
    search_results = te
<think>嗯,用户想了解怎么用DeepSeek OpenWebUIOllama搭建私有的RAG知识库。首先,我得确认这两个工具的作用它们之间的关系。Ollama应该是在本地运行大模型的工具,而DeepSeek OpenWebUI可能是一个用户界面,用来管理交互。RAG需要结合检索生成,所以可能需要向量数据库,比如Chroma或者FAISS。 接下来,得理清步骤。首先,用户需要安装Ollama,然后下载适合的模型,比如llama2或者deepseek的模型。然后安装DeepSeek OpenWebUI,可能需要进行配置,让它连接到Ollama。接着处理文档,转换成向量,存入数据库。最后整合RAG流程,测试整个系统。 可能需要注意的细节:Ollama的安装方法,是否支持Windows还是仅限Linux/macOS。DeepSeek OpenWebUI的配置可能需要修改设置文件,指向本地Ollama服务。文档处理部分需要分词、向量化,可能需要用到Hugging Face的模型或者sentence-transformers。RAG的实现逻辑,如何结合检索结果生成回答。 用户可能遇到的问题包括环境配置错误,模型下载失败,OpenWebUI无法连接Ollama,或者向量数据库的集成问题。需要确保各服务之间的端口开放,比如Ollama默认的11434端口,OpenWebUI的端口是否冲突。 另外,要提醒用户准备足够的计算资源,尤其是运行本地模型需要较大的内存显存。如果用户没有GPU,可能需要选择较小的模型或者使用量化版本。最后,测试部分需要验证检索是否正确,生成答案是否相关,可能需要示例代码或者命令。</think>以下为使用DeepSeek OpenWebUIOllama搭建私有RAG知识库的完整技术方案: --- ### 一、技术架构组成 $$ \text{RAG系统} = \text{Ollama(大模型)} + \text{DeepSeek OpenWebUI(交互层)} + \text{向量数据库} + \text{文档处理流水线} $$ 其中核心组件版本建议: - Ollama v0.1.25+ - DeepSeek OpenWebUI最新版 - Sentence-Transformers/all-MiniLM-L6-v2(嵌入模型) - Chroma DB(轻量级向量库) --- ### 二、详细搭建步骤 #### 步骤1:部署Ollama ```bash # Linux/macOS安装 curl -fsSL https://ollama.ai/install.sh | sh # 启动服务 ollama serve & # 下载模型(示例) ollama pull llama2:13b-chat # 基础大模型 ollama pull deepseek-ai/deepseek-coder-33b-instruct # 专用领域模型 ``` #### 步骤2:安装OpenWebUI ```bash # 使用Docker部署 docker run -d -p 3000:8080 \ -v openwebui:/app/backend/data \ --add-host=host.docker.internal:host-gateway \ --name openwebui \ ghcr.io/openwebui/openwebui:main # 配置模型连接 修改配置文件指向本地Ollama: API_BASE_URL=http://host.docker.internal:11434 ``` #### 步骤3:文档处理流水线 ```python from langchain.document_loaders import DirectoryLoader from langchain.text_splitter import RecursiveCharacterTextSplitter # 加载文档(支持PDF/DOCX/TXT) loader = DirectoryLoader('/知识库路径', glob="**/*.pdf") docs = loader.load() # 文档分块(数学表达) $$ \text{chunk_size}=512,\ \text{chunk_overlap}=64 $$ splitter = RecursiveCharacterTextSplitter.from_huggingface_tokenizer( tokenizer_name="BAAI/bge-small-en-v1.5", chunk_size=512, chunk_overlap=64 ) chunks = splitter.split_documents(docs) ``` #### 步骤4:向量数据库构建 ```python from langchain.vectorstores import Chroma from langchain.embeddings import HuggingFaceEmbeddings # 嵌入模型选择 embed_model = HuggingFaceEmbeddings( model_name="sentence-transformers/all-MiniLM-L6-v2" ) # 创建向量库 vector_db = Chroma.from_documents( documents=chunks, embedding=embed_model, persist_directory="./chroma_db" ) ``` #### 步骤5:RAG流程集成 ```python from langchain.chains import RetrievalQA from langchain.llms import Ollama # 初始化Ollama连接 llm = Ollama(base_url="http://localhost:11434", model="deepseek-coder-33b") # 构建检索链 qa_chain = RetrievalQA.from_chain_type( llm=llm, retriever=vector_db.as_retriever(search_kwargs={"k": 3}), chain_type="stuff" ) # 查询示例 response = qa_chain.run("如何配置Ollama的GPU加速?") ``` --- ### 三、核心参数优化建议 1. **分块策略优化**: $$ \text{信息密度阈值} = \frac{\text{关键实体数}}{\text{段落长度}} \geq 0.15 $$ 建议通过TF-IDF分析动态调整chunk_size 2. **检索增强参数**: ```yaml retriever: search_type: mmr # 最大边界相关算法 score_threshold: 0.65 fetch_k: 10 ``` 3. **推理参数配置**: ```python Ollama( temperature=0.3, top_p=0.9, num_ctx=4096 # 上下文窗口 ) ``` --- ### 四、验证测试方法 1. **检索有效性测试**: $$ \text{查全率} = \frac{\text{相关段落召回数}}{\text{总相关段落数}} $$ 建议构建测试集验证召回率 > 85% 2. **生成质量评估**: ```python # 使用RAGAS评估框架 from ragas.metrics import faithfulness, answer_relevancy score = evaluate( qa_chain, metrics=[faithfulness, answer_relevancy] ) ``` --- ### 五、常见问题解决方案 | 问题现象 | 排查方向 | 修复方案 | |---------|---------|---------| | OpenWebUI无法连接Ollama | 网络策略检查 | `docker network create ollama-net`并接入同一网络 | | 中文检索效果差 | 嵌入模型适配 | 切换为`text2vec-large-chinese`模型 | | 响应速度慢 | 量化模型 | 使用`llama2:13b-chat-q4_K_M`量化版本 | --- 该方案已在16GB内存+NVIDIA T4 GPU环境验证通过,建议生产环境使用Kubernetes进行容器编排管理。可通过调整chunk_size检索策略适配不同领域知识库需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值