ubuntu 部署 ChatGLM-6B 完整流程 模型量化 Nvidia

news2024/12/25 9:13:13

ubuntu 部署 ChatGLM-6B 完整流程 模型量化 Nvidia

  • 环境与设备
    • 环境准备
    • 克隆模型
    • 代码部署 ChatGLM-6B
    • 完整代码

ChatGLM-6B 是一个开源的、支持中英双语的对话语言模型,基于 General Language Model (GLM) 架构,具有 62 亿参数。结合模型量化技术,用户可以在消费级的显卡上进行本地部署(INT4 量化级别下最低只需 6GB 显存)。 ChatGLM-6B 使用了和 ChatGPT 相似的技术,针对中文问答和对话进行了优化。经过约 1T 标识符的中英双语训练,辅以监督微调、反馈自助、人类反馈强化学习等技术的加持,62 亿参数的 ChatGLM-6B 已经能生成相当符合人类偏好的回答

本篇文章将介绍ubuntu 部署 ChatGLM-6B 完整流程 模型量化 Nvidia GUP

希望能写一些简单的教程和案例分享给需要的人

环境与设备

系统:Ubuntu 22.04.2 LTS (ubuntu 就行)
设备:Nvidia GeForce RTX 4090 (英伟达 就行)

以下是一些推荐的消费级显卡:

  1. Nvidia GeForce RTX 3080: RTX 3080 是一款性能出色的显卡,适用于高质量游戏和深度学习任务。它提供了强大的图形性能和 CUDA 核心,能够满足许多高性能计算需求。

  2. AMD Radeon RX 6800 XT: 如果你对 AMD 的显卡感兴趣,RX 6800 XT 是一款强大的选择。它具有出色的游戏性能和计算能力,适用于多种应用场景。

  3. Nvidia GeForce RTX 3070: RTX 3070 是一款性价比较高的显卡,它在性能和价格之间找到了很好的平衡。它适用于游戏、图形设计和一些中等规模的深度学习任务。

环境准备

在开始之前,确保 Ubuntu 系统已经安装了Python和必要的依赖项。

输入下面命令:判断PIP是否安装

 pip --version

输入
如果没安装,就安装 python3-pip

sudo apt update
sudo apt install python3-pip

安装完成后如下图:

在这里插入图片描述

克隆模型

全部都完成后,我们就可以去下载模型了

去下面这个网站,下载模型

https://huggingface.co/THUDM/chatglm2-6b-32k

在这里插入图片描述

点击克隆后,我们需要使用命令:

git lfs install
git clone https://huggingface.co/THUDM/chatglm2-6b-32k

这个时候,可能会遇到报错:需要安装 git ,还有 git-lfs

在这里插入图片描述

sudo apt install git

sudo apt install git-lfs

这两个都安装完成后,我们再克隆,我这边会到指定的路径克隆,大家自行选择。

克隆成功后,如下图:

在这里插入图片描述

代码部署 ChatGLM-6B

git clone https://github.com/THUDM/ChatGLM-6B.git

在这里插入图片描述

代码克隆下来后,就安装环境 pytorch

PyTorch 是一个开源的机器学习框架,它提供了丰富的工具和库,用于构建和训练各种深度学习模型。它由 Facebook 的人工智能研究院(Facebook AI Research,缩写为FAIR)开发并维护,旨在为研究人员和开发者提供一个灵活、动态的平台来实现各种机器学习任务。

PyTorch 提供了一种动态计算图的机制,这意味着您可以在运行时构建、修改和调整计算图,使其更加灵活和直观。这使得 PyTorch 在实验和原型开发阶段非常有用,因为它能够快速适应不同的数据和模型结构。此外,PyTorch 还具有广泛的神经网络库、优化算法以及用于数据加载和预处理的工具。它也支持 GPU 加速,可以在 NVIDIA CUDA 上利用 GPU 进行高效的计算,加速模型训练过程。总之,PyTorch 是一个受欢迎的机器学习框架,广泛用于深度学习研究、开发和应用。它以其动态计算图、灵活性和易用性而闻名。

直接进入下面网址

https://pytorch.org/

进入页面后,翻到下一页,我这里是ubuntu 所以我这边用预览版最新的 CUDA 12.1
ubuntu

关于CUDA的支持可以通过命令 nvidia-smi 来查看

在这里插入图片描述
我们执行命令

在这里插入图片描述

pip3 install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cu121

等待安装结束

在这里插入图片描述
都按照完成后,进入项目,我这里项目路径是这个 /home/ai/dev/code

cd /home/ai/dev/code
cd /home/ai/dev/code/ChatGLM-6B

然后安装 环境

pip install -r requirements.txt

等待这些都安装完成后,

api.py 文件中的路径:

将原本的:THUDM/chatglm-6b

更换成:/home/ai/dev/model/chatglm2-6b-32k

/home/ai/dev/model/chatglm2-6b-32k

在这里插入图片描述

执行下面命令:

python3 api.py

在这里插入图片描述
测试一下:

curl -X POST "http://127.0.0.1:8000" \
     -H 'Content-Type: application/json' \
     -d '{"prompt": "你好", "history": []}'

在这里插入图片描述

上面是 API 的效果。如果选需要 ui 版本 web_demo.py 这个文件 修改模型路径后,执行:

python3 web_demo.py

修改截图如下:

在这里插入图片描述

方便外网请求的修改地方如下:

在这里插入图片描述

执行结果如下:

在这里插入图片描述

在这里插入图片描述

完整代码

api.py

from fastapi import FastAPI, Request
from transformers import AutoTokenizer, AutoModel
import uvicorn, json, datetime
import torch

DEVICE = "cuda"
DEVICE_ID = "0"
CUDA_DEVICE = f"{DEVICE}:{DEVICE_ID}" if DEVICE_ID else DEVICE


def torch_gc():
    if torch.cuda.is_available():
        with torch.cuda.device(CUDA_DEVICE):
            torch.cuda.empty_cache()
            torch.cuda.ipc_collect()


app = FastAPI()


@app.post("/")
async def create_item(request: Request):
    global model, tokenizer
    json_post_raw = await request.json()
    json_post = json.dumps(json_post_raw)
    json_post_list = json.loads(json_post)
    prompt = json_post_list.get('prompt')
    history = json_post_list.get('history')
    max_length = json_post_list.get('max_length')
    top_p = json_post_list.get('top_p')
    temperature = json_post_list.get('temperature')
    response, history = model.chat(tokenizer,
                                   prompt,
                                   history=history,
                                   max_length=max_length if max_length else 2048,
                                   top_p=top_p if top_p else 0.7,
                                   temperature=temperature if temperature else 0.95)
    now = datetime.datetime.now()
    time = now.strftime("%Y-%m-%d %H:%M:%S")
    answer = {
        "response": response,
        "history": history,
        "status": 200,
        "time": time
    }
    log = "[" + time + "] " + '", prompt:"' + prompt + '", response:"' + repr(response) + '"'
    print(log)
    torch_gc()
    return answer


if __name__ == '__main__':
    tokenizer = AutoTokenizer.from_pretrained("/home/ai/dev/model/chatglm2-6b-32k", trust_remote_code=True)
    model = AutoModel.from_pretrained("/home/ai/dev/model/chatglm2-6b-32k", trust_remote_code=True).half().cuda()
    model.eval()
    uvicorn.run(app, host='0.0.0.0', port=8000, workers=1)

web_demo.py

from transformers import AutoModel, AutoTokenizer
import gradio as gr
import mdtex2html

tokenizer = AutoTokenizer.from_pretrained("/home/ai/dev/model/chatglm2-6b-32k", trust_remote_code=True)
model = AutoModel.from_pretrained("/home/ai/dev/model/chatglm2-6b-32k", trust_remote_code=True).half().cuda()
model = model.eval()

"""Override Chatbot.postprocess"""


def postprocess(self, y):
    if y is None:
        return []
    for i, (message, response) in enumerate(y):
        y[i] = (
            None if message is None else mdtex2html.convert((message)),
            None if response is None else mdtex2html.convert(response),
        )
    return y


gr.Chatbot.postprocess = postprocess


def parse_text(text):
    """copy from https://github.com/GaiZhenbiao/ChuanhuChatGPT/"""
    lines = text.split("\n")
    lines = [line for line in lines if line != ""]
    count = 0
    for i, line in enumerate(lines):
        if "```" in line:
            count += 1
            items = line.split('`')
            if count % 2 == 1:
                lines[i] = f'<pre><code class="language-{items[-1]}">'
            else:
                lines[i] = f'<br></code></pre>'
        else:
            if i > 0:
                if count % 2 == 1:
                    line = line.replace("`", "\`")
                    line = line.replace("<", "&lt;")
                    line = line.replace(">", "&gt;")
                    line = line.replace(" ", "&nbsp;")
                    line = line.replace("*", "&ast;")
                    line = line.replace("_", "&lowbar;")
                    line = line.replace("-", "&#45;")
                    line = line.replace(".", "&#46;")
                    line = line.replace("!", "&#33;")
                    line = line.replace("(", "&#40;")
                    line = line.replace(")", "&#41;")
                    line = line.replace("$", "&#36;")
                lines[i] = "<br>"+line
    text = "".join(lines)
    return text


def predict(input, chatbot, max_length, top_p, temperature, history):
    chatbot.append((parse_text(input), ""))
    for response, history in model.stream_chat(tokenizer, input, history, max_length=max_length, top_p=top_p,
                                               temperature=temperature):
        chatbot[-1] = (parse_text(input), parse_text(response))       

        yield chatbot, history


def reset_user_input():
    return gr.update(value='')


def reset_state():
    return [], []


with gr.Blocks() as demo:
    gr.HTML("""<h1 align="center">ChatGLM</h1>""")

    chatbot = gr.Chatbot()
    with gr.Row():
        with gr.Column(scale=4):
            with gr.Column(scale=12):
                user_input = gr.Textbox(show_label=False, placeholder="Input...", lines=10).style(
                    container=False)
            with gr.Column(min_width=32, scale=1):
                submitBtn = gr.Button("Submit", variant="primary")
        with gr.Column(scale=1):
            emptyBtn = gr.Button("Clear History")
            max_length = gr.Slider(0, 4096, value=2048, step=1.0, label="Maximum length", interactive=True)
            top_p = gr.Slider(0, 1, value=0.7, step=0.01, label="Top P", interactive=True)
            temperature = gr.Slider(0, 1, value=0.95, step=0.01, label="Temperature", interactive=True)

    history = gr.State([])

    submitBtn.click(predict, [user_input, chatbot, max_length, top_p, temperature, history], [chatbot, history],
                    show_progress=True)
    submitBtn.click(reset_user_input, [], [user_input])

    emptyBtn.click(reset_state, outputs=[chatbot, history], show_progress=True)

demo.queue().launch(server_name='0.0.0.0', share=False, inbrowser=True)

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

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

相关文章

Go学习-Day1

Go学习-Day1 个人博客&#xff1a;CSDN博客 打卡。 Go语言的核心开发团队&#xff1a; Ken Thompson (C语言&#xff0c;B语言&#xff0c;Unix的发明者&#xff0c;牛人)Rob Pike(UTF-8发明人)Robert Griesemer(协助HotSpot编译器&#xff0c;Js引擎V8) Go语言有静态语言的…

Sentinel使用实例

不说了&#xff0c;直接上官方文档 https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/readme-zh.md Sentinel Example 项目说明 本项目演示如何使用 Sentinel starter 完成 Spring Clo…

推荐工具!使终端便于 DevOps 和 Kubernetes 使用

如果你熟悉 DevOps 和 Kubernetes 的使用&#xff0c;就会知道命令行界面&#xff08;CLI&#xff09;对于管理任务有多么重要。好在现在市面上有一些工具可以让终端在这些环境中更容易使用。在本文中&#xff0c;我们将探讨可以让工作流程简化的优秀工具&#xff0c;帮助你在 …

Intel汇编和ATT汇编的区别?

一、前缀不同 在 Intel 语法中&#xff0c;没有寄存器前缀或立即前缀。 然而&#xff0c;在 AT&T 中&#xff0c;寄存器的前缀是“%”&#xff0c;而 immed 的前缀是“$”。 Intel 语法十六进制或二进制即时数据分别带有“h”和“b”后缀。 此外&#xff0c;如果第一个十六…

最新AI系统ChatGPT网站程序源码+搭建教程/公众号/H5端/安装配置教程/完整知识库

1、前言 SparkAi系统是基于国外很火的ChatGPT进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。 那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧&#xff01;…

nginx一般轮询、加权轮询、ip_hash等负载均衡模式配置介绍

一.负载均衡含义简介 二.nginx负载均衡配置方式 准备三台设备&#xff1a; 2.190均衡服务器&#xff0c;2.191web服务器1&#xff0c;2.160web服务器2&#xff0c;三台设备均安装nginx&#xff0c;两台web服务器均有网页内容 1.一般轮询负载均衡 &#xff08;1&#xff09…

基于深度信念神经网络的矿石产量预测,基于DBN的矿石产量预测,DBN的详细原理

目录 背影 DBN神经网络的原理 DBN神经网络的定义 受限玻尔兹曼机(RBM) DBN的矿石产量预测 基本结构 主要参数 数据 MATALB代码 结果图 展望 背影 DBN是一种深度学习神经网络,拥有提取特征,非监督学习的能力,是一种非常好的分类算法,本文将DBN算法进行矿石产量预测 DB…

golang Cobra 快速使用

package mainimport("fmt""os""github.com/spf13/cobra" )func f1(){fmt.Printf("这是主命令的运行函数 ") } func f2(){fmt.Println("这是一个子命令的运行函数") }func main(){var rootCmd &cobra.Command{Use: &quo…

【果树农药喷洒机器人】Part8:果树对靶变量喷药实验

&#x1f4e2;&#xff1a;博客主页 【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d; 收藏 ⭐不迷路&#x1f649; &#x1f4e2;&#xff1a;内容若有错误&#xff0c;敬请留言 &#x1f4dd;指正…

Maven - 全面解析 Maven BOM (Bill of Materials):打造高效依赖管理与模块化开发

文章目录 Whats BOMWhy Bom常見的官方BOMSpring Maven BOM dependencySpringBoot SpringCloud Maven BOM dependencyJBOSS Maven BOM dependencyRESTEasy Maven BOM dependencyJersey Maven BOM dependency How Bom定义BOM其他工程使用的方法 BOM VS POM What’s BOM BOM&…

jmeter中用户参数和用户定义的变量的区别

如果使用jmeter做过参数化的人都知道&#xff0c;参数化的方式有多种&#xff0c;其中一种就是使用用户定义的变量&#xff0c;还有一种是使用用户参数。那么&#xff0c;这两个有什么异同呢&#xff1f; 一、先说相同的点&#xff1a; 1、都可以参数化&#xff0c;以供sample…

ArrayList浅拷贝clone,Kotlin

ArrayList浅拷贝clone&#xff0c;Kotlin import kotlin.collections.ArrayListfun main() {var list ArrayList<MyData>()for (i in 0..<3) {list.add(MyData(i, 0))}//浅拷贝list到copyListvar copyList list.clone()println(list)println(copyList)println("…

SSM整合(XML方式)

文章目录 SSM整合之后xml方式1 系统环境1.1 软件环境1.2 项目环境1.3 配置web.xml1.4 配置jdbc.properties文件1.5 配置SpringMVC核心文件1.6 配置Spring的核心文件1.7 配置MyBatis的核心文件1.8 配置数据库1.9 配置文件位置 2 编写后端代码2.1 编写实体类2.2 编写Dao接口2.3 编…

AOP与SpringAOP

AOP与SpringAOP 一、什么是AOP&#xff0c;什么是SpringAOP二、AOP与拦截器的区别三、实现SpringAOP1.添加SpringBootAOP依赖2.创建切面3.创建切点4.创建通知5.创建连接点 效果 一、什么是AOP&#xff0c;什么是SpringAOP AOP即Aspect-Oriented Programming面向切面编程。 它是…

CRC 校验码

CRC 校验码 题目解答发送端如何计算商 接收端 题目 假设生成多项式为 G(X)X4X31&#xff0c;要求出二进制序列10110011的CRC校验码 解答 发送端 首先 生成多项式为&#xff1a;G(X)X4X31&#xff0c;改写为二进制比特串为11001(有X的几次方&#xff0c;对应的2的几次方的位…

stable diffusion 单张图片换头roop安装配置

1.首先安装秋叶大佬的webui 2.然后在拓展里面搜索roop,下载roop插件,然后重启webui 3.重启后,在文生图和图生图的界面,就可以看到roop的入口 4.这里面,需要提前安装Visual Studio. 勾选一些必要的选项,这里可以参照b站的视频 # 秋叶版本Stablediffusion的Roop插件的安装 …

RocketMQ消费者可以手动消费但无法主动消费问题,或生成者发送超时

1.大多数是配置问题 修改rocketmq文件夹broker.conf 2.配置与集群IP或本地IPV4一样 重启 在RocketMQ独享实例中支持IPv4和IPv6双栈&#xff0c;主要是通过在网络层面上同时支持IPv4和IPv6协议栈来实现的。RocketMQ的Broker端、Namesrv端和客户端都需要支持IPv4和IPv6协议&…

Qt扫盲-Qt Paint System 概述

Qt Paint System 概述 一、概述二、绘图设备和后端1. Widget2. Image3. Pixmap4. OpenGL绘制设备5. Picture6. 自定义绘制后端 三、绘图与填充1. Drawing2. 填充 Filling 四、坐标系统1. 渲染Window-Viewport转换 五、读写图像文件1. QMovie 六、绘图相关设备 一、概述 Qt的pa…

【Antd】DatePicker日期选择框设置disabledDate不可选择的日期

需要先引入moment import moment from moment; 调用 antd 组件时&#xff1a; <RangePicker disabledDate{disabledDate} /> 其中 disabledDate 赋值如下&#xff1a; 1、当天之前的不可选&#xff0c;不包括当天&#xff1a; const disabledDate (current) > {/…

MyBatis-Plus学习笔记(尚硅谷)

一、MyBatis-Plus 1.简介 MyBatis-Plus (opens new window)&#xff08;简称 MP&#xff09;是一个 MyBatis (opens new window)的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 我们的愿景是成为 MyBatis 最好的搭档&…