自学内容网 自学内容网

Qwen2-VL通过特殊Token来区分图像和文本输入

Qwen2-VL通过特殊Token来区分图像和文本输入

flyfish

• 图像特征序列的界定Token:
在图像特征序列的开始和结束处,分别插入 <|vision_start|> 和 <|vision_end|> 这两个特殊Token,以此来划定图像内容的范围,让模型明确知道哪些部分是图像对应的特征。

• 对话中的图像标识Token:在对话数据格式中,使用 <|im_start|> 和 <|im_end|> 这两个特殊Token来标识对话中的图像部分,便于模型识别对话中哪些内容是与图像相关的信息,从而更好地理解对话的上下文和意图。

chat_template.json

使用Jinja2模板引擎的语法编写的,主要用于Python应用程序中,尤其是Web开发框架如Flask和Django。Jinja2模板语言允许开发者通过简单的标记和控制结构来动态生成文本输出,比如HTML页面、配置文件或者在这个场景下的多模态对话输入序列。

chat_template.json文件中,Jinja2模板语法被用来根据输入的messages列表动态构建包含文本、图像和视频信息的输入序列,其中涉及到变量初始化、条件判断、循环遍历等逻辑操作,这些操作都是通过Jinja2特有的标记和表达式来实现的。例如:

{% set ... %}用于变量赋值。

{% if ... %}{% elif ... %}{% endif %}用于条件判断。

{% for ... in ... %}{% endfor %}用于循环遍历。

{{ ... }}用于输出变量或表达式的结果。

这种模板语言使得开发者能够以一种简洁而强大的方式来处理复杂的文本生成任务,特别是在需要根据不同的输入数据动态生成格式化文本的场景下。

{
    "chat_template": "
        {% set image_count = namespace(value = 0) %}
        {% set video_count = namespace(value = 0) %}
        {% for message in messages %}
            {% if loop.first and message['role']!= 'system' %}
                <|im_start|>system
                You are a helpful assistant.
                <|im_end|>
            {% endif %}
            <|im_start|>{{ message['role'] }}
                {% if message['content'] is string %}
                    {{ message['content'] }}<|im_end|>
                {% else %}
                    {% for content in message['content'] %}
                        {% if content['type'] == 'image' or 'image' in content or 'image_url' in content %}
                            {% set image_count.value = image_count.value + 1 %}
                            {% if add_vision_id %}Picture {{ image_count.value }}: {% endif %}
                            <|vision_start|><|image_pad|><|vision_end|>
                        {% elif content['type'] == 'video' or 'video' in content %}
                            {% set video_count.value = video_count.value + 1 %}
                            {% if add_vision_id %}Video {{ video_count.value }}: {% endif %}
                            <|vision_start|><|video_pad|><|vision_end|>
                        {% elif 'text' in content %}
                            {{ content['text'] }}
                        {% endif %}
                    {% endfor %}
                    <|im_end|>
                {% endif %}
        {% endfor %}
        {% if add_generation_prompt %}
            <|im_start|>assistant
        {% endif %}
    "
}

多模态对话模板定义,用于生成多模态对话交互的文本格式 ,其中包含了对图像、视频等不同类型内容的处理逻辑,解释:

  1. 初始化计数器

    {% set image_count = namespace(value=0) %}
    {% set video_count = namespace(value=0) %}
    
    • 这两行代码初始化了两个计数器,image_count 用于统计消息中图像的数量,video_count 用于统计视频的数量。namespace 是一种在模板中创建可修改变量的方式。
  2. 遍历消息列表

    {% for message in messages %}
    
    • 这是一个循环,遍历名为 messages 的列表,其中的每个元素 message 代表一条对话消息。
  3. 处理系统消息

    {% if loop.first and message['role']!= 'system' %}
    <|im_start|>system
    You are a helpful assistant.
    <|im_end|>
    {% endif %}
    
    • 如果当前消息是列表中的第一条消息,并且其角色不是 system,则插入一段系统消息,表明助手是有帮助的。<|im_start|><|im_end|> 可能是用于标记消息开始和结束的特殊分隔符。
  4. 处理不同角色的消息内容

    <|im_start|>{{ message['role'] }}
    {% if message['content'] is string %}
    {{ message['content'] }}<|im_end|>
    
    • 首先标记当前消息的角色(如 userassistant 等)。如果消息内容是字符串类型,直接输出该字符串,并使用 <|im_end|> 标记消息结束。
  5. 处理多模态内容

    {% else %}
    {% for content in message['content'] %}
    {% if content['type'] == 'image' or 'image' in content or 'image_url' in content %}
    {% set image_count.value = image_count.value + 1 %}
    {% if add_vision_id %}Picture {{ image_count.value }}: {% endif %}
    <|vision_start|><|image_pad|><|vision_end|>
    
    • 如果消息内容不是简单字符串,而是一个包含多种类型内容的列表(如多模态消息),则遍历这个列表。
    • 当检测到内容类型为图像(通过判断 content['type'] 是否为 'image' 或内容中是否包含 'image''image_url')时,图像计数器 image_count 加1。
    • 如果 add_vision_id 为真,则添加一个图像编号前缀(如 Picture 1:)。
    • 然后使用 <|vision_start|><|image_pad|><|vision_end|> 这些特殊标记来表示图像内容的占位符。实际应用中,<|image_pad|> 位置可能会被替换为图像的具体信息或引用。
    {% elif content['type'] == 'video' or 'video' in content %}
    {% set video_count.value = video_count.value + 1 %}
    {% if add_vision_id %}Video {{ video_count.value }}: {% endif %}
    <|vision_start|><|video_pad|><|vision_end|>
    
    • 类似地,当检测到视频内容时,视频计数器 video_count 加1。如果 add_vision_id 为真,添加视频编号前缀(如 Video 1:),并使用 <|vision_start|><|video_pad|><|vision_end|> 标记视频内容的占位符。
    {% elif 'text' in content %}
    {{ content['text'] }}
    {% endif %}
    {% endfor %}
    <|im_end|>
    {% endif %}
    
    • 如果内容包含文本(通过判断是否有 'text' 键),则输出该文本内容。
    • 完成对当前消息内容列表的遍历后,使用 <|im_end|> 标记消息结束。
  6. 生成助手回复提示

    {% if add_generation_prompt %}
    <|im_start|>assistant
    {% endif %}
    
    • 如果 add_generation_prompt 为真,插入一个标记,表示助手回复的开始,通常用于提示模型生成回复内容。

原文地址:https://blog.csdn.net/flyfish1986/article/details/145158700

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!