IBM 发布基于 LLMON 标记语言的 Granite 4.1 3B/8B 实验预览模型
LLMON: An LLM-Native Markup Language, now in Granite 4.1 3B and 8B
IBM 发布两个基于 Granite 4.1 的实验预览模型 granite-4.1-3b-LLMON-preview 和 granite-4.1-8b-LLMON-preview,训练它们消费和生成 LLMON(LLM Object Notation)标记语言,用保留特殊 token 的标签显式标记指令、数据和约束的结构与绑定关系。
官方介绍了LLMON标记语言的设计原理与训练方式,并给出提示注入防御的基准数据,读者可以据此评估能否替换现有 Granite 工作流。
LLM 依赖其上下文来生成下一批 token。在长对话轨迹中,上下文会充满多种类型的组件:系统提示词、过往对话轮次、作用于检索文档的指令、工具响应或用户数据、约束允许输出的要求,以及推理链。上下文带有丰富的结构,但其中大部分对模型而言是隐式的,或以 JSON 等并非为 LLM 消化而设计的格式编码。这是 LLM(尤其是规模较小的模型)脆弱且有时会以意想不到的方式失败的主要原因之一。缺乏显式结构还可能被攻击者利用,例如以提示词注入的形式。
为解决这一问题,我们开发了 LLMON(LLM Object Notation,发音为“lemon”),这是一种 LLM 原生的标记语言,用于向模型显式传达结构和语义。语义上连贯的组件用有意义的标签标记,并包裹在保留的特殊 token 定界符中。数据模式(包括嵌套)以对因果 LLM 而言无歧义的方式声明。唯一 ID 使得可以指向位于上下文任意位置的具体指令,并将其绑定到其应作用于的数据载荷上,类似于编程语言中调用函数并传递参数的方式。
今天我们发布两个实验性预览模型,它们衍生自 Granite 4.1 基础模型,经过训练以消费和生成带有 LLMON 标记的文本:granite-4.1-3b-LLMON-preview 和 granite-4.1-8b-LLMON-preview。我们同时还发布一个 GitHub 仓库,其中包含用于处理 LLMON 的工具包以及工作流和模板示例。
它能带来什么:
- 隐藏在用户数据中的间接提示词注入大多会被 LLMON 模型忽略,这得益于指令/数据的显式分离。在某些基准测试中,攻击成功率降至接近零,而普通的指令微调模型则有很高概率被劫持。同时,与 Granite 4.1 Instruct 模型相比,其通用能力得以保持。
- 无关的段落、旧的对话轮次和工具输出不会被牵扯进答案中,因为每条指令都与其所作用的确切数据绑定。
- 指令、数据和要求都被清晰标记,使得模型能够利用它们在应用代码层面的结构和含义。可以在 Mellea 中试用,它通过自动将 LLM 调用 LLMON 化,原生支持 LLMON。
- 你不再需要费心强迫 LLM 遵守 JSON 结构。使用我们的转换器可以将现有 JSON 无损地转换为 LLMON。你也可以定义自己的结构和相应标签,并在 LLMON 模型之上微调一个 LoRA 来理解它。
为什么不用 JSON?
JSON 是为解析器设计的,而不是为因果语言模型设计的。分词器并不受约束去遵循语法,结构由可能也出现在普通文本中的 token({、"、:)编码。对模型而言,文档内部的引号和关闭字段的引号是同一个 token。对解析器而言清晰的转义规则,对模型来说只是统计模式。嵌套深度靠数括号来编码,而 transformer 在这方面已知较弱,尤其是在长跨度上。
LLMON 则相反,它是一种类 XML 的标记语言,其结构定界符是保留的特殊 token 而非字符,因此结构和内容使用词表的不同部分。标签在每个片段(span)的开头声明,片段之间的边界是显式的。嵌套结构在局部声明,因此模型无需在长片段范围内跟踪层级关系。
由于大多数团队已经有了围绕 JSON 构建的流水线,我们创建了转换工具和示例笔记本,可以在 JSON 与 LLMON 之间无损地相互转换。
LLMON 与聊天模板有什么关系?
LLMON 并不取代聊天模板,而是对它进行增强。常规聊天模板告诉模型哪个部分属于哪个角色(system、user、assistant),而 LLMON 告诉模型每个组件的含义,以及组件之间在角色内部和跨角色时的相互关系。
LLMON 预览模型自带聊天模板,因此你只需像传给任何聊天模型那样构建 messages 列表,并照常调用 apply_chat_template;它会渲染出如下所示的 LLMON。唯一区别是,一轮对话现在可以为各个部分命名,并将每个部分标记为 exec:True 或 False。被标记为 True 的部分会绑定到渲染输出底部的 exec 块中,该块声明要运行哪条指令以及它操作的对象;被标记为 False 的部分仍会渲染到上下文中,但不会被任何内容引用。
messages = [ { "role": "user",
"instruction": [{ "value": "Write a short paragraph about", "exec": True }],
"data": [{ "value": "IBM Company", "exec": True }],
"requirement": [ {"value": "Use less than 10 words", "exec": True},
{"value": "Do not use commas", "exec": True}]
} ]
模型接收到的是如下内容(此处为便于阅读添加了换行和缩进,模板本身并不输出这些):
<|open|>instr<|:|>Ȗ<|close|>Write a short paragraph about<|open_end|>
<|open|>data<|:|>ä¦<|close|>IBM Company<|open_end|>
<|open|>req<|:|>Á¼<|close|>Use less than 10 words<|open_end|>
<|open|>req<|:|>¢¬<|close|>Do not use commas<|open_end|>
<|open|>exec<|:|>ÄÐ<|close|>
<|open|>exec<|.|>instruction<|close|>instr<|:|>Ȗ<|open_end|>
<|open|>exec<|.|>input<|close|>data<|:|>ä¦<|open_end|>
<|open|>exec<|.|>requirement<|close|>req<|:|>Á¼<|open_end|>
<|open|>exec<|.|>requirement<|close|>req<|:|>¢¬<|open_end|>
<|open|>exec<|.|>output<|close|>assistant<|:|>ãø<|open_end|>
<|open_end|>
<|open|>assistant<|:|>ãø<|close|>
双字符的块 ID 取自一个固定集合,该分词器将其中每个 ID 编码为单个 token,因此无论使用哪个 ID,寻址一个块始终只消耗两个 token。
角色仍然是一个单独的 user 轮次,但其各组件以五个可独立寻址的块的形式到达模型,并由第六个块(exec 块)将它们绑定在一起,该块声明:运行这条指令,作用于这些数据,受这两项要求约束,并把答案放入此处指定的块中——也就是模型随后填充的同一个 assistant 块。传统模板会把所有组件展平成一个字符串,让模型自行推断哪部分是任务、哪部分是对象、哪些是约束。
LLMON 如何应对提示注入攻击
间接提示注入是一种攻击方式,恶意指令被隐藏在数据载荷中,例如检索到的文档、工具响应或用户提供的数据。这正是 LLMON 的指令/数据分离设计所要解决的问题。
我们将 LLMON 预览模型与多个开源和闭源模型进行了比较。我们在 OPI 基准上进行了评估,该基准将注入内容置于经典 NLP 任务的数据中,并采用了多种攻击策略。我们报告的鲁棒性定义为 1 − 攻击成功率,即在攻击中模型未执行被注入指令的比例。
所有非 LLMON 模型都极易受攻击,会以很高的概率执行注入的指令。LLMON 在该基准上几乎消除了这一问题:相对于我们测试过的最佳前沿模型,多避免了 47% 的攻击;相对于最佳开源模型,多避免了 95% 的攻击。我们在其他基准(ASB 和 StruQ)上也观察到类似的趋势。值得注意的是,这些基准测试的是对静态间接提示注入的鲁棒性,而指令/数据分离恰好直接应对这类攻击。我们也在积极改进跨多轮对话展开的自适应攻击的防御能力。
通用能力
安全性的提升并不以牺牲通用能力为代价。在各类标准基准上,LLMON 模型的表现与 Granite 4.1 Instruct 模型相当。
简而言之,如果你今天正在试用 Granite 4.1 3B 或 8B,可以换用 LLMON 预览版,应当能获得相当的通用性能,同时获得强得多的提示注入抵抗能力。无需任何转换流水线,只需对对话轮次中的各部分命名(例如上面示例中的 instruction、data、requirement)即可。随附的聊天模板会自动将它们转换为 LLMON 块。我们的 LLMON-converters 库则更进一步:如果某个部分本身是结构化的,例如 JSON 文档,LLMON 化会将其结构保留为有类型、可独立寻址的块,而不是一整段不透明的字符串。
我们如何训练这些模型
这些模型从 Granite 4.1 的基础检查点(而非已发布的 instruct 模型)出发,因此 LLMON 行为是在后训练阶段习得的,而不是叠加在现有聊天格式之上。
LLMON 定义了六个定界符,用于标记标签的开始与结束,并支持嵌套与锚定;它们作为保留的单个 token 安装在分词器中。我们将一个常规的指令微调语料库重新序列化为 LLMON 格式:每个提示组件都成为自己可寻址的块,每个轮次都带有一个执行块,指明要运行哪条指令、作用于哪些输入,以及输出去向。任务配比与常规 instruct 模型所见相同(聊天、多轮、RAG、工具调用),这也是基准性能与常规微调模型相近的原因。此外,我们用上下文中存在但刻意不绑定的诱饵指令和数据块来扩充数据,而目标输出保持不变。这样模型就学会遵循执行块所规定的依赖关系,而忽略其余内容。随后是强化学习:五个连续的 GRPO 阶段,涵盖多领域推理、RLHF、知识校准和数学,最后是一个 DPO 阶段,使用由模型自身对注入尝试的响应构建的约一千条 on-policy 偏好对。
由此产生的权限规则是从这一布局中自然得出的,而非额外加上的防护栏:通过执行块触达的指令具有权威性,而作为输入触达的任何内容(数据、文档、工具 schema、工具结果)只是供阅读的材料,而非要执行的命令。此外,执行块中未被调用的指令和数据片段会被忽略。这是一种习得的行为,而非强制的保证。要了解这一点在 LLMON 模型的注意力层中如何体现,可以在 Hugging Face Spaces 上试试 LLMON Attention Visualization。
自带词表(ScienceWorld)
LLMON 并不绑定固定的模式(schema):你可以选择适合自己领域的标签名称和结构,并微调一个适配器来读写它们。我们在 ScienceWorld 上演示了这一点。ScienceWorld 是一个文本型基准测试,智能体在其中通过逐条发出命令并从模拟器获得得分来完成基础科学任务(例如把水烧开)。我们定义了一个词表,用于捕捉解决这些任务所涉及的规划轨迹中的结构。该词表包含诸如 instr.task.goal、req.planning_policy.rule、data.state.room、data.state.inventory 和 assistant.next_action 这样的标签。我们用这些标签渲染了 ScienceWorld 参考解法的每一步,并在 LLMON 模型之上微调了一个 LoRA。训练后的模型随后游玩留出的测试对局,并用新词表写出其下一步动作。这个笔记本演示了完整的工作流程,从转换参考轨迹,到游玩测试对局,再到将适配器与未经训练的基础模型进行对比评分。另一个面向工具调用智能体的示例可在这个笔记本中找到。
立即试用
这是一个实验性预览版,适合探索和评估,但尚未达到生产环境的要求。
- 模型:granite-4.1-3b-LLMON-preview & granite-4.1-8b-LLMON-preview
- 可视化演示:LLMON 注意力可视化
- LLMON 仓库:https://github.com/generative-computing/llmon
- Mellea:https://github.com/generative-computing/mellea
- 论文:https://arxiv.org/abs/2610.38120、https://arxiv.org/abs/2603.22519
告诉我们你的发现:哪些有效、哪些失败了,以及你希望看到哪些用例。欢迎发布到 GitHub Discussions。
来源: Hugging Face Blog · huggingface.co


