配置全解析¶
本深入解读将指导您编写用于运行食谱的配置。
如何编写 YAML 配置并使用它运行食谱
如何使用
instantiate
和parse
API如何有效地使用配置和 CLI 覆盖来运行食谱
熟悉 torchtune 概述
确保 安装 torchtune
了解 食谱基础
参数在哪里?¶
有两个主要入口点供您配置参数:**配置**和**CLI 覆盖**。配置是 YAML 文件,它定义了在一个位置运行食谱所需的所有参数。它们是用于重现运行的单一真实来源。配置参数可以使用 tune
在命令行中进行覆盖,以便快速更改和实验,而无需修改配置。
编写配置¶
配置是 torchtune 中运行食谱的主要入口点。它们应该是 YAML 文件,它们只是列出您想要为特定运行定义的参数的值。
seed: null
shuffle: True
device: cuda
dtype: fp32
enable_fsdp: True
...
使用 instantiate
配置组件¶
许多字段需要使用关联的关键字参数指定 torchtune 对象作为参数。模型、数据集、优化器和损失函数是常见的示例。您可以使用 _component_
子字段轻松地做到这一点。在 _component_
中,您需要指定要在食谱中实例化的对象的点路径。点路径是您通常在 Python 文件中导入对象时使用的确切路径。例如,要在您的配置中使用自定义参数指定 alpaca_dataset
dataset:
_component_: torchtune.datasets.alpaca_dataset
train_on_input: False
在这里,我们将 train_on_input
的默认值从 True
更改为 False
。
在配置中指定 _component_
后,您可以像这样在食谱的设置中创建指定对象的实例
from torchtune import config
# Access the dataset field and create the object instance
dataset = config.instantiate(cfg.dataset)
这将自动使用在 dataset
下的字段中指定的任何关键字参数。
正如所写,前面的示例实际上会抛出错误。如果您查看 alpaca_dataset
的方法,您会注意到我们缺少一个必需的位置参数,即分词器。由于这也是一个可配置的 torchtune 对象,让我们通过查看 instantiate()
API 来了解如何处理这个问题。
def instantiate(
config: DictConfig,
*args: Tuple[Any, ...],
**kwargs: Dict[str, Any],
)
instantiate()
也接受位置参数和关键字参数,并在创建对象时自动使用这些参数与配置一起使用。这意味着我们不仅可以传入分词器,还可以根据需要添加配置中未指定的其他关键字参数
# Tokenizer is needed for the dataset, configure it first
tokenizer:
_component_: torchtune.models.llama2.llama2_tokenizer
path: /tmp/tokenizer.model
dataset:
_component_: torchtune.datasets.alpaca_dataset
# Note the API of the tokenizer we specified - we need to pass in a path
def llama2_tokenizer(path: str) -> Llama2Tokenizer:
# Note the API of the dataset we specified - we need to pass in a model tokenizer
# and any optional keyword arguments
def alpaca_dataset(
tokenizer: ModelTokenizer,
train_on_input: bool = True,
max_seq_len: int = 512,
) -> InstructDataset:
from torchtune import config
# Since we've already specified the path in the config, we don't need to pass
# it in
tokenizer = config.instantiate(cfg.tokenizer)
# We pass in the instantiated tokenizer as the first required argument, then
# we change an optional keyword argument
dataset = config.instantiate(
cfg.dataset,
tokenizer,
train_on_input=False,
)
请注意,其他关键字参数将覆盖配置中任何重复的键。
使用插值引用其他配置字段¶
有时,您需要对多个字段使用相同的值。您可以使用插值来引用另一个字段,而 instantiate()
将自动为您解析它。
output_dir: /tmp/alpaca-llama2-finetune
metric_logger:
_component_: torchtune.utils.metric_logging.DiskLogger
log_dir: ${output_dir}
验证您的配置¶
我们提供了一个方便的 CLI 实用程序 tune validate
,用于快速验证您的配置是否格式良好且所有组件都可以正确实例化。如果您想测试将要使用其运行实验的确切命令,也可以传入覆盖。如果任何参数格式不正确,tune validate
将列出找到错误的所有位置。
tune cp llama2/7B_lora_single_device ./my_config.yaml
tune validate ./my_config.yaml
编写配置的最佳实践¶
让我们讨论一些编写配置以充分利用它们的准则。
严密配置¶
虽然将尽可能多的内容放入配置中以便在更改实验参数时获得最大灵活性可能很诱人,但我们鼓励您仅将将在食谱中使用或实例化的字段包含在配置中。这确保了对运行食谱时使用的选项的完全清晰度,并且将使调试变得容易得多。
# dont do this
alpaca_dataset:
_component_: torchtune.datasets.alpaca_dataset
slimorca_dataset:
...
# do this
dataset:
# change this in config or override when needed
_component_: torchtune.datasets.alpaca_dataset
仅使用公共 API¶
如果您希望在配置中指定的组件位于私有文件中,请在您的配置中使用公共点路径。这些组件通常在父模块的 __init__.py
文件中公开。这样,您可以保证在配置中使用的 API 的稳定性。您的组件点路径中不应有下划线。
# don't do this
dataset:
_component_: torchtune.datasets._alpaca.alpaca_dataset
# do this
dataset:
_component_: torchtune.datasets.alpaca_dataset
命令行覆盖¶
配置是收集所有参数以运行食谱的主要位置,但有时您可能希望快速尝试不同的值,而无需更新配置本身。为了实现快速实验,您可以通过 tune
命令为配置中的参数指定覆盖值。这些应指定为键值对 k1=v1 k2=v2 ...
例如,要使用自定义模型和分词器目录运行 lora_finetune_single_device
食谱,您可以提供覆盖
tune run lora_finetune_single_device \
--config llama2/7B_lora_single_device \
checkpointer.checkpoint_dir=/home/my_model_checkpoint \
checkpointer.checkpoint_files=['file_1','file_2'] \
tokenizer.path=/home/my_tokenizer_path
覆盖组件¶
如果您想覆盖在配置中通过 _component_
字段实例化的类或函数,您可以直接将值分配给参数名称。组件中的任何嵌套字段都可以使用点符号覆盖。
dataset:
_component_: torchtune.datasets.alpaca_dataset
# Change to slimorca_dataset and set train_on_input to True
tune run lora_finetune_single_device --config my_config.yaml \
dataset=torchtune.datasets.slimorca_dataset dataset.train_on_input=True
删除配置字段¶
当通过覆盖更改组件时,您可能需要从配置中删除某些参数,这些覆盖需要不同的关键字参数。您可以使用 ~ 标志来做到这一点,并指定要删除的配置字段的点路径。例如,如果您想覆盖内置配置并使用 bitsandbytes.optim.PagedAdamW8bit
优化器,您可能需要删除诸如 foreach
之类的参数,这些参数特定于 PyTorch 优化器。请注意,此示例要求您已安装 bitsandbytes
。
# In configs/llama3/8B_full.yaml
optimizer:
_component_: torch.optim.AdamW
lr: 2e-5
foreach: False
# Change to PagedAdamW8bit and remove fused, foreach
tune run --nproc_per_node 4 full_finetune_distributed --config llama3/8B_full \
optimizer=bitsandbytes.optim.PagedAdamW8bit ~optimizer.foreach