接下来,我们要插入角色控制的特殊 token。这部分就不需要使用基于 ML 或者神经网络的分词器了,直接根据结构,用传统算法编排 role 和 content 的结构就行
我不理解,为什么一定要使用特殊 Token 来处理角色控制,又为什么要将角色和内容分开处理?我为什么不能直接将下面的文本作为 Chat Template,直接进行分词和嵌入?
用户:你好!\n\n 助手:你好,我是你的 AI 助理。\n\n 用户:我想问一个问题
Role Control or Role Play?
正如我的前一篇文章所言,Token String 是给人看的,Token ID 是给程序看的,而 Vector 才是模型处理的内容。
为了训练一个对话模型,我们需要提供大量的、结构化的模型数据,让模型学会“对话”是怎么进行的。例如,我们以 <User> 和<Assistant>这两个特殊 文本 作为表示角色的标记,并将其贯彻在所有语料中,那么模型将如我们所预期的那样,在 <User> 和<Assistant>这两个 Token(对应的 ID)上,拟合到极为强大的语义特征——这两个 Token 一旦出现,就意味着接下来文本的说话人发生了变化。这种在训练时定向拟合形成的、强大的角色感知,我们称之为角色控制(Role Control)。在模型看来,这就是它记忆里自己和你曾经的对话。
而我们在一些 System Prompt 中经常见到这样一种写法:
<example>
<User> 你好!<Assistant> 你好,我是 xx 助手,由 xxx 开发……
</example>
<User> 和 <Assistant> 标签看起来很像 Role Control 吧?实际上,这里的 Prompt 充其量只是 Role Play,即角色扮演。其对于模型的控制力远远小于上文的真·Role Control,如果把上文的 Role Control 比作你记忆里我们之前的对话,那么这段对话的充其量只是我对你说:”我们之间进行过了几轮对话,我刚才说 xxx,你回答我 xxx“。模型学习过这类角色扮演的语料,并且有足够的泛化能力理解和应对,会在一定程度上理解你表达的意思,但这与真正的 Role Control 本质不同且相去甚远。
为什么不能将 <User> 和 <Assistant> 文本作为 Role Control?
如果直接将 <User> 和 <Assistant> 文本作为特殊 Token,那么意味着 Role Control 的强大语义表达,侵占了这两个词可能含有的其他语义;换句话说,用户不能用这两个特定字符串表示其他的意思了。放在文本中,那么这两个词的语义就是彻底的过拟合(因为模型将有极强的倾向认为其语义是角色转换,其他可能性被大幅度忽视),会导致模型误以为此处即发生了角色转换,进而不能理解到文本的真实含义。换句话说,这个词的词义被污染了,既不是完全的角色控制,也没能表达好自然语言的含义。
举个形象点的例子,某个网站直接使用字符串拼接的方式构造 SQL 查询语句,那么输入如果包含 AND 1=1 这样的特殊内容,即使用户的本意并不是 Bool 盲注,那么也可能导致 SQL 处理失误 。
如果我们使用更加复杂、非常用字符串(如带 <> 或 | 的格式,<|im_start|>user),以期避免与常用词冲突,那么问题来了:什么是常用字符串,又有什么是非常用字符串?如果认为使用常用字符串会对模型运行产生干扰,那么即使使用非常用字符串,干扰仍然存在,只不过现实场景中触发概率更小而已,但同样可以确定是失败的设计。设计一种更加复杂混乱的 SQL 方言,并不能从根本上填堵存在特殊字符组合导致 SQL 注入行为的风险。
直接禁止用户输入 <User> 和 <Assistant>,更是饮鸩止渴的错误处理,这就像 WAF 直接通过关键字匹配,把可能涉及 SQL 注入的特殊字符串拉黑了,导致用户永远无法传入这样的内容,无论其本意如何。
最终的解决方法——科学地构造 Chat Template
因此,目前的大语言模型基本都采取了同一种策略——分离角色(Role)和正文(Content)。
区别对待 Chat Template 的不同部分才是正解。对于正文部分,我们期望它是一个纯文本的语义表达,它不该包含任何特殊字符。因此我们先将正文提取出来,使用一个不含任何特殊 Token 的 tokenizer 分词完毕,得到不含任何特殊 Token 的 Token ID 序列,然后按照规则,将其与角色控制的特殊 Token 拼接成最终的 Chat Template。
采用这种方式,我们才可以正确地处理任何形式的用户输入,而不需要担心特殊 token 的强大语义表达影响真实的语义理解。
同样按照 SQL 安全的话说,这相当于预编译 SQL 语句,在逻辑上显式地区分命令(Command)和内容(Content),保证能够处理用户的任何输入组合。