# mypy: 允许未类型化定义
来自
警告
导入
警告
导入
火炬
__all__ = [
"ReLU6 激活函数",
"Hardswish",
"ELU",
"LeakyReLU",
"Sigmoid 激活函数",
"Softmax",
"MultiheadAttention",
"PReLU",
]
[文档]类 ReLU6(torch.nn.ReLU):
应用逐元素函数:
ReLU6(x) = min(max(x0, x), q(6)),其中 x0 是
零点,以及 :math:`q(6)` 是数字 6 的量化表示。
参数:
inplace: 可选在原地执行操作。默认:``False``
形状:
- 输入::math:`(N, *)` 其中 `*` 表示,任何数量的额外
维度
输出::math:`(N, *)`,与输入形状相同
.. 图像:: ../scripts/activation_images/ReLU6.png
示例::
>>> m = nn.quantized.ReLU6()
>>> input = torch.randn(2)
>>> # xdoctest: +SKIP
>>> input = torch.quantize_per_tensor(input, 1.0, 0, dtype=torch.qint32)
>>> output = m(input)
"""
"""
def __init__(self, inplace=False):
super().__init__(inplace)
self.inplace = inplace
def forward(self, input):
return torch.ops.quantized.relu6(input, self.inplace)
def _get_name(self):
return "QuantizedReLU6"
@staticmethod
def from_float(mod, use_precomputed_fake_quant=False):
return ReLU6(mod.inplace)
[文档]class Hardswish(torch.nn.Hardswish):
这是 `torch.nn.Hardswish` 的量化版本。
参数:
scale:输出张量的量化尺度
zero_point:输出张量的量化零点
"""
"""
def __init__(self, scale, zero_point, device=None, dtype=None):
factory_kwargs = {"device": device, "dtype": dtype}
super().__init__()
self.register_buffer("scale", torch.tensor(scale, **factory_kwargs))
self.register_buffer("zero_point", torch.tensor(zero_point, **factory_kwargs))
def forward(self, input):
return torch.ops.quantized.hardswish(input, self.scale, self.zero_point)
def _get_name(self):
return "QuantizedHardswish"
@staticmethod
def from_float(mod, use_precomputed_fake_quant=False):
scale, zero_point = mod.activation_post_process.calculate_qparams()
return Hardswish(float(scale), int(zero_point))
@classmethod
def from_reference(cls, mod, scale, zero_point):
return cls(float(scale), int(zero_point))
[文档]class ELU(torch.nn.ELU):
r"""这是 :class:`~torch.nn.ELU` 的量化等效版本。
Args:
输出张量的量化尺度
zero_point:输出张量的量化零点
alpha:alpha 常数
```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 __init__(self, scale, zero_point, alpha=1.0):
super().__init__(alpha)
self.scale = scale
self.zero_point = zero_point
def forward(self, input):
return torch.ao.nn.quantized.functional.elu(
input, self.scale, self.zero_point, self.alpha
)
def _get_name(self):
return "QuantizedELU"
@staticmethod
def from_float(mod, use_precomputed_fake_quant=False):
scale, zero_point = mod.activation_post_process.calculate_qparams()
return ELU(float(scale), int(zero_point), mod.alpha)
@classmethod
def from_reference(cls, mod, scale, zero_point):
return cls(float(scale), int(zero_point), mod.alpha)
[文档]class LeakyReLU(torch.nn.LeakyReLU):
r"""这是 :class:`~torch.nn.LeakyReLU` 的量化等效版本。
Args:
输出张量的量化尺度
zero_point:输出张量的量化零点
negative_slope: 控制负斜率的倾斜角度。默认值:1e-2
```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 __init__(
self,
scale: float,
zero_point: int,
负斜率:浮点数 = 1e-2,
内置:布尔值 = False,
设备=None,
数据类型=None,
)
-> None:
factory_kwargs = {"device": device, "dtype": dtype}
super().__init__(negative_slope, inplace)
self.register_buffer("scale", torch.tensor(scale, **factory_kwargs))
self.register_buffer("zero_point", torch.tensor(zero_point, **factory_kwargs))
def forward(self, input):
return torch.ops.quantized.leaky_relu(
input, self.negative_slope, self.inplace, self.scale, self.zero_point
)
def _get_name(self):
return "QuantizedLeakyReLU"
@classmethod
def from_float(cls, mod, use_precomputed_fake_quant=False):
scale, zero_point = mod.activation_post_process.calculate_qparams()
return cls(float(scale), int(zero_point), mod.negative_slope, mod.inplace)
@classmethod
def from_reference(cls, mod, scale, zero_point):
return cls(float(scale), int(zero_point), mod.negative_slope, mod.inplace)
[文档]class Sigmoid(torch.nn.Sigmoid):
r"""这是 :class:`~torch.nn.Sigmoid` 的量化等效版本。"""
Args:
scale: 输出张量的量化尺度
输出张量的量化零点:量化输出张量的零点
""
def __init__(self, output_scale: float, output_zero_point: int):
super().__init__()
self.output_scale = output_scale
self.output_zero_point = output_zero_point
def forward(self, input):
return torch.ops.quantized.sigmoid(
输入,self.output_scale,self.output_zero_point
)
@classmethod
def from_float(cls, mod, use_precomputed_fake_quant=False):
(
输出比例
输出零点
) = mod.activation_post_process.calculate_qparams()
返回 cls(float(output_scale), int(output_zero_point))
类 Softmax(
火炬.nn.Softmax):
r这是 :class:`~torch.nn.Softmax` 的量化版本。
参数:
dim: Softmax 将要计算的维度(因此沿 dim 的每个切片都将求和为 1)。
输出张量的量化尺度
输出张量的量化零点
```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)
```
定义
初始化(
自身,
暗淡=
无,
比例=1.0,
零点=0):
超级().
初始化()
自身.
维度 =
维度
自身.
缩放 =
缩放
自身.
零点 =
零点
定义
前向(
自身,
输入):
维度 =
自身.
维度
如果
维度
是
无:
栈级别 = 3
# 注意:在 _get_softmax_dim 上添加 mypy 忽略似乎不那么糟糕
将 `_get_softmax_dim` 设为一个官方 API。
维度 =
火炬.nn.
功能性._get_softmax_dim(
# 类型: 忽略[attr-defined]
"softmax", 输入.
暗淡(),
栈级别
)
返回
火炬.
操作.
量化.
软式最大化(
输入,
暗淡,
自身.
比例,
自身.
零点)
定义
_获取名称(
自身):
返回
量化 softmax
@staticmethod
定义
从浮点数(mod,
使用预计算的假量化=
错误):
比例,
零点 = mod.
激活后处理.
计算 q 参数()
返回 Softmax(mod.
暗淡, float(
比例), int(
零点))
@classmethod
定义
来自参考(
类, mod,
比例,
零点):
返回
类(mod.
暗淡, float(
比例), int(
零点))
类
多头注意力(
火炬.ao.nn.
可量化的.
多头注意力):
浮点模块 =
火炬.ao.nn.
可量化的.
多头注意力
定义
_获取名称(
自身):
返回
"量化多头注意力"
@classmethod
定义
从浮点数(
类,
其他):
整个流程是浮点数 -> 观察到 -> 量化
# 此类仅从观察到的转换为量化
抛出异常
不支持的操作异常(
"看起来您正在尝试转换一个 "
"未观察到的 MHA 模块。请参阅"
"可量化的 MHA 示例。"
)
@classmethod
定义
来自观察(
类,
其他):
转换 =
火炬.ao.
量化.
转换(
其他,
映射=
无,
内置=
错误,
移除 qconfig=True,
转换自定义配置字典=
无,
)
转换.
类 =
类
# 移除 bias_k 和 bias_v 的参数以进行量化
# TODO: 这可能是准确度下降的潜在原因。
# 离散猫取第一个元素的尺度(scale)和 zp,这可能会在 bias_k
# 和 bias_v(它们与 k/v 一起被 cat)中丢失精度。
# 以及 bias_v(它们与 k/v 一起被 cat)中丢失精度。
如果
转换.
偏差_k
是 not
无:
偏差_k =
转换.
参数.
弹出(
"偏置_k")
sc, zp = 火炬.
_根据张量选择_qparams(
偏置_k,
范围缩减=
错误)
偏差_k =
火炬.
按张量量化(
偏置_k, sc, zp,
火炬.quint8)
setattr(转换,
"偏置_k",
偏置_k)
# 无需注意:B010
如果
转换.
偏置_v
是 not
无:
偏置_v =
转换.
参数.
弹出(
"偏差_v")
sc, zp = 火炬.
_根据张量选择_qparams(
偏置_k,
范围缩减=
假 # type: ignore[possibly-undefined]
)
偏置_v =
火炬.
按张量量化(
偏置_v, sc, zp,
火炬.quint8)
setattr(转换,
"偏差_v",
偏置_v)
# 无需注意:B010
删除
转换.
投影权重
删除
转换.in_proj_bias
返回
转换
类 PReLU(
火炬.nn.
模块):
r这是 `~torch.nn.PReLU` 的量化等效形式。
参数:
输出张量的量化尺度
输出张量的量化零点
参数数量:参数数量:1,或输入通道数。默认:1
```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)
```
定义
初始化(
自身,
输出尺度: float,
输出零点: int, num_parameters:
整型 = 1
) -> 无:
超级().
初始化()
自身.
参数数量 =
参数数量
自身.
缩放 =
输出比例
自身.
零点 =
输出零点
w = 火炬.randn(num_parameters,
数据类型=
火炬.float)
qw = 火炬.
按张量量化(w,
比例=1.0,
零点=0,
数据类型=
火炬.quint8)
自身.
设置权重(qw)
定义
设置权重(
自身, w:
火炬.
张量) ->
无:
自身.
权重 = w
定义
前向(
自身,
输入:
火炬.
张量) ->
火炬.
张量:
返回
火炬.
操作.
量化.
预激活函数(
输入,
自身.
重量,
自身.
比例,
自身.
零点
)
定义
_获取名称(
自身):
返回
量化 PReLU
@classmethod
定义
从浮点数(
类, mod,
使用预计算的假量化=
错误):
比例,
零点 = mod.
激活后处理.
计算 q 参数()
qprelu = 类(float(
比例), int(
零点), mod.num_parameters)
float_wt = mod.重量.float()
观察者 = mod.qconfig.
重量()
观察者(
浮点权重)
如果
观察者.dtype !=
火炬.quint8:
警告(
f"PReLU 的权重观察器应具有 quint8 数据类型,但得到了"{
观察者.
数据类型}"
)
重量比例, wt_zp =
观察者.
计算 q 参数()
权重 =
火炬.
按张量量化(
浮点权重, float(
重量比例), int(wt_zp),
火炬.
无符号 8 位整数
)
qprelu.设置权重(
权重)
返回 qprelu
@classmethod
定义
来自参考(
类, mod,
比例,
零点):
qprelu = 类(float(
比例), int(
零点), mod.num_parameters)
float_wt = mod.重量.float()
观察者 = mod.qconfig.
重量()
观察者(
浮点权重)
如果
观察者.dtype !=
火炬.quint8:
警告(
f"PReLU 的权重观察器应具有 quint8 数据类型,但得到了"{
观察者.
数据类型}"
)
重量比例, wt_zp =
观察者.
计算 q 参数()
权重 =
火炬.
按张量量化(
浮点权重, float(
重量比例), int(wt_zp),
火炬.
无符号 8 位整数
)
qprelu.设置权重(
权重)
返回 qprelu