torch.ao.nn.quantized.dynamic.modules.linear 的源代码
# mypy: 允许未类型化定义
导入
火炬
导入 torch.ao.nn.intrinsic
作为 nni
导入 torch.ao.nn.quantized
作为 nnq
来自 torch.ao.nn.quantized.modules.utils
导入 _quantize_weight
__all__ = [
"线性",
]
[文档]
类
线性(
氮气.
线性):
r""
以浮点张量作为输入和输出的动态量化线性模块。
我们采用与 `torch.nn.Linear` 相同的接口,请参阅文档。
https://pytorch.org/docs/stable/nn.html#torch.nn.Linear 查看文档。
与 :class:`torch.nn.Linear` 相似,属性将被随机
权重(Tensor):模块的非可学习量化权重
属性:
weight (Tensor):该模块的非可学习量化权重,形状为
形状 :math:`(\text{out\_features}, \text{in\_features})`.
bias (Tensor):该模块的非可学习浮点偏置,形状为
math:`(\text{out\_features})`。如果 :attr:`bias` 为 ``True``,
这些值被初始化为零。
示例:
>>> # xdoctest: +SKIP
>>> m = nn.quantized.dynamic.Linear(20, 30)
>>> input = torch.randn(128, 20)
>>> output = m(input)
>>> 打印(output.size())
torch.Size([128, 30])
```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)
```
# 本类中使用的版本与父类 nnq.Linear 不同
_version = 4
定义
初始化(
自身,
输入特征,
输出特征,
偏差=True,
数据类型=
火炬.qint8):
超级().
初始化(
输入特征,
输出特征,
偏差,
数据类型=
数据类型)
我们在这里不与缓冲区或属性等纠缠
为了保持模块简单,*一切*都只是 Python 属性
序列化逻辑在下面的序列化和反序列化模块中显式处理
模块中进行
自身.
版本 = 4
定义
前向(
自身, x):
# 注意,我们可以处理 self.bias == None 的情况
如果
自身._packed_params.dtype ==
火炬.qint8:
如果
自身.
版本
是 None
或
自身.
版本 < 4:
Y = 火炬.
操作.
量化.
线性动态(
x, 自身._packed_params._packed_params
)
否则:
Y = 火炬.
操作.
量化.
线性动态(
x, 自身._packed_params._packed_params,
范围缩减=
真实
)
elif 自身._packed_params.dtype ==
火炬.float16:
Y = 火炬.
操作.
量化.
线性动态浮点 16 位(
x, 自身._packed_params._packed_params
)
否则:
抛出异常
运行时错误(
"在动态量化线性中不支持数据类型!")
返回 Y.
到(x.
数据类型)
定义
_获取名称(
自身):
返回
动态量化线性
定义
额外表示(
自身):
extra_repr_str = fin_features={
自身.
输入特征}, out_features={
自身.
输出特征}
, 数据类型={
自身._packed_params.
数据类型}"
如果
自身._packed_params.dtype ==
火炬.qint8:
extra_repr_str += f", 协议方案="{
自身.
重量().
q 方案()}"
返回 extra_repr_str
定义
从状态字典加载(
自身,
state_dict,
前缀,
本地元数据,
严格的,
缺少键,
预期之外的键,
错误信息,
):
版本 =
本地元数据.
获取(
版本,
无)
自身.
版本 =
版本
超级().
从状态字典加载(
state_dict,
前缀,
本地元数据,
错误,
缺少键,
预期之外的键,
错误信息,
)
[文档] @类方法
def from_float(cls, mod, use_precomputed_fake_quant=False):
r"""从浮点模块或 qparams_dict 创建一个动态量化模块
Args:
mod (模块): 一个浮点模块,可以是 torch.ao.quantization
utilities 生成的,或者由用户提供的
"""
float_modules = [
torch.nn.Linear
torch.nn.modules.linear.NonDynamicallyQuantizableLinear
torch.ao.nn.intrinsic.modules.fused.LinearReLU
torch.ao.nn.qat.dynamic.Linear,
]
assert (
type(mod) in float_modules
), “nn.quantized.dynamic.Linear.from_float 仅适用于以下之一” + str(
[float_mod.__name__ for float_mod in float_modules]
)
assert hasattr(mod, "qconfig"), "输入浮点模块必须定义 qconfig"
如果类型(mod)等于 nni.LinearReLU:
mod = mod[0]
如果 mod.qconfig 不是 None 并且 mod.qconfig.weight 不是 None:
weight_observer = mod.qconfig.weight()
否则:
我们如果在文件开头导入 qconfig,就会遇到循环导入问题:
# https://github.com/pytorch/pytorch/pull/24231. 当前的解决方案是推迟
导入直到我们需要为止。
从 torch.ao.quantization.qconfig 导入 default_dynamic_qconfig
weight_observer = default_dynamic_qconfig.weight()
dtype = weight_observer.dtype
assert dtype in [torch.qint8, torch.float16], (
"仅支持的数据类型为 "
动态量化线性层支持的类型为 qint8 和 float16,获取到:{dtype}
)
weight_observer(mod.weight)
if dtype == torch.qint8:
qweight = _quantize_weight(mod.weight.float(), weight_observer)
elif dtype == torch.float16:
qweight = mod.weight.float()
else:
raise RuntimeError(
"指定的动态量化线性不支持的数据类型!"
)
qlinear = cls(mod.in_features, mod.out_features, dtype=dtype)
qlinear.set_weight_bias(qweight, mod.bias)
return qlinear
[文档] @类方法
def from_reference(cls, ref_qlinear):
"""从参考量化模块创建一个(fbgemm/qnnpack)动态量化模块
模块
Args:
ref_qlinear (模块): 一个引用的量化模块,可以是 torch.ao.quantization 函数生成的,或者由用户提供的
torch.ao.quantization 函数生成的,或者由用户提供的
"""
qlinear = cls(
ref_qlinear.in_features,
ref_qlinear.out_features,
dtype=ref_qlinear.weight_dtype,
)
qweight = ref_qlinear.get_quantized_weight()
bias = ref_qlinear.bias
qlinear.set_weight_bias(qweight, bias)
返回 qlinear