实现文本分类、信息抽取、文本匹配等任务
前言
在实现文本分类、信息抽取、文本匹配等任务时,可以采用两种主要的方法。首先,可以对一些基础模型进行微调训练,以适应特定任务的需求。这种方法通常需要标注数据,通过调整模型参数来提高其在特定任务上的表现。
其次,基于大模型(如预训练的语言模型)进行任务实现也是一种有效的方法。大模型通常在大规模数据上训练,具备较强的泛化能力和理解能力,可以通过少量的示例进行少量学习(few-shot learning)或零样本学习(zero-shot learning),从而快速适应新的任务。
这里使用基础模型与大语言模型作为对比,实现文本分类、信息抽取、文本匹配等任务,侧重点在于大模型的实现。基础模型选择BERT,大模型选择ChatGLM3-6B。
它们之间的使用存在一定区别,具体区别如下:
BERT:通常需要在特定任务上进行微调,以适应具体应用。
大模型:大模型可以通过提示(prompt)进行零样本或少量样本学习,能够在没有微调的情况下直接用于多种任务。
基础模型BERT:文本分类
因为使用BERT模型实现特定任务,通常需要基于模型进行微调训练,这里仅仅使用Bert模型实现文本分类任务为例说明。
加载模型
导入微调训练的库与加载BERT分词器、BERT模型
python
# 导入必要的库
import torch # PyTorch库,用于深度学习模型的构建和训练
from sklearn.model_selection import train_test_split # 从sklearn库导入用于数据集划分的函数
from transformers import BertTokenizer, BertForSequenceClassification # 从transformers库导入BERT分词器和分类模型
from transformers import Trainer, TrainingArguments # 导入Trainer类和训练参数设置类
from datasets import load_dataset, Dataset # 导入用于加载数据集的函数和Dataset类
# 加载BERT分词器
# 'bert-base-chinese'是预训练的中文BERT模型
tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
# 加载BERT模型用于序列分类
# num_labels=2表示这是一个二分类任务(例如正面和负面情感分类)
model = BertForSequenceClassification.from_pretrained('bert-base-chinese', num_labels=2)
数据准备
这里准备2类小说相关的数据,2类数据各20条,前20条属于爱情小说,后20条属于科幻小说,假设微调训练数据如下
python
# 数据准备
data = {
'text': [
"在乡村小镇,两个青梅竹马的朋友因误会而分开,多年后重逢,重新点燃了爱情的火花。",
"一位年轻女孩在城市中追逐自己的梦想,却意外邂逅了一个温暖的灵魂,改变了她的人生轨迹。",
"在异国他乡,一位游客与当地艺术家展开了一段浪漫的爱情故事,探索文化与心灵的碰撞。",
"一位成功的职场女性在事业巅峰时,遇见了一位温柔的男子,开启了一段意想不到的爱情旅程。",
"通过一封信,一个孤独的女孩与一个神秘的男孩建立了深厚的情感,最终决定相见。",
"两个性格迥异的人在一次音乐节上相遇,彼此吸引,却因生活的压力而面临选择。",
"一位年轻的作家在创作过程中,遇到了自己的灵感来源,展开了一段充满激情的爱情。",
"在一次旅行中,两个陌生人因共同的经历而相知相爱,最终决定一起面对未来。",
"一位失去爱情的女人在朋友的鼓励下,重新开始寻找属于自己的幸福。",
"在一场婚礼上,伴郎与伴娘意外擦出爱的火花,经历了一系列搞笑与感人的事件。",
"一位年轻女孩在社交平台上结识了一个男孩,逐渐发展出一段虚拟而真实的爱情。",
"在一次偶然的相遇中,两个曾经的爱人重新审视彼此的感情,决定给爱情一次机会。",
"在一座神秘的古堡中,一对恋人经历了时间的考验,最终找到了彼此的真爱。",
"一位年轻的摄影师在拍摄过程中,邂逅了一位模特,展开了一段浪漫的爱情故事。",
"两个在同一条街道上生活的邻居,因一场突如其来的暴风雨而走到了一起。",
"一位刚刚经历分手的女孩,在朋友的帮助下,重新找回了对爱情的信心。",
"在一场意外中,两个完全不同背景的人相遇,逐渐发现彼此的心灵契合。",
"一位年轻的音乐家在追求梦想的过程中,遇到了支持她的真爱。",
"在一个古老的图书馆中,一位书迷与一位收藏家的相遇,开启了一段书香爱情。",
"一位女孩在寻找失踪父亲的过程中,遇到了一个愿意陪伴她的男孩,爱情悄然绽放。",
"在一个遥远的星系,一艘宇宙飞船的船员们发现了一种未知的外星生命,改变了他们的命运。",
"地球因环境恶化而陷入危机,一位年轻的科学家研发出一种新技术,试图拯救人类。",
"在未来的城市中,人工智能已成为生活的一部分,但一位程序员发现了AI的潜在威胁。",
"一群探险者在寻找新星球的过程中,意外发现了一个古老文明的遗迹,揭开了历史的秘密。",
"在一个虚拟现实的世界中,一位玩家为了逃避现实,逐渐迷失在游戏中。",
"一位年轻的女工程师在开发太空电梯的过程中,遭遇了来自外星势力的挑战。",
"在未来的社会中,基因编辑技术得到广泛应用,但一场意外导致了不可预知的后果。",
"一位科学家在实验中意外穿越时空,回到过去,试图改变历史的进程。",
"地球即将被外星人入侵,一位普通市民挺身而出,成为人类的英雄。",
"在一个高度发达的科技社会中,一名少女发现了一个关于人类起源的惊天秘密。",
"一位太空探险家在遥远的星球上发现了人类的未来,但必须做出艰难的选择。",
"在未来的城市中,一场关于意识上传的实验引发了伦理与道德的争论。",
"一位年轻的机器人学家创造了一款具有人类情感的机器人,改变了两者的命运。",
"在一个被遗弃的空间站中,幸存者们必须面对内心的恐惧与外部的威胁。",
"地球的资源即将耗尽,一位科学家带领团队寻找新星球的希望与挑战。",
"在一个模拟现实的世界中,人们逐渐失去了对真实生活的感知,陷入了虚幻的迷雾。",
"一位年轻的宇航员在太空任务中,意外发现了外星文明的存在,面临巨大的选择。",
"在未来的社会中,人与机器的界限逐渐模糊,一场关于自由意志的斗争展开。",
"一位天文学家在观察星空时,捕捉到了外星信号,改变了人类的历史。",
"在一个被科技统治的世界里,一位反叛者努力寻找人类的真实情感与自由。"
],
# 0代表爱情小说,1代表科幻小说
'label': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
}
数据预处理
在数据预处理中,主要是将文本进行tokenizer操作
python
# 将字典格式的数据转换为Dataset对象
# data应该是一个包含文本和标签的字典,例如 {'text': [...], 'label': [...]}
dataset = Dataset.from_dict(data)
# 将数据集划分为训练集和测试集,test_size=0.2表示20%的数据用于测试
train_test = dataset.train_test_split(test_size=0.2)
# 定义预处理函数,用于对输入文本进行分词和编码
def preprocess_function(examples):
# 使用tokenizer对文本进行编码,参数说明:
# truncation=True:如果文本长度超过最大长度,则截断文本
# padding='max_length':填充到最大长度,确保所有输入长度一致
# max_length=512:设置最大长度为512(BERT模型的最大输入长度)
return tokenizer(examples['text'], truncation=True, padding='max_length', max_length=512)
# 对训练集和测试集应用预处理函数,batched=True表示一次处理多个样本以提高效率
tokenized_datasets = train_test.map(preprocess_function, batched=True)
模型训练
设置训练参数、创建训练器并进行模型训练和评估
python
# 定义训练参数
training_args = TrainingArguments(
output_dir='./results', # 模型和结果保存的目录
evaluation_strategy='epoch', # 评估策略,这里设置为每个训练周期(epoch)后进行评估
learning_rate=2e-5, # 学习率,控制模型更新的步伐
per_device_train_batch_size=8, # 每个设备(GPU/CPU)上的训练批次大小
per_device_eval_batch_size=8, # 每个设备上的评估批次大小
num_train_epochs=3, # 训练的总周期数
weight_decay=0.01, # 权重衰减,用于正则化,防止过拟合
logging_dir='./logs', # 日志保存目录
logging_steps=10, # 每10步记录一次日志
)
# 创建Trainer对象,负责模型的训练和评估
trainer = Trainer(
model=model, # 传入要训练的模型
args=training_args, # 传入训练参数
train_dataset=tokenized_datasets['train'], # 训练数据集
eval_dataset=tokenized_datasets['test'], # 评估数据集
)
# 开始训练模型
trainer.train()
# 在评估数据集上评估模型性能
trainer.evaluate()
训练输出说明:
40/40:表示当前训练过程中已经处理的步骤(steps)数量和总步骤数量。在这里,"40"表示模型在整个训练过程中总共进行了40个步骤。这通常是指在所有训练周期(epochs)中累积的步骤数,而不是每个周期的步骤数。
00:05:表示当前训练已经持续的时间,这里是5秒。
Epoch 5/5:表示当前训练周期是第5个周期,总共进行5个周期的训练。
Epoch:表示训练的周期数。在这里,共进行了5个训练周期(Epoch 1, 2, 3, 4, 5)。
Training Loss:训练损失。每个epoch结束时记录的训练损失值。它反映了模型在训练集上的表现。这里有一些epoch的训练损失值:
Epoch 1: 没有记录(No log),可能是由于在第一个周期没有完成足够的训练步骤来计算损失。
Epoch 2: 训练损失为 0.008400
Epoch 3: 训练损失为 0.003800
Epoch 4: 训练损失为 0.001600
Epoch 5: 训练损失为 0.001000
从这些值可以看出,训练损失随着训练周期的增加而逐渐降低,表明模型在训练集上的表现有所改善。
Validation Loss:验证损失。每个epoch结束时记录的验证损失值,表示模型在验证集上的表现。具体值如下:
Epoch 1: 验证损失为 0.005392
Epoch 2: 验证损失为 0.002440
Epoch 3: 验证损失为 0.001267
Epoch 4: 验证损失为 0.000874
Epoch 5: 验证损失为 0.000786
验证损失也显示出逐渐下降的趋势,这通常意味着模型在学习和泛化能力上有所提升。
计算步骤数
在训练过程中,步骤(steps)的数量通常是通过以下公式计算得出的:
python
steps = 训练样本数 / 每批次样本数
根据公式可以计算总的steps:
python
训练样本数 = 32(从40条数据中按80%划分得到)
每批次样本数 = 4(per_device_train_batch_size=4)
因此,训练步骤的数量为:steps = 32 / 4 = 8
这意味着在每个epoch中,模型会进行8个训练步骤。
评估输出说明:
eval_loss: 模型在验证集上的损失值。较低的损失值通常表示模型在验证集上的表现良好,能够更好地拟合数据。在您的情况下,这个值非常小,表明模型在验证集上具有很好的性能。
eval_runtime: 进行验证评估所花费的总时间,单位为秒。在这个例子中,模型在验证集上评估的时间为0.0917秒。
eval_samples_per_second: 模型在验证集上每秒处理的样本数量。在这个例子中,模型每秒处理约87.252个样本。这是一个重要的性能指标,反映了模型的评估速度。
eval_steps_per_second: 模型在验证集上每秒处理的训练步骤数量。在这个例子中,模型每秒进行约21.813个步骤。这个值通常会比样本处理速度慢,因为每个步骤可能处理多个样本(取决于批次大小)。
epoch: 表示当前评估是在第5个训练周期(epoch)完成后进行的。这与之前的训练输出一致,表明模型在完成所有5个训练周期后进行了验证评估。
保存模型
将经过微调训练的模型保存到本地目录
python
from transformers import AutoModelForSequenceClassification, AutoTokenizer
# 保存模型的实际路径
model.save_pretrained("./models/my-bert-base-chinese")
# 保存模型的权重和配置文件,同时也保存tokenizer
tokenizer.save_pretrained("./models/my-bert-base-chinese")
加载模型进行推理
python
from transformers import AutoModelForSequenceClassification, AutoTokenizer
import torch
model_path = "./models/my-bert-base-chinese"
# 加载模型和 tokenizer
model = AutoModelForSequenceClassification.from_pretrained(model_path)
tokenizer = AutoTokenizer.from_pretrained(model_path)
# 将模型设置为评估模式
model.eval()
# 准备输入数据
input_text = "在繁华的都市中,两个年轻人因一次偶然的相遇而相识,随着时间的推移,他们的感情经历了甜蜜与磨难,最终找到了彼此的真爱。"
inputs = tokenizer(input_text, return_tensors="pt")
# 进行推理
with torch.no_grad(): # 在推理时不需要计算梯度
outputs = model(**inputs)
# 从输出中提取 logits
logits = outputs.logits
# 获取预测类别
predictions = torch.argmax(logits, dim=-1)
# 输出预测结果
print(f"预测类别: {predictions.item()}")
不出意外,将成功预测分类结果,输出结果如下:
大模型:文本分类
加载模型
加载chatglm3-6b预训练模型和相应的分词器
python
# 从 transformers 库导入 AutoTokenizer 和 AutoModel,用于加载预训练模型和分词器
from transformers import AutoTokenizer, AutoModel
# 指定模型的路径
model_path = '/root/work/models/chatglm3-6b'
# 从指定路径加载预训练的分词器,设置 trust_remote_code 为 True 以信任远程代码
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
# 从指定路径加载预训练的模型,设置 trust_remote_code 为 True 以信任远程代码,并以 8 位模式加载
model = AutoModel.from_pretrained(model_path, trust_remote_code=True, load_in_8bit=True)
# 将模型设置为评估模式,以便在推理时禁用训练特性(如 dropout)
model = model.eval()
数据
定义一些用于文本分类的类别样例测试数据
python
class_examples = {
'爱情小说': '在繁华的都市中,两个年轻人因一次偶然的相遇而相识,随着时间的推移,他们的感情经历了甜蜜与磨难,最终找到了彼此的真爱。',
'科幻小说': '在不远的未来,地球面临着资源枯竭的危机。一位年轻的科学家带领团队探索外星球,希望找到适合人类生存的新家园。',
'悬疑小说': '一桩离奇的谋杀案震惊了整个小镇,侦探在调查过程中发现了隐藏在每个人心中的秘密,真相逐渐浮出水面。',
'历史小说': '故事发生在古代王朝,讲述了一位勇敢的女将军如何在战乱中保护自己的家园,并最终改变了国家的命运。',
'奇幻小说': '在一个魔法与怪兽共存的世界里,一位年轻的魔法学徒踏上了寻找失落王国的冒险之旅,途中结识了各种奇异的伙伴。',
'成长小说': '一个普通的少年在面对家庭和学业压力时,逐渐学会了如何面对生活中的挑战,最终实现了自我成长与蜕变。'
}
构建提示Prompt
创建一个init_prompt_template()
函数,用于初始化前置prompt,以便模型进行Few-shot少量示例学习
python
# 初始化提示Prompt函数
def init_prompt_template():
# 获取所有分类的类别列表
class_list = list(class_examples.keys())
# 初始化预设的对话历史记录
pre_history = [
{"role": "user", "content": f'现在你是一个文本分类器,请你按照要求将我给你的句子分类到:{class_list}类别中。'},
{"role": "assistant", "content": "好的。"}
]
# 遍历给定的示例样本
for key, value in class_examples.items():
# 将用户的请求添加到历史记录中,询问每个示例的类别
pre_history.append({"role": "user", "content": f'"{value}"是{class_list}中的什么类别?'})
# 将模型的回答(类别)添加到历史记录中
pre_history.append({"role": "assistant", "content": key})
# 返回包含类别列表和预设历史记录的字典
return {"class_list": class_list, "pre_history": pre_history}
得到预处理的Few-shot少量学习示例:
定义推理函数
创建一个inference()
推理函数,传入参数sentences:待推理的句子列表,同时传入参数init_prompts:初始设定的少量few-shot示例
python
def inference(sentences: list, init_prompts: dict):
# 遍历每个待推理的句子
for sentence in sentences:
# 构造用于推理的提示句
sentence_prompt = f'"{sentence}"是{init_settings["class_list"]}中的什么类别?'
# 调用模型进行推理,获取响应和历史记录
response, history = model.chat(tokenizer, sentence_prompt, history=init_prompts['pre_history'])
# 打印句子和推理结果
print(f'>>> 待分类文本: {sentence}')
print(f'>>> 推理回答: {response}')
print(f'>>> history: {history}')
# 分隔输出
print("-" * 100)
执行文本分类测试
准备一些测试文本数据,调用初始化提示示例与执行推理操作。
python
# 文本分类句子
sentences = [
'在一个充满魔法的王国中,年轻的女巫发现自己拥有改变命运的力量,她必须与黑暗势力斗争,以拯救她的家园。',
'一位著名作家的神秘失踪引发了一场媒体风暴,记者在调查中揭开了隐藏在辉煌背后的阴暗秘密。',
'在一个小镇上,两个青梅竹马的朋友因误解而分开,经过多年的生活磨砺,他们终于在一次偶然的重逢中重新找到了彼此。'
]
# 少量示例
init_prompts = init_prompt_template()
# 推理
inference(sentences, init_prompts)
推理结果下:
大模型:信息抽取
加载模型
加载chatglm3-6b预训练模型和相应的分词器
python
# 从 transformers 库导入 AutoTokenizer 和 AutoModel,用于加载预训练模型和分词器
from transformers import AutoTokenizer, AutoModel
# 指定模型的路径
model_path = '/root/work/models/chatglm3-6b'
# 从指定路径加载预训练的分词器,设置 trust_remote_code 为 True 以信任远程代码
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
# 从指定路径加载预训练的模型,设置 trust_remote_code 为 True 以信任远程代码,并以 8 位模式加载
model = AutoModel.from_pretrained(model_path, trust_remote_code=True, load_in_8bit=True)
# 将模型设置为评估模式,以便在推理时禁用训练特性(如 dropout)
model = model.eval()
数据
定义一些用于信息抽取的实体属性与示例数据
bash
# 定义关于书籍的实体属性
schema = ['日期', '书名', '售价', '销量', '作者']
# 示例数据
data_examples = [
{
'content': '2024-05-15,《梦境探险者》在全国范围内发布,首日销量达到50000本,成为畅销书。作者小李表示,故事灵感来源于他的旅行经历。',
'answers': "{'日期': '2024-05-15', '书名': '梦境探险者', '销量': '50000本', '作者': '小李'}"
},
{
'content': '2023-11-20,小说《时间的旅人》正式上市,开售价格为80元,第一周销量突破30000本,受到了读者的广泛好评。',
'answers': "{'日期': '2023-11-20', '书名': '时间的旅人', '售价': '80元', '销量': '30000本', '作者': ''}"
},
{
'content': '作家阿华的新书《星际迷航》在书展上发布,售价为120元,预售期间已售出15000本,备受期待。',
'answers': "{'日期': '', '书名': '星际迷航', '售价': '120元', '销量': '15000本', '作者': '阿华'}"
}
]
构建提示Prompt
创建一个init_prompt_template()
函数,用于初始化前置prompt,以便模型进行Few-shot少量示例学习
bash
# 信息抽取的模版
template = "对于已知句子: {} \n请提取其中关于{}的实体,并按照JSON格式输出(包含所有实体),当句子中不存在实体信息时请使用''作为提取结果表示,多个值之间用,分隔。"
def init_prompt_template():
"""
初始化前置prompt,便于模型做学习。
"""
# 初始化一个列表,用于存储用户和助手的对话历史
pre_history = [
# 用户请求信息抽取的任务说明
{"role": "user", "content": "现在你需要帮助我完成信息抽取任务,当我给你一个句子时,你需要帮我抽取出句子中实体信息,并按照JSON的格式输出(包含所有实体),当句子中不存在实体信息时请使用''作为提取结果表示,多个值之间用,分隔"},
# 助手确认
{"role": "assistant", "content": "好的。"},
]
# 遍历数据示例以构建对话历史
for row in data_examples:
# 从当前示例中提取句子和答案
sentence = row["content"]
answers = row["answers"]
# 将句子和提取目标格式化到模板中
sentence_with_prompt = template.format(sentence, schema)
# 将格式化后的句子添加到对话历史中
pre_history.append({"role": "user", "content": sentence_with_prompt})
# 将模型的回答添加到历史记录中
pre_history.append({"role": "assistant", "content": answers})
# 返回包含对话历史的字典
return {"pre_history": pre_history}
经过处理的对话内容如下:
定义推理函数
创建一个inference()
推理函数,传入参数sentences:待推理的句子列表,同时传入参数init_prompts:初始设定的少量few-shot示例
bash
def inference(sentences: list, init_prompts: list):
"""
推理函数。
Args:
sentences (List[str]): 待抽取的句子。
init_prompts (dict): 初始设定,包含人为给定的 few-shot example。
"""
# 遍历待处理的句子列表
for sentence in sentences:
# 使用模板格式化当前句子
sentence_with_prompt = template.format(sentence, schema)
# 获取初始化的对话历史
history = init_prompts["pre_history"]
# 调用模型的 chat 方法进行推理,获取响应和更新后的历史
response, history = model.chat(tokenizer, sentence_with_prompt, history=history)
# 打印待提取的文本
print(f'>>> 待提取文本: {sentence}')
# 打印模型的推理回答
print(f'>>> 推理回答: {response}')
print("\n\n")
执行信息抽取测试
准备一些测试数据,同时初始化Prompt,一同传递给推理函数执行推理
python
# 测试数据
sentences = [
'2023-06-10,《夏日微风》在全国发布,开售价格为90元,首周销量达到25000本,作者小张表示非常感谢读者的支持。',
'2024-03-05,小说《逆风飞翔》在书店上架,定价75元,首日销量为18000本,受到读者热烈追捧。',
'《未来之门》正式上市,售价100元,预售期间已售出12000本,作者小李对此表示满意。',
]
# 少量示例
init_prompts = init_prompt_template()
# 推理
inference(sentences, init_prompts)
执行推理,得到预期结果,具体内容如下:
大模型:文本匹配
加载模型
加载chatglm3-6b预训练模型和相应的分词器
python
# 从 transformers 库导入 AutoTokenizer 和 AutoModel,用于加载预训练模型和分词器
from transformers import AutoTokenizer, AutoModel
# 指定模型的路径
model_path = '/root/work/models/chatglm3-6b'
# 从指定路径加载预训练的分词器,设置 trust_remote_code 为 True 以信任远程代码
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
# 从指定路径加载预训练的模型,设置 trust_remote_code 为 True 以信任远程代码,并以 8 位模式加载
model = AutoModel.from_pretrained(model_path, trust_remote_code=True, load_in_8bit=True)
# 将模型设置为评估模式,以便在推理时禁用训练特性(如 dropout)
model = model.eval()
数据
python
text_matching_data = [
{
'sentence1': '《星际探险》讲述了一群宇航员探索未知星球的故事。',
'sentence2': '小说《星际探险》描述了宇航员们在外太空的冒险经历。',
'result': '相似'
},
{
'sentence1': '《爱情花园》描绘了一段浪漫的爱情故事。',
'sentence2': '《战争与和平》是一本关于历史和战争的小说。',
'result': '不相似'
},
{
'sentence1': '在《魔法学院》中,主人公学习如何使用魔法。',
'sentence2': '《魔法学院》这本书讲述了一个年轻人学习魔法的历程。',
'result': '相似'
},
{
'sentence1': '《时间旅行者》描述了主人公穿越时空的冒险。',
'sentence2': '《时间旅行者》这本书讲述了一个人在不同时间点的经历。',
'result': '相似'
},
{
'sentence1': '《侦探故事》中的侦探解决了一系列复杂的案件。',
'sentence2': '《美食之旅》是一部关于美食和旅行的小说。',
'result': '不相似'
}
]
构建提示Prompt
python
def init_prompt_template():
pre_history = [
(
'请帮助我完成文本匹配任务,当我给你两个句子时,你需要回答我这两句话语义是否相似。只需要回答: `相似`或`不相似`,不要做多余的回答。',
'明白,我将只回答`相似`或`不相似`。'
)
]
for row in text_matching_data:
sentence1 = row['sentence1']
sentence2 = row['sentence2']
result = row['result']
pre_history.append({"role": "user", "content": f'句子1:{sentence1} \n句子2:{sentence2} \n上述两句话的语义相似吗?'})
pre_history.append({"role": "assistant", "content": result})
return {"pre_history": pre_history}
得到预处理的少量学习示例:
定义推理函数
定义inference ()
推理函数用于判断给定句子对的语义相似性。
python
def inference(sentences: list, init_prompts: list):
"""
推理函数,用于判断句子对的语义相似性。
Args:
sentences (List[dict]): 包含句子对的字典列表,每个字典包含'sentence1'和'sentence2'。
init_prompts (dict): 初始设定,包含人为给定的 few-shot example。
"""
# 遍历待处理的句子对列表
for row in sentences:
# 从当前行中提取句子1和句子2
sentence1 = row['sentence1']
sentence2 = row['sentence2']
# 构建提示内容,询问两个句子的语义相似性
prompt = f'句子1: {sentence1} \n句子2: {sentence2} \n上述两句话的语义相似吗?'
# 获取初始化的对话历史
history = init_prompts['pre_history']
# 调用模型的 chat 方法进行推理,获取响应和更新后的历史
response, history = model.chat(tokenizer, prompt, history=history)
# 打印待匹配的文本
print(f'>>> 待匹配文本: \n{prompt}')
print("\n")
# 打印模型的推理回答
print(f'>>> 推理回答: {response}')
print("\n\n")
执行文本匹配测试
准备一些测试数据,同时初始化Prompt,一同传递给推理函数执行推理
python
sentences =[
{
'sentence1': '《魔法学院》是一本关于学习魔法的书。',
'sentence2': '《魔法学校》讲述了一个年轻人学习魔法的故事。',
},
{
'sentence1': '《奇幻之旅》讲述了一位年轻魔法师的冒险故事。',
'sentence2': '《科技未来》探讨了未来科技的发展。',
},
{
"sentence1": "《时间旅行者》讲述了主人公穿越不同历史时期的经历。",
"sentence2": "《未来之书》探讨了科技对人类生活的影响。"
}
]
# 少量示例
init_prompts = init_prompt_template()
# 推理
inference(sentences, init_prompts)
推理结果下: