AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


用消费级显卡微调属于自己的Agent!
发布日期:2024-04-17 20:11:02 浏览次数: 1725


本文为魔搭社区轻量级训练推理工具SWIFT微调实战教程系列

SWIFT(Scalable lightWeight Infrastructure for Fine-Tuning)是魔搭ModelScope开源社区推出的一套完整的轻量级训练推理工具基于PyTorch的轻量级、开箱即用的模型微调、推理框架,让AI爱好者用自己的消费级显卡就能玩转大模型和AIGC。


魔搭官方,公众号:魔搭ModelScope社区大模型时代,还缺一只雨燕 | SWIFT:魔搭社区轻量级微调推理框架


SWIFT支持了开源模型,尤其是中小型模型(7B、14B等)对Agent场景的训练,并将loss-scale技术(https://arxiv.org/pdf/2309.00986.pdf)应用到agent训练中,使中小模型API Call能力更稳定,并支持使用单张商业级显卡进行Agent推理和部署,可以直接在生产场景中全链路闭环落地使用。

接下来进入手把手Agent微调实操:


环境安装



# 设置pip全局镜像 (加速下载)pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/# 安装ms-swiftgit clone https://github.com/modelscope/swift.gitcd swiftpip install -e .[llm]
# 环境对齐 (通常不需要运行. 如果你运行错误, 可以跑下面的代码, 仓库使用最新环境测试)pip install -r requirements/framework.txt-Upip install -r requirements/llm.txt-U


数据准备



为训练Agent能力,魔搭官方提供了两个开源数据集:

  • 魔搭通用问答知识数据集(包含38万条通用知识多轮对话数据)

    • 链接:https://www.modelscope.cn/datasets/iic/ms_bench/summary

  • 魔搭通用Agent训练数据集(包含3万条Agent格式的API调用数据)

    • 链接:https://www.modelscope.cn/datasets/iic/ms_agent/summary


魔搭通用问答数据集数据格式如下:

{"id": "MS_Agent_Bench_126374","conversations": [{"from": "system","value": "Answer the following questions as best you can. You have access to the following APIs:\n1. hm_recipe_recommend: Call this tool to interact with the hmreciperecommend API. What is the hmreciperecommend API useful for? . Parameters: [{\"name\": \"keywords_dict\", \"description\": \"盒马推荐菜谱关键词字典。\", \"required\": \"True\"}]\n\n2. hm_product_marketing: Call this tool to interact with the hmproductmarketing API. What is the hmproductmarketing API useful for? . Parameters: [{\"name\": \"sku_code_list\", \"description\": \"盒马商品的编码列表\", \"required\": \"True\"}]\n\n3. hm_product_info: Call this tool to interact with the hmproductinfo API. What is the hmproductinfo API useful for? . Parameters: [{\"name\": \"sku_code_list\", \"description\": \"盒马商品的编码列表\", \"required\": \"True\"}, {\"name\": \"sku_name_list\", \"description\": \"盒马商品的名称列表\", \"required\": \"True\"}, {\"name\": \"property_list\", \"description\": \"盒马商品的属性列表\", \"required\": \"True\"}]\n\n4. hm_product_recommend: Call this tool to interact with the hmproductrecommend API. What is the hmproductrecommend API useful for? . Parameters: [{\"name\": \"keywords_dict\", \"description\": \"盒马推荐商品关键词字典。\", \"required\": \"True\"}]\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of the above tools[hm_recipe_recommend, hm_product_marketing, hm_product_info, hm_product_recommend]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can be repeated zero or more times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\nBegin!"}, {"from": "user","value": "你好,请问你们有哪些手机可以推荐?"}, {"from": "assistant","value": "Action: hm_product_recommend\nAction Input: {'keywords_dict': {'商品类目': '手机'}}\nObservation: [{'sku_code': '10518244314', 'product_name': '小米11 Ultra 5G手机 256GB', 'bussiness_type': '标品', 'product_price': '5999', 'product_description': '拥有120Hz高刷新率和骁龙888处理器,还配备了高品质相机系统'}, {'sku_code': '10222726664', 'product_name': 'vivo X60 Pro 5G手机 256GB', 'bussiness_type': '标品', 'product_price': '4498', 'product_description': '搭载Exynos 1080处理器与ZEISS联合调校的相机系统,拍照实力十足'}, {'sku_code': '18227073452', 'product_name': '华为畅享 20 Pro 5G手机 128GB', 'bussiness_type': '标品', 'product_price': '2699', 'product_description': '拥有4000mAh的电池容量和优秀的相机而价格非常亲民'}]\nThought: I now know the final answer\nFinal Answer: 您好,我们有以下几款手机供您选择:1.小米11 Ultra 5G手机 256GB:价格为5999元,拥有120Hz高刷新率和骁龙888处理器,还配备了高品质相机系统;2. vivo X60 Pro 5G手机 256GB:售价为4498元,搭载Exynos 1080处理器与ZEISS联合调校的相机系统,拍照实力十足;3. 华为畅享 20 Pro 5G手机 128GB:价格亲民,只需2699元即可拥有优秀的相机和4000mAh的电池容量。这些手机都具有不同的特点和功能,您可以根据自己的需求进行选择。如果您有其他问题或需求,请随时告诉我。"}, {"from": "user","value": "我想买一款拍照好的手机,有推荐吗?"}, {"from": "assistant","value": "Action: hm_product_recommend\nAction Input: {'keywords_dict': {'商品类目': '手机', '适用场景': '拍照'}}\nObservation: [{'sku_code': '15956662254', 'product_name': '小米11 Ultra 5G手机 256GB', 'bussiness_type': '标品', 'product_price': '5999', 'product_description': '拥有120Hz高刷新率和骁龙888处理器,还配备了高品质相机系统'}, {'sku_code': '19424216918', 'product_name': 'vivo X60 Pro 5G手机 256GB', 'bussiness_type': '标品', 'product_price': '4498', 'product_description': '搭载Exynos 1080处理器与ZEISS联合调校的相机系统,拍照实力十足'}, {'sku_code': '14347982715', 'product_name': 'OPPO Ace2 5G手机 256GB', 'bussiness_type': '标品', 'product_price': '3999', 'product_description': '拍照实力十足,支持65W超级闪充'}]\nThought: I now know the final answer\nFinal Answer: 如果您想要一款拍照表现出色的手机,我为您推荐以下几款产品:1.小米11 Ultra 5G手机 256GB:价格为5999元,配备了高品质相机系统,可以拍摄出色的照片;2. vivo X60 Pro 5G手机 256GB:售价为4498元,相机系统由ZEISS联合调校,拍照实力十足;3. OPPO Ace2 5G手机 256GB:价格为3999元,不仅拍照实力十足,还支持65W超级闪充,让你的手机充电更加便捷。这些手机都有不同的特点和功能,您可以根据自己的需求进行选择。如果您还有其他问题或需求,请随时告诉我。"}, {"from": "user","value": "小米11 Ultra拍照性能怎么样?"}, {"from": "assistant","value": "Action: hm_product_info\nAction Input: {'sku_code_list': ['15956662254'], 'sku_name_list': ['小米11 Ultra 5G手机 256GB'], 'property_list': [['拍照性能']]}\nObservation: [{'sku_code': '15956662254', 'property': {'拍照性能': '小米11 Ultra 5G手机配备了1亿像素的主摄像头,还有120X超长焦电影摄像头,以及20MP超广角摄像头等组合,拍照性能非常出色。'}}]\nThought: I now know the final answer\nFinal Answer: 小米11 Ultra 5G手机配备了1亿像素的主摄像头,还有120X超长焦电影摄像头,以及20MP超广角摄像头等组合,拍照性能非常出色。如果您还有其他问题或需求,请随时告诉我。"}]}

Agent数据集的system字段具体格式如下(将\"字符转换为"字符, \n转换为换行):

Answer the following questions as best you can. You have access to the following APIs:1. hm_recipe_recommend: Call this tool to interact with the hmreciperecommend API. What is the hmreciperecommend API useful for? . Parameters: [{"name": "keywords_dict", "description": "盒马推荐菜谱关键词字典。", "required": "True"}]
2. hm_product_marketing: Call this tool to interact with the hmproductmarketing API. What is the hmproductmarketing API useful for? . Parameters: [{"name": "sku_code_list", "description": "盒马商品的编码列表", "required": "True"}]
3. hm_product_info: Call this tool to interact with the hmproductinfo API. What is the hmproductinfo API useful for? . Parameters: [{"name": "sku_code_list", "description": "盒马商品的编码列表", "required": "True"}, {"name": "sku_name_list", "description": "盒马商品的名称列表", "required": "True"}, {"name": "property_list", "description": "盒马商品的属性列表", "required": "True"}]
4. hm_product_recommend: Call this tool to interact with the hmproductrecommend API. What is the hmproductrecommend API useful for? . Parameters: [{"name": "keywords_dict", "description": "盒马推荐商品关键词字典。", "required": "True"}]
Use the following format:
Thought: you should always think about what to doAction: the action to take, should be one of the above tools[hm_recipe_recommend, hm_product_marketing, hm_product_info, hm_product_recommend]Action Input: the input to the actionObservation: the result of the action... (this Thought/Action/Action Input/Observation can be repeated zero or more times)Thought: I now know the final answerFinal Answer: the final answer to the original input questionBegin!

API格式:

Answer the following questions as best you can. You have access to the following APIs:序号: API名称: API作用 API参数
...
Use the following format:
Thought: you should always think about what to doAction: the action to take, should be one of the above tools[API名称列表]Action Input: the input to the actionObservation: the result of the action... (this Thought/Action/Action Input/Observation can be repeated zero or more times)Thought: I now know the final answerFinal Answer: the final answer to the original input questionBegin!
Agent数据集调用API的response的结构如下:
Agent数据集调用API的response的结构如下:
Action: hm_product_recommendAction Input: {'keywords_dict': {'商品类目': '手机', '适用场景': '拍照'}}Observation: [{'sku_code': '15956662254', 'product_name': '小米11 Ultra 5G手机 256GB', 'bussiness_type': '标品', 'product_price': '5999', 'product_description': '拥有120Hz高刷新率和骁龙888处理器,还配备了高品质相机系统'}, {'sku_code': '19424216918', 'product_name': 'vivo X60 Pro 5G手机 256GB', 'bussiness_type': '标品', 'product_price': '4498', 'product_description': '搭载Exynos 1080处理器与ZEISS联合调校的相机系统,拍照实力十足'}, {'sku_code': '14347982715', 'product_name': 'OPPO Ace2 5G手机 256GB', 'bussiness_type': '标品', 'product_price': '3999', 'product_description': '拍照实力十足,支持65W超级闪充'}]Thought: I now know the final answerFinal Answer: 如果您想要一款拍照表现出色的手机,我为您推荐以下几款产品:1.小米11 Ultra 5G手机 256GB:价格为5999元,配备了高品质相机系统,可以拍摄出色的照片;2. vivo X60 Pro 5G手机 256GB:售价为4498元,相机系统由ZEISS联合调校,拍照实力十足;3. OPPO Ace2 5G手机 256GB:价格为3999元,不仅拍照实力十足,还支持65W超级闪充,让你的手机充电更加便捷。这些手机都有不同的特点和功能,您可以根据自己的需求进行选择。如果您还有其他问题或需求,请随时告诉我。
  • Action:实际调用的API名称

  • Action Input: 实际的输入参数

  • Observation: 该部分是实际调用结果,训练时不参与loss,推理时需要外部调用后填入模型

  • Thought: 模型思考输出

  • Final Answer: 模型的最终回答



微调


在Agent训练中,为了避免训练后造成严重知识遗忘,我们的数据配比为ms-agent:ms-bench数据集1比2,其中ms_agent共30000条,随机抽样ms_bench数据集60000条,同时为了改变模型认知,增加自我认知数据3000条。

数据集条数
ms-agent30000(全数据集)
ms-bench60000(抽样)
self-recognition3000(重复抽样)


我们也支持使用自己的Agent数据集。数据集格式需要符合自定义数据集的要求。更具体地,Agent的response/system应该符合上述的Action/Action Input/Observation格式。

我们将MLPEmbedder加入了lora_target_modules. 你可以通过指定--lora_target_modules ALL在所有的linear层(包括qkvo以及mlp和embedder)加lora. 这通常是效果最好的。

微调使用了qwen-7b-chat模型,超参数如下:

超参数
LR5e-5
Epoch2
lora_rank8
lora_alpha32
lora_target_modulesALL
batch_size2
gradient_accumulation_steps32 total


运行命令和其他超参数如下:

# Experimental environment: A100nproc_per_node=8
PYTHONPATH=../../.. \torchrun \--nproc_per_node=$nproc_per_node \--master_port 29500 \llm_sft.py \--model_id_or_path qwen/Qwen-7B-Chat \--model_revision master \--sft_type lora \--tuner_backend swift \--dtype AUTO \--output_dir output \--dataset ms-agent \--train_dataset_mix_ratio 2.0 \--train_dataset_sample -1 \--num_train_epochs 2 \--max_length 2048 \--check_dataset_strategy warning \--lora_rank 8 \--lora_alpha 32 \--lora_dropout_p 0.05 \--lora_target_modules ALL \--self_cognition_sample 3000 \--model_name 卡卡罗特 \--model_author 陶白白 \--gradient_checkpointing true \--batch_size 2 \--weight_decay 0.01 \--learning_rate 5e-5 \--gradient_accumulation_steps $(expr 32 / $nproc_per_node) \--max_grad_norm 0.5 \--warmup_ratio 0.03 \--eval_steps 100 \--save_steps 100 \--save_total_limit 2 \--logging_steps 10

训练过程使用了8*A100硬件环境,训练时长3小时。该训练使用单卡也可以运行,用户可以将DDP改为单卡命令即可。


推理



我们针对通用知识和Agent进行评测。下面列出了一个简单的评测结果。

原始模型

通用知识

西湖醋鱼怎么做

新冠和普通感冒有什么区别

Agent能力

我们使用一个火焰报警场景作为测试用例:

Answer the following questions as best you can. You have access to the following APIs:1. fire_recognition: Call this tool to interact with the fire recognition API. This API is used to recognize whether there is fire in the image. Parameters: [{"name": "image", "description": "The input image to recognize fire", "required": "True"}]
2. fire_alert: Call this tool to interact with the fire alert API. This API will start an alert to warn the building's administraters. Parameters: []
3. call_police: Call this tool to interact with the police calling API. This API will call 110 to catch the thief. Parameters: []
4. call_fireman: Call this tool to interact with the fireman calling API. This API will call 119 to extinguish the fire. Parameters: []
Use the following format:
Thought: you should always think about what to doAction: the action to take, should be one of the above tools[fire_recognition, fire_alert, call_police, call_fireman]Action Input: the input to the actionObservation: the result of the action... (this Thought/Action/Action Input/Observation can be repeated zero or more times)Thought: I now know the final answerFinal Answer: the final answer to the original input questionBegin!

可以看到,人工输入Observation后模型答案并不正确。


训练后

通用知识

西湖醋鱼怎么做

新冠和普通感冒有什么区别


Agent能力

可以看到,训练后模型可以正确调用API并给出最终答案。


自我认知


在命令行中使用Agent

目前命令行的Agent推理支持需要指定--eval_human true,因为该参数为false的时候会读取数据集内容,此时无法手动传入Observation:后面的API调用结果。也可用--ckpt_dir指定训练后输出

swift infer --model_type chatglm3-6b-32k --eval_human true --stop_words Observation: --infer_backend pt

运行命令后,改变system字段:

# 单行system<<< reset-system<<< Answer the following questions as best you can. You have access to the following APIs:\n1. fire_recognition: Call this tool to interact with the fire recognition API. This API is used to recognize whether there is fire in the image. Parameters: [{"name": "image", "description": "The input image to recognize fire", "required": "True"}]\n\n2. fire_alert: Call this tool to interact with the fire alert API. This API will start an alert to warn the building's administraters. Parameters: []\n\n3. call_police: Call this tool to interact with the police calling API. This API will call 110 to catch the thief. Parameters: []\n\n4. call_fireman: Call this tool to interact with the fireman calling API. This API will call 119 to extinguish the fire. Parameters: []\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of the above tools[fire_recognition, fire_alert, call_police, call_fireman]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can be repeated zero or more times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\nBegin!

如果需要以多行方式输入,可以用下面的命令(多行信息以#号结束):

# 多行system<<< multi-line#<<<[M] reset-system#<<<[MS] Answer the following questions as best you can. You have access to the following APIs:1. fire_recognition: Call this tool to interact with the fire recognition API. This API is used to recognize whether there is fire in the image. Parameters: [{"name": "image", "description": "The input image to recognize fire", "required": "True"}]
2. fire_alert: Call this tool to interact with the fire alert API. This API will start an alert to warn the building's administraters. Parameters: []
3. call_police: Call this tool to interact with the police calling API. This API will call 110 to catch the thief. Parameters: []
4. call_fireman: Call this tool to interact with the fireman calling API. This API will call 119 to extinguish the fire. Parameters: []
Use the following format:
Thought: you should always think about what to doAction: the action to take, should be one of the above tools[fire_recognition, fire_alert, call_police, call_fireman]Action Input: the input to the actionObservation: the result of the action... (this Thought/Action/Action Input/Observation can be repeated zero or more times)Thought: I now know the final answerFinal Answer: the final answer to the original input questionBegin!#

下面就可以进行Agent问答:

<<< 输入图片是/tmp/1.jpg,协助判断图片中是否存在着火点Thought: I need to use the fire\_recognition API to analyze the input image and determine if there are any signs of fire.
Action: Use the fire\_recognition API to analyze the input image.
Action Input: /tmp/1.jpg
Observation:<<< [{'coordinate': [101.1, 200.9], 'on_fire': True}]Thought: The fire\_recognition API has returned a result indicating that there is fire in the input image.
Final Answer: There is fire in the input image.


可以看到,模型已经返回了API调用的结果分析。用户可以继续问问题进行多轮Agent场景。也可以指定--infer_backend vllm--stream true来使用vllm和流式推理。


在部署中使用Agent

由于部署不支持history管理,因此agent的API调用结果拼接需要用户自行进行,下面给出一个OpenAI格式可运行的代码范例。

服务端:


swift deploy --model_type chatglm3-6b-32k --stop_words Observation

客户端:

from openai import OpenAIclient = OpenAI(api_key='EMPTY',base_url='http://localhost:8000/v1',)model_type = client.models.list().data[0].idprint(f'model_type: {model_type}')
system = """Answer the following questions as best you can. You have access to the following APIs:1. fire_recognition: Call this tool to interact with the fire recognition API. This API is used to recognize whether there is fire in the image. Parameters: [{\"name\": \"image\", \"description\": \"The input image to recognize fire\", \"required\": \"True\"}]
2. fire_alert: Call this tool to interact with the fire alert API. This API will start an alert to warn the building's administraters. Parameters: []
3. call_police: Call this tool to interact with the police calling API. This API will call 110 to catch the thief. Parameters: []
4. call_fireman: Call this tool to interact with the fireman calling API. This API will call 119 to extinguish the fire. Parameters: []
Use the following format:
Thought: you should always think about what to doAction: the action to take, should be one of the above tools[fire_recognition, fire_alert, call_police, call_fireman]Action Input: the input to the actionObservation: the result of the action... (this Thought/Action/Action Input/Observation can be repeated zero or more times)Thought: I now know the final answerFinal Answer: the final answer to the original input questionBegin!"""messages = [{'role': 'system','content': system}, {'role': 'user','content': '输入图片是/tmp/1.jpg,协助判断图片中是否存在着火点'}]resp = client.chat.completions.create(model=model_type,messages=messages,stop=['Observation:'],seed=42)response = resp.choices[0].message.contentprint(f'response: {response}')
# # 流式messages.append({'role': 'assistant', 'content': response + "\n[{'coordinate': [101.1, 200.9], 'on_fire': True}]"})print(messages)stream_resp = client.chat.completions.create(model=model_type,messages=messages,stop=['Observation:'],stream=True,seed=42)
print('response: ', end='')for chunk in stream_resp:print(chunk.choices[0].delta.content, end='', flush=True)print()## Output:# model_type: chatglm3-6b-32k# response: Thought: I need to check if there is fire in the image# Action: Use fire\_recognition API# Action Input: /tmp/2.jpg# Observation:# [{'role': 'system', 'content': 'Answer the following questions as best you can. You have access to the following APIs:\n1. fire_recognition: Call this tool to interact with the fire recognition API. This API is used to recognize whether there is fire in the image. Parameters: [{"name": "image", "description": "The input image to recognize fire", "required": "True"}]\n\n2. fire_alert: Call this tool to interact with the fire alert API. This API will start an alert to warn the building\'s administraters. Parameters: []\n\n3. call_police: Call this tool to interact with the police calling API. This API will call 110 to catch the thief. Parameters: []\n\n4. call_fireman: Call this tool to interact with the fireman calling API. This API will call 119 to extinguish the fire. Parameters: []\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of the above tools[fire_recognition, fire_alert, call_police, call_fireman]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can be repeated zero or more times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\nBegin!'}, {'role': 'user', 'content': '输入图片是/tmp/2.jpg,协助判断图片中是否存在着火点'}, {'role': 'assistant', 'content': "Thought: I need to check if there is fire in the image\nAction: Use fire\\_recognition API\nAction Input: /tmp/2.jpg\nObservation:\n[{'coordinate': [101.1, 200.9], 'on_fire': True}]"}]# response:# Final Answer: There is fire in the image at coordinates [101.1, 200.9]

总结


通过SWIFT支持的Agent训练能力,我们使用ms-agent和ms-bench对qwen-7b-chat模型进行了微调。可以看到微调后模型保留了通用知识问答能力,并在system字段增加了API的情况下可以正确调用并完成任务。需要注意的是:

  1. 训练从LoRA变为全参数训练,知识遗忘问题会更加严重,数据集混合比例需要实际测试调整

  2. 部分模型可能在训练后仍然调用效果不佳,可以测试该模型本身预训练能力是否扎实




53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询