使用 MinT
SFT 监督微调
SFT(监督微调)适用于有标注的 prompt → response 数据。在 MinT 上通过 loss_fn='cross_entropy' 走标准训练循环,训练对象是 LoRA 低秩适配器。
构造 Datum
Prompt token 的 loss weight 设为 0,不参与梯度计算;completion token 的 weight 设为 1.0。整体经过 teacher-forcing 偏移:input 为 all_tokens[:-1],target 为 all_tokens[1:],weights 为 all_weights[1:]。
def process_sft_example(prompt_text, completion_text, tokenizer):
prompt_ids = tokenizer.encode(prompt_text, add_special_tokens=True)
completion_ids = tokenizer.encode(f" {completion_text}", add_special_tokens=False)
completion_ids.append(tokenizer.eos_token_id)
all_tokens = prompt_ids + completion_ids
all_weights = [0.0] * len(prompt_ids) + [1.0] * len(completion_ids)
return types.Datum(
model_input=types.ModelInput.from_ints(tokens=all_tokens[:-1]),
loss_fn_inputs={
"target_tokens": all_tokens[1:],
"weights": all_weights[1:],
},
)Chat 风格的数据推荐使用 apply_chat_template(..., add_generation_prompt=True) 处理 prompt 部分。
使用 Renderer(推荐)
mint.recipe 提供 Renderer,自动处理 chat template、loss masking 和 teacher-forcing 偏移:
from mint import recipe
renderer = recipe.renderers.get_renderer(
recipe.get_recommended_renderer_name("Qwen/Qwen3-0.6B"), tokenizer
)
messages = [
{"role": "user", "content": "..."},
{"role": "assistant", "content": "..."},
]
model_input, weights = renderer.build_supervised_example(messages)
datum = recipe.datum_from_model_input_weights(model_input, weights, max_length=2048)多轮对话默认只对最后一条 assistant 消息算 loss;如需在每条 assistant 消息上都算,传 train_on_what=TrainOnWhat.ALL_ASSISTANT_MESSAGES。
参数
| 参数 | 类型 | 默认值 | 含义 |
|---|---|---|---|
base_model | str | "Qwen/Qwen3-0.6B" | 底座模型 ID |
rank | int | 16 | LoRA 秩;越大表达力越强但显存更多,典型 8–64 |
train_mlp | bool | True | 训练 MLP 层 |
train_attn | bool | True | 训练 attention 层 |
train_unembed | bool | True | 训练 unembedding(输出)层 |
loss_fn | str | "cross_entropy" | SFT 固定使用 cross_entropy,无其他选项 |
learning_rate | float | 5e-5 | Adam 学习率;instruction tuning 典型 1e-5 到 1e-4 |
weight_decay | float | 0.0 | L2 正则;LoRA 典型 0.0–0.01 |
Tinker 兼容说明
- 不要调用
zero_grad_async();MinT 服务端自动清零梯度。 loss_fn传给forward_backward(...),不传给AdamParams。save_weights_for_sampler(...)与save_weights_and_get_sampling_client(...)在序列化 LoRA 权重方面等价。
何时选择哪种算法
SFT 适合"有标注的 prompt → response"。偏好对数据请看 DPO;带奖励 / 验证器 / 环境反馈的场景请看 RL (GRPO);两阶段管线请看 SFT + RL 组合 Recipe。