当前位置: 首页 > news >正文

【笔记】书生·浦语大模型实战营——第三课(基于 InternLM 和 LangChain 搭建你的知识库)

【参考:tutorial/langchain at main · InternLM/tutorial】
【参考:(3)基于 InternLM 和 LangChain 搭建你的知识库_哔哩哔哩_bilibili-【OpenMMLab】】

笔记

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

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

在这里插入图片描述

基础作业

这里需要等好几分钟才行
在这里插入图片描述
bug:
碰到pandas相关报错就卸载重装
输出文字乱码:重新生成向量文件 python create_db.py

在这里插入图片描述

在这里插入图片描述

  • create_db.py
# 首先导入所需第三方库
from langchain.document_loaders import UnstructuredFileLoader
from langchain.document_loaders import UnstructuredMarkdownLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.embeddings.huggingface import HuggingFaceEmbeddings
from tqdm import tqdm
import os# 获取文件路径函数
def get_files(dir_path):# args:dir_path,目标文件夹路径file_list = []for filepath, dirnames, filenames in os.walk(dir_path):# os.walk 函数将递归遍历指定文件夹for filename in filenames:# 通过后缀名判断文件类型是否满足要求if filename.endswith(".md"):# 如果满足要求,将其绝对路径加入到结果列表file_list.append(os.path.join(filepath, filename))elif filename.endswith(".txt"):file_list.append(os.path.join(filepath, filename))return file_list# 加载文件函数
def get_text(dir_path):# args:dir_path,目标文件夹路径# 首先调用上文定义的函数得到目标文件路径列表file_lst = get_files(dir_path)# docs 存放加载之后的纯文本对象docs = []# 遍历所有目标文件for one_file in tqdm(file_lst):file_type = one_file.split('.')[-1]if file_type == 'md':loader = UnstructuredMarkdownLoader(one_file)elif file_type == 'txt':loader = UnstructuredFileLoader(one_file)else:# 如果是不符合条件的文件,直接跳过continuedocs.extend(loader.load())return docs# 目标文件夹
tar_dir = ["/root/data/InternLM","/root/data/InternLM-XComposer","/root/data/lagent","/root/data/lmdeploy","/root/data/opencompass","/root/data/xtuner"
]# 加载目标文件
docs = []
for dir_path in tar_dir:docs.extend(get_text(dir_path))# 对文本进行分块
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=150)
split_docs = text_splitter.split_documents(docs)# 加载开源词向量模型
embeddings = HuggingFaceEmbeddings(model_name="/root/data/model/sentence-transformer")# 构建向量数据库
# 定义持久化路径
persist_directory = 'data_base/vector_db/chroma'
# 加载数据库
vectordb = Chroma.from_documents(documents=split_docs,embedding=embeddings,persist_directory=persist_directory  # 允许我们将persist_directory目录保存到磁盘上
)
# 将加载的向量数据库持久化到磁盘上
vectordb.persist()
  • LLM.py
from langchain.llms.base import LLM
from typing import Any, List, Optional
from langchain.callbacks.manager import CallbackManagerForLLMRun
from transformers import AutoTokenizer, AutoModelForCausalLM
import torchclass InternLM_LLM(LLM):# 基于本地 InternLM 自定义 LLM 类tokenizer : AutoTokenizer = Nonemodel: AutoModelForCausalLM = Nonedef __init__(self, model_path :str):# model_path: InternLM 模型路径# 从本地初始化模型super().__init__()print("正在从本地加载模型...")self.tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)self.model = AutoModelForCausalLM.from_pretrained(model_path, trust_remote_code=True).to(torch.bfloat16).cuda()self.model = self.model.eval()print("完成本地模型的加载")def _call(self, prompt : str, stop: Optional[List[str]] = None,run_manager: Optional[CallbackManagerForLLMRun] = None,**kwargs: Any):# 重写调用函数 (这里可以随意改动)system_prompt = """You are an AI assistant whose name is InternLM (书生·浦语).- InternLM (书生·浦语) is a conversational language model that is developed by Shanghai AI Laboratory (上海人工智能实验室). It is designed to be helpful, honest, and harmless.- InternLM (书生·浦语) can understand and communicate fluently in the language chosen by the user such as English and 中文."""messages = [(system_prompt, '')]response, history = self.model.chat(self.tokenizer, prompt , history=messages)return response@propertydef _llm_type(self) -> str:return "InternLM"
  • web_demo.py

from langchain.vectorstores import Chroma
from langchain.embeddings.huggingface import HuggingFaceEmbeddings
import os
from LLM import InternLM_LLM
from langchain.prompts import PromptTemplate
from langchain.chains import RetrievalQAdef load_chain():# 加载问答链# 定义 Embeddingsembeddings = HuggingFaceEmbeddings(model_name="/root/data/model/sentence-transformer")# 向量数据库持久化路径persist_directory = 'data_base/vector_db/chroma'# 加载数据库vectordb = Chroma(persist_directory=persist_directory,  # 允许我们将persist_directory目录保存到磁盘上embedding_function=embeddings)# 加载自定义 LLMllm = InternLM_LLM(model_path = "/root/data/model/Shanghai_AI_Laboratory/internlm-chat-7b")# 定义一个 Prompt Templatetemplate = """使用以下上下文来回答最后的问题。如果你不知道答案,就说你不知道,不要试图编造答案。尽量使答案简明扼要。总是在回答的最后说“谢谢你的提问!”。{context}问题: {question}有用的回答:"""QA_CHAIN_PROMPT = PromptTemplate(input_variables=["context","question"],template=template)# 运行 chainqa_chain = RetrievalQA.from_chain_type(llm,retriever=vectordb.as_retriever(),return_source_documents=True,chain_type_kwargs={"prompt":QA_CHAIN_PROMPT})return qa_chainclass Model_center():"""存储检索问答链的对象 """def __init__(self):# 构造函数,加载检索问答链self.chain = load_chain()def qa_chain_self_answer(self, question: str, chat_history: list = []):"""调用问答链进行回答"""if question == None or len(question) < 1:return "", chat_historytry:chat_history.append((question, self.chain({"query": question})["result"]))# 将问答结果直接附加到问答历史中,Gradio 会将其展示出来return "", chat_historyexcept Exception as e:return e, chat_historyimport gradio as gr# 实例化核心功能对象
model_center = Model_center()
# 创建一个 Web 界面
block = gr.Blocks()
with block as demo:with gr.Row(equal_height=True):   with gr.Column(scale=15):# 展示的页面标题gr.Markdown("""<h1><center>InternLM</center></h1><center>书生浦语</center>""")with gr.Row():with gr.Column(scale=4):# 创建一个聊天机器人对象chatbot = gr.Chatbot(height=450, show_copy_button=True)# 创建一个文本框组件,用于输入 prompt。msg = gr.Textbox(label="Prompt/问题")with gr.Row():# 创建提交按钮。db_wo_his_btn = gr.Button("Chat")with gr.Row():# 创建一个清除按钮,用于清除聊天机器人组件的内容。clear = gr.ClearButton(components=[chatbot], value="Clear console")# 设置按钮的点击事件。当点击时,调用上面定义的 qa_chain_self_answer 函数,并传入用户的消息和聊天历史记录,然后更新文本框和聊天机器人组件。db_wo_his_btn.click(model_center.qa_chain_self_answer, inputs=[msg, chatbot], outputs=[msg, chatbot])gr.Markdown("""提醒:<br>1. 初始化数据库时间可能较长,请耐心等待。2. 使用中如果出现异常,将会在文本输入框进行展示,请不要惊慌。 <br>""")
gr.close_all()
# 直接启动
demo.launch()

进阶作业

选择一个垂直领域,收集该领域的专业资料构建专业知识库,并搭建专业问答助手,并在 OpenXLab 上成功部署(截图,并提供应用地址)

目前待定

相关文章:

  • 【Flink精讲】Flink数据延迟处理
  • 【前端】使用javascript开发一个在线RGB颜色转换
  • wpf的资源路径
  • 基于ssm运动会管理系统的设计与实现 【附源码】
  • 少儿编程 2023年12月中国电子学会图形化编程等级考试Scratch编程三级真题解析(判断题)
  • 秋招阿里巴巴java笔试试题-精
  • GitHub pull request(傻瓜式入门版)
  • STM32F103RCT6使用数据手册及应用示例程序分享
  • 【Spring Boot】SpringMVC入门
  • 【测试发布】
  • C语言基础语法跟练
  • Linux网络配置与抓包工具介绍
  • Pytorch将标签转为One-Hot编码
  • 模型的权值平均的原理和Pytorch的实现
  • Spark与云存储的集成:S3、Azure Blob Storage
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • Akka系列(七):Actor持久化之Akka persistence
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • echarts花样作死的坑
  • Linux后台研发超实用命令总结
  • Python十分钟制作属于你自己的个性logo
  • Redis在Web项目中的应用与实践
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • springboot_database项目介绍
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • text-decoration与color属性
  • webpack项目中使用grunt监听文件变动自动打包编译
  • Windows Containers 大冒险: 容器网络
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 三分钟教你同步 Visual Studio Code 设置
  • 深度学习中的信息论知识详解
  • 使用SAX解析XML
  • 我这样减少了26.5M Java内存!
  • 详解移动APP与web APP的区别
  • 用jquery写贪吃蛇
  • python最赚钱的4个方向,你最心动的是哪个?
  • 从如何停掉 Promise 链说起
  • # include “ “ 和 # include < >两者的区别
  • #ifdef 的技巧用法
  • (八)Flask之app.route装饰器函数的参数
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (二十四)Flask之flask-session组件
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (过滤器)Filter和(监听器)listener
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • (转载)OpenStack Hacker养成指南
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .net连接MySQL的方法
  • // an array of int
  • /dev下添加设备节点的方法步骤(通过device_create)
  • @Autowired注解的实现原理
  • @PreAuthorize注解
  • [Android实例] 保持屏幕长亮的两种方法 [转]