使用llama-factory进行lora微调后,推理正常,但是tools调用异常
System Info / 系統信息
操作系统=ubuntu20.04 显卡=4 x v100 model=glm-9b-chat python=3.11.8 llama-factory=0.8.3 transformers=4.43.3 vllm=0.5.3.post1
Who can help? / 谁可以帮助到您?
No response
Information / 问题信息
- [ ] The official example scripts / 官方的示例脚本
- [ ] My own modified scripts / 我自己修改的脚本和任务
Reproduction / 复现过程
通过llama-factory对glm-9b-chat模型进行lora微调,使用Supervised Fine-Tuning,主要是微调自我意识,然后将微调后的模型导出,修改GLM-4-main/basic_demo/openai_api_server.py文件,设置MODEL_PATH = '/opt/glm-9b-chat-lora',启动openai_api_server.py,通过接口正常的推理没有问题,一切正常 然后进行tool调用时报错,报错信息如下:
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 399, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 70, in __call__
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in __call__
await super().__call__(scope, receive, send)
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/starlette/applications.py", line 123, in __call__
await self.middleware_stack(scope, receive, send)
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/starlette/middleware/errors.py", line 186, in __call__
raise exc
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/starlette/middleware/errors.py", line 164, in __call__
await self.app(scope, receive, _send)
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/starlette/middleware/cors.py", line 85, in __call__
await self.app(scope, receive, send)
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 65, in __call__
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
raise exc
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
await app(scope, receive, sender)
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/starlette/routing.py", line 756, in __call__
await self.middleware_stack(scope, receive, send)
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/starlette/routing.py", line 776, in app
await route.handle(scope, receive, send)
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/starlette/routing.py", line 297, in handle
await self.app(scope, receive, send)
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/starlette/routing.py", line 77, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
raise exc
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
await app(scope, receive, sender)
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/starlette/routing.py", line 72, in app
response = await func(request)
^^^^^^^^^^^^^^^^^^^
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/fastapi/routing.py", line 278, in app
raw_response = await run_endpoint_function(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/fastapi/routing.py", line 191, in run_endpoint_function
return await dependant.call(**values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/GLM-4-main/basic_demo/openai_api_server.py", line 369, in create_chat_completion
output = await anext(predict_stream_generator)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/GLM-4-main/basic_demo/openai_api_server.py", line 453, in predict_stream
async for new_response in generate_stream_glm4(gen_params):
File "/opt/GLM-4-main/basic_demo/openai_api_server.py", line 206, in generate_stream_glm4
inputs = tokenizer.apply_chat_template(messages, add_generation_prompt=True, tokenize=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/transformers/tokenization_utils_base.py", line 1833, in apply_chat_template
rendered_chat = compiled_template.render(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/jinja2/environment.py", line 1304, in render
self.environment.handle_exception()
File "/root/anaconda3/envs/glm/lib/python3.11/site-packages/jinja2/environment.py", line 939, in handle_exception
raise rewrite_traceback_stack(source=source)
File "<template>", line 1, in top-level template code
TypeError: can only concatenate str (not "NoneType") to str
Expected behavior / 期待表现
是我微调的问题吗,希望微调后能实现原来glm-9b-chat的tool调用能力
不支持Function Call 功能,因为 vLLM 官方仓库统一没有支持该功能(无论何种模型)
不支持Function Call 功能,因为 vLLM 官方仓库统一没有支持该功能(无论何种模型)
我用的GLM-4-main/basic_demo/openai_api_server.py脚本,原始模型支持Function Call,微调后就不支持了,这是怎么回事
GLM4中openai的demo底座是vllm,vllm不支持Function Call https://zhipu-ai.feishu.cn/wiki/VpncwoWn4i2ZsDkWSqYcbtwSnWd
但是原始模型使用openai_api_server.py是支持function call的啊,为什么微调后,再用openai_api_server.py就不支持了,如果想要支持,我需要改哪些。
v100不支持bf16,微调只能用bf16进行
v100支持bf16,我微调成功了
那你的意思是微调的时候选择fp32或者fp16?
那你的意思是微调的时候选择fp32或者fp16?
微调的时候最好是bf16,fp16可能会出现溢出问题,推理的时候fp16可以成功运行,但也会有很小概率溢出,fp32的话相对这两个精度会慢,资源消耗也会大
其实我想要的是微调后仍然能通过openai_api_server.py支持function call
其实我想要的是微调后仍然能通过openai_api_server.py支持function call
请问你这问题解决了吗,我使用llama-factory,显卡是4090并采用bf16精度微调工具,也是报错这个
问题没有解决,总感觉哪里有问题,但是glm的人也不给实质性的回答。我在哔哩哔哩上问过别人,那个人说他也遇到这个问题,解决不了就放弃使用function call了。
问题没有解决,总感觉哪里有问题,但是glm的人也不给实质性的回答。我在哔哩哔哩上问过别人,那个人说他也遇到这个问题,解决不了就放弃使用function call了。
你没“复习”,“遗忘也正常”。 微调是会调整内部参数权重,训练数据要有你新增的数据集,也要有你期望要保留功能的数据集。然后,保留功能的数据集,占比还要比你新增的数据集多很多。
上面说的,是我看到glm的人,在chatglm和 glm 项目,有回复过。意思就是上面的那样。 微调后,会遗忘。不想遗忘原来的,在微调时,就需要学习少量新的 + 大量复习旧的。
我微调后,个人的看法是, 个人 会把 开源的 5+5+5+7+6+4 这样的多边形战士。调整后,多半会变成 7+2+3+5 的多边形战士。调的好的可以做到 10+2+3+5 的多边形战士。
我微调后,个人的看法是, 个人 会把 开源的 5+5+5+7+6+4 这样的多边形战士。调整后,多半会变成 7+2+3+5 的多边形战士。调的好的可以做到 10+2+3+5 的多边形战士。
我们这个问题不是说的微调没效果,我们的问题是微调后只要Agent触发函数调用就会报错
+1
@kaixindeyouxia 环境版本: vllm=0.5.3 transformers=4.44.0 我的建议是,如果想用glm4-9b-chat+lora微调+工具调用,可以在openai_api_server.py用lora_request传递lora微调模型,运行openai_api_server.py,这样就可以两者兼得。(我是用langchain那套方法测试工具调用的)
如果用命令行启动vllm serve服务,vllm不支持工具调用,但是它并发推理是真的快。还有个问题,我用命令行参数传递lora模型,貌似也不起作用,不知道为什么。
如果是llama-factory训练lora之后将lora和glm4-9b-chat进行merge,合并之后的模型运行openai_api_server.py调用工具,会有报错。 [(https://github.com/THUDM/GLM-4/issues/607)]
我成功复现你的问题了,问题出现在template模版上,llama-factory到处merge后的模型文件时,替换了glm-4-9b-chat的chat_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仓库中提交修复代码。
更多信息可以参考issue:https://github.com/THUDM/GLM-4/issues/607
@sixsixcoder 非常感谢,改天我试试。