微调数据的结构直接决定了模型学习到的能力。要让模型掌握一项新能力,您必须以一致、机器可读的格式提供该能力的示例。对于大多数微调任务,这些数据通常采用两种主要格式之一组织:指令式或对话式。您选择的格式是一项基础性决定,它使您的数据集与模型的预期使用场景相符。指令式格式指令式数据集旨在训练模型执行特定、独立的任务。模型学习将给定的提示映射到期望的完成内容。这种格式非常适合需要一次性请求和响应的应用,例如文本摘要、翻译、分类和问答。最常见的结构是一系列 JSON 对象,其中每个对象代表一个训练示例。尽管字段名称可能有所不同,但它们通常包含一个指令、一个可选的用于提供上下文的输入,以及期望的输出。设想一个用于训练模型总结文章的数据集。一个数据点可能看起来像这样:{ "instruction": "用三句话总结以下文章。", "input": "The Falcon 9 is a two-stage rocket designed and manufactured by SpaceX for the reliable and safe transport of satellites and the Dragon spacecraft into orbit. The rocket's first stage is reusable, capable of re-entering the atmosphere and landing vertically after separating from the second stage. This reusability has significantly reduced the cost of access to space.", "output": "The Falcon 9 is a two-stage, reusable rocket from SpaceX used for orbital transport. Its first stage can land vertically after launch, a feature that lowers launch costs. This capability makes it a cost-effective choice for deploying satellites and spacecraft." }训练期间,这些结构化字段通常使用提示模板组合成一个字符串。该模板统一了输入格式,告知模型需要执行哪种任务。对于上述示例,模板可能是:prompt = f"""以下是一个描述任务的指令,以及提供更多上下文的输入。请写出恰当完成请求的回复。 ### 指令: {example['instruction']} ### 输入: {example['input']} ### 回复: """模型随后被训练,以生成output字段中的文本作为对该格式化提示的完成。提示模板在所有示例中的一致性对于稳定的训练是很有帮助的。对话式格式对话式数据集训练模型进行多轮对话。数据不以单一指令和响应的形式,而是以一系列交流的形式组织。这种格式对于构建聊天机器人、虚拟助手或任何必须在多次交互中保持上下文的应用来说都很必要。数据通常表示为回合列表,其中每个回合都指定说话者的角色(user或assistant)及其消息(content)。许多开源模型(如Llama)都是使用这种结构的数据进行微调的。以下是一个用于训练技术支持助手的两轮对话示例:{ "messages": [ { "role": "用户", "content": "我正在尝试连接到我的新数据库,但收到“连接超时”错误。我应该首先检查什么?" }, { "role": "助手", "content": "“连接超时”错误通常指向网络或防火墙问题。您能确认您的机器可以访问数据库服务器的IP地址,并且您与服务器之间的任何防火墙上端口5432已打开吗?" }, { "role": "用户", "content": "我可以ping通IP,但我怎么检查端口呢?" }, { "role": "助手", "content": "您可以使用`telnet`或`nc`(netcat)这样的工具。例如,在命令行中,您可以运行`telnet YOUR_DATABASE_IP 5432`。如果连接成功,则端口是开放的;否则,它很可能被阻止了。" } ] }这个完整的消息列表构成一个训练示例。模型学习根据整个之前的对话历史来生成assistant的回复。处理过程中,回合列表会被转换为一个格式化字符串,通常使用基础模型分词器定义的特殊标记来区分角色和回合。比较数据结构这两种格式的主要区别在于它们对上下文的表示。指令式格式是无状态的,将每个示例视为一个独立任务。对话式格式是有状态的,训练模型基于对话中的先前回合进行回复。digraph G { rankdir=TB; splines=ortho; node [shape=box, style="filled,rounded", fontname="sans-serif", margin=0.2]; edge [fontname="sans-serif", color="#495057"]; subgraph cluster_0 { style="filled,rounded"; color="#e9ecef"; label="指令式流程"; "Instruction" [label="提示\n(指令 + 输入)", fillcolor="#a5d8ff"]; "Model_I" [label="模型", fillcolor="#fa5252"]; "Response" [label="输出", fillcolor="#69db7c"]; "Instruction" -> "Model_I" [arrowhead=normal]; "Model_I" -> "Response" [arrowhead=normal]; } subgraph cluster_1 { style="filled,rounded"; color="#e9ecef"; label="对话式流程"; "User_1" [label="用户回合 1", fillcolor="#a5d8ff"]; "Model_A1" [label="模型", fillcolor="#fa5252"]; "Asst_1" [label="助手回合 1", fillcolor="#69db7c"]; "User_2" [label="用户回合 2", fillcolor="#a5d8ff"]; "Model_A2" [label="模型", fillcolor="#fa5252"]; "Asst_2" [label="助手回合 2", fillcolor="#69db7c"]; "User_1" -> "Model_A1" -> "Asst_1" -> "User_2" -> "Model_A2" -> "Asst_2" [arrowhead=normal]; } }该图说明了指令式(单轮)和对话式(多轮)数据格式的信息流。如何选择合适的格式您选择的数据格式应完全取决于最终应用的需求。在以下情况使用指令式格式:任务是独立的,不依赖于之前的交互。例如文档总结、情感分析或根据规范生成代码。您希望为明确定义、可重复的功能构建一个可靠工具。输入和输出明确定义且独立完整。在以下情况使用对话式格式:模型必须记住交互的先前部分才能连贯地回应。应用是聊天机器人、客户支持代理或角色扮演角色。交互预期是多轮演进的对话。也可以将单轮任务构建到对话式结构中。例如,一条指令可以简单地成为两轮对话中的第一个user消息。然而,对于严格面向任务的微调,指令式格式更为直接,通常也更易于构建。选择合适的数据结构是确保模型学习您打算实现的行为的第一步。