spikingjelly.activation_based.distributed.analysis 源代码

from __future__ import annotations

from dataclasses import dataclass
from typing import Iterable, List, Optional, Sequence, Tuple

import torch.nn as nn

from spikingjelly.activation_based import base


LinearLike = (nn.Linear,)


[文档] @dataclass class SNNDistributedAnalysis: r""" **API Language** - :ref:`中文 <SNNDistributedAnalysis-cn>` | :ref:`English <SNNDistributedAnalysis-en>` ---- .. _SNNDistributedAnalysis-cn: * **中文** SNN 分布式训练分析器。分析模型结构并推荐并行策略。 ---- .. _SNNDistributedAnalysis-en: * **English** SNN distributed training analyzer. """ memory_module_names: Tuple[str, ...] tensor_parallel_candidate_names: Tuple[str, ...] unsupported_tensor_parallel_names: Tuple[str, ...] notes: Tuple[str, ...] tensor_parallel_roots: Optional[Tuple[str, ...]] = None
SNNDistributedAnalysis.__init__.__doc__ = r"""Initialize distributed capability analysis results. .. admonition:: Chinese 初始化 SNN 分布式能力分析结果,包括状态模块、张量并行候选模块和提示信息。 :param memory_module_names: Names of stateful memory modules. :type memory_module_names: tuple[str, ...] :param tensor_parallel_candidate_names: Names of modules that can use tensor parallelism. :type tensor_parallel_candidate_names: tuple[str, ...] :param unsupported_tensor_parallel_names: Names seen under tensor-parallel roots but not supported. :type unsupported_tensor_parallel_names: tuple[str, ...] :param notes: Human-readable analysis notes. :type notes: tuple[str, ...] :param tensor_parallel_roots: Roots used by the analysis. :type tensor_parallel_roots: tuple[str, ...] or None """ def _iter_named_modules_under_roots( module: nn.Module, roots: Optional[Sequence[str]] = None, ) -> Iterable[Tuple[str, nn.Module]]: if not roots: for name, child in module.named_modules(): if name: yield name, child return named_children = dict(module.named_modules()) seen = set() for root in roots: if not root: raise ValueError( "tensor_parallel_roots entries must be non-empty module paths; " "pass None or omit the argument to scan the full model." ) if root not in named_children: raise KeyError( f"tensor_parallel_roots contains unknown module path '{root}'." ) root_module = named_children[root] for sub_name, child in root_module.named_modules(): full_name = root if not sub_name else f"{root}.{sub_name}" if full_name in seen: continue seen.add(full_name) yield full_name, child def analyze_snn_distributed_capability( module: nn.Module, tensor_parallel_roots: Optional[Sequence[str]] = None, ) -> SNNDistributedAnalysis: r""" **API Language** - :ref:`中文 <analyze_snn_distributed_capability-cn>` | :ref:`English <analyze_snn_distributed_capability-en>` ---- .. _analyze_snn_distributed_capability-cn: * **中文** 分析 SNN 模型的分布式训练能力。 ---- .. _analyze_snn_distributed_capability-en: * **English** Analyze SNN distributed capability. """ memory_modules: List[str] = [] tensor_parallel_candidates: List[str] = [] unsupported_tp: List[str] = [] notes: List[str] = [] for name, child in module.named_modules(): if not name: continue if isinstance(child, base.MemoryModule): memory_modules.append(name) for name, child in _iter_named_modules_under_roots(module, tensor_parallel_roots): if isinstance(child, LinearLike): tensor_parallel_candidates.append(name) elif isinstance( child, (nn.Conv1d, nn.Conv2d, nn.Conv3d), ): unsupported_tp.append(name) if memory_modules: notes.append( "Stateful neuron modules remain local/replicated in this first DTensor-ready layer." ) if unsupported_tp: notes.append( "Conv tensor parallel is not enabled in this first implementation; only Linear-like modules " "are auto-parallelized." ) if not tensor_parallel_candidates: notes.append( "No Linear-like tensor-parallel candidates were found under the selected roots." ) return SNNDistributedAnalysis( memory_module_names=tuple(memory_modules), tensor_parallel_candidate_names=tuple(tensor_parallel_candidates), unsupported_tensor_parallel_names=tuple(unsupported_tp), notes=tuple(notes), tensor_parallel_roots=( tuple(tensor_parallel_roots) if tensor_parallel_roots is not None else None ), )