本地化部署大语言模型 ChatGLM

2023-11-03

本地化部署大语言模型 ChatGLM

ChatGLM-6B 是一个开源的、支持中英双语的对话语言模型,基于 General Language Model (GLM) 架构,具有 62 亿参数。结合模型量化技术,用户可以在消费级的显卡上进行本地部署(INT4 量化级别下最低只需 6GB 显存)。 ChatGLM-6B 使用了和 ChatGPT 相似的技术,针对中文问答和对话进行了优化。

前期筹备

GitHub 基础包

GitHub: ChatGLM-6B

下载 ChatGLM-6B 压缩包到本地

请添加图片描述

语言模型文件

Hugging Face: Model

下载 训练好的 语言模型文件

请添加图片描述

每一个都要下载

请添加图片描述

基础配置

解压 ChatGLM-6B-main.zip 文件

请添加图片描述

新建一个名为 model 的文件夹

请添加图片描述

把刚才在 Hugging Face 上下载的所有文件都放进来
应该是 20 个 检查一下

请添加图片描述

返回 ChatGLM-6B-main 跟目录 找到名为 web_demo.py 的文件

请添加图片描述

可以用记事本 或则 其他工具打开

请添加图片描述

更改第 45行代码
原本代码:
tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True)
model = AutoModel.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True).half().cuda()
修改过后代码:
tokenizer = AutoTokenizer.from_pretrained("model", trust_remote_code=True)
model = AutoModel.from_pretrained("model", trust_remote_code=True).half().quantize(4).cuda()
就是把 THUDM/chatglm-6b 更改为 model
并在 half()方法之后添加 quantize(4) 方法

请添加图片描述

量化需求:
如果显存小于14G 就使用 quantize(4) 方法 如果你要使用 quantize(8)你就要关闭所有应用
说一下我的电脑配置:i7、16G内存、2060ti显卡(6G显存)
各位看官老爷自己对比一下

在这里插入图片描述

显存查看方法

Win + R 键 打开命令窗口
输入 dxdiag 然后点击确认

请添加图片描述

打开系统自带的诊断工具之后 随便点一个显示

请添加图片描述

这个显示内存就是你的 显存

请添加图片描述

Anaconda 模块

Anaconda 官网: Anaconda 官网

ChatGLM-6B 网页部署

Anaconda 环境创建

打开 Anaconda 点击 Environments

请添加图片描述

新建一个环境

请添加图片描述

起一个名字
注意:记住 Python 版本 有点重要 最好使用 3.10.10
如果没有可以在官网重新下载 更新一下

请添加图片描述

点击那个运行按钮 并打开 Open Terminal

在这里插入图片描述

根目录操作

输入 D: 进入相应硬盘

请添加图片描述

使用 cd 命令 进入到 ChatGML 根目录
我这边是 D:\Unity\ChatGLM-6B\ChatGLM-6B-main
大家根据自己的 解压路径进行 打开

请添加图片描述

基础依赖加载

键入 pip install -r requirements.txt
加载依赖项 反正我这边是会加载不完全

请添加图片描述

transformers 和 protobuf 库加载

下载 protobuf 和 transformers 库支持
pip install protobuf==3.20.0 transformers==4.27.1 icetk cpm_kernels

请添加图片描述

因为要使用 Web 显示 所以也需要加载 gradio库
pip install gradio

请添加图片描述

先启动跑一下看看 能不能运行的起来 万一可以呢 是吧
python web_demo.py

请添加图片描述

Pytorch 源修改

Pytorch: Pytorch

报错:AssertionError: Torch not compiled with CUDA enabled
这个就是 只支持 CPUCUDR 问题不大
去 Pytorch 找到对应的 直接 conda

请添加图片描述

注意选择对啊
如果conda 实在是卡的不能行的话  你就试试 pip
两个命令都给你:

conda: conda install pytorch torchvision torchaudio pytorch-cuda=11.7 -c pytorch -c nvidia
pip: pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu117

请添加图片描述
请添加图片描述

当出现这一句的时候 你直接 输入 y 回车就行

请添加图片描述

依赖库补充

下载完毕之后你会发现 还是缺少依赖库 找到相应名称
比如这个 chardet 直接 pip install
pip install chardet

请添加图片描述

再次运行 python web_demo.py 命令

请添加图片描述

好吧 果然不可以  缺少 cchardet库
那就继续下载呗
pip install cchardet

请添加图片描述

来了来了 全场最大的麻烦来了
明明下载都下载好了 就是无法执行 你气不气

请添加图片描述

找了一百年 重新下载也不行 换成清华源 也不行
最后的最后 就想着要不换下轮子呢

请添加图片描述

补充依赖 pypi 配置

pypi: pypi官网

在搜索框输入 你想要查询库名称

请添加图片描述

注意选择对应的 系统 我是 win64 所以就选择了第一个
这里还有一个坑

请添加图片描述

cd 到你存放 刚刚下载文件的目录

请添加图片描述

cchardet 依赖错误解决

输入 pip install D:\Unity\ChatGLM-6B\cchardet-2.1.7-cp39-cp39-win_amd64.whl
这是我的路径 各位 自行更改哈
然后你会发现 又错了!!!
不能用 完犊子 真的差点吐血 好在是解决了

请添加图片描述

回到下载文件夹 各位还记得 自己创建环境时的 Python 版本吗 对 就是那个!
原本名称是 cp39 改成 cp310 就能用了
真真不想吐槽了

请添加图片描述

你要是不知道自己环境对应的 就输入:
pip debug --verbose
按照对应的更改一下就行了

请添加图片描述

执行 pip install D:\Unity\ChatGLM-6B\cchardet-2.1.7-cp310-cp310-win_amd64.whl

请添加图片描述

成功 毫无悬念

请添加图片描述

cd 到ChatGLM 根目录
cd D:\Unity\ChatGLM-6B\ChatGLM-6B-main

请添加图片描述

再次运行 python web_demo.py
发现还是不行 那还说什么  上大招

请添加图片描述

强制 归一化

强制 最新归一化
pip install --force-reinstall charset-normalizer==3.1.0

请添加图片描述

再次启动
python web_demo.py
搓手等待...

请添加图片描述

网页部署成功

天见犹怜 终于终于 成功了
真是一波三折 再三折 好在是成功了

请添加图片描述

好了大家可以尽情的调教自己的 GPT

请添加图片描述

ChatGLM-6B 本地部署

Anaconda Terminal

在上面创建好的环境下 重新打开 执行 Terminal 

在这里插入图片描述

导航到 根目录

请添加图片描述

依赖项加载

使用 pip install fastapi uvicorn 命令安装相关 依赖

请添加图片描述

api.py 文件修改

在根目录找到 api.py 文件并打开

请添加图片描述

初始代码:这两句在 5354
	tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True)
	model = AutoModel.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True).half().cuda()
更改为下面的:稍微解释一下。
因为我的模型放在了根目录的 model 文件夹下 所以把 "THUDM/chatglm-6b" 更改为了 "model"
你们也可以按需更改。
    tokenizer = AutoTokenizer.from_pretrained("model", trust_remote_code=True)
    model = AutoModel.from_pretrained("model", trust_remote_code=True).half().cuda()
可以直接替换的完整代码:
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("model", trust_remote_code=True)
    model = AutoModel.from_pretrained("model", trust_remote_code=True).half().cuda()
    model.eval()
    uvicorn.run(app, host='0.0.0.0', port=8000, workers=1)

api.py 执行

执行命令:python api.py

请添加图片描述

本地化部署 成功

可以自己设置访问网址和端口 只要设置好就行。
我这边直接使用的是默认的:http://127.0.0.1:8000 或者 http://0.0.0.0:8000

请添加图片描述

发送 Json 数据 Unity 模块

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 发送 数据
/// </summary>
[System.Serializable]
public class PostDataJson_ZH 
{
    /// <summary>
    /// 发送信息
    /// </summary>
    public string prompt;
    /// <summary>
    /// 细节
    /// </summary>
    public List<string> history;
}

接收 Json 数据 Unity 模块

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 接收 数据
/// </summary>
[System.Serializable]
public class AcceptJson_ZH 
{
    /// <summary>
    /// 返回消息
    /// </summary>
    public string response;
    /// <summary>
    /// 多个回答
    /// </summary>
    public List<List<string>> history;
    /// <summary>
    /// 状态
    /// </summary>
    public int status;
    /// <summary>
    /// 返回事件
    /// </summary>
    public string time;
}

Unity 结合

using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

public class ChatGLM_ZH : MonoBehaviour
{
    [Header("本地化访问网址")]
    public string _OpenAIUrl= "http://127.0.0.1:8000";

    [Header("基础模板设置")]
    [SerializeField]
    public PostDataJson_ZH _PostData = new PostDataJson_ZH();

    [Header("接收数据")]
    public string _RobotChatText;

    [Header("问题")]
    public string _SendMessage= "你好";


    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Q))
        {
            _SendMessage = GameObject.Find("输入").GetComponent<InputField>().text;
            StartCoroutine(GetPostData(_SendMessage));
        }
    }

    /// <summary>
    /// POST 方法请求
    /// </summary>
    /// <param 问题="_SendMessage"></param>
    /// <returns></returns>
    private IEnumerator GetPostData(string _SendMessage)
    {
        using (UnityWebRequest _Request = new UnityWebRequest(_OpenAIUrl, "POST"))
        {
            //{"prompt": "你好", "history": []}

            _PostData.prompt = _SendMessage;

            //数据转换
            string _JsonText = JsonUtility.ToJson(_PostData);
            print(_JsonText);

            byte[] _Data = System.Text.Encoding.UTF8.GetBytes(_JsonText);
            //数据上传 等待响应
            _Request.uploadHandler = new UploadHandlerRaw(_Data);
            _Request.downloadHandler = new DownloadHandlerBuffer();


            //数据重定向
            _Request.SetRequestHeader("Content-Type", "application/json");

            //等待响应 开始与远程服务器通信
            yield return _Request.SendWebRequest();

            //数据返回
            if (_Request.responseCode == 200)
            {
                //接收返回信息
                string _Message = _Request.downloadHandler.text;

                print(_Message);

                //数据转换
                AcceptJson_ZH _Textback = JsonUtility.FromJson<AcceptJson_ZH>(_Message);

                //确保当前有消息传回
                if (_Textback.response != null)
                {
                    //输出显示
                    _RobotChatText = _Textback.response;

                    GameObject.Find("输出").GetComponent<Text>().text = _RobotChatText;
                }
            }
        }
    }
}

本地化 运行 效果

命令行 输出

请添加图片描述

Unity 输出

请添加图片描述

使用网址合集

GitHub: ChatGLM-6B
Hugging Face: Model
Anaconda 官网: Anaconda 官网
Pytorch: Pytorch
Pypi: pypi官网
清华大学镜像网站: 清华大学镜像网站

执行命令合集

//基础包依赖加载
pip install -r requirements.txt

//transformers 和 protobuf 依赖加载
pip install protobuf==3.20.0 transformers==4.27.1 icetk cpm_kernels

//网页使用 gradio 库 加载
pip install gradio

//网页 启动命令
python web_demo.py

//CPU 转换
conda: conda install pytorch torchvision torchaudio pytorch-cuda=11.7 -c pytorch -c nvidia
pip: pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu117

//chardet 库 补充依赖
pip install chardet

//cchardet 库 补充依赖
pip install cchardet

//查看当前平台支持的版本
pip debug --verbose

//cchardet 库 轮子 加载
pip install D:\Unity\ChatGLM-6B\cchardet-2.1.7-cp310-cp310-win_amd64.whl

//强制 最新归一化
pip install --force-reinstall charset-normalizer==3.1.0

//启动命令
python web_demo.py


//本地化 依赖加载
pip install fastapi uvicorn

//本地化 启动命令
python api.py

//断开服务
Ctrl + C

//清华源 镜像
核心句式:-i https://pypi.tuna.tsinghua.edu.cn/simple
例如下载的是:cchardet
正常下载是:pip install cchardet
清华源下载是:pip install cchardet -i https://pypi.tuna.tsinghua.edu.cn/simple

暂时先这样吧,如果有时间的话就会更新模型微调文章以及抽时间更新GLM130B的部署,实在看不明白就留言,看到我会回复的。
路漫漫其修远兮,与君共勉。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

本地化部署大语言模型 ChatGLM 的相关文章

随机推荐

  • 菜鸟学四轴控制器之6:刀具半径补偿算法

    为什么要有刀具补偿 想象一下 如果我们的刀具可以理想到半径无穷小 倒是不需要考虑半径的补偿 但是实际上我们用到的是刀具的边沿在雕刻物体 如下图 简单来看 好像是直接平行于轮廓进行移动就可以了 其实不然 单条直线的雕刻是平行 但是直线和直线
  • /etc/rc.d/rc.sysinit脚本分析

    bin bash etc rc d rc sysinit run once at boot time Rerun ourselves through initlog 通过 sbin initlog 命令重新运行自己 if z IN INIT
  • 【Jenkins】安装提示: this account either does not have the privilege logon as a service

    错误详情 安装 Jenkins 时系统提示如下错误 this account either does not have the privilege logon as a service 1 解决方案 2 选择 本地安全策略 按下Win R组
  • C++11之用户自定义字面量(ClassType operator““_C(param...))

    系列文章 C 11之正则表达式 regex match regex search regex replace C 11之线程库 Thread Mutex atomic lock guard 同步 C 11之智能指针 unique ptr s
  • QT开发错误集

    1 error multiple definition of QWidget 在项目 pro中 SOURCES 处添加的 h和 cpp文件有重复添加 将重复的去掉就可以了 2 VS2010 QT 很多代码下面会出现红色波浪线 项目 属性 v
  • Python员工信息作业

    作业简介 根据用户输入 来实现增删改查 处理员工信息数据 1 信息格式 2 文本数据 1 Alex Li 22 13651054608 IT 2013 04 01 2 Jack Wang 28 13451024608 HR 2015 01
  • c++ 等待子线程结束_第3篇 Linux系统编程--线程生命周期与状态

    在上一篇中 我们已经通过知道如何创建多个线程 本篇会谈论到线程的生命周期 在此之前应该了解一下线程在一个进程中的内存布局 主线程和线程栈 每个栈都是一个独立的虚拟内存分配 可以将其放置在任意位置 重要的是要注意 栈的大小通常是有限的 操作系
  • 了解 sourceMap 配置

    Devtool 此选项控制是否生成 以及如何生成 source map 选择一种 source map 格式来增强调试过程 不同的值会明显影响到构建 build 和重新构建 rebuild 的速度 配置很多 分别有以下几种 eval 每个模
  • 一些常见数学问题的算法

    代码来源 晴神 算法笔记 一 最大公约数 int gcd int a int b if b 0 return a else return gcd b a b 二 最小公倍数 lcm a b ab d ab有可能溢出 因此更恰当的写法是a d
  • IDEA的这几个调试的骚操作,用了都说爽!

    来源 https dwz cn zMaNp9Kf 一 条件断点 循环中经常用到这个技巧 比如 遍历1个大List的过程中 想让断点停在某个特定值 参考上图 在断点的位置 右击断点旁边的小红点 会出来一个界面 在Condition这里填入断点
  • Linux设置自定义命令

    哪个用户使用 就在哪个用户的目录下进行下面操作即可 例如我的用户名是cgk 1 首先进入到cgk的目录下 2 打开bashrc文件 3 将想要添加的自定义命令写入后保存即可 例 alias jup jupyter lab port 8889
  • exception is java.sql.SQLDataException: Unsupported conversion from TIMESTAMP to java.lang.Long

    org springframework dao DataIntegrityViolationException Error attempting to get column operate time from result set Caus
  • [Spring Boot]05 国内Java开发者必备的两个提速神器:Maven的国内镜像、Spring的国内脚手架

    目录 一 Maven的国内镜像 二 Spring的国内脚手架 给 Java 开发者推荐两个提速神器 一 Maven的国内镜像 Maven的国内镜像 官网地址 http maven aliyun com 配置方法很简单 只需要找到 Maven
  • Python+selenium学习

    maximize window 最大化浏览器和刷新当前页面refresh from selenium import webdriver driver webdriver Firefox driver get https www baidu
  • WordPress使用【前端投稿】功能时为用户怎么添加插入文章标签

    在使用Wordpress做前端投稿功能的时候 可能需要用户填写文章标签 在插入文章的时候很多人不知道怎么把这些标签插入进去 下面这篇文章来为大家带来WordPress使用前端投稿功能时插入文章标签方法 在Wordpress里 wp inse
  • [力扣] 剑指 Offer 07. 重建二叉树-----Java

    题目 剑指 Offer 07 重建二叉树 例子 preorder 3 9 20 15 7 inorder 9 3 15 20 7 分析 1 我们知道前序遍历 那么前序遍历的第一个数一定是根结点 也就是 3 一定是根结点 2 我们可以找到中序
  • 【JS逆向】破解xx志愿headers中u-sign加密参数

    注意 文章内容仅用于学习和技术交流 如有侵权请联系我删除 学者应洁身自好 切勿做出违法的事情 旨在提供逆向思路 aHR0cHM6Ly93d3cueW91enkuY24vdHp5L3NlYXJjaC9jb2xsZWdlcy9jb2xsZWdl
  • linux下wifi的sta和ap操作

    前言 在linux开发中wifi是很常见的一个工作 wifi有STA模式和AP模式 今天分享下如何使用工具在Linux中控制wifi 作者 良知犹存 转载授权以及围观 欢迎关注微信公众号 羽林君 或者添加作者个人微信 become me 介
  • [网络安全]xss-labs level-4 解题详析

    读者可参考 订阅专栏 Xss Labs靶场攻防实战 姿势 逻辑后端代码 使用 str replace 分别将 gt 和 lt 替换为空字符串 该题使用onblur onfocus事件绕过 onblur onfocus事件 onblur 事件
  • 本地化部署大语言模型 ChatGLM

    本地化部署大语言模型 ChatGLM 本地化部署大语言模型 ChatGLM 前期筹备 GitHub 基础包 语言模型文件 基础配置 显存查看方法 Anaconda 模块 ChatGLM 6B 网页部署 Anaconda 环境创建 根目录操作