TRL 文档

训练自定义

Hugging Face's logo
加入 Hugging Face 社区

并获得增强型文档体验

开始使用

训练自定义

TRL 的设计考虑了模块化,以便用户能够有效地根据自己的需求自定义训练循环。下面是一些关于如何应用和测试不同技术的示例。

在多个 GPU/节点上训练

TRL 中的训练器使用 🤗 Accelerate 来启用跨多个 GPU 或节点的分布式训练。为此,首先通过运行以下命令创建一个 🤗 Accelerate 配置文件:

accelerate config

并根据您的多 GPU/多节点设置回答问题。然后,您可以通过运行以下命令启动分布式训练:

accelerate launch your_script.py

我们还在 示例文件夹 中提供了可用作模板的配置文件。要使用这些模板,只需在启动作业时传递配置文件的路径,例如:

accelerate launch --config_file=examples/accelerate_configs/multi_gpu.yaml --num_processes {NUM_GPUS} path_to_script.py --all_arguments_of_the_script

有关更多详细信息,请参阅 示例页面

使用 DeepSpeed 进行分布式训练

TRL 中的所有训练器都可以与 DeepSpeed ZeRO-{1,2,3} 一起在多个 GPU 上运行,以有效地对优化器状态、梯度和模型权重进行分片。为此,请运行以下命令:

accelerate launch --config_file=examples/accelerate_configs/deepspeed_zero{1,2,3}.yaml --num_processes {NUM_GPUS} path_to_your_script.py --all_arguments_of_the_script

请注意,对于 ZeRO-3,需要进行少量调整才能通过 zero3_init_context_manager() 上下文管理器在正确的设备上初始化您的奖励模型。特别是,这需要避免 DeepSpeed 在固定数量的训练步骤后挂起。以下是来自 sentiment_tuning 示例中涉及的内容片段

ds_plugin = ppo_trainer.accelerator.state.deepspeed_plugin
if ds_plugin is not None and ds_plugin.is_zero3_init_enabled():
    with ds_plugin.zero3_init_context_manager(enable=False):
        sentiment_pipe = pipeline("sentiment-analysis", model="lvwerra/distilbert-imdb", device=device)
else:
    sentiment_pipe = pipeline("sentiment-analysis", model="lvwerra/distilbert-imdb", device=device)

有关 DeepSpeed 插件的更多信息,请参阅 🤗 Accelerate 文档

使用不同的优化器

默认情况下,PPOTrainer 创建一个 torch.optim.Adam 优化器。您可以创建一个不同的优化器并将其传递给 PPOTrainer

import torch
from transformers import GPT2Tokenizer
from trl import PPOTrainer, PPOConfig, AutoModelForCausalLMWithValueHead

# 1. load a pretrained model
model = AutoModelForCausalLMWithValueHead.from_pretrained('gpt2')
ref_model = AutoModelForCausalLMWithValueHead.from_pretrained('gpt2')
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')

# 2. define config
ppo_config = {'batch_size': 1, 'learning_rate':1e-5}
config = PPOConfig(**ppo_config)


# 2. Create optimizer
optimizer = torch.optim.SGD(model.parameters(), lr=config.learning_rate)


# 3. initialize trainer
ppo_trainer = PPOTrainer(config, model, ref_model, tokenizer, optimizer=optimizer)

为了进行内存高效的微调,您还可以从 bitsandbytes 传递 Adam8bit 优化器。

import torch
import bitsandbytes as bnb

from transformers import GPT2Tokenizer
from trl import PPOTrainer, PPOConfig, AutoModelForCausalLMWithValueHead

# 1. load a pretrained model
model = AutoModelForCausalLMWithValueHead.from_pretrained('gpt2')
ref_model = AutoModelForCausalLMWithValueHead.from_pretrained('gpt2')
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')

# 2. define config
ppo_config = {'batch_size': 1, 'learning_rate':1e-5}
config = PPOConfig(**ppo_config)


# 2. Create optimizer
optimizer = bnb.optim.Adam8bit(model.parameters(), lr=config.learning_rate)

# 3. initialize trainer
ppo_trainer = PPOTrainer(config, model, ref_model, tokenizer, optimizer=optimizer)

使用LION优化器

您也可以使用来自 Google 的新的 LION 优化器,首先获取优化器定义的源代码 此处,并将其复制以便您可以导入优化器。请确保在初始化优化器时仅考虑可训练参数,以实现更内存高效的训练。

optimizer = Lion(filter(lambda p: p.requires_grad, self.model.parameters()), lr=self.config.learning_rate)

...
ppo_trainer = PPOTrainer(config, model, ref_model, tokenizer, optimizer=optimizer)

我们建议您使用您将用于 Adam 的学习率除以 3,如 此处 所述。我们观察到使用此优化器时与经典 Adam 相比有所改进(请参阅 此处 的完整日志)。

添加学习率调度器

您还可以通过添加学习率调度器来调整您的训练!

import torch
from transformers import GPT2Tokenizer
from trl import PPOTrainer, PPOConfig, AutoModelForCausalLMWithValueHead

# 1. load a pretrained model
model = AutoModelForCausalLMWithValueHead.from_pretrained('gpt2')
ref_model = AutoModelForCausalLMWithValueHead.from_pretrained('gpt2')
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')

# 2. define config
ppo_config = {'batch_size': 1, 'learning_rate':1e-5}
config = PPOConfig(**ppo_config)


# 2. Create optimizer
optimizer = torch.optim.SGD(model.parameters(), lr=config.learning_rate)
lr_scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.9)

# 3. initialize trainer
ppo_trainer = PPOTrainer(config, model, ref_model, tokenizer, optimizer=optimizer, lr_scheduler=lr_scheduler)

通过共享层进行内存高效的微调

您可以用于更内存高效微调的另一个工具是在参考模型和您想要训练的模型之间共享层。

import torch
from transformers import AutoTokenizer
from trl import PPOTrainer, PPOConfig, AutoModelForCausalLMWithValueHead, create_reference_model

# 1. load a pretrained model
model = AutoModelForCausalLMWithValueHead.from_pretrained('bigscience/bloom-560m')
ref_model = create_reference_model(model, num_shared_layers=6)
tokenizer = AutoTokenizer.from_pretrained('bigscience/bloom-560m')

# 2. initialize trainer
ppo_config = {'batch_size': 1}
config = PPOConfig(**ppo_config)
ppo_trainer = PPOTrainer(config, model, ref_model, tokenizer)

传递 8 位参考模型

由于 trl 在使用 from_pretrainedtransformers 加载模型时支持所有关键字参数,因此您还可以利用 transformers 中的 load_in_8bit 来进行更内存高效的微调。

在此处阅读有关 transformers 中 8 位模型加载的更多信息 此处

# 0. imports
# pip install bitsandbytes
import torch
from transformers import AutoTokenizer
from trl import PPOTrainer, PPOConfig, AutoModelForCausalLMWithValueHead

# 1. load a pretrained model
model = AutoModelForCausalLMWithValueHead.from_pretrained('bigscience/bloom-560m')
ref_model = AutoModelForCausalLMWithValueHead.from_pretrained('bigscience/bloom-560m', device_map="auto", load_in_8bit=True)
tokenizer = AutoTokenizer.from_pretrained('bigscience/bloom-560m')

# 2. initialize trainer
ppo_config = {'batch_size': 1}
config = PPOConfig(**ppo_config)
ppo_trainer = PPOTrainer(config, model, ref_model, tokenizer)

使用CUDA缓存优化器

在训练大型模型时,您应该更好地处理CUDA缓存,方法是迭代地清除它。为此,只需将 optimize_cuda_cache=True 传递给 PPOConfig

config = PPOConfig(..., optimize_cuda_cache=True)

使用分数缩放/标准化/裁剪

大型语言模型中 RLHF 的秘密第一部分:PPO 所述,我们支持分数(又名奖励)缩放/标准化/裁剪,以通过 PPOConfig 提高训练稳定性。

from trl import PPOConfig

ppo_config = {
    use_score_scaling=True,
    use_score_norm=True,
    score_clip=0.5,
}
config = PPOConfig(**ppo_config)

要运行 ppo.py,您可以使用以下命令

python examples/scripts/ppo.py --log_with wandb --use_score_scaling --use_score_norm --score_clip 0.5
< > GitHub上的更新