spikingjelly.activation_based.ann2snn.recipes.base 源代码
from __future__ import annotations
from typing import TYPE_CHECKING
import torch.nn as nn
from torch import fx
if TYPE_CHECKING:
from spikingjelly.activation_based.ann2snn.converter import (
FXConverter,
ModuleConverter,
)
__all__ = [
"ConversionRecipe",
"FXConversionRecipe",
"ModuleConversionRecipe",
]
[文档]
class FXConversionRecipe:
r"""
**API Language** - :ref:`中文 <ConversionRecipe-cn>` | :ref:`English <ConversionRecipe-en>`
----
.. _ConversionRecipe-cn:
* **中文**
FX graph 路径的 ANN2SNN 转换 recipe 基类。兼容名
``ConversionRecipe`` 等价于 ``FXConversionRecipe``。Recipe 是策略对象,
只定义 :class:`~spikingjelly.activation_based.ann2snn.converter.FXConverter`
在固定 FX 转换模板中每一步应该做什么;Recipe 本身不提供 ``convert``、
``run`` 或 ``__call__`` 执行入口。
子类可以覆盖 :meth:`validate`、:meth:`before_trace`、
:meth:`after_trace`、:meth:`insert_observers`、:meth:`calibrate`、
:meth:`replace` 和 :meth:`finalize`。``before_trace`` 接收原始 ANN;
图步骤接收同一个 ``FXConverter`` 和当前 ``fx.GraphModule``。步骤可以
原地修改对象,也必须返回下一步要继续使用的对象。
----
.. _ConversionRecipe-en:
* **English**
Base class for FX graph ANN2SNN conversion recipes. The compatibility name
``ConversionRecipe`` is equivalent to ``FXConversionRecipe``. A recipe is a
strategy object that defines what each step in the fixed
:class:`~spikingjelly.activation_based.ann2snn.converter.FXConverter`
pipeline should do; the recipe itself does not expose a ``convert``,
``run`` or ``__call__`` execution entrypoint.
Subclasses can override :meth:`validate`, :meth:`before_trace`,
:meth:`after_trace`, :meth:`insert_observers`, :meth:`calibrate`,
:meth:`replace` and :meth:`finalize`. ``before_trace`` receives the original
ANN. Graph steps receive the same ``FXConverter`` and the current
``fx.GraphModule``. They may mutate the object in-place, and must return the
object that the next step should use.
"""
[文档]
def validate(self, converter: "FXConverter") -> None:
r"""
**API Language** - :ref:`中文 <ConversionRecipe.validate-cn>` | :ref:`English <ConversionRecipe.validate-en>`
----
.. _ConversionRecipe.validate-cn:
* **中文**
校验当前 recipe 的前置条件。默认实现不做任何检查。该方法由
``FXConverter`` / ``Converter`` 在每次转换开始时调用一次,子类不应
在这里执行图转换。
:param converter: 执行当前 recipe 的转换器。
:type converter: FXConverter
----
.. _ConversionRecipe.validate-en:
* **English**
Validate this recipe's prerequisites. The default implementation checks
nothing. ``FXConverter`` / ``Converter`` calls this method once at the
beginning of each conversion; subclasses should not perform graph
conversion here.
:param converter: Converter that executes this recipe.
:type converter: FXConverter
"""
return None
[文档]
def before_trace(self, converter: "FXConverter", ann: nn.Module) -> nn.Module:
r"""
**API Language** - :ref:`中文 <ConversionRecipe.before_trace-cn>` | :ref:`English <ConversionRecipe.before_trace-en>`
----
.. _ConversionRecipe.before_trace-cn:
* **中文**
FX tracing 之前运行的步骤。默认直接返回 ``ann``。子类可在此设置
训练/推理模式,或执行必须发生在 tracing 前的模型准备。
:param converter: 执行当前 recipe 的转换器。
:type converter: FXConverter
:param ann: 待 trace 的原始 ANN。
:type ann: torch.nn.Module
:return: 后续 tracing 使用的 ANN。
:rtype: torch.nn.Module
----
.. _ConversionRecipe.before_trace-en:
* **English**
Step executed before FX tracing. The default implementation returns
``ann`` unchanged. Subclasses can set training/eval mode or perform
model preparation that must happen before tracing.
:param converter: Converter that executes this recipe.
:type converter: FXConverter
:param ann: Original ANN to be traced.
:type ann: torch.nn.Module
:return: ANN used by FX tracing.
:rtype: torch.nn.Module
"""
return ann
[文档]
def after_trace(
self, converter: "FXConverter", fx_model: fx.GraphModule
) -> fx.GraphModule:
r"""
**API Language** - :ref:`中文 <ConversionRecipe.after_trace-cn>` | :ref:`English <ConversionRecipe.after_trace-en>`
----
.. _ConversionRecipe.after_trace-cn:
* **中文**
FX tracing 和 device 转移之后运行的步骤。默认直接返回
``fx_model``。子类可在此执行 Conv-BN 融合或做其他 tracing 后预处理;
影响 FX tracing 的训练/推理模式应在 :meth:`before_trace` 中设置。
:param converter: 执行当前 recipe 的转换器。
:type converter: FXConverter
:param fx_model: 已 trace 并移动到目标 device 的 ``GraphModule``。
:type fx_model: torch.fx.GraphModule
:return: 后续步骤使用的 ``GraphModule``。
:rtype: torch.fx.GraphModule
----
.. _ConversionRecipe.after_trace-en:
* **English**
Step executed after FX tracing and device transfer. The default
implementation returns ``fx_model`` unchanged. Subclasses can fuse
Conv-BN modules or perform other post-tracing preprocessing here;
training/eval mode that affects FX tracing should be set in
:meth:`before_trace`.
:param converter: Converter that executes this recipe.
:type converter: FXConverter
:param fx_model: ``GraphModule`` after tracing and device transfer.
:type fx_model: torch.fx.GraphModule
:return: ``GraphModule`` used by later steps.
:rtype: torch.fx.GraphModule
"""
return fx_model
[文档]
def insert_observers(
self, converter: "FXConverter", fx_model: fx.GraphModule
) -> fx.GraphModule:
r"""
**API Language** - :ref:`中文 <ConversionRecipe.insert_observers-cn>` | :ref:`English <ConversionRecipe.insert_observers-en>`
----
.. _ConversionRecipe.insert_observers-cn:
* **中文**
插入校准 observer / hook 的步骤。默认不插入任何模块并直接返回
``fx_model``。需要校准数据的 recipe 可在此修改 FX 图。
:param converter: 执行当前 recipe 的转换器。
:type converter: FXConverter
:param fx_model: 当前 ``GraphModule``。
:type fx_model: torch.fx.GraphModule
:return: 后续步骤使用的 ``GraphModule``。
:rtype: torch.fx.GraphModule
----
.. _ConversionRecipe.insert_observers-en:
* **English**
Insert calibration observers or hooks. The default implementation
inserts nothing and returns ``fx_model`` unchanged. Recipes that need
calibration data can mutate the FX graph here.
:param converter: Converter that executes this recipe.
:type converter: FXConverter
:param fx_model: Current ``GraphModule``.
:type fx_model: torch.fx.GraphModule
:return: ``GraphModule`` used by later steps.
:rtype: torch.fx.GraphModule
"""
return fx_model
[文档]
def calibrate(
self, converter: "FXConverter", fx_model: fx.GraphModule
) -> fx.GraphModule:
r"""
**API Language** - :ref:`中文 <ConversionRecipe.calibrate-cn>` | :ref:`English <ConversionRecipe.calibrate-en>`
----
.. _ConversionRecipe.calibrate-cn:
* **中文**
运行校准数据的步骤。默认不运行 dataloader 并直接返回 ``fx_model``。
需要校准的子类应自行决定是否使用 ``torch.no_grad()``、如何解析 batch,
以及如何更新已插入的 observer / hook。
:param converter: 执行当前 recipe 的转换器。
:type converter: FXConverter
:param fx_model: 当前 ``GraphModule``。
:type fx_model: torch.fx.GraphModule
:return: 后续步骤使用的 ``GraphModule``。
:rtype: torch.fx.GraphModule
----
.. _ConversionRecipe.calibrate-en:
* **English**
Run calibration data. The default implementation does not iterate over
the dataloader and returns ``fx_model`` unchanged. Subclasses that need
calibration should decide whether to use ``torch.no_grad()``, how to
parse batches, and how to update inserted observers or hooks.
:param converter: Converter that executes this recipe.
:type converter: FXConverter
:param fx_model: Current ``GraphModule``.
:type fx_model: torch.fx.GraphModule
:return: ``GraphModule`` used by later steps.
:rtype: torch.fx.GraphModule
"""
return fx_model
[文档]
def replace(
self, converter: "FXConverter", fx_model: fx.GraphModule
) -> fx.GraphModule:
r"""
**API Language** - :ref:`中文 <ConversionRecipe.replace-cn>` | :ref:`English <ConversionRecipe.replace-en>`
----
.. _ConversionRecipe.replace-cn:
* **中文**
执行核心替换的步骤,例如将 activation 替换为 spiking neuron,或将 ANN
module 替换为 TD operator。默认直接返回 ``fx_model``。
:param converter: 执行当前 recipe 的转换器。
:type converter: FXConverter
:param fx_model: 当前 ``GraphModule``。
:type fx_model: torch.fx.GraphModule
:return: 替换后的 ``GraphModule``。
:rtype: torch.fx.GraphModule
----
.. _ConversionRecipe.replace-en:
* **English**
Perform the core replacement step, such as replacing activations with
spiking neurons or replacing ANN modules with TD operators. The default
implementation returns ``fx_model`` unchanged.
:param converter: Converter that executes this recipe.
:type converter: FXConverter
:param fx_model: Current ``GraphModule``.
:type fx_model: torch.fx.GraphModule
:return: Replaced ``GraphModule``.
:rtype: torch.fx.GraphModule
"""
return fx_model
[文档]
def finalize(self, converter: "FXConverter", fx_model: fx.GraphModule) -> nn.Module:
r"""
**API Language** - :ref:`中文 <ConversionRecipe.finalize-cn>` | :ref:`English <ConversionRecipe.finalize-en>`
----
.. _ConversionRecipe.finalize-cn:
* **中文**
转换结束前的收尾步骤。默认直接返回 ``fx_model``。子类可在此做最终
graph lint、清理临时模块、恢复状态,或包装最终返回的
:class:`torch.nn.Module`。
:param converter: 执行当前 recipe 的转换器。
:type converter: FXConverter
:param fx_model: 当前 ``GraphModule``。
:type fx_model: torch.fx.GraphModule
:return: 最终转换结果。
:rtype: torch.nn.Module
----
.. _ConversionRecipe.finalize-en:
* **English**
Final step before returning the converted model. The default
implementation returns ``fx_model`` unchanged. Subclasses can perform
final graph linting, clean temporary modules, restore state, or wrap the
final returned :class:`torch.nn.Module`.
:param converter: Converter that executes this recipe.
:type converter: FXConverter
:param fx_model: Current ``GraphModule``.
:type fx_model: torch.fx.GraphModule
:return: Final converted model.
:rtype: torch.nn.Module
"""
return fx_model
ConversionRecipe = FXConversionRecipe
[文档]
class ModuleConversionRecipe:
r"""
**API Language** - :ref:`中文 <ModuleConversionRecipe-cn>` | :ref:`English <ModuleConversionRecipe-en>`
----
.. _ModuleConversionRecipe-cn:
* **中文**
直接 ``nn.Module`` tree 转换 recipe 基类。该路径不执行 FX tracing,
只由 :class:`~spikingjelly.activation_based.ann2snn.converter.ModuleConverter`
调用 :meth:`validate` 和 :meth:`convert_module`。适用于 SpikeZIP 这类
需要按 module tree 替换子模块、但不改写 FX graph 的转换。该基类没有
``before_trace``、``after_trace``、``insert_observers``、``calibrate``、
``replace`` 或 ``finalize`` 生命周期。
----
.. _ModuleConversionRecipe-en:
* **English**
Base class for direct ``nn.Module`` tree conversion recipes. This path does
not run FX tracing. :class:`~spikingjelly.activation_based.ann2snn.converter.ModuleConverter`
only calls :meth:`validate` and :meth:`convert_module`. It is intended for
conversions such as SpikeZIP that replace submodules in a module tree
without rewriting an FX graph. This base class has no ``before_trace``,
``after_trace``, ``insert_observers``, ``calibrate``, ``replace`` or
``finalize`` lifecycle.
"""
[文档]
def validate(self, converter: "ModuleConverter") -> None:
r"""
**API Language** - :ref:`中文 <ModuleConversionRecipe.validate-cn>` | :ref:`English <ModuleConversionRecipe.validate-en>`
----
.. _ModuleConversionRecipe.validate-cn:
* **中文**
校验 module-tree recipe 的前置条件。默认实现不做任何检查。
:param converter: 执行当前 recipe 的 module converter。
:type converter: ModuleConverter
----
.. _ModuleConversionRecipe.validate-en:
* **English**
Validate prerequisites for a module-tree recipe. The default
implementation checks nothing.
:param converter: Module converter that executes this recipe.
:type converter: ModuleConverter
"""
return None
[文档]
def convert_module(
self,
converter: "ModuleConverter",
ann: nn.Module,
) -> nn.Module:
r"""
**API Language** - :ref:`中文 <ModuleConversionRecipe.convert_module-cn>` | :ref:`English <ModuleConversionRecipe.convert_module-en>`
----
.. _ModuleConversionRecipe.convert_module-cn:
* **中文**
执行直接 module-tree 转换。默认直接返回 ``ann``。实现必须返回
``torch.nn.Module`` 实例。
:param converter: 执行当前 recipe 的 module converter。
:type converter: ModuleConverter
:param ann: 待转换的原始 ANN 或 QANN。
:type ann: torch.nn.Module
:return: 转换后的模型。
:rtype: torch.nn.Module
----
.. _ModuleConversionRecipe.convert_module-en:
* **English**
Execute direct module-tree conversion. The default implementation
returns ``ann`` unchanged. Implementations must return a
``torch.nn.Module`` instance.
:param converter: Module converter that executes this recipe.
:type converter: ModuleConverter
:param ann: Original ANN or QANN to convert.
:type ann: torch.nn.Module
:return: Converted model.
:rtype: torch.nn.Module
"""
return ann