fastAPI接口(普通流式响应和大模型流式响应)

1. 流式输出和非流失输出:

大模型的流式输出(Streaming Output)和非流式输出(Non-streaming Output)是指在生成文本或其他输出时,如何将结果返回给用户或下游系统。

流式输出 (Streaming Output):流式输出意味着模型生成的内容是逐步、逐块返回的,而不是等到整个生成过程完成后再一次性返回所有内容。
  优点:
   用户可以更早地开始看到部分结果,提高用户体验。
   对于长时间生成任务,可以减少内存占用,因为不需要一次性存储完整的输出。
   更适合实时应用,如在线聊天机器人,其中即时反馈是非常重要的。
  应用场景:适用于需要即时响应的场景,比如对话系统、直播翻译等。

非流式输出 (Non-streaming Output):非流式输出是指模型在完成整个生成过程后,一次性返回全部生成的结果。
  **优点:
   实现简单,易于处理和调试。
   在某些情况下,可能更适合那些需要对完整输出进行后续处理的应用。
  应用场景:适用于那些不依赖即时反馈、或者需要对整个输出进行整体处理的场景,例如批量文本生成、文档摘要等。

2. 流式输出、非流失输出和vllm的同步、异步关系

对于vllm同步:无论是流式还是非流式输出,vllm的LLM函数创建的模型对象通常以同步的方式工作,处理多并发情况时只能以队列形式一个个输出。对于非流式输出,它会阻塞直到生成完成并返回结果;对于流式输出,它也可以逐步返回数据给前端,但这是假流式,因为后端以及把所有的文本都输出了,然后我们又把文本一个个传给前端。

对vllm异步:异步引擎同样可以支持流式和非流式输出,但它允许你以非阻塞的方式处理这些输出。你可以启动一个生成任务而不等待它完成,然后根据需要逐步获取流式输出,或者在任务完成后一次性获取非流式输出(也是并发状态)。这为高并发环境下的应用提供了更好的性能和灵活性。

总结:流式输出和非流式输出关注的是输出的传输方式,而AsyncLLMEngine和LLM则更多地涉及到执行模式(同步 vs 异步)。两者可以组合使用,例如,你可以使用AsyncLLMEngine来异步地处理流式输出,从而在高并发环境中获得最佳性能和用户体验。

3. fastapi流式响应代码

from fastapi import FastAPI
import uvicorn
import os
import json
import time
from starlette.responses import StreamingResponse
# from fastapi.responses import StreamingResponse# 创建一个FastAPI应用程序实例
app = FastAPI()@app.post("/api")
def aaa():# StreamingResponse是一个提供的用于包装流式响应的类,必须以json字符串进行数据传递# starlette.responses和fastapi.responses中的StreamingResponse对象实现方式基本类似。return StreamingResponse(handle_post_request())def handle_post_request():for i in range(5):print(i)time.sleep(1)yield json.dumps({'type': i}) + '\n'if __name__ == "__main__":uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("API_PORT", 7777)), workers=1)

开启上述api后,使用以下代码发送请求:

import json
import requests# url_api = "http://10.4.0.141:800h1/cat/stream"
url_api = "http://localhost:7777/api"# 此调用方法为推荐方法。也可直接request.post发送请求,见https://editor.csdn.net/md/?articleId=144560081
with requests.post(url_api, stream=True) as r:r.raise_for_status()  # 检查请求是否成功print(r.iter_lines())for line in r.iter_lines():if line:  # 过滤掉保持连接的空行print(json.loads(line.decode('utf-8')))

4. LLM流式输出代码(非接口型,仅后端)

普通后端的流式输出使用TextStreamer(是同步的,不适合做api的流式响应)

from modelscope import AutoModelForCausalLM, AutoTokenizer
from transformers import TextStreamer
model_name = "地址"model = AutoModelForCausalLM.from_pretrained(model_name,torch_dtype="auto",device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)prompt = "你是谁"
messages = [{"role": "system", "content": "You are Qwen, created by Alibaba Cloud. You are a helpful assistant."},{"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(messages,tokenize=False,add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)# 非流输出
# generated_ids = model.generate(
#     **model_inputs,
#     max_new_tokens=1024
# )# generated_ids = [
#     output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
# ]# response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
# print(response)# 流输出,普通后端的流式输出使用TextStreamer,这是同步的,不适合于api交互做流式响应,必须使用TextIteratorStreamer,它是异步的
streamer = TextStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
generated_ids = model.generate(**model_inputs,max_new_tokens=512,streamer=streamer,
)

5. LLM流式响应代码(接口型FastAPI)

API的流式输出使用TextIteratorStreamer(是异步的,适合做api的流式响应)

from fastapi import FastAPI
import uvicorn
import os
import json
from starlette.responses import StreamingResponse
# from fastapi.responses import StreamingResponse
from transformers import TextIteratorStreamer
from threading import Thread
from modelscope import AutoModelForCausalLM, AutoTokenizer# 创建一个FastAPI应用程序实例
app = FastAPI()model_name = "地址"model = AutoModelForCausalLM.from_pretrained(model_name,torch_dtype="auto",device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)prompt = "写一篇800字的作文"
messages = [{"role": "system", "content": "You are Qwen, created by Alibaba Cloud. You are a helpful assistant."},{"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(messages,tokenize=False,add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)@app.post("/api")
def aaa():# StreamingResponse包装的是可迭代对象return StreamingResponse(handle_post_request())def handle_post_request():# TextIteratorStreamer为异步。skip_prompt=True, skip_special_tokens=True可以去除输出中的|im_start|等标记streamer = TextIteratorStreamer(tokenizer, timeout=60.0, skip_prompt=True, skip_special_tokens=True)generation_kwargs = {"max_new_tokens": 1024,  # 或者任何其他生成参数"streamer": streamer,}thread = Thread(target=model.generate, kwargs={**model_inputs, **generation_kwargs})thread.start()answer = ''for new_text in streamer:answer += new_textprint(answer)yield json.dumps({'content': answer}) + '\n'if __name__ == "__main__":uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("API_PORT", 7777)), workers=1)

前端的调用为

import json
import requests# url_api = "http://10.4.0.141:800h1/cat/stream"
url_api = "http://localhost:7777/api"with requests.post(url_api, stream=True) as r:r.raise_for_status()  # 检查请求是否成功print(r.iter_lines())for line in r.iter_lines():if line:  # 过滤掉保持连接的空行print(json.loads(line.decode('utf-8')))

6. 注意

非流式响应:fastapi之间的通信一般都是json对象的形式,发送请求时请求体为{},后端返回请求时的响应体也为{}。

流式响应:fastapi之间的通信一般都是json对象字符串格式的形式。使用json.dumps()将 str或者python对象(basemodel或者dict)转为json字符串格式。且流式响应一定要使用StreamingResponse对象包装

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

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

相关文章

VBA技术资料MF238:ADO提取多文件区域指定数据到工作表

我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套,分为初级、中级、高级三大部分,教程是对VBA的系统讲解&#…

Mapper代理开发

引入 Mybatis入门方式中,以下代码仍存在硬编码问题 Mapper 代理开发: 目的: 解决原生方式中的硬编码 简化后期执行sql ------下图中,第一段代码是原生硬编码代码块,第二个是引入了Mapper代理开发的代码块。 Mapper代…

ubuntu22.04编译安装Opencv4.8.0+Opencv-contrib4.8.0教程

本章教程,主要记录在Ubuntu22.04版本系统上编译安装安装Opencv4.8.0+Opencv-contrib4.8.0的具体过程。 一、下载opencv和opencv-contrib包 wget https://github.com/opencv/opencv/archive/refs/tags/4.8.0.zip wget https://github.com/opencv/opencv_contrib/archive/refs/…

thinkphp8+layui分页

前端 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>demo</title><link href"//unpkg.com/layui2.9.20/dist/css/layui.css" rel"stylesheet"> </head> <…

使用C语言连接MySQL

库的准备 要使用C语言连接mysql&#xff0c;需要使用mysql官网提供的connect库&#xff0c;可以去官网下载&#xff0c;由于我们要下载到 Linux 操作系统中&#xff0c;也可以使用如下指令进行安装库 sudo apt-get install libmysqlclient-dev MySQL连接C/C的库通常会安装在/us…

【软件设计_设计模式】设计模式代码笔记

设计模式&#xff08;Design pattern&#xff09;代表了最佳的实践&#xff0c;通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。…

【Android学习】RxJava

文章目录 资料连接1. Merge & Zip操作符: 合并数据源2. Map & FlapMap & ConcatMap & Buffer: 变换操作符3. retry & retryUntil & retryWhen : 错误处理操作符4. Transformer & Compose 转换操作符5. 网络请求嵌套回调 FlatMap6. 网络请求出错重连…

Mac配置 Node镜像源的时候报错解决办法

在Mac电脑中配置国内镜像源的时候报错,提示权限问题,无法写入配置文件。本文提供解决方法,青测有效。 一、原因分析 遇到的错误是由于 .npm 目录下的文件被 root 用户所拥有,导致当前用户无法写入相关配置文件。 二、解决办法 在终端输入以下命令,输入管理员密码即可。 su…

PyTorch基础入门

目录 前言一、[张量的广播&基本运算](https://www.bilibili.com/video/BV1Gg411u7Lr/?spm_id_from333.999.0.0)1. 张量的广播特性2. 逐点&规约&比较运算 二、张量的线性代数运算1. BLAS & LAPACK2. 矩阵形变及特殊矩阵构造3. 矩阵基本运算4. 矩阵的线性代数运…

Java基础夯实——2.6 Java中锁

1 Java中锁的概念 锁用于控制多个线程对共享资源的访问。只有持有锁的线程才能访问被保护的资源&#xff0c;其他线程必须等待锁的释放。这种机制可以防止线程之间的竞争条件&#xff08;Race Condition&#xff09;。保证了同一时刻只有一个线程持有对象的锁并修改该对象&…

【VSCode】常用插件汇总

1 Path Autocomplete&#xff08;路径提示的插件&#xff09; 步骤一&#xff1a;在vscode的扩展搜索中直接搜索Path Autocomplete&#xff0c;直接安装 步骤二&#xff1a;配置 配置 VS Code settings.json "path-autocomplete.pathMappings": {"": &q…

IOS通过WDA自动化中遇到的问题

IOS自动化遇到的问题 搭建WDA环境中遇到的问题1、XCode unsupport iphone xxx.2、创建Bundle Identifier出现问题&#xff1a;Communication with Apple failed3、创建Bundle Identifier出现问题&#xff1a;Automatic signing failed \Signing certificate is invalid4、创建B…

Golang Gin Redis+Mysql 同步查询更新删除操作(我的小GO笔记)

我的需求是在处理几百上千万数据时避免缓存穿透以及缓存击穿情况出现&#xff0c;并且确保数据库和redis同步&#xff0c;为了方便我查询数据操作加了一些条件精准查询和模糊查询以及全字段模糊查询、分页、排序一些小玩意&#xff0c;redis存储是hash表key值也就是数据ID&…

(六)- DRM驱动开发(qcom)

一&#xff0c;Linux Android Display 1&#xff0c;Linux Android Display Software Subsystem 密 2&#xff0c;Linux Android Display Architecture 密 二&#xff0c;DRM/KMS Adreno DPU 1&#xff0c;硬件框图 密 1.1 Qualcomm Adreno DPU 8-Series Overview 密 …

游戏AI实现-寻路算法(GBFS)

贪婪最佳优先算法是宽度优先遍历和贪婪算法结合的产物&#xff0c;使用启发式函数选择当前最低代价的节点&#xff0c;改善了宽度优先遍历需要遍历地图的大量节点来找寻结果的缺点。 算法过程&#xff1a; 1.首先设置开始节点的启发函数值&#xff08;h&#xff09;为0&#…

[Unity]Unity跨平台开发之Android简介

Android要求和兼容 图形接口支持 注意&#xff1a; 新的 Unity 项目默认不支持 OpenGL ES 2.0。 由于硬件和图形 API 的限制&#xff0c;并非所有渲染管道都与 Android 兼容。 图片压缩 Android标准压缩格式是ETC和ASTC。Unity默认压缩格式是ASTC。如果Android设备不支持您选…

监控易在汽车制造行业信息化运维中的应用案例

引言 随着汽车制造行业的数字化转型不断深入&#xff0c;信息化类IT软硬件设备的运行状态监控、故障告警、报表报告以及网络运行状态监控等成为了企业运维管理的关键环节。监控易作为一款全面、高效的信息化运维管理工具&#xff0c;在汽车制造行业中发挥着重要作用。本文将结合…

python进行矩阵运算

python进行矩阵运算 一、矩阵相乘二、矩阵求逆三、矩阵特征值与特征向量求解四、矩阵约当标准型与转换矩阵求解五、矩阵奇异值分解六、矩阵方程组求解 一、矩阵相乘 python中矩阵相乘可以使用numpy实现&#xff0c;也可以使用sympy实现&#xff0c;以numpy实现为例&#xff0c…

Trimble天宝三维激光扫描仪在建筑工程竣工测量中的应用【沪敖3D】

竣工测量是建筑项目竣工阶段的一个至关重要的环节&#xff0c;它为建筑工程的质量验收和成果核查提供了核心的参考依据。传统的竣工测量方法&#xff0c;如全站仪测量&#xff0c;主要依赖于现场人工操作&#xff0c;存在一些明显的局限性&#xff0c;例如作业时间长、工作量大…

【JavaWeb后端学习笔记】Spring Task实现定时任务处理

Spring Task是Spring框架提供的任务调度工具&#xff0c;可以按照约定的时间自动执行某个代码逻辑。 主要的应用场景有&#xff1a;纪念日提醒&#xff0c;处理订单未支付&#xff0c;还款提醒等。 1、corn表达式 使用Spring Task首先需要了解corn表达式&#xff0c;通过cor…