【AI最佳实践导读】大家好,我是一个拥有8年经验的全栈开发者。我在这个行业中度过了许多精彩的时刻,从我的第一份工作,到在第二家公司度过的近6年的时间,再到我决定成为一名独立开发者,每一步都充满了挑战和收获。现在,我主要从事远程项目开发,并正在研究AI领域的技术,同时也在运营自己的自媒体平台。
在我的职业生涯中,我有幸参与了许多令人兴奋的项目,其中一些涉及到最前沿的技术,如人工智能和机器学习。这些项目不仅让我有机会深入了解这些技术,也让我看到了它们在解决实际问题中的巨大潜力。
今天,我想和大家分享一个项目:使用ChatGLM-6B模型和PaddleNLP实现角色扮演功能。这是一个非常有趣的项目,它让我有机会深入研究这些先进的AI技术,并看到它们在测试中的效果。
在这个教程中,我将向你们展示如何在BML CodeLab上运行这个项目,包括如何设置环境,如何编写代码。我希望这个教程能对你们有所帮助,无论你是一个有经验的开发者,还是一个对AI技术感兴趣的初学者。
什么是ChatGLM-6B
“ChatGLM-6B”是OpenAI的一个特定版本的ChatGLM模型,开源的、支持中英双语的对话语言模型,其中的”6B”表示该模型有60亿(6 billion)的参数。参数的数量通常是衡量一个神经网络模型复杂性和处理能力的一个重要指标。一般来说,参数越多,模型的处理能力越强,但同时也需要更多的计算资源来训练和运行。
这个模型是在大量的文本数据上训练的,包括书籍、网页和其他类型的文本。通过这种训练,模型学习到了如何理解和生成自然语言。在对话任务中,ChatGLM-6B能够根据给定的对话历史生成连贯的回复。
需要注意的是,虽然ChatGLM-6B是一个强大的模型,但它并不完美。由于 ChatGLM-6B 的规模较小,它可能会生成不准确或者不相关的回复,也可能不理解一些复杂的问题。此外,它也不能理解或生成超出其训练数据范围的信息。例如,它不能理解或生成在其训练数据收集结束后发生的事件或信息。
基于ChatGLM-6B模型 + prompt实现角色扮演功能,几句话调教一个专属聊天机器人,几行代码完成聊天机器人应用搭建!
本项目的技术基础是 ChatGLM 和 Prompt。ChatGLM 可以让机器像人类一样进行对话。Prompt 则是一种预设的对话模板,能够帮助机器生成更加准确和流畅的回答。通过结合这两种技术,项目能够提供高度自然和准确的交流体验。
环境设置
在开始编写代码之前,我们需要确保我们的开发环境已经准备就绪。由于我们将在BML CodeLab上运行这个项目,我们需要安装最新版本的Paddle和PaddleNLP。
bash复制代码import paddle
print(paddle.version.cuda())
from IPython.display import clear_output
!unzip paddlenlp.zip
!cp -Rf paddlenlp /home/aistudio/.data/webide/pip/lib/python3.7/site-packages/paddlenlp
# !python -m pip install paddlepaddle-gpu==0.0.0.post112 -f https://www.paddlepaddle.org.cn/whl/linux/gpu/develop.html
# 注意安装后重启内核
# 下次重启该项目后,可能要再安装paddlepaddle-gpu==0.0.0.post112,或者加 --user 避免下次再安装
!python -m pip install paddlepaddle-gpu==0.0.0.post112 -f https://www.paddlepaddle.org.cn/whl/linux/gpu/develop.html --user
clear_output()
print('安装完毕,注意重启内核')
读取模型
ini复制代码import warnings
warnings.filterwarnings("ignore")
import paddle
from paddlenlp.transformers import (
ChatGLMConfig,
ChatGLMForConditionalGeneration,
ChatGLMTokenizer,
)
from predict_convert import convert_example_neko,convert_example, get_response
#读取原始的chatglm-6b模型
model_name_or_path = 'data/data217141'
# model_name_or_path = 'THUDM/glm-515m'
tokenizer = ChatGLMTokenizer.from_pretrained(model_name_or_path)
config = ChatGLMConfig.from_pretrained(model_name_or_path)
paddle.set_default_dtype(config.paddle_dtype)
model = ChatGLMForConditionalGeneration.from_pretrained(
model_name_or_path,
tensor_parallel_degree=paddle.distributed.get_world_size(),
tensor_parallel_rank=0,
load_state_as_np=True,
dtype=config.paddle_dtype,
)
model.eval()
功能设计
问答和历史对话设计
正如前面提到,GLM是个填词模型,对话通过填空实现。故参考了官方的测试代码,用 ‘问:’、‘答:’分别表示用户和系统回复的起始,用 [Round x] 表示轮次来记录历史对话。
通过预载入对话历史(prompt表示),实现模型根据对话填充‘答:’后面的内容
最终变成通过prompt来实现角色设定,利用ChatGLM的填词功能来填充角色对话
在 history = [(‘xxxx’),(‘xx’)] 处修改
括号内前面是用户说,后面是系统答。修改和设计对话历史,让模型顺着前文更好地回答
ini复制代码import os
from IPython.display import clear_output as clear
import json
input_length=2048 # max input length
output_length=160 # max output length
start = 0
history = ''
# 括号内前面是用户说,后面是系统答。修改和设计对话历史,让模型顺着前文更好地回答
history = [('你是一只会说话、会搭建神经网络、精通python的猫猫,可以自由回答问题,像人类一样思考和表达。现在你与我对话时每一句话后面都要加上喵,并加上表情。”。','好的主人喵~🥰'),
('你是?','我是猫猫啊,喵~😅😅')]
auto_query=''
example = {'user_input':'' , 'sys_output':'' ,'history':history}
# # 载入对话历史
# example = np.load('history_chat.npy',allow_pickle=True).tolist()
# example['user_input']=''
print(convert_example(example, tokenizer, get_query=False))
while(1):
user_input = input()
if(user_input==''):
user_input = auto_query
if(user_input== '1'):
print('-----n》》退出')
break
if(user_input== '2'):
# prompt = convert_example_neko(example, tokenizer, get_query=True)
prompt = convert_example(example, tokenizer, get_query=True)
auto_query = get_response(prompt, model, tokenizer, input_length, output_length,print_prompt=False,rand= True)
print('-----n》》是否计划回复(是则直接回车,否则不用管):'+auto_query)
continue
if(user_input== '0'):
user_input_pre = example['history'][-1][0]
example['history'].pop()
# prompt = convert_example_neko(example, tokenizer, get_query=False)
prompt = convert_example(example, tokenizer, get_query=False)
os.system('cls' if os.name == 'nt' else 'clear')
clear()
response = get_response(prompt, model, tokenizer, input_length, output_length,print_prompt=True,rand= True)
print(response)
example['history'].append((user_input_pre,response))
print('-----n》》直接输入进行回复;或者扣1退出;扣2提示一个回复例子;扣9保存对话历史;扣0换一个系统回答;')
continue
if(user_input== '3'):
user_input = '你是谁?我们刚才谈了什么?'
if(user_input== '9'):
import numpy as np
np.save('history_chat',example)
print('对话已保存history_chat.npy')
continue
os.system('cls' if os.name == 'nt' else 'clear')
clear()
example['user_input'] = user_input
# prompt = convert_example_neko(example, tokenizer, get_query=False)
prompt = convert_example(example, tokenizer, get_query=False)
res = get_response(prompt, model, tokenizer, input_length, output_length,print_prompt=True,rand= False)
example['sys_output'] = res
example['history'].append((user_input,res))
print(res)
# 遗忘
while(len(convert_example(example, tokenizer, get_query=False)) +16 >= input_length):
example['history'] = example['history'][1:]
print('-----n》》直接输入进行回复;或者扣1退出;扣2提示一个回复例子;扣9保存对话历史;扣0换一个系统回答;')
角色模板设计 通过prompt来实现角色扮演功能
prompt.json 可以参考****awesome-chatgpt-prompts 如果不想自己下载可以联系我分享
python复制代码with open('prompt.json', 'r') as file:
content = file.read()
prompts = json.loads(content)
outs = []
for i in range(len(prompts)):
outs.append(str(i) +' ' + prompts[i]['act'] + 'n')
print(''.join(outs))
print('》》输入对应的数字查看模板;')
user_input = input()
try:
clear()
prompt = prompts[int(user_input)]['prompt']
print(prompt)
except:
None
res = get_response(prompt, model=model, tokenizer=tokenizer, input_length=1024, output_length=160,print_prompt=False)
print(res)
这只是一个基本的示例,你可以根据自己的需求对其进行修改。例如,你可以创建更多的角色,或者为模型生成的文本添加更多的上下文信息。
小技巧
如何防止内容识别为AI生成的?
-
个性化和情感化:AI生成的内容通常较为客观和中立,缺乏个性化和情感化的元素。在内容中加入一些个人观点、情感色彩或者个人经历等元素,可以使内容更具人性化,从而降低被识别为AI生成的可能性。
-
使用非标准语言和俚语:AI通常在生成内容时会遵循标准语言规则,而人类在交流时往往会使用一些非标准语言、俚语或者地方方言。在内容中适当使用这些非标准语言和俚语,可以使内容更具人性化。
-
避免使用模板:AI生成的内容往往有一定的模板化倾向,如果你的内容中有大量重复的模式或者结构,可能会被识别为AI生成。尽量避免使用固定的模板,让内容更具变化和创新性。
-
加入错误和不完美:人类在写作时往往会有一些小错误或者不完美,而AI生成的内容通常会非常完美,没有任何错误。适当地在内容中加入一些小错误或者不完美,可以使内容更具人性化。
-
结合实际情况:AI在生成内容时,往往无法考虑到所有的实际情况和细节。在内容中加入一些具体的实际情况和细节,可以使内容更具真实感。
如何避免生成重复的内容?
-
使用唯一标识符:在生成内容时,可以为每个内容块分配一个唯一的标识符。然后在生成新的内容块时,检查其是否与已有的标识符重复。这种方法需要一个机制来跟踪和存储已生成的内容。
-
使用检查点:在生成内容的过程中,定期保存检查点。然后在生成新的内容时,从最近的检查点开始,而不是从头开始。这可以避免生成完全相同的内容。
-
使用不同的输入:如果你的AI模型是基于输入生成内容的,那么可以尝试提供不同的输入,以生成不同的内容。例如,你可以改变输入的顺序,或者添加一些随机性。
-
使用多样性参数:一些AI模型允许你设置一个多样性参数,这可以影响生成内容的多样性。通过增加多样性参数,你可以使生成的内容更加多样化,从而减少重复。
-
后处理:在生成内容后,可以使用一些后处理步骤来检测和删除重复的内容。例如,你可以使用一些文本相似度度量来检测重复的内容,然后删除它们。
如何将上下文导入给模型?
-
直接输入:对于一些模型,比如GPT-3,你可以直接将上下文信息作为输入提供给模型。例如,如果你想让模型生成一个故事的续篇,你可以将故事的前半部分作为输入提供给模型。
-
编码上下文:对于一些模型,你可能需要将上下文信息编码为模型可以理解的形式。例如,你可以将上下文信息编码为一个向量,然后将这个向量作为模型的输入。
-
使用上下文感知的模型:一些模型,如Transformer模型,具有内置的机制来处理上下文信息。这些模型可以处理一系列的输入,并在生成每个输出时考虑到所有先前的输入。
-
使用记忆网络:记忆网络是一种特殊的神经网络,它可以在处理序列数据时保留先前的信息。这使得它们非常适合处理需要上下文信息的任务。
以上只是一些基本的方法,具体的实现可能需要根据你的具体情况和需求进行调整。