Open Jimmy-L99 opened 1 month ago
我这边试验的结果也是merge后异常
解决了吗?遇到同样的问题
想知道你们是怎么merge的,template还在吗?想查看一下tokenizer_config.json中的chat_template是否发生变化
想知道你们是怎么merge的,template还在吗?想查看一下tokenizer_config.json中的chat_template是否发生变化
我是通过LLaMA-Factory工具微调的,自带导出模型的功能。
@zRzRzRzRzRzRzR 我是直接按llama-factory的命令运行 llamafactory export xxxx.yaml yaml文件如下:
### model
model_name_or_path: models/glm-4-9b-chat
adapter_name_or_path: finetune_model/lora_finetune
template: glm4
finetuning_type: lora
### export
export_dir: finetune_model/lora_finetune_merge
export_size: 2
export_device: cpu
export_legacy_format: false
chat_template我检查了一下: 原本的:
`"chat_template": "[gMASK]<sop>{% for item in messages %}{% if item['tools'] is defined %}<|system|>\n你是一个名为 GLM-4 的人工智能助手。你是基于智谱AI训练的语言模型 GLM-4 模型开发的,你的任务是针对用户的问题和要求提供适当的答复和支持。\n\n# 可用工具{% set tools = item['tools'] %}{% for tool in tools %}{% if tool['type'] == 'function' %}\n\n## {{ tool['function']['name'] }}\n\n{{ tool['function'] | tojson(indent=4) }}\n在调用上述函数时,请使用 Json 格式表示调用的参数。{% elif tool['type'] == 'python' %}\n\n## python\n\n当你向 `python` 发送包含 Python 代码的消息时,该代码将会在一个有状态的 Jupyter notebook 环境中执行。\n`python` 返回代码执行的输出,或在执行 60 秒后返回超时。\n`/mnt/data` 将会持久化存储你的文件。在此会话中,`python` 无法访问互联网。不要使用 `python` 进行任何网络请求或者在线 API 调用,这些在线内容的访问将不会成功。{% elif tool['type'] == 'simple_browser' %}\n\n## simple_browser\n\n你可以使用 `simple_browser` 工具。该工具支持以下函数:\n`search(query: str, recency_days: int)`:使用搜索引擎进行查询并显示结果,可以使用 `recency_days` 参数控制搜索内容的时效性。\n`mclick(ids: list[int])`:获取一系列指定 id 的页面内容。每次调用时,须选择3-10个页面。选择多个角度的页面,同时尽可能选择可信任的信息来源。考虑到部分页面是无法加载的,你也可以多打开一些可能有用的页面而不用担心内容过多。\n`open_url(url: str)`:打开指定的 URL。\n\n使用 `【{引用 id}†{引用文本}】` 来引用内容。\n\n操作步骤:1. 使用 `search` 来获得信息列表; 2. 使用 `mclick` 来获取指定 ID 页面的内容; 3. 根据获得的内容进行回复。在回复中应当引用信息来源。\n 如果用户提供了 URL,也可以用 `open_url` 直接打开页面。\n如果初次搜索结果没有找到合适的信息,也可以再次使用 `search` 进行搜索。{% elif tool['type'] == 'cogview' %}\n\n## cogview\n\n如果用户的请求中包含了对图像的描述,你可以使用 `cogview` 来生成图像并展示给用户。你需要向 `cogview` 发送图像描述,规则:\n- 发送给 `cogview` 的消息必须使用英语。用户的中文描述必须完全翻译为英语。\n- 应当尽可能详细地描述图像生成的需求,需求描述约 100 英文单词。\n- 保持用户原始描述的意图。不要虚构内容或者没见过的人物。\n- 如无特殊说明,所在地为中国,持有中国立场并遵循中国社会主义价值观。{% endif %}{% endfor %}{% endif %}{% if item['content'] %}<|{{ item['role'] }}|>{{ item['metadata'] }}\n{{ item['content'] }}{% endif %}{% endfor %}{% if add_generation_prompt %}<|assistant|>{% endif %}",`
merge之后:
"chat_template": "{{ '[gMASK]<sop>' }}{% if messages[0]['role'] == 'system' %}{% set loop_messages = messages[1:] %}{% set system_message = messages[0]['content'] %}{% else %}{% set loop_messages = messages %}{% endif %}{% if system_message is defined %}{{ '<|system|>\n' + system_message }}{% endif %}{% for message in loop_messages %}{% set content = message['content'] %}{% if message['role'] == 'user' %}{{ '<|user|>\n' + content + '<|assistant|>' }}{% elif message['role'] == 'assistant' %}{{ '\n' + content }}{% endif %}{% endfor %}",
这块我不太了解了,但确实有变化,会不会是这个的原因。
我是通过llama-factory的webui直接导出的,template选的是glm4
能否提供微调数据集和工具测试的完整代码以供测试
能否提供微调数据集和工具测试的完整代码以供测试
貌似没法提供,毕竟都是按照llama-factory教程部署和操作的。数据集应该随便一个都行。
llamafactory-cli train xxx.yaml
### train.yaml:
### model
model_name_or_path: /root/ljm/models/glm-4-9b-chat
### method
stage: sft
do_train: true
finetuning_type: lora
lora_target: query_key_value
lora_rank: 16
lora_alpha: 32
lora_dropout: 0.05
### dataset
dataset: self_congnition_dataset1
template: glm4
cutoff_len: 4096
max_samples: 3000
overwrite_cache: true
preprocessing_num_workers: 16
### output
output_dir: /root/finetune_model/
logging_steps: 10
save_steps: 500
plot_loss: true
overwrite_output_dir: true
### train
per_device_train_batch_size: 2
gradient_accumulation_steps: 2
learning_rate: 5.0e-4
num_train_epochs: 3.0
\# max_steps: 2000
lr_scheduler_type: cosine
warmup_ratio: 0.03
fp16: true
### eval
val_size: 0.1
per_device_eval_batch_size: 1
evaluation_strategy: steps
eval_steps: 100
llamafactory-cli export merge.yaml
### model
model_name_or_path: models/glm-4-9b-chat
adapter_name_or_path: finetune_model/lora_finetune
template: glm4
finetuning_type: lora
### export
export_dir: finetune_model/lora_finetune_merge
export_size: 2
export_device: cpu
export_legacy_format: false
我成功复现你的问题了,问题出现在template模版上,目前的解决方案是修改llama-factory微调merge后权重的tokenizer_config.json
文件,替换chat_template
为:
"chat_template": "[gMASK]<sop>{% for item in messages %}{% if item['tools'] is defined %}<|system|>\n你是一个名为 GLM-4 的人工智能助手。你是基于智谱AI训练的语言模型 GLM-4 模型开发的,你的任务是针对用户的问题和要求提供适当的答复和支持。\n\n# 可用工具{% set tools = item['tools'] %}{% for tool in tools %}{% if tool['type'] == 'function' %}\n\n## {{ tool['function']['name'] }}\n\n{{ tool['function'] | tojson(indent=4) }}\n在调用上述函数时,请使用 Json 格式表示调用的参数。{% elif tool['type'] == 'python' %}\n\n## python\n\n当你向 `python` 发送包含 Python 代码的消息时,该代码将会在一个有状态的 Jupyter notebook 环境中执行。\n`python` 返回代码执行的输出,或在执行 60 秒后返回超时。\n`/mnt/data` 将会持久化存储你的文件。在此会话中,`python` 无法访问互联网。不要使用 `python` 进行任何网络请求或者在线 API 调用,这些在线内容的访问将不会成功。{% elif tool['type'] == 'simple_browser' %}\n\n## simple_browser\n\n你可以使用 `simple_browser` 工具。该工具支持以下函数:\n`search(query: str, recency_days: int)`:使用搜索引擎进行查询并显示结果,可以使用 `recency_days` 参数控制搜索内容的时效性。\n`mclick(ids: list[int])`:获取一系列指定 id 的页面内容。每次调用时,须选择3-10个页面。选择多个角度的页面,同时尽可能选择可信任的信息来源。考虑到部分页面是无法加载的,你也可以多打开一些可能有用的页面而不用担心内容过多。\n`open_url(url: str)`:打开指定的 URL。\n\n使用 `【{引用 id}†{引用文本}】` 来引用内容。\n\n操作步骤:1. 使用 `search` 来获得信息列表; 2. 使用 `mclick` 来获取指定 ID 页面的内容; 3. 根据获得的内容进行回复。在回复中应当引用信息来源。\n 如果用户提供了 URL,也可以用 `open_url` 直接打开页面。\n如果初次搜索结果没有找到合适的信息,也可以再次使用 `search` 进行搜索。{% elif tool['type'] == 'cogview' %}\n\n## cogview\n\n如果用户的请求中包含了对图像的描述,你可以使用 `cogview` 来生成图像并展示给用户。你需要向 `cogview` 发送图像描述,规则:\n- 发送给 `cogview` 的消息必须使用英语。用户的中文描述必须完全翻译为英语。\n- 应当尽可能详细地描述图像生成的需求,需求描述约 100 英文单词。\n- 保持用户原始描述的意图。不要虚构内容或者没见过的人物。\n- 如无特殊说明,所在地为中国,持有中国立场并遵循中国社会主义价值观。{% endif %}{% endfor %}{% endif %}{% if item['content'] %}<|{{ item['role'] }}|>{{ item['metadata'] }}\n{{ item['content'] }}{% endif %}{% endfor %}{% if add_generation_prompt %}<|assistant|>{% endif %}",
重新执行python openai_api_server.py
服务后,向服务器发送工具调用的请求即可。
随后我们将在LLaMA-Factory仓库中提交修复代码。
@sixsixcoder 调用工具不报错了。通过llamafactory微调glm4后乱码是什么原因导致的啊,随便一个训练数据都是这个问题。
(glm4) [root@adsl-172-10-0-187 basic_demo]# python openai_api_request.py
ChatCompletion(id='chatcmpl-ZPaE1pu1lJo7XBetF5gIRHYH7LKBK', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!', refusal=None, role='assistant', audio=None, function_call=None, tool_calls=None))], created=1731026510, model='glm-4', object='chat.completion', service_tier=None, system_fingerprint='fp_xJsllLODf', usage=CompletionUsage(completion_tokens=256, prompt_tokens=47, total_tokens=303, completion_tokens_details=None, prompt_tokens_details=None))
ChatCompletion(id='chatcmpl-U25035HyRrY03K6JBO94XfLEN0pTh', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!', refusal=None, role='assistant', audio=None, function_call=None, tool_calls=None))], created=1731026517, model='glm-4', object='chat.completion', service_tier=None, system_fingerprint='fp_nXuYgjRcJ', usage=CompletionUsage(completion_tokens=256, prompt_tokens=166, total_tokens=422, completion_tokens_details=None, prompt_tokens_details=None))
None
您微调后要把openai_api_request.py
中的function_chat
函数的tools
变量修改成数据集同样格式的内容
@Andy1018 请教一下,你这边用的也是glm4-9b-chat吗
@Andy1018 请教一下,你这边用的也是glm4-9b-chat吗
是的
@sixsixcoder 调用工具不报错了。通过llamafactory微调glm4后乱码是什么原因导致的啊,随便一个训练数据都是这个问题。 (glm4) [root@adsl-172-10-0-187 basic_demo]# python openai_api_request.py ChatCompletion(id='chatcmpl-ZPaE1pu1lJo7XBetF5gIRHYH7LKBK', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!', refusal=None, role='assistant', audio=None, function_call=None, tool_calls=None))], created=1731026510, model='glm-4', object='chat.completion', service_tier=None, system_fingerprint='fp_xJsllLODf', usage=CompletionUsage(completion_tokens=256, prompt_tokens=47, total_tokens=303, completion_tokens_details=None, prompt_tokens_details=None)) ChatCompletion(id='chatcmpl-U25035HyRrY03K6JBO94XfLEN0pTh', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!', refusal=None, role='assistant', audio=None, function_call=None, tool_calls=None))], created=1731026517, model='glm-4', object='chat.completion', service_tier=None, system_fingerprint='fp_nXuYgjRcJ', usage=CompletionUsage(completion_tokens=256, prompt_tokens=166, total_tokens=422, completion_tokens_details=None, prompt_tokens_details=None)) None 您微调后要把
openai_api_request.py
中的function_chat
函数的tools
变量修改成数据集同样格式的内容
这个问题可以参考:https://github.com/THUDM/GLM-4/issues/637 将环境运行在pytorch2.4.0和transformers4.45.0上
使用vllm
加载模型时,将enforce_eager
改为False
试试,在basic_demo/glm_server.py
的 671 行
System Info / 系統信息
Who can help? / 谁可以帮助到您?
@sixsixcoder @zr
Information / 问题信息
Reproduction / 复现过程
1. LoRA微调
使用LLaMA-Factory,自定义数据集、yaml文件,
llamafactory-cli train
进行LoRA微调。2.glm4-9b-chat和LoRA进行merge
使用LLaMA-Factory,
llamafactory-cli export
得到merge模型。3.工具调用测试代码
使用官方提供的openai_api_server.py, vLLM推理。
工具测试部分代码:
4.模型测试
测试如下,用base和两种不同的lora调用方式测试
tools result:
深圳目前时刻的天气是多云, 温度为26.0℃, 湿度为38.0%, 风向为东北, 风力为≤3级
LLM_response: 今天深圳的天气是多云,气温约为26摄氏度,相对湿度为38%,风向为东北风,风力较弱,风速不超过3级。
输出结果: INFO: 172.16.21.155:36244 - "POST /v1/chat/completions HTTP/1.1" 500 Internal Server Error ERROR: Exception in ASGI application Traceback (most recent call last): File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 401, in run_asgi result = await app( # type: ignore[func-returns-value] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in call return await self.app(scope, receive, send) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in call await super().call(scope, receive, send) File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/starlette/applications.py", line 113, in call await self.middleware_stack(scope, receive, send) File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/starlette/middleware/errors.py", line 187, in call raise exc File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/starlette/middleware/errors.py", line 165, in call await self.app(scope, receive, _send) File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/starlette/middleware/cors.py", line 85, in call await self.app(scope, receive, send) File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 62, in call await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/starlette/_exception_handler.py", line 62, in wrapped_app raise exc File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/starlette/_exception_handler.py", line 51, in wrapped_app await app(scope, receive, sender) File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/starlette/routing.py", line 715, in call await self.middleware_stack(scope, receive, send) File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/starlette/routing.py", line 735, in app await route.handle(scope, receive, send) File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/starlette/routing.py", line 288, in handle await self.app(scope, receive, send) File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/starlette/routing.py", line 76, in app await wrap_app_handling_exceptions(app, request)(scope, receive, send) File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/starlette/_exception_handler.py", line 62, in wrapped_app raise exc File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/starlette/_exception_handler.py", line 51, in wrapped_app await app(scope, receive, sender) File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/starlette/routing.py", line 73, in app response = await f(request) ^^^^^^^^^^^^^^^^ File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/fastapi/routing.py", line 301, in app raw_response = await run_endpoint_function( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/fastapi/routing.py", line 212, in run_endpoint_function return await dependant.call(**values) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/root/ljm/ChatGLM4/GLM-4/api_server/openai_api_server.py", line 389, in create_chat_completion async for response in generate_stream_glm4(gen_params): File "/root/ljm/ChatGLM4/GLM-4/api_server/openai_api_server.py", line 205, in generate_stream_glm4 inputs = tokenizer.apply_chat_template(messages, add_generation_prompt=True, tokenize=False) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/transformers/tokenization_utils_base.py", line 1844, in apply_chat_template rendered_chat = compiled_template.render( ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/jinja2/environment.py", line 1304, in render self.environment.handle_exception() File "/root/anaconda3/envs/glm4_9b-chat-128k_vLLM/lib/python3.11/site-packages/jinja2/environment.py", line 939, in handle_exception raise rewrite_traceback_stack(source=source) File "", line 1, in top-level template code TypeError: can only concatenate str (not "NoneType") to str