[Question] How to use system prompt?

#32
by jankinf - opened

I ran the code according to the official examples and added a system prompt before the user. Whether it is {"content": [{"type": "text", "content": "You are a helpful assistant"}]} or {"content": "You are a helpful assistant"}, an error will occur. The former seems to conflict with the chat template, while the latter will cause an error within the transformers:

.venv/lib/python3.10/site-packages/transformers/processing_utils.py", line 1308, in <listcomp>
    visuals = [content for content in message["content"] if content["type"] in ["image", "video"]]
TypeError: string indices must be integers

My running code is as follows:

from transformers import AutoProcessor, LlavaForConditionalGeneration

model_id = "mistral-community/pixtral-12b"
processor = AutoProcessor.from_pretrained(model_id)
model = LlavaForConditionalGeneration.from_pretrained(model_id, device_map="cuda")

chat = [
    {
        "role": "system",
        # "content": [{"type": "text", "content": "You are a helpful assistant"}],
        "content": "You are a helpful assistant",
    },
    {
        "role": "user",
        "content": [
            {"type": "text", "content": "Tell me a joke"},
        ],
    },
]


inputs = processor.apply_chat_template(
    chat,
    add_generation_prompt=True,
    tokenize=True,
    return_dict=True,
    return_tensors="pt",
).to(model.device)

generate_ids = model.generate(**inputs, max_new_tokens=500)
output = processor.batch_decode(
    generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False
)[0]
print(output)

May someone please help me with this?

In chat_template.json {%- if loop.last and system_message is defined %} indicates that if it is the last message and there is a system message, the system message will be placed within the command tag. There may be a logical issue here, as system messages are typically handled at the beginning of the conversation rather than placed in the last user message.

A similar issue occured at another repo: https://huggingface.co/mistralai/Mistral-Nemo-Instruct-2407/discussions/47

{
  "chat_template": "{%- if messages[0][\"role\"] == \"system\" %}{%- if messages[0][\"content\"] is not string %}{%- if messages[0][\"content\"]|length == 1 and messages[0][\"content\"][0][\"type\"] == \"text\" %}{%- set system_message = messages[0][\"content\"][0][\"content\"] %}{%- endif %}{%- else %}{%- set system_message = messages[0][\"content\"] %}{%- endif %}{%- set loop_messages = messages[1:] %}\n{%- else %}{%- set loop_messages = messages %}{%- endif %}{{- bos_token }}{%- for message in loop_messages %}{%- if (message['role'] == 'user') != (loop.index0 % 2 == 0) %}{{- raise_exception('After the optional system message, conversation roles must alternate user/assistant/user/assistant/...') }}{%- endif %}{%- if message[\"role\"] == \"user\" %}{%- if loop.first and system_message is defined %}{{- \"[INST]\" + system_message + \"\n\n\" }}{%- else %}{{ \"[INST]\" }}{%- endif %}{%- endif %}{%- if message[\"content\"] is not string %}{%- for chunk in message[\"content\"] %}{%- if chunk[\"type\"] == \"text\" %}{%- if \"content\" in chunk %}{{- chunk[\"content\"] }}{%- elif \"text\" in chunk %}{{- chunk[\"text\"] }}{%- endif %}{%- elif chunk[\"type\"] == \"image\" %}{{- \"[IMG]\" }}{%- else %}{{- raise_exception(\"Unrecognized content type!\") }}{%- endif %}{%- endfor %}{%- else %}{{- message[\"content\"] }}{%- endif %}{%- if message[\"role\"] == \"user\" %}{{- \"[/INST]\" }}{%- elif message[\"role\"] == \"assistant\" %}{{- eos_token}}{%- else %}{{- raise_exception(\"Only user and assistant roles are supported, with the exception of an initial optional system message!\") }}{%- endif %}{%- endfor %}"
}

This template seems to solve the two problems mentioned above.

+ import json
+ with open("chat_template.json", "r") as fp:
+     chat_template = json.load(fp)["chat_template"]

inputs = processor.apply_chat_template(
    chat,
    add_generation_prompt=True,
    tokenize=True,
    return_dict=True,
    return_tensors="pt",
+    chat_template=chat_template,
).to(model.device)
Your need to confirm your account before you can post a new comment.

Sign up or log in to comment