PyTorch Quantization:`torch.ao.quantization.fx.custom_config.ConvertCustomConfig.set_preserved_attributes()`の徹底解説
torch.ao.quantization.fx.custom_config.ConvertCustomConfig.set_preserved_attributes()
は、PyTorch Quantizationにおいて、カスタムモジュールの属性を量子化変換時に保持するための設定方法を定義します。
役割
量子化変換では、モデル内のモジュールを量子化対応のものに置き換えます。この際、一部の属性は量子化の影響を受けずに保持する必要があります。set_preserved_attributes()
は、このような属性を個別に指定するためのメソッドです。
使用方法
このメソッドは、ConvertCustomConfig
オブジェクトに対して呼び出し、以下の引数を渡します。
module_type
: 対象となるカスタムモジュールの型preserved_attributes
: 保持する属性名のリスト
例
from torch.ao.quantization import fx
def my_custom_module(input):
# カスタム処理を行う
return output
ConvertCustomConfig().set_preserved_attributes(
preserved_attributes=["weight", "bias"],
module_type=my_custom_module
)
上記の例では、my_custom_module
型のカスタムモジュールの weight
属性と bias
属性を量子化変換時に保持するように設定しています。
注意点
- 保持する属性は、カスタムモジュールの定義に記載されている属性名と一致する必要があります。
- このメソッドは、静的量子化でのみ使用できます。
from torch.ao.quantization import fx
qconfig = {
'my_custom_module': {
'weight': {'dtype': torch.qint8},
'activation': {'dtype': torch.quint8}
}
}
fx.convert_fx(model, qconfig=qconfig)
上記の例では、my_custom_module
型のカスタムモジュールの weight
属性を 8 ビット整数の量子化データ型 torch.qint8
に、activation
属性を 8 ビット符号付き整数の量子化データ型 torch.quint8
に変換するように設定しています。
import torch
import torch.nn as nn
from torch.ao.quantization import fx
# カスタムモジュールを定義
class MyCustomModule(nn.Module):
def __init__(self):
super().__init__()
self.weight = nn.Parameter(torch.randn(10, 20))
self.bias = nn.Parameter(torch.randn(20))
def forward(self, input):
# カスタム処理を行う
output = torch.matmul(input, self.weight) + self.bias
return output
# 静的量子化を行う
model = fx.convert_fx(MyCustomModule(), qconfig=None)
# カスタムモジュールの属性を保持するように設定
ConvertCustomConfig().set_preserved_attributes(
preserved_attributes=["weight", "bias"],
module_type=MyCustomModule
)
# モデルを保存する
torch.save(model, "my_model.pth")
このコードでは、MyCustomModule
というカスタムモジュールを定義し、量子化変換時に weight
属性と bias
属性を保持するように設定しています。
QConfig オブジェクトを用いて属性を保持する
import torch
import torch.nn as nn
from torch.ao.quantization import fx
# カスタムモジュールを定義
class MyCustomModule(nn.Module):
def __init__(self):
super().__init__()
self.weight = nn.Parameter(torch.randn(10, 20))
self.bias = nn.Parameter(torch.randn(20))
def forward(self, input):
# カスタム処理を行う
output = torch.matmul(input, self.weight) + self.bias
return output
# QConfig オブジェクトを作成
qconfig = {
'my_custom_module': {
'weight': {'dtype': torch.qint8},
'activation': {'dtype': torch.quint8},
'preserved_attributes': ['weight', 'bias'] # 属性を保持するように設定
}
}
# 静的量子化を行う
model = fx.convert_fx(MyCustomModule(), qconfig=qconfig)
# モデルを保存する
torch.save(model, "my_model.pth")
このコードでは、QConfig
オブジェクトを用いて、カスタムモジュールの属性を保持するように設定しています。preserved_attributes
キーに属性名をリストとして渡すことで、量子化変換時に属性が保持されます。
カスタムモジュールと QConfig オブジェクトを組み合わせる
import torch
import torch.nn as nn
from torch.ao.quantization import fx
# カスタムモジュールを定義
class MyCustomModule(nn.Module):
def __init__(self):
super().__init__()
self.weight = nn.Parameter(torch.randn(10, 20))
self.bias = nn.Parameter(torch.randn(20))
def forward(self, input):
# カスタム処理を行う
output = torch.matmul(input, self.weight) + self.bias
return output
# QConfig オブジェクトを作成
qconfig = {
'my_custom_module': {
'weight': {'dtype': torch.qint8},
'activation': {'dtype': torch.quint8}
}
}
# カスタムモジュールの属性を保持するように設定
ConvertCustomConfig().set_preserved_attributes(
preserved_attributes=["weight", "bias"],
module_type=MyCustomModule
)
# 静的量子化を行う
model = fx.convert_fx(MyCustomModule(), qconfig=qconfig)
# モデルを保存する
torch.save(model, "my_model.pth")
このコードでは、カスタムモジュールの属性を保持するために ConvertCustomConfig
と QConfig
オブジェクトを組み合わせて使用しています。QConfig
オブジェクトで量子化設定を行い、ConvertCustomConfig
で属性を保持するモジュールを個別に指定することで、より柔軟な設定が可能になります。
- 詳細については、PyTorch Quantization のドキュメントを参照してください。
- これらの例はあくまで基本的な使用方法であり、実際のユースケースに合わせて調整する必要があります。
QConfig オブジェクト
import torch
from torch.ao.quantization import fx
qconfig = {
"my_custom_module": {
"weight": {"dtype": torch.qint8},
"activation": {"dtype": torch.quint8},
"preserved_attributes": ["weight", "bias"], # 属性を保持するように設定
}
}
# 静的量子化を行う
model = fx.convert_fx(my_custom_module, qconfig=qconfig)
この方法では、preserved_attributes
キーに保持したい属性名をリストとして渡すことで、量子化変換時に属性が保持されます。コードが簡潔になり、可読性も向上します。
prepare_custom_module 関数
カスタムモジュールに対して量子化を適用する前に、prepare_custom_module
関数を利用して、属性を明示的にコピーする方法もあります。
import torch
def prepare_custom_module(model):
# カスタムモジュールの属性をコピーして保持する処理
custom_module = model.my_custom_module
custom_module.preserved_weight = custom_module.weight.detach()
custom_module.preserved_bias = custom_module.bias.detach()
# 以降の処理
return model
model = fx.prepare(MyCustomModule(), prepare_custom_module)
# ... (量子化処理)
この方法では、prepare_custom_module
関数内で、コピーしたい属性を明示的にコピーして、新しい属性名で保持します。ただし、コードが冗長になりやすく、メンテナンス性が低下する可能性があります。
トレースの修正
高度なテクニックですが、量子化前のトレース (fx.graph) を修正して、属性を保持させる方法もあります。ただし、この方法は複雑でエラーが発生しやすいため、推奨されません。