ChatGLM模型通过api方式调用响应时间慢怎么破,Fastapi流式接口来解惑,能快速提升响应速度

ChatGLM-6B流式HTTP API

本工程仿造OpneAI Chat Completion API(即GPT3.5 API)的实现,为ChatGLM-6B提供流式HTTP API。


文章目录

  • ChatGLM-6B流式HTTP API
  • 前言
  • 一、下载代码安装环境
  • 二、接口服务脚本代码
  • 三、运行启动命令
  • 总结


前言

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


一、下载代码安装环境

依赖环境
实际版本以ChatGLM-6B官方为准。但是这里需要提醒一下:
官方更新stream_chat方法后,已不能使用4.25.1的transformers包,故transformers==4.27.1。
cpm_kernel需要本机安装CUDA(若torch中的CUDA使用集成方式,如各种一键安装包时,需要注意这点。)
为了获得更好的性能,建议使用CUDA11.6或11.7配合PyTorch 1.13和torchvision 0.14.1。

我使用的是3090显卡
python版本是3.9

先安装这个protobuf>=3.18,<3.20.1transformers==4.27.1 transformers版本必须是4.27.1要不然会报错
torch安装命令用conda方式,不要使用pip要不然cpm_kernels会报错
安装命令
conda install pytorch==1.12.1 torchvision==0.13.1 torchaudio==0.12.1 cudatoolkit=11.3 -c pytorch
torch==1.12.1+cu113
torchvision==0.13.1
安装完以上的环境再安装下面的,保证万无一失
icetk
cpm_kernels
uvicorn==0.18.1必须这个版本,不然会报错
fastapi

二、接口服务脚本代码

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 sysdef 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 loggerlogger = getLogger('ChatGLM', 'chatlog.log')MAX_HISTORY = 5class 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 = Noneif 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 modeldef 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, historydef stream(self, query, history):if query is None or history is None:yield {"query": "", "response": "", "history": [], "finished": True}size = 0response = ""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_idbot = 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["query"]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["query"]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, debug = False)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)

三、运行启动命令

python3 -u chatglm_service_fastapi.py --host 127.0.0.1 --port 8800 --quantize 8 --device 0
参数中,--device 为 -1 表示 cpu,其他数字i表示第i张卡。
根据自己的显卡配置来决定参数,--quantize 16 需要12g显存,显存小的话可以切换到4或者8

在这里插入图片描述

接口请求方式
流式接口,使用server-sent events技术。接口URL: http://{host_name}/stream请求方式:POST(JSON body)返回方式:使用Event Stream格式,返回服务端事件流,
事件名称:delta
数据类型:JSON
返回结果:字段名	类型	说明
delta	string	产生的字符
query	string	用户问题,为省流,finished为true时返回
response	string	目前为止的回复,finished为true时,为完整的回复
history	array[string]	会话历史,为省流,finished为true时返回
finished	boolean	true 表示结束,false 表示仍然有数据流。

在这里插入图片描述

curl  调用方式
curl --location --request POST 'http://hostname:8800/stream' \
--header 'Host: localhost:8001' \
--header 'User-Agent: python-requests/2.24.0' \
--header 'Accept: */*' \
--header 'Content-Type: application/json' \
--data-raw '{"query": "给我写个广告" ,"history": [] }'

总结

以上就是今天要讲的内容,更多大语言模型知识关注微信公众号:CV算法小屋
加我微信:Lh1141755859,加交流群,备注:进群

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

相见恨晚,这才是横跨三大操作系统的终极神器!真的太太太好用了。。。

点关注公众号&#xff0c;回复“1024”获取2TB学习资源&#xff01; 此前给大家推荐过无数的Chrome插件&#xff0c;涉及工作、生活、学习、娱乐等方方面面&#xff0c;大大提高了浏览器的可玩性。 但回到桌面端&#xff0c;我们依然还是需要下载大量的软件客户端&#xff0c;来…

str.replace()——Python的“第四”字符串格式

str.replace()&#xff0c;Python的“第四”字符串格式。 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程》&#xff0c;不仅仅是基础那么简单…… 地址&#xff1a;https://lqpybo…

详解Handler

详解Handler 文章目录 详解Handler1.Handler的工作流程1.1主线程具有如上性质的原因1.2流程图 2.Handler流程中的重要的几个方法2.1Message中的属性2.2.1what2.2.2replyTo2.2.3obtain 2.2Handler.post()与Handler.sendMessage()2.2.1post的源码2.2.1.1sendMessageDelayed()源码…

AI_News周刊:第四期

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 News 1.对抗“唤醒人工智能”马斯克招募团队开发 OpenAI 竞争对手 据两位直接了解这项工作的人士和另一位了解情况的人士透露&#xff0c;埃隆马斯克最近几周与人工智能研究人员接洽&#xff0c;商讨成…

tasker配置文件_如何在Android上管理Tasker配置文件和自动执行功能

tasker配置文件 Previously mentioned Tasker is an Android automation powerhouse. We’ll show you how to export and import profiles so you don’t have to create them from scratch. We also have some for you to download and tweak to your heart’s extent. 前面提…

大家都在卷ChatGPT的时候,我已经...

最近因ChatGPT爆火&#xff0c;使得很多人非常的焦虑&#xff0c;下面是我看到的一位好朋友心情&#xff01;不知道大家是否也有同样的心情&#xff01;&#xff5e; 感觉很多人在看到ChatGPT时都有这样的担忧&#xff0c;这样的担忧是不是源自于神经网络如果参数量足够大&…

渗透测试|网络安全常用靶场

搭建教程网络上随便一搜一大堆&#xff0c;这里就不再赘述 vulhub 免费开源漏洞靶场 www.vulhub.org vulnhub 国外的一个靶场&#xff0c;难度中上&#xff08;类似于真实渗透环境&#xff09; https://www.vulnhub.com/ pikachu 综合靶场 https://github.com/zhuifengs…

关于渗透测试

今天看到某安全公司网站上有关渗透测试的内容&#xff0c;感觉不错&#xff0c;转了过来 原文&#xff1a;http://cimersec.w92.mc-test.com/index.php/Profession/view/id/9 渗透测试&#xff0c;是指为了对客户目标网络的安全性进行实际检查&#xff0c;进行带有攻击性行为的…

实战渗透--一次对后台登录系统的简单渗透测试

某网站后台登录界面 发现有验证码框 猜想会不会存在验证码绕过的漏洞 首先随意输入用户名密码&#xff08;用于抓包&#xff09; 打开burp抓包 分析数据包后 找到对应的传参点 即输入的账号密码还有验证码 这里可以看到 账号和密码全都是明文传输 并没有进行加密 所以更改起来还…

网络渗透测试

1.5指纹识别 指纹由于其终身不变性唯一性和方便性 ,几乎已成为生物特征识别的代名词.通常我们说的指纹就是人的手指末端正面皮肤凹凸不平纹线&#xff0c;纹线规律的排列形成不同纹型。 内容 1.6查找真实IP 在渗透测试过程中&#xff0c;目标服务器可能只有一个域名。 1…

渗透安全测试

渗透安全测试 PTES&#xff08;渗透测试执行标准&#xff09;&#xff0c;渗透测试的过程包括交互&#xff0c;信息收集建模&#xff0c;Vul-可行性分析&#xff0c;开发&#xff0c;后期开发等。渗透测试旨在提高系统的安全性&#xff0c;而不是为了破坏&#xff0c;不会影响…

【渗透测试基础】越权攻击讲解

01 什么是越权 越权&#xff0c;是攻击者在获得低权限账号后&#xff0c;利用一些方式绕过权限检查&#xff0c;访问或者操作到原本无权访问的高权限功能。在实际的代码安全审查中&#xff0c;这类漏洞很难通过工具进行自动化检测&#xff0c;因此危害很大。越权有两种类型&am…

渗透测试工具

前言 本篇文章总结了很好用的渗透测试工具&#xff0c;会不断更新&#xff01;&#xff01;&#xff01; 供大家学习使用&#xff01;&#xff01;&#xff01; 正文 01 信息收集 1.1 dirsearch 1.1.1介绍&#xff1a; 类似御剑扫描的一款网站目录扫描器&#xff0c;由pyt…

PentestGPT:一款由ChatGPT驱动的强大渗透测试工具

关于PentestGPT PentestGPT是一款由ChatGPT驱动的强大渗透测试工具,该工具旨在实现渗透测试任务执行过程的自动化。该工具基于ChatGPT实现其功能,允许广大研究人员以交互式的方式使用,并指导渗透测试人员进行渗透测试任务的总体进度调控并执行指定操作。 除此之外,Pentes…

利用ChatGPT进行内网域渗透学习

ChatGPT可以直接模拟在域内环境中的命令执行结果 1、查看共享 2、定位域控

考研政治考题分布、单选多选技巧Keywords、大题点默析

文章目录 一、考题分布(一) 选择33道 (16道单选&#xff0c;17道多选:16117250分)(二) 大题5道 (51050分) 二、选择技巧、选择题规律Keywords选择题规律 三、大题点默析结构 一、考题分布 (一) 选择33道 (16道单选&#xff0c;17道多选:16117250分) 1-4&#xff1a;马原4道单…

chatgpt-4它的未来是什么?该如何应用起来?

在当今快节奏的数字通信世界中&#xff0c;ChatGPT已成为一个强大的在线聊天平台&#xff0c;改变了人们互动和沟通的方式。凭借其先进的AI功能、用户友好的界面和创新技术&#xff0c;ChatGPT已成为个人和企业的热门选择。 然而&#xff0c;ChatGPT的未来有望更加激动人心和具…

万字干货!ChatGPT 从零完全上手实操指南!【二】

2.调教 GPT之奖惩指令 其实这个所谓“奖惩指令&#xff08;有监督学习&#xff09;”的作用和调教原理很好理解&#xff0c;它就像是我们教育孩子一样。 如果你希望孩子达到你理想的行为标准&#xff0c;那么你就需要对他进行教育&#xff0c;如果孩子做得好&#xff0c;我们就…

分享一些程序员接私活、兼职的平台

跟大家分享一下如何判断一个外包项目是否靠谱&#xff0c;有哪些接项目的渠道&#xff0c;以及其他接私活的经验。 判断项目是否靠谱&#xff0c;上来不说需求没有文档直接问你多少需要多少钱&#xff0c;说话不靠谱&#xff0c;可能就是打听价的&#xff0c;这样的项目无需太…

chatgpt赋能python:Python如何成为一名兼职SEO?

Python如何成为一名兼职SEO&#xff1f; 简介 SEO&#xff0c;即搜索引擎优化&#xff0c;是一种很有前途的职业。随着互联网的发展&#xff0c;越来越多的公司意识到网站能为自己带来的价值&#xff0c;从而开始注重SEO。如果你想在这个领域探索机会&#xff0c;那么Python就…