如何使用 Kubeflow 优化 LLM 微调的超参数
本页介绍如何使用 Katib 的 Python API 在微调大型语言模型 (LLMs) 的过程中优化超参数 (HPs),以及如何进行配置。
前提条件
您需要安装以下 Katib 组件来运行本指南中的代码
注意:如果您选择定义自己的自定义目标函数并在其中优化参数,目前不支持分布式训练。在这种情况下,无需安装 Training Operator 控制平面。有关详细说明,请参阅本指南。
注意:请确保在安装 Katib 控制平面之前安装 Training Operator 控制平面。这可以确保应用正确的命名空间标签,并启用 PyTorchJob CRD 在 Katib 中使用。
加载模型和数据集
要优化预训练模型的超参数,从提供者加载模型和数据集至关重要。目前,可以通过 Kubeflow Training Operator 的 storage_initializer
API 使用外部平台,如 HuggingFace 和 S3 兼容对象存储(例如 Amazon S3)来完成此操作。
HuggingFace 集成
HuggingFace 提供者支持无缝集成模型和数据集,用于训练和评估。您可以使用以下代码导入 Hugging Face 所需的组件
from kubeflow.storage_initializer.hugging_face import (
HuggingFaceModelParams,
HuggingFaceDatasetParams,
HuggingFaceTrainerParams,
)
HuggingFaceModelParams
描述
HuggingFaceModelParams
dataclass 包含用于初始化 Hugging Face 模型的配置参数,并带有验证检查。
属性 | 类型 | 描述 |
---|---|---|
model_uri | str | Hugging Face 模型的 URI 或路径(不能为空)。 |
transformer_type | TRANSFORMER_TYPES | 指定用于各种 NLP/ML 任务的模型类型。 |
access_token | Optional[str] (默认值:None ) | 用于访问 Hugging Face 上私有模型的 token。 |
num_labels | Optional[int] (默认值:None ) | 输出标签的数量(用于分类任务)。 |
支持的 Transformer 类型 (TRANSFORMER_TYPES
)
模型类型 | 任务 |
---|---|
AutoModelForSequenceClassification | 文本分类 |
AutoModelForTokenClassification | 命名实体识别 |
AutoModelForQuestionAnswering | 问答 |
AutoModelForCausalLM | 文本生成(因果) |
AutoModelForMaskedLM | 掩码语言模型 |
AutoModelForImageClassification | 图像分类 |
使用示例
from transformers import AutoModelForSequenceClassification
from kubeflow.storage_initializer.hugging_face import HuggingFaceModelParams
params = HuggingFaceModelParams(
model_uri="bert-base-uncased",
transformer_type=AutoModelForSequenceClassification,
access_token="huggingface_access_token",
num_labels=2 # For binary classification
)
HuggingFaceDatasetParams
描述
HuggingFaceDatasetParams
类包含用于从 Hugging Face 加载数据集的配置参数,并带有验证检查。
属性 | 类型 | 描述 |
---|---|---|
repo_id | str | Hugging Face 上数据集仓库的标识符(不能为空)。 |
access_token | Optional[str] (默认值:None ) | 用于访问 Hugging Face 上私有数据集的 token。 |
split | Optional[str] (默认值:None ) | 要加载的数据集分割(例如,"train" ,"test" )。 |
使用示例
from kubeflow.storage_initializer.hugging_face import HuggingFaceDatasetParams
dataset_params = HuggingFaceDatasetParams(
repo_id="imdb", # Public dataset repository ID on Hugging Face
split="train", # Dataset split to load
access_token=None # Not needed for public datasets
)
HuggingFaceTrainerParams
描述
HuggingFaceTrainerParams
类用于在 Hugging Face 框架中定义训练过程的参数。它包含训练参数和 LoRA 配置,以优化模型训练。
参数 | 类型 | 描述 |
---|---|---|
training_parameters | transformers.TrainingArguments | 包含学习率、轮次、批大小等训练参数。 |
lora_config | LoraConfig | LoRA 配置,用于减少模型中可训练参数的数量。 |
用于定义超参数搜索空间的 Katib Search API
Katib Search API 允许用户在模型调优期间定义超参数的搜索空间。此 API 支持连续、离散和分类参数采样,从而实现灵活高效的超参数优化。
以下是定义超参数搜索空间的可用方法
函数 | 描述 | 参数类型 | 参数 |
---|---|---|---|
double() | 在指定范围内采样连续浮点值。 | double | min (float, 必需), max (float, 必需), step (float, 可选) |
int() | 在指定范围内采样整数值。 | int | min (int, 必需), max (int, 必需), step (int, 可选) |
categorical() | 从预定义类别列表中采样一个值。 | categorical | list (List, 必需) |
使用示例
这是一个如何使用 HuggingFaceTrainerParams
类定义训练和 LoRA 参数的示例。
import kubeflow.katib as katib
from kubeflow.storage_initializer.hugging_face import HuggingFaceTrainerParams
from transformers import TrainingArguments
from peft import LoraConfig
# Set up training and LoRA configuration
trainer_params = HuggingFaceTrainerParams(
training_parameters=TrainingArguments(
output_dir="results",
# Using katib search api to define a search space for the parameter
learning_rate=katib.search.double(min=1e-05, max=5e-05),
num_train_epochs=3,
per_device_train_batch_size=8,
),
lora_config=LoraConfig(
r=katib.search.int(min=8, max=32),
lora_alpha=16,
lora_dropout=0.1,
bias="none",
),
)
S3 兼容对象存储集成
除了 Hugging Face,您还可以与 S3 兼容的对象存储平台集成来加载数据集。要使用 S3,请使用 S3DatasetParams
类定义数据集参数。
from kubeflow.storage_initializer.s3 import S3DatasetParams
S3DatasetParams
描述
S3DatasetParams
类用于从 S3 兼容对象存储中加载数据集。参数定义如下
参数 | 类型 | 描述 |
---|---|---|
endpoint_url | str | S3 兼容存储服务的 URL。 |
bucket_name | str | 包含数据集的 S3 存储桶名称。 |
file_key | str | 存储桶中数据集文件的 Key(路径)。 |
region_name | str , 可选 | S3 存储桶的 AWS 区域(可选)。 |
access_key | str , 可选 | 用于 S3 身份验证的访问密钥(可选)。 |
secret_key | str , 可选 | 用于 S3 身份验证的密钥(可选)。 |
使用示例
from kubeflow.storage_initializer.s3 import S3DatasetParams
s3_params = S3DatasetParams(
endpoint_url="https://s3.amazonaws.com",
bucket_name="my-dataset-bucket",
file_key="datasets/train.csv",
region_name="us-west-2",
access_key="YOUR_ACCESS_KEY",
secret_key="YOUR_SECRET_KEY"
)
优化大型语言模型的超参数
在优化 GPT、BERT 或类似基于 Transformer 的大型语言模型 (LLMs) 的超参数时,优化各种超参数以提高模型性能至关重要。本小节涵盖了通过 tune
函数调优 LLMs 所使用的关键参数,特别是使用 Katib 等工具在 Kubernetes 环境中进行自动化超参数优化。
LLM 超参数调优的关键参数
参数 | 描述 | 必需参数 |
---|---|---|
name | 实验名称。 | 必需参数 |
model_provider_parameters | 模型提供者的参数,例如模型类型和配置。 | 可选参数 |
dataset_provider_parameters | 数据集提供者的参数,例如数据集配置。 | 可选参数 |
trainer_parameters | Trainer 的配置,包括模型训练的超参数。 | 可选参数 |
storage_config | 存储配置,如 PVC 大小和存储类。 | 可选参数 |
objective | 用于训练和优化的目标函数。 | 可选参数 |
base_image | 执行目标函数的镜像。 | 可选参数 |
parameters | 用于调优实验的超参数。 | 可选参数 |
namespace | 实验的 Kubernetes 命名空间。 | 可选参数 |
env_per_trial | 每个试验的环境变量。 | 可选参数 |
algorithm_name | 用于超参数搜索的算法。 | 可选参数 |
algorithm_settings | 搜索算法的设置。 | 可选参数 |
objective_metric_name | 用于优化的目标指标名称。 | 可选参数 |
additional_metric_names | 从目标函数收集的其他指标列表。 | 可选参数 |
objective_type | 目标指标的优化类型(最小化或最大化)。 | 可选参数 |
objective_goal | 目标成功的阈值。 | 可选参数 |
max_trial_count | 要运行的最大试验次数。 | 可选参数 |
parallel_trial_count | 并行运行的试验次数。 | 可选参数 |
max_failed_trial_count | 允许的最大失败试验次数。 | 可选参数 |
resources_per_trial | 每个试验的资源需求,包括 CPU、内存和 GPU。 | 可选参数 |
retain_trials | 是否保留已完成试验的资源。 | 可选参数 |
packages_to_install | 要安装的其他 Python 包列表。 | 可选参数 |
pip_index_url | 安装 Python 包的 PyPI URL。 | 可选参数 |
metrics_collector_config | 指标收集器的配置。 | 可选参数 |
LLMs 支持的目标指标
目前,对于大型语言模型 (LLM) 超参数优化,仅支持将train_loss
作为目标指标。这是因为train_loss
是 Hugging Face 中trainer.train()
函数产生的默认指标,我们的 trainer 使用了它。我们计划在未来的更新中扩展对其他指标的支持。配置
resources_per_trial
从外部平台导入模型和数据集时,需要使用TrainerResources
对象定义resources_per_trial
。将num_workers
设置为大于 1 的值可以通过 PyTorchJob 启用分布式训练。要禁用分布式训练,只需设置num_workers=1
。配置示例
import kubeflow.katib as katib resources_per_trial=katib.TrainerResources( num_workers=1, num_procs_per_worker=1, resources_per_worker={"gpu": 0, "cpu": 1, "memory": "10G",}, )
定义自定义目标函数
除了使用model_provider_parameters
、dataset_provider_parameters
和trainer_parameters
从外部平台导入模型和数据集外,用户还可以灵活地定义自定义目标函数,以及用于超参数优化的自定义镜像和参数。有关详细说明,请参阅本指南。
示例:在 IMDB 数据集上优化 Llama-3.2 进行二元分类的超参数
此代码提供了一个超参数优化 Llama-3.2 模型 在 IMDB 电影评论数据集上执行二元分类任务的示例。Llama-3.2 模型使用 LoRA(低秩 адаптация)进行微调,以减少可训练参数的数量。此示例中使用的数据集包含来自 IMDB 数据集的 1000 条电影评论,训练过程通过 Katib 优化以找到最佳超参数。
Katib 配置
下表概述了用于超参数优化过程的 Katib 配置
参数 | 描述 |
---|---|
exp_name | 实验名称 (llama )。 |
model_provider_parameters | Hugging Face 模型 (Llama-3.2) 的参数。 |
dataset_provider_parameters | IMDB 数据集 (1000 条电影评论) 的参数。 |
trainer_parameters | Hugging Face trainer 的参数,包括 LoRA 设置。 |
objective_metric_name | 要最小化的目标指标,在本例中为 "train_loss" 。 |
objective_type | 优化类型:训练损失的 "minimize" 。 |
algorithm_name | 使用的优化算法,设置为 "random" 用于随机搜索。 |
max_trial_count | 要运行的最大试验次数,设置为 10 。 |
parallel_trial_count | 并行运行的试验次数,设置为 2 。 |
resources_per_trial | 分配给每个试验的资源:2 个 GPU,4 个 CPU,10GB 内存。 |
代码示例
import kubeflow.katib as katib
from kubeflow.katib import KatibClient
from transformers import AutoModelForSequenceClassification, TrainingArguments
from peft import LoraConfig
from kubeflow.storage_initializer.hugging_face import (
HuggingFaceModelParams,
HuggingFaceDatasetParams,
HuggingFaceTrainerParams,
)
hf_model = HuggingFaceModelParams(
model_uri = "hf://meta-llama/Llama-3.2-1B",
transformer_type = AutoModelForSequenceClassification,
)
# Train the model on 1000 movie reviews from imdb
# https://hugging-face.cn/datasets/stanfordnlp/imdb
hf_dataset = HuggingFaceDatasetParams(
repo_id = "imdb",
split = "train[:1000]",
)
hf_tuning_parameters = HuggingFaceTrainerParams(
training_parameters = TrainingArguments(
output_dir = "results",
save_strategy = "no",
learning_rate = katib.search.double(min=1e-05, max=5e-05),
num_train_epochs=3,
),
# Set LoRA config to reduce number of trainable model parameters.
lora_config = LoraConfig(
r = katib.search.int(min=8, max=32),
lora_alpha = 8,
lora_dropout = 0.1,
bias = "none",
),
)
cl = KatibClient(namespace="kubeflow")
# Optimizing Hyperparameters for Binary Classification
exp_name = "llama"
cl.tune(
name = exp_name,
model_provider_parameters = hf_model,
dataset_provider_parameters = hf_dataset,
trainer_parameters = hf_tuning_parameters,
objective_metric_name = "train_loss",
objective_type = "minimize",
algorithm_name = "random",
max_trial_count = 10,
parallel_trial_count = 2,
resources_per_trial={
"gpu": "2",
"cpu": "4",
"memory": "10G",
},
)
cl.wait_for_experiment_condition(name=exp_name)
# Get the best hyperparameters.
print(cl.get_optimal_hyperparameters(exp_name))