大模型学习与实践笔记(五)

news2024/12/23 9:29:23

一、环境配置

1. huggingface 镜像下载 sentence-transformers 开源词向量模型

import os

# 设置环境变量
os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'

# 下载模型
os.system('huggingface-cli download --resume-download sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 --local-dir /root/data/model/sentence-transformer')

2.下载 NLTK 相关资源

git clone https://gitee.com/yzy0612/nltk_data.git  --branch gh-pages

cd nltk_data

wget -O averaged_perceptron_tagger.zip https://raw.githubusercontent.com/nltk/nltk_data/gh-pages/packages/taggers/averaged_perceptron_tagger.zip

wget -O punkt.zip https://raw.githubusercontent.com/nltk/nltk_data/gh-pages/packages/tokenizers/punkt.zip

二、检索库构建

1.构建知识向量库

# 首先导入所需第三方库
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:
            # 如果是不符合条件的文件,直接跳过
            continue
        docs.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()

运行效果

2.将InternLM 接入 LangChain

from langchain.llms.base import LLM
from typing import Any, List, Optional
from langchain.callbacks.manager import CallbackManagerForLLMRun
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch

class InternLM_LLM(LLM):
    # 基于本地 InternLM 自定义 LLM 类
    tokenizer : AutoTokenizer = None
    model: AutoModelForCausalLM = None

    def __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
        
    @property
    def _llm_type(self) -> str:
        return "InternLM"

3.构建检索问答链

from langchain.vectorstores import Chroma
from langchain.embeddings.huggingface import HuggingFaceEmbeddings
import os

# 定义 Embeddings
embeddings = HuggingFaceEmbeddings(model_name="/root/data/model/sentence-transformer")

# 向量数据库持久化路径
persist_directory = 'data_base/vector_db/chroma'

# 加载数据库
vectordb = Chroma(
    persist_directory=persist_directory, 
    embedding_function=embeddings
)

from LLM import InternLM_LLM
llm = InternLM_LLM(model_path = "/root/model/Shanghai_AI_Laboratory/internlm-chat-7b")
llm.predict("你是谁")

from langchain.prompts import PromptTemplate

# 我们所构造的 Prompt 模板
template = """使用以下上下文来回答最后的问题。如果你不知道答案,就说你不知道,不要试图编造答案。尽量使答案简明扼要。总是在回答的最后说“谢谢你的提问!”。
{context}
问题: {question}
有用的回答:"""

# 调用 LangChain 的方法来实例化一个 Template 对象,该对象包含了 context 和 question 两个变量,在实际调用时,这两个变量会被检索到的文档片段和用户提问填充
QA_CHAIN_PROMPT = PromptTemplate(input_variables=["context","question"],template=template)

from langchain.chains import RetrievalQA

qa_chain = RetrievalQA.from_chain_type(llm,retriever=vectordb.as_retriever(),return_source_documents=True,chain_type_kwargs={"prompt":QA_CHAIN_PROMPT})

# 检索问答链回答效果
question = "什么是InternLM"
result = qa_chain({"query": question})
print("检索问答链回答 question 的结果:")
print(result["result"])

# 仅 LLM 回答效果
result_2 = llm(question)
print("大模型回答 question 的结果:")
print(result_2)

运行效果:

4.gradio 部署

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 RetrievalQA

def load_chain():
    # 加载问答链
    # 定义 Embeddings
    embeddings = 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
    )

    # 加载自定义 LLM
    llm = InternLM_LLM(model_path = "/root/model/Shanghai_AI_Laboratory/internlm-chat-7b")

    # 定义一个 Prompt Template
    template = """使用以下上下文来回答最后的问题。如果你不知道答案,就说你不知道,不要试图编造答
    案。尽量使答案简明扼要。总是在回答的最后说“谢谢你的提问!”。
    {context}
    问题: {question}
    有用的回答:"""

    QA_CHAIN_PROMPT = PromptTemplate(input_variables=["context","question"],template=template)

    # 运行 chain
    qa_chain = RetrievalQA.from_chain_type(llm,retriever=vectordb.as_retriever(),return_source_documents=True,chain_type_kwargs={"prompt":QA_CHAIN_PROMPT})
    
    return qa_chain

class 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_history
        try:
            chat_history.append(
                (question, self.chain({"query": question})["result"]))
            # 将问答结果直接附加到问答历史中,Gradio 会将其展示出来
            return "", chat_history
        except Exception as e:
            return e, chat_history

import 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()

运行效果:

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

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

相关文章

一卡通水控电控开发踩过的坑

最近在做一个项目&#xff0c;是对接一卡通设备的。我一开始只拿到设备和3个文档开局。不知道从哪下手。一步一步踩坑过来。踩了很多没有必要的坑&#xff0c;写出来给有用的人吧。 读卡器怎么用&#xff1f; 有个读卡器&#xff0c;一开始什么软件也不提供。我都不知道是干嘛…

Spring Boot - Application Events 的发布顺序_ApplicationContextInitializedEvent

文章目录 Pre概述Code源码分析 Pre Spring Boot - Application Events 的发布顺序_ApplicationEnvironmentPreparedEvent Spring Boot - Application Events 的发布顺序_ApplicationEnvironmentPreparedEvent 概述 Spring Boot 的广播机制是基于观察者模式实现的&#xff0c…

NLP论文阅读记录 - 05 | 2023 抽象总结与提取总结:实验回顾

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.相关工作2.1 提取方法2.2 抽象方法2.3 数据集 三.本文方法四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结果4.6 细粒度分析 五 总结思考 前言 Abstractive vs. Extractiv…

从头安装与使用一个docker GPU环境

GPU版docker的安装与使用 欢迎使用GPU版docker安装使用说明使用官方教程安装docker新建一个GPU版docker环境调用docker环境执行本地python文件 欢迎使用GPU版docker安装使用说明 使用官方教程安装docker 导入源仓库的GPG key curl -fsSL https://download.docker.com/linux/…

RTL编码(1)——概述

一、RTL级描述 RTL&#xff08;Register Transfer Level&#xff09;级&#xff1a;寄存器&#xff0b;组合逻辑&#xff0c;其功能与时序用Verilog HDL&#xff08;以下简称Verilog&#xff09;或VHDL代码描述。 RTL描述包含了同步数字电路最重要的三个特征&#xff1a;组合逻…

水产冷链物流行业零下25℃库架一体 海格里斯HEGERLS四向穿梭式冷藏冷库智能密集仓

随着国内外仓储物流整体规模和低温产品消费需求的稳步增长&#xff0c;冷链市场应用潜力不断释放。在传统“货架叉车”的方式下&#xff0c;货物、人员及机械设备不断进出&#xff0c;容易造成温度波动&#xff0c;导致冷量流失。立体冷库则以更高密度、更具成本效益的方式&…

electron+vue网页直接播放RTSP视频流?

目前大部分摄像头都支持RTSP协议&#xff0c;但是在浏览器限制&#xff0c;最新版的浏览器都不能直接播放RTSP协议&#xff0c;Electron 桌面应用是基于 Chromium 内核的&#xff0c;所以也不能直接播放RTSP&#xff0c;但是我们又有这个需求怎么办呢&#xff1f; 市场上的方案…

【动态规划】 【字典树】C++算法:472 连接词

作者推荐 【动态规划】458:可怜的小猪 涉及知识点 动态规划 字典树 LeetCode472 连接词 给你一个 不含重复 单词的字符串数组 words &#xff0c;请你找出并返回 words 中的所有 连接词 。 连接词 定义为&#xff1a;一个完全由给定数组中的至少两个较短单词&#xff08;不…

jenkins 自由风格部署vue项目,参数化构建vue项目

1. 丢弃旧的构建 2. 是否需要install 3. git 4. 配置node16: 5. 脚本&#xff1a; 脚本&#xff1a; #进入Jenkins工作空间下项目目录 cd /var/lib/jenkins/workspace/你的任务名称 node -v #检测node版本&#xff08;此条命令非必要&#xff09; npm -v #检测npm版本&#x…

【开源】基于JAVA语言的康复中心管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 普通用户模块2.2 护工模块2.3 管理员模块 三、系统展示四、核心代码4.1 查询康复护理4.2 新增康复训练4.3 查询房间4.4 查询来访4.5 新增用药 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的康复中…

Linux ----冯诺依曼体系结构与操作系统

目录 前言 一、冯诺依曼体系结构 二、为什么选择冯诺依曼体系结构&#xff1f; 三、使用冯诺依曼结构解释问题 问题1&#xff1a; 问题2: 四、操作系统 1.操作系统是什么 2.为什么需要操作系统 3.操作系统怎样管理的 4.如何给用户提供良好环境 五、我们是怎样调用系…

imgaug库指南(18):从入门到精通的【图像增强】之旅

引言 在深度学习和计算机视觉的世界里&#xff0c;数据是模型训练的基石&#xff0c;其质量与数量直接影响着模型的性能。然而&#xff0c;获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此&#xff0c;数据增强技术应运而生&#xff0c;成为了解决这一问题的…

CodeQL基本使用

0x01 安装codeql 去github下载一个对应版本的codeql捆绑包。 https://github.com/github/codeql-action/releases 然后解压&#xff0c;这里我是解压到桌面 然后用添加到环境变量中 然后在任意位置输入codeql命令&#xff0c;如果能有以下提示就表示安装成功 然后下载vscode…

戴尔服务器有8条内存条,开机有一条内存条自检提示出错,可以不用管他吗,有影响吗?

环境 戴尔R730 问题描述 戴尔服务器有8条内存条&#xff0c;开机有一条内存条自检提示出错&#xff0c;可以不用管他吗&#xff0c;有影响吗&#xff1f; 提示B1内存有问题 解决方案 不能&#xff0c;有影响&#xff0c;安装系统时卡住在启动节目无法正常安装&#xff0c;…

mysql原理--redo日志1

1.redo日志是个啥 我们知道 InnoDB 存储引擎是以页为单位来管理存储空间的&#xff0c;我们进行的增删改查操作其实本质上都是在访问页面&#xff08;包括读页面、写页面、创建新页面等操作&#xff09;。我们前边唠叨 Buffer Pool 的时候说过&#xff0c;在真正访问页面之前&a…

神州数码集团荣获“TiDB 社区最佳贡献企业”

日前&#xff0c;神州数码在 TiDB 开源社区中获得了“TiDB 社区最佳贡献企业”奖。PingCAP 颁发该奖项以认可生态企业在社区中的卓越贡献和积极参与。 神州数码与 PingCAP 最早于 2020 年 12 月 28 日进行战略合作&#xff0c;基于全球领先的开源分布式关系型数据库 TiDB&…

详细分析Java中的@JsonFormat注解和@DateTimeFormat注解

目录 前言1. JsonFormat注解2. DateTimeFormat注解3. Demo3.1 无注解3.2 有注解 4. 拓展 前言 下文中涉及MybatisPlus的逻辑删除的知识&#xff0c;可看我之前这篇文章&#xff1a;详细讲解MybatisPlus实现逻辑删除 对应的Navicat设置数据库最新时间可看我这篇文章&#xff1…

修改SSH默认端口,使SSH连接更安全

以CentOS7.9为例&#xff1a; 1、修改配置文件 vi /etc/ssh/sshd_config 2、远程电脑可连接&#xff0c;暂时将SELinux关闭 # 查询状态 getenforce # 关闭 setenforce 0 # 开启 setenforce 1 3、SELinux设置&#xff08;如果启用&#xff09;&#xff0c;semanage管理工具安…

雷达信号处理——恒虚警检测(CFAR)

雷达信号处理的流程 雷达信号处理的一般流程&#xff1a;ADC数据——1D-FFT——2D-FFT——CFAR检测——测距、测速、测角。 雷达目标检测 首先要搞清楚什么是检测&#xff0c;检测就是判断有无。雷达在探测的时候&#xff0c;会出现很多峰值&#xff0c;这些峰值有可能是目标…

GPT function calling v2

原文&#xff1a;GPT function calling v2 - 知乎 OpenAI在2023年11月10号举行了第一次开发者大会&#xff08;OpenAI DevDays&#xff09;&#xff0c;其中介绍了很多新奇有趣的新功能和新应用&#xff0c;而且更新了一波GPT的API&#xff0c;在1.0版本后的API调用与之前的0.…