AIMET API 文档(4)


1.1.6 量化模拟API

1.1.6.1 用户指南链接

要了解有关量化模拟的更多信息,请参阅量化模拟

1.1.6.2 示例笔记本链接

有关展示如何使用 PyTorch 量化感知训练的端到端笔记本,请参阅此处

1.1.6.3 指南

AIMET Quantization Sim 要求 PyTorch 模型定义遵循某些准则。 这些指南在此处详细描述。 模型指南

AIMET 提供模型准备器 API,允许用户为 AIMET 量化功能准备 PyTorch 模型。 这里详细介绍了 API 和使用示例。 模型准备器 API

AIMET 还包括一个模型验证器实用程序,允许用户检查其模型定义。 请在此处查看此实用程序的 API 和使用示例。 模型验证器 API

1.1.6.4 顶层API

class aimet_torch.quantsim.QuantizationSimModel(model, dummy_input, quant_scheme=<QuantScheme.post_training_tf_enhanced: 2>, rounding_mode=‘nearest’, default_output_bw=8, default_param_bw=8, in_place=False, config_file=None, default_data_type=<QuantizationDataType.int: 1>, master_opdef_file=None, backend_opdef_files=None)[source]

实现向模型添加量化模拟操作的机制。 这允许对推理精度进行脱靶模拟。 还允许对模型进行微调以抵消量化的影响。

QuantizationSimModel 的构造函数。

参数:

扫描二维码关注公众号,回复: 16891182 查看本文章
  • model (Module) – 添加模拟操作的模型
  • dummy_input (Union[Tensor, Tuple]) – 将输入传递给模型。用于解析模型图。 如果模型有多个输入,则传递一个元组。 用户应将张量放置在适当的设备上。
  • quant_scheme (Union[str, QuantScheme]) – 量化方案。 量化方案用于计算量化编码。 有多种方案可供选择。 请参阅 QuantScheme 枚举定义。
  • rounding_mode (str) – 舍入模式。 支持的选项是“最近”或“随机”
  • default_output_bw (int) – 用于量化所有层输入和输出的默认位宽 (4-31)
  • default_param_bw (int) – 用于量化所有层参数的默认位宽 (4-31)
  • in_place (bool) – 如果为 True,则就地修改给定的“模型”以添加量化模拟节点。 仅当用户想要避免创建模型副本时建议使用此选项
  • config_file (Optional[str]) – 模型量化器的配置文件路径
  • default_data_type (QuantizationDataType) – 用于量化所有层输入、输出和参数的默认数据类型。 可能的选项有 QuantizationDataType.int 和 QuantizationDataType.float。 请注意,模式 default_data_type=QuantizationDataType.float 仅支持 default_output_bw=16 和 default_param_bw=16
  • master_opdef_file (Optional[str]) – 主操作定义的 xml 文件路径
  • backend_opdef_files (Optional[List[str]]) – 用于后端操作定义的 xml 文件的路径列表 未找到匹配的情况下应用的位宽、数据类型将根据提供的 xml 的顺序进行处理

以下 API 可用于计算模型的编码

QuantizationSimModel.compute_encodings(forward_pass_callback, forward_pass_callback_args)[source]

计算模型中所有量化模拟节点的编码。 它还用于查找范围学习的初始编码

参数:

  • forward_pass_callback – 简单地向前运行的回调函数会传递模型。 此回调函数应使用代表性数据进行前向传递,因此计算出的编码适用于所有数据样本。 此回调在内部选择要用于计算编码的数据样本数量。
  • forward_pass_callback_args – 这些参数按原样传递给forward_pass_callback。 该参数的类型由用户决定。 例如,可以简单地是表示要使用的数据样本的数量的整数。 或者可以是参数元组或表示更复杂事物的对象。 如果设置为None,则将不带参数调用forward_pass_callback。

返回:

以下API可用于保存和恢复量化模型

quantsim.save_checkpoint(file_path)

此 API 为用户提供了一种保存量化模型检查点的方法,该检查点可以在稍后加载以继续微调,例如另请参阅 load_checkpoint()

参数:

  • quant_sim_model (QuantizationSimModel) – 用于保存检查点的 QuantizationSimModel
  • file_path (str) – 要保存检查点的文件的路径

返回:

quantsim.load_checkpoint()
加载量化模型

参数: file_path (str) – 要保存检查点的文件的路径
返回类型: QuantizationSimModel
返回: 加载检查点后创建的 QuantizationSimModel 的新实例

以下 API 可用于将模型导出到目标

QuantizationSimModel.export(path, filename_prefix, dummy_input, onnx_export_args=None, propagate_encodings=False, export_to_torchscript=False, use_embedded_encodings=False)[source]

此方法导出量化模拟模型,以便它可以在目标上运行。

具体来说,保存以下内容:

  1. sim-model 导出为常规 PyTorch 模型,无需任何模拟操作
  2. 量化编码导出到单独的 JSON 格式的文件,然后可以由目标运行时导入(如果需要)
  3. (可选)导出 ONNX 格式的等效模型。 此外,ONNX 模型中的节点命名与相应的 PyTorch 模块名称相同。 这有助于将 ONNX 节点与其 #2 中的量化编码相匹配。

参数:

  • path (str) – 存储模型 pth 和编码的路径
  • filename_prefix (str) – 用于模型 pth 和编码文件的文件名的前缀
  • dummy_input (Union[Tensor, Tuple]) – 模型的虚拟输入。 用于解析模型图。 需要将 dummy_input 放置在 CPU 上。
  • onnx_export_args (Union[OnnxExportApiArgs, Dict[~KT, ~VT], None]) – 可选导出参数,具有以字典或 OnnxExportApiArgs 对象形式提供的 onnx 特定覆盖。 如果未提供,则默认为“opset_version”= None、“​​input_names”= None、“​​output_names”= None,对于 torch 版本 < 1.10.0,“enable_onnx_checker”= False。
  • propagate_encodings (bool) – 如果为 True,则中间操作的编码条目(当一个 PyTorch 操作导致多个 ONNX 节点时)将使用与该系列操作的输出张量相同的 BW 和 data_type 进行填充。 默认为 False。
  • export_to_torchscript (bool) – 如果为 True,则导出到 torchscript。 否则导出到 onnx。 默认为 False。
  • use_embedded_encodings (bool) – 如果为 True,则将导出另一个嵌入 fakequant 节点的 onnx 模型

编码格式在量化编码规范中描述

1.1.6.5 枚举定义

量化方案枚举

class aimet_common.defs.QuantScheme[source]

量化方案的枚举

post_training_percentile = 6

对于张量,根据传递的百分位值选择调整后的最小值和最大值。 量化编码是使用调整后的最小值和最大值来计算的。

post_training_tf = 1

对于张量,张量的绝对最小值和最大值用于计算量化编码。

post_training_tf_enhanced = 2

对于张量,搜索并选择最小化量化噪声的最佳最小值和最大值。 使用选定的最小值和最大值计算量化编码。’

training_range_learning_with_tf_enhanced_init = 4

对于张量,编码值使用 post_training_tf_enhanced 方案进行初始化。 然后,在训练期间学习编码。

training_range_learning_with_tf_init = 3

对于张量,编码值使用 post_training_tf 方案进行初始化。 然后,在训练期间学习编码。

1.1.6.6 代码示例 - 量化感知训练 (QAT)

此示例演示如何使用 AIMET 执行 QAT(量化感知训练)。 QAT 是一项 AIMET 功能,它将量化模拟操作(有时也称为假量化操作)添加到经过训练的 ML 模型中,并使用标准训练管道对模型进行几个时期的微调或训练。 生成的模型应显示量化机器学习加速器的准确性有所提高。

简称为 QAT - 量化参数(例如激活的每个张量尺度/偏移量)计算一次。 在微调过程中,模型权重会更新,以最大限度地减少前向传播中量化的影响,保持量化参数恒定。

需要导入

import torch
import torch.cuda

加载 PyTorch 模型

对于此示例,我们将从 torchvision 加载预训练的 ResNet18 模型。 同样,您可以加载任何预训练的 PyTorch 模型。

from torchvision.models import resnet18

    model = resnet18(pretrained=True)
    model = model.cuda()

准备量化模拟模型

AIMET量化模拟要求用户的模型定义遵循一定的准则。 例如,前向传递中定义的函数应更改为等效的 torch.nn.Module。 AIMET 用户指南列出了所有这些指南。 以下 ModelPreparer API 使用 PyTorch 1.9+ 版本中提供的新图形转换功能,并自动执行符合上述准则所需的模型定义更改。

更多详情请参考:模型准备器API

from aimet_torch.model_preparer import prepare_model
    prepared_model = prepare_model(model)

创建量化仿真模型

现在我们使用 AIMET 创建 QuantizationSimModel。 这基本上意味着 AIMET 将在模型图中插入假量化操作并配置它们。 这里解释一些参数

from aimet_common.defs import QuantScheme
    from aimet_torch.quantsim import QuantizationSimModel
    input_shape = (1, 3, 224, 224)
    dummy_input = torch.randn(input_shape).cuda()

    quant_sim = QuantizationSimModel(prepared_model, dummy_input=dummy_input,
                                     quant_scheme=QuantScheme.post_training_tf_enhanced,
                                     default_param_bw=8, default_output_bw=8,
                                     config_file='../../TrainingExtensions/common/src/python/aimet_common/quantsim_config/'
                                                 'default_config.json')

从compute_encodings()回调的用户创建的示例函数

尽管 AIMET 已将“量化器”节点添加到模型图中,但该模型尚未准备好使用。 在我们使用 sim 模型进行推理或训练之前,我们需要为每个“量化器”节点找到适当的比例/偏移量化参数。 对于激活量化节点,我们需要通过模型传递未标记的数据样本来收集范围统计数据,然后让 AIMET 计算适当的比例/偏移量化参数。 该过程有时称为校准。 AIMET 将其简单地称为“计算编码”。

因此,我们创建一个例程来通过模型传递未标记的数据样本。 这应该相当简单 - 使用现有的训练或验证数据加载器来提取一些样本并将其传递给模型。 我们不需要计算任何损失指标等。因此我们可以为此目的忽略模型输出。 关于数据样本的一些提示

在实践中,我们需要整个数据样本的一小部分来计算编码。 例如,ImageNet 的训练数据集有 1M 个样本。 对于计算编码,我们只需要 500 或 1000 个样本。

如果用于计算编码的样本分布良好,这可能是有益的。 不需要覆盖所有类等,因为我们只查看每层激活时的值范围。 然而,我们绝对希望避免极端的情况,例如使用所有“黑暗”或“明亮”样本 - 例如,仅使用夜间拍摄的照片可能无法给出理想的结果。

def pass_calibration_data(sim_model, forward_pass_args=None):
    """
    The User of the QuantizationSimModel API is expected to write this function based on their data set.
    This is not a working function and is provided only as a guideline.

    :param sim_model:
    :param args: other arguments for the forwards
    :return:
    """

    # User action required
    # The following line of code is an example of how to use the ImageNet data's validation data loader.
    # Replace the following line with your own dataset's validation data loader.
    data_loader = ImageNetDataPipeline.get_val_dataloader()

    # User action required
    # For computing the activation encodings, around 1000 unlabelled data samples are required.
    # Edit the following 2 lines based on your batch size.
    # batch_size * max_batch_counter should be 1024
    batch_size = 64
    max_batch_counter = 16

    sim_model.eval()

    current_batch_counter = 0
    with torch.no_grad():
        for input_data, target_data in data_loader:

            inputs_batch = input_data  # labels are ignored
            sim_model(inputs_batch)

            current_batch_counter += 1
            if current_batch_counter == max_batch_counter:
                break

计算量化编码

现在我们调用 AIMET 使用上述例程将数据传递给模型,然后计算量化编码。 这里的编码是指比例/偏移量化参数。

quant_sim.compute_encodings(pass_calibration_data, forward_pass_callback_args=None)

微调量化仿真模型

为了执行量化感知训练 (QAT),我们只需再训练模型几个时期(通常为 15-20 个时期)。 与任何训练工作一样,需要搜索超参数以获得最佳结果。 好的起点是在训练原始模型时使用与最终学习率相同数量级的学习率,并每 5 个时期左右将学习率降低 10 倍。

出于本示例的目的,我们将仅训练 1 个 epoch。 但请随意更改您认为合适的这些参数。

# User action required
    # The following line of code illustrates that the model is getting finetuned.
    # Replace the following finetune() unction with your pipeline's finetune() function.
    ImageNetDataPipeline.finetune(quant_sim.model, epochs=1, learning_rate=5e-7, learning_rate_schedule=[5, 10],
                                  use_cuda=use_cuda)

    # Determine simulated accuracy
    accuracy = ImageNetDataPipeline.evaluate(quant_sim.model, use_cuda)
    print(accuracy)

导出模型

所以我们在QAT之后有了一个改进的模型。 现在下一步就是实际将该模型用于目标。 为此,我们需要导出具有更新权重的模型,而不使用虚假的量化操作。 我们还导出自使用 QAT 以来在训练期间更新的编码(比例/偏移量化参数)。 AIMET QuantizationSimModel 为此提供了一个导出 API。

# Export the model which saves pytorch model without any simulation nodes and saves encodings file for both
    # activations and parameters in JSON format
    quant_sim.export(path='./', filename_prefix='quantized_resnet18', dummy_input=dummy_input.cpu())

1.1.7 自适应舍入 API

1.1.7.1 用户指南链接

要了解有关此技术的更多信息,请参阅 AdaRound

1.1.7.2 示例笔记本链接

有关展示如何使用 PyTorch AdaRound 的端到端笔记本,请参阅此处

1.1.7.3 顶层API

aimet_torch.adaround.adaround_weight.Adaround.apply_adaround(model, dummy_input, params, path, filename_prefix, default_param_bw=4, param_bw_override_list=None, ignore_quant_ops_list=None, default_quant_scheme=<QuantScheme.post_training_tf_enhanced: 2>, default_config_file=None)

返回每个模块(Conv 和 Linear)优化权重舍入的模型,并将相应的量化编码保存到单独的 JSON 格式的文件中,然后可由 QuantSim 导入以进行推理或 QAT

参数:

  • model (Module) – 模型到 Adaround
  • dummy_input (Union[Tensor, Tuple]) – 模型的虚拟输入。 用于解析模型图。 如果模型有多个输入,则传递一个元组。 用户应将张量放置在适当的设备上。
  • params (AdaroundParameters) – Adaround 的参数
  • path (str) – 存储参数编码的路径
  • filename_prefix (str) – 用于编码文件的文件名的前缀
  • default_param_bw (int) – 用于量化图层参数的默认位宽 (4-31)
  • param_bw_override_list (Optional[List[Tuple[Module, int]]]) – 元组列表。 每个元组都是一个模块以及该模块要使用的相应参数位宽
  • ignore_quant_ops_list (Optional[List[Module]]) – 在 AdaRounding 所需的量化过程中,会跳过此处列出的操作。 不要在此列表中指定 Conv 和 Linear 模块。 这样做,会影响准确性
  • default_quant_scheme (QuantScheme) – 量化方案。 支持的选项使用定量方案枚举 QuantScheme.post_training_tf 或 QuantScheme.post_training_tf_enhanced
  • default_config_file (Optional[str]) – 模型量化器的默认配置文件

返回类型: Module
返回: 使用 Adarounded 权重进行建模,并在提供的路径中保存相应的参数编码 JSON 文件

1.1.7.4 Adaround参数

class aimet_torch.adaround.adaround_weight.AdaroundParameters(data_loader, num_batches, default_num_iterations=None, default_reg_param=0.01, default_beta_range=(20, 2), default_warm_start=0.2, forward_fn=None)[source]

Adaround 的配置参数

参数:

  • data_loader (DataLoader[+T_co]) – 数据加载器
  • num_batches (int) – 用于 Adaround 的批次数。 此参数的通常推荐值是 (1) len(data_loader) 和 (2) ceil(2000/batch_size) 中较小的值
  • default_num_iterations (Optional[int]) – 每层周围的迭代次数。 对于具有 8 位或更高位权重的模型,默认值为 10K;对于低于 8 位权重的模型,默认值为 15K。
  • default_reg_param (float) – 正则化参数,在舍入损失与重建损失之间进行权衡。 默认 0.01
  • default_beta_range (Tuple) – 用于舍入损失退火的开始和停止 beta 参数(start_beta、end_beta)。 默认 (20, 2)
  • default_warm_start (float) – 预热期,在此期间舍入损失的影响为零。 默认 20% (0.2)
  • forward_fn (Optional[Callable[[Module, Any], Any]]) – 可选的适配器函数,在给定模型和数据加载器生成的输入的情况下执行前向传递。 该函数期望模型作为第一个参数,并输入模型作为第二个参数。
1.1.7.5 枚举定义

量化方案枚举

class aimet_common.defs.QuantScheme[source]

量化方案的枚举

post_training_percentile = 6

对于张量,根据传递的百分位值选择调整后的最小值和最大值。 量化编码是使用调整后的最小值和最大值来计算的。

post_training_tf = 1

对于张量,张量的绝对最小值和最大值用于计算量化编码。

post_training_tf_enhanced = 2

对于张量,搜索并选择最小化量化噪声的最佳最小值和最大值。 使用选定的最小值和最大值计算量化编码。

Training_range_learning_with_tf_enhanced_init = 4

对于张量,编码值使用 post_training_tf_enhanced 方案进行初始化。 然后,在训练期间学习编码。

training_range_learning_with_tf_init = 3

对于张量,编码值使用 post_training_tf 方案进行初始化。 然后,在训练期间学习编码。

猜你喜欢

转载自blog.csdn.net/weixin_38498942/article/details/133070299