Vai_q_pytorch は、複数の量子化ストラテジ設定のための JSON 形式の量子化コンフィギュレーション ファイルをサポートしています。
使用法
torch_quantizer API に量子化コンフィギュレーション ファイルを渡すだけで、カスタマイズされた設定を有効にできます。
config_file = "./pytorch_quantize_config.json"
quantizer = torch_quantizer(quant_mode=quant_mode,
module=model,
input_args=(input),
device=device,
quant_config_file=config_file)
./example/ ディレクトリには、int_config.json、bfloat16_config.json、mix_precision_config.json の 3 つのサンプルが含まれています。モデルを量子化するには、コンフィギュレーション ファイルを
config_xxx_config.json
コマンドと共に使用します。python resnet18_quant.py --quant_mode calib --config_file int_config.json
python resnet18_quant.py --quant_mode test --config_file int_config.json
サンプル コンフィギュレーション ファイルでは、「overall_quantizer_config」内のモデル設定は「entropy」キャリブレーション方法および「per_tensor」量子化に設定されています。
"overall_quantize_config": {
...
"method": "entropy",
...
"per_channel": false,
...
},
「tensor_quantize_config」は、「maxmin」キャリブレーション法と「per_tensor」量子化を使用して重みを設定します。これは、重みがモデル設定とは異なる量子化方法を使用するということです。
"tensor_quantize_config": {
...
"weights": {
...
"method": "maxmin",
...
"per_channel": false,
...
}
「layer_quantize_config」のリストには、単一レイヤーの量子化設定があります。この設定はレイヤーの種類によって決まり、「torch.nn.Conv2d」レイヤーにチャネルごとの量子化を適用します。
"layer_quantize_config": [
{
"layer_type": "torch.nn.Conv2d",
...
"overall_quantize_config": {
...
"per_channel": false,
設定
- convert_relu6_to_relu
- (グローバルなクオンタイザー設定) ReLU6 を ReLU に変換するかどうか。オプション: True または False。
- include_cle
- (グローバルなクオンタイザー設定) クロス レイヤー イコライゼーションを使用するかどうか。オプション: True または False。
- include_bias_corr
- (グローバルなクオンタイザー設定) バイアス補正を使用するかどうか。オプション: True または False
- target_device
- (グローバルなクオンタイザー設定) 量子化されたモデルのターゲット タイプ。オプション: DPU、CPU、GPU
- quantizable_data_type
- (グローバルなクオンタイザー設定) モデル内で量子化されるテンソルのタイプ。
- data_type
- (テンソルの量子化設定) 量子化に使用するデータ型。オプション: int、bfloat16、float16、float32
- bit_width
- (テンソルの量子化設定) 量子化に使用するビット幅。データ型が int の場合のみ適用されます。
- method
- (テンソルの量子化設定) 量子化スケールのキャリブレーションに使用する方法。オプション: Maxmin、Percentile、Entropy、MSE、diffs。データ型が int の場合のみ適用されます。
- round_mode
- (テンソルの量子化設定) キャリブレーション プロセスの丸め方法。オプション: half_even、half_up、half_down、std_round。データ型が int の場合のみ適用されます。
- symmetry
- (テンソルの量子化設定) 対称量子化を使用するかどうか。オプション: True または False。データ型が int の場合のみ適用されます。
- per_channel
- (テンソルの量子化設定) per_channel 量子化を使用するかどうか。オプション: True または False。データ型が int の場合のみ適用されます。
- signed
- (テンソルの量子化設定) 符号付き量子化を使用するかどうか。オプション: True または False。データ型が int の場合のみ適用されます。
- narrow_range
- (テンソルの量子化設定) 符号付き量子化に対称整数範囲を使用するかどうか。オプション: True または False。データ型が int の場合のみ適用されます。
- scale_type
- (テンソルの量子化設定) 量子化プロセスで使用されるスケールのタイプ。オプション: Float、poweroftwo。データ型が int の場合のみ適用されます。
- calib_statistic_method
- (テンソルの量子化設定) 複数のバッチ データが異なるスケールを持つ場合に、最適な量子化スケールを選択する方法。オプション: modal、max、mean、median。データ型が int の場合のみ適用されます。
階層的設定: 量子化の設定は、階層的なワークフローに従います。
- torch_quantizer API にコンフィギュレーション ファイルが指定されていない場合、DPU デバイス向けにカスタマイズされ、poweroftwo 量子化手法を使用したデフォルトの設定が適用されます。
- コンフィギュレーション ファイルが指定されている場合は、(グローバルなクオンタイザー設定とグローバルなテンソル量子化設定を含む) モデル設定がデフォルト設定をオーバーライドします。
- ファイルでモデル設定のみを指定した場合は、モデル内のすべてのテンソルに同じ設定が採用されます。
- レイヤー設定を使用して、特定の設定パラメーターを特定のレイヤーに割り当てることができます。
デフォルト コンフィギュレーション:
デフォルト設定の詳細を次に示します。
"convert_relu6_to_relu": false,
"include_cle": true,
"include_bias_corr": true,
"target_device": "DPU",
"quantizable_data_type": [
"input",
"weights",
"bias",
"activation"],
"datatype": "int",
"bit_width": 8,
"method": "diffs",
"round_mode": "std_round",
"symmetry": true,
"per_channel": false,
"signed": true,
"narrow_range": false,
"scale_type": "poweroftwo",
"calib_statistic_method": "modal"
モデル設定:
サンプル コンフィギュレーション ファイル int_config.json では、モデル内のすべてのテンソルに同じ int8 量子化が割り当てられます。そのような場合、
overall_quantize_config
キーワードの下に、グローバルな量子化パラメーターを次のように指定する必要があります。 "convert_relu6_to_relu": false,
"include_cle": false,
"keep_first_last_layer_accuracy": false,
"keep_add_layer_accuracy": false,
"include_bias_corr": false,
"target_device": "CPU",
"quantizable_data_type": [
"input",
"weights",
"bias",
"activation"],
"overall_quantize_config": {
"datatype": "int",
"bit_width": 8,
"method": "maxmin",
"round_mode": "half_even",
"symmetry": true,
"per_channel": false,
"signed": true,
"narrow_range": false,
"scale_type": "float",
"calib_statistic_method": "max"
}
int_config.json と同様に、bfloat16_config.json でモデル内のすべてのテンソルに同じ bfloat16 量子化が設定されます。この場合、グローバルな量子化パラメーターで指定されるデータ型は次に示すもののみです。
"convert_relu6_to_relu": false,
"convert_silu_to_hswish": false,
"include_cle": false,
"keep_first_last_layer_accuracy": false,
"keep_add_layer_accuracy": false,
"include_bias_corr": false,
"target_device": "CPU",
"quantizable_data_type": [
"input",
"weights",
"bias",
"activation"
],
"overall_quantize_config": {
"datatype": "bfloat16"
}
オプションにより、モデル内の複数のテンソルの量子化設定を個別に設定できます。これらは「tensor_quantize_config」キーワードの下に設定する必要があります。たとえば、コンフィギュレーション ファイル「mix_precision_config.json」では、グローバルなデータ型の量子化が bfloat16 に設定され、バイアスのデータ型を float16 に変更しています。残りのパラメーターはグローバルな設定と一致しています。
"tensor_quantize_config": {
"bias": {
"datatype": "float16",
}
}
レイヤー設定:
レイヤーの量子化設定は、「layer_quantize_config」リストに含める必要があります。各レイヤーの設定方法には、レイヤー タイプとレイヤー名の 2 つのパラメーターが関係します。レイヤー設定を実行する場合には、次の 5 つのことに注意してください。
- 各レイヤー設定はディクショナリ形式にする必要があります。
- 各レイヤー設定には、「quantizable_data_type」および「overall_quantize_config」パラメーターが必要です。「overall_quantize_config」パラメーターには、このレイヤーのすべての量子化パラメーターが含まれている必要があります。
- レイヤー タイプに基づく設定では、「layer_name」パラメーターを NULL にする必要があります。
- レイヤー名に基づく設定では、モデルのキャリブレーション プロセスを実行する必要があります。キャリブレーション後、quantized_result ディレクトリにある Python ファイルから必要なレイヤー名を選択する必要があります。また、layer_type パラメーターが NULL であることを確認します。
- モデル設定の場合と同じように、レイヤー内の複数のテンソルの量子化設定を個別にカスタマイズできます。これらの個別のテンソル設定は「tensor_quantize_config」キーワードを使用して指定する必要があります。
サンプル コンフィギュレーション ファイルには、2 つのレイヤー設定があります。1 つはレイヤー タイプに基づくもので、もう 1 つはレイヤー名に基づくものです。レイヤー タイプに基づくレイヤー設定では、torch.nn.Conv2d レイヤーを特定の量子化パラメーターに設定する必要があります。重みの「per_channel」パラメーターは「true」に設定され、アクティベーションの「method」パラメーターは「entropy」に設定されます
{
"layer_type": "torch.nn.Conv2d",
"layer_name": null,
"quantizable_data_type": [
"weights",
"bias",
"activation"],
"overall_quantize_config": {
"bit_width": 8,
"method": "maxmin",
"round_mode": "half_even",
"symmetry": true,
"per_channel": false,
"signed": true,
"narrow_range": false,
"scale_type": "float",
"calib_statistic_method": "max"
},
"tensor_quantize_config": {
"weights": {
"per_channel": true
},
"activation": {
"method": "entropy"
}
}
}
レイヤー名に基づくレイヤー設定では、ResNet::ResNet/Conv2d[conv1]/input.2 という名前のレイヤーを特定の量子化パラメーターに設定する必要があります。このレイヤーのアクティベーションの round_mode は「half_up」に設定されます。
{
"layer_type": null,
"layer_name": "ResNet::ResNet/Conv2d[conv1]/input.2",
"quantizable_data_type": [
"weights",
"bias",
"activation"],
"overall_quantize_config": {
"bit_width": 8,
"method": "maxmin",
"round_mode": "half_even",
"symmetry": true,
"per_channel": false,
"signed": true,
"narrow_range": false,
"scale_type": "float",
"calib_statistic_method": "max"
},
"tensor_quantize_config": {
"activation": {
"round_mode": "half_up"
}
}
}
レイヤー名「ResNet::ResNet/Conv2d[conv1]/input.2」は、次のサンプル コードの「example/resnet18_quant.py」の生成されたファイル「quantize_result/ResNet.py 」から取得されます。 - コマンド「
python resnet18_quant.py --subset_len 100
」を使用してサンプル コードを実行します。quantize_result/ResNet.py ファイルが生成されます。 - このファイル内で、最初のたたみ込みレイヤーの名前は「ResNet::ResNet/Conv2d[conv1]/input.2」です。
- このレイヤーに特定の設定を適用する場合は、量子化コンフィギュレーション ファイルにレイヤー名をコピーします。
import torch
import pytorch_nndct as py_nndct
class ResNet(torch.nn.Module):
def __init__(self):
super(ResNet, self).__init__()
self.module_0 = py_nndct.nn.Input() #ResNet::input_0
self.module_1 = py_nndct.nn.Conv2d(in_channels=3, out_channels=64, kernel_size=[7, 7], stride=[2, 2], padding=[3, 3], dilation=[1, 1], groups= 1, bias=True) #ResNet::ResNet/Conv2d[conv1]/input.2
設定の制限
DPU に関連する設計上の制限により、整数量子化を使用し、DPU 上で量子化されたモデルを運用する場合、量子化設定は次の制限を満たす必要があります。
method: diffs or maxmin
round_mode: std_round for weights, bias, and input; half_up for activation.
symmetry: true
per_channel: false
signed: true
narrow_range: true
scale_type: poweroftwo
calib_statistic_method: modal.
CPU および GPU デバイスには、このような制限はありません。ただし、異なる設定を使用する場合に競合が発生することがあります。たとえば、キャリブレーション法「maxmin」、「percentile」、「mse」、「entropy」は、キャリブレーション統計手法「modal」をサポートしていません。さらに、対称モードが「asymmetry」に設定されている場合、キャリブレーション方法「mse」および「entropy」はサポートされません。設定の競合が発生した場合、量子化ツールはエラー メッセージでユーザーに通知します。