增加對tokenizer.chat_template的支援
#22
by
p208p2002
- opened
簡短
設置 tokenizer.chat_template
來使用tokenizer.apply_chat_template
, model.generate
和 pipeline
(text-gen) 等transformer提供之功能,減少不一致性可能。
model_id_or_path = "THUDM/chatglm3-6b"
tokenizer = AutoTokenizer.from_pretrained(model_id_or_path,trust_remote_code=True)
tokenizer.chat_template = "{% for message in messages %}{% if loop.first %}[gMASK]sop<|{{ message['role'] }}|> \n {{ message['content'] }}{% else %}<|{{ message['role'] }}|> \n {{ message['content'] }}{% endif %}{% endfor %}{% if add_generation_prompt %}<|assistant|>{% endif %}"
此PR目的
新版本的 transformer tokenizer 已經支援 chat_template 屬性 (https://huggingface.co./blog/zh/chat-templates),其目的在更好的讓使用者遵守聊天模型需要的對話格式。
一些第三方部屬框架也開始採用這個設定(如OpenLLM),但是對於沒有設置tokenizer.chat_template
的分詞器會自動fallback採用tokenizer.default_chat_template
導致格式不正確:
目前沒有設置 chat_template
chatglm_tokenizer.chat_template
# None
預設的 chat_template (ChatML格式)
chatglm_tokenizer.default_chat_template
# {% for message in messages %}{{'<|im_start|>' + message['role'] + '
# ' + message['content'] + '<|im_end|>' + '
# '}}{% endfor %}{% if add_generation_prompt %}{{ '<|im_start|>assistant
# ' }}{% endif %}
chat_template fot chatglm
這個PR提供 jinja template 讓新的 tokenzier.chat_template feature 能夠 work:
{% for message in messages %}{% if loop.first %}[gMASK]sop<|{{ message['role'] }}|> \n {{ message['content'] }}{% else %}<|{{ message['role'] }}|> \n {{ message['content'] }}{% endif %}{% endfor %}{% if add_generation_prompt %}<|assistant|>{% endif %}
使用 chat_template
現在可以直接使用 model.generate
,具體效果如下:
from transformers import AutoTokenizer,AutoModelForCausalLM
model_id_or_path = "THUDM/chatglm3-6b"
tokenizer = AutoTokenizer.from_pretrained(model_id_or_path,trust_remote_code=True)
tokenizer.chat_template = "{% for message in messages %}{% if loop.first %}[gMASK]sop<|{{ message['role'] }}|> \n {{ message['content'] }}{% else %}<|{{ message['role'] }}|> \n {{ message['content'] }}{% endif %}{% endfor %}{% if add_generation_prompt %}<|assistant|>{% endif %}"
model = AutoModelForCausalLM.from_pretrained(model_id_or_path,device_map="auto",trust_remote_code=True)
inputs = tokenizer.apply_chat_template([
{"role":"system","content":"你是一位樂於助人、尊重他人且誠實的助理。請始終以最有幫助的方式回答問題。如果你對某個問題不知道答案,請不要提供虛假信息。"},
{"role":"user","content":"如何減緩地球暖化?"}
],add_generation_prompt=True,tokenize=True,return_tensors="pt")
out = model.generate(inputs,max_new_tokens=256)
print(tokenizer.decode(out[0]))
[gMASK]sop<|system|>
你是一位樂於助人、尊重他人且誠實的助理。請始終以最有幫助的方式回答問題。如果你對某個問題不知道答案,請不要提供虛假信息。<|user|>
如何減緩地球暖化?<|assistant|>
減緩地球暖化有許多方法,以下是一些主要的措施:
1. 減少二氧化碳排放:這包括減少工業和交通碳排放,以及提高能源效率。
2. 採用可再生能源:如太陽能、風能和水能等。
3. 保護森林:森林可以吸收二氧化碳,如果森林被砍伐或被燒毀,會增加二氧化碳的排放。
4. 減少溫室氣體排放:這包括減少農業和工業溫室氣體排放,以及提高能源效率。
5. 改變飲食習慣:減少肉類和乳製品 consumption,因為它們產生的大氣碳排}>
格式正確性驗證
已經透過difflab
與tokenizer.build_chat_input
比較確輸出一致性
#from difflib import ndiff
# 如果樣板結果與官方版本不同,比較差異
if not jinja_template_result == official_result:
str1 = jinja_template_result
str2 = official_result
diff = ndiff(str1.splitlines(), str2.splitlines())
for line in diff:
print(line)
p208p2002
changed pull request title from
Update tokenizer_config.json
to 增加對tokenizer.chat_template的支援
zRzRzRzRzRzRzR
changed pull request status to
merged
请问tokenizer.apply_chat_template()方法与ChatGLM3 github repo中给出的格式似乎不同