Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chat模型的prompt template #227

Closed
apepkuss opened this issue Oct 22, 2023 · 14 comments
Closed

chat模型的prompt template #227

apepkuss opened this issue Oct 22, 2023 · 14 comments

Comments

@apepkuss
Copy link

请问,在使用chat模型进行多轮对话的场景下,所使用的prompt template的具体格式是怎样的?谢谢!

@djsaber
Copy link

djsaber commented Oct 26, 2023

可以参考模型文件中的generation_utils.py

@apepkuss
Copy link
Author

@djsaber 谢谢回复!研究了generation_utils.py,但是这里面处理的数据,输入是python dict, 而输出的是tokens。是否可以提供一个字符串形式的prompt template?比如类似于 llama2-7B-chat 给出的prompt template:

<s>[INST] <<SYS>>
{{ system_prompt }}
<</SYS>>

{{ user_message }} [/INST]

@djsaber
Copy link

djsaber commented Oct 27, 2023

据我个人经验,百川的多轮对话用了两个特殊token表示用户和模型,这两个token在多轮对话场景下具有较强的影响:
user_token_id = 195
assistant_token_id = 196
整体prompt的组成是sys + histort + query,sys为系统信息,可为空“”,history为上下文多轮问答信息,query为当前轮用户提问,例如第n轮聊天,具体输入就是:
sys+[195]+q1+[196]+a1+[195]+q2+[196]+a2+...+[195]+qn+[196]
以上仅个人愚见,仅供参考

@shirubei
Copy link

shirubei commented Oct 28, 2023

据我个人经验,百川的多轮对话用了两个特殊token表示用户和模型,这两个token在多轮对话场景下具有较强的影响: user_token_id = 195 assistant_token_id = 196 整体prompt的组成是sys + histort + query,sys为系统信息,可为空“”,history为上下文多轮问答信息,query为当前轮用户提问,例如第n轮聊天,具体输入就是: sys+[195]+q1+[196]+a1+[195]+q2+[196]+a2+...+[195]+qn+[196] 以上仅个人愚见,仅供参考

请问,您上面说的195, 196是指的ascii码吗?谢谢

@shirubei
Copy link

#239

@apepkuss
Copy link
Author

百川在hugging face上给出的models,都没有详细陈述 prompt template 的字符串形式,这其实对于直接使用模型而不是通过API调用的开发来说是很困难的。

@shirubei
Copy link

只能自己摸索

@apepkuss
Copy link
Author

没错!

@djsaber
Copy link

djsaber commented Oct 29, 2023

据我个人经验,百川的多轮对话用了两个特殊token表示用户和模型,这两个token在多轮对话场景下具有较强的影响: user_token_id = 195 assistant_token_id = 196 整体prompt的组成是sys + histort + query,sys为系统信息,可为空“”,history为上下文多轮问答信息,query为当前轮用户提问,例如第n轮聊天,具体输入就是: sys+[195]+q1+[196]+a1+[195]+q2+[196]+a2+...+[195]+qn+[196] 以上仅个人愚见,仅供参考

请问,您上面说的195, 196是指的ascii码吗?谢谢

是输入模型的token的编码

@shirubei
Copy link

据我个人经验,百川的多轮对话用了两个特殊token表示用户和模型,这两个token在多轮对话场景下具有较强的影响: user_token_id = 195 assistant_token_id = 196 整体prompt的组成是sys + histort + query,sys为系统信息,可为空“”,history为上下文多轮问答信息,query为当前轮用户提问,例如第n轮聊天,具体输入就是: sys+[195]+q1+[196]+a1+[195]+q2+[196]+a2+...+[195]+qn+[196] 以上仅个人愚见,仅供参考

请问,您上面说的195, 196是指的ascii码吗?谢谢

是输入模型的token的编码

多谢!那如果我要判断的是否为该token的话,用的是 \u195 和 \u196 这样的形式吗

@greyamber
Copy link

greyamber commented Oct 30, 2023

百川通过两个保留token(token的类型是int32_t) 195和196来代表用户和模型的开始点。195对应明文(明文的类型是string)是"<reserved_106>", 196对应明文是"<reserved_107>"

所以具体格式要看是如何实现tokenizer的。
如果tokenizer支持字符串 + token_id的方式,格式是:
"""
系统prompt \n
[195] + 用户输入1 + [196] + 模型输出1 + [195] + 用户输入2 + [196] + 模型输出2 ...... + [196]
"""

如果tokenizer只支持明文的方式,格式是
"""
系统prompt \n
<reserved_106> + 用户输入1 + <reserved_107> + 模型输出1 + <reserved_106> + 用户输入2 + <reserved_107> + 模型输出2 ...... + <reserved_107>
"""

值得注意的是,使用纯明文的prompt之前,需要测试一下自己实现的tokenizer,是不是能正确的把<reserved_106>和<reserved_107>序列化成195和196这两个token。因为自己实现tokenizer(比如llama.cpp server的baichuan tokenzier),可能会做一些预处理,也可能会有一些编码上的不对齐,导致这种比较特殊的token被错误转换。

官方给出的例子使用字符串 + token_id的方式
https://modelscope.cn/models/baichuan-inc/Baichuan2-13B-Chat/file/view/master/generation_utils.py
image

@shirubei
Copy link

感谢楼上,解释非常清楚,明白了!

@apepkuss apepkuss closed this as completed Nov 9, 2023
@dalong2hongmei
Copy link

百川通过两个保留token(token的类型是int32_t) 195和196来代表用户和模型的开始点。195对应明文(明文的类型是string)是"<reserved_106>", 196对应明文是"<reserved_107>"

所以具体格式要看是如何实现tokenizer的。 如果tokenizer支持字符串 + token_id的方式,格式是: """ 系统prompt \n [195] + 用户输入1 + [196] + 模型输出1 + [195] + 用户输入2 + [196] + 模型输出2 ...... + [196] """

如果tokenizer只支持明文的方式,格式是 """ 系统prompt \n <reserved_106> + 用户输入1 + <reserved_107> + 模型输出1 + <reserved_106> + 用户输入2 + <reserved_107> + 模型输出2 ...... + <reserved_107> """

值得注意的是,使用纯明文的prompt之前,需要测试一下自己实现的tokenizer,是不是能正确的把<reserved_106>和<reserved_107>序列化成195和196这两个token。因为自己实现tokenizer(比如llama.cpp server的baichuan tokenzier),可能会做一些预处理,也可能会有一些编码上的不对齐,导致这种比较特殊的token被错误转换。

官方给出的例子使用字符串 + token_id的方式 https://modelscope.cn/models/baichuan-inc/Baichuan2-13B-Chat/file/view/master/generation_utils.py image

感谢啊,就是要找的明文输入方式。有点疑问,看generation_utils.py的build_chat_input方法,没看到system prompt要加“/n”换行的,是我理解错了吗?

@mvllwong
Copy link

百川通过两个保留token(token的类型是int32_t) 195和196来代表用户和模型的开始点。195对应明文(明文的类型是string)是"<reserved_106>", 196对应明文是"<reserved_107>"
所以具体格式要看是如何实现tokenizer的。 如果tokenizer支持字符串 + token_id的方式,格式是: """ 系统prompt \n [195] + 用户输入1 + [196] + 模型输出1 + [195] + 用户输入2 + [196] + 模型输出2 ...... + [196] """
如果tokenizer只支持明文的方式,格式是 """ 系统prompt \n <reserved_106> + 用户输入1 + <reserved_107> + 模型输出1 + <reserved_106> + 用户输入2 + <reserved_107> + 模型输出2 ...... + <reserved_107> """
值得注意的是,使用纯明文的prompt之前,需要测试一下自己实现的tokenizer,是不是能正确的把<reserved_106>和<reserved_107>序列化成195和196这两个token。因为自己实现tokenizer(比如llama.cpp server的baichuan tokenzier),可能会做一些预处理,也可能会有一些编码上的不对齐,导致这种比较特殊的token被错误转换。
官方给出的例子使用字符串 + token_id的方式 https://modelscope.cn/models/baichuan-inc/Baichuan2-13B-Chat/file/view/master/generation_utils.py image

感谢啊,就是要找的明文输入方式。有点疑问,看generation_utils.py的build_chat_input方法,没看到system prompt要加“/n”换行的,是我理解错了吗?

他写错了,而且jinja版本也写错了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants