to 2024 / 06 / 01
行动模拟
该项目拟通过大语言模型分析拆解人类描述的任务,自动的调用行动库进行执行并完成内容的汇报。因而需要针对任务对大模型进行微调(比如本项目使用的p-tuning v2),行动模拟即针对微调结果将大模型与行动库进行对接,模拟实际场景下的函数输入输出。
第一步,即加载微调后的大模型,可参考之前博客中给出的cli_demo.py
:
# load raw model
tokenizer = AutoTokenizer.from_pretrained(model_path % model_name, trust_remote_code=True)
config = AutoConfig.from_pretrained(model_path % model_name, trust_remote_code=True)
config.pre_seq_len = pre_seq_len
model = AutoModel.from_pretrained(model_path % model_name, config=config, trust_remote_code=True)
# feed ptuning model
prefix_state_dict = torch.load(os.path.join(model_path % ptuning_checkpoint, "pytorch_model.bin"))
new_prefix_state_dict = {}
for k, v in prefix_state_dict.items():
if k.startswith("transformer.prefix_encoder."):
new_prefix_state_dict[k[len("transformer.prefix_encoder."):]] = v
model.transformer.prefix_encoder.load_state_dict(new_prefix_state_dict)
# model config
model = model.quantize(quantization_bit)
model = model.half().cuda()
model.transformer.prefix_encoder.float().cuda()
model.eval()
第二步,即设计大模型与行动库的交互步骤,这里根据场景要求给出五步:
- 语言模型基于人类输入文本进行任务类型判定和拆解
- 行动库接受参数并模拟对应任务反馈给语言模型结果
- 语言模型基于结果进行简单分析并给出任务结果报告
- 整合输出结果以 PDF 的格式展示为报告方便下载打印
- 记录所有内容并反馈给后端,供前后端交互
def simulate(uid, prompt, options, params, history_formatted, chat_tmp_path):
# init
data_lines = []; act_img_path = None
prefix = ["【系统】","【核心】"]; suffix = "\n\n"; key = "KEY"
act_map = {"零":__act0, "壹":__act1, "贰":__act2}
template = ["步骤#理解并基于输入拆分函数参数\*语音#%s",
"步骤#基于函数调用结果进行总结\*结果#%s"]
# step1: LLM response -> understand & split
data_lines.append("%s正在与LLM语言核心交互%s" % (prefix[0], suffix))
response0, _ = model.chat(tokenizer, template[0] % prompt, history_formatted,
max_length=params['max_length'], top_p=params['top_p'], temperature=params['temperature'])
# WARN:TEST
response0 = response0 + "KEY壹;济南"
data_lines.append("%s%s%s" % (prefix[1], response0, suffix))
# step2: text split & action select( N=3 )
kidx_st = response0.find(key)
uf_flag = kidx_st==-1
if not uf_flag:
kidx_ed = response0.find(";", kidx_st)
uf_flag = kidx_ed==-1
if uf_flag:
data_lines.append("%sLLM语言核心解析函数失败%s" % (prefix[0], suffix))
else:
act_info, act_response, act_text, act_img_path = act_map[response0[kidx_st+3:kidx_ed]](response0[kidx_ed:])
data_lines.append("%s%s%s" % (prefix[0], act_info, suffix))
data_lines.append("%s%s%s" % (prefix[0], "默认查询日期:" + str(datetime.date.today()), suffix))
data_lines.append("%s%s%s" % (prefix[0], act_response, suffix))
# step4: LLM response -> analysis
response1, _ = model.chat(tokenizer, template[1] % act_response, history_formatted,
max_length=params['max_length'], top_p=params['top_p'], temperature=params['temperature'])
data_lines.append("%s%s%s" % (prefix[1], response1, suffix))
# step4: pdf generate
if __gen_pdf(uid, act_text):
data_lines.append("%s任务报告输出完成%s" % (prefix[1], suffix))
else:
data_lines.append("%s任务报告生成失败%s" % (prefix[1], suffix))
# step5: write to the tmp_file
with open(chat_tmp_path, mode="w", encoding='utf-8') as f:
f.writelines(data_lines)
# step6: send back sim_img_path
return act_img_path
这里需要设计好大语言模型微调时的prompt,确保模型交互没有问题。实际上这里模型参与了多种问题的处理,我尝试了基于不同的prompt模板训练不同的微调模型,使其对于当前的多任务情况更加适配,这在之后的博客中会有所提及。但这里的行动库并不完善,其中模拟操作可能需要返回图片等佐证。
FastAPI 交互
在行动模拟程序与后端的交互中,我写了一个样例:
img_path = simulate(uid, prompt, options, params, history_formatted, chat_tmp_path)
# gen stream_obj
def __itf():
cline=""
with open(chat_tmp_path, mode="r", encoding='utf-8') as f:
for line in f:
cline = cline + line; time.sleep(tdelay)
yield ("data: " + json.dumps(
dict(
role="AI", id=uid,
parentMessageId=None,
text=cline + footer
)
))
# return stream response
return StreamingResponse(content=__itf(), headers=stream_response_headers,
media_type="text/event-stream")
行动模拟程序最后一步将所有交互过程写回到临时文件,FastAPI 后端生成一个文件的字节流以相应的格式传给前端进行展示,这里使用了StreamingResponse
,其实际上还可以传递图片,文件可以通过FileResponse
进行传输。目前为测试版,仅供参考。
参考资料
[1] ChatGLM-6B/ptuning at main · THUDM/ChatGLM-6B · GitHub
[2] 自定义响应 - HTML,流,文件和其他 - FastAPI (tiangolo.com)
标签:FastAPI,lines,V0,prefix,实训,act,path,model,data From: https://www.cnblogs.com/yichengliu0219/p/18262396