# mypy: 允许未类型化装饰器
# mypy: 允许未类型化定义
导入
数字
导入
警告
来自 typing_extensions
导入
已弃用
导入
火炬
导入 torch.nn
作为
然后
来自
火炬
导入
张量 # noqa: F401
来自 torch._jit_internal
导入
字典,
列表,
可选,
元组,
联合 # noqa: F401
来自 torch.ao.nn.quantized.modules.utils
导入 _quantize_weight
来自 torch.nn.utils.rnn
导入 PackedSequence
__all__ = [
pack_weight_bias,
PackedParameter,
RNNBase,
"长短期记忆网络",
"门控循环单元",
"RNNCellBase",
RNN 单元,
LSTM 单元,
GRU 单元,
应用置换,
]
定义
应用置换(
张量:
张量,
置换:
张量,
暗淡:
整型 = 1) ->
张量:
返回
张量.
索引选择(
暗淡,
置换)
@deprecated(
"`apply_permutation` 已弃用,请使用 `tensor.index_select(dim, permutation)` 代替",
分类=
未来警告,
)
定义 apply_permutation(
张量:
张量,
置换:
张量,
暗淡:
整型 = 1) ->
张量:
返回
应用置换(
张量,
置换,
暗淡)
定义
打包权重偏差(
权重,
偏置,
数据类型):
如果 dtype ==
火炬.qint8:
# 对于每一层,对于每个方向,我们需要进行量化和打包
# 按此顺序打包权重和参数:
#
# w_ih, w_hh
包装重量 =
火炬.
操作.
量化.
线性预打包(
权重,
偏置)
返回
包装重量
否则:
# 对于每一层,对于每个方向,我们需要进行量化和打包
权重和打包参数的顺序如下:
#
打包的输入隐藏层权重、打包的隐藏层隐藏层权重、输入隐藏层偏置、隐藏层隐藏层偏置
打包的权重 =
火炬.
操作.
量化.
线性预打包 fp16(
权重,
偏置)
返回
打包的权重
类 PackedParameter(
火炬.nn.
模块):
定义
初始化(
自身,
参数):
超级().
初始化()
自身.
参数 =
参数
定义
保存到状态字典(
自身,
目的地,
前缀,
保留变量):
超级().
保存到状态字典(
目的地,
前缀,
保留变量)
目的地[
前缀 +
参数] =
自身.
参数
定义
从状态字典加载(
自身,
state_dict,
前缀,
本地元数据,
严格的,
缺少键,
预期之外的键,
错误信息,
):
自身.
参数 = state_dict[
前缀 +
参数]
超级().
从状态字典加载(
state_dict,
前缀,
本地元数据,
错误,
缺少键,
预期之外的键,
错误信息,
)
类 RNNBase(
火炬.nn.
模块):
浮点模块 = nn.RNNBase
_version = 2
定义
初始化(
自身,
模式,
输入大小,
隐藏层大小,
层数=1,
偏置=True,
批量优先=
错误,
dropout=0.0,
双向的=
错误,
数据类型=
火炬.qint8,
):
超级().
初始化()
自身.
模式 =
模式
自身.
输入大小 =
输入大小
自身.hidden_size = hidden_size
自身.
层数 =
层数
自身.
偏差 =
偏差
自身.
批量优先 =
批量优先
自身.dropout = float(dropout)
自身.
双向 =
双向
自身.dtype = dtype
自身.
版本 = 2
自身.
训练 =
假
方向数量 = 2
如果
双向
否则 1
# "type: ignore" 是必需的,因为整数和数字不完全可比较
# https://github.com/python/mypy/issues/8566
如果 (
not isinstance(dropout, 数字.
数字)
或 not 0
≤ dropout
≤ 1 # type: ignore[operator]
或 isinstance(dropout,
布尔)
):
抛出异常 ValueError(
"dropout 应该是一个在 [0, 1] 范围内的数字"
表示一个元素被置零的概率
零化
)
如果 dropout > 0
和
层数 == 1: # type: ignore[operator]
warnings.警告(
"dropout 选项在所有层之后添加 dropout,但最后一个层除外,因此非零 dropout 期望"
"循环层之后,所以非零 dropout 期望"
f"num_layers 的值大于 1,但得到了 dropout="{dropout}
和
f"num_layers="{
层数}"
)
如果
模式 ==
"长短期记忆网络":
网格大小 = 4 * hidden_size
elif 模式 ==
"门控循环单元":
网格大小 = 3 * hidden_size
否则:
抛出异常 ValueError(
识别不到的 RNN 模式: +
模式)
所有权重值 = []
为
层
在
范围(
层数):
为 _
在
范围(
方向数量):
层输入大小 = (
输入大小
如果
层 == 0
否则 hidden_size *
方向数量
)
w_ih = 火炬.randn(
网格大小,
层输入大小).
到(
火炬.float)
网格_hh =
火炬.randn(
网格大小,
隐藏层大小).
到(
火炬.float)
b_ih = 火炬.randn(
网格大小).
到(
火炬.float)
b_hh = 火炬.randn(
网格大小).
到(
火炬.float)
如果 dtype ==
火炬.qint8:
w_ih = 火炬.
按张量量化(
我_ih,
比例=0.1,
零点=0,
数据类型=
火炬.qint8
)
网格_hh =
火炬.
按张量量化(
我_hh,
比例=0.1,
零点=0,
数据类型=
火炬.qint8
)
包装输入高度 =
火炬.
操作.
量化.
线性预打包(
我_ih,
你_ih)
打包_hh =
火炬.
操作.
量化.
线性预打包(
我_hh,
你_hh)
如果
自身.
版本
是 None
或
自身.
版本 < 2:
单元参数 = (
火炬.
操作.
量化.
使量化单元参数动态化(
压缩输入隐藏状态,
压缩隐藏状态,
你_ih, b_hh
)
)
否则:
单元参数 = (
火炬.
操作.
量化.
使量化单元参数动态化(
压缩输入隐藏状态,
压缩隐藏状态,
你_ih,
你_hh,
真实
)
)
否则:
packed_ih = 火炬.
操作.
量化.
线性预打包 fp16(
我_ih,
你_ih)
packed_hh = 火炬.
操作.
量化.
线性预打包 fp16(
我_hh,
你_hh)
cell_params = 火炬.
操作.
量化.make_quantized_cell_params_fp16(
压缩输入隐藏状态,
打包_hh
)
所有重量值.
追加(
打包参数(
单元参数))
自身.
所有权重值 =
火炬.nn.
模块列表(
所有权重值)
定义
_获取名称(
自身):
返回
动态量化 RNN
定义
额外表示(
自身):
s = "{输入大小},
{隐藏层大小}"
如果
自身.
层数 != 1:
s += ", num_layers="
{层数}"
如果
自身.
偏差
是 not True:
s += ", 偏置="
{偏置}"
如果
自身.
批量优先
是 not
错误:
s += ", batch_first="{batch_first}"
如果
自身.dropout != 0:
s += ", dropout="{dropout}"
如果
自身.
双向
是 not
错误:
s += ", 双向="
{双向}"
返回 s.
格式(**
自身.
字典)
定义 __repr__(
自身):
# 我们不想显示`ModuleList`子项,因此自定义
`__repr__`。这与 nn.Module.__repr__相同,除了检查
`PackedParameter`和`nn.ModuleList`。
你仍然应该重写`extra_repr`来添加更多信息。
额外行 = []
额外表示 =
自身.
额外表示()
# 空字符串将被分割成列表 ['']
如果
额外表示:
额外行 =
额外表示.
分割("
输入文本翻译为简体中文为:\n")
子行 = []
为
键,
模块
在
自身.
模块.
项目():
如果 isinstance(
模块, (PackedParameter, nn.
模块列表)):
继续
mod_str = 表示(
模块)
mod_str = nn.模块.
模块._addindent(mod_str, 2)
子行.
追加(
“(” + key + "): " + mod_str)
行 =
额外行 +
子行
主字符串 =
自身.
_获取名称() +
“(”
如果
行:
# 简单的一行信息,大多数内置模块都会使用
如果
长度(
额外行) == 1
和 not
子行:
主字符串 +=
额外行[0]
否则:
主字符串 += "
输入文本翻译为简体中文为:\n " + "
输入文本翻译为简体中文为:\n ".
加入(
行) + "
输入文本翻译为简体中文为:\n"
主字符串 +=
)"
返回
主字符串
定义
检查输入(
自身,
输入:
张量, batch_sizes:
可选[
张量]) ->
无:
预期输入维度 = 2
如果
批大小
是 not None
否则 3
如果
输入.
暗淡() !=
期望的输入维度:
抛出异常
运行时错误(
f"输入必须具有"{
期望的输入维度}
维度,实际得到{
输入.
暗淡()}"
)
如果
自身.
输入大小 !=
输入.
尺寸(-1):
抛出异常
运行时错误(
f"input.size(-1)必须等于 input_size。期望"{
自身.
输入大小}
,获得{
输入.
尺寸(-1)}"
)
定义
获取期望的隐藏尺寸(
自身,
输入:
张量, batch_sizes:
可选[
张量]
) -> 元组[int, int, int
]
如果
批大小
是 not
无:
小批量 = int(batch_sizes[0])
否则:
小批量 =
输入.
尺寸(0)
如果
自身.
批量优先
否则
输入.
尺寸(1)
方向数量 = 2
如果
自身.
双向
否则 1
预期隐藏大小 = (
自身.
层数 *
方向数量,
微批,
自身.
隐藏层大小,
)
返回
预期隐藏大小
定义
检查隐藏层大小(
自身,
hx: 张量,
预期隐藏大小:
元组[int, int, int
]
信息:
字符串 =
预期隐藏大小{}
,获得{}",
) -> 无:
如果 hx.
尺寸() !=
预期隐藏大小:
抛出异常
运行时错误(
信息.
格式(
预期隐藏大小,
列表(hx.
尺寸())))
定义
检查前向参数(
自身,
输入:
张量,
隐藏:
张量, batch_sizes:
可选[
张量]
) -> 无:
自身.
检查输入(
输入, batch_sizes)
预期隐藏大小 =
自身.
获取期望的隐藏尺寸(
输入, batch_sizes)
自身.
检查隐藏层大小(
隐藏,
预期隐藏大小,
信息=
预期隐藏大小{}
,获得{}"
)
定义
打乱隐藏状态(
自身, hx:
张量,
置换:
可选[
张量]) ->
张量:
如果
排列
是
无:
返回 hx
返回
应用置换(hx,
置换)
定义
从状态字典加载(
自身,
state_dict,
前缀,
本地元数据,
严格的,
缺少键,
预期之外的键,
错误信息,
):
版本 =
本地元数据.
获取(
版本,
无)
自身.
版本 =
版本
超级().
从状态字典加载(
state_dict,
前缀,
本地元数据,
错误,
缺少键,
预期之外的键,
错误信息,
)
定义
设置权重偏差(
自身,
权重偏差字典):
定义
权重偏差名称(ihhh,
层,
后缀):
权重名称 = f
重量{
呜呜}
下划线{
层}{
后缀}"
偏置名称 = f
偏差_{ihhh}_l{
层}{
后缀}"
返回
权重名称,
偏差名称
方向数量 = 2
如果
自身.
双向
否则 1
# TODO: 在 RNNBase 的__init__中去重
所有权重值 = []
为
层
在
范围(
自身.
层数):
为
方向
在
范围(
方向数量):
后缀 = "_reverse"
如果
方向 == 1
否则
请提供需要翻译的文本
w_ih 名称, b_ih_name = weight_bias_name("ih",
层,
后缀)
w_hh_name, b_hh_name = weight_bias_name(hh,
层,
后缀)
w_ih = weight_bias_dict[网络层名称]
b_ih = 权重偏置字典[
隐藏层名称]
网格_hh =
权重偏置字典[
系统名称]
b_hh = 权重偏差字典[
b_hh 名称]
如果
我_ih.dtype ==
火炬.qint8:
紧凑的 ih =
火炬.
操作.
量化.
线性预打包(
我_ih,
你_ih)
压缩_hh =
火炬.
操作.
量化.
线性预打包(
我_hh,
你_hh)
如果
自身.
版本
是 None
或
自身.
版本 < 2:
单元参数 = (
火炬.
操作.
量化.
使量化单元参数动态化(
压缩输入隐藏状态,
压缩隐藏状态,
你_ih, b_hh
)
)
否则:
单元参数 = (
火炬.
操作.
量化.
动态化量化单元参数(
压缩输入隐藏状态,
压缩隐藏状态,
你_ih,
你_hh,
真实
)
)
否则:
紧凑输入门 =
火炬.
操作.
量化.
线性预打包 fp16(
我_ih,
你_ih)
紧凑隐藏门 =
火炬.
操作.
量化.
线性预打包 fp16(
我_hh,
你_hh)
单元参数 =
火炬.
操作.
量化.make_quantized_cell_params_fp16(
压缩输入隐藏状态, packed_hh
)
_all_weight_values.追加(PackedParameter(
单元参数))
自身.
_所有权重值 =
火炬.nn.
模块列表(
_所有权重值)
@classmethod
定义
从浮点数(
类, mod,
使用预计算的假量化=
错误):
断言
类型(mod)
在 {
火炬.nn.
长短期记忆网络,
火炬.nn.GRU,
}, "nn.quantized.dynamic.RNNBase.from_float 仅适用于 nn.LSTM 和 nn.GRU"
断言
有属性(mod,
qconfig),
输入浮点模块必须定义 qconfig
如果 mod.qconfig
是 not None
和 mod.qconfig.
权重
是 not
无:
weight_observer_method = mod.qconfig.权重
否则:
如果我们在文件开头导入 qconfig,将出现循环导入问题:
# https://github.com/pytorch/pytorch/pull/24231. 当前的解决方案是推迟导入,直到需要它。
#
来自 torch.ao.quantization.qconfig
导入 default_dynamic_qconfig
权重观察者方法 =
默认动态 Q 配置.
权重
dtype = 权重观察者方法().dtype
支持的标量类型 = [
火炬.qint8,
火炬.float16]
如果 dtype not
在
支持的标量类型:
抛出异常
运行时错误(
f不支持动态 RNN 量化的数据类型:{
数据类型}"
)
RNNBase 可以是 LSTM 或 GRU
qRNNBase: 联盟[
长短期记忆网络, GRU]
如果 mod.
模式 ==
"长短期记忆网络":
qRNNBase = 长短期记忆网络(
mod.输入大小,
mod.隐藏层大小,
mod.层数,
mod.偏置,
mod.批量优先,
mod.dropout,
mod.双向的,
数据类型,
)
elif mod.模式 ==
"门控循环单元":
qRNNBase = GRU(
mod.输入大小,
mod.隐藏层大小,
mod.层数,
mod.偏置,
mod.批量优先,
mod.dropout,
mod.双向的,
数据类型,
)
否则:
抛出异常
不支持的操作异常(
目前仅支持 LSTM/GRU 进行 QuantizedRNN 量化
)
方向数量 = 2
如果 mod.
双向
否则 1
断言 mod.
偏差
_所有权重值 = []
为
层
在
范围(qRNNBase.
层数):
为
方向
在
范围(
方向数量):
后缀 = "_reverse"
如果
方向 == 1
否则
请提供需要翻译的文本
定义
检索权重偏差(ihhh):
权重名称 = f
"权重_{ihhh}
__l{
层}{
后缀}"
偏差名称 = f
"偏差_"{
嗡嗡嗡}
下划线{
层}{
后缀}"
权重 = getattr(mod,
重量名称)
偏差 = getattr(mod,
偏差名称)
返回
重量,
偏差
输入层权重,
偏置_ih =
检索权重偏差(
ih)
weight_hh, 偏置_hh =
检索权重偏差(
hh)
如果 dtype ==
火炬.qint8:
定义
量化打包(w, b):
重量观察者 =
权重观察者方法()
重量观察者(w)
权重 = _quantize_weight(w.float(),
重量观察者)
打包权重 =
火炬.
操作.
量化.
线性预打包(
权重, b)
返回
包装重量
包装输入高度 =
量化打包(
输入层权重,
偏差_ih)
包装高度高度 =
量化打包(weight_hh,
隐藏层偏置)
如果 qRNNBase.
版本
是 None
或 qRNNBase.
版本 < 2:
单元参数 = (
火炬.
操作.
量化.
动态化量化单元参数(
压缩输入隐藏状态,
压缩隐藏状态,
偏差_ih,
偏置_hh
)
)
否则:
单元参数 = (
火炬.
操作.
量化.
动态化量化单元参数(
压缩输入隐藏状态,
压缩隐藏状态,
偏差_ih,
隐藏层偏置,
真实
)
)
elif dtype == 火炬.float16:
紧凑的输入隐藏层 =
火炬.
操作.
量化.
线性预打包 fp16(
输入层权重.float(),
偏置_ih
)
packed_hh = 火炬.
操作.
量化.
线性预打包 fp16(
weight_hh.float(), 偏置_hh
)
单元参数 =
火炬.
操作.
量化.
创建量化单元参数 fp16(
压缩输入隐藏状态, packed_hh
)
否则:
抛出异常
运行时错误(
"指定的动态量化 LSTM 数据类型不受支持!"
)
_所有权重值.
追加(
打包参数(
单元参数))
qRNNBase._all_weight_values = 火炬.nn.
模块列表(_all_weight_values)
返回 qRNNBase
定义
权重偏置(
自身):
返回权重和偏差的字典
weight_bias_dict: 字典[
字符串,
字典] = {
权重: {},
偏置: {}}
计算 = 0
方向数量 = 2
如果
自身.
双向
否则 1
为
层
在
范围(
自身.
层数):
为
方向
在
范围(
方向数量):
后缀 = "_reverse"
如果
方向 == 1
否则
请提供需要翻译的文本
key_name1 = fweight_ih_l{
层}{
后缀}"
key_name2 = fweight_hh_l{
层}{
后缀}"
# 紧凑权重是 torchbind 类中的 CellParamsSerializationType 的一部分
# 在紧凑权重类中,权重和偏置可以作为 Tensors 访问
压缩权重偏差 =
自身.
_所有权重值[
忽略索引
计算
].参数.__getstate__()[0
]
[4]
权重偏差字典[
权重
]
[键名 1] =
压缩权重偏差[
0
].__getstate__()[0
]
[0]
权重偏差字典[
权重
]
[键名 2] =
压缩权重偏差[
1
].__getstate__()[0
]
[0]
key_name1 = fbias_ih_l{
层}{
后缀}"
key_name2 = fbias_hh_l{
层}{
后缀}"
weight_bias_dict[偏置
]
[key_name1] = 压缩权重偏差[
0
].__getstate__()[0
]
[1]
权重偏差字典[
偏置
]
[键名 2] =
压缩权重偏差[
1
].__getstate__()[0
]
[1]
计算 =
计算 + 1
返回
权重偏差字典
定义
获取权重(
自身):
返回
自身.
权重偏置()[
权重]
定义
获取偏差(
自身):
返回
自身.
权重偏置()[
偏置]
[文档]
类
长短期记忆网络(RNNBase):
r""
一种动态量化 LSTM 模块,输入和输出为浮点张量。
我们采用与 `torch.nn.LSTM` 相同的接口,请参阅
https://pytorch.org/docs/stable/nn.html#torch.nn.LSTM 以获取文档。
示例:
>>> # xdoctest: +SKIP
>>> rnn = nn.LSTM(10, 20, 2)
>>> input = torch.randn(5, 3, 10)
>>> h0 = torch.randn(2, 3, 20)
>>> c0 = torch.randn(2, 3, 20)
输出,(hn,cn) = rnn(input, (h0,c0))
```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)
```
浮点模块 = nn.LSTM
__重载__ = {
前进: ["forward_packed",
前向张量]}
定义
初始化(
自身, *
参数, **kwargs):
超级().
初始化(
"长短期记忆网络", *
参数, **kwargs)
定义
_获取名称(
自身):
返回
动态量化 LSTM
定义 forward_impl(
自身,
输入:
张量,
hx: 可选[
元组[
张量,
张量]],
batch_sizes: 可选[
张量
]
最大批量大小: int,
排序索引:
可选[
张量
]
) -> 元组[
张量,
元组[
张量,
张量
]]
如果 hx
是
无:
方向数量 = 2
如果
自身.
双向
否则 1
零值 =
火炬.
零(
自身.
层数 *
方向数量,
最大批量大小,
自身.
隐藏层大小,
数据类型=
输入.
数据类型,
设备=
输入.
设备,
)
hx = (零,
零)
否则:
每个隐藏状态的批次应与用户认为他/她正在传递的输入序列相匹配。
用户认为他/她正在传递的输入序列。
hx = 自身.
打乱隐藏状态(hx,
排序索引)
自身.
检查前向参数(
输入, hx, batch_sizes)
所有参数 = [m.
参数
为 m
在
自身.
所有权重值]
如果
批大小
是
无:
结果 =
火炬.
量化 LSTM(
输入,
hx,
_所有参数,
自身.
偏置,
自身.
层数,
float(自身.dropout),
自身.
训练,
自身.
双向的,
自身.
批量优先,
数据类型=
自身.
数据类型,
使用动态=True,
)
否则:
结果 =
火炬.
量化 LSTM(
输入,
batch_sizes,
hx,
_所有参数,
自身.
偏置,
自身.
层数,
float(自身.dropout),
自身.
训练,
自身.
双向的,
数据类型=
自身.
数据类型,
使用动态=True,
)
输出 =
结果[0]
隐藏 =
结果[1
]
返回
输出,
隐藏
@torch.算子.
导出
定义
前向张量(
自身,
输入:
张量, hx:
可选[
元组[
张量,
张量]] = None
) -> 元组[
张量,
元组[
张量,
张量
]]
批大小 = None
最大批量大小 =
输入.
尺寸(0)
如果
自身.
批量优先
否则
输入.
尺寸(1)
排序索引 = None
未排序索引 = None
输出,
隐藏 =
自身.forward_impl(
输入, hx, batch_sizes,
最大批量大小,
排序索引
)
返回
输出,
自身.
打乱隐藏状态(
隐藏,
未排序的索引)
@torch.算子.
导出
定义 forward_packed(
自身,
输入: PackedSequence, hx:
可选[
元组[
张量,
张量]] = None
) -> 元组[PackedSequence,
元组[
张量,
张量
]]
输入_, batch_sizes,
排序索引,
未排序索引 =
输入
最大批量大小 = int(batch_sizes[0])
输出_,
隐藏 =
自身.forward_impl(
输入_, hx, batch_sizes,
最大批量大小,
排序索引
)
输出 = PackedSequence(
输出_, batch_sizes,
排序索引,
未排序的索引)
返回
输出,
自身.
打乱隐藏状态(
隐藏,
未排序的索引)
由于问题 #43072 需要 "type: ignore"
定义
打乱隐藏状态(
# 类型:忽略[覆盖]
自身,
hx: 元组[
张量,
张量
]
置换:
可选[
张量
]
) -> 元组[
张量,
张量
]:
如果
排列
是
无:
返回 hx
返回
应用置换(hx[0
]
置换),
应用置换(
hx[1]
排列
)
# "type: ignore" 由于问题 #43072 需要忽略类型检查
定义
检查前向参数(
# 类型:忽略[覆盖]
自身,
输入:
张量,
隐藏:
元组[
张量,
张量
]
batch_sizes: 可选[
张量
]
) -> 无:
自身.
检查输入(
输入, batch_sizes)
预期隐藏大小 =
自身.
获取期望的隐藏尺寸(
输入, batch_sizes)
自身.
检查隐藏层大小(
隐藏[0
]
预期隐藏大小,
预期隐藏层[0]大小{}
,获得{}"
)
自身.
检查隐藏层大小(
隐藏[1
]
预期隐藏大小,
预期隐藏[1]大小{}
,获得{}"
)
@torch.算子.
忽略
定义
前向(
自身,
输入, hx=
无):
如果 isinstance(
输入, PackedSequence):
返回
自身.forward_packed(
输入, hx)
否则:
返回
自身.
前向张量(
输入, hx)
@classmethod
定义
从浮点数(
类, mod,
使用预计算的假量化=
错误):
返回
超级().
从浮点数(
mod, 使用预计算的假量化=
使用预计算的假量化
)
@classmethod
定义
来自参考(
类, ref_mod):
断言
有属性(ref_mod, "weight_ih_l0_dtype"),
"我们假设 weight_ih_l0"
"存在于 LSTM 中,可能需要放宽假设以支持该用例"
qmod = 类(
ref_mod.输入大小,
ref_mod.隐藏层大小,
ref_mod.层数,
ref_mod.偏置,
ref_mod.批量优先,
ref_mod.dropout,
ref_mod.双向的,
# 假设存在层 0,这应该没问题
ref_mod.weight_ih_l0_dtype,
)
qmod.设置权重偏差(ref_mod.get_quantized_weight_bias_dict())
返回 qmod
[文档]
类 GRU(RNNBase):
r将多层门控循环单元(GRU)RNN 应用于输入序列。
对于输入序列中的每个元素,每一层计算以下函数:
函数:
.. math::
\begin{array}{ll}
r_t = σ(W_{ir} x_t + b_{ir} + W_{hr} h_{(t-1)} + b_{hr})
z_t = σ(W_{iz} x_t + b_{iz} + W_{hz} h_{(t-1)} + b_{hz})
n_t = tanh(W_{in} x_t + b_{in} + r_t ⊙ (W_{hn} h_{(t-1)}+ b_{hn}))
h_t = (1 - z_t) ⊙ n_t + z_t ⊙ h_{(t-1)}
\end{array}
在时间`t`,:math:`h_t`是隐藏状态,:math:`x_t`是输入
在时间`t`,:math:`h_{(t-1)}`是层的隐藏状态
在时间`t-1`或时间`0`的初始隐藏状态,以及:math:`r_t`,
math:`z_t`,:math:`n_t`分别是重置、更新和新门
σ是 Sigmoid 函数,而⊙是 Hadamard 积。
在多层 GRU 中,第 l 层的输入 x^(l)_t
(:math:`l >= 2`) 是前一层隐藏状态 :math:`h^{(l-1)}_t` 乘以
dropout :math:`\delta^{(l-1)}_t` 其中每个 :math:`\delta^{(l-1)}_t` 是一个伯努利随机变量
变量以概率:attr:`dropout`取值为:math:`0`。
参数:
input_size: 输入 `x` 预期特征的数量
hidden_size: 隐藏状态 `h` 中的特征数量
num_layers: 循环层的数量。例如,设置 ``num_layers=2``
这意味着将两个 GRU 堆叠起来形成一个`堆叠 GRU`,
第二个 GRU 接收第一个 GRU 的输出并
计算最终结果。默认:1
如果为 ``False``,则该层不使用偏置权重 `b_ih` 和 `b_hh`。
默认:``True``
batch_first:如果为 ``True``,则输入和输出张量以(batch,seq,feature)的形式提供。
作为 (batch, seq, feature)。默认:``False``
dropout:如果非零,则在每个输出的基础上引入一个`Dropout`层
GRU 层除了最后一层,dropout 概率相等
:attr:`dropout`. 默认值:0
bidirectional:如果为 True,则变为双向 GRU。默认值:`False`
输入:input,h_0
- **输入** 形状为 `(seq_len, batch, input_size)`:包含特征的张量
输入序列的特征。输入也可以是打包的可变长度变量
序列。请参阅:func:`torch.nn.utils.rnn.pack_padded_sequence`
了解详情。
- **h_0** 形状为 `(num_layers * num_directions, batch, hidden_size)` 的张量:
包含每个批次中每个元素的初始隐藏状态。
默认为零,如果没有提供。如果 RNN 是双向的,
则 num_directions 应为 2,否则应为 1。
输出:输出,h_n
- **输出**的形状为`(seq_len, batch, num_directions * hidden_size)`:张量
包含来自 GRU 最后一层的输出特征 h_t。
对于每个`t`。如果输入的是`:class:`torch.nn.utils.rnn.PackedSequence`,则输出也将是一个打包序列。
如果给定的是打包序列作为输入,输出也将是一个打包序列。
对于未打包的情况,可以使用`output.view(seq_len, batch, num_directions, hidden_size)`来分离方向。
使用`output.view(seq_len, batch, num_directions, hidden_size)`可以分离输出。
前进和后退的方向分别为 `0` 和 `1`。
类似地,方向可以在打包的情况下进行分隔。
- **h_n** 的形状为 `(num_layers * num_directions, batch, hidden_size)`:张量
包含 `t = seq_len` 的隐藏状态
如*输出*,层可以通过以下方式分离:
``h_n.view(num_layers, num_directions, batch, hidden_size)``。
形状:
- 输入 1: :math:`(L, N, H_{in})` 张量包含输入特征,其中
math:`H_{in}=\text{input\_size}` 且 `L` 表示序列长度。
- 输入 2::math:`(S, N, H_{out})` 张量
包含每个批处理元素中的初始隐藏状态。
math:`H_{out}=\text{hidden\_size}`
默认为零,如果未提供。其中 :math:`S=\text{num\_layers} * \text{num\_directions}`
如果 RNN 是双向的,则 num_directions 应为 2,否则应为 1。
- 输出 1: :math:`(L, N, H_{all})` 其中 :math:`H_{all}=\text{num\_directions} * \text{hidden\_size}`
- 输出 2: :math:`(S, N, H_{out})` 包含下一个隐藏状态的张量
批量中的每个元素
属性:
weight_ih_l[k]:第 k 层的可学习输入-隐藏权重。
(W_ir|W_iz|W_in),形状为 `(3*hidden_size, input_size)`,对于 `k = 0` 。
否则,形状为 `(3*hidden_size, num_directions * hidden_size)`
weight_hh_l[k]:第 :math:`\text{k}^{th}` 层的可学习隐藏-隐藏权重
(W_hr|W_hz|W_hn),形状为 `(3*hidden_size, hidden_size)`
bias_ih_l[k]:第 :math:`\text{k}^{th}` 层的可学习输入-隐藏偏置
(b_ir|b_iz|b_in),形状为 `(3*hidden_size)`
bias_hh_l[k]:第 :math:`\text{k}^{th}` 层的可学习隐藏-隐藏偏置
(b_hr|b_hz|b_hn),形状为 `(3*hidden_size)`
.. 注意::
所有权重和偏置都初始化为:math:`\mathcal{U}(-\sqrt{k}, \sqrt{k})`
其中:math:`k = \frac{1}{\text{hidden\_size}}`
.. 注意::
新门 :math:`n_t` 的计算与原始论文和其他框架略有不同。
在原始实现中,在乘以权重矩阵之前,先进行 :math:`r_t` 和前一个隐藏状态 :math:`h_{(t-1)}` 的 Hadamard 积 :math:`(\odot)`。
在原始实现中,在乘以权重矩阵之前,先进行 :math:`r_t` 和前一个隐藏状态 :math:`h_{(t-1)}` 的 Hadamard 积 :math:`(\odot)`。
`W` 和偏置项的添加:
.. math::
\begin{aligned}
n_t = tanh(W_{in} x_t + b_{in} + W_{hn} ( r_t \odot h_{(t-1)} ) + b_{hn})
\end{aligned}
这与 PyTorch 实现不同,PyTorch 是在 :math:`W_{hn} h_{(t-1)}` 之后进行的
.. math::
\begin{aligned}
n_t = tanh(W_{in} x_t + b_{in} + r_t \odot (W_{hn} h_{(t-1)}+ b_{hn}))
\end{aligned}
故意这样实现以提高效率。
.. 包含 :: ../cudnn_persistent_rnn.rst
示例:
>>> # xdoctest: +SKIP
>>> rnn = nn.GRU(10, 20, 2)
>>> input = torch.randn(5, 3, 10)
>>> h0 = torch.randn(2, 3, 20)
输出,hn = rnn(input, h0)
```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)
```
浮点模块 = nn.GRU
__重载__ = {
前进: [
"前向打包",
"前向张量"]}
定义
初始化(
自身, *
参数, **kwargs):
超级().
初始化(
"门控循环单元", *
参数, **kwargs)
定义
_获取名称(
自身):
返回
"动态量化 GRU"
定义
检查前向参数(
自身,
输入:
张量,
隐藏:
张量, batch_sizes:
可选[
张量]
) -> 无:
自身.
检查输入(
输入, batch_sizes)
预期隐藏大小 =
自身.
获取期望的隐藏尺寸(
输入, batch_sizes)
自身.
检查隐藏层大小(
隐藏,
预期隐藏大小,
预期隐藏大小{}
,获得{}"
)
定义 forward_impl(
自身,
输入:
张量,
hx: 可选[
张量
]
batch_sizes: 可选[
张量
]
最大批量大小: int,
排序索引:
可选[
张量
]
) -> 元组[
张量,
张量
]:
如果 hx
是
无:
方向数量 = 2
如果
自身.
双向
否则 1
零值 =
火炬.
零(
自身.
层数 *
方向数量,
最大批量大小,
自身.
隐藏层大小,
数据类型=
输入.
数据类型,
设备=
输入.
设备,
)
hx = 零值
否则:
每个隐藏状态的批次应与用户认为他/她正在传递的输入序列相匹配。
用户认为他/她正在传递的输入序列。
hx = 自身.
打乱隐藏状态(hx,
排序索引)
自身.
检查前向参数(
输入, hx, batch_sizes)
所有参数 = [m.
参数
为 m
在
自身.
所有权重值]
如果
批大小
是
无:
结果 =
火炬.
量化 GRU(
输入,
hx,
_所有参数,
自身.
偏置,
自身.
层数,
自身.dropout,
自身.
训练,
自身.
双向的,
自身.
批量优先,
)
否则:
结果 =
火炬.
量化 GRU(
输入,
batch_sizes,
hx,
_所有参数,
自身.
偏置,
自身.
层数,
自身.dropout,
自身.
训练,
自身.
双向的,
)
输出 =
结果[0]
隐藏 =
结果[1]
返回
输出,
隐藏
@torch.算子.
导出
定义
前向张量(
自身,
输入:
张量, hx:
可选[
张量] = None
) -> 元组[
张量,
张量
]:
批大小 = None
最大批量大小 =
输入.
尺寸(0)
如果
自身.
批量优先
否则
输入.
尺寸(1)
排序索引 = None
未排序索引 = None
输出,
隐藏 =
自身.forward_impl(
输入, hx, batch_sizes,
最大批量大小,
排序索引
)
返回
输出,
自身.
打乱隐藏状态(
隐藏,
未排序的索引)
@torch.算子.
导出
定义 forward_packed(
自身,
输入: PackedSequence, hx:
可选[
张量] = None
) -> 元组[PackedSequence,
张量
]:
输入_, batch_sizes,
排序索引,
未排序索引 =
输入
最大批量大小 = int(batch_sizes[0])
输出_,
隐藏 =
自身.forward_impl(
输入_, hx, batch_sizes,
最大批量大小,
排序索引
)
输出 = PackedSequence(
输出_, batch_sizes,
排序索引,
未排序的索引)
返回
输出,
自身.
打乱隐藏状态(
隐藏,
未排序的索引)
定义
打乱隐藏状态(
自身, hx:
张量,
置换:
可选[
张量]) ->
张量:
如果
排列
是
无:
返回 hx
返回
应用置换(hx,
置换)
@torch.算子.
忽略
定义
前向(
自身,
输入, hx=
无):
如果 isinstance(
输入, PackedSequence):
返回
自身.forward_packed(
输入, hx)
否则:
返回
自身.
前向张量(
输入, hx)
@classmethod
定义
从浮点数(
类, mod,
使用预计算的假量化=
错误):
返回
超级().
从浮点数(
mod, 使用预计算的假量化=
使用预计算的假量化
)
@classmethod
定义
来自参考(
类, ref_mod):
断言
有属性(ref_mod, "weight_ih_l0_dtype"),
"我们假设 weight_ih_l0 "
存在 LSTM 中,可能需要放宽假设以支持用例
qmod = 类(
ref_mod.输入大小,
ref_mod.隐藏层大小,
ref_mod.层数,
ref_mod.偏置,
ref_mod.批量优先,
ref_mod.dropout,
ref_mod.双向的,
# 层 0,应该没问题
ref_mod.weight_ih_l0_dtype,
)
qmod.设置权重偏差(ref_mod.
获取量化权重偏差字典())
返回 qmod
类 RNNCellBase(
火炬.nn.
模块):
# _FLOAT_MODULE = nn.CellRNNBase
常量 = [
输入大小,
隐藏层大小,
偏置]
定义
初始化(
自身,
输入大小,
隐藏层大小,
偏置=True, num_chunks=4,
数据类型=
火炬.qint8
):
超级().
初始化()
自身.
输入大小 =
输入大小
自身.hidden_size = hidden_size
自身.
偏差 =
偏差
自身.
权重数据类型 = dtype
如果
偏置:
自身.
偏置_ih =
火炬.randn(
num_chunks: 分块数量 *
隐藏层大小).
到(
数据类型=
火炬.float)
自身.
偏置_hh =
火炬.randn(
num_chunks: 分块数量 *
隐藏层大小).
到(
数据类型=
火炬.float)
否则:
自身.
注册参数(
"偏置_ih",
无)
自身.
注册参数(
"偏差_hh",
无)
weight_ih = 火炬.randn(
num_chunks: 分块数量 *
隐藏层大小,
输入大小).
到(
火炬.float)
权重_hh =
火炬.randn(
num_chunks: 分块数量 *
隐藏层大小,
隐藏层大小).
到(
火炬.float)
如果 dtype ==
火炬.qint8:
weight_ih = 火炬.
按张量量化(
输入层权重,
比例=1,
零点=0,
数据类型=
火炬.qint8
)
权重_hh =
火炬.
按张量量化(
weight_hh, 比例=1,
零点=0,
数据类型=
火炬.qint8
)
如果 dtype ==
火炬.qint8:
每层每个方向都需要进行量化打包
按此顺序打包权重和打包参数:
#
w_ih, w_hh
打包权重_ih =
火炬.
操作.
量化.
线性预打包(
输入层权重,
自身.
偏置_ih
)
打包重量高高位 =
火炬.
操作.
量化.
线性预打包(
weight_hh, 自身.
偏置_hh
)
否则:
每层每个方向都需要进行量化打包
按此顺序打包权重和打包参数:
#
按顺序打包 packed_ih、packed_hh、b_ih、b_hh
打包权重 packed_weight_ih =
火炬.
操作.
量化.
线性预打包 fp16(
输入层权重,
自身.
偏置_ih
)
包装重量_hh =
火炬.
操作.
量化.
线性预打包 fp16(
weight_hh, 自身.
偏置_hh
)
自身.
_包装重量_ih =
包装重量_ih
自身.
_包装重量_hh =
包装重量
定义
_获取名称(
自身):
返回
动态量化 RNN 基
定义
额外表示(
自身):
s = "{输入大小},
{隐藏层大小}"
如果
偏差
在
自身.
字典
和
自身.
偏差
是 not True:
s += ", 偏置="
{偏置}"
如果
"非线性"
在
自身.
字典
和
自身.
非线性 !=
双曲正切:
s += 非线性=
{非线性}"
返回 s.
格式(**
自身.
字典)
定义
检查前向输入(
自身,
输入):
如果
输入.
尺寸(1) !=
自身.
输入大小:
抛出异常
运行时错误(
f输入存在不一致的 input_size: 获取{
输入.
尺寸(1)}
,预期{
自身.
输入大小}"
)
定义
检查前向隐藏(
自身,
输入:
张量, hx:
张量,
隐藏标签:
字符串 =
请提供需要翻译的文本
) -> 无:
如果
输入.
尺寸(0) != hx.
尺寸(0):
抛出异常
运行时错误(
f"输入批次大小"{
输入.
尺寸(0)}
不匹配隐藏{
隐藏标签}
批量大小{hx.
尺寸(0)}"
)
如果 hx.
尺寸(1) !=
自身.
隐藏层大小:
抛出异常
运行时错误(
f隐藏{
隐藏标签}
存在不一致的隐藏大小:获取{hx.
尺寸(1)}
,预期{
自身.
隐藏层大小}"
)
@classmethod
定义
从浮点数(
类, mod,
使用预计算的假量化=
错误):
断言
类型(mod)
在 {
火炬.nn.LSTMCell,
火炬.nn.
GRU 单元,
火炬.nn.
RNN 单元,
}, nn.quantized.dynamic.RNNCellBase.from_float\
仅适用于 nn.LSTMCell、nn.GRUCell 和 nn.RNNCell
断言
有属性(mod,
qconfig),
输入浮点模块必须定义 qconfig
如果 mod.qconfig
是 not None
和 mod.qconfig.
权重
是 not
无:
权重观察者方法 = mod.qconfig.
权重
否则:
# 如果在文件开头导入 qconfig,我们将遇到循环导入问题:
# https://github.com/pytorch/pytorch/pull/24231。当前的解决方案是推迟导入:
导入直到我们需要它。
来自 torch.ao.quantization.qconfig
导入 default_dynamic_qconfig
权重观察者方法 =
默认动态 Q 配置.
权重
dtype = 权重观察者方法().dtype
支持的标量类型 = [
火炬.qint8,
火炬.float16]
如果 dtype not
在
支持的标量类型:
抛出异常
运行时错误(
f不支持动态 RNN 量化的数据类型:{
数据类型}"
)
qRNNCellBase: 联盟[LSTMCell,
GRU 单元,
RNN 单元]
如果
类型(mod) ==
火炬.nn.LSTMCell:
qRNNCellBase = LSTMCell(
mod.输入大小, mod.
隐藏层大小,
偏置=mod.
偏置,
数据类型=dtype
)
elif 类型(mod) ==
火炬.nn.
GRU 单元:
qRNNCellBase = GRU 单元(
mod.输入大小, mod.
隐藏层大小,
偏置=mod.
偏置,
数据类型=dtype
)
elif 类型(mod) ==
火炬.nn.
RNN 单元:
qRNNCellBase = RNN 单元(
mod.输入大小,
mod.隐藏层大小,
偏置=mod.
偏置,
非线性=mod.
非线性,
数据类型=
数据类型,
)
否则:
抛出异常
不支持的操作异常(
目前只支持 LSTMCell、GRUCell 和 RNNCell\
用于 QuantizedRNN
)
断言 mod.
偏差
定义
_观察和量化权重(
重量):
如果 dtype ==
火炬.qint8:
重量观察者 =
权重观察者方法()
重量观察者(
重量)
权重 = _quantize_weight(
重量.float(),
重量观察者)
返回
权重
否则:
返回
重量.float()
qRNNCellBase._packed_weight_ih = pack_weight_bias(
_observe_and_quantize_weight(mod.输入层权重), mod.
偏差_ih, dtype
)
qRNNCellBase._packed_weight_hh = pack_weight_bias(
_observe_and_quantize_weight(mod.weight_hh), mod.隐藏层偏置, dtype
)
返回 qRNNCellBase
@classmethod
定义
来自参考(
类, ref_mod):
断言
有属性(ref_mod, "weight_ih_dtype"),
"我们假设 weight_ih "
"存在于参考模块中,可能需要放宽假设以支持用例"
如果
有属性(ref_mod,
非线性):
qmod = 类(
ref_mod.输入大小,
ref_mod.隐藏层大小,
ref_mod.偏置,
ref_mod.非线性,
数据类型=ref_mod.
权重_ih 数据类型,
)
否则:
qmod = 类(
ref_mod.输入大小,
ref_mod.隐藏层大小,
ref_mod.偏置,
数据类型=ref_mod.
权重_ih 数据类型,
)
权重偏置字典 = {
权重: {
weight_ih: ref_mod.
获取量化输入隐藏层权重(),
"隐藏层权重": ref_mod.
获取量化隐藏层权重(),
},
偏置: {
"偏置_ih": ref_mod.
偏差_ih,
"偏差_hh": ref_mod.
隐藏层偏置,
},
}
qmod.设置权重偏差(
权重偏差字典)
返回 qmod
定义
权重偏置(
自身):
# 返回权重和偏置的字典
权重偏差字典:
字典[
字符串,
字典] = {
权重: {},
偏置: {}}
w1, b1 = 自身._packed_weight_ih.__getstate__()[0]
w2, b2 = 自身.
_包装重量_hh.__getstate__()[0]
# TODO:这些可以简化为一级?例如使用 weight_ih 作为键
# 直接
权重偏差字典[
权重
]
["权重_ih"] = w1
权重偏差字典[
权重
]
["权重_hh"] = w2
权重偏差字典[
偏置
]
["偏置_ih"] = b1
权重偏差字典[
偏置
]
["偏差_hh"] = b2
返回
权重偏差字典
定义
获取权重(
自身):
返回
自身.
权重偏置()[
权重]
定义
获取偏置(
自身):
返回
自身.
权重偏置()[
偏置]
定义
设置权重偏差(
自身,
权重偏差字典):
# TODO: 这些可以简化为一级,例如使用 weight_ih 作为键
直接
自身._packed_weight_ih =
包装权重偏差(
权重偏差字典[
权重
]
["权重_ih"
]
权重偏差字典[
偏置
]
["偏置_ih"
]
自身.
权重数据类型,
)
自身.
_打包权重_hh =
包装权重偏差(
权重偏差字典[
权重
]
["重量_hh"
]
权重偏差字典[
偏置
]
["偏差_hh"
]
自身.
权重数据类型,
)
定义
保存到状态字典(
自身,
目的地,
前缀,
保留变量):
超级().
保存到状态字典(
目的地,
前缀,
保留变量)
目的地[
前缀 +
"_打包重量_ih"] =
自身.
_打包权重_ih
目的地[
前缀 +
"_打包权重_hh"] =
自身.
_打包权重_hh
定义
从状态字典加载(
自身,
state_dict,
前缀,
本地元数据,
严格的,
缺少键,
预期之外的键,
错误信息,
):
自身.
_打包权重_ih = state_dict.
弹出(
前缀 + "_packed_weight_ih")
自身._packed_weight_hh = state_dict.
弹出(
前缀 + "_packed_weight_hh")
超级().
从状态字典加载(
state_dict,
前缀,
本地元数据,
错误,
缺少键,
预期之外的键,
错误信息,
)
[文档]
类
RNN 单元(RNNCellBase):
r一个具有 tanh 或 ReLU 非线性函数的 Elman RNN 单元。
动态量化 RNNCell 模块,输入输出为浮点张量。
权重被量化为 8 位。我们采用与`torch.nn.RNNCell`相同的接口,
请参阅 https://pytorch.org/docs/stable/nn.html#torch.nn.RNNCell 以获取文档。
示例:
>>> # xdoctest: +SKIP
>>> rnn = nn.RNNCell(10, 20)
>>> input = torch.randn(6, 3, 10)
>>> hx = torch.randn(3, 20)
>>> output = []
>>> for i in range(6):
... hx = rnn(input[i], hx)
... output.append(hx)
```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)
```
常量 = [
输入大小,
隐藏层大小,
偏置,
非线性]
定义
初始化(
自身,
输入大小,
隐藏层大小,
偏置=True,
非线性=
双曲正切,
数据类型=
火炬.qint8
):
超级().
初始化(
输入大小,
隐藏层大小,
偏置, num_chunks=1,
数据类型=
数据类型)
自身.
非线性 =
非线性
定义
_获取名称(
自身):
返回
动态量化 RNN 单元
定义
前向(
自身,
输入:
张量, hx:
可选[
张量] =
无) ->
张量:
自身.
检查前向输入(
输入)
如果 hx
是
无:
hx = 火炬.
零(
输入.
尺寸(0),
自身.
隐藏层大小,
数据类型=
输入.
数据类型,
设备=
输入.
设备
)
自身.
检查前向隐藏状态(
输入, hx, "")
如果
自身.
非线性 ==
双曲正切:
返回 =
火炬.
操作.
量化.
动态量化 tanh 单元量化 RNN(
输入,
hx,
自身._packed_weight_ih,
自身._packed_weight_hh,
自身.
偏差_ih,
自身.
隐藏层偏置,
)
elif 自身.
非线性 ==
ReLU:
返回 =
火炬.
操作.
量化.
量化 RNN-ReLU 单元动态(
输入,
hx,
自身._packed_weight_ih,
自身.
_包装重量_hh,
自身.
偏差_ih,
自身.
隐藏层偏置,
)
否则:
返回 =
输入
# TODO: 当 jit 支持异常流程时删除
抛出异常
运行时错误(f
"未知非线性:"{
自身.
非线性}")
返回
返回
@classmethod
定义
从浮点数(
类, mod,
使用预计算的假量化=
错误):
返回
超级().
从浮点数(
mod, 使用预计算的假量化=
使用预计算的假量化
)
[文档]
类 LSTMCell(RNNCellBase):
r"一个长短期记忆(LSTM)单元。"
一种动态量化 LSTMCell 模块,输入和输出为浮点张量。
权重量化为 8 位。我们采用与`torch.nn.LSTMCell`相同的接口,
请参阅 https://pytorch.org/docs/stable/nn.html#torch.nn.LSTMCell 获取文档。
示例:
>>> # xdoctest: +SKIP
>>> rnn = nn.LSTMCell(10, 20)
>>> input = torch.randn(6, 3, 10)
>>> hx = torch.randn(3, 20)
>>> cx = torch.randn(3, 20)
>>> output = []
>>> for i in range(6):
... hx, cx = rnn(input[i], (hx, cx))
... output.append(hx)
```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)
```
定义
初始化(
自身, *
参数, **kwargs):
超级().
初始化(*
参数, num_chunks=4, **kwargs)
# 类型:忽略[杂项]
定义
_获取名称(
自身):
返回 "DynamicQuantizedLSTMCell"
定义
前向(
自身,
输入:
张量, hx:
可选[
元组[
张量,
张量]] = None
) -> 元组[
张量,
张量
]:
自身.
检查前向输入(
输入)
如果 hx
是
无:
零值 =
火炬.
零(
输入.
尺寸(0),
自身.
隐藏层大小,
数据类型=
输入.
数据类型,
设备=
输入.
设备
)
hx = (零,
零)
自身.
检查前向隐藏状态(
输入, hx[0
] "[0]")
自身.
检查隐藏的前向(
输入, hx[1
] "[1]")
返回
火炬.
操作.
量化.
量化 LSTM 单元动态(
输入,
hx,
自身._packed_weight_ih,
自身._packed_weight_hh,
自身.
偏差_ih,
自身.
隐藏层偏置,
)
@classmethod
定义
从浮点数(
类, mod,
使用预计算的假量化=
错误):
返回
超级().
从浮点数(
mod, 使用预计算的假量化=
使用预计算的假量化
)
[文档]class GRUCell(RNNCellBase):
r"""一个门控循环单元(GRU)单元
一个动态量化 GRUCell 模块,输入和输出为浮点张量。
权重量化为 8 位。我们采用与`torch.nn.GRUCell`相同的接口,
请参阅 https://pytorch.org/docs/stable/nn.html#torch.nn.GRUCell 以获取文档说明。
示例::
>>> # xdoctest: +SKIP
>>> rnn = nn.GRUCell(10, 20)
>>> input = torch.randn(6, 3, 10)
>>> hx = torch.randn(3, 20)
>>> output = []
>>> for i in range(6):
... hx = rnn(input[i], hx)
... output.append(hx)
"""
def __init__(self, 输入大小, 隐藏大小, 偏置=True, 数据类型=torch.qint8):
super().__init__(input_size, hidden_size, bias, num_chunks=3, dtype=dtype)
def _get_name(self):
return "DynamicQuantizedGRUCell"
def forward(self, input: Tensor, hx: Optional[Tensor] = None) -> Tensor:
self.check_forward_input(input)
if hx is None:
hx = torch.zeros(
input.size(0), self.hidden_size, dtype=input.dtype, device=input.device
)
self.check_forward_hidden(input, hx, "")
return torch.ops.quantized.quantized_gru_cell_dynamic(
input,
hx,
self._packed_weight_ih,
self._packed_weight_hh,
self.bias_ih,
self.bias_hh,
)
@classmethod
def from_float(cls, mod, use_precomputed_fake_quant=False):
return super().from_float(
mod, 使用预计算的假量化=use_precomputed_fake_quant
)