大模型如何构建自己的数据集,以及停用词的使用实战
角色身份+任务具体目标+任务背景+输出示例+原文内容。
我自己构建数据集的方式,其实就是用大模型的能力提升自己想要的小模型,整体思路是我先用目前已知的大模型,比如文心一言或者Kimi生成训练集,人工质检训练集后,送入小模型训练出自己场景的模型,比如Qwen2-7B-Instruction,最后部署模型。
一、构建大模型训练集
1.1. 规划Prompt模板设计示例:
角色身份+任务具体目标+任务背景+输出示例+原文内容
1.2.使用大模型进行数据预标注
第一步构建提示词模板,根据自己的项目问答需求,使用kimi link:协助进行prompt优化,下文有详细讲解
第二步利用提示词模板,调用kimi的api进行批量标注,
注意 将输出结果转化成模型训练需要的格式
from openai import OpenAI
client = OpenAI(
api_key=" 填写自己的key",
base_url="https://api.moonshot.cn/v1",
)
completion = client.chat.completions.create(
model="moonshot-v1-8k",
messages=[
{
"role": "system",
"content": "你是一位行业高级专家,具备深厚的行业知识,请基于你的专业知识,对提供的【原文】进行分析,并完成以下任务。"
},
{
"role": "user",
"content": "【任务1】:相关性判断\n- **目标**:判断【原文】XXXX\n- **输出格式**:思考过程 + #### + 结论。\n"
"【任务2】:相关性判断\n- **目标**:\n- **提醒**:\n \n- **输出格式**:#### + 结论。"
"内容替换掉上述模板中的`【原文】`部分。"
},
],
temperature=0.3,
# stream=True,
)
results=completion.choices[0].message.content
for i in results.split():
print(i)
1.3.prompt构建的关键点
在大模型领域,prompt是一种结构化的输入序列,用于引导预训练模型生成预期的输出,通常包含任务要求,背景信息,格式规定以及示例,以充分利用模型的能力在特定任务中生成高质量的响应,构建原则,清晰明了,表达简单直白。
构建prompt的四大要素
1.3.1.明确目标和任务
使用清晰简洁和准确的语言,有助于缩小模型的输出范围,减少误解和生成不相关内容的风险,从而提高生成内容的质量和相关性,
1.3.2.上下文和背景信息
举个例子
假设你是一名城市规划师,正在为一个新兴城市设计一项公共交通系统。请撰写一份报告,评估当前已有的一些全球先进城市的交通系统,包括它们的优缺点和用户满意度情况。报告应包含对每个交通系统的详细分析,并提出适应你所在城市的建议。对应的上下文:
1.角色和身份:城市规划师
2. 任务的具体目标:为新兴城市设计公共交通系统
3. 相关历史和现状:
- 当前城市的交通现状
- 系统需求的背景和动力
- 特定要求和条件:
- 需要评估全球已有先进交通系统的优缺点
- 必须分析用户满意度
- 读者或受众:城市管理层及相关公众
通过提供这些上下文和背景信息,模型能够理解任务的背景,识别关键因素并生成有效和相关的建议。例如,模型会更倾向于提供实用的、在你的新兴城市中可行的交通系统建议,而不是泛泛而谈。这样可以确保任务的完成更符合实际需求和目的。
1.3.3 详细的衡量标准或考评维度
优秀的prompt应具备实现任务目标详细的衡量标准或者考评维度。提供清晰,全面,高效的评估,确保prompt达成目标客观且有据可依,从而有效实现任务目标
1.3.4 明确的输入和输出格式
输入格式是指模型接收的原始数据的结构和形式。明确的输入格式定义了数据应该如何组织和呈现,以确保模型能够正确解析和理解这些数据。输出格式是指模型生成结果的预期结构和形式。明确的输出格式定义了模型应该如何组织和呈现生成的内容,以满足特定的需求或标准。
示例输入和输出语法正确,结构清晰,语言通顺易懂
8个指标优化
1.4.1 样本和示例
在提示工程中,样本是特定任务中用来指导和帮助模型理解任务要求的具体输入输出配对。样本可以是one-shot或few-shot,并且在提示的上下文中常常用于提供明确的任务示例。
1.One-shot 示例:
提供给模型的单个输入输出配对示例,帮助模型理解任务要求和期望的输出格式。适用于模型已有相关领域知识时。
适用场景:模型已有一定基础知识,只需要一个示例来了解具体格式和期望输出。
2.Few-shot 示例:
提供给模型的多个(通常是2-5个)输入输出配对示例,进一步明确任务细节和复杂性。适用模型对任务有一定了解但需要更多具体示例时。
适用场景:任务较复杂,或者模型对任务不够熟悉,需要通过多个示例来学习任务特征
样本和衡量标准
1.文本分类任务:
衡量标准:分类准确率、召回率。
样本关系:提供正负样本和中立分类的示例,帮助模型理解分类边界。
2.情感分析任务:
衡量标准:分类正确性(正面、中性、负面)、文本流畅度。
样本关系:多情感示例展示,使模型更好地捕捉情感细节。
3.翻译任务:
衡量标准:译文准确性、流畅性、语法正确性。
样本关系:双语示例帮助模型掌握准确的翻译对,确保译文忠实且流畅。
4.文本摘要任务:
衡量标准:摘要内容覆盖率、简洁度、流畅度。
样本关系:展示长文本和对应的高质量摘要,使模型学习如何提炼关键信息。
5.问答任务:
衡量标准:回答准确性、完整性、相关性。
样本关系:通过问答对示例,指导模型生成准确且相关的答案。
1.4.2 简洁和直接
PROMPT应避免不必要的背景信息和复杂措辞,明确指令、内容精简、直达要点,明确任务要求以便模型能够迅速聚焦任务,准确生成内容。
简洁性:去除了冗长的描述,指令内容简明扼要。
直接性:明确任务要求,聚焦于总结核心观点和主题思想。
易执行:简洁明确的指令减少了误解的可能性,使执行者能够迅速聚焦任务。
1.4.3 避免歧义
避免出现多义词,模糊短语,明确指代对象
1.4.4 分步骤和层次化的指导
分步骤是指将一个复杂任务分解成多个简单且明确的步骤,每一个步骤都被清晰地表述。这种方法通过细化任务,减少复杂性,以确保每一环节都可以独立理解和执行。例如,在撰写一份研究报告时,将任务分解为选择主题、进行文献综述、设计研究方法、数据收集与分析、撰写报告等五个独立的步骤,使得每一步都有明确的目标和方法。
在撰写一份关于人工智能伦理问题的研究报告时:
-
选择主题
-
进行文献综述
-
设计研究方法
-
数据收集与分析
-
撰写报告
层次化信息是指通过分级和组织信息,引导用户逐步深入理解和解决问题。在这种结构中,高层次的信息提供总体框架和逻辑顺序,低层次的信息细化具体内容和操作细节。例如,在撰写报告的过程中,可以先提供报告的总体架构(如引言、文献综述、研究方法、结果与讨论、结论与建议),然后针对每一部分进一步细化,描述其具体构成和内容。这种方法帮助用户从总体概念逐步过渡到具体操作,确保全面理解和准确执行。 -
总体架构:引言->文献综述->研究方法->结果与讨论->结论与建议->参考文献
-
细化说明:
引言:背景介绍、研究问题、研究目标
文献综述:按主题分类、总结前人研究、提出研究空白
研究方法:样本选择、数据收集方法、数据质量控制
结果与讨论:数据呈现、结果解读、文献支持或反驳
结论与建议:研究发现、政策建议、研究局限性和未来方向
通过结合分步骤和层次化指导的方法,不仅可以确保任务的每一步被准确执行,还能逐步引导用户深入理解和解决问题。
举个例子
任务描述:撰写一份关于人工智能伦理问题的研究报告
👎 请撰写一份关于人工智能伦理问题的研究报告。
说明:
缺乏分步骤:任务描述没有将撰写过程逐步展开,导致任务太过模糊和复杂。
缺少层次化信息:没有提供报告的总体框架或内部逻辑,也没有细化每一部分应该包含的具体内容。
👍请撰写一份关于人工智能伦理问题的研究报告。为了确保报告的完整性和逻辑清晰,请按以下步骤和结构进行:
a.选择主题
-
明确你研究的具体伦理问题,如“人工智能在医疗行业中的伦理问题”。
-
定义研究范围,例如隐私保护和决策透明度。
b.进行文献综述
-
搜索并阅读相关文献(学术论文、书籍、白皮书)。
-
总结每个文献的核心观点,特别注意提取与自己主题相关的细节。
c.设计研究方法
-
确定你将采用的研究方法(定性、定量或混合)。
-
描述数据收集手段:问卷调查、采访还是二手数据分析。
d.数据收集与分析
-
实施数据收集工作,确保方法一致。
-
使用合适的分析工具和技术进行数据分析。
e.撰写报告
-
引言:
-
描述研究背景、目的和重要性。
-
具体陈述研究问题和目标。
-
-
文献综述:
- 按主题或分类总结前人研究成果和理论框架。
-
研究方法:
- 描述研究的设计、数据收集和分析方法。
-
结果与讨论:
- 呈现分析结果,结合文献讨论其意义。
-
结论与建议:
- 总结研究发现,提出建议,并指出研究局限性和未来研究方向。
-
参考文献:
- 列出所有引用的文献。"
说明:
分步骤:任务被明确地分解为多个独立且具体的步骤,从选择主题到撰写每个部分,都有清晰的指示。
层次化信息:提供了研究报告的总体架构,并在每一部分中进一步细化了具体内容和要求。每一层次的信息都为下一层次铺平了道路,使得整篇报告的撰写过程逻辑清晰且容易实现。
1.4.5 考虑多种可能性和边界条件
在设计 PROMPT 时,充分考虑可能出现的各种输入情况和极端条件,从而确保模型在面对各种非理想输入时仍能产生合理的输出。包括但不限于正例和反例、数据稀缺、极端值、格式错误和冲突信息等情况。
1.4.6 语言和文化敏感性
考虑语言和文化敏感性以及遵循伦理规范对于设计有效、安全的 Prompts 至关重要。一个优秀的 PROMPT 是能够有效引导用户或 AI 系统生成符合预期、高质量响应的输入语句,同时在设计和使用过程中体现出显著的语言和文化敏感性,并严格遵循伦理规范。
1.4.7 数据隐私和安全性
1.数据隐私:
避免敏感信息: 在设计PROMPT时,确保不会包含或请求敏感信息,如个人识别信息(PII)、财务数据、健康数据等。
脱敏处理: 如果需要测试真实数据,确保所有数据已进行脱敏处理,即所有敏感信息被替换或删除。
1.4.8 约束
约束是对提示内容施加的特定限制或要求,合理设置约束是提示设计中的关键步骤,有助于提高生成内容的质量、相关性和适用性。通过对不同类型的约束如内容、格式、风格等多方面的限制,可以使AI模型生成更加符合需求的结果,从而在多个应用场景下实现最佳效果。
使用LLama-Factory训练请参考我的另一篇文章
二、停止词的使用
在构建prompt时候,我要求的输出格式是:结论+####+思考过程,这样做的目的是使用停止词,加快推理速度,其中“####”作用是分隔符,同时也是停止词,控制模型要不要输出思考过程,有思考过程和没有思考过程的速度相差5倍左右
Transformer中eos_token_id=提示词的id
generated_ids = model.generate(
model_inputs.input_ids,
max_new_tokens=512,
eos_token_id=820
)
提示词id获取代码
from transformers import AutoTokenizer
model_path="/data/LLaMA-Factory-main/models/qwen_lora_sft0722"
# 加载分词器
tokenizer=AutoTokenizer.from_pretrained(model_path)
# 输入文本
text="####"
# 编码文本
encode_input=tokenizer(text)
tokens=tokenizer.convert_ids_to_tokens(encode_input["input_ids"])
print(tokens)
print(encode_input["input_ids"])
启动服务代码
from flask import Flask, request, jsonify
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
import time
from transformers import BitsAndBytesConfig
import torch
app = Flask(__name__)
app.json.ensure_ascii = False
device = "cuda" # the device to load the model onto
#path = "/data/LLaMA-Factory-main/models/qwen_lora_sft0725_end_token"
path="/data/Qwen2-7B-Instruct"
quantization = "" # int8、int4、""
if quantization == "int4":
nf4_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_use_double_quant=True,
bnb_4bit_compute_dtype=torch.bfloat16
)
model = AutoModelForCausalLM.from_pretrained(path, quantization_config=nf4_config)
elif quantization == "int8":
model = AutoModelForCausalLM.from_pretrained(
path,
device_map="auto",
load_in_8bit=True
)
else:
model = AutoModelForCausalLM.from_pretrained(
path,
torch_dtype="auto",
#torch_dtype=torch.float16,
device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(path)
# tokenizer.pad_token = "[PAD]"
# tokenizer.padding_side = "left"
@app.route('/algorithm/ChatRest', methods=["POST"])
def qwen():
prompt = request.json.get("prompt")
history = request.json.get("history")
messages = []
if history:
for item in history:
messages.append({"role": "user", "content": item.get("query", "")})
messages.append({"role": "system", "content": item.get("answer", "")})
messages.append({"role": "user", "content": prompt})
print(messages)
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(device)
generated_ids = model.generate(
model_inputs.input_ids,
max_new_tokens=512,
#eos_token_id=820
)
generated_ids = [
output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
return jsonify({
"sucess": True,
"code": "200",
"msg": "解析成功",
"data": {
"query": prompt,
"answer": response
}
})
if __name__ == '__main__':
app.run(host="0.0.0.0")
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)