AIMET API 文档(10)
1.3 用于压缩的 PyTorch 模型可视化 API
1.3.1 顶级API压缩
classaimet_torch.visualize_serialized_data.VisualizeCompression(visualization_url)
更新散景服务器会话文档并通过会话 ID 压缩将图形/表格发布到服务器。
VisualizeCompression.display_eval_scores(saved_eval_scores_dict_path)
将评价分数表发布到服务器。
参数
save_eval_scores_dict_path – 每层评估分数的文件路径
返回
没有任何
VisualizeCompression.display_comp_ratio_plot(comp_ratio_list_path)
将最佳压缩比发布到服务器。
参数
comp_ratio_list_path – pkl 文件的路径以及每层的压缩率
返回
没有任何
1.3.2 代码示例
所需进口
from decimal import Decimal
import torch
from torchvision import models
import aimet_common.defs
import aimet_torch.defs
import aimet_torch.utils
from aimet_common.utils import start_bokeh_server_session
from aimet_torch.compress import ModelCompressor
from aimet_torch.visualize_serialized_data import VisualizeCompression
带可视化参数的模型压缩
def model_compression_with_visualization(eval_func):
"""
Code example for compressing a model with a visualization url provided.
"""
process = None
try:
visualization_url, process = start_bokeh_server_session()
input_shape = (1, 3, 224, 224)
model = models.resnet18(pretrained=True).to(torch.device('cuda'))
modules_to_ignore = [model.conv1]
greedy_params = aimet_common.defs.GreedySelectionParameters(target_comp_ratio=Decimal(0.65),
num_comp_ratio_candidates=10,
saved_eval_scores_dict=
'../data/resnet18_eval_scores.pkl')
auto_params = aimet_torch.defs.SpatialSvdParameters.AutoModeParams(greedy_params,
modules_to_ignore=modules_to_ignore)
params = aimet_torch.defs.SpatialSvdParameters(aimet_torch.defs.SpatialSvdParameters.Mode.auto, auto_params,
multiplicity=8)
# If no visualization URL is provided, during model compression execution no visualizations will be published.
ModelCompressor.compress_model(model=model, eval_callback=eval_func, eval_iterations=5,
input_shape=input_shape,
compress_scheme=aimet_common.defs.CompressionScheme.spatial_svd,
cost_metric=aimet_common.defs.CostMetric.mac, parameters=params,
visualization_url=None)
comp_ratios_file_path = './data/greedy_selection_comp_ratios_list.pkl'
eval_scores_path = '../data/resnet18_eval_scores.pkl'
# A user can visualize the eval scores dictionary and optimal compression ratios by executing the following code.
compression_visualizations = VisualizeCompression(visualization_url)
compression_visualizations.display_eval_scores(eval_scores_path)
compression_visualizations.display_comp_ratio_plot(comp_ratios_file_path)
finally:
if process:
process.terminate()
process.join()
1.4 用于量化的 PyTorch 模型可视化 API
1.4.1 顶级 API 量化
aimet_torch.visualize_model.visualize_relative_weight_ranges_to_identify_problematic_layers(模型, results_dir , selected_layers=None )
对于每个选定的层,发布显示每个层的权重范围的线图、相对权重范围的汇总统计数据以及显示输出通道相对于最小权重范围的权重范围的直方图。
参数
-
模型( Module) – pytorch 模型
-
results_dir ( str) – 保存散景图的目录
-
selected_layers ( Optional[ List[~T]]) – 用户可以选择可视化的图层列表。如果选定的图层为“无”,则所有线性和卷积层都将可视化。
返回类型
List[ Figure]
返回
散景图列表
aimet_torch.visualize_model.visualize_weight_ranges(模型, results_dir , selected_layers=None )
通过散点图可视化每层的权重范围,该散点图显示相对于标准差绘制的平均值、相对于最大值绘制的最小值以及每个输出通道的包含最小值、最大值和平均值的线图。
参数
-
模型( Module) – pytorch 模型
-
selected_layers ( Optional[ List[~T]]) – 用户可以选择可视化的图层列表。如果选定的图层为“无”,则所有线性和卷积层都将可视化。
-
results_dir ( str) – 保存散景图的目录
返回类型
List[ Figure]
返回
散景图列表
aimet_torch.visualize_model.visualize_changes_after_optimization(old_model ,new_model , results_dir , selected_layers=None )
可视化对模型应用某些优化之前和之后的变化。
参数
-
old_model ( Module) – 优化前的 pytorch 模型
-
new_model ( Module) – 优化后的 pytorch 模型
-
results_dir ( str) – 保存散景图的目录
-
selected_layers ( Optional[ List[~T]]) – 用户可以选择可视化的图层列表。如果选定的图层为“无”,则所有线性和卷积层都将可视化。
返回类型
List[ Figure]
返回
散景图列表
代码示例
所需进口
import copy
import torch
from torchvision import models
from aimet_torch.cross_layer_equalization import equalize_model
from aimet_torch import batch_norm_fold
from aimet_torch import visualize_model
优化后模型对比
def visualize_changes_in_model_after_and_before_cle():
"""
Code example for visualizating model before and after Cross Layer Equalization optimization
"""
model = models.resnet18(pretrained=True).to(torch.device('cpu'))
model = model.eval()
# Create a copy of the model to visualize the before and after optimization changes
model_copy = copy.deepcopy(model)
# Specify a folder in which the plots will be saved
results_dir = './visualization'
batch_norm_fold.fold_all_batch_norms(model_copy, (1, 3, 224, 224))
equalize_model(model, (1, 3, 224, 224))
visualize_model.visualize_changes_after_optimization(model_copy, model, results_dir)
在模型中可视化体重范围
def visualize_weight_ranges_model():
"""
Code example for model visualization
"""
model = models.resnet18(pretrained=True).to(torch.device('cpu'))
model = model.eval()
# Specify a folder in which the plots will be saved
results_dir = './visualization'
batch_norm_fold.fold_all_batch_norms(model, (1, 3, 224, 224))
# Usually it is observed that if we do BatchNorm fold the layer's weight range increases.
# This helps in visualizing layer's weight
visualize_model.visualize_weight_ranges(model, results_dir)
在模型中可视化相对体重范围
def visualize_relative_weight_ranges_model():
"""
Code example for model visualization
"""
model = models.resnet18(pretrained=True).to(torch.device('cpu'))
model = model.eval()
# Specify a folder in which the plots will be saved
results_dir = './visualization'
batch_norm_fold.fold_all_batch_norms(model, (1, 3, 224, 224))
# Usually it is observed that if we do BatchNorm fold the layer's weight range increases.
# This helps in finding layers which can be equalized to get better performance on hardware
visualize_model.visualize_relative_weight_ranges_to_identify_problematic_layers(model, results_dir)
1.4 PyTorch 层输出生成 API
该 API 捕获并保存模型的中间层输出。该模型可以是原始模型 (FP32) 或 Quantsim。层输出根据 Quantsim 导出 API 导出的 PyTorch/ONNX/TorchScript 模型进行命名。这允许在目标设备上的 FP32 模型、量化模拟模型和实际量化模型之间进行层输出比较,以调试精度不匹配问题。
1.4.1 顶级API
aimet_torch.layer_output_utils.LayerOutputUtil(model、dir_path、naming_scheme=<NamingScheme.PYTORCH: 1>、dummy_input=None、onnx_export_args=None )
实现捕获和保存模型中间层的输出(fp32/quantsim)。
LayerOutputUtil 的构造函数。
参数
-
model ( Module) – 需要其层输出的模型。
-
dir_path ( str) – 将保存图层输出的目录。
-
naming_scheme ( NamingScheme) – 命名层输出时遵循的命名方案。根据导出的模型(pytorch、onnx 或 torchscript)有多种方案。请参阅 NamingScheme 枚举定义。
-
dummy_input ( Union[ Tensor, Tuple, List[~T], None]) – 模型的虚拟输入。如果naming_scheme 为“NamingScheme.ONNX”或“NamingScheme.TORCHSCRIPT”,则为必需。
-
onnx_export_args ( Union[ OnnxExportApiArgs, Dict[~KT, ~VT], None]) – 应与传递给 Quantsim 导出 API 的参数相同,以确保导出的 onnx 模型中存在的层输出名称与生成的层输出名称之间的一致性。如果naming_scheme 为“NamingScheme.ONNX”,则为必需。
以下 API 可用于生成层输出
LayerOutputUtil.generate_layer_outputs(input_batch )
此方法捕获模型每一层的输出并将输入和相应的层输出保存到磁盘。
参数
input_batch ( Union[ Tensor, List[ Tensor], Tuple[ Tensor]]) – 我们想要获得层输出的一批输入。
返回
没有任何
1.4.2 枚举定义
命名方案枚举
aimet_torch.layer_output_utils.NamingScheme
层输出命名方案的枚举。
-
ONNX= 2
根据导出的 onnx 模型命名输出。层输出名称通常是数字。 -
PYTORCH= 1
根据导出的 pytorch 模型命名输出。使用图层名称。 -
TORCHSCRIPT= 3
根据导出的 torchscript 模型命名输出。层输出名称通常是数字。
1.4.3 代码示例
进口
import torch
from torchvision import models
from aimet_torch.onnx_utils import OnnxExportApiArgs
from aimet_torch.model_preparer import prepare_model
from aimet_torch.quantsim import QuantizationSimModel
from aimet_torch.layer_output_utils import LayerOutputUtil, NamingScheme
获取原始或QuantSim模型
# Obtain original model
original_model = models.resnet18()
original_model.eval()
original_model = prepare_model(original_model)
# Obtain quantsim model
dummy_input = torch.rand(1, 3, 224, 224)
def forward_pass(model: torch.nn.Module, input_batch: torch.Tensor):
model.eval()
with torch.no_grad():
_ = model(input_batch)
quantsim = QuantizationSimModel(model=original_model, quant_scheme='tf_enhanced',
dummy_input=dummy_input, rounding_mode='nearest',
default_output_bw=8, default_param_bw=8, in_place=False)
quantsim.compute_encodings(forward_pass_callback=forward_pass,
forward_pass_callback_args=dummy_input)
获取预处理的输入
# Get the inputs that are pre-processed using the same manner while computing quantsim encodings
input_batches = get_pre_processed_inputs()
生成层输出
# Generate layer-outputs
layer_output_util = LayerOutputUtil(model=quantsim.model, dir_path='./layer_output_dump', naming_scheme=NamingScheme.ONNX,
dummy_input=dummy_input, onnx_export_args=OnnxExportApiArgs())
for input_batch in input_batches:
layer_output_util.generate_layer_outputs(input_batch)