文章目录
- [0. 引言](#0. 引言)
- [1. 大语言模型的运用](#1. 大语言模型的运用)
-
- [1.1 角色标识与管理](#1.1 角色标识与管理)
- [1.2 内容结构化](#1.2 内容结构化)
- [1.3 元数据传递](#1.3 元数据传递)
- [1.4 模拟多轮对话](#1.4 模拟多轮对话)
- [2. tokenizer如何配合](#2. tokenizer如何配合)
-
- [2.1 ChatML 标签的标记化](#2.1 ChatML 标签的标记化)
- [2.2 处理特殊标记](#2.2 处理特殊标记)
- [3. 训练时如何处理ChatML](#3. 训练时如何处理ChatML)
-
- [3.1 训练数据预处理](#3.1 训练数据预处理)
- [3.2 调整训练目标](#3.2 调整训练目标)
- [3.3 使用约束解码技术](#3.3 使用约束解码技术)
- [4. 总结](#4. 总结)
0. 引言
ChatML(Chat Markup Language)是一种用于在对话中定义消息格式的标记语言。它允许开发者以结构化的方式传递消息内容、元数据、角色信息等,从而在对话系统中实现更加复杂和精确的交互。ChatML通常用于描述对话系统中的参与者(如用户、助手)的身份,以及消息的内容,以便模型能够更好地理解上下文并生成相应的响应。
ChatML 的基本结构类似于其他标记语言,如 HTML,但它专门用于对话系统。例如,消息可以被标记为来自用户或助手,还可以包含其他元数据,如时间戳、消息类型等。
1. 大语言模型的运用
1.1 角色标识与管理
ChatML 允许开发者明确指定对话中的角色,例如用户和助手。这种角色标识有助于大模型理解对话的上下文,区分不同角色的发言,从而生成更符合预期的响应。
例如:
plaintext
<|user|> 我想知道今天的新闻。
<|assistant|> 今天的头条新闻是...
在这个示例中,模型通过 <|user|>
和 <|assistant|>
标签来区分谁在说话,从而更好地理解和回应用户的问题。
1.2 内容结构化
ChatML 可以帮助开发者以结构化的方式传递多种信息,包括文本、代码片段、表格、图片链接等。这对于需要处理复杂信息的大模型尤为重要,可以帮助模型准确解析和理解内容。
例如,带有代码片段的对话:
plaintext
<|user|> 你能帮我写一个Python函数吗?
<|assistant|> 当然,这是一个简单的函数:
def add(a, b):
return a + b
1.3 元数据传递
ChatML 可以包含对话中的元数据,如时间戳、消息类型、情绪分析等。这些信息有助于模型在生成响应时考虑更多因素,从而提高生成内容的相关性和准确性。
plaintext
<|user| metadata={"mood": "happy"}|> 我今天心情很好,你呢?
<|assistant|> 很高兴听到这个!我也很好!
在这个示例中,用户消息中的 metadata
提供了额外的信息,帮助模型调整响应的语气和内容。
1.4 模拟多轮对话
ChatML 可以用于模拟多轮对话,使模型能够处理更长时间的上下文,保持对话的一致性和连贯性。
例如,llama2的多轮对话:
<s>[INST] <<SYS>>
{{ system_prompt }}
<</SYS>>
{{ user_message }} [/INST]
2. tokenizer如何配合
ChatML 和 tokenizer 的配合在大语言模型的处理中非常重要,因为它们共同决定了输入文本如何被模型理解和处理。
2.1 ChatML 标签的标记化
ChatML 中的标签(如 <|user|>
和 <|assistant|>
)在输入到模型之前,会经过 tokenizer 的处理。Tokenizer 会将这些标签以及文本内容转化为模型可以理解的 token 序列。通常,这些标签会被标记为一个或多个独立的 token,这样模型就能够识别和区分不同角色或内容类型。
例如,假设我们有以下 ChatML 输入:
plaintext
<|user|> 你好,今天的天气怎么样?
<|assistant|> 今天的天气晴朗,气温在25°C左右。
在标记化后,可能会生成如下的 token 序列(假设每个标签和单词都被标记为一个独立的 token):
[<|user|>, 你好, ,, 今天, 的, 天气, 怎么样, ?, <|assistant|>, 今天, 的, 天气, 晴朗, ,, 气温, 在, 25, °C, 左右, 。]
2.2 处理特殊标记
Tokenizer 可能会为特殊标记(如 <|endoftext|>
)生成特定的 token,用于指示文本的结束或对话的某些特殊状态。ChatML 标签与这些特殊标记共同工作,确保模型在需要时结束生成,或切换到对话的下一个阶段。
3. 训练时如何处理ChatML
在训练大语言模型时,为了确保模型在生成文本时不会输出 ChatML 或其他特殊标签,可以采取以下几种策略。
3.1 训练数据预处理
(1)标签过滤
在训练数据集中,如果包含了类似 <|user|>
或 <|assistant|>
这样的特殊标签,确保这些标签不会被直接用作模型的生成目标。在训练前,可以对数据进行预处理,将这些标签从目标输出中移除,或者用自然语言描述替换它们。
(2)标签编码
如果必须保留这些标签,可以在训练过程中将这些标签编码成不容易被模型误用的特殊 token(如 <SOT>
代表开始标签),并在解码时进行转换。这样,模型即使生成了这些标签,它们也不会以原始形式出现。
3.2 调整训练目标
(1)忽略标签的损失计算
在训练期间,可以将特殊标签的 token 排除在损失函数的计算之外。这意味着即使模型在训练过程中看到这些标签,它们也不会被作为学习的目标。因此,模型在生成输出时更倾向于生成普通文本,而非特殊标签。
(2)增加对自然语言输出的权重
在训练数据中增加自然语言文本的比重,减少或控制含有特殊标签的部分,使模型更倾向于生成自然语言而非特殊标签。
3.3 使用约束解码技术
(1)强制禁用生成特定 token
在推理(生成)阶段,可以使用约束解码技术(如 beam search 或 sampling with constraints),明确禁用生成特定的 token 或 token 序列。如果模型试图生成这些被禁用的 token,解码算法会自动排除这些选项,从而强制模型输出合法的自然语言文本。
(2)使用 logit 替换
在生成过程中,可以动态修改模型的 logit 输出,显著降低特殊标签对应 token 的概率,使它们几乎不可能被选中。
4. 总结
通过使用 ChatML,开发者能够更好地控制和优化大模型的行为,使其更好地理解对话的结构和上下文,从而生成更为精准和贴近用户需求的响应。这在需要复杂对话管理和高精度内容生成的应用场景中尤为重要。
欢迎关注本人,我是喜欢搞事的程序猿; 一起进步,一起学习;
欢迎关注知乎/CSDN:SmallerFL
也欢迎关注我的wx公众号(精选高质量文章):一个比特定乾坤