快捷方式

导出 LLM

无需手动编写代码调用 torch.export()、ExecuTorch 的各种降低 (lowering) API,甚至无需与 TorchAO quantize_ API 交互进行量化,我们提供了一开箱即用的体验,可以高效地将一系列支持的模型导出到 ExecuTorch。

先决条件

LLM 导出功能需要 pytorch_tokenizers 包。如果您遇到 ModuleNotFoundError: No module named 'pytorch_tokenizers' 错误,请从 ExecutorTorch 源代码安装它。

pip install -e ./extension/llm/tokenizers/

支持的模型

截至本篇文档,支持的 LLM 列表包括以下模型:

  • Llama 2/3/3.1/3.2

  • Qwen 2.5/3

  • Phi 3.5/4-mini

  • SmolLM2

支持的 LLM 的最新列表可以在代码 此处 找到。

export_llm API

export_llm 是 ExecuTorch 用于 LLM 的高级导出 API。在本教程中,我们将重点使用此 API 导出 Llama 3.2 1B。 export_llm 的参数可以通过 CLI 参数或 YAML 配置文件指定,其字段在 LlmConfig 中定义。要调用 export_llm

python -m executorch.examples.extension.llm.export.export_llm
  --config <path-to-config-yaml>
  +base.<additional-CLI-overrides>

基本导出

要执行 Llama3.2 的基本导出,我们首先需要下载检查点文件(consolidated.00.pth)和参数文件(params.json)。您可以在 Llama 网站Hugging Face 上找到它们。

然后,我们将 model_classcheckpoint(检查点文件路径)和 params(参数文件路径)指定为参数。此外,稍后当我们使用运行器 API 运行导出的 .pte 文件时,运行器需要了解此模型的 bos 和 eos id,以便知道何时终止。这些可以通过 .pte 中的 bos 和 eos 获取方法来暴露,我们可以通过在 metadata 参数中指定 bos 和 eos id 来添加它们。这些 token 的值通常可以在 HuggingFace 上找到的模型的 tokenizer_config.json 中找到。

# path/to/config.yaml
base:
  model_class: llama3_2
  checkpoint: path/to/consolidated.00.pth
  params: path/to/params.json
  metadata: '{"get_bos_id":128000, "get_eos_ids":[128009, 128001]}'

# export_llm
python -m extension.llm.export.export_llm \
  --config path/to/config.yaml

我们只需要为 Llama 模型系列手动指定检查点路径,因为它是我们最优化的模型,并且我们有更高级的优化,例如 SpinQuant,这些优化需要自定义检查点。

对于其他支持的 LLM,检查点将自动从 HuggingFace 下载,并且参数文件可以在 executorch/examples/models 下的相应目录中找到,例如 executorch/examples/models/qwen3/config/0_6b_config.json

导出设置

ExportConfig 包含导出 .pte 的设置,例如 max_seq_length(提示的最大长度)和 max_context_length(模型的内存/缓存的最大长度)。

添加优化

export_llm 在导出前、导出过程中以及降低过程中对模型进行各种优化。量化和委托给加速器后端是主要的优化,将在接下来的两个部分中介绍。所有其他优化都可以在 ModelConfig 中找到。我们将继续添加一些优化。

# path/to/config.yaml
base:
  model_class: llama3_2
  checkpoint: path/to/consolidated.00.pth
  params: path/to/params.json
  metadata: '{"get_bos_id":128000, "get_eos_ids":[128009, 128001]}'
model:
  use_kv_cache: True
  use_sdpa_with_kv_cache: True

# export_llm
python -m extension.llm.export.export_llm \
  --config path/to/config.yaml

use_kv_cacheuse_sdpa_with_kv_cache 推荐用于导出任何 LLM,而其他选项则视情况而定。例如:

  • use_shared_embedding 可用于具有绑定输入/输出嵌入层的模型,前提是您使用 TorchAO 低精度操作进行量化(quantization.qmode: torchao:8da(\d+)wquantization.qmode: torchao:fpa(\d+)w),更多信息请参见 此处

  • use_attention_sink 用于通过在达到最大上下文长度时从 KV 缓存的开头移除内容来扩展生成。

  • quantize_kv_cache 以 int8 量化 KV 缓存。

  • local_global_attention 实现 Local-Global Attention,使特定的注意力层使用更小的局部滑动窗口 KV 缓存。

量化

量化选项由 QuantizationConfig 定义。ExecuTorch 通过两种方式进行量化:

  1. TorchAO quantize_ API

  2. pt2e 量化

TorchAO (XNNPACK)

TorchAO 在源代码级别进行量化,将 Linear 模块替换为 QuantizedLinear 模块。**要在 XNNPACK 后端上进行量化,请遵循此量化路径。** 量化模式定义在 此处

常用的有:

  • 8da4w:表示 int8 动态激活 + int4 权重量化。

  • int8:int8 仅权重量化。

组大小通过以下方式指定:

  • group_size:8、32、64 等。

对于 Arm CPU,还有 低精度内核,用于 int8 动态激活 + int[1-8] 权重量化。请注意,这不应与 XNNPACK 一起使用,并且根据我们的实验,对于等效的 8da4w,性能有时可能更好。要使用它们,请将 qmode 指定为以下任一项:

  • torchao:8da(\d+)w:int8 动态激活 + int[1-8] 权重,例如 torchao:8da5w

  • torchao:fpa(\d+)w:仅 int[1-8] 权重,例如 torchao:fpa4w

要量化嵌入层,请指定 embedding_quantize: <bitwidth>,<groupsize>(这里的 bitwidth 必须是 2、4 或 8),或者对于低精度内核,请使用 embedding_quantize: torchao:<bitwidth>,<groupsize>bitwidth 可以是 1-8)。

# path/to/config.yaml
base:
  model_class: llama3_2
  checkpoint: path/to/consolidated.00.pth
  params: path/to/params.json
  metadata: '{"get_bos_id":128000, "get_eos_ids":[128009, 128001]}'
model:
  use_kv_cache: True
  use_sdpa_withp_kv_cache: True
quantization:
  embedding_quantize: 4,32
  qmode: 8da4w

# export_llm
python -m extension.llm.export.export_llm \
  --config path/to/config.yaml

pt2e (QNN, CoreML, 和 Vulkan)

pt2e 在导出后的图级别进行量化,替换节点并注入量化/反量化节点。**要在非 CPU 后端(QNN、CoreML、Vulkan)上进行量化,请遵循此量化路径。** 有关 pt2e 的更多信息,请阅读 此处,以及 ExecuTorch 如何使用 pt2e 的信息 此处

CoreML 和 Vulkan 对 export_llm 的支持目前仍处于实验阶段且有限。有关 QNN 导出的更多信息,请阅读 在 Android (Qualcomm) 上运行

后端支持

后端选项由 BackendConfig 定义。每个后端都有自己的后端配置选项。以下是一个将 LLM 降低到 XNNPACK 以实现 CPU 加速的示例:

# path/to/config.yaml
base:
  model_class: llama3_2
  checkpoint: path/to/consolidated.00.pth
  params: path/to/params.json
  metadata: '{"get_bos_id":128000, "get_eos_ids":[128009, 128001]}'
model:
  use_kv_cache: True
  use_sdpa_withp_kv_cache: True
quantization:
  embedding_quantize: 4,32
  qmode: 8da4w
backend:
  xnnpack:
    enabled: True
    extended_ops: True  # Expand the selection of ops delegated to XNNPACK.

# export_llm
python -m extension.llm.export.export_llm \
  --config path/to/config.yaml

性能分析和调试

要查看哪些算子被委托给后端,哪些没有,请指定 verbose: True

# path/to/config.yaml
...
debug:
  verbose: True
...

# export_llm
python -m extension.llm.export.export_llm \
  --config path/to/config.yaml

在日志中,将有一个表格列出图中所有算子,以及哪些被委托,哪些未被委托。

这是一个例子:

点击查看委托详情

总委托子图数:368
委托节点数:2588
非委托节点数:2513

op_type

# in_delegated_graphs

# in_non_delegated_graphs

0

_assert_scalar

0

167

1

_local_scalar_dense

0

123

2

add

0

31

3

aten__to_copy_default

0

44

4

aten_add_tensor

418

44

5

aten_alias_copy_default

0

52

15

aten_linear_default

183

0

18

aten_mul_tensor

445

0

20

aten_pow_tensor_scalar

157

0

22

aten_rsqrt_default

157

0

27

aten_view_copy_default

0

126

31

getitem

366

628

41

torchao_quantize_affine_default

183

0

42

Total

2588

2513


为了进行进一步的性能分析,您可以选择使用 ExecuTorch 开发者工具 来执行诸如将单个算子性能追溯到源代码、查看内存规划以及调试中间激活等操作。要生成 ETRecord 以将 .pte 程序链接回源代码,您可以使用:

# path/to/config.yaml
...
debug:
  generate_etrecord: True
...

# export_llm
python -m extension.llm.export.export_llm \
  --config path/to/config.yaml

其他调试和性能分析选项可以在 DebugConfig 中找到。

一些示例选项:

  • profile_memory:用于生成 chrome trace 格式的激活内存配置文件。它允许您可视化模型不同中间张量在模型执行过程中的生命周期、它们的生命周期如何重叠、这些张量来自哪里以及它们如何影响模型的内存占用。有关内存配置文件的更多详细信息,请单击 此处

  • profile_path:用于生成 export_llm 各组件的时间配置文件。这些组件包括 torch.export、量化、to_edge、通过 to_backend API 的委托等。此选项会生成一个 .html 文件,以火焰图/冰柱图格式提供时间配置文件。这有助于了解 export_llm 的哪个部分花费的时间最多。对开发者和 ExecuTorch 的贡献者来说非常有价值。有关火焰图的更多信息,您可以查看 https://www.parca.dev/docs/icicle-graph-anatomy/

要了解更多关于 ExecuTorch 开发者工具的信息,请参阅 ExecuTorch 开发者工具简介

文档

访问全面的 PyTorch 开发者文档

查看文档

教程

为初学者和高级开发者提供深入的教程

查看教程

资源

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

查看资源