关于配置的所有内容¶
本深入指南将引导您编写用于运行配方的配置文件。
如何编写 YAML 配置文件并使用它运行配方
如何使用
instantiate和parseAPI如何有效使用配置文件和 CLI 覆盖来运行示例
确保已 安装 torchtune
理解 配方的基本原理
参数存储在哪里?¶
您可以配置参数的两个主要入口是:configs 和CLI overrides。Configs 是 YAML 文件,它们在一个位置定义了运行配方所需的所有参数。它们是重现运行的唯一来源。Config 参数可以通过命令行使用 tune 进行快速更改和实验,而无需修改 config。
编写配置文件¶
配置文件是运行 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: Any,
**kwargs: 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,
) -> SFTDataset:
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.training.metric_logging.DiskLogger
log_dir: ${output_dir}
验证您的配置¶
我们提供了一个方便的命令行工具,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 单设备微调 配方,您可以提供覆盖选项:
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