目录

Llama3 在 torchtune 中

您将学习如何:
  • 下载 Llama3-8B 权重和分词器

  • 使用LoRA和QLoRA微调Llama3-8B

  • 评估您微调的Llama3-8B模型

  • 使用您微调后的模型生成文本

  • 量化您的模型以加速生成

先决条件

Llama3-8B

Llama3-8B 是 Meta AI 发布的新模型,其性能在 一系列不同的基准测试 中优于 Llama2 系列模型。 Llama2-7B 和 Llama3-8B 模型之间有几个主要变化:

  • Llama3-8B 使用了 分组查询注意力,而不是 Llama2-7B 中的标准多头注意力。

  • Llama3-8B 拥有更大的词表规模(128,256,而 Llama2 模型为 32,000)

  • Llama3-8B 使用了与 Llama2 模型不同的分词器(tiktoken 而不是 sentencepiece

  • Llama3-8B 在其 MLP 层中使用了比 Llama2-7B 更大的中间维度。

  • Llama3-8B 使用更高的基础值来计算其旋转位置嵌入(rotary positional embeddings)中的 theta


获取Llama3-8B的访问权限

首先,让我们从 Hugging Face 下载模型。您需要遵循 Meta 官方页面 上的说明来获取模型访问权限。 接下来,请务必从 此处 获取您的 Hugging Face 令牌。

tune download meta-llama/Meta-Llama-3-8B \
    --output-dir <checkpoint_dir> \
    --hf-token <ACCESS TOKEN>

微调Llama3-8B在torchtune

torchtune 提供了用于在一台或多台 GPU 上微调 Llama3-8B 的 LoRA、QLoRA 和全微调配方。有关 torchtune 中 LoRA 的更多信息,请参阅我们的 LoRA 教程。 有关 torchtune 中 QLoRA 的更多信息,请参阅我们的 QLoRA 教程

让我们来看看如何使用 torchtune 在单台设备上对 Llama3-8B 模型应用 LoRA 进行微调。在本示例中,为便于说明,我们将在一个常见的指令数据集(instruct dataset)上进行一个 epoch 的微调。单设备 LoRA 微调的基本命令为

tune run lora_finetune_single_device --config llama3/8B_lora_single_device

注意

要查看所有配方及其对应的配置列表,只需在命令行中运行 tune ls

我们也可以根据需要添加命令行覆盖,例如

tune run lora_finetune_single_device --config llama3/8B_lora_single_device \
    checkpointer.checkpoint_dir=<checkpoint_dir> \
    tokenizer.path=<checkpoint_dir>/tokenizer.model \
    checkpointer.output_dir=<checkpoint_dir>

这将从上方 <checkpoint_dir> 命令中使用的 tune download 加载 Llama3-8B 检查点(checkpoint)和分词器(tokenizer), 然后以原始格式将最终检查点保存到同一目录中。有关 torchtune 支持的检查点格式的更多详细信息,请参阅我们的 检查点深度解析

注意

如需查看该配置(及其他配置)支持的所有可调参数,请使用 tune cp 复制(并修改)默认配置。tune cp 也可与配方脚本配合使用,以便进行更深度的自定义修改——这些修改无法通过直接调整现有可配置参数来实现。有关 tune cp 的更多信息,请参阅修改配置一节。

训练完成后,模型检查点将被保存,并且它们的位置会被记录下来。对于LoRA微调,最终的检查点将包含合并后的权重,同时一个仅包含(小得多的)LoRA权重的副本也会被单独保存。

在我们的实验中,我们观察到峰值内存使用量为 18.5 GB。默认配置可在配备 24 GB 显存的消费级 GPU 上进行训练。

如果你有多个可用的GPU,你可以运行该配方的分布式版本。 torchtune 利用了 PyTorch Distributed 的 FSDP API 来拆分模型、优化器状态和梯度。这应该能够让你增加批量大小,从而实现更快的整体训练速度。 例如,在两个设备上:

tune run --nproc_per_node 2 lora_finetune_distributed --config llama3/8B_lora

最后,如果我们希望进一步减少内存占用,可以通过以下方式利用 torchtune 的 QLoRA 配方:

tune run lora_finetune_single_device --config llama3/8B_qlora_single_device

由于我们的默认配置启用了完整的 bfloat16 训练,因此上述所有命令都可以在至少拥有 24 GB VRAM 的设备上运行,实际上 QLoRA 配方的峰值分配内存应低于 10 GB。您还可以尝试不同的 LoRA 和 QLoRA 配置,甚至进行完整的微调。试试看!


评估使用EleutherAI的Eval Harness微调的Llama3-8B模型

现在我们已经对 Llama3-8B 进行了微调,接下来该做什么呢?让我们使用上一节中通过 LoRA 微调得到的模型,并探讨几种不同的方法,以评估其在我们所关注任务上的性能。

首先,torchtune 提供了与 EleutherAI 的评估工具包 的集成,用于在常见基准任务上对模型进行评估。

注意

请确保您已通过 pip install "lm_eval==0.4.*" 安装了评估工具包。

在本教程中,我们将使用 harness 中的 truthfulqa_mc2 任务。 该任务衡量模型在回答问题时的诚实倾向,并评估模型在“一个问题后跟一个或多个真实回答和一个或多个虚假回答”场景下的零样本准确率。首先,让我们复制配置文件,以便将 YAML 文件指向我们微调后的检查点文件。

tune cp eleuther_evaluation ./custom_eval_config.yaml

接下来,我们将 custom_eval_config.yaml 修改为包含微调后的检查点。

model:
  _component_: torchtune.models.llama3.llama3_8b

checkpointer:
  _component_: torchtune.utils.FullModelMetaCheckpointer

  # directory with the checkpoint files
  # this should match the output_dir specified during
  # fine-tuning
  checkpoint_dir: <checkpoint_dir>

  # checkpoint files for the fine-tuned model. These will be logged
  # at the end of your fine-tune
  checkpoint_files: [
    consolidated.00.pth
  ]

  output_dir: <checkpoint_dir>
  model_type: LLAMA3

# Make sure to update the tokenizer path to the right
# checkpoint directory as well
tokenizer:
  _component_: torchtune.models.llama3.llama3_tokenizer
  path: <checkpoint_dir>/tokenizer.model

最后,我们可以使用修改后的配置文件运行评估。

tune run eleuther_eval --config ./custom_eval_config.yaml

亲自试一试,看看你的模型能达到怎样的准确率!


使用我们微调的Llama3-8B模型生成文本

接下来,让我们看看另一种评估模型的方法:生成文本!torchtune 提供了一个 生成的配方

与我们所做的类似,让我们复制并修改默认生成配置。

tune cp generation ./custom_generation_config.yaml

现在我们将 custom_generation_config.yaml 修改为指向我们的检查点和分词器。

model:
  _component_: torchtune.models.llama3.llama3_8b

checkpointer:
  _component_: torchtune.utils.FullModelMetaCheckpointer

  # directory with the checkpoint files
  # this should match the output_dir specified during
  # fine-tuning
  checkpoint_dir: <checkpoint_dir>

  # checkpoint files for the fine-tuned model. These will be logged
  # at the end of your fine-tune
  checkpoint_files: [
    consolidated.00.pth
  ]

  output_dir: <checkpoint_dir>
  model_type: LLAMA3

# Make sure to update the tokenizer path to the right
# checkpoint directory as well
tokenizer:
  _component_: torchtune.models.llama3.llama3_tokenizer
  path: <checkpoint_dir>/tokenizer.model

使用我们经过 LoRA 微调的模型运行生成,可以看到以下输出:

tune run generate --config ./custom_generation_config.yaml \
prompt="Hello, my name is"

[generate.py:122] Hello, my name is Sarah and I am a busy working mum of two young children, living in the North East of England.
...
[generate.py:135] Time for inference: 10.88 sec total, 18.94 tokens/sec
[generate.py:138] Bandwidth achieved: 346.09 GB/s
[generate.py:139] Memory used: 18.31 GB

通过量化实现更快的生成

我们可以看到模型耗时不到 11 秒,每秒生成近 19 个 token。 我们可以通过量化模型来稍微加速这一过程。这里我们将使用 torchao 提供的仅权重的 4 比特量化。

如果你一路跟到了这里,那么现在你应该已经熟悉这套流程了。 接下来,我们复制量化配置,并将其指向我们微调后的模型。

tune cp quantization ./custom_quantization_config.yaml

并使用以下内容更新 custom_quantization_config.yaml

# Model arguments
model:
  _component_: torchtune.models.llama3.llama3_8b

checkpointer:
  _component_: torchtune.utils.FullModelMetaCheckpointer

  # directory with the checkpoint files
  # this should match the output_dir specified during
  # fine-tuning
  checkpoint_dir: <checkpoint_dir>

  # checkpoint files for the fine-tuned model. These will be logged
  # at the end of your fine-tune
  checkpoint_files: [
    consolidated.00.pth
  ]

  output_dir: <checkpoint_dir>
  model_type: LLAMA3

要对模型进行量化,我们现在可以运行:

tune run quantize --config ./custom_quantization_config.yaml

[quantize.py:90] Time for quantization: 2.93 sec
[quantize.py:91] Memory used: 23.13 GB
[quantize.py:104] Model checkpoint of size 4.92 GB saved to /tmp/Llama-3-8B-hf/consolidated-4w.pt

我们可以看到,该模型现在小于 5 GB,即每个 80 亿参数的平均大小略高于 4 位。

注意

与微调后的检查点不同,量化方案会输出单个检查点文件。 这是因为目前我们的量化 API 尚不支持任何跨格式的转换。 因此,您将无法在 torchtune 之外使用这些量化模型。 但您可以在 torchtune 内部的生成(generation)和评估(evaluation)方案中使用这些模型。 这些结果将有助于您确定:在您偏好的推理引擎中,应选用哪种量化方法。

让我们使用量化后的模型再次运行相同的生成过程。 首先,我们将对 custom_generation_config.yaml 再做一次修改。

checkpointer:
  # we need to use the custom TorchTune checkpointer
  # instead of the HF checkpointer for loading
  # quantized models
  _component_: torchtune.utils.FullModelTorchTuneCheckpointer

  # directory with the checkpoint files
  # this should match the output_dir specified during
  # fine-tuning
  checkpoint_dir: <checkpoint_dir>

  # checkpoint files point to the quantized model
  checkpoint_files: [
    consolidated-4w.pt,
  ]

  output_dir: <checkpoint_dir>
  model_type: LLAMA3

# we also need to update the quantizer to what was used during
# quantization
quantizer:
  _component_: torchtune.utils.quantization.Int4WeightOnlyQuantizer
  groupsize: 256

让我们重新运行生成!

tune run generate --config ./custom_generation_config.yaml \
prompt="Hello, my name is"

[generate.py:122] Hello, my name is Jake.
I am a multi-disciplined artist with a passion for creating, drawing and painting.
...
Time for inference: 1.62 sec total, 57.95 tokens/sec

通过对模型进行量化并运行 torch.compile,我们获得了超过 3 倍的速度提升!

这仅仅是使用 torchtune 和更广泛的生态系统操作 Llama3-8B 的开始。 我们期待看到您构建的成果!

文档

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

查看文档

教程

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

查看教程

资源

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

查看资源