首页 > 其他分享 >ChatGLM-6B云服务器部署教程

ChatGLM-6B云服务器部署教程

时间:2023-06-16 19:11:06浏览次数:75  
标签:6B logger self 教程 quantize ChatGLM model response history

目录

CSDN链接地址:https://blog.csdn.net/Yh_yh_new_Yh/article/details/131252177

一、准备服务器

服务器地址:https://www.autodl.com

1.购买服务器

在这里插入图片描述

2.开机进入终端

在这里插入图片描述

3.进入终端

在这里插入图片描述

参考链接:https://zhuanlan.zhihu.com/p/614323117

二、部署ChatGLM

1.执行命令

cd ChatGLM-6B/

# 执行web页面
python web_demo.py

# 执行api接口
python api.py

2.本地代理访问地址

# 本地打开cmd
ssh -CNg -L 6006:127.0.0.1:6006 [email protected] -p 29999

# 访问地址
http://127.0.0.1:6006

2.1 结果如下

在这里插入图片描述

2.2 api接口一样操作

在这里插入图片描述

参考链接:https://www.autodl.com/docs/ssh_proxy/

三、Fastapi流式接口

现在市面上好多教chatglm-6b本地化部署,命令行部署,webui部署的,但是api部署的方式企业用的很多,官方给的api没有直接支持流式接口,调用起来时间响应很慢,这次给大家讲一下流式服务接口如何写,大大提升响应速度

1.api_fast.py

from fastapi import FastAPI, Request
from sse_starlette.sse import ServerSentEvent, EventSourceResponse
from fastapi.middleware.cors import CORSMiddleware
import uvicorn
import torch
from transformers import AutoTokenizer, AutoModel
import argparse
import logging
import os
import json
import sys

def getLogger(name, file_name, use_formatter=True):
    logger = logging.getLogger(name)
    logger.setLevel(logging.INFO)
    console_handler = logging.StreamHandler(sys.stdout)
    formatter = logging.Formatter('%(asctime)s    %(message)s')
    console_handler.setFormatter(formatter)
    console_handler.setLevel(logging.INFO)
    logger.addHandler(console_handler)
    if file_name:
        handler = logging.FileHandler(file_name, encoding='utf8')
        handler.setLevel(logging.INFO)
        if use_formatter:
            formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s')
            handler.setFormatter(formatter)
        logger.addHandler(handler)
    return logger

logger = getLogger('ChatGLM', 'chatlog.log')

MAX_HISTORY = 5

class ChatGLM():
    def __init__(self, quantize_level, gpu_id) -> None:
        logger.info("Start initialize model...")
        self.tokenizer = AutoTokenizer.from_pretrained(
            "THUDM/chatglm-6b", trust_remote_code=True)
        self.model = self._model(quantize_level, gpu_id)
        self.model.eval()
        _, _ = self.model.chat(self.tokenizer, "你好", history=[])
        logger.info("Model initialization finished.")
    
    def _model(self, quantize_level, gpu_id):
        model_name = "THUDM/chatglm-6b"
        quantize = int(args.quantize)
        tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True)
        model = None
        if gpu_id == '-1':
            if quantize == 8:
                print('CPU模式下量化等级只能是16或4,使用4')
                model_name = "THUDM/chatglm-6b-int4"
            elif quantize == 4:
                model_name = "THUDM/chatglm-6b-int4"
            model = AutoModel.from_pretrained(model_name, trust_remote_code=True).float()
        else:
            gpu_ids = gpu_id.split(",")
            self.devices = ["cuda:{}".format(id) for id in gpu_ids]
            if quantize == 16:
                model = AutoModel.from_pretrained(model_name, trust_remote_code=True).half().cuda()
            else:
                model = AutoModel.from_pretrained(model_name, trust_remote_code=True).half().quantize(quantize).cuda()
        return model
    
    def clear(self) -> None:
        if torch.cuda.is_available():
            for device in self.devices:
                with torch.cuda.device(device):
                    torch.cuda.empty_cache()
                    torch.cuda.ipc_collect()
    
    def answer(self, query: str, history):
        response, history = self.model.chat(self.tokenizer, query, history=history)
        history = [list(h) for h in history]
        return response, history

    def stream(self, query, history):
        if query is None or history is None:
            yield {"query": "", "response": "", "history": [], "finished": True}
        size = 0
        response = ""
        for response, history in self.model.stream_chat(self.tokenizer, query, history):
            this_response = response[size:]
            history = [list(h) for h in history]
            size = len(response)
            yield {"delta": this_response, "response": response, "finished": False}
        logger.info("Answer - {}".format(response))
        yield {"query": query, "delta": "[EOS]", "response": response, "history": history, "finished": True}


def start_server(quantize_level, http_address: str, port: int, gpu_id: str):
    os.environ['CUDA_DEVICE_ORDER'] = 'PCI_BUS_ID'
    os.environ['CUDA_VISIBLE_DEVICES'] = gpu_id

    bot = ChatGLM(quantize_level, gpu_id)
    
    app = FastAPI()
    app.add_middleware( CORSMiddleware,
        allow_origins = ["*"],
        allow_credentials = True,
        allow_methods=["*"],
        allow_headers=["*"]
    )
    
    @app.get("/")
    def index():
        return {'message': 'started', 'success': True}
    
    @app.post("/chat")
    async def answer_question(arg_dict: dict):
        result = {"query": "", "response": "", "success": False}
        try:
            text = arg_dict["prompt"]
            ori_history = arg_dict["history"]
            logger.info("Query - {}".format(text))
            if len(ori_history) > 0:
                logger.info("History - {}".format(ori_history))
            history = ori_history[-MAX_HISTORY:]
            history = [tuple(h) for h in history] 
            response, history = bot.answer(text, history)
            logger.info("Answer - {}".format(response))
            ori_history.append((text, response))
            result = {"query": text, "response": response,
                      "history": ori_history, "success": True}
        except Exception as e:
            logger.error(f"error: {e}")
        return result

    @app.post("/stream")
    def answer_question_stream(arg_dict: dict):
        def decorate(generator):
            for item in generator:
                yield ServerSentEvent(json.dumps(item, ensure_ascii=False), event='delta')
        result = {"query": "", "response": "", "success": False}
        try:
            text = arg_dict["prompt"]
            ori_history = arg_dict["history"]
            logger.info("Query - {}".format(text))
            if len(ori_history) > 0:
                logger.info("History - {}".format(ori_history))
            history = ori_history[-MAX_HISTORY:]
            history = [tuple(h) for h in history]
            return EventSourceResponse(decorate(bot.stream(text, history)))
        except Exception as e:
            logger.error(f"error: {e}")
            return EventSourceResponse(decorate(bot.stream(None, None)))

    @app.get("/clear")
    def clear():
        history = []
        try:
            bot.clear()
            return {"success": True}
        except Exception as e:
            return {"success": False}

    @app.get("/score")
    def score_answer(score: int):
        logger.info("score: {}".format(score))
        return {'success': True}

    logger.info("starting server...")
    uvicorn.run(app=app, host=http_address, port=port)


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Stream API Service for ChatGLM-6B')
    parser.add_argument('--device', '-d', help='device,-1 means cpu, other means gpu ids', default='0')
    parser.add_argument('--quantize', '-q', help='level of quantize, option:16, 8 or 4', default=16)
    parser.add_argument('--host', '-H', help='host to listen', default='0.0.0.0')
    parser.add_argument('--port', '-P', help='port of this service', default=8800)
    args = parser.parse_args()
    start_server(args.quantize, args.host, int(args.port), args.device)

1.2 将api_fast.py上传到服务器

在这里插入图片描述

2.准备插件

# 安装sse-starlette
pip install sse-starlette

# 启动命令
python api_fast.py

3.访问地址

ps:本地cmd启动代理

在这里插入图片描述

参考链接:https://blog.csdn.net/weixin_43228814/article/details/130063010

参考材料:

标签:6B,logger,self,教程,quantize,ChatGLM,model,response,history
From: https://www.cnblogs.com/cnwanj/p/17486351.html

相关文章

  • 【Python入门教程】调取电脑摄像头并发送照片至邮箱
    ​        本博文纯属娱乐,仅供大家学习参考,不得以此侵犯他人隐私。本篇文章参考Python研究者的python窃取摄像头的图片。在这里先感谢大佬的付出,大家可以去关注一下。一、获取邮箱授权码        授权码用于调用邮箱实现邮件的发送,这里以QQ邮箱做演示,在设置的账......
  • C4D如何制作碰撞动效?用C4D制作碰撞动效的教程
    可以帮助你快速掌握C4D这个软件的应用;并且还有各种C4D设计案例,包含产品动画,海报制作,建模渲染,场景动效等视频教程,非常适合自学设计的小伙伴哦。用C4D制作碰撞动效的教程:1.打开【C4D】。2.创建立方体,在【对象属性】调整大小为【50cm*50*50cm】;点击【运动图形】、【克隆】,按【Alt】键......
  • 项目管理工具----普加项目管理中间件(PlusProject )入门教程(3):如何配置列(下)
    普加项目管理中间件是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表,可满足项目管理应用程序的所有需求,是最完善的甘特图图表库。前面分别介绍标准列和自定义列,是本质来说每一列都是一个对象,标准列是预设好了各种属性的包装好的对象,方便直接使用,自定义列是按需处理的更加灵......
  • EViews下载(附序列号及教程)-EViews10.0破解版免费下载 软件大全
    EViews最新版是一款世界性的计量经济学软件,EViews最新版拥有创新的图形化的用户界面和强大的分析引擎,完美结合了现代软件技术和您需要的特征,EViews最新版可以快速和有效的管理您的数据。有需要的小伙伴快来下载使用吧。[下载地址]:后台私信我Eviews软件具有以下特点:1.强大的数据处......
  • Keil 5软件详细安装教程和安装包下载 软件大全
    Keil编程软件是一款为嵌入式系统设计开发开发而设计的软件。它包含了多种嵌入式设备的开发工具,如C编译器、调试器、仿真器等,并提供了多种模拟器和开发板支持。Keil编程软件被广泛应用于物联网、汽车、医疗等领域。[下载地址]:后台私信我II.功能特点A.支持多种处理器架构,如ARM、AVR......
  • 项目管理工具----普加项目管理中间件(PlusProject )入门教程(3):如何配置列(中)
    普加项目管理中间件是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表,可满足项目管理应用程序的所有需求,是最完善的甘特图图表库。除了上文的标准列,开发者可以根据自己扩展的任务属性类型,来创建自己的列。比如://文本输入框编辑列varstringColumn={name:"name",......
  • python测试系列教程——python+Selenium+chrome自动化测试框架
    需要的环境浏览器(Firefox/Chrome/IE…)PythonSeleniumSeleniumIDE(如果用Firefox)FireBug、FirePath(如果用Firefox)chromedriver、IEDriverServer、phantomjs.exeIDE(Pycharm/Sublime/Eclipse…)1、浏览器建议用Firefox或Chrome,千万不要用最新版本,要用早两到三个版本的。2......
  • Adobe InCopy CC2022【IC编写辅助软件】中文直装版安装教程
    ic2022是一款功能强大的辅助编写软件,其全名叫AdobeInCopy2022,也是一款由Adobe公司提供的软件,如ps、InDesign、pr等,这些都是一些企业经常使用的软件。而且该软件也是许多企业或个人用户喜爱的软件,软件的主要功能是帮助用户进行文案编辑和修改,是为作者、在编辑中,设计者们专门制作了......
  • OpenIddict使用教程
    @@openiddictpassword模式流程 OpenIddict是一个ASP.NETCore身份验证库,可帮助您添加OpenIDConnect和OAuth2.0支持到ASP.NETCore应用程序中。下面是OpenIddict使用教程的步骤:安装OpenIddict,在项目中添加OpenIddict.Core和OpenIddict.EntityFrameworkCoreNuget包。......
  • git cherry-pick 教程
    场景:部分代码变动(某几个提交),这时可以采用Cherrypick。1拿到代码变动提交的log,切换到代码变动的分支,然后查看log.==>gitcheckout变动分支名gitlog在英文状态下输入q!退出log2切换到自己的分支,输入gitcherry-pickgitlog的哈希值3gitpush提交上去下面......