ó
    óó�jä  ã                   óè  • S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
Jr  SSKJr  SSKJrJr  SSKJr  SSKrSSKrSSKJr  SSKJr  SS	KJrJr  SS
KJr  SSK J!r!J"r"J#r#  SSK$J$r$  SSK%r&SSK'J(r(J)r)  SSK*J+r+J,r,  SSK-J.r.J/r/  SSK0J1r1  SSK2J3r3  SSK4J5r5  SSK6J7r7  SSK8J9r9  \&Rt                  Rv                  Ry                  5         \3" \=5      r>\R~                  R�                  \R~                  Rƒ                  \B5      5      rC\R~                  R‰                  \CS5      rCSrESrFSrGS0 \CS4S jrHS rI " S S\5      rJ\&Rt                  R–                  R˜                   " S S5      5       rMg) zßCore SpeechBrain code for running experiments.

Authors
 * Peter Plantinga 2020, 2023
 * Abdel Heba 2020
 * Mirco Ravanelli 2020
 * Aku Rouhe 2021
 * Andreas Nautsch 2022
 * Sylvain de Langen 2023
 * Adel Moumen 2023, 2024
é    N)Úcontextmanager)Údate)ÚEnumÚauto)ÚSimpleNamespace)Úresolve_references)Úversion)ÚDataParallelÚSyncBatchNorm)ÚDistributedDataParallel)Ú
DataLoaderÚDistributedSamplerÚIterableDataset)Útqdm)ÚLoopedLoaderÚSaveableDataLoader)ÚDistributedSamplerWrapperÚReproducibleRandomSampler)Ú	AMPConfigÚTorchAutocast)Úis_distributed_initialized)Ú
get_logger)Úrm_vector_weight_decay)Úprepare_profiler)Ú
RunOptionszlog-config.yamlÚbrain_intra_epoch_ckpté   é   Tc                 ó¢  •  [         R                  R                  R                  5       (       Ga–  [        R
                  R                  U 5      (       d  [        R                  " U 5        Ub½  [        R
                  R                  U S5      n[        USS9 n[        Xb5      nSSS5        [        USSS9 n[        S[        R                  " 5       -  US9  [        S[        R
                  R                  U5      -  US9  [        S	US9  [        R                   " WU5        SSS5        ["        R$                  " ["        R&                  " 5       R(                  5      n	U	b?  [        R
                  R+                  U	R,                  5      n
[        R.                  " X 5        [        R
                  R                  U S
5      nSSSU000n[         R                  R0                  R3                  X<5        [4        [6        l        [         R                  R:                  R=                  5         [0        R?                  S5        [0        R?                  SU  35        U(       ak  [         R                  R0                  RA                  5       n[        [        R
                  R                  U S5      SSS9 nURC                  U5        SSS5        [         R                  R                  RE                  5         g! , (       d  f       GNS= f! , (       d  f       GNæ= f! , (       d  f       N[= f! [         R                  R                  RE                  5         f = f)aê  Create the output folder and relevant experimental files.

Arguments
---------
experiment_directory : str
    The place where the experiment directory should be created.
hyperparams_to_save : str
    A filename of a yaml file representing the parameters for this
    experiment. If passed, references are resolved, and the result is
    written to a file in the experiment directory called "hyperparams.yaml".
overrides : dict
    A mapping of replacements made in the yaml file, to save in yaml.
log_config : str
    A yaml filename containing configuration options for the logger.
save_env_desc : bool
    If True, an environment state description is saved to the experiment
    directory, in a file called env.log in the experiment directory.
Nzhyperparams.yamlúutf-8©ÚencodingÚwz# Generated %s from:)Úfilez# %sz# yamllint disablezlog.txtÚhandlersÚfile_handlerÚfilenamezBeginning experiment!zExperiment folder: zenv.log)#ÚsbÚutilsÚdistributedÚif_main_processÚosÚpathÚisdirÚmakedirsÚjoinÚopenr   Úprintr   ÚtodayÚabspathÚshutilÚcopyfileobjÚinspectÚ	getmoduleÚcurrentframeÚf_backÚrealpathÚ__file__ÚcopyÚloggerÚsetup_loggingÚ_logging_excepthookÚsysÚ
excepthookÚquirksÚlog_applied_quirksÚinfoÚget_environment_descriptionÚwriteÚddp_barrier)Úexperiment_directoryÚhyperparams_to_saveÚ	overridesÚ
log_configÚsave_env_descÚhyperparams_filenameÚfÚresolved_yamlr#   ÚmoduleÚcallingfileÚlog_fileÚlogger_overridesÚdescription_strÚfos                  ÚžC:\Users\johnn\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\LocalCache\local-packages\Python313\site-packages\speechbrain/core.pyÚcreate_experiment_directoryrX   >   sX  € ð25+ä�8‰8×Ñ×/Ñ/×1Ò1Ü—7‘7—=‘=Ð!5×6Ñ6Ü—’Ð0Ô1ð #Ñ.Ü')§w¡w§|¡|Ø(Ð*<ó(Ð$ô Ð-¸Ò@ÀAÜ$6°qÓ$D�M÷ AäÐ.°¸gÒFÈ!ÜÐ0´4·:²:³<Ñ?ÀaÒHÜ˜&¤2§7¡7§?¡?Ð3FÓ#GÑGÈaÒPÜÐ.°QÒ7Ü×&Ò& }°aÔ8÷	 Gô ×&Ò&¤w×';Ò';Ó'=×'DÑ'DÓEˆFØÑ!Ü Ÿg™g×.Ñ.¨v¯©Ó?�Ü—’˜KÔ>ô —w‘w—|‘|Ð$8¸)ÓDˆHà˜^¨j¸(Ð-CÐDð Ðô �H‰H�O‰O×)Ñ)¨*ÔGÜ0ŒCŒNô
 �H‰H�O‰O×.Ñ.Ô0ô �K‰KÐ/Ô0Ü�K‰KÐ-Ð.BÐ-CÐDÔEö Ü"$§(¡(§/¡/×"MÑ"MÓ"O�ÜÜ—G‘G—L‘LÐ!5°yÓAØØ$òð Ø—H‘H˜_Ô-÷ô 	�‰×Ñ×(Ñ(Õ*÷U AÖ@úçFÖFú÷@õ ûô 	�‰×Ñ×(Ñ(Õ*úsV   ‚BL$ ÂK/Â#L$ Â6A,LÄ"F
L$ Ê,LÊ>L$ Ë/
K>Ë9L$ Ì
LÌL$ Ì
L!ÌL$ Ì$*Mc                 ó0   • [         R                  SXU4S9  g)z-Interrupt exception raising to log the error.z
Exception:)Úexc_infoN)r>   Úerror)Úexc_typeÚ	exc_valueÚexc_tracebacks      rW   r@   r@   �   s   € ä
‡L�L�¨¸mÐ(L€LÒMó    c                   óB   • \ rS rSrSr\" 5       r\" 5       r\" 5       rSr	g)ÚStageé”   z*Simple enum to track stage of experiments.© N)
Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   ÚTRAINÚVALIDÚTESTÚ__static_attributes__rc   r_   rW   ra   ra   ”   s   † Ù4á‹F€EÙ‹F€EÙ‹6ƒDr_   ra   c                   óæ  • \ rS rSrSr     S&S jrS rS rS rS'S jr	S'S	 jr
 S(S
 jrS rS rS rS)S jrS*S jrS rS rS rS rS rS rS r\R2                  " 5       S 5       rS rS rS rSS0 0 4S jr\S 5       r S r!S r"S r#SSS0 4S  jr$S! r%\&S+S" j5       r'\(RR                  RT                  RV                  S# 5       r,\(RR                  RT                  RZ                  S$ 5       r.S%r/g),ÚBrainéœ   ai  Brain class abstracts away the details of data loops.

The primary purpose of the `Brain` class is the implementation of
the ``fit()`` method, which iterates epochs and datasets for the
purpose of "fitting" a set of modules to a set of data.

In order to use the ``fit()`` method, one should sub-class the ``Brain``
class and override any methods for which the default behavior does not
match the use case. For a simple use case (e.g., training a single model
with a single dataset) the only methods that need to be overridden are:

* ``compute_forward()``
* ``compute_objectives()``

The example below illustrates how overriding these two methods is done.

For more complicated use cases, such as multiple modules that need to
be updated, the following methods can be overridden:

* ``fit_batch()``
* ``evaluate_batch()``

Arguments
---------
modules : dict[str, torch.nn.Module]
    These modules are passed to the optimizer by default if they have
    trainable parameters, and will have ``train()``/``eval()`` called on them.
opt_class : Optional[Type[torch.optim]]
    A torch optimizer constructor that takes only the list of
    parameters (e.g. a lambda or partial function definition). By default,
    this will be passed all modules in ``modules`` at the
    beginning of the ``fit()`` method. This behavior can be changed
    by overriding the ``configure_optimizers()`` method.
hparams : Optional[dict]
    Each key:value pair should consist of a string key and a hyperparameter
    that is used within the overridden methods. These will
    be accessible via an ``hparams`` attribute, using "dot" notation:
    e.g., self.hparams.model(x).
run_opts : Optional[Union[RunOptions, dict]]
    A set of options to change the runtime environment, see ``RunOptions`` for a list.
    Typically in a script this comes from ``speechbrain.parse_args``, an alias
    for ``RunOptions.from_command_line_args``. If an option is not defined here
    (keep in mind that `parse_args` will inject some options by default),
    then the option is also searched for in hparams (by key).
checkpointer : Optional[speechbrain.utils.checkpoints.Checkpointer]
    By default, this will be used to load checkpoints, and will have the
    optimizer added to continue training if interrupted.

Example
-------
>>> from torch.optim import SGD
>>> class SimpleBrain(Brain):
...     def compute_forward(self, batch, stage):
...         return self.modules.model(batch[0] * self.hparams.scalar)
...
...     def compute_objectives(self, predictions, batch, stage):
...         return torch.nn.functional.l1_loss(predictions, batch[0])
>>> model = torch.nn.Linear(in_features=10, out_features=10)
>>> brain = SimpleBrain(
...     modules={"model": model},
...     opt_class=lambda x: SGD(x, lr=0.1),
...     hparams={"scalar": 5},
...     run_opts={"device": "cpu"},
... )
>>> brain.fit(range(1), ([torch.rand(10, 10), torch.rand(10, 10)],))
Nc                 ó>  • S U l         X l        XPl        [        U[        5      (       a  [
        R                  " U5      n[        5       nUR                  5       R                  5        HŒ  u  pxUbG  XtR                  ;   a8  Ub%  Xs;   a   [        R                  U S3SXG    3-   5        [        XXG   5        MO  Ub.  Xs;   a)  [        R                  SU S35        [        XX7   5        M€  [        XU5        MŽ     [        R                  R                  [         :X  a"  [        R                  R"                  [$        :¼  d†  [        R'                  S[)        [        R                  R                  5      -   S-   [)        [        R                  R"                  5      -   S-   [)        [         5      -   S-   [)        [$        5      -   5        [*        R,                  R/                  S5      S L=(       a!    [*        R,                  R/                  S	5      S LU l        U R2                  (       a  U R0                  (       a  [5        S
5      eU R6                  S:”  a&  U R8                  S:”  a  [        R:                  " S5        U R<                  c-  [>        R@                  RB                  RE                  5       U l        U R<                  S:X  a  SU l#        O�SU R<                  ;   aN  SU l#         U R<                  RI                  S5      u  pš[J        RL                  RO                  [Q        U
5      5        O#U R<                  RI                  S5      S   U l#        U R2                  (       a-  [J        RL                  RS                  5       S:X  a  [5        S5      e[J        RT                  RW                  U5      RY                  U R<                  5      U l-        U RZ                   HX  n[]        U RZ                  U   S5      (       d  M#  U RZ                  U   RY                  U R<                  5      U RZ                  U'   MZ     Ub  [_        S-0 UD6U l0        U Rb                  (       a¯  U Rd                  (       dž  U R                  b‘  []        U R                  S5      (       av  [f        Rh                  " 5       n[        R                  SURj                   35        [l        Rn                  " URj                  5      U R                  l8        XÀR                  l9        S U l:        U Rv                  (       a  [        R'                  S5        SU l<        U Rz                  (       a  [        R'                  S5        SU l<        U RF                  S:X  a+  U Rx                  S:X  d  U R|                  S:X  a  [5        S5      eU Rx                  S:H  =(       a    U RF                  S:H  nU R~                  (       a  U(       a  [        R'                  S5        [        R                  SU S35        [        R                  SU Rx                   S35        [        R                  SU R|                   S35        [€        R‚                  " [J        R„                  5      [€        R‚                  " S5      :  a-  [J        RL                  R†                  R‰                  US9U lE        O$[J        Rˆ                  " U R<                  US9U lE        [Œ        RŽ                  " U Rx                  5      R�                  n[“        U RF                  US 9U lJ        [Œ        RŽ                  " U R|                  5      R�                  n[“        U RF                  US 9U lK        U(       a2  U R                  b%  U R                  R™                  S!U RŠ                  S"S#9  U R›                  5         U R0                  (       au  [Q        [*        R,                  S   5      U lN        [Ÿ        5       (       dE  U Rœ                  S:”  a  [5        S$5      e[        R'                  S%5        [        R                  S&5        S'U lP        SU lQ        SU lR        U R                  b  U R                  R™                  S(U 5        U R¦                  (       d%  [        R©                  U Rª                  S)5      U lU        S U lV        U R®                  (       ap  [        R                  S*5        U R°                  U R²                  -   S+-
  U lZ        [·        U R²                  U R°                  U R`                  R¸                  5      U lV        []        U RZ                  S,5      (       a  U RZ                  Rº                  U l^        g U RZ                  U l^        g ! [4         a#    [J        RL                  RO                  S5         GNVf = f).Nz. which is specified in hparams was overridden zby command line input to: zRun option z from hparams is usedzDetected Python Ú.z-. We suggest using SpeechBrain with Python >=ÚRANKÚ
LOCAL_RANKzÕTo use data_parallel backend, start your script with:
	python experiment.py hyperparams.yaml --data_parallel_backend=True
To use DDP backend, start your script with:
	torchrun [args] experiment.py hyperparams.yamlr   z…The options `ckpt_interval_minutes` and `ckpt_interval_steps` are mutually exclusive. Please keep only one active per experiment run.ÚcpuÚcudaÚ:z0You must have at least 1 GPU to use DataParallelÚtoÚcheckpoints_dirzRSince debug mode is active, switching checkpointer output to temporary directory: ztThe option `--auto_mix_prec` is deprecated and will be removed in the future. Please use `--precision=fp16` instead.Úfp16zxThe option `--bfloat16_mix_prec` is deprecated and will be removed in the future. Please use `--precision=bf16` instead.Úbf16zÊThe option `--precision` or `--eval_precision` is set to fp16. This option is not yet supported on CPU. Please use `--precision=bf16` or `--eval_precision=bf16` instead to enable mixed precision on CPU.z€The option `skip_nonfinite_grads` will be ignored because GradScaler is enabled and will automatically skip nonfinite gradients.zGradscaler enabled: `Ú`z'Using training precision: `--precision=z.Using evaluation precision: `--eval_precision=z2.4.0)Úenabled)Údevice_typeÚdtypeÚscalerT)Úoptional_loadz³ ================ WARNING ===============Please add sb.ddp_init_group() into your exp.pyTo use DDP backend, start your script with:
	torchrun [args] experiment.py hyperparams.yamlzMTo use DDP, please add sb.utils.distributed.ddp_init_group() into your exp.pyzAOnly the main process is alive, all other subprocess were killed.ç        ÚbrainÚ z$Pytorch profiler has been activated.é   rQ   rc   )_Úoptimizers_dictÚ	opt_classÚcheckpointerÚ
isinstanceÚdictr   Úfrom_dictionaryÚas_dictÚitemsÚoverridden_argsr>   rE   ÚsetattrrA   Úversion_infoÚmajorÚPYTHON_VERSION_MAJORÚminorÚPYTHON_VERSION_MINORÚwarningÚstrr,   ÚenvironÚgetÚdistributed_launchÚdata_parallel_backendÚ
ValueErrorÚckpt_interval_minutesÚckpt_interval_stepsÚexitÚdevicer(   r)   r*   Úinfer_devicer}   ÚsplitÚtorchru   Ú
set_deviceÚintÚdevice_countÚnnÚ
ModuleDictrw   ÚmodulesÚhasattrr   ÚhparamsÚdebugÚdebug_persistentlyÚtempfileÚTemporaryDirectoryÚnameÚpathlibÚPathrx   ÚtempdirÚtrain_samplerÚauto_mix_precÚ	precisionÚbfloat16_mix_precÚeval_precisionÚskip_nonfinite_gradsr	   ÚparseÚ__version__ÚampÚ
GradScalerr   r   Ú	from_namer~   r   Útraining_ctxÚevaluation_ctxÚadd_recoverableÚprint_trainable_parametersÚrankr   Úavg_train_lossÚstepÚoptimizer_stepÚtqdm_colored_barÚfromkeysÚtqdm_barcolorÚprofilerÚprofile_trainingÚprofile_stepsÚprofile_warmupÚtot_prof_stepsr   Úoutput_folderrQ   Úraw_modules)Úselfr§   r†   r©   Úrun_optsr‡   Úrun_opt_defaultsÚargÚdefaultÚ_Údevice_indexrQ   r±   Úgradscaler_enabledÚtrain_dtypeÚ
eval_dtypes                   rW   Ú__init__ÚBrain.__init__á   s½  € ð  $ˆÔØ"ŒØ(ÔÜ�h¤×%Ñ%Ü!×1Ò1°(Ó;ˆHô &›<ÐØ,×4Ñ4Ó6×<Ñ<Ö>‰LˆCØÑ#¨×/GÑ/GÓ(GØÑ&¨3«>Ü—K‘KØ˜%ÐMÐNØ6°x±}°oÐFñGôô ˜ 8¡=Ö1ð Ñ$¨«Ü—‘˜k¨#¨Ð.CÐDÔEÜ˜ 7¡<Ö0ä˜ 7Ö+ñ ?ô& ×Ñ×"Ñ"Ô&:Ó:Ü× Ñ ×&Ñ&Ô*>Ó>ä�N‰NØ"Ü”c×&Ñ&×,Ñ,Ó-ñ.àñô ”c×&Ñ&×,Ñ,Ó-ñ.ð Bñ	Bô
 Ô*Ó+ñ,ð ñô Ô*Ó+ñ,ô	ô �J‰J�N‰N˜6Ó"¨$Ð.÷ 9Ü—
‘
—‘˜|Ó,°DÐ8ð 	Ôð
 ×%×%¨$×*A×*AÜðAóð ð ×%Ñ%¨Ó)¨d×.FÑ.FÈÓ.JÜ�HŠHðBôð �;‰;ÑÜŸ(™(×.Ñ.×;Ñ;Ó=ˆDŒKð �;‰;˜%ÓØ$ˆDÕØ�t—{‘{Ó"Ø%ˆDÔð)Ø"&§+¡+×"3Ñ"3°CÓ"8‘�Ü—
‘
×%Ñ%¤c¨,Ó&7Õ8ð  $Ÿ{™{×0Ñ0°Ó5°aÑ8ˆDÔð ×%×%¬%¯*©*×*AÑ*AÓ*CÀqÓ*HÜÐOÓPÐPô —x‘x×*Ñ*¨7Ó3×6Ñ6°t·{±{ÓCˆŒð —l”lˆFÜ�t—|‘| FÑ+¨T×2Ó2Ø'+§|¡|°FÑ';×'>Ñ'>¸t¿{¹{Ó'K�—‘˜VÓ$ñ #ð
 ÑÜ*Ñ5¨WÑ5ˆDŒLð �J�JØ×+×+Ø×!Ñ!Ñ-Ü˜×)Ñ)Ð+<×=Ñ=ä×1Ò1Ó3ˆGÜ�K‰Kð2Ø29·,±,°ðAôô 18·²¸W¿\¹\Ó0JˆD×ÑÔ-ð )0×ÑÔ%ð "ˆÔà××Ü�N‰Nð9ôð $ˆDŒNà×!×!Ü�N‰Nð9ôð $ˆDŒNà×Ñ˜uÓ$Ø�N‰N˜fÓ$¨×(;Ñ(;¸vÓ(Eäð4óð ð �N‰N˜fÑ$×C¨×)9Ñ)9¸VÑ)Cð 	ð ×$×$Ö);Ü�N‰Nð,ôô 	�‰Ð+Ð,>Ð+?¸qÐAÔBÜ�‰Ð=¸d¿n¹nÐ=MÈQÐOÔPÜ�‰Ø<¸T×=PÑ=PÐ<QÐQRÐSô	
ô �=Š=œ×*Ñ*Ó+¬g¯mªm¸GÓ.DÓDÜŸ*™*Ÿ.™.×3Ñ3Ð<NÐ3ÐOˆD�Kä×*Ò*Ø—‘Ð%7ñˆDŒKô  ×)Ò)¨$¯.©.Ó9×?Ñ?ˆÜ)Ø×(Ñ(°ñ
ˆÔô ×(Ò(¨×)<Ñ)<Ó=×CÑCˆ
Ü+Ø×(Ñ(°
ñ
ˆÔö  $×"3Ñ"3Ñ"?Ø×Ñ×-Ñ-Ø˜$Ÿ+™+°Tð .ñ ð
 	×'Ñ'Ô)à×"×"ÜœBŸJ™J vÑ.Ó/ˆDŒIÜ-×/Ñ/Ø—9‘9˜q“=Ü$ðIóð ô —N‘NðQôô —K‘Kð<ôð "ˆÔØˆŒ	ØˆÔð ×ÑÑ(Ø×Ñ×-Ñ-¨g°tÔ<ð ×$×$Ü!%§¡¨t×/AÑ/AÀ2Ó!FˆDÔð ˆŒØ× × Ü�K‰KÐ>Ô?Ø#'×#5Ñ#5¸×8KÑ8KÑ#KÈqÑ"PˆDÔÜ,Ø×#Ñ#Ø×"Ñ"Ø—‘×*Ñ*óˆDŒMô �t—|‘| X×.Ñ.ð �L‰L×Ñð 	Õð —‘ð 	Õøôo ó )Ü—
‘
×%Ñ% a×(ð)ús   ËAe/ å/)fæfc           
      ó*  • SnSnU R                   R                  5        H:  nX#R                  5       -  nUR                  (       d  M(  XR                  5       -  nM<     U R                  R
                  nUS:X  a8  [        R                  S5        [        R                  U SU SU SSS S35        gUS:X  aa  [        R                  S5        [        R                  R                  R                  U5      n[        R                  U SU SU SSS	 S35        gS
U-  U-  n[        R                  R                  R                  U5      n[        R                  R                  R                  U5      n[        R                  U SU SU SUS	 S35        g)z7Prints the number of trainable parameters in the model.r   zThe model has no parameters!z; Model Statistics:
* Total Number of Trainable Parameters: z
* Total Number of Parameters: z"
* Trainable Parameters represent z.2fz% of the total size.z&The model has no trainable parameters!z.4féd   N)r§   Ú
parametersÚnumelÚrequires_gradÚ	__class__rd   r>   r”   rE   r(   r)   Úformat_order_of_magnitude)rÏ   Útotal_trainable_paramsÚtotal_parametersÚ	parameterÚ
class_nameÚformatted_total_paramsÚpercentage_trainableÚformatted_trainable_paramss           rW   rÀ   Ú Brain.print_trainable_parametersÔ  s½  € à!"ÐØÐØŸ™×0Ñ0Ö2ˆIØ§¡Ó 1Ñ1ÐØ×&×&Ñ&Ø&¯/©/Ó*;Ñ;Ò&ñ 3ð —^‘^×,Ñ,ˆ
Ø˜qÓ Ü�N‰NÐ9Ô:Ü�K‰KØ�,ð ;Ø;QÐ:Rð S1Ø1AÐ0Bð C4Ø45°c°7Ð:NðPõð $ qÓ(Ü�N‰NÐCÔDÜ%'§X¡X§_¡_×%NÑ%NØ ó&Ð"ô �K‰KØ�,ð ;Ø;QÐ:Rð S1Ø1GÐ0Hð I4Ø45°c°7Ð:NðPõð Ð,Ñ,Ð/?Ñ?ð !ô —‘—‘×9Ñ9Ø*óð 'ô
 &(§X¡X§_¡_×%NÑ%NØ ó&Ð"ô �K‰KØ�,ð ;Ø;UÐ:Vð W1Ø1GÐ0Hð I4Ø4HÈÐ3MÐMaðcõr_   c                 ó   • [         e)a�  Forward pass, to be overridden by sub-classes.

Arguments
---------
batch : torch.Tensor or tensors
    An element from the dataloader, including inputs for processing.
stage : Stage
    The stage of the experiment: Stage.TRAIN, Stage.VALID, Stage.TEST

Returns
-------
torch.Tensor or torch.Tensors
    The outputs after all processing is complete.
    Directly passed to ``compute_objectives()``.
©ÚNotImplementedError)rÏ   ÚbatchÚstages      rW   Úcompute_forwardÚBrain.compute_forward  s
   € ô  "Ð!r_   c                 ó   • [         e)aÑ  Compute loss, to be overridden by sub-classes.

Arguments
---------
predictions : torch.Tensor or torch.Tensors
    The output tensor or tensors to evaluate.
    Comes directly from ``compute_forward()``.
batch : torch.Tensor or tensors
    An element from the dataloader, including targets for comparison.
stage : Stage
    The stage of the experiment: Stage.TRAIN, Stage.VALID, Stage.TEST

Returns
-------
loss : torch.Tensor
    A tensor with the computed loss.
rë   )rÏ   Úpredictionsrí   rî   s       rW   Úcompute_objectivesÚBrain.compute_objectives  s
   € ô$ "Ð!r_   c                 ó   • g)zïGets called when a stage starts.

Useful for defining class variables used during the stage.

Arguments
---------
stage : Stage
    The stage of the experiment: Stage.TRAIN, Stage.VALID, Stage.TEST
epoch : int
    The current epoch count.
Nrc   )rÏ   rî   Úepochs      rW   Úon_stage_startÚBrain.on_stage_start+  s   € ð 	r_   c                 ó   • g)a8  Gets called at the end of a stage.

Useful for computing stage statistics, saving checkpoints, etc.

Arguments
---------
stage : Stage
    The stage of the experiment: Stage.TRAIN, Stage.VALID, Stage.TEST
stage_loss : float
    The average loss over the completed stage.
epoch : int
    The current epoch count.
Nrc   )rÏ   rî   Ú
stage_lossrö   s       rW   Úon_stage_endÚBrain.on_stage_end9  ó   € ð 	r_   c                 ó€  • U[         R                  R                  :X  a  U R                  X5      n[         R                  R
                  R                  " U40 UD6nU R                  bV  UbS  [        U[        5      (       d  [        U[        5      (       a)  X2R                  -   nU R                  R                  Xe5        U$ )a  Creates DataLoaders for Datasets.

This is used by ``fit()`` and ``evaluate()`` if they just receive
Datasets.

Alternatively, this can be called from outside the Brain subclass.
In that case, the DataLoader should be passed to ``fit()`` in place
of the dataset.

The Stage.TRAIN DataLoader is handled specially. It has extra args for
shuffle and drop_last. In DDP a DistributedSampler is created (unless
the dataset is an IterableDataset).

NOTE
----
Some important DataLoader arguments are passed via **loader_kwargs,
e.g., batch_size, num_workers, pin_memory.

NOTE
----
By default, ``evaluate()`` specifies ckpt_prefix=None to stop the test
DataLoader being added to the checkpointer. If you need to add a
recoverable after saving checkpoints (e.g., at test time, after
checkpointing the training), and still be able to recover reasonably,
you should probably specify ``allow_partial_load=True``.

Arguments
---------
dataset : Dataset
    A set of data to use to create data loader. If the Dataset is a
    DynamicItemDataset, PaddedBatch is used as the default collate_fn,
    unless specified in loader_kwargs.
stage : Stage
    The stage of the experiment: Stage.TRAIN, Stage.VALID, Stage.TEST
ckpt_prefix : str, None
    Prefix to use for SaveableDataLoader Checkpoint name. The Stage
    name is added to this to create the full key. Set to None to not
    save the DataLoader.
**loader_kwargs : dict
    Additional keyword arguments to the DataLoader.
    E.g., batch_size, num_workers, pin_memory.

Returns
-------
DataLoader for the input dataset
)r(   ra   ri   Ú_train_loader_specificsÚdataioÚ
dataloaderÚmake_dataloaderr‡   rˆ   r   r   r®   r¿   )rÏ   Údatasetrî   Úckpt_prefixÚloader_kwargsr  Úckpt_keys          rW   r  ÚBrain.make_dataloaderI  s£   € ðd ”B—H‘H—N‘NÓ"Ø ×8Ñ8¸ÓPˆMô —Y‘Y×)Ñ)×9Ò9Øñ
Ø$ñ
ˆ
ð
 ×ÑÑ)ØÑ'ä˜:Ô'9×:Ñ:Ü˜j¬,×7Ñ7ð #§Z¡ZÑ/ˆHØ×Ñ×-Ñ-¨hÔCØÐr_   c                 óØ  • UR                  SS 5      nUR                  SS5      nU(       a`  U R                  (       dO  Ub  [        S5      e[        R                  R                  SS5      n[        XS9nX0l        U R                  US'   US	 U R                  (       Ga  [        U[        5      (       dü  [        U R                  S5      (       a  U R                  R                  S	:H  nOS
nUR                  SS5      nUb1  [        UU R                  UUS9U l        SUS'   U R                  US'   U$ UR                  S5      c1  [        UU R                  UUS9U l        SUS'   U R                  US'   U$ [        UR                  SS 5      U R                  US9U l        U R                  US'    U$ U R                  (       a*  [        U[        5      (       a  [        R!                  S5        U$ )NÚsamplerÚshuffleFz>Cannot specify both shuffle=Trueand a sampler in loader_kwargsÚSB_GLOBAL_SEEDi&l”!)ÚseedÚsortingÚrandomTÚ	drop_last)rÁ   r  r
  Úbatch_sampler)rÁ   r
  r  )rÁ   r
  zDCannot automatically solve distributed sampling for IterableDataset.)r—   r˜   rš   r,   r–   r   r²   rˆ   r   r¨   r©   r  r   rÁ   r   r>   r”   )rÏ   r  r  r	  r
  r  Úshuffle_ddpr  s           rW   rÿ   ÚBrain._train_loader_specifics“  s÷  € Ø×#Ñ# I¨tÓ4ˆð  ×#Ñ# I¨uÓ5ˆÞ˜4×2×2ØÑ"Ü ð5óð ô —:‘:—>‘>Ð"2°IÓ>ˆDÜ/°ÑCˆGØ!(ÔØ'+×'9Ñ'9ˆM˜)Ñ$ð ˜iÐ(ð ×"×"Ð"¬:°g¼×+OÑ+Oä�t—|‘| Y×/Ñ/à—L‘L×(Ñ(¨HÑ4ñ ð #�à%×)Ñ)¨+°uÓ=ˆIð Ñ"Ü%>ØØŸ™Ø'Ø#ñ	&�Ô"ð ,1�˜iÑ(Ø+/×+=Ñ+=�˜iÑ(ð2 Ðð1 ×"Ñ" ?Ó3Ñ;ä%7ØØŸ™Ø'Ø'ñ	&�Ô"ð ,1�˜iÑ(Ø+/×+=Ñ+=�˜iÑ(ð Ðô &?Ø!×%Ñ% o°tÓ<ØŸ™Ø'ñ&�Ô"ð
 26×1CÑ1C�˜oÒ.ð Ðð ×$×$¬°G¼_×)MÑ)MÜ�N‰Nð'ôð Ðr_   c                 ó´   • U R                  5         U R                  5         U R                  5         U R                  b  U R                  R	                  5         gg)zðGets called at the beginning of ``fit()``, on multiple processes
if ``distributed_count > 0`` and backend is ddp.

Default implementation compiles the jit modules, initializes
optimizers, and loads the latest checkpoint to resume training.
N)Ú_compileÚ_wrap_distributedÚinit_optimizersr‡   Úrecover_if_possible©rÏ   s    rW   Úon_fit_startÚBrain.on_fit_startÚ  sN   € ð 	�‰Œð 	×ÑÔ ð 	×ÑÔð ×ÑÑ(Ø×Ñ×1Ñ1Õ3ð )r_   c                 ó„  • U R                   R                  5       nU R                  b„  U R                  (       a  [	        U R                   5      nU R                  U5      U l        SU R
                  0U l        U R                  b'  U R                  R                  SU R
                  5        gg[        R                  S5        g)a«  Called during ``on_fit_start()``, initialize optimizers
after parameters are fully configured (e.g. DDP, jit).

The default implementation of this method depends on an optimizer
class being passed at initialization that takes only a list
of parameters (e.g., a lambda or a partial function definition).
This creates a single optimizer that optimizes all trainable params.

Override this class if there are multiple optimizers.
Nr†   Ú	optimizerzSNo `opt_class` was provided to this Brain class, skipping optimizer initialization.)r§   rÝ   r†   Úremove_vector_weight_decayr   r  r…   r‡   r¿   r>   rE   )rÏ   Ú
all_paramss     rW   r  ÚBrain.init_optimizersï  s–   € ð —\‘\×,Ñ,Ó.ˆ
à�>‰>Ñ%Ø×.×.Ü3°D·L±LÓA�
à!Ÿ^™^¨JÓ7ˆDŒNà$/°·±Ð#@ˆDÔ à× Ñ Ñ,Ø×!Ñ!×1Ñ1°+¸t¿~¹~ÕNð -ô �K‰Kð5õr_   c                 óì   • U R                   b@  U R                  U R                   5      R                  5        H  nUR                  US9  M     gU R                  b  U R
                  R                  US9  gg)zêSets the gradients of all optimized ``torch.Tensor``s to zero
if ``set_to_none=False`` (default) or to None otherwise.

Setting gradients to None should save the memory, e.g.
during ``evaluate()`` and thus larger batch might be used.
N©Úset_to_none)r…   Úfreeze_optimizersÚvaluesÚ	zero_gradr†   r  )rÏ   r"  Úopts      rW   r%  ÚBrain.zero_grad  sg   € ð ×ÑÑ+Ø×-Ñ-¨d×.BÑ.BÓC×JÑJÖL�Ø—‘¨+�Ó6ò Mà�^‰^Ñ'Ø�N‰N×$Ñ$°Ð$Ò=ð (r_   c                 óR   • U R                   b  U R                   R                  XS9  gg)aÑ  Gets called at the beginning of ``evaluate()``

Default implementation loads the best-performing checkpoint for
evaluation, based on stored metrics.

Arguments
---------
max_key : str
    Key to use for finding best checkpoint (higher is better).
    By default, passed to ``self.checkpointer.recover_if_possible()``.
min_key : str
    Key to use for finding best checkpoint (lower is better).
    By default, passed to ``self.checkpointer.recover_if_possible()``.
N©Úmax_keyÚmin_key)r‡   r  )rÏ   r*  r+  s      rW   Úon_evaluate_startÚBrain.on_evaluate_start  s1   € ð" ×ÑÑ(Ø×Ñ×1Ñ1Øð 2ò ð )r_   c                 óÔ  • U R                   U R                  -  S:H  nU R                  X5        U R                  U(       + 5         U R                     U R                  U[        R                  R                  5      nU R                  X1[        R                  R                  5      nSSS5        U R                  R                  WU R                  -  5      nU R                  U5        UR                  5         SSS5        U(       a  U R                  5         U R                  UWWU5        UR!                  5       R#                  5       $ ! , (       d  f       N¨= f! , (       d  f       Nh= f)aå  Fit one batch, override to do multiple updates.

The default implementation depends on a few methods being defined
with a particular behavior:

* ``compute_forward()``
* ``compute_objectives()``
* ``optimizers_step()``

Also depends on having optimizers passed at initialization.

Arguments
---------
batch : list of torch.Tensors
    Batch of data to use for training. Default implementation assumes
    this batch has two elements: inputs and targets.

Returns
-------
detached loss
r   N)rÃ   Úgrad_accumulation_factorÚon_fit_batch_startÚno_syncr½   rï   r(   ra   ri   ró   r   ÚscaleÚcheck_loss_isfiniteÚbackwardÚoptimizers_stepÚon_fit_batch_endÚdetachrt   )rÏ   rí   Úshould_stepÚoutputsÚlossÚscaled_losss         rW   Ú	fit_batchÚBrain.fit_batch0  s  € ð, —y‘y 4×#@Ñ#@Ñ@ÀQÑFˆØ×Ñ Ô3à�\‰\˜kœ/Õ*Ø×"Ó"Ø×.Ñ.¨u´b·h±h·n±nÓE�Ø×.Ñ.¨w¼r¿x¹x¿~¹~ÓN�÷ #ð Ÿ+™+×+Ñ+Ø�t×4Ñ4Ñ4óˆKð ×$Ñ$ [Ô1Ø× Ñ Ô"÷ +ö Ø× Ñ Ô"à×Ñ˜e W¨d°KÔ@Ø�{‰{‹}× Ñ Ó"Ð"÷ #Õ"ú÷ +Õ*ús&   ÁEÁAEÂ&AEÅ
E	ÅEÅ
E'c                 óÚ   • [         R                  " U5      (       dP  U =R                  S-  sl        U R                  U R                  :”  a  [	        S5      e[
        R                  S5        gg)a"  Check if the loss is finite.

If the loss is not finite, log a helpful message and increment the `nonfinite_count`.
If the `nonfinite_count` exceeds the `--nonfinite_patience` threshold, stop the training
and raise an error.

This check is particularly useful when the loss becomes NaN or inf, while the
parameters and gradients remain finite. It helps prevent getting stuck in an
infinite loop during training.

Arguments
---------
loss : tensor
    The loss tensor after ``backward()`` has been called but
    before the optimizers ``step()``.
r„   z¤Loss is not finite and patience is exhausted. To debug, wrap `fit()` with autograd's `detect_anomaly()`, e.g.

with torch.autograd.detect_anomaly():
	brain.fit(...)zPatience not yet exhausted.N)r¡   ÚisfiniteÚnonfinite_countÚnonfinite_patiencerš   r>   r”   )rÏ   r:  s     rW   r3  ÚBrain.check_loss_isfiniteY  sa   € ô" �~Š~˜d×#Ñ#Ø× Ò  AÑ%Õ ð ×#Ñ# d×&=Ñ&=Ó=Ü ðIóð ô —‘Ð<Õ=ð $r_   c                 óH  • U R                   R                  5        H„  nUR                  (       d  M  UR                  c  M%  [        R
                  " UR                  5      R                  5       (       a  MZ  SUl        [        R                  SUR                   S35        M†     g)zXChecks if the gradients are finite. If not, it will emit a warning and set them to zero.Nz
Gradients z% contain NaN or Inf. Setting to None.)
r§   rÝ   rß   Úgradr¡   r?  Úallr>   r”   r®   )rÏ   Úparams     rW   Úcheck_gradientsÚBrain.check_gradientsx  sn   € à—\‘\×,Ñ,Ö.ˆEØ×"×"Ñ" u§z¡zÓ'=Ü—~’~ e§j¡jÓ1×5Ñ5×7Ó7Ø!%�E”JÜ—N‘NØ$ U§Z¡Z LÐ0UÐVöò	 /r_   c                 ó   • U$ )z¬By default, this method returns the passed optimizers.
Override this method if you want to freeze some optimizers
during training. To do so, return a of active optimizers.
rc   )rÏ   Ú
optimizerss     rW   r#  ÚBrain.freeze_optimizers‚  s
   € ð
 Ðr_   c                 ó8  • U R                   b  U R                  U R                   5      nOU R                  b  SU R                  0nOgUR	                  5        H  nU R
                  R                  U5        M      UR	                  5        HG  n[        R                  R                  R                  UR                  S   S   U R                  5        MI     U R
                  R                  5       (       d!  U R                  (       a  U R                  5         UR	                  5        H  nU R
                  R!                  U5        M      U R
                  R#                  5         UR	                  5        H  nUR%                  SS9  M     U =R&                  S-  sl        g)zvPerforms a step of gradient descent on the optimizers. This method is called every
``grad_accumulation_factor`` steps.Nr  r   ÚparamsTr!  r„   )r…   r#  r†   r  r$  r   Úunscale_r¡   r¥   r)   Úclip_grad_norm_Úparam_groupsÚmax_grad_normÚ
is_enabledr·   rG  rÃ   Úupdater%  rÄ   )rÏ   Úvalid_optimizersr&  s      rW   r5  ÚBrain.optimizers_step‰  sJ  € ð ×ÑÑ+Ø#×5Ñ5°d×6JÑ6JÓKÑØ�^‰^Ñ'ð !,¨T¯^©^Ð<Ñð
 ð $×*Ñ*Ö,ˆCØ�K‰K× Ñ  Ö%ñ -ð $×*Ñ*Ö,ˆCÜ�H‰H�N‰N×*Ñ*Ø× Ñ  Ñ# HÑ-¨t×/AÑ/Aöñ -ð �{‰{×%Ñ%×'Ñ'¨D×,E×,EØ× Ñ Ô"ð $×*Ñ*Ö,ˆCØ�K‰K×Ñ˜SÖ!ñ -ð 	�‰×ÑÔà#×*Ñ*Ö,ˆCØ�M‰M dˆMÓ+ñ -ð 	×Ò˜qÑ Ör_   c                 ó   • g)a¯  Called at the beginning of ``fit_batch()``.

This method is not called under the AMP context manager. Do not assume
automatic casting of the input batch to a lower precision (e.g. fp16).

Arguments
---------
batch : list of torch.Tensors
    Batch of data to use for training. Default implementation assumes
    this batch has two elements: inputs and targets.
should_step : boolean
    Whether optimizer.step() was called or not.
Nrc   )rÏ   rí   r8  s      rW   r0  ÚBrain.on_fit_batch_start¸  rý   r_   c                 ó   • g)a©  Called after ``fit_batch()``.

Arguments
---------
batch : list of torch.Tensors
    Batch of data to use for training. Default implementation assumes
    this batch has two elements: inputs and targets.
outputs : list or dictionary of torch.Tensors
    Returned value of compute_forward().
loss : torch.Tensor
    Returned value of compute_objectives().
should_step : boolean
    Whether optimizer.step() was called or not.
Nrc   )rÏ   rí   r9  r:  r8  s        rW   r6  ÚBrain.on_fit_batch_endÈ  s   € ð 	r_   c                 óÈ   • U R                      U R                  XS9nU R                  X1US9nSSS5        WR                  5       R	                  5       $ ! , (       d  f       N,= f)aè  Evaluate one batch, override for different procedure than train.

The default implementation depends on two methods being defined
with a particular behavior:

* ``compute_forward()``
* ``compute_objectives()``

Arguments
---------
batch : list of torch.Tensors
    Batch of data to use for evaluation. Default implementation assumes
    this batch has two elements: inputs and targets.
stage : Stage
    The stage of the experiment: Stage.VALID, Stage.TEST

Returns
-------
detached loss
©rî   N)r¾   rï   ró   r7  rt   )rÏ   rí   rî   Úoutr:  s        rW   Úevaluate_batchÚBrain.evaluate_batchÙ  sZ   € ð, × Ó Ø×&Ñ& uÐ&Ð:ˆCØ×*Ñ*¨3¸UÐ*ÐCˆD÷ !ð �{‰{‹}× Ñ Ó"Ð"÷ !Õ ús   � AÁ
A!c                 óÐ  • U R                  [        R                  U5        U R                  R	                  5         U R                  5         SU l        U R                  b6  [        U R                  S5      (       a  U R                  R                  U5        [        R                  " 5       nSn[        UU R                  SU(       + U R                  S   S9 nU R                  b  U R                  R                  5         U GH‚  nU R                   (       a  ["        R%                  S5          GOZU =R                  S-  sl        US-  nU R'                  U5      nU R)                  X€R*                  5      U l        UR-                  U R*                  S9  U R                  bw  U R                  R                  5         U R                  R.                  U R0                  :”  a9  ["        R%                  S	5        U R                  R3                  5         [5        5         U R6                  (       a  U R                  U R8                  :X  a    OEU R;                  XE5      (       d  GM[  U R=                  5         [        R                  " 5       nSnGM…     S S S 5        U R                  SS
9  U R?                  [        R                  U R*                  U5        SU l        SU l        g ! , (       d  f       NW= f)Nr   Ú	set_epochTÚtrain)ÚinitialÚdynamic_ncolsÚdisableÚcolourzTrain iteration limit exceededr„   )Ú
train_lossz+The profiler finished, training is stopped.r!  r�   ) r÷   ra   ri   r§   ra  r%  r@  r²   r¨   r`  Útimer   rÃ   rÇ   rÈ   ÚstartÚ_optimizer_step_limit_exceededr>   rE   r<  Úupdate_averagerÂ   Úset_postfixÚstep_numrÌ   ÚstopÚquitrª   Údebug_batchesÚ_should_save_intra_epoch_ckptÚ_save_intra_epoch_ckptrû   )	rÏ   Ú	train_setrö   ÚenableÚlast_ckpt_timeÚsteps_since_ckptÚtrí   r:  s	            rW   Ú
_fit_trainÚBrain._fit_trainô  s?  € à×ÑœEŸK™K¨Ô/Ø�‰×ÑÔØ�‰Ôð  !ˆÔà×ÑÑ)¬gØ×Ñ ÷/
ñ /
ð ×Ñ×(Ñ(¨Ô/ô Ÿš›ˆØÐÜØØ—I‘IØØ”JØ×%Ñ% gÑ.ò
ð Ø�}‰}Ñ(Ø—‘×#Ñ#Ô%Ü�Ø×6×6Ü—K‘KÐ @ÔAÚØ—	’	˜Q‘•	Ø  AÑ%Ð Ø—~‘~ eÓ,�Ø&*×&9Ñ&9Ø×-Ñ-ó'�Ô#ð —‘¨×)<Ñ)<�Ñ=à—=‘=Ñ,Ø—M‘M×&Ñ&Ô(Ø—}‘}×-Ñ-°×0CÑ0CÓCÜŸ™ØIôð Ÿ™×*Ñ*Ô,Üœð —:—: $§)¡)¨t×/AÑ/AÓ"AÙà×5Ñ5Ø"÷ô ð ×/Ñ/Ô1Ü%)§Y¢Y£[�NØ'(Ó$ñ? ÷
ðV 	�‰ 4ˆÑ(Ø×Ñœ%Ÿ+™+ t×':Ñ':¸EÔBØ!ˆÔØˆ�	÷]
õ 
ús   ÃF KÉ,KË
K%c                 ó’  • U R                   c  gU R                  S::  a  U R                  S::  a  g[        R                  " 5       U-
  S-  nSU R                  s=:  =(       a    U:  Os  nU=(       d    SU R                  s=:  =(       a    U:*  Os  n[	        5       (       d  U$ U/n[
        R                  R                  USS9  US   $ )z‡Determines if an intra-epoch checkpoint should be saved.

Returns True if there's a checkpointer and time or steps has exceeded limit.
Fr   g      N@)Úsrc)r‡   r›   rœ   rg  r   r¡   r*   Úbroadcast_object_list)rÏ   rt  ru  Úelapsed_minutesÚdecisionÚbroadcast_lists         rW   rp  Ú#Brain._should_save_intra_epoch_ckpt5  s¿   € ð
 ×ÑÑ$Øð ×%Ñ%¨Ó*¨t×/GÑ/GÈ1Ó/LØô  Ÿ9š9›;¨Ñ7¸4Ñ?ˆØ�t×1Ñ1×CÓC°OÔCˆð ×O˜q 4×#;Ñ#;×OÓOÐ?OÔOˆô *×+Ñ+ØˆOð '˜ZˆNÜ×Ñ×3Ñ3°NÈÐ3ÑJØ! !Ñ$Ð$r_   c                 ób  • UGb  U R                  [        R                  U5        U R                  R	                  5         Sn[
        R                  " 5          [        USU(       + U R                  S   S9 Hv  nU =R                  S-  sl	        U R                  U[        R                  S9nU R                  Xd5      nU R                  (       d  MZ  U R                  U R                  :X  d  Mv    O   SU l	        U R                  [        R                  XB5        S S S 5        g g ! , (       d  f       g = f)Nr�   TÚvalid©rc  rd  re  r„   r[  r   )r÷   ra   rj   r§   Úevalr¡   Úno_gradr   rÇ   rÃ   r]  rj  rª   ro  rû   )rÏ   Ú	valid_setrö   rs  Úavg_valid_lossrí   r:  s          rW   Ú
_fit_validÚBrain._fit_validT  sê   € àÒ Ø×Ñ¤§¡¨UÔ3Ø�L‰L×ÑÔØ ˆNÜ—’•Ü!ØØ"&Ø &œJØ×-Ñ-¨gÑ6ô	�Eð —I’I ‘N•IØ×.Ñ.¨u¼E¿K¹KÐ.ÐH�DØ%)×%8Ñ%8¸Ó%N�Nð —z—z‘z d§i¡i°4×3EÑ3EÕ&EÙñð �”	Ø×!Ñ!¤%§+¡+¨~ÔE÷! !�ð	 !÷ !•ús   ÁA5D ÃD Ã++D Ä 
D.c                 ó  • U R                   (       a  [        R                  S5        g[        U[        5      (       dB  [        U[
        5      (       d-  U R                  " U4S[        R                  R                  0UD6nUbX  [        U[        5      (       dC  [        U[
        5      (       d.  U R                  " U4[        R                  R                  SS.UD6nU R                  5         Uc  U R                  (       + nU=(       a(    [        R                  R                  R                  5       nU HV  nU R!                  X(US9  U R#                  X8US9  U R$                  (       a  X€R&                  :X  d  U R(                  (       d  MV    g   g)a  Iterate epochs and datasets to improve objective.

Relies on the existence of multiple functions that can (or should) be
overridden. The following methods are used and expected to have a
certain behavior:

* ``fit_batch()``
* ``evaluate_batch()``
* ``update_average()``

If the initialization was done with distributed_count > 0 and the
distributed_backend is ddp, this will generally handle multiprocess
logic, like splitting the training data into subsets for each device and
only saving a checkpoint on the main process.

Arguments
---------
epoch_counter : iterable
    Each call should return an integer indicating the epoch count.
train_set : Dataset, DataLoader
    A set of data to use for training. If a Dataset is given, a
    DataLoader is automatically created. If a DataLoader is given, it is
    used directly.
valid_set : Dataset, DataLoader
    A set of data to use for validation. If a Dataset is given, a
    DataLoader is automatically created. If a DataLoader is given, it is
    used directly.
progressbar : bool
    Whether to display the progress of each epoch in a progressbar.
train_loader_kwargs : dict
    Kwargs passed to `make_dataloader()` for making the train_loader
    (if train_set is a Dataset, not DataLoader).
    E.G. batch_size, num_workers.
    DataLoader kwargs are all valid.
valid_loader_kwargs : dict
    Kwargs passed to `make_dataloader()` for making the valid_loader
    (if valid_set is a Dataset, not DataLoader).
    E.g., batch_size, num_workers.
    DataLoader kwargs are all valid.

Returns
-------
None
z8Test only mode, skipping training and validation stages.Nrî   )rî   r  )rr  rö   rs  )r…  rö   rs  )Ú	test_onlyr>   rE   rˆ   r   r   r  r(   ra   ri   rj   r  Únoprogressbarr)   r*   r+   rw  r‡  rª   Údebug_epochsri  )	rÏ   Úepoch_counterrr  r…  ÚprogressbarÚtrain_loader_kwargsÚvalid_loader_kwargsrs  rö   s	            rW   ÚfitÚ	Brain.fitl  sJ  € ðj �>�>Ü�K‰KØJôð ô �y¤*×-Ñ-Ü˜)¤\×2Ñ2à×,Ò,ØñÜ!#§¡§¡ðØ3FñˆIð Ñ Ü�y¤*×-Ñ-Ü˜)¤\×2Ñ2à×,Ò,Øðä—h‘h—n‘nØ ñð &ñ	ˆIð 	×ÑÔàÑØ"×0Ñ0Ô0ˆKð ×G¤§¡×!5Ñ!5×!EÑ!EÓ!Gˆó #ˆEØ�O‰O iÀVˆOÑLØ�O‰O iÀVˆOÑLð —
—
Ø×.Ñ.Ó.Ø×6×6Ñ6áò #r_   c                 ó^   • U R                   S L=(       a    U R                  U R                   :¬  $ ©N)Úoptimizer_step_limitrÄ   r  s    rW   ri  Ú$Brain._optimizer_step_limit_exceededÎ  s1   € ð ×%Ñ%¨TÐ1÷ AØ×#Ñ# t×'@Ñ'@Ñ@ð	
r_   c                 óh   • U R                   R                  SSS [        S0[        R                  S9  g)z,Saves a CKPT with specific intra-epoch flag.Fr„   c                 ó(   • [         U R                  ;   $ r”  )ÚINTRA_EPOCH_CKPT_FLAGÚmeta)Úcs    rW   Ú<lambda>Ú.Brain._save_intra_epoch_ckpt.<locals>.<lambda>Ú  s   € Ô%:¸a¿f¹fÒ%Dr_   T)Úend_of_epochÚnum_to_keepÚckpt_predicaterš  Ú	verbosityN)r‡   Úsave_and_keep_onlyr™  ÚloggingÚDEBUGr  s    rW   rq  ÚBrain._save_intra_epoch_ckptÕ  s3   € à×Ñ×,Ñ,ØØÙDÜ'¨Ð.Ü—m‘mð 	-ò 	
r_   c                 ó€  • [        [        S5      nU(       d  U R                  b  [        S5      e[	        5       nU R
                  (       aM  U R                  c  [	        U R                  5      nO*[	        U R                  5      n[        R                  S5        [	        5       nU R                  (       aM  U R                  c  [	        U R                  5      nO*[	        U R                  5      n[        R                  S5        X#-   H!  nX@R                  ;  d  M  [        SU S35      e   U H  n [        R
                  " U R                  U   U R                  U R                  U R                  S9nUR                  U R                   5      U R                  U'   UR#                  U5        M�     U HW  n[        R                  R%                  U R                  U   5      nUR                  U R                   5      U R                  U'   MY     g! [         a'  n[        R                  S	U S
U 35         SnAGM  SnAff = f)z;Compile requested modules with either JIT or TorchInductor.ÚcompileNz_'compile_module_keys' specified, but this install of PyTorch seems to be too old to support it.zy--compile and --compile_module_keys are both specified. Only modules specified in --compile_module_keys will be compiled.zm--jit and --jit_module_keys are both specified. Only modules specified in --jit_module_keys will be compiled.zmodule z% is not defined in your hparams file.)ÚmodeÚ	fullgraphÚdynamicÚ'zh' in 'compile_module_keys' failed to compile and will be skipped (may fallback onto JIT, if specified): )r¨   r¡   Úcompile_module_keysrš   Úsetr§  r§   r>   r”   ÚjitÚjit_module_keysÚcompile_modeÚcompile_using_fullgraphÚ#compile_using_dynamic_shape_tracingÚ	Exceptionrw   rž   ÚdiscardÚscript)rÏ   Úcompile_availabler¬  r¯  r®   rQ   Úes          rW   r  ÚBrain._compileß  së  € ä#¤E¨9Ó5Ðæ  T×%=Ñ%=Ñ%IÜð5óð ô
 "›eÐØ�<�<Ø×'Ñ'Ñ/Ü&)¨$¯,©,Ó&7Ñ#ä&)¨$×*BÑ*BÓ&CÐ#Ü—‘ðXôô ›%ˆØ�8�8Ø×#Ñ#Ñ+Ü"% d§l¡lÓ"3‘ä"% d×&:Ñ&:Ó";�Ü—‘ðTôð (Ô9ˆDØŸ<™<Õ'Ü Ø˜d˜VÐ#HÐIóð ñ :ó (ˆDðÜŸšØ—L‘L Ñ&Ø×*Ñ*Ø"×:Ñ:Ø ×DÑDñ	�ð "(§¡¨4¯;©;Ó!7ˆD�L‰L˜ÑØ×#Ñ# DÖ)ñ# (ó& $ˆDÜ—Y‘Y×%Ñ% d§l¡l°4Ñ&8Ó9ˆFØ!'§¡¨4¯;©;Ó!7ˆD�L‰L˜Óò $øô ó Ü—‘Ø˜�vð #à#$ #ð'ôö
 ûðús   Ä/AHÈ
H=ÈH8È8H=c                 óœ  • U R                   (       d  U R                  (       d  gU R                   (       aµ  U R                  R                  5        H–  u  p[	        S UR                  5        5       5      (       d  M,  [        R                  " U5      nU R                  S:X  a  [        USU R                  S9nO [        UU R                  /U R                  S9nX R                  U'   M˜     gU R                  R                  5        HE  u  p[	        S UR                  5        5       5      (       d  M,  [        U5      nX R                  U'   MG     g)z5Wrap modules with distributed wrapper when requested.Nc              3   ó8   #   • U  H  oR                   v •  M     g 7fr”  ©rß   ©Ú.0Úps     rW   Ú	<genexpr>Ú*Brain._wrap_distributed.<locals>.<genexpr>%  ó   é € ÐDÒ0C¨1—–Ò0Cùó   ‚Úgloo)Ú
device_idsÚfind_unused_parametersc              3   ó8   #   • U  H  oR                   v •  M     g 7fr”  r»  r¼  s     rW   r¿  rÀ  7  rÁ  rÂ  )r˜   r™   r§   rŒ   ÚanyrÝ   r   Úconvert_sync_batchnormÚdistributed_backendÚDDPrÅ  rž   ÚDP)rÏ   r®   rQ   s      rW   r  ÚBrain._wrap_distributed  s  € à×&×&¨t×/I×/IØØ×$×$Ø $§¡× 2Ñ 2Ö 4‘�ÜÑD°×0AÑ0AÔ0CÓD×DÓDÜ*×AÒAÀ&ÓI�FØ×/Ñ/°6Ó9Ü!$Ø"Ø'+Ø37×3NÑ3Nñ"™ô "%Ø"Ø(,¯© }Ø37×3NÑ3Nñ"˜ð
 *0—L‘L Ó&ò !5ð$ !%§¡× 2Ñ 2Ö 4‘�ÜÑD°×0AÑ0AÔ0CÓD×DÓDÜ ›Z�FØ)/—L‘L Ó&ò !5r_   c                 ó¢  • Uc  U R                   (       + nU=(       a(    [        R                  R                  R	                  5       n[        U[        5      (       d<  [        U[        5      (       d'  SUS'   U R                  " U[        R                  40 UD6nU R                  X#S9  U R                  [        R                  SS9  U R                  R                  5         Sn[        R                   " 5          [#        USU(       + U R$                  S   S9 Hv  nU =R&                  S	-  sl        U R)                  U[        R                  S
9n	U R+                  X—5      nU R,                  (       d  MZ  U R&                  U R.                  :X  d  Mv    O   U R1                  [        R                  US5        SSS5        SU l        U$ ! , (       d  f       N= f)a]  Iterate test_set and evaluate brain performance. By default, loads
the best-performing checkpoint (as recorded using the checkpointer).

Arguments
---------
test_set : Dataset, DataLoader
    If a DataLoader is given, it is iterated directly. Otherwise passed
    to ``self.make_dataloader()``.
max_key : str
    Key to use for finding best checkpoint, passed to
    ``on_evaluate_start()``.
min_key : str
    Key to use for finding best checkpoint, passed to
    ``on_evaluate_start()``.
progressbar : bool
    Whether to display the progress in a progressbar.
test_loader_kwargs : dict
    Kwargs passed to ``make_dataloader()`` if ``test_set`` is not a
    DataLoader. NOTE: ``loader_kwargs["ckpt_prefix"]`` gets
    automatically overwritten to ``None`` (so that the test DataLoader
    is not added to the checkpointer).

Returns
-------
average test loss
Nr  r)  )rö   r�   TÚtestr‚  r„   r[  r   )r‹  r(   r)   r*   r+   rˆ   r   r   r  ra   rk   r,  r÷   r§   rƒ  r¡   r„  r   rÇ   rÃ   r]  rj  rª   ro  rû   )
rÏ   Útest_setr*  r+  rŽ  Útest_loader_kwargsrs  Úavg_test_lossrí   r:  s
             rW   ÚevaluateÚBrain.evaluate;  s{  € ðD ÑØ"×0Ñ0Ô0ˆKð ×G¤§¡×!5Ñ!5×!EÑ!EÓ!Gˆô �x¤×,Ñ,Ü˜(¤L×1Ñ1à04Ð˜}Ñ-Ø×+Ò+Øœ%Ÿ*™*ñØ(:ñˆHð 	×Ñ wÐÑ@Ø×ÑœEŸJ™J¨dÐÑ3Ø�‰×ÑÔØˆÜ�]Š]�_ÜØØ"Ø"œ
Ø×)Ñ)¨&Ñ1ô	�ð —	’	˜Q‘•	Ø×*Ñ*¨5¼¿
¹
Ð*ÐC�Ø $× 3Ñ 3°DÓ H�ð —:—:‘: $§)¡)¨t×/AÑ/AÕ"AÙñð ×ÑœeŸj™j¨-¸Ô>÷ ð  ˆŒ	ØÐ÷# �_ús   Ã5A5G Å.G Æ
%G Ç 
Gc                 ó”   • [         R                  " U5      (       a,  X"U R                  -  -  nU[        U5      U R                  -  -  nU$ )zÜUpdate running average of the loss.

Arguments
---------
loss : torch.tensor
    detached loss, a single float value.
avg_loss : float
    current running average.

Returns
-------
avg_loss : float
    The average loss.
)r¡   r?  rÃ   Úfloat)rÏ   r:  Úavg_losss      rW   rj  ÚBrain.update_average‚  s@   € ô �>Š>˜$×ÑØ 4§9¡9Ñ,Ñ,ˆHØœ˜d› d§i¡iÑ/Ñ/ˆHØˆr_   c              #   ód  #   • U(       a¡  / nU R                   R                  5        H8  n[        US5      (       d  M  UR                  UR                  5        SUl        M:     Sv •  SnU R                   R                  5        H$  n[        US5      (       d  M  X$   Ul        US-  nM&     gSv •  g7f)a  Copies pytorch's implementation for doing no_sync across all modules.

Explanation: nn.module.no_sync() is a context manager for when one does
not want to sync gradients, which happens when using both DDP and gradient accumulation.
Speechbrain brain's class can contain multiple modules and calling no_sync on these
individually would be very awkward, therefore this contextmanager exists.

Arguments
---------
use : bool
    If set to `False` will still sync gradients, useful to make behavior toggleable.

Yields
------
None
Úrequire_backward_grad_syncFNr   r„   )r§   r$  r¨   ÚappendrÙ  )rÏ   ÚuseÚold_values_listrQ   Úis        rW   r1  ÚBrain.no_sync–  sž   é € ö$ Ø ˆOØŸ,™,×-Ñ-Ö/�Ü˜vÐ'C×DÑDáØ×&Ñ& v×'HÑ'HÔIØ49�Ö1ñ 0ó ØˆAØŸ,™,×-Ñ-Ö/�Ü˜vÐ'C×DÑDÙØ4CÑ4F�Ô1Ø�Q‘’ò	 0ô ùs   ‚B.B0c                 óà   • U R                   U R                  U R                  S.n[        USSS9 nUR	                  [
        R                  " U5      5        S S S 5        g ! , (       d  f       g = f)N)rÃ   rÂ   rÄ   r#   r    r!   )rÃ   rÂ   rÄ   r1   rG   ÚyamlÚdump)rÏ   r-   Ú	save_dictr#   s       rW   Ú_saveÚBrain._saveº  sU   € ð —I‘IØ"×1Ñ1Ø"×1Ñ1ñ
ˆ	ô
 �$˜ gÒ.°!Ø�G‰G”D—I’I˜iÓ(Ô)÷ /×.Ö.ús   °&AÁ
A-c                 óT  • A[        USS9 n[        R                  " U5      nS S S 5        WS   U l        US   U l        SU;  aI  U R
                  R                  nSU S3nUS-  n[        R                  " U5        U R                  U l	        g US   U l	        g ! , (       d  f       N|= f)	Nr    r!   rÃ   rÂ   rÄ   z'optimizer_step' not found in z checkpoint.z7 Using the saved 'step' value (BACKWARDS COMPATIBILITY))
r1   rà  Ú	safe_loadrÃ   rÂ   rà   rd   ÚwarningsÚwarnrÄ   )rÏ   r-   rž  rO   râ  ÚclsnameÚMSGs          rW   Ú_recoverÚBrain._recoverÄ  s�   € àÜ�$ Ò)¨QÜŸš qÓ)ˆI÷ *à˜fÑ%ˆŒ	Ø'Ð(8Ñ9ˆÔà 9Ó,Ø—n‘n×-Ñ-ˆGØ2°7°)¸<ÐHˆCØÐLÑLˆCÜ�MŠM˜#ÔØ"&§)¡)ˆDÕà"+Ð,<Ñ"=ˆDÕ÷ *Õ)ús   ŒBÂ
B')rÂ   r‡   rž   r}   r˜   r¾   r©   r§   r@  r†   r  rÄ   r…   r´   rÈ   rÁ   rÎ   r   rÃ   rÌ   rÇ   r²   r½   )NNNNNr”  )zdataloader-)F)NN)T)0rd   re   rf   rg   rh   rÙ   rÀ   rï   ró   r÷   rû   r  rÿ   r  r  r%  r,  r<  r3  rG  r#  r5  r0  r6  r¡   r„  r]  rw  rp  r‡  r‘  Úpropertyri  rq  r  r  rÒ  rj  r   r1  r(   r)   ÚcheckpointsÚmark_as_saverrã  Úmark_as_loaderrë  rl   rc   r_   rW   rn   rn   œ   sb  † ñAðJ ØØØØôq
òf-ò^ò&ô*ôð" +8ôHòTEòN4ò*ô<>ôò,'#òR>ò>òò-!ò^ò ð" ‡]‚]ƒ_ñ#ó ð#ò4?òB%ò>Fð8 ØØØô`ðD ñ
ó ð
ò
ò>8ò@0ð> ØØØôEòNð( ó!ó ð!ðF ‡X�X×Ñ×'Ñ'ñ*ó (ð*ð ‡X�X×Ñ×(Ñ(ñ>ó )ó>r_   rn   )Nrh   r7   r£  r,   r¯   r5   rA   r¬   rg  rç  Ú
contextlibr   Údatetimer   Úenumr   r   Útypesr   r¡   rà  Úhyperpyyamlr   Ú	packagingr	   Útorch.nnr
   rË  r   Útorch.nn.parallelr   rÊ  Útorch.utils.datar   r   r   r   Úspeechbrainr(   Úspeechbrain.dataio.dataloaderr   r   Úspeechbrain.dataio.samplerr   r   Úspeechbrain.utils.autocastr   r   Úspeechbrain.utils.distributedr   Úspeechbrain.utils.loggerr   Úspeechbrain.utils.optimizersr   Úspeechbrain.utils.profilingr   Úspeechbrain.utils.run_optsr   r)   rC   Úapply_quirksrd   r>   r-   Údirnamer4   r<   ÚDEFAULT_LOG_CONFIGr0   r™  r‘   r“   rX   r@   ra   rî  Úregister_checkpoint_hooksrn   rc   r_   rW   Ú<module>r     s,  ðñ
ó Û Û 	Û Û Û 
Û Û Û Ý %Ý ß Ý !ã Û Ý *Ý ÷õ =ß LÑ LÝ ã ß J÷÷ @Ý DÝ /Ý ?Ý 8Ý 1à ‡�‡�× Ñ Ô á	�HÓ	€Ø—W‘W—_‘_ R§W¡W§_¡_°XÓ%>Ó?Ð Ø—W‘W—\‘\Ð"4Ð6GÓHÐ Ø0Ð ØÐ ØÐ ð
 ØØ!ØôN+òbNô
ˆDô ð ‡�×Ñ×/Ñ/÷v>ð v>ó 0ñv>r_   