第5课-流式部署


文档摘要

我们希望做一个流式输出的后端,然后让前端去捕获这个流式输出,并且在聊天界面中流式输出。 首先构造流式输出引擎。 然后生成responsestream,这个responsestream里面有一个生成器,叫做responsegen。我们可以像列表一样去迭代这个生成器,然后取出生成的文本。 这样我们就可以在Jupyter的界面看到流式输出了。 我们也可以做一个后端,可以用FastAPI来做。这是一个新的python web框架,性能很强悍。 我们先来安装一下这个框架: 在Jupyter的格子中输入以下内容。 框架都很小,很快就安装好。 下面我们来改造一下,用fastapi做成http接口。

我们希望做一个流式输出的后端,然后让前端去捕获这个流式输出,并且在聊天界面中流式输出。
首先构造流式输出引擎。

# 构造流式输出引擎 query_engine = index.as_query_engine( streaming=True, similarity_top_k=3, llm=llm)

然后生成response_stream,这个response_stream里面有一个生成器,叫做response_gen。我们可以像列表一样去迭代这个生成器,然后取出生成的文本。

response_stream = query_engine.query("请写一篇1000字的文章论述法学专业就业前景") for text in response_stream.response_gen: print(text,end="")

这样我们就可以在Jupyter的界面看到流式输出了。

我们也可以做一个后端,可以用FastAPI来做。这是一个新的python web框架,性能很强悍。

我们先来安装一下这个框架:
在Jupyter的格子中输入以下内容。

%pip install fastapi %pip install uvicorn

框架都很小,很快就安装好。

下面我们来改造一下,用fastapi做成http接口。
新建一个Jupyter notebook的格子,填入以下代码:

import uvicorn from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import StreamingResponse app = FastAPI() app.add_middleware(CORSMiddleware,allow_origins=["*"]) @app.get('/stream_chat') async def stream_chat(param:str = "你好"): async def generate(): # 我们假设query_engine已经构建完成 response_stream = query_engine.query(param) for text in response_stream.response_gen: yield text return StreamingResponse(generate(), media_type='text/event-stream') if __name__ == '__main__': config = uvicorn.Config(app, host='0.0.0.0', port=5000) server = uvicorn.Server(config) await server.serve()

可以看到,这里的关键的关键在于yield语句的使用以及用一个generate函数构建Response。

然后在前端我们就可以愉快地接收了。

当然也可以新建一个python文件,填入以下代码:

import uvicorn from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import StreamingResponse app = FastAPI() app.add_middleware(CORSMiddleware,allow_origins=["*"]) @app.get('/stream_chat') async def stream_chat(param:str = "你好"): def generate(): # 我们假设query_engine已经构建完成 response_stream = query_engine.query(param) for text in response_stream.response_gen: yield text return StreamingResponse(generate(), media_type='text/event-stream') if __name__ == '__main__': uvicorn.run(app, host='0.0.0.0', port=5000)

可以看到在jupyter的格子中运行的代码与在py文件中运行的代码的区别仅仅在于if __name__ == '__main__':之后的代码。这是因为Jupyter是一个交互式的环境,它会在每个单元格中运行代码,而不是在一个独立的程序中运行。因此,当我们在Jupyter中运行一个程序时,它会在一个新的进程中运行,而不是在当前进程中运行。这就是为什么我们在Jupyter中运行的代码需要在if __name__ == '__main__':之后的代码中用uvicorn.Server启动服务器。而在py文件中运行的代码则不需要。

我们甚至可以直接在浏览器地址栏里输入:
http://127.0.0.1/stream_chat?param=你是谁?
然后浏览器页面就会出现流式输出。

我们也可以把它封装到一个js函数中

async function fetchStream(param) { const url = `http://127.0.0.1:5000/stream_chat?param=${encodeURIComponent(param)}`; const response = await fetch(url); const reader = response.body.getReader(); while (true) { const { value, done } = await reader.read(); if (done) { // 如果没有更多的数据可读,退出循环 statusvue.isTalking=false; break; } // 处理接收到的数据 const text = new TextDecoder("utf-8").decode(value); console.log(text) } }

然后我们就可以在想要用到地地方调用这个fetchStream函数了。这个函数需要一个参数,是字符串形式的。

本教程配了一个chat.html 文件,如果后端用fastapi配置好了,浏览器http://127.0.0.1/stream_chat?param=你是谁?也能有内容了,就可以在本地电脑双击打开这个chat.html 文件进行对话聊天。

好了,现在我们可以从零搭建起一个RAG应用了。未来我们可以一起搭建起一套开源的 To B的RAG系统。这个RAG系统也叫wow-rag,目前计划采用的技术栈是:
前端:TS + Vue3 + Element Plus
后端:FastAPI
大模型框架:Llama-index
大模型:自塾自封装One-API服务
数据库:Qdrant
我们计划不依赖于docker。只有一个zip包,解压后双击就部署完成。
我们计划做成五个套餐版本,分别是:

  1. 如果客户只有一个破电脑,上个网都卡,我们就给他部署套餐一。
  2. 如果客户有一个不错的电脑,我们就给他部署套餐二。
  3. 如果客户有一个不错的服务器,我们就给他部署套餐三。
  4. 如果客户有一个更好的服务器,我们就给他部署套餐四。
  5. 如果客户有一个更好的服务器,我们就给他部署套餐五。
    如果你有兴趣参与这项计划,请发邮件 zishuco@163.com 联系自塾,加入RAG开发员团队。

发布者: 作者: 转发
评论区 (0)
U