GraphRAG + Ollama 本地部署全攻略:避坑实战指南

news2024/11/17 17:35:04

1

为什么要对 GraphRAG 本地部署?

微软开源 GraphRAG 后,热度越来越高,目前 GraphRAG 只支持 OpenAI 的闭源大模型,导致部署后使用范围大大受限,本文通过 GraphRAG 源码的修改,来支持更广泛的 Embedding 模型和开源大模型,从而使得 GraphRAG 的更容易上手使用。

2

GraphRAG 一键安装

第一步、安装 GraphRAG

需要 Python 3.10-3.12 环境。

第二步、创建知识数据文件夹

安装完整后,需要创建一个文件夹,用来存储你的知识数据,目前 GraphRAG 只支持 txt 和 csv 格式。

第三步、准备一份数据放在 /ragtest/input 目录下

第四步、初始化工作区

首先,我们需要运行以下命令来初始化。

其次,我们第二步已经准备了 ragtest 目录,运行以下命令完成初始化。

运行完成后,在 ragtest 目录下生成以下两个文件:.envsettings.yaml。ragtest 目录下的结构如下:

.env 文件包含了运行 GraphRAG 管道所需的环境变量。如果您检查该文件,您会看到一个定义的环境变量,GRAPHRAG_API_KEY=<API_KEY>。这是 OpenAI API 或 Azure OpenAI 端点的 API 密钥。您可以用自己的 API 密钥替换它。

settings.yaml 文件包含了管道的设置。您可以修改此文件以更改管道的设置。

3

修改配置文件支持本地部署大模型

第一步、确保已安装 Ollama

如果你还没安装或者不会安装,可以参考我之前写的文章《Spring AI + Ollama 快速构建大模型应用程序(含源码)》。

第二步、确保已安装以下本地模型

Embedding 嵌入模型`  `quentinz/bge-large-zh-v1.5:latest``LLM 大模型`  `gemma2:9b

第三步、修改 settings.yaml 以支持以上两个本地模型,以下是修改后的文件

encoding_model: cl100k_base``skip_workflows: []``llm:`  `api_key: ollama`  `type: openai_chat # or azure_openai_chat`  `model: gemma2:9b # 你 ollama 中的本地 llm 模型,可以换成其他的,只要你安装了就可以`  `model_supports_json: true # recommended if this is available for your model.`  `max_tokens: 2048`  `api_base: http://localhost:11434/v1 # 接口注意是v1`  `concurrent_requests: 1 # the number of parallel inflight requests that may be made``   ``parallelization:`  `stagger: 0.3``   ``async_mode: threaded # or asyncio``   ``embeddings:`  `async_mode: threaded # or asyncio`  `llm:`    `api_key: ollama`    `type: openai_embedding # or azure_openai_embedding`    `model: quentinz/bge-large-zh-v1.5:latest # 你 ollama 中的本地 Embeding 模型,可以换成其他的,只要你安装了就可以`    `api_base: http://localhost:11434/api # 注意是 api`    `concurrent_requests: 1 # the number of parallel inflight requests that may be made``chunks:`  `size: 300`  `overlap: 100`  `group_by_columns: [id] # by default, we don't allow chunks to cross documents`    `input:`  `type: file # or blob`  `file_type: text # or csv`  `base_dir: "input"`  `file_encoding: utf-8`  `file_pattern: ".*\\.txt$"``   ``cache:`  `type: file # or blob`  `base_dir: "cache"``   ``storage:`  `type: file # or blob`  `base_dir: "output/${timestamp}/artifacts"``   ``reporting:`  `type: file # or console, blob`  `base_dir: "output/${timestamp}/reports"``   ``entity_extraction:`  `prompt: "prompts/entity_extraction.txt"`  `entity_types: [organization,person,geo,event]`  `max_gleanings: 0``   ``summarize_descriptions:`  `prompt: "prompts/summarize_descriptions.txt"`  `max_length: 500``   ``claim_extraction:`  `prompt: "prompts/claim_extraction.txt"`  `description: "Any claims or facts that could be relevant to information discovery."`  `max_gleanings: 0``   ``community_report:`  `prompt: "prompts/community_report.txt"`  `max_length: 2000`  `max_input_length: 8000``   ``cluster_graph:`  `max_cluster_size: 10``   ``embed_graph:`  `enabled: false # if true, will generate node2vec embeddings for nodes``   ``umap:`  `enabled: false # if true, will generate UMAP embeddings for nodes``   ``snapshots:`  `graphml: false`  `raw_entities: false`  `top_level_nodes: false``   ``local_search:`  `max_tokens: 5000``   ``global_search:`  `max_tokens: 5000

第四步、运行 GraphRAG 构建知识图谱索引

构建知识图谱的索引需要一定的时间,构建过程如下所示:

4

修改源码支持本地部署大模型

接下来修改源码,保证进行 local 和 global 查询时给出正确的结果。

第一步、修改成本地的 Embedding 模型

修改源代码的目录和文件:

…/Python/Python310/site-packages/graphrag/llm/openai/openai_embeddings_llm.py"

修改后的源码如下:

   ``# Copyright (c) 2024 Microsoft Corporation.``# Licensed under the MIT License``   ``"""The EmbeddingsLLM class."""``   ``from typing_extensions import Unpack``   ``from graphrag.llm.base import BaseLLM``from graphrag.llm.types import (`    `EmbeddingInput,`    `EmbeddingOutput,`    `LLMInput,``)``   ``from .openai_configuration import OpenAIConfiguration``from .types import OpenAIClientTypes``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_list = []`        `for inp in input:`            `embedding = ollama.embeddings(model="quentinz/bge-large-zh-v1.5:latest",prompt=inp)`            `embedding_list.append(embedding["embedding"])`        `return embedding_list`        `# embedding = await self.client.embeddings.create(`        `#     input=input,`        `#     **args,`        `# )`        `# return [d.embedding for d in embedding.data]``   

第二步、继续修改 Embedding 模型

修改源代码的目录和文件:

…/Python/Python310/site-packages/graphrag/query/llm/oai/embedding.py"

修改后的源码如下:

   ``# Copyright (c) 2024 Microsoft Corporation.``# Licensed under the MIT License``   ``"""OpenAI Embedding model implementation."""``   ``import asyncio``from collections.abc import Callable``from typing import Any``   ``import numpy as np``import tiktoken``from tenacity import (`    `AsyncRetrying,`    `RetryError,`    `Retrying,`    `retry_if_exception_type,`    `stop_after_attempt,`    `wait_exponential_jitter,``)``   ``from graphrag.query.llm.base import BaseTextEmbedding``from graphrag.query.llm.oai.base import OpenAILLMImpl``from graphrag.query.llm.oai.typing import (`    `OPENAI_RETRY_ERROR_TYPES,`    `OpenaiApiType,``)``from graphrag.query.llm.text_utils import chunk_text``from graphrag.query.progress import StatusReporter``   ``from langchain_community.embeddings import OllamaEmbeddings``   ``   ``   ``class OpenAIEmbedding(BaseTextEmbedding, OpenAILLMImpl):`    `"""Wrapper for OpenAI Embedding models."""``   `    `def __init__(`        `self,`        `api_key: str | None = None,`        `azure_ad_token_provider: Callable | None = None,`        `model: str = "text-embedding-3-small",`        `deployment_name: str | None = None,`        `api_base: str | None = None,`        `api_version: str | None = None,`        `api_type: OpenaiApiType = OpenaiApiType.OpenAI,`        `organization: str | None = None,`        `encoding_name: str = "cl100k_base",`        `max_tokens: int = 8191,`        `max_retries: int = 10,`        `request_timeout: float = 180.0,`        `retry_error_types: tuple[type[BaseException]] = OPENAI_RETRY_ERROR_TYPES,  # type: ignore`        `reporter: StatusReporter | None = None,`    `):`        `OpenAILLMImpl.__init__(`            `self=self,`            `api_key=api_key,`            `azure_ad_token_provider=azure_ad_token_provider,`            `deployment_name=deployment_name,`            `api_base=api_base,`            `api_version=api_version,`            `api_type=api_type,  # type: ignore`            `organization=organization,`            `max_retries=max_retries,`            `request_timeout=request_timeout,`            `reporter=reporter,`        `)``   `        `self.model = model`        `self.encoding_name = encoding_name`        `self.max_tokens = max_tokens`        `self.token_encoder = tiktoken.get_encoding(self.encoding_name)`        `self.retry_error_types = retry_error_types``   `    `def embed(self, text: str, **kwargs: Any) -> list[float]:`        `"""`        `Embed text using OpenAI Embedding's sync function.``   `        `For text longer than max_tokens, chunk texts into max_tokens, embed each chunk, then combine using weighted average.`        `Please refer to: https://github.com/openai/openai-cookbook/blob/main/examples/Embedding_long_inputs.ipynb`        `"""`        `token_chunks = chunk_text(`            `text=text, token_encoder=self.token_encoder, max_tokens=self.max_tokens`        `)`        `chunk_embeddings = []`        `chunk_lens = []`        `for chunk in token_chunks:`            `try:`                `embedding, chunk_len = self._embed_with_retry(chunk, **kwargs)`                `chunk_embeddings.append(embedding)`                `chunk_lens.append(chunk_len)`            `# TODO: catch a more specific exception`            `except Exception as e:  # noqa BLE001`                `self._reporter.error(`                    `message="Error embedding chunk",`                    `details={self.__class__.__name__: str(e)},`                `)``   `                `continue`        `chunk_embeddings = np.average(chunk_embeddings, axis=0, weights=chunk_lens)`        `chunk_embeddings = chunk_embeddings / np.linalg.norm(chunk_embeddings)`        `return chunk_embeddings.tolist()``   `    `async def aembed(self, text: str, **kwargs: Any) -> list[float]:`        `"""`        `Embed text using OpenAI Embedding's async function.``   `        `For text longer than max_tokens, chunk texts into max_tokens, embed each chunk, then combine using weighted average.`        `"""`        `token_chunks = chunk_text(`            `text=text, token_encoder=self.token_encoder, max_tokens=self.max_tokens`        `)`        `chunk_embeddings = []`        `chunk_lens = []`        `embedding_results = await asyncio.gather(*[`            `self._aembed_with_retry(chunk, **kwargs) for chunk in token_chunks`        `])`        `embedding_results = [result for result in embedding_results if result[0]]`        `chunk_embeddings = [result[0] for result in embedding_results]`        `chunk_lens = [result[1] for result in embedding_results]`        `chunk_embeddings = np.average(chunk_embeddings, axis=0, weights=chunk_lens)  # type: ignore`        `chunk_embeddings = chunk_embeddings / np.linalg.norm(chunk_embeddings)`        `return chunk_embeddings.tolist()``   `    `def _embed_with_retry(`        `self, text: str | tuple, **kwargs: Any`    `) -> tuple[list[float], int]:`        `try:`            `retryer = Retrying(`                `stop=stop_after_attempt(self.max_retries),`                `wait=wait_exponential_jitter(max=10),`                `reraise=True,`                `retry=retry_if_exception_type(self.retry_error_types),`            `)`            `for attempt in retryer:`                `with attempt:`                    `embedding = (`                        `OllamaEmbeddings(`                            `model=self.model,`                        `).embed_query(text)`                        `or []`                    `)`                    `return (embedding, len(text))`        `except RetryError as e:`            `self._reporter.error(`                `message="Error at embed_with_retry()",`                `details={self.__class__.__name__: str(e)},`            `)`            `return ([], 0)`        `else:`            `# TODO: why not just throw in this case?`            `return ([], 0)``   `    `async def _aembed_with_retry(`        `self, text: str | tuple, **kwargs: Any`    `) -> tuple[list[float], int]:`        `try:`            `retryer = AsyncRetrying(`                `stop=stop_after_attempt(self.max_retries),`                `wait=wait_exponential_jitter(max=10),`                `reraise=True,`                `retry=retry_if_exception_type(self.retry_error_types),`            `)`            `async for attempt in retryer:`                `with attempt:`                    `embedding = (`                        `await OllamaEmbeddings(`                            `model=self.model,`                        `).embed_query(text) or [] )`                    `return (embedding, len(text))`        `except RetryError as e:`            `self._reporter.error(`                `message="Error at embed_with_retry()",`                `details={self.__class__.__name__: str(e)},`            `)`            `return ([], 0)`        `else:`            `# TODO: why not just throw in this case?`            `return ([], 0)

5

GraphRAG 效果测试

第一、local 查询

第二、global 查询

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

😝有需要的小伙伴,可以Vx扫描下方二维码免费领取🆓

👉1.大模型入门学习思维导图👈

要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。

对于从来没有接触过AI大模型的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。(全套教程文末领取哈)
在这里插入图片描述

👉2.AGI大模型配套视频👈

很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,每个章节都是当前板块的精华浓缩。

在这里插入图片描述
在这里插入图片描述

👉3.大模型实际应用报告合集👈

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。(全套教程文末领取哈)

在这里插入图片描述

👉4.大模型落地应用案例PPT👈

光学理论是没用的,要学会跟着一起做,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。(全套教程文末领取哈)

在这里插入图片描述

👉5.大模型经典学习电子书👈

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

img

在这里插入图片描述

👉6.大模型面试题&答案👈

截至目前大模型已经超过200个,在大模型纵横的时代,不仅大模型技术越来越卷,就连大模型相关的岗位和面试也开始越来越卷了。为了让大家更容易上车大模型算法赛道,我总结了大模型常考的面试题。

在这里插入图片描述

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

😝有需要的小伙伴,可以Vx扫描下方二维码免费领取🆓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2066438.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot之项目搭建并say hi

写在前面 本文看下如何搭建一个最简单的支持http接口的hello程序。 1&#xff1a;正文 接着引入springboot依赖&#xff1a; <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><v…

4.7重复的子字符串(LC_459-E)

给定一个非空的字符串 s &#xff0c;检查是否可以通过由它的一个子串重复多次构成。 示例 1: 输入: s "abab" 输出: true 解释: 可由子串 "ab" 重复两次构成。示例 2: 输入: s "aba" 输出: false示例 3: 输入: s "abcabcabcabc"…

无线终端ZWS云应用(一)—1分钟快速接入CATCOM-100 DTU上云

环境监测设备&#xff08;如温湿度传感器&#xff09;可以通过DTU终端CATCOM-100接入ZWS云平台&#xff0c;实现远程监控和管理。 准备工作 准备一个温湿度传感器和一个致远电子的DTU终端CATCOM-100。准备一张SIM卡&#xff0c;用于4G联网。 操作步骤 1. 云平台设备创建 1.1 …

PCIe563XD系列多功能异步数据采集卡64路AD信号采集500K采样频率

阿尔泰科技 型号&#xff1a;PCIe5630D/5631D/5632D/5633Dhttps://item.taobao.com/item.htm?spma1z10.3-c-s.w4002-265216876.12.84513350msbilC&id589158158140&piskf6qstfsYFCA6dK09z-BERdlfDjobG5szWKMYE-KwHcntcqeoOlla3juYGWce0OmNomNjOScZ7chwcmwbiSuY0jrXIkN…

nodejs发送邮件给多个收件人如何实现群发?

node.js发送邮件的方法&#xff1f;如何用nodejs自动发送邮件&#xff1f; Node.js发送邮件是一种高效而灵活的解决方案&#xff0c;尤其是在需要群发邮件时。AokSend将探讨如何使用Node.js发送邮件给多个收件人&#xff0c;帮您实现邮件的批量发送。 nodejs发送邮件&#xf…

2024年3款精选工具+谷歌翻译:发现那些你不知道的高级功能!

现在这世界变得越来越像一个村了&#xff0c;语言不应该是我们聊天的绊脚石。但是在工作的时候&#xff0c;碰到不同语言的文件、邮件和会议&#xff0c;翻译还是挺考验人的。好在有谷歌翻译这个牛气的工具&#xff0c;还有其他几个好用的软件帮忙&#xff0c;让我们在工作上翻…

前端常见**MS题 [3]

css部分 1、简单说明一下盒模型 CSS盒模型定义了盒的每个部分包含&#xff1a; margin, border, padding, content 。根据盒子大小的计算方式不同盒模型分成了两种&#xff0c;标准盒模型和怪异盒模型。 标准模型&#xff0c;给盒设置 width 和 height&#xff0c;实际设置的是…

【吊打面试官系列-Memcached面试题】memcached 的多线程是什么?如何使用它们?

大家好&#xff0c;我是锋哥。今天分享关于 【memcached 的多线程是什么&#xff1f;如何使用它们&#xff1f; 】面试题&#xff0c;希望对大家有帮助&#xff1b; memcached 的多线程是什么&#xff1f;如何使用它们&#xff1f; 线程就是定律&#xff08;threads rule&#…

linux 第一个命令的编写

1. 命令的概念 命令就是可执行程序。 比如说输入“ls -al”命令&#xff0c;ls 就是可执行程序的的名字。-al 就是要传递进去的参数。 ps 命令&#xff1a; 功能&#xff1a;显示进程的动态。 输入 ps 命令 当 shell 接收到命令以后&#xff0c;会根据输入的字符到环境变量和默…

UDP/TCP --- Socket编程

本篇将使用 Linux 中的系统调用来实现模拟 TCP 和 UDP 的通信过程&#xff0c;其中只对 UDP 和 TCP 进行了简单的介绍&#xff0c;本篇主要实现的是代码&#xff0c;至于 UDP 和 TCP 的详细讲解将会在之后的文章中给出。 本篇给出的 tcp 和 udp 的代码中的 echo 都是测试连接是…

电脑死机之后强制关机重启,只能进入到Bios,不能进入到系统?

前言 最近遇到好几件比较有意思的事情&#xff0c;粉丝过来求助咨询&#xff1a;电脑不知怎的就黑屏死机了&#xff0c;重启之后&#xff0c;电脑只能进入到Bios&#xff0c;无论怎么重启都没用。 把电脑拆出来看了看&#xff0c;线路一切正常。感觉上可能是内存条的问题&…

NRK3301语音识别芯片在汽车内饰氛围灯上的应用方案解析

随着智能汽车的快速发展&#xff0c;车载语音交互技术逐渐成为提升驾驶体验的关键技术之一。传统的汽车内饰氛围灯语音识别系统往往依赖于手动操作&#xff0c;不仅操作繁琐&#xff0c;而且在驾驶过程中容易分散驾驶员的注意力。因此&#xff0c;开发一种高效、便捷的汽车内饰…

OpenAI gym: when is reset required?

题意&#xff1a;“OpenAI Gym: 什么时候需要重置&#xff1f;” 问题背景&#xff1a; Although I can manage to get the examples and my own code to run, I am more curious about the real semantics / expectations behind OpenAI gym API, in particular Env.reset() …

基于网格尺度的上海市人口分布空间聚集特征分析与冷热点识别

在上篇文章提到了同一研究空间在不同尺度下的观察可能会带来不同的见解和发现&#xff0c;这次我们把尺度缩放到网格&#xff0c;来看网格尺度下的空间自相关性、高/低聚类&#xff0c;这些&#xff0c;因为尺度缩放到网格尺度了&#xff0c;全国这个行政区范围就显的太大了&am…

Python采集网页数据:八招全解

在信息时代&#xff0c;海量的数据日益成为企业和个人获取商业价值的重要手段。而获取这些数据的方式之一就是通过网络爬虫技术采集网络上的各种信息&#xff0c;对于 Python 程序员来说&#xff0c;这项工作并不困难。本文将从八个方面&#xff0c;带你了解如何使用 Python 采…

查找技术与平衡查找树

目录 引言 查找技术的重要性 顺序查找 顺序查找的优缺点对比 二分查找 二分查找的步骤总结 哈希查找 哈希函数设计与冲突解决 平衡查找树 二叉搜索树、AVL树与红黑树 平衡查找树的插入与删除操作 平衡查找树的应用场景 总结与应用 综合实例分析 引言 查找是计算机…

算法训练营三刷(Java) | 第六天~第十一天

算法训练营三刷&#xff08;Java&#xff09; | 第六天~第十一天 第六天 LeetCode 242 有效的字母异位词 解题思路&#xff1a; 数组哈希记录每个字幕出现的次数&#xff0c;然后进行比较。Java中字符串取下标i处字符可以使用charAt成员函数也可以转化为字符数组之后用数组的…

三菱PLC数据 转IEC61850项目案例

目录 1 案例说明 2 VFBOX网关工作原理 3 准备工作 4 网关采集三菱PLC数据 5 用IEC61850协议转发数据 6 网关使用多个逻辑设备和逻辑节点的方法 7 其他说明 8 案例总结 1 案例说明 设置vfbox网关采集三菱PLC数据把采集的数据转成IEC61850协议转发给其他系统。 2 VFBOX网关工…

【Python大语言模型系列】如何在LangChain中使用ReAct构建AI Agent(案例+源码)

一、引言 当前&#xff0c;在各个大厂纷纷卷LLM的情况下&#xff0c;各自都借助自己的LLM推出了自己的AI Agent&#xff0c;比如字节的Coze&#xff0c;百度的千帆等&#xff0c;还有开源的Dify。你是否想知道其中的原理&#xff1f;是否想过自己如何实现一套AI Agent&#xff…

联想凌拓发布多款新一代AI数据管理解决方案

联想凌拓发布多款新一代AI数据管理解决方案 联想凌拓正式宣布推出 NetApp AFF C 系列、 NetApp ASA A 系列、 NetApp ASA C 系列、Lenovo ThinkSystem DG系列、Lenovo ThinkSystem DM3010H企业级存储阵列及MagnaScale数据管理平台V4.0全面升级&#xff0c;让企业应用更简便、更…