/swift/blob/main/swift/llm/utils/template.py[swift源码解析]

/swift/blob/main/swift/llm/utils/template.py[swift源码解析]

源码:

和llama-factory 定义qwen模板的对比:


def register_template(template_type: str, template: Template, *, exist_ok: bool = False, **kwargs) -> None:
    if not exist_ok and template_type in TEMPLATE_MAPPING:
        raise ValueError(f'The `{template_type}` has already been registered in the TEMPLATE_MAPPING.')
    template.template_type = template_type
    template_info = {'template': template, **kwargs}
    TEMPLATE_MAPPING[template_type] = template_info


register_template(
    TemplateType.default,
    Template([], ['### Human:\n{{QUERY}}\n\n### Assistant:\n'], ['\n\n'], [['eos_token_id']], DEFAULT_SYSTEM,
             ['{{SYSTEM}}\n\n']))


# You can set the query as '' to serve as a template for pre-training.
class DefaultGenerationTemplate(Template):

    def __init__(self):
        super().__init__([], ['{{QUERY}}'], None, [['eos_token_id']], auto_add_bos=True)


register_template(TemplateType.default_generation, DefaultGenerationTemplate(), is_generation=True)
register_template(
    TemplateType.default_generation_bos,
    Template([['bos_token_id']], ['{{QUERY}}'], None, [['eos_token_id']]),
    is_generation=True)


class QwenTemplate(Template):

    def __init__(self, auto_add_bos: bool = False):
        super().__init__([], ['<|im_start|>user\n{{QUERY}}<|im_end|>\n<|im_start|>assistant\n'], ['<|im_end|>\n'],
                         ['<|im_end|>'],
                         DEFAULT_SYSTEM, ['<|im_start|>system\n{{SYSTEM}}<|im_end|>\n'],
                         auto_add_bos=auto_add_bos)

中文为您解释这段代码。让我们逐行进行分析:

claude


def register_template(template_type: str, template: Template, *, exist_ok: bool = False, **kwargs) -> None:
这个函数用于注册一个新的模板。它接受模板类型(字符串)、Template对象、可选的exist_ok标志,以及任何额外的关键字参数。


    if not exist_ok and template_type in TEMPLATE_MAPPING:
        raise ValueError(f'The `{template_type}` has already been registered in the TEMPLATE_MAPPING.')
这行代码检查模板类型是否已经存在于TEMPLATE_MAPPING中。如果存在且exist_ok为False,则抛出ValueError。

python
复制
    template.template_type = template_type
    template_info = {'template': template, **kwargs}
    TEMPLATE_MAPPING[template_type] = template_info
这些行设置模板的template_type属性,创建一个包含模板和任何额外kwargs的字典,并将其添加到TEMPLATE_MAPPING中,使用template_type作为键。

python
复制
register_template(
    TemplateType.default,
    Template([], ['### Human:\n{{QUERY}}\n\n### Assistant:\n'], ['\n\n'], [['eos_token_id']], DEFAULT_SYSTEM,
             ['{{SYSTEM}}\n\n']))
这里注册了一个默认模板。它为人类和助手消息使用特定的格式,并包含查询和系统消息的占位符。

python
复制
class DefaultGenerationTemplate(Template):

def __init__(self):
        super().__init__([], ['{{QUERY}}'], None, [['eos_token_id']], auto_add_bos=True)
这定义了一个DefaultGenerationTemplate类,它继承自Template。这是一个简单的模板,只包含查询。

python
复制
register_template(TemplateType.default_generation, DefaultGenerationTemplate(), is_generation=True)
这将DefaultGenerationTemplate注册为默认生成模板。

python
复制
register_template(
    TemplateType.default_generation_bos,
    Template([['bos_token_id']], ['{{QUERY}}'], None, [['eos_token_id']]),
    is_generation=True)
这注册了另一个默认生成模板,但这个包含了一个序列开始标记。

python
复制
class QwenTemplate(Template):

def __init__(self, auto_add_bos: bool = False):
        super().__init__([], ['<|im_start|>user\n{{QUERY}}<|im_end|>\n<|im_start|>assistant\n'], ['<|im_end|>\n'],
                         ['<|im_end|>'],
                         DEFAULT_SYSTEM, ['<|im_start|>system\n{{SYSTEM}}<|im_end|>\n'],
                         auto_add_bos=auto_add_bos)
这定义了一个QwenTemplate类,它是Qwen模型使用的特定模板格式。它包含特殊标记来表示用户、助手和系统消息的开始和结束。

总的来说,这段代码为不同类型的语言模型交互设置了各种模板,允许根据不同的模型或使用场景灵活地格式化输入和输出。

Claude-3.5-Sonnet

Poe

QwenTemplate 的类

这段代码定义了一个名为 QwenTemplate 的类,它继承自 Template 类。这个类用于设置 Qwen 模型的对话模板。让我为您解释这段代码的含义,并渲染出真实的输出效果:

auto_add_bos: 一个布尔值参数,用于控制是否自动添加开始标记(Beginning of Sequence)。

初始化参数:

  • 空列表 []: 可能表示没有特殊的前缀。
  • 用户输入模板: ['<|im_start|>user\n{{QUERY}}<|im_end|>\n<|im_start|>assistant\n']
  • 助手回复结束标记: ['<|im_end|>\n']
  • 整个对话结束标记: ['<|im_end|>']
  • 默认系统消息: DEFAULT_SYSTEM(这是一个预定义的常量)
  • 系统消息模板: ['<|im_start|>system\n{{SYSTEM}}<|im_end|>\n']

现在,让我们渲染一下这个模板的真实输出效果。假设我们有一个用户查询和一个系统消息,它们会被这样格式化:

<|im_start|>system
你是一个友善的AI助手。
<|im_end|>

<|im_start|>user
你好,请介绍一下自己。
<|im_end|>

<|im_start|>assistant
作为一个AI助手,我很高兴能够与您交流。我是一个设计用来协助和回答各种问题的人工智能程序。我可以处理多种主题,包括但不限于科技、历史、文化、科学等。我的知识库涵盖了广泛的领域,但它是静态的,截止到2024年4月。

我的主要目标是提供有用、准确和友好的回答。我会尽力理解您的问题并给出最相关的信息。如果有什么不清楚的地方,我会请求澄清。我也可以进行一些基本的分析、计算,甚至是创意写作。

虽然我很乐意与您交流,但请记住我是一个AI,没有真实的情感或个人经历。我的回答是基于程序和数据的。如果您有任何其他问题或需要帮助,请随时告诉我。
<|im_end|>

这就是使用 QwenTemplate 类定义的模板渲染后的真实输出效果。每个部分(系统消息、用户输入和助手回复)都被特定的标记包围,以便模型能够区分不同的角色和消息边界。这种格式有助于模型理解对话的结构和上下文,从而生成更加连贯和相关的回复。

Read more

消息中间件学习总结(7)——RocketMQ之万亿级数据洪峰下的分布式消息引擎

消息中间件学习总结(7)——RocketMQ之万亿级数据洪峰下的分布式消息引擎

前言 通过简单回顾阿里中间件(Aliware)消息引擎的发展史,本文开篇于双11消息引擎面临的低延迟挑战,通过经典的应用场景阐述可能会面临的问题 - 响应慢,雪崩,用户体验差,继而交易下跌。为了应对这些不可控的洪峰数据,中间件团队通过大量研究和实践,推出了低延迟高可用解决方案,在分布式存储领域具有一定的普适性。在此基础上,通过对现有有限资源的规划,又推出了分级的容量保障策略,通过限流、降级,甚至熔断技术,能够有效保障重点业务的高吞吐,成功的支撑集团包括海外业务平缓舒畅地度过双11高峰。与此同时,在一些对高可靠、高可用要求极为苛刻的场景下,中间件团队又重点推出了基于多副本机制的高可用解决方案,能够动态识别机器宕机、机房断网等灾难场景,自动实现主备切换。整个切换过程对用户透明,运维开发人员无需干预,极大地提升消息存储的可靠性以及整个集群的高可用性。 1. 消息引擎家族史 阿里中间件消息引擎发展到今日,前前后后经历了三代演进。第一代,推模式,数据存储采用关系型数据库。在这种模式下,消息具有很低的延迟特性,尤其在阿里淘宝这种高频交易场景中,具有非常广泛地应用。第二代,拉模式,自研的专有

By Ne0inhk
消息中间件学习总结(8)——RocketMQ之RocketMQ捐赠给Apache那些鲜为人知的故事

消息中间件学习总结(8)——RocketMQ之RocketMQ捐赠给Apache那些鲜为人知的故事

序言 今年的双十一对阿里巴巴中间件消息团队来说,注定是个不平凡的日子。在这一天,稳定性小组重点攻克的低延迟存储解决方案成功地经受住了大考。整个大促期间,99.996%的延迟落在了10ms以内,极个别由于GC引发的停顿在50ms以内,对于读写比例几乎均衡的分布式消息引擎来说,这一结果无不令人兴奋。甚至可以毫不夸张地讲,即便拿到明年的Java one大会上,也必定是场非常吸睛的技术干货分享。接下来,团队同学会把相关的经验提炼总结出来,期待能在接下来全球Qcon大会上为小伙伴们带去尽可能多的干货分享。 除此之外,更让大家倍感欣慰是我们终于为赢得世界的尊重,拥抱世界走出了第一步,这一步走的着实不易,每走一步,回头看看,都是记忆满满。正所谓,桥曾坚固,但已坍塌;路虽沧桑,但已破旧;街曾繁华,但已被拆;巷虽深远,但已变旧。唯一不变的,是那生命里留下的深深脚印。 初衷 捐赠最好的项目给Apache~ 这个想法,最早是14年中旬,在开发maven dependency mediator这个开源组件的时候冒出来的。当时,为了解决中间件组件依赖问题,我研究分析了业界最主流的开源方案,有Maven

By Ne0inhk
java监控命令报错 ERROR: ptrace(PTRACE_ATTACH, ..) failed for 12015: Operation not permitted 错误处理

java监控命令报错 ERROR: ptrace(PTRACE_ATTACH, ..) failed for 12015: Operation not permitted 错误处理

执行jinfo,jstat等命令报错ERROR: ptrace(PTRACE_ATTACH, ..) failed for 12015: Operation not permitted; 原因是操作系统出于安全考虑,引入了一种叫做ptrace scope的安全机制。这种机制为了防止用户访问当前正在运行的进程的内存和状态,所以在调试程序的过程中导致gdb不能正常工作。这种安全机制可以防止恶意软件附加到其他进程中(如SSH或者GPG),读取程序内存,产生安全问题。比如著名的openssl的"心脏出血"漏洞。 建议“ echo 0 > /proc/sys/kernel/yama/ptrace_scope ”,调试结束后再改成1;echo 1 > /proc/sys/kernel/yama/ptrace_scope;毕竟是为了安全。当然这个需要root权限或者sudo; root@zhouxx:~# vi

By Ne0inhk
Java web应用性能分析之【6种OOM模拟】

Java web应用性能分析之【6种OOM模拟】

常见的6中OOM 1. 堆溢出-java.lang.OutOfMemoryError: Java heap space。 检查大对象 2. 栈溢出-java.lang.OutOfMemorryError:unable to create new native thread    检查多线程 3. 栈溢出-java.lang.StackOverFlowError。 检查递归 4. 元信息溢出-java.lang.OutOfMemoryError: Metaspace。 5. 直接内存溢出-java.lang.OutOfMemoryError: Direct buffer memory。 排查nio,一般重点检查netty,它里面的nio用直接内存用的多 6. GC超限-java.lang.OutOfMemoryError: GC overhead limit exceeded。 验证效果 启动脚本

By Ne0inhk