AI大模型探索之路-实战篇3:基于私有模型GLM-企业级知识库开发实战

本文主要是介绍AI大模型探索之路-实战篇3:基于私有模型GLM-企业级知识库开发实战,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 概述
  • 一、本地知识库核心架构回顾(RAG)
    • 1. 知识数据向量化
    • 2. 知识数据检索返回
  • 二、大模型选择
    • 1. 模型选择标准
    • 2. ChatGLM3-6B
  • 三、Embedding模型选择
  • 四、改造后的技术选型
  • 五、资源准备
    • 1. 安装git-lfs
    • 2. 下载GLM模型
    • 3. 下载Embeding模型
  • 六、代码落地实践
    • 1. Embedding代码改造
    • 2. LLM代码改造
    • 3. 测试运行
  • 总结


前言

在当今信息时代,数据已经成为企业的核心资产之一。对于许多企业而言,信息安全和私密性是至关重要的,因此对外部服务提供的数据接口存在天然的警惕性。因此常规的基于在线大模型接口落地企业知识库项目,很难满足这些企业的安全需求。面对这样的挑战,只有私有化的部署方案才能满足企业需求;

在实战篇2中《AI大模型探索之路-实战篇2:基于CVP架构-企业级知识库实战落地》,设计实现了基于CVP架构的企业知识库。本篇文章中将对企业知识库进行进一步的改造升级,以满足企业安全性方面的需求;利用开源的GLM大模型,进行私有化部署,重新设计落地整个企业级知识库。

概述

在构建企业知识库的过程中,通常会涉及两种类型的大模型API:嵌入向量化模型和LLM语言分析处理模型。为了确保企业的安全性需求得到满足,我们采用开源的GLM大模型进行私有化部署,并重新设计了整个知识库机器人的架构。接下来,我们将深入探讨这一改造升级过程。
在这里插入图片描述

一、本地知识库核心架构回顾(RAG)

1. 知识数据向量化

首先,通过文档加载器加载本地知识库数据,然后使用文本拆分器将大型文档拆分为较小的块,便于后续处理。接着,对拆分的数据块进行Embedding向量化处理,最后将向量化后的数据存储到向量数据库中以便于检索。
在这里插入图片描述

2. 知识数据检索返回

根据用户输入,使用检索器从向量数据库中检索相关的数据块。然后,利用包含问题和检索到的数据的提示,交给ChatModel / LLM(聊天模型/语言生成模型)生成答案。
在这里插入图片描述

二、大模型选择

1. 模型选择标准

1)开源的:需要选择开源的项目方便自主扩展。
2)高性能的:选择各方面性能指标比较好的,能够提升用户体验。
3)可商用的:在不增加额外成本的前提下,保证模型的商用可行性。
4)低成本部署的:部署时要能够以最低成本代价部署运行知识库,降低公司成本开支。
5)中文支持:需要选择对我母语中文支持性比较好的模型,能够更好的解析理解中文语义。

2. ChatGLM3-6B

ChatGLM3-6B 是 ChatGLM3 系列中的开源模型,也是目前各方面性能比较突出的大模型:
1)更强大的基础模型: ChatGLM3-6B 的基础模型 ChatGLM3-6B-Base 采用了更多样的训练数据、更充分的训练步数和更合理的训练策略。在语义、数学、推理、代码、知识等不同角度的数据集上测评显示,* ChatGLM3-6B-Base 具有在 10B 以下的基础模型中最强的性能*。
2)更完整的功能支持: ChatGLM3-6B 采用了全新设计的 Prompt 格式 ,除正常的多轮对话外。同时原生支持工具调用(Function Call)、代码执行(Code Interpreter)和 Agent 任务等复杂场景。
3)更全面的开源序列: 除了对话模型 ChatGLM3-6B 外,还开源了基础模型 ChatGLM3-6B-Base 、长文本对话模型 ChatGLM3-6B-32K 和进一步强化了对于长文本理解能力的 ChatGLM3-6B-128K。

三、Embedding模型选择

我们要选择一个开源免费的、中文支持性比较好的,场景合适的,各方面排名靠前的嵌入模型。
MTEB排行榜是衡量文本嵌入模型在各种嵌入任务上性能的重要基准;可从排行榜中选相应的Enbedding模型;
在这里插入图片描述

本次从中选择使用比较广泛的 bge-large-zh-v1.5 (同样也是智谱AI的开源模型)
在这里插入图片描述

四、改造后的技术选型

1)LLM模型:ChatGLM3-6B
2)Embedding模型:bge-large-zh-v1.5
3)应用开发框架:LangChain
4)向量数据库:FAISS/pinecone/Milvus
5)WEB框架:streamlit/gradio

五、资源准备

将 Hugging Face Hub 上的预训练模型,下载到本地使用更方便,性能更快。

1. 安装git-lfs

1)需要先安装Git LFS ,Ubuntu系统操作命令:

curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
sudo apt-get install git-lfs

在这里插入图片描述

Centos命令参考:

curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.rpm.sh | sudo bash
sudo yum install git-lfs

2)执行:git lfs install

在这里插入图片描述

2. 下载GLM模型

下载使用huggingface上的大模型

git clone https://huggingface.co/THUDM/chatglm3-6b

在这里插入图片描述

注意:下载后记得和huggingface上的文件列表对比,看看是否有缺失,缺少了单独下载补全。

3. 下载Embeding模型

下载huggingface上的词嵌入模型

git clone https://huggingface.co/BAAI/bge-large-zh-v1.5

在这里插入图片描述

注意:下载后记得和huggingface上的文件列表对比,看看是否有缺失,缺少了单独下载补全。

对比后发现果然少了pytorch_model.bin文件
在这里插入图片描述

手动单独下载pytorch_model.bin文件

wget https://huggingface.co/BAAI/bge-large-zh-v1.5/resolve/main/pytorch_model.bin

结果下载超时了😅😅😅
在这里插入图片描述

后发现国内gitee上有一个hf-models; 专门放的hugginface的模型。😄
在这里插入图片描述

改用gitee地址下载

git clone https://gitee.com/hf-models/bge-large-zh-v1.5.git

果然皇天不负苦心人。。。。😀
在这里插入图片描述

六、代码落地实践

1. Embedding代码改造

将原来的openai嵌入模型

def get_openaiEmbedding_model():return OpenAIEmbeddings(openai_api_key=Keys.OPENAI_API_KEY,openai_api_base=Keys.OPENAI_API_BASE)

改造替换为私有嵌入模型:

# 私有嵌入模型部署
embedding_model_dict = {#"text2vec3": "shibing624/text2vec-base-chinese",#"baaibge": "BAAI/bge-large-zh-v1.5",#"text2vec3": "/root/autodl-tmp/text2vec-base-chinese","baaibge": "/root/autodl-tmp/bge-large-zh-v1.5",
}def get_embedding_model(model_name="baaibge"):"""加载embedding模型:param model_name::return:"""encode_kwargs = {"normalize_embeddings": False}model_kwargs = {"device": "cuda:0"}print(embedding_model_dict[model_name])return HuggingFaceEmbeddings(model_name=embedding_model_dict[model_name],model_kwargs=model_kwargs,encode_kwargs=encode_kwargs)

2. LLM代码改造

将原来的OpenAI的LLM模型

def get_openai_model():llm_model = ChatOpenAI(openai_api_key=Keys.OPENAI_API_KEY,model_name=Keys.MODEL_NAME,openai_api_base=Keys.OPENAI_API_BASE,temperature=0)return llm_model

改造为GLM的LLM模型

def get_chatglm3_6b_model(model_path=keys.Keys.CHATGLM3_MODEL_PATH):MODEL_PATH = os.environ.get('MODEL_PATH', model_path)llm = chatglm3()llm.load_model(model_name_or_path=MODEL_PATH)return llm

chatglm3说明:由于langchain中暂未集成ChatGLM,因此需要自己封装一个ChatGLM的类

import json
from langchain.llms.base import LLM
from transformers import AutoTokenizer, AutoModel, AutoConfig
from typing import List, Optional
import os,yamlfrom models.utils import tool_config_from_fileclass chatglm3(LLM):max_token: int = 8192do_sample: bool = False#do_sample: bool = Truetemperature: float = 0.8top_p = 0.8tokenizer: object = Nonemodel: object = Nonehistory: List = []tool_names: List = []has_search: bool = Falsedef __init__(self):super().__init__()@propertydef _llm_type(self) -> str:return "ChatGLM3"def load_model(self, model_name_or_path=None):model_config = AutoConfig.from_pretrained(model_name_or_path,trust_remote_code=True)self.tokenizer = AutoTokenizer.from_pretrained(model_name_or_path,trust_remote_code=True)self.model = AutoModel.from_pretrained(model_name_or_path, config=model_config, trust_remote_code=True).half().cuda()# def tool_config_from_file(tool_name, directory="../Tool/"):#     """search tool yaml and return json format"""#     for filename in os.listdir(directory):#         if filename.endswith('.yaml') and tool_name in filename:#             file_path = os.path.join(directory, filename)#             with open(file_path, encoding='utf-8') as f:#                 return yaml.safe_load(f)#     return Nonedef _tool_history(self, prompt: str):ans = []tool_prompts = prompt.split("You have access to the following tools:\n\n")[0].split("\n\nUse a json blob")[0].split("\n")tool_names = [tool.split(":")[0] for tool in tool_prompts]self.tool_names = tool_namestools_json = []for i, tool in enumerate(tool_names):tool_config = tool_config_from_file(tool)if tool_config:tools_json.append(tool_config)else:ValueError(f"Tool {tool} config not found! It's description is {tool_prompts[i]}")ans.append({"role": "system","content": "Answer the following questions as best as you can. You have access to the following tools:","tools": tools_json})query = f"""{prompt.split("Human: ")[-1].strip()}"""return ans, querydef _extract_observation(self, prompt: str):return_json = prompt.split("Observation: ")[-1].split("\nThought:")[0]self.history.append({"role": "observation","content": return_json})returndef _extract_tool(self):if len(self.history[-1]["metadata"]) > 0:metadata = self.history[-1]["metadata"]content = self.history[-1]["content"]if "tool_call" in content:for tool in self.tool_names:if tool in metadata:input_para = content.split("='")[-1].split("'")[0]action_json = {"action": tool,"action_input": input_para}self.has_search = Truereturn f"""Action: ```{json.dumps(action_json, ensure_ascii=False)}
```"""final_answer_json = {"action": "Final Answer","action_input": self.history[-1]["content"]}self.has_search = Falsereturn f"""Action: ```{json.dumps(final_answer_json, ensure_ascii=False)}```"""def _call(self, prompt: str, history: List = [], stop: Optional[List[str]] = ["<|user|>"]):print("======")print(prompt)print("======")if not self.has_search:self.history, query = self._tool_history(prompt)else:self._extract_observation(prompt)query = ""# print("======")# print(history)# print("======")_, self.history = self.model.chat(self.tokenizer,query,history=self.history,do_sample=self.do_sample,max_length=self.max_token,temperature=self.temperature,)response = self._extract_tool()history.append((prompt, response))return response

3. 测试运行

在knowledge_base_v2 下运行:streamlit run knowledge_chatbot.py
在这里插入图片描述

上传知识库,再进行对话测试
在这里插入图片描述


总结

通过私有化部署的企业知识库项目已经成功实践落地。在未来的学习中,我们将进一步探索如何优化整个架构,例如利用微调技术改善知识库性能,优化Prompt的设计,集成更强大的外挂工具以满足特殊业务需求,以及如何加强大模型应用的安全性,包括加入模型审查流程等。

👉系列篇章:AI大模型探索之路-实战篇2:基于CVP架构-企业级知识库实战落地
🔖更多专栏系列文章:AIGC-AI大模型探索之路

文章若有瑕疵,恳请不吝赐教;若有所触动或助益,还望各位老铁多多关注并给予支持。

这篇关于AI大模型探索之路-实战篇3:基于私有模型GLM-企业级知识库开发实战的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

springboot项目redis缓存异常实战案例详解(提供解决方案)

《springboot项目redis缓存异常实战案例详解(提供解决方案)》redis基本上是高并发场景上会用到的一个高性能的key-value数据库,属于nosql类型,一般用作于缓存,一般是结合数据... 目录缓存异常实践案例缓存穿透问题缓存击穿问题(其中也解决了穿透问题)完整代码缓存异常实践案例Red

Spring AI 实现 STDIO和SSE MCP Server的过程详解

《SpringAI实现STDIO和SSEMCPServer的过程详解》STDIO方式是基于进程间通信,MCPClient和MCPServer运行在同一主机,主要用于本地集成、命令行工具等场景... 目录Spring AI 实现 STDIO和SSE MCP Server1.新建Spring Boot项目2.a

Spring Boot拦截器Interceptor与过滤器Filter深度解析(区别、实现与实战指南)

《SpringBoot拦截器Interceptor与过滤器Filter深度解析(区别、实现与实战指南)》:本文主要介绍SpringBoot拦截器Interceptor与过滤器Filter深度解析... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实

基于C#实现MQTT通信实战

《基于C#实现MQTT通信实战》MQTT消息队列遥测传输,在物联网领域应用的很广泛,它是基于Publish/Subscribe模式,具有简单易用,支持QoS,传输效率高的特点,下面我们就来看看C#实现... 目录1、连接主机2、订阅消息3、发布消息MQTT(Message Queueing Telemetr

Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例

《Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例》本文介绍Nginx+Keepalived实现Web集群高可用负载均衡的部署与测试,涵盖架构设计、环境配置、健康检查、... 目录前言一、架构设计二、环境准备三、案例部署配置 前端 Keepalived配置 前端 Nginx

Python日期和时间完全指南与实战

《Python日期和时间完全指南与实战》在软件开发领域,‌日期时间处理‌是贯穿系统设计全生命周期的重要基础能力,本文将深入解析Python日期时间的‌七大核心模块‌,通过‌企业级代码案例‌揭示最佳实践... 目录一、背景与核心价值二、核心模块详解与实战2.1 datetime模块四剑客2.2 时区处理黄金法

SpringBoot实现接口数据加解密的三种实战方案

《SpringBoot实现接口数据加解密的三种实战方案》在金融支付、用户隐私信息传输等场景中,接口数据若以明文传输,极易被中间人攻击窃取,SpringBoot提供了多种优雅的加解密实现方案,本文将从原... 目录一、为什么需要接口数据加解密?二、核心加解密算法选择1. 对称加密(AES)2. 非对称加密(R

Spring Boot集成Logback终极指南之从基础到高级配置实战指南

《SpringBoot集成Logback终极指南之从基础到高级配置实战指南》Logback是一个可靠、通用且快速的Java日志框架,作为Log4j的继承者,由Log4j创始人设计,:本文主要介绍... 目录一、Logback简介与Spring Boot集成基础1.1 Logback是什么?1.2 Sprin

Linux高并发场景下的网络参数调优实战指南

《Linux高并发场景下的网络参数调优实战指南》在高并发网络服务场景中,Linux内核的默认网络参数往往无法满足需求,导致性能瓶颈、连接超时甚至服务崩溃,本文基于真实案例分析,从参数解读、问题诊断到优... 目录一、问题背景:当并发连接遇上性能瓶颈1.1 案例环境1.2 初始参数分析二、深度诊断:连接状态与

C#实现高性能Excel百万数据导出优化实战指南

《C#实现高性能Excel百万数据导出优化实战指南》在日常工作中,Excel数据导出是一个常见的需求,然而,当数据量较大时,性能和内存问题往往会成为限制导出效率的瓶颈,下面我们看看C#如何结合EPPl... 目录一、技术方案核心对比二、各方案选型建议三、性能对比数据四、核心代码实现1. MiniExcel