1 prompt工程
例如:做一个天气预报系统,用户可以提问并查询某个城市、某个日期的天气。
系统实现非常简单:写一个prompt工程提取用户query中关键词:日期+城市,调用天气预报API查询天气(日期+城市)。
用户查询天气的query:
9月1日北京天气预报
8月30日杭州天气怎么样?
上海9月2日的天气情况
...
为什么需要prompt工程? A:为了让大模型更好理解用户问题。
prompt工程样例如下,把用户问题query转换成prompt,传入大模型可以得到更准确的结果。
prompt_template='''
分析问题中出现过的城市和日期
交互格式如下:
问题:用户的原始问题,里面可能包含城市和日期信息
回答:提炼问题中出现的城市名和日期,按格式整理返回,
城市:值是城市的名字
日期:值是具体日期
现在开始。
问题:%s
回答:
'''
prompt=prompt_template%(Q,)
print(prompt)
生成的prompt如下:
分析问题中出现过的城市和日期
交互格式如下:
问题:用户的原始问题,里面可能包含城市和日期信息
回答:提炼问题中出现的城市名和日期,按格式整理返回,
城市:值是城市的名字
日期:值是具体日期
现在开始。
问题:8月29日杭州天气预报
回答:
城市: 杭州
日期: 8月29日
没有微调的初始化模型,执行多次回答格式并不稳定,会出现如下回答:
杭州:城市名 - 杭州,日期 - 2021年8月29日
2 SFT微调
监督式微调,即提供足够多训练数据(上述Q-A),让模型学习解析结构化数据日期、城市的能力。
步骤1 生成训练数据
随机生成1000个样本,每个样本按照SFT微调数据格式拼接,样例代码如下:
for i in range(100):
Q=Q_list[random.randint(0,len(Q_list)-1)] ## 选择问题格式
city=city_list[random.randint(0,len(city_list)-1)] ## 随机选择城市
year=random.randint(1990,2025) ## 随机选择日期
Q=Q[0].format(city=city,year=year,month=month,day=day) # 问题
A='城市:%s\n日期:%s'%(city, date_field)
example={
"id": 'identity_{}'.format(i),
'conversations': {
{
"from": "user",
"value": prompt_template%(Q,),
},
{
"from": "assistant",
"value": A,
},
}
}
# print(example)
train_data.append(example)
步骤2 训练
Qwen提供如下微调脚本
- 全参数微调 训练过程中更新所有参数
- LoRA (LoRA)[arxiv.org/abs/2106.09…
- Q-LoRA (Q-LoRA)[arxiv.org/abs/2106.09… attention等技术。
本案例使用Q-LoRA微调,参照官方文档执行.
bash finetune/finetune_qlora_single_gpu.sh -m qwen/Qwen-1_8B-Chat-Int4/ -d sft_weather/train.txt
单卡训练大概20几分钟。
3 加载SFT模型
按照文档
from peft import AutoPeftModelForCausalLM
model = AutoPeftModelForCausalLM.from_pretrained(
'Qwen-main/output_qwen', # path to the output directory
device_map="auto",
trust_remote_code=True
).eval()
测试SFT后的效果
Q_list=['2024年9月1号北京天晴?''西安有个xx明星演唱会,5月2日,你打算去不?']
for Q in Q_list:
prompt=prompt_template%(Q,)
A,hist=model.chat(tokenizer,prompt,history=None)
执行结果满足要求。如下: