赞
踩
PLATO-MINI| 6-layers, 12-heads, 768-hidden|在十亿级别的中文对话数据上进行预训练。参数量更小,但效果更好。只支持闲聊型对话。
无需任何前端知识,学会最简单的Plato-mini闲聊机器人部署教程,举一反三,通过替换模型或者API,可以部署现有OpenAI提供的GPT API和未来的文心一言模型
学会教程,拥有一款专属于自己的chatGPT!
# 更新paddlenlp的版本 >= 2.5.0
!pip install --upgrade paddlenlp
PaddleNLP2.5.0 新特新之一
HuggingFace 生态联合
PaddleNLP首次和HuggingFace生态联合,支持所有Model和Tokenizer类支持直接从Huggingface Hub下载和上传,开发者可以直接从HuggingFace体验预训练模型效果
基于PLATO-MINI,模型在十亿级别的中文对话数据上进行了预训练,闲聊场景对话效果显著。
使用Taskflow,等待模型加载完毕,可以在ai studio直接体验开箱即用的交互式闲聊对话。
# 加载Taskflow
from paddlenlp import Taskflow
dialogue = Taskflow("dialogue")
# 单句对话(非交互式)
dialogue(["你好,我是桨飞飞"])
推荐:使用终端terminal进入python解释器进行体验
可配置参数:
输入exit
可退出交互模式
# 多轮对话(交互式)
# 取消下方代码注释,体验交互,输入`exit`可退出交互模式
# dialogue.interactive_mode(max_turn=4)
从源码中看PLATO-MINI的interaction的交互是如何做工作的?
先忽略max_turn这个参数,仅看轮询交互的逻辑,地址:源码
interaction
函数def interaction(args, model, tokenizer): history = [] start_info = "Enter [EXIT] to quit the interaction, [NEXT] to start a new conversation." cprint(start_info, "yellow", attrs=["bold"]) while True: user_utt = input(colored("[Human]: ", "red", attrs=["bold"])).strip() if user_utt == "[EXIT]": break elif user_utt == "[NEXT]": history = [] cprint(start_info, "yellow", attrs=["bold"]) else: history.append(user_utt) inputs = tokenizer.dialogue_encode( history, add_start_token_as_response=True, return_tensors=True, is_split_into_words=False ) inputs["input_ids"] = inputs["input_ids"].astype("int64") ids, scores = model.generate( input_ids=inputs["input_ids"], token_type_ids=inputs["token_type_ids"], position_ids=inputs["position_ids"], attention_mask=inputs["attention_mask"], max_length=args.max_dec_len, min_length=args.min_dec_len, decode_strategy=args.decode_strategy, temperature=args.temperature, top_k=args.top_k, top_p=args.top_p, num_beams=args.num_beams, length_penalty=args.length_penalty, early_stopping=args.early_stopping, num_return_sequences=args.num_return_sequences, use_fast=True, ) bot_response = select_response( ids, scores, tokenizer, args.max_dec_len, args.num_return_sequences, keep_space=False )[0] print(colored("[Bot]:", "blue", attrs=["bold"]), colored(bot_response, attrs=["bold"])) history.append(bot_response) return
history
的列表,用于存放用户的历史问询(50行)user_utt
接收用户的输入指令(54行)user_utt
共有三种状态:(55~61行)
[EXIT]
:输入exit结束对话[NEXT]
:输入next重置机器人正常语句
:输入正常对话,history会保存当前对话tokenizer
编码history
中的所有对话得到inputs
信息(可以猜测max_turn=n就是保留最近的n次对话,把history更改为history[-(n*2):]可以很容易自定义记忆对话轮数的功能) (62-65行)可以发现PLATO-MINI的闲聊交互模式,逻辑是比较简单的,通过将所有历史对话数据保存并全部输入到模型的方式习得上下文信息
只在terminal中进行闲聊交互不满足与我们的需求
如何使用最便捷的方式构建一个交互式的前端页面用于作品分享和传播呢?
答案之一是:Streamlit
Streamlit 是一个基于 Python 的 Web 应用程序框架,致力于以更高效、更灵活的方式可视化数据,并分析结果。作为一个开源库,可以帮助数据科学家和学者在短时间内开发机器学习 (ML) 可视化仪表板。只需几行代码,我们就可以构建并部署强大的数据应用程序。
为什么选择Streamlit?
目前,应用程序需求量巨大,开发人员需要一直开发新的库和框架,帮助构建并部署快速上手的仪表板。Streamlit库可将仪表板的开发时间从几天缩短至几小时。以下是选择 Streamlit 的原因:
AI Studio提供了Streamlit
通过 点击 - 文件 - 新建 - Streamlit文件 可以创建一个Streamlit.py程序用于构建即使应用
Streamlit中文使用博客推荐:无需前端技能 用Streamlit部署你的模型
st-chat一款再streamlit中快速构建聊天机器人的插件
地址:Github
首先是安装st-chat,由于AI Studio的Python环境默认为3.7版本,直接pip安装会报错,所以直接git到AI Studio本地进行加载,除了一些报错信息,目前在本项目中运行,AI Studio在本项目中运行from streamlit_chat import message
不会发生错误。
在streamlit.py文件中运行一下示例代码:
import streamlit as st
from streamlit_chat import message
message("My message")
message("Hello bot!", is_user=True) # align's the message to the right
如下图所示,可以看到一个经典的对话框
这里我们举一反三,仿照作者在examples给出的复杂一些/examples/chatbot.py
构建基于PLATO-MINI模型的闲聊机器人
PS:若后续开放了文心一言的API,有key的小伙伴也可以尝试部署为对话机器人,其他的模型和API接口也可以举一反三部署为Chat Bot
先查看例子,看看需要修改什么?
我们没有使用API获得回答,而是通过模型,需要加载模型的代码和通过模型返回答案的函数(原始query函数失效,需重写)
修改一下get_text()为中文“你好!”开始
没有保存历史对话功能,添加一个保存history的列表,增加历史对话保存能力
import streamlit as st from streamlit_chat import message import requests st.set_page_config( page_title="Streamlit Chat - Demo", page_icon=":robot:" ) API_URL = "https://api-inference.huggingface.co/models/facebook/blenderbot-400M-distill" headers = {"Authorization": st.secrets['api_key']} st.header("Streamlit Chat - Demo") st.markdown("[Github](https://github.com/ai-yash/st-chat)") if 'generated' not in st.session_state: st.session_state['generated'] = [] if 'past' not in st.session_state: st.session_state['past'] = [] def query(payload): response = requests.post(API_URL, headers=headers, json=payload) return response.json() def get_text(): input_text = st.text_input("You: ","Hello, how are you?", key="input") return input_text user_input = get_text() if user_input: output = query({ "inputs": { "past_user_inputs": st.session_state.past, "generated_responses": st.session_state.generated, "text": user_input, },"parameters": {"repetition_penalty": 1.33}, }) st.session_state.past.append(user_input) st.session_state.generated.append(output["generated_text"]) if st.session_state['generated']: for i in range(len(st.session_state['generated'])-1, -1, -1): message(st.session_state["generated"][i], key=str(i)) message(st.session_state['past'][i], is_user=True, key=str(i) + '_user')
# 加载模型
from paddlenlp.transformers import UnifiedTransformerTokenizer
from paddlenlp.transformers import UnifiedTransformerLMHeadModel
model_name = 'plato-mini'
model = UnifiedTransformerLMHeadModel.from_pretrained(model_name)
tokenizer = UnifiedTransformerTokenizer.from_pretrained(model_name)
from utils import select_response # 修改query,参数使用源码中的默认值 def query(history): inputs = tokenizer.dialogue_encode( history, add_start_token_as_response=True, return_tensors=True, is_split_into_words=False ) inputs["input_ids"] = inputs["input_ids"].astype("int64") ids, scores = model.generate( input_ids=inputs["input_ids"], token_type_ids=inputs["token_type_ids"], position_ids=inputs["position_ids"], attention_mask=inputs["attention_mask"], max_length=64, min_length=1, decode_strategy="sampling", temperature=1.0, top_k=5, top_p=1.0, num_beams=0, length_penalty=1.0, early_stopping=False, num_return_sequences=20, ) max_dec_len = 64 num_return_sequences = 20 bot_response = select_response( ids, scores, tokenizer, max_dec_len, num_return_sequences, keep_space=False )[0] return bot_response
# 修改后
def get_text():
input_text = st.text_input("用户: ","你好!", key="input")
return input_text
history = []
user_input = get_text()
history.append(user_input)
if user_input:
output = query(history)
st.session_state.past.append(user_input)
st.session_state.generated.append(output)
history.append(output)
import streamlit as st from streamlit_chat import message from utils import select_response # 加载模型 from paddlenlp.transformers import UnifiedTransformerTokenizer from paddlenlp.transformers import UnifiedTransformerLMHeadModel model_name = 'PLATO-MINI' model = UnifiedTransformerLMHeadModel.from_pretrained(model_name) tokenizer = UnifiedTransformerTokenizer.from_pretrained(model_name) st.set_page_config( page_title="PLATO-MINI Chat - Demo", page_icon=":robot:" ) st.header("PLATO-MINI Chat - Demo") st.markdown("[Github](https://github.com/ai-yash/st-chat)") if 'generated' not in st.session_state: st.session_state['generated'] = [] if 'past' not in st.session_state: st.session_state['past'] = [] def query(history): inputs = tokenizer.dialogue_encode( history, add_start_token_as_response=True, return_tensors=True, is_split_into_words=False ) inputs["input_ids"] = inputs["input_ids"].astype("int64") ids, scores = model.generate( input_ids=inputs["input_ids"], token_type_ids=inputs["token_type_ids"], position_ids=inputs["position_ids"], attention_mask=inputs["attention_mask"], max_length=64, min_length=1, decode_strategy="sampling", temperature=1.0, top_k=5, top_p=1.0, num_beams=0, length_penalty=1.0, early_stopping=False, num_return_sequences=20, ) max_dec_len = 64 num_return_sequences = 20 bot_response = select_response( ids, scores, tokenizer, max_dec_len, num_return_sequences, keep_space=False )[0] return bot_response def get_text(): input_text = st.text_input("用户: ","你好!", key="input") return input_text history = [] user_input = get_text() history.append(user_input) if user_input: output = query(history) st.session_state.past.append(user_input) st.session_state.generated.append(output) history.append(output) if st.session_state['generated']: for i in range(len(st.session_state['generated'])-1, -1, -1): message(st.session_state["generated"][i], key=str(i)) message(st.session_state['past'][i], is_user=True, key=str(i) + '_user')
相信大家已经掌握了Taskflow和Streamlit部署PLATO-MINI的正确打开方式,快快动手体验吧!
本项目基于PaddleNLP 一键预测功能。
如果对您有帮助,欢迎star收藏一下,不易走丢哦~链接指路:https://github.com/PaddlePaddle/PaddleNLP
现在,开启你的NLP之旅吧!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。