目录

什么是示例?

本篇深入探讨将引导您完成 torchtune 中训练配方的设计。

本次深入探讨将涵盖什么
  • 什么是配方?

  • 构成配方的核心成分是什么?

  • 我应该如何构建新配方?

配方是 torchtune 用户的主要入口点。这些可以考虑 作为用于训练和选择性评估 LLM 的“目标”端到端管道。 每个 recipe 都实现了一种训练方法(例如:完全微调),其中包含一组有意义的 特征(例如:FSDP + 激活检查点 + 梯度累积 + 混合精度 training)应用于给定的模型系列(例如:Llama2)。

随着模型训练变得越来越复杂,预测新模型变得越来越困难 架构和训练方法,同时还要考虑每一个可能的权衡 (例如:内存与模型质量)。我们认为 a) 用户最适合进行权衡 特定于他们的使用案例,以及 b) 没有放之四海而皆准的解决方案。因此,示例 旨在易于理解、扩展和调试,而不是通用的入口点 所有可能的设置。

根据您的用例和专业水平,您通常会发现自己需要修改 现有配方(例如:添加新功能)或编写新配方。torchtune 制作编写配方 通过提供经过充分测试的模块化组件/构建块和通用实用程序,轻松实现 (例如:WandB Logging and Checkpointing)。


配方设计

torchtune 中的 recipes 设计为:

  • 很简单。完全使用 native-PyTorch 编写。

  • 正确。每个组件的数值奇偶校验以及与 参考实现和基准测试。

  • 易于理解。每个配方都提供了一组有限的有意义的功能,而不是 每个可能的功能都隐藏在 100 多个标志后面。代码重复比不必要的代码更可取 抽象。

  • 易于扩展。不依赖于训练框架,也无需实现继承。用户 不需要遍历层层叠叠的抽象来弄清楚如何扩展核心 功能性。

  • 可供一系列用户访问。用户可以决定他们希望如何与 torchtune 配方交互:
    • 通过修改现有配置来开始训练模型

    • 修改自定义案例的现有配方

    • 直接使用可用的构建块编写全新的配方/训练范例

每个配方由三个部分组成:

  • 可配置的参数,通过 yaml 配置和命令行覆盖指定

  • Recipe Script,将所有内容放在一起的入口点,包括解析和验证 configs、设置环境以及正确使用 recipe 类

  • Recipe Class,训练所需的核心逻辑,通过一组 API 暴露给用户

在以下部分中,我们将仔细研究这些组件中的每一个。 有关完整的工作示例,请参阅 torchtune 中的完整微调配方和相关的配置


哪些示例不是什么?

  • Monolithic 运动鞋。配方是一个单一的 trainer,旨在支持每个 可能的功能。

  • 广义入口点。配方并不意味着支持所有可能的模型 架构或微调方法。

  • 外部框架的包装器。配方并不意味着要成为包装器 外部框架。这些是使用 torchtune 构建块完全用 native-PyTorch 编写的。 依赖项主要以附加实用程序或与 周边生态系统(例如:EleutherAI 的评估工具)。


配方脚本

这是每个配方的主要入口点,并为用户提供了对如何 设置配方、如何训练模型以及如何使用后续检查点。 这包括:

  • 环境设置

  • 解析和验证配置

  • 训练模型

  • 使用多个配方类设置多阶段训练(例如:蒸馏)

脚本通常应按以下顺序构建操作:

  • 初始化 recipe 类,该类反过来初始化 recipe 状态

  • Load and Validate 检查点以在恢复训练时更新配方状态

  • 初始化配方组件(model、tokenizer、optimizer、loss 和 dataloader) 从检查点(如果适用)

  • 训练模型

  • 训练完成后清理配方状态

示例脚本如下所示:

# Initialize the process group
init_process_group(backend="gloo" if cfg.device == "cpu" else "nccl")

# Setup the recipe and train the model
recipe = FullFinetuneRecipeDistributed(cfg=cfg)
recipe.setup(cfg=cfg)
recipe.train()
recipe.cleanup()

# Other stuff to do after training is complete
...

Recipe 类

recipe 类承载了用于训练模型的核心逻辑。每个类都实现了一个相关的 接口并公开一组 API。为了进行微调,此类的结构如下:

初始化配方状态,包括 seed、device、dtype、度量记录器、相关标志等:

def __init__(...):

    self._device = utils.get_device(device=params.device)
    self._dtype = training.get_dtype(dtype=params.dtype, device=self._device)
    ...

加载检查点,从检查点更新配方状态,初始化组件并从检查点加载状态字典

def setup(self, cfg: DictConfig):

    ckpt_dict = self.load_checkpoint(cfg.checkpointer)

    # Setup the model, including FSDP wrapping, setting up activation checkpointing and
    # loading the state dict
    self._model = self._setup_model(...)
    self._tokenizer = self._setup_tokenizer(...)

    # Setup Optimizer, including transforming for FSDP when resuming training
    self._optimizer = self._setup_optimizer(...)
    self._loss_fn = self._setup_loss(...)
    self._sampler, self._dataloader = self._setup_data(...)

在所有 epoch 中向前和向后运行,并在每个 epoch 结束时保存 checkpoint

def train(...):

    self._optimizer.zero_grad()
    for curr_epoch in range(self.epochs_run, self.total_epochs):

        for idx, batch in enumerate(self._dataloader):
            ...

            with self._autocast:
                logits = self._model(...)
                ...
                loss = self._loss_fn(logits, labels)

            if self.global_step % self._log_every_n_steps == 0:
                self._metric_logger.log_dict(...)

            loss.backward()
            self._optimizer.step()
            self._optimizer.zero_grad()

            # Update the number of steps when the weights are updated
            self.global_step += 1

        self.save_checkpoint(epoch=curr_epoch)

清理配方状态

def cleanup(...)

    self.metric_loggers.close()
    ...

使用配置运行 Recipes

要使用一组用户定义的参数运行配方,您需要编写一个配置文件。 你可以在我们的 config deep-dive 中了解有关配置的所有信息。

使用 Config 和 CLI 解析parse

我们提供了一个方便的装饰器,它将 使用 Tune with Config 从命令行启用运行的配方 和 CLI 覆盖解析。

@config.parse
def recipe_main(cfg: DictConfig) -> None:
    recipe = FullFinetuneRecipe(cfg=cfg)
    recipe.setup(cfg=cfg)
    recipe.train()
    recipe.cleanup()

运行配方

您应该能够通过提供自定义的直接路径来运行配方 配方和自定义配置,使用带有任何 CLI 覆盖的 tune 命令:

tune run <path/to/recipe> --config <path/to/config> k1=v1 k2=v2 ...

文档

访问 PyTorch 的全面开发人员文档

查看文档

教程

获取面向初学者和高级开发人员的深入教程

查看教程

资源

查找开发资源并解答您的问题

查看资源