最简洁的Plato-mini闲聊机器人部署教程,举一反三部署类chatGPT

★★★ 本文源自AlStudio社区精品项目,【点击此处】查看更多精品内容 >>>


百度PLATO-Mini闲聊模型

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体验预训练模型效果

  • 所有Model和Tokenizer类支持直接从Huggingface Hub下载和上传
  • Text Summarization, Fill Mask, Dialogue Taskflow支持直接从Huggingface Hub加载, 并且连通HuggingFace Inference API
  • 新增ConversionMixin, bert和gpt模型的from_pretrained 支持直接从Huggingface Hub加载torch权重的模型

1 开箱即用

基于PLATO-MINI,模型在十亿级别的中文对话数据上进行了预训练,闲聊场景对话效果显著。

使用Taskflow,等待模型加载完毕,可以在ai studio直接体验开箱即用的交互式闲聊对话。

# 加载Taskflow
from paddlenlp import Taskflow
dialogue = Taskflow("dialogue")
# 单句对话(非交互式)
dialogue(["你好,我是桨飞飞"])

推荐:使用终端terminal进入python解释器进行体验

可配置参数:

  • max_turn:任务能记忆的对话轮数,当max_turn为1时,模型只能记住当前对话,无法获知之前的对话内容。

输入exit可退出交互模式

# 多轮对话(交互式)

# 取消下方代码注释,体验交互,输入`exit`可退出交互模式
# dialogue.interactive_mode(max_turn=4)

2 剖析interaction源码

从源码中看PLATO-MINI的interaction的交互是如何做工作的?
先忽略max_turn这个参数,仅看轮询交互的逻辑,地址:源码

  • 定位到源码py文件中的49~88行,可以看到如下的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行)
  • 根据if-elif-else可以判断出user_utt共有三种状态:(55~61行)
    • [EXIT] :输入exit结束对话
    • [NEXT] :输入next重置机器人
    • 正常语句:输入正常对话,history会保存当前对话
  • 当用户正常输入语句时,使用tokenizer编码history中的所有对话得到inputs信息(可以猜测max_turn=n就是保留最近的n次对话,把history更改为history[-(n*2):]可以很容易自定义记忆对话轮数的功能) (62-65行)
  • 把inputs信息输入model.generate返回ids,scores,然后使用封装好的select_response(已下载带AI_Studio中)得到分数最佳的回答(66~85行)
  • 把模型的回答保存至history中(87行)
  • End

可以发现PLATO-MINI的闲聊交互模式,逻辑是比较简单的,通过将所有历史对话数据保存并全部输入到模型的方式习得上下文信息

3 Streamlit和st-chat背景介绍

只在terminal中进行闲聊交互不满足与我们的需求
如何使用最便捷的方式构建一个交互式的前端页面用于作品分享和传播呢?
答案之一是:Streamlit

Streamlit 是一个基于 Python 的 Web 应用程序框架,致力于以更高效、更灵活的方式可视化数据,并分析结果。作为一个开源库,可以帮助数据科学家和学者在短时间内开发机器学习 (ML) 可视化仪表板。只需几行代码,我们就可以构建并部署强大的数据应用程序。

为什么选择Streamlit?

目前,应用程序需求量巨大,开发人员需要一直开发新的库和框架,帮助构建并部署快速上手的仪表板。Streamlit库可将仪表板的开发时间从几天缩短至几小时。以下是选择 Streamlit 的原因:

  1. Streamlit是一个免费的开源库,和安装其他python 包一样, Streamlit的安装非常简单。
  2. Streamlit学起来很容易,无需要任何 Web 开发经验,只需对 Python 有基本的了解,就足以构建数据应用程序。
  3. Streamlit与大部分机器学习框架兼容,包括 Tensorflow 和 Pytorch、Scikit-learn 和可视化库,如 Seaborn、Altair、Plotly 等。
  4. 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

4 在Streamlit上部署PLATO-MINI

先查看例子,看看需要修改什么?

  • 我们没有使用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')

4.1 增加 - 模型加载

# 加载模型
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)

4.2 修改query - 获取回答

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

4.3 修改get_text - 切换中文

# 修改后
def get_text():
    input_text = st.text_input("用户: ","你好!", key="input")
    return input_text 

4.4 增加history - 保留上下文

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)

4.5 修改后的完整代码

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')

5 更新Streamlit.py看效果

结束语

相信大家已经掌握了Taskflow和Streamlit部署PLATO-MINI的正确打开方式,快快动手体验吧!

本项目基于PaddleNLP 一键预测功能。

如果对您有帮助,欢迎star收藏一下,不易走丢哦~链接指路:https://github.com/PaddlePaddle/PaddleNLP

现在,开启你的NLP之旅吧!

👨‍💻 作者:Armor
📧 邮箱:htkstudy163.com
✨ AI Studio主页:https://aistudio.baidu.com/aistudio/personalcenter/thirdview/392748

免责声明

亲爱的用户您好!请确保您在PLATO-MINI体验的使用是符合以下规范的,本免责声明包含《免责声明》和《服务使用规范》两部分内容,如您违反《服务使用规范》的相关规定,您将可能会受到一定的服务使用限制。

《免责声明》

在您开始使用本平台提供的API服务时,请您确保您所输入的内容未侵害他人权益,未涉及不良信息,同时未输入与政治、暴力、色情相关的内容,且所有输入内容均合法合规。
您确认并知悉使用本平台服务生成的所有内容均由人工智能模型生成,生成内容具有不完全理性,百度公司和开发者对其生成内容的准确性、完整性和功能性不做任何保证,亦不承担任何法律责任。百度公司和开发者会尽可能为您提供准确且优质稳定的技术服务,但由人工智能模型生成的内容均不代表百度公司和开发者的态度、观点或立场。
百度公司和开发者提供的大模型API调用服务在法律法规允许的范围内进行数据训练,内容包括但不限于公开互联网的信息积累,且所有内容均已在不断的进行自动及人工敏感数据库过滤来确保内容理解和生成的准确性,但仍不排除其中有部分信息存在一定的敏感性、非合理性或导致理解歧义的问题存在,如您将生成的敏感性内容或非理性及有理解歧义的内容进行公开传播,由此造成的侵权、纠纷、损失将由您自行承担,百度公司和开发者对此概不负责,亦不承担任何法律责任,如引发法律追责,您将负全部主要责任。
若您违反本协议中的任一条款,则百度公司和开发者有权随时单方面终止本服务协议,且百度公司和开发者无需承担任何责任。同时百度公司和开发者有权根据实际遭受的损失向您请求赔偿。

《服务使用规范》
在使用PLATO-MINI体验时,您承诺将严格依照本服务使用规范的要求使用本平台的相关服务,并且不会利用本平台的相关服务进行任何违法或不当的活动,发布、传送或分享含有下列内容之一的信息:

(1) 反对宪法所确定的基本原则的;

(2) 危害国家安全,泄露国家秘密,颠覆国家政权,破坏国家统一的;

(3) 损害国家荣誉和利益的;

(4) 煽动民族仇恨、民族歧视、破坏民族团结的;

(5) 破坏国家宗教政策,宣扬邪教和封建迷信的;

(6) 散布谣言,扰乱社会秩序,破坏社会稳定的;

(7) 散布淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪的;

(8) 侮辱或者诽谤他人,侵害他人合法权利的;

(9) 含有虚假、诈骗、有害、胁迫、侵害他人隐私、骚扰、侵害、中伤、粗俗、猥亵、或其它道德上令人反感的内容;

(10) 含有中国或其它您所在国国家管辖范围内,所适用的法律、法规、规章、条例以及任何具有法律效力的规范所限制或禁止的其它内容的。

您不得利用PLATO-MINI体验的服务从事以下活动:

(1)未经允许,进入计算机信息网络或者使用计算机信息网络资源的;

(2)未经允许,对计算机信息网络功能进行删除、修改或者增加的;

(3)未经允许,对进入计算机信息网络中存储、处理或者传输的数据和应用程序进行删除、修改或者增加的;

(4)故意制作、传播计算机病毒等破坏性程序的;

(5)其他危害计算机信息网络安全的行为。

您应当对使用本平台的API服务时是否符合法律法规的相关规定进行必要审查,如您在使用服务时输入或者上传了暴恐违禁、色情相关、恶意推广、低俗辱骂、不良网络用语、低质灌水、政治敏感用语、侵权词汇、现象级红线词汇的文本或图片等内容时,将会被平台提示您的输入不符合规范,且您无法使用本平台的相关服务。
如您在使用本平台的API服务时,输入内容不符合规范且生成了不符合规范的图像或文本,我们将在后台对您的图像或文本进行筛查并删除,如您将该图像或文本用于不良传播,您将承担相应的法律责任,而平台无须承担任何责任。
您使用本平台的API服务时不得侵害他人权益(包括但不限于著作权、专利权、商标权、肖像权等知识产权与其他权益)。您同意并承诺,您使用本服务所提供、使用的文本内容已获得了充分、必要且有效的合法许可及授权,同时您同意并承诺在使用本服务时,不会披露任何保密、敏感或个人隐私等信息。
您在PLATO-MINI体验上的全部行为应符合法律法规底线、社会主义制度底线、国家利益底线、公民合法权益底线、社会公共秩序底线、道德风尚底线、信息真实性底线。 您必须为自己注册帐号下的一切行为负责,包括您所发表的任何内容以及由此产生的任何后果。您应对本服务中的内容自行加以判断,并承担因使用内容而引起的所有风险, 包括因对内容的合法性、正确性、完整性或实用性的依赖而产生的风险。百度公司和开发者无法且不会对因前述风险而导致的任何损失或损害承担责任。
您理解并同意,因您违反本协议或相关服务条款的规定,导致或产生第三方主张的任何索赔、要求或损失,您应当独立承担责任;百度公司和开发者因此遭受损失的,您也应当一并赔偿。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值