当前,它仅返回最小批量大小为1。我们希望在发生内存溢出之前尽可能增加批量大小。这只需要进行前向传递。
wlsrxk511#
kuhbmx9i2#
b4qexyjb3#
关于Ludwig Slack的问题:
在模型训练过程中(即作为微调的一部分),是否要最大化"forward"路径的batch_size,还是仅在predict()部分(即纯粹作为推理的一部分——“零梯度”)?如果是前者,那么这意味着我们正在处理微调的情况,那么eval_batch_size是否应该接受FineTuneTrainerConfig中的auto和None值?如果是后者,那么同样的问题也会出现在LLMTrainerConfig中(因为NoneTrainerConfig继承了LLMTrainerConfig,实际功能将进入NoneTrainer)。或者是另一个配置类?通过尝试ECD测试,test_trainer.py::test_tune_batch_size_and_lr,我假设对于LLM情况,它将是关于LLMTrainerConfig或NoneTrainerConfig;然而,初步实验表明是FineTuneTrainerConfig,因为这是解析配置的方式(即在FineTuneTrainerConfig中验证eval_batch_size)。
如果有额外的背景信息,将不胜感激。
py49o6xq4#
在模型训练过程中(即作为微调的一部分),是想最大化"forward"路径的batch_size,还是只在predict()部分(即纯粹作为推理——“零梯度”——使用,在这种情况下,我们不使用基础模型,而是将config["adapter"]["pretrained_adapter_weights"]设置为已经微调过的模型名称)?NoneType LLM Trainer类用于零样本/少量样本推理!因此,这将是最大化model.train()函数调用中的batch_size,其中trainer: type设置为None,类似于这样:
model.train()
trainer: type
trainer: type: none
在这种情况下,我们要么使用预训练/微调的基础模型,要么使用预训练的基础模型加上适配器来执行前向传播并最大化batch大小。如果是前者,意味着我们正在处理微调的情况,那么eval_batch_size是否应该接受FineTuneTrainerConfig中的auto和None值?如果是后者,那么同样的问题也会出现在LLMTrainerConfig(因为NoneTrainerConfig扩展了LLMTrainerConfig,实际功能将进入NoneTrainer)。或者是不同的配置类?通过在ECD测试中进行实验,test_trainer.py::test_tune_batch_size_and_lr,我假设对于LLM情况,它将是关于LLMTrainerConfig或NoneTrainerConfig;然而,初始实验指向FineTuneTrainerConfig,因为这是解析配置的方式(即,在FineTuneTrainerConfig中验证eval_batch_size)。既然是后者的情况,我们基本上可以将batch_size: auto作为训练器配置的一部分:
batch_size: auto
trainer: type: none batch_size: auto
这将尝试从最小可能的batch大小(1)一直到epoch大小的batch大小,并适应可以放入内存而不会导致CPU/GPU OOMs的最大可能的batch大小(我们在这里主要关注的是GPU OOMs)。实际代码实现将进入NoneTypeTrainer实现:https://github.com/ludwig-ai/ludwig/blob/master/ludwig/trainers/trainer_llm.py#L217。由于此函数在训练器中被调用时模型已经在内存中初始化,因此它只需要执行前向传播直到OOM。任何额外的背景都将非常有帮助。我认为这里有两件事我们想要做:
epoch
torch.no_grad()
max_new_tokens
max_sequence_length
global_max_sequence_length
min_new_tokens
t0ybt7op5#
以下是对情况的分析(由@arnavgarg1和@alexsherstinsky提出),并提出了未来工作的想法。
暂停对这个功能的进一步开发;需要进行更深入的产品级和设计讨论才能继续进行。
零样本/少样本推理要求在执行 model.predict() 之前必须先执行 model.train() ,这是与生成元数据有关的特殊情况,只能通过执行 model.train() 调用来获得。因此,我们必须“伪训练”模型以进行零样本/少样本推理。为此,我们将训练器类型配置为“none”,然后当 LudwigModel.train() 执行时,将调用 LudwigModel._tune_batch_size() 。执行 LudwigModel._tune_batch_size() 将更新内存中的 LudwigModel.config_obj.trainer.batch_size = tuned_batch_size 。在内部,它会调用训练器的 tune_batch_size() 方法。对于 ECD 模型,如果 batch_size 设置为“auto”或 eval_batch_size 设置为“auto”/ None ,那么它实际上只会做一些事情;否则,它会被跳过,因为这些批量大小是用户明确设置的。对于 NoneTrainer ,我们目前只是返回 1 (https://github.com/ludwig-ai/ludwig/blob/master/ludwig/trainers/trainer_llm.py#L217)。“伪训练”实际上只是在表面上为每个数据集调用 model.evaluate() ,计算一组“指标”;本质上,需要调用 model.train() -- 即使没有进行训练 -- 以便能够使用预训练的 LLMs 进行 model.predict() 调用(否则,Ludwig 会报错,提示模型“尚未训练”)。然而,在当前实现中,这种最优的 batch_size 将无法提供给 model.predict() (因为 model.predict() 以 128 为默认参数接受 batch_size 作为参数)。这一事实意味着当前的 batch_size 优化(没有进行架构更改的情况下)仅是为了加速最终过时的 model.train() 调用。此外,当训练器 type 被配置为“none”并在新鲜加载的微调 LLM 上执行推理时, model.train() 调用执行速度极快(在 Ludwig 从存储中加载模型后)。下面是一个 Google Colab笔记本中的示例配置,用于说明所进行的实验:
model.predict()
LudwigModel.train()
LudwigModel._tune_batch_size()
LudwigModel.config_obj.trainer.batch_size = tuned_batch_size
tune_batch_size()
batch_size
eval_batch_size
None
NoneTrainer
1
model.evaluate()
128
type
5条答案
按热度按时间wlsrxk511#
take
kuhbmx9i2#
self-assign
b4qexyjb3#
关于Ludwig Slack的问题:
在模型训练过程中(即作为微调的一部分),是否要最大化"forward"路径的batch_size,还是仅在predict()部分(即纯粹作为推理的一部分——“零梯度”)?如果是前者,那么这意味着我们正在处理微调的情况,那么eval_batch_size是否应该接受FineTuneTrainerConfig中的auto和None值?如果是后者,那么同样的问题也会出现在LLMTrainerConfig中(因为NoneTrainerConfig继承了LLMTrainerConfig,实际功能将进入NoneTrainer)。或者是另一个配置类?通过尝试ECD测试,test_trainer.py::test_tune_batch_size_and_lr,我假设对于LLM情况,它将是关于LLMTrainerConfig或NoneTrainerConfig;然而,初步实验表明是FineTuneTrainerConfig,因为这是解析配置的方式(即在FineTuneTrainerConfig中验证eval_batch_size)。
如果有额外的背景信息,将不胜感激。
py49o6xq4#
在模型训练过程中(即作为微调的一部分),是想最大化"forward"路径的batch_size,还是只在predict()部分(即纯粹作为推理——“零梯度”——使用,在这种情况下,我们不使用基础模型,而是将config["adapter"]["pretrained_adapter_weights"]设置为已经微调过的模型名称)?
NoneType LLM Trainer类用于零样本/少量样本推理!因此,这将是最大化
model.train()
函数调用中的batch_size,其中trainer: type
设置为None,类似于这样:在这种情况下,我们要么使用预训练/微调的基础模型,要么使用预训练的基础模型加上适配器来执行前向传播并最大化batch大小。
如果是前者,意味着我们正在处理微调的情况,那么eval_batch_size是否应该接受FineTuneTrainerConfig中的auto和None值?如果是后者,那么同样的问题也会出现在LLMTrainerConfig(因为NoneTrainerConfig扩展了LLMTrainerConfig,实际功能将进入NoneTrainer)。或者是不同的配置类?通过在ECD测试中进行实验,test_trainer.py::test_tune_batch_size_and_lr,我假设对于LLM情况,它将是关于LLMTrainerConfig或NoneTrainerConfig;然而,初始实验指向FineTuneTrainerConfig,因为这是解析配置的方式(即,在FineTuneTrainerConfig中验证eval_batch_size)。
既然是后者的情况,我们基本上可以将
batch_size: auto
作为训练器配置的一部分:这将尝试从最小可能的batch大小(1)一直到
epoch
大小的batch大小,并适应可以放入内存而不会导致CPU/GPU OOMs的最大可能的batch大小(我们在这里主要关注的是GPU OOMs)。实际代码实现将进入NoneTypeTrainer实现:https://github.com/ludwig-ai/ludwig/blob/master/ludwig/trainers/trainer_llm.py#L217。由于此函数在训练器中被调用时模型已经在内存中初始化,因此它只需要执行前向传播直到OOM。任何额外的背景都将非常有帮助。
我认为这里有两件事我们想要做:
torch.no_grad()
上下文管理器调用前向传播,这样我们就不必担心梯度的内存问题,这将有效地允许更大的batch大小。max_new_tokens
等于输出特征的max_sequence_length
个数或者指定的global_max_sequence_length
(哪个都行),然后使用每个样本包含最大可能生成的令牌的批次从1递增到epoch长度。原因是我们希望根据最坏情况下每个样本产生的所有max_new_tokens
令牌来调整batch大小。由于传统的注意力计算序列长度与所需内存呈二次关系,因此我们希望调整以获得产生最坏情况max_new_tokens的前向传播的最大batch大小。我知道这些模型是自回归的,所以我们不能保证达到这个最坏情况,但我认为实际上可以通过Generation Config参数强制实现这一点:https://github.com/ludwig-ai/ludwig/blob/master/ludwig/schema/llms/generation.py#L10 通过将min_new_tokens
设置为输出特征之一的max_sequence_length
、global_max_sequence_length
或某个回退值(如256个令牌)来实现。请告诉我是否有帮助!我很乐意回答更多的问题
t0ybt7op5#
以下是对情况的分析(由@arnavgarg1和@alexsherstinsky提出),并提出了未来工作的想法。
TL/DR
暂停对这个功能的进一步开发;需要进行更深入的产品级和设计讨论才能继续进行。
详细信息
分析
零样本/少样本推理要求在执行
model.predict()
之前必须先执行model.train()
,这是与生成元数据有关的特殊情况,只能通过执行model.train()
调用来获得。因此,我们必须“伪训练”模型以进行零样本/少样本推理。为此,我们将训练器类型配置为“none”,然后当LudwigModel.train()
执行时,将调用LudwigModel._tune_batch_size()
。执行LudwigModel._tune_batch_size()
将更新内存中的LudwigModel.config_obj.trainer.batch_size = tuned_batch_size
。在内部,它会调用训练器的tune_batch_size()
方法。对于 ECD 模型,如果batch_size
设置为“auto”或eval_batch_size
设置为“auto”/None
,那么它实际上只会做一些事情;否则,它会被跳过,因为这些批量大小是用户明确设置的。对于NoneTrainer
,我们目前只是返回1
(https://github.com/ludwig-ai/ludwig/blob/master/ludwig/trainers/trainer_llm.py#L217)。“伪训练”实际上只是在表面上为每个数据集调用model.evaluate()
,计算一组“指标”;本质上,需要调用model.train()
-- 即使没有进行训练 -- 以便能够使用预训练的 LLMs 进行model.predict()
调用(否则,Ludwig 会报错,提示模型“尚未训练”)。然而,在当前实现中,这种最优的batch_size
将无法提供给model.predict()
(因为model.predict()
以128
为默认参数接受batch_size
作为参数)。这一事实意味着当前的batch_size
优化(没有进行架构更改的情况下)仅是为了加速最终过时的model.train()
调用。此外,当训练器type
被配置为“none”并在新鲜加载的微调 LLM 上执行推理时,model.train()
调用执行速度极快(在 Ludwig 从存储中加载模型后)。下面是一个 Google Colab笔记本中的示例配置,用于说明所进行的实验: