# mypy: 允许未类型化定义
来自
未来
导入
注释
来自 dataclasses
导入
数据类
来自
打字
导入
任意,
可选
来自 torch.ao.quantization
导入
QConfig 映射
来自 torch.ao.quantization.backend_config
导入
后端配置
来自 torch.ao.quantization.quant_type
导入 (
_get_quant_type_to_str,
从字符串获取量类型,
量类型,
)
__all__ = [
转换自定义配置,
融合自定义配置,
"准备自定义配置",
"独立模块配置条目",
]
# TODO: 将所有使用替换为这些常量
独立模块名称字典键 =
"独立模块名称"
单独模块类字典键 =
独立模块类
浮点数到观测字典键 =
浮点数到观测自定义模块类
观测到量化字典键 =
"观测到量化自定义模块类"
不可追踪模块名称字典键 =
"不可追踪模块名称"
不可追踪模块类字典键 =
不可追踪模块类
输入量化索引字典键 =
输入量化 idxs
输出量化索引字典键 =
"输出量化 idxs"
保留属性字典键 =
"保留属性"
[文档]@dataclass
class StandaloneModuleConfigEntry:
# qconfig_mapping 用于在子模块中调用的 prepare 函数,
# None 表示使用父 qconfig_mapping 中的 qconfig
qconfig_mapping: 可选[QConfigMapping]
example_inputs: 元组[Any, ...]
prepare_custom_config: 可选[PrepareCustomConfig]
backend_config: 可选[BackendConfig]
[文档]
类
准备自定义配置:
""
Custom configuration for :func:`~torch.ao.quantization.quantize_fx.prepare_fx` 和
func:`~torch.ao.quantization.quantize_fx.prepare_qat_fx`。
演示用法:
prepare_custom_config = PrepareCustomConfig() \
.set_standalone_module_name("module1", qconfig_mapping, example_inputs, \
child_prepare_custom_config, backend_config)
.set_standalone_module_class(MyStandaloneModule, qconfig_mapping, example_inputs,
child_prepare_custom_config, backend_config)
.set_float_to_observed_mapping(FloatCustomModule, ObservedCustomModule)
.set_non_traceable_module_names(["module2", "module3"])
.set_non_traceable_module_classes([NonTraceableModule1, NonTraceableModule2])
.set_input_quantized_indexes([0])
.set_output_quantized_indexes([0])
.set_preserved_attributes(["attr1", "attr2"])
```python
# 假设输入文本为:
input_text = '"""'
# 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API)
def translate_to_simplified_chinese(text):
# 这里应该调用真实的翻译 API 进行翻译
# 由于示例中不使用真实的 API,以下为模拟翻译结果
return text
# 输出翻译结果
translated_text = translate_to_simplified_chinese(input_text)
print(translated_text)
```
def 初始化(
自身) ->
无:
自身.
独立模块名称:
字典[
字符串,
独立模块配置条目] = {}
自身.
独立模块类:
字典[
类型,
独立模块配置条目] = {}
自身.float_to_observed_mapping:
字典[
量化类型,
字典[
类型,
类型]] = {}
自身.
不可追踪的模块名称:
列表[
字符串] = []
自身.
不可追踪的模块类:
列表[
类型] = []
自身.
输入量化索引:
列表[int] = []
自身.
输出量化索引:
列表[int] = []
自身.
保留属性:
列表[
字符串] = []
def __repr__(自身):
字典非空 = {k: v
为 k, v
在
自身.
字典.
项目()
如果
长度(v) > 0}
返回 f
准备自定义配置({dict_nonempty})"
[文档] def set_standalone_module_name(
self,
module_name: str,
qconfig_mapping: Optional[QConfigMapping],
example_inputs: 任意元组类型...
prepare_custom_config: 可选的[自定义配置准备]类型
backend_config: 可选的[后端配置]类型
) -> [自定义配置准备]:
“”
设置运行以 ``module_name`` 标识的独立模块的配置。
如果 ``qconfig_mapping`` 为 None,则将使用父 ``qconfig_mapping``。
如果 ``prepare_custom_config`` 为 None,则将使用空的 ``PrepareCustomConfig``。
如果 `backend_config` 为 None,则将使用父级 `backend_config`。
"""
self.standalone_module_names[module_name] = StandaloneModuleConfigEntry(
qconfig_mapping, example_inputs, prepare_custom_config, backend_config
)
返回自身
[文档] def 设置独立模块类(
self,
module_class: 类型,
qconfig_mapping: 可选[QConfigMapping],
example_inputs: 元组[任何类型, ...],
prepare_custom_config: 可选[PrepareCustomConfig],
backend_config: 可选[BackendConfig],
) -> 准备自定义配置:
"""
设置运行由 ``module_class`` 标识的独立模块的配置。
如果 `qconfig_mapping` 为 None,则将使用父级 `qconfig_mapping`。
如果 `prepare_custom_config` 为 None,则将使用空的 `PrepareCustomConfig`。
如果 `backend_config` 为 None,则将使用父级 `backend_config`。
"""
self.standalone_module_classes[module_class] = StandaloneModuleConfigEntry(
qconfig_mapping, example_inputs, prepare_custom_config, backend_config
)
return self
[文档] def set_float_to_observed_mapping(
self,
float_class: 类型,
observed_class: 类型,
quant_type: QuantType = QuantType.STATIC,
) -> 准备自定义配置:
"""
将自定义浮点模块类映射到自定义观测模块类。
观察的模块类必须有一个 `from_float` 类方法,该方法将浮点模块类转换为
到观察的模块类。目前仅支持静态量化。
```python
# 输入文本
input_text = '"""'
# 翻译函数(此处为示例,实际翻译功能需调用真实的翻译 API)
def translate_to_simplified_chinese(text):
# 假设的翻译结果
return text
# 输出翻译结果
translated_text = translate_to_simplified_chinese(input_text)
print(translated_text)
```
如果 quant_type 不等于 QuantType.STATIC:
raise ValueError(
"set_float_to_observed_mapping 目前仅支持静态量化"
)
if quant_type not in self.float_to_observed_mapping:
self.float_to_observed_mapping[quant_type] = {}
self.float_to_observed_mapping[quant_type][float_class] = observed_class
return self
[文档] def set_non_traceable_module_names(
self, 模块名称列表: list[str]
) -> 准备自定义配置:
"""
设置无法进行符号跟踪的模块,通过名称标识。
"""
self.non_traceable_module_names = 模块名称列表
返回 self
[文档] def 设置不可追踪模块类(
self, 模块类列表: list[type]
) -> 准备自定义配置:
"""
设置无法进行符号跟踪的模块,通过类标识。
"""
self.non_traceable_module_classes = module_classes
返回 self
[文档] def set_input_quantized_indexes(self, indexes: list[int]) -> PrepareCustomConfig:
""
设置应进行量化的图输入的索引。
否则默认假设输入为 fp32。
""
self.input_quantized_indexes = indexes
return self
[文档] def set_output_quantized_indexes(self, indexes: list[int]) -> PrepareCustomConfig:
"""
设置需要量化的图输出的索引。
否则默认假设输出为 fp32。
"""
self.output_quantized_indexes = indexes
返回自身
[文档] def set_preserved_attributes(self, attributes: list[str]) -> PrepareCustomConfig:
"""
设置在图模块中即使未使用也将持久化的属性的名称
模型的 ``forward`` 方法。
"""
self.preserved_attributes = attributes
返回 self
# TODO: 删除此行
[文档] @classmethod
def from_dict(
类,
准备自定义配置字典:
字典[
字符串,
任意]
) -> 准备自定义配置:
""
创建一个包含以下项的字典的 ``PrepareCustomConfig``:
"standalone_module_name": 一个包含(module_name, qconfig_mapping, example_inputs,)的列表
子准备自定义配置,后端配置元组
"独立模块类" 一个由 (模块类, qconfig 映射, 示例输入) 组成的列表
子准备自定义配置,后端配置元组
"float_to_observed_custom_module_class": 一个从量化映射到观察到的自定义模块类的嵌套字典
模式到一个内部映射,从浮点模块类到观察模块类,例如
{"static": {FloatCustomModule: ObservedCustomModule}}
"non_traceable_module_name": 无法符号追踪的模块名称列表
"non_traceable_module_class": 无法符号追踪的模块类列表
"input_quantized_idxs": 应量化图输入的索引列表
"output_quantized_idxs": 应量化图输出的索引列表
"保留属性列表,即使它们在 `forward` 中未使用也会持续存在"
此函数主要用于向后兼容,未来可能会被移除。
```python
# 假设输入文本为:
input_text = '"""'
# 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API)
def translate_to_simplified_chinese(text):
# 这里应该调用真实的翻译 API 进行翻译
# 由于示例中不使用真实的 API,以下为模拟翻译结果
return text
# 输出翻译结果
translated_text = translate_to_simplified_chinese(input_text)
print(translated_text)
```
def _get_qconfig_mapping(对象:
任意,
字典键:
字符串) ->
可选[
QConfig 映射
]:
""
尝试将给定对象转换为 QConfigMapping,如果可能,否则抛出异常。
```python
# 假设输入文本为:
input_text = '"""'
# 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API)
def translate_to_simplified_chinese(text):
# 这里应该调用真实的翻译 API 进行翻译
# 由于示例中不使用真实的 API,以下为模拟翻译结果
return text
# 输出翻译结果
translated_text = translate_to_simplified_chinese(input_text)
print(translated_text)
```
如果 isinstance(
对象,
QConfig 映射)
或
对象
是
无:
返回
对象
如果 isinstance(
对象,
字典):
返回
QConfig 映射.from_dict(
对象)
提升 ValueError(
f在 prepare_custom_config_dict[]中期望 QConfigMapping,却得到
输入文本:
"Immersive Translate"
翻译:
沉浸式翻译{字典键}
输入文本:
"Immersive Translate"
翻译:
沉浸式翻译]{
类型(
对象)}
'"'
)
def 获取准备自定义配置(
对象:
任意,
字典键:
字符串
) -> 可选[
准备自定义配置
]:
""
尝试将给定对象转换为 PrepareCustomConfig,如果可能,否则抛出异常。
```python
# 假设输入文本为:
input_text = '"""'
# 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API)
def translate_to_simplified_chinese(text):
# 这里应该调用真实的翻译 API 进行翻译
# 由于示例中不使用真实的 API,以下为模拟翻译结果
return text
# 输出翻译结果
translated_text = translate_to_simplified_chinese(input_text)
print(translated_text)
```
如果 isinstance(
对象,
准备自定义配置)
或
对象
是
无:
返回
对象
如果 isinstance(
对象,
字典):
返回
准备自定义配置.from_dict(
对象)
提升 ValueError(
f预期在 prepare_custom_config_dict 中为 PrepareCustomConfig
输入文本:
"Immersive Translate"
翻译:
沉浸式翻译{字典键}
输入文本:
"Immersive Translate"
翻译:
沉浸式翻译],获取 '{
类型(
对象)}
'"'
)
def _获取后端配置(
对象:
任意,
字典键:
字符串) ->
可选[
后端配置
]:
""
尝试将给定对象转换为 BackendConfig,如果可能,否则抛出异常。
```python
# 假设输入文本为:
input_text = '"""'
# 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API)
def translate_to_simplified_chinese(text):
# 这里应该调用真实的翻译 API 进行翻译
# 由于示例中不使用真实的 API,以下为模拟翻译结果
return text
# 输出翻译结果
translated_text = translate_to_simplified_chinese(input_text)
print(translated_text)
```
如果 isinstance(
对象,
后端配置)
或
对象
是
无:
返回
对象
如果 isinstance(
对象,
字典):
返回
后端配置.from_dict(
对象)
提升 ValueError(
f在 prepare_custom_config_dict[]中期望 BackendConfig,却得到
输入文本:
"Immersive Translate"
翻译:
沉浸式翻译{字典键}
输入文本:
"Immersive Translate"
翻译:
沉浸式翻译]{
类型(
对象)}
'"'
)
配置 =
类()
为 (
模块名称,
qconfig 字典,
示例输入,
_准备自定义配置字典,
后端配置字典,
) 在
准备自定义配置字典.
获取(
单独模块名称字典键, []):
qconfig 映射 =
获取_qconfig 映射(
qconfig 字典,
独立模块名称字典键
)
prepare_custom_config = _get_prepare_custom_config(
_prepare_custom_config_dict, 单独模块名称字典键
)
backend_config = 获取后端配置(
后端配置字典,
单独模块名称字典键
)
配置.
设置独立模块名称(
模块名称,
QConfig 映射,
示例输入,
准备自定义配置,
后端配置,
)
为 (
模块类,
qconfig 字典,
示例输入,
_准备自定义配置字典,
后端配置字典,
) 在
准备自定义配置字典.
获取(
单独模块类字典键, []):
qconfig 映射 =
_获取 qconfig 映射(
qconfig 字典,
单独模块类字典键
)
prepare_custom_config = _获取准备自定义配置(
准备自定义配置字典,
独立模块类字典键
)
backend_config = 获取后端配置(
后端配置字典,
单独模块类字典键
)
配置.
设置单独模块类(
模块类,
QConfig 映射,
示例输入,
准备自定义配置,
后端配置,
)
为
量化类型名称,
自定义模块映射
在
准备自定义配置字典.
获取(
FLOAT_TO_OBSERVED_DICT_KEY, {}
).项目():
量化类型 =
_从字符串获取量化类型(
量化类型名称)
为
浮点类,
被观察类
在
自定义模块映射.
项目():
配置.
将浮点数设置为观测映射(
浮点类,
观察到的类,
量化类型
)
配置.
设置不可追踪模块名称(
准备自定义配置字典.
获取(
不可追踪模块名称字典键,
[]
)
配置.
设置不可追踪的模块类(
准备自定义配置字典.
获取(
不可追踪模块类字典键,
[]
)
配置.
设置输入量化索引(
准备自定义配置字典.
获取(
输入量化索引字典键,
[]
)
配置.
设置输出量化索引(
准备自定义配置字典.
获取(
输出量化索引字典键,
[]
)
配置.
设置保留属性(
准备自定义配置字典.
获取(
保留属性字典键,
[]
)
返回
配置
[文档] def to_dict(
自身) ->
字典[
字符串,
任意
]:
""
将此 `PrepareCustomConfig` 转换为包含以下项的字典。
func:`~torch.ao.quantization.fx.custom_config.PrepareCustomConfig.from_dict`。
```python
# 假设输入文本为:
input_text = '"""'
# 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API)
def translate_to_simplified_chinese(text):
# 这里应该调用真实的翻译 API 进行翻译
# 由于示例中不使用真实的 API,以下为模拟翻译结果
return text
# 输出翻译结果
translated_text = translate_to_simplified_chinese(input_text)
print(translated_text)
```
def _make_tuple(键:
任意, e: StandaloneModuleConfigEntry):
qconfig_dict = e.QConfig 映射.to_dict()
如果 e.
qconfig 映射
否则 None
准备自定义配置字典 = (
e.准备自定义配置.to_dict()
如果 e.prepare_custom_config
否则 None
)
返回 (
键,
qconfig 字典,
e.示例输入,
准备自定义配置字典,
e.后端配置,
)
d: 字典[
字符串,
任意] = {}
为
模块名称, sm_config_entry
在
自身.
独立模块名称.
项目():
如果 STANDALONE_MODULE_NAME_DICT_KEY not
在 d:
d[单独模块名称字典键] = []
d[单独模块名称字典键].
追加(
_make_tuple(模块名称,
sm 配置条目)
)
为
模块类,
简单配置条目
在
自身.
独立模块类.
项目():
如果
独立模块类字典键 not
在 d:
d[独立模块类字典键] = []
d[单独模块类字典键].
追加(
_创建元组(
模块类,
sm 配置条目)
)
为 (
量化类型,
浮点数到观测值的映射,
) 在
自身.
浮点数到观测映射.
项目():
如果 FLOAT_TO_OBSERVED_DICT_KEY not
在 d:
d[FLOAT_TO_OBSERVED_DICT_KEY] = {}
d[浮点数到观测字典键
]
获取量化类型到字符串的映射(
量化类型)
] = 浮点数到观测映射
如果
长度(
自身.
不可追踪的模块名称) > 0:
d[不可追踪模块名称字典键] =
自身.
不可追踪的模块名称
如果
长度(
自身.
不可追踪的模块类) > 0:
d[无法追踪的模块类字典键] =
自身.
无法追踪的模块类
如果
长度(
自身.
输入量化索引) > 0:
d[输入量化索引字典键] =
自身.
输入量化索引
如果
长度(
自身.
输出量化索引) > 0:
d[输出量化索引字典键] =
自身.
输出量化索引
如果
长度(
自身.
保留属性) > 0:
d[保留属性字典键] =
自身.
保留属性
返回 d
[文档]
类 ConvertCustomConfig:
""
对`:func:`~torch.ao.quantization.quantize_fx.convert_fx`的定制配置进行操作。
演示用法:
convert_custom_config = ConvertCustomConfig()
.set_observed_to_quantized_mapping(ObservedCustomModule, QuantizedCustomModule)
.set_preserved_attributes(["attr1", "attr2"])
```python
# 假设输入文本为:
input_text = '"""'
# 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API)
def translate_to_simplified_chinese(text):
# 这里应该调用真实的翻译 API 进行翻译
# 由于示例中不使用真实的 API,以下为模拟翻译结果
return text
# 输出翻译结果
translated_text = translate_to_simplified_chinese(input_text)
print(translated_text)
```
def 初始化(
自身) ->
无:
自身.
观测到量化映射:
字典[
量化类型,
字典[
类型,
类型]] = {}
自身.
保留属性:
列表[
字符串] = []
def __repr__(自身):
字典非空 = {k: v
为 k, v
在
自身.
字典.
项目()
如果
长度(v) > 0}
返回 f
ConvertCustomConfig({dict_nonempty})"
[文档] def 设置观察到的量化映射(
self,
observed_class: 类型,
quantized_class: 类型,
quant_type: QuantType = QuantType.STATIC,
) -> 转换自定义配置:
"""
将自定义观测模块类映射到自定义量化模块类。
量化模块类必须有一个 `from_observed` 类方法,该方法可以将观测模块类
转换为量化模块类。
"""
如果 quant_type 不在 self.observed_to_quantized_mapping 中:
self.observed_to_quantized_mapping[quant_type] = {}
self.observed_to_quantized_mapping[quant_type][observed_class] = quantized_class
返回 self
[文档] def set_preserved_attributes(self, attributes: list[str]) -> ConvertCustomConfig:
"""
设置在图模块中即使未被模型“forward”方法使用也将保留的属性名称。
the model's ``forward`` method.
"``"
self.preserved_attributes = attributes
返回 self
# TODO: 删除此行
[文档] @类方法
def from_dict(
cls, convert_custom_config_dict: dict[str, Any]
) -> ConvertCustomConfig:
```python
# 输入文本
input_text = '"""'
# 翻译函数(此处为示例,实际翻译功能需调用真实的翻译 API)
def translate_to_simplified_chinese(text):
# 假设的翻译结果
return text
# 输出翻译结果
translated_text = translate_to_simplified_chinese(input_text)
print(translated_text)
```
创建一个包含以下项的字典“ConvertCustomConfig”:
"observed_to_quantized_custom_module_class": 一个从量化映射到自定义模块类的嵌套字典
模式到一个内部映射,从观察到的模块类到量化模块类,例如:
{
"static": {FloatCustomModule: ObservedCustomModule}
"dynamic": {FloatCustomModule: ObservedCustomModule}
"weight_only": {FloatCustomModule: ObservedCustomModule}
}
"保留属性列表,即使它们在 ``forward`` 中未使用也会持续存在"
此函数主要用于向后兼容,未来可能会被移除
"``"
conf = cls()
for quant_type_name, custom_module_mapping in convert_custom_config_dict.get(
OBSERVED_TO_QUANTIZED_DICT_KEY, {}
).items():
quant_type = _quant_type_from_str(quant_type_name)
for observed_class, quantized_class in custom_module_mapping.items():
conf.set_observed_to_quantized_mapping(
observed_class, quantized_class, quant_type
)
conf.set_preserved_attributes(
convert_custom_config_dict.get(PRESERVED_ATTRIBUTES_DICT_KEY, [])
)
返回配置
[文档] 定义为字典:dict[str, Any]
"""
将此 ``ConvertCustomConfig`` 转换为包含以下项的字典
`torch.ao.quantization.fx.custom_config.ConvertCustomConfig.from_dict` 函数。
"""
d: 字典[str, Any] = {}
for (
quant_type,
observed_to_quantized_mapping,
) 在 self.observed_to_quantized_mapping.items() 中:
if OBSERVED_TO_QUANTIZED_DICT_KEY not in d:
d[OBSERVED_TO_QUANTIZED_DICT_KEY] = {}
d[OBSERVED_TO_QUANTIZED_DICT_KEY][
_get_quant_type_to_str(quant_type)
] = observed_to_quantized_mapping
如果 self.preserved_attributes 的长度大于 0:
d[PRESERVED_ATTRIBUTES_DICT_KEY] = self.preserved_attributes
返回 d
[文档]
类
融合自定义配置:
""
对`:func:`~torch.ao.quantization.quantize_fx.fuse_fx`的定制配置。
演示用法:
fuse_custom_config = FuseCustomConfig().set_preserved_attributes(["attr1", "attr2"])
```python
# 假设输入文本为:
input_text = '"""'
# 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API)
def translate_to_simplified_chinese(text):
# 这里应该调用真实的翻译 API 进行翻译
# 由于示例中不使用真实的 API,以下为模拟翻译结果
return text
# 输出翻译结果
translated_text = translate_to_simplified_chinese(input_text)
print(translated_text)
```
def 初始化(
自身) ->
无:
自身.
保留属性:
列表[
字符串] = []
def __repr__(自身):
非空字典 = {k: v
为 k, v
在
自身.
字典.
项目()
如果
长度(v) > 0}
返回 f
FuseCustomConfig({dict_nonempty})"
[文档] def set_preserved_attributes(self, attributes: list[str]) -> FuseCustomConfig:
"""
设置在图模块中即使未使用也将持久化的属性名称
模型的 ``forward`` 方法。
"""
self.preserved_attributes = attributes
返回 self
# TODO: 删除此行
[文档] @classmethod
def from_dict(cls, fuse_custom_config_dict: dict[str, Any]) -> FuseCustomConfig:
"""
从以下项的字典创建一个 ``ConvertCustomConfig``:
"保留属性列表,即使它们在 `forward` 中未使用也会持续存在"
此函数主要用于向后兼容,未来可能会被移除
""
conf = cls()
conf.set_preserved_attributes(
fuse_custom_config_dict.get(PRESERVED_ATTRIBUTES_DICT_KEY, [])
)
return conf
[文档] def to_dict(self) -> dict[str, Any]:
"""
将此 ``FuseCustomConfig`` 转换为包含以下项的字典。
func:`~torch.ao.quantization.fx.custom_config.ConvertCustomConfig.from_dict`。
"""
d: 字典[str, Any] = {}
if len(self.preserved_attributes) > 0:
d[PRESERVED_ATTRIBUTES_DICT_KEY] = self.preserved_attributes
返回 d