我目前正在使用 Huggingface 中的 SFTTrainer 微调 LLama 模型。但是,我提出了一个问题,我无法通过文档回答(至少,它有点模糊)。
我的数据集包含从 20 个令牌到 5k 个令牌的样本。
目前我正在使用 || |和
max_seq_length=512,
.
packing=True
但是,我不清楚的是,具有 >512 个标记的样本会发生什么情况。它们是否被简单截断?
如果是,是否有任何简单的选项来分割它们,而不是截断它们?
If yes, is there any simple option to split them, rather to truncate them?
是的,在
SFTTrainer
中使用
max_seq_length=512
时,长度超过 512 个标记的样本会被
截断
。 这意味着只会保留前 512 个标记,其余标记将被丢弃。
你有几个选项可以避免截断并利用你的长序列样本:
-
增加
max_seq_length
: - 这是最简单的选择,但它会增加内存使用量并可能导致训练速度变慢。
- 你需要找到一个在模型能力和内存限制之间取得平衡的值。
-
尝试不同的
max_seq_length
值,看看哪个值最适合你的硬件和数据集。 -
将长样本分割成较小的块:
-
你可以使用数据预处理步骤将长样本分割成多个较小的块,这些块可以容纳在
max_seq_length
限制内。 - 例如,你可以将 1024 个标记的样本分割成两个 512 个标记的样本。
-
你需要确保在分割样本时保留上下文信息。这可以通过以下方式实现:
- 重叠窗口: 使用重叠的窗口来分割样本,以便每个块都包含来自先前块的一些上下文信息。
- 添加特殊标记: 在每个块的开头添加特殊标记,以指示它是较长序列的一部分,并在块之间提供上下文信息。
-
使用支持长序列的模型/方法:
- 一些模型和方法专门设计用于处理长序列,例如 Transformer-XL、Reformer 和 Longformer。
- 这些模型使用不同的技术来有效地处理长距离依赖关系,并且可以处理比传统 Transformer 更长的序列。
- 但是,切换到不同的模型或方法需要对代码进行更重要的更改。
关于你的问题的直接答案:
目前,
SFTTrainer
没有提供自动分割长序列的内置选项。你需要在将数据传递给训练器之前预处理数据以分割样本。
我建议首先尝试增加
max_seq_length
,看看它是否有助于你的特定任务和数据集。如果内存使用量成为一个问题,那么将长样本分割成较小的块是一个不错的选择。