LLaMA-Factory mask_history
2025-12-17
LLaMA-Factory
00

目录

mask_history 参数详解
1. 基本定义
2. 核心机制
2.1 反转编码顺序(优先保留最后一轮)
2.2 屏蔽历史轮次的损失
2.3 反转序列拼接顺序
3. 实际效果对比
当 mask_history=False(默认):
当 mask_history=True:
4. 使用场景
5. 限制条件
6. 与您例子中的 loss_mask 的关系
7. 总结

mask_history 参数详解

1. 基本定义

54:57:src/llamafactory/hparams/data_args.py
展开代码
mask_history: bool = field( default=False, metadata={"help": "Whether or not to mask the history and train on the last turn only."}, )
  • 默认值:False
  • 作用:在多轮对话中,只对最后一轮计算损失,历史轮次不参与损失计算

2. 核心机制

2.1 反转编码顺序(优先保留最后一轮)

49:50:src/llamafactory/data/processor/supervised.py
展开代码
if self.data_args.mask_history: encoded_pairs = encoded_pairs[::-1] # high priority for last turns
  • 将对话对反转,确保最后一轮优先处理,避免被截断

2.2 屏蔽历史轮次的损失

70:73:src/llamafactory/data/processor/supervised.py
展开代码
if self.data_args.mask_history and turn_idx != 0: # train on the last turn only target_label = [IGNORE_INDEX] * target_len else: target_label = target_ids
  • turn_idx == 0:最后一轮,正常计算损失
  • turn_idx != 0:历史轮次,target_label 设为 IGNORE_INDEX,不计算损失

2.3 反转序列拼接顺序

75:80:src/llamafactory/data/processor/supervised.py
展开代码
if self.data_args.mask_history: # reversed sequences input_ids = source_ids + target_ids + input_ids labels = source_label + target_label + labels else: input_ids += source_ids + target_ids labels += source_label + target_label
  • mask_history=True:新内容前置(source_ids + target_ids + input_ids
  • mask_history=False:按时间顺序拼接(input_ids += source_ids + target_ids

3. 实际效果对比

假设有一个3轮对话:

展开代码
轮次1: User: "你好" → Assistant: "你好!" 轮次2: User: "今天天气怎么样?" → Assistant: "今天天气很好。" 轮次3: User: "适合出门吗?" → Assistant: "适合出门。"

mask_history=False(默认):

展开代码
input_ids: [轮次1的user+assistant] + [轮次2的user+assistant] + [轮次3的user+assistant] labels: [IGNORE...IGNORE, 轮次1的assistant] + [IGNORE...IGNORE, 轮次2的assistant] + [IGNORE...IGNORE, 轮次3的assistant]
  • 所有轮次都计算损失

mask_history=True

展开代码
input_ids: [轮次3的user+assistant] + [轮次2的user+assistant] + [轮次1的user+assistant] (反转) labels: [IGNORE...IGNORE, 轮次3的assistant] + [IGNORE...IGNORE, IGNORE...IGNORE] + [IGNORE...IGNORE, IGNORE...IGNORE]
  • 只有最后一轮(轮次3)计算损失
  • 历史轮次仍作为上下文,但不参与梯度更新

4. 使用场景

  • 长对话训练:只优化最新回复,避免历史干扰
  • 上下文学习:保留历史作为上下文,但不训练历史回复
  • 节省计算:减少需要计算损失的 token 数

5. 限制条件

176:177:src/llamafactory/hparams/data_args.py
展开代码
if self.mask_history and self.train_on_prompt: raise ValueError("`mask_history` is incompatible with `train_on_prompt`.")
  • 不能与 train_on_prompt=True 同时使用(两者冲突)

6. 与您例子中的 loss_mask 的关系

  • mask_history:在数据预处理阶段统一屏蔽历史轮次
  • loss_mask:在消息级别精细控制每个消息是否计算损失

目前 LLaMA-Factory 不支持消息级别的 loss_mask,但 mask_history 可以实现“只训练最后一轮”的效果。

7. 总结

  • mask_history=True:只对最后一轮计算损失,历史轮次作为上下文但不参与训练
  • 适用于长对话场景,可节省计算并聚焦最新回复
  • train_on_prompt 互斥
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Dong

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!