chore: import upstream snapshot with attribution
Create PR to main with cherry-pick from release / cherry-pick (push) Failing after 0s
CICD NeMo / pre-flight (push) Failing after 0s
CICD NeMo / configure (push) Has been skipped
Build, validate, and release Neural Modules / pre-flight (push) Failing after 1s
CICD NeMo / code-linting (push) Has been skipped
Build, validate, and release Neural Modules / release (push) Has been skipped
Build, validate, and release Neural Modules / release-summary (push) Has been cancelled
CICD NeMo / cicd-test-container-build (push) Has been cancelled
CICD NeMo / cicd-import-tests (push) Has been cancelled
CICD NeMo / L0_Setup_Test_Data_And_Models (push) Has been cancelled
CICD NeMo / cicd-main-unit-tests (push) Has been cancelled
CICD NeMo / cicd-main-speech (push) Has been cancelled
CICD NeMo / Nemo_CICD_Test (push) Has been cancelled
CICD NeMo / Coverage (e2e) (push) Has been cancelled
CICD NeMo / Coverage (unit-test) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
CICD NeMo / cicd-wait-in-queue (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:28:58 +08:00
commit ba4be087d5
2316 changed files with 2668701 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
# Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from nemo.utils.loggers.clearml_logger import ClearMLLogger, ClearMLParams
from nemo.utils.loggers.dllogger import DLLogger, DLLoggerParams
from nemo.utils.loggers.mlflow_logger import MLFlowParams
+191
View File
@@ -0,0 +1,191 @@
# Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
from argparse import Namespace
from dataclasses import dataclass
from pathlib import Path
from typing import Any, List, Literal, Mapping, Optional, Union
import pandas as pd
from lightning.pytorch.callbacks import Checkpoint
from lightning.pytorch.loggers import Logger
from lightning.pytorch.utilities.parsing import AttributeDict
from lightning_utilities.core.apply_func import apply_to_collection
from omegaconf import DictConfig, ListConfig, OmegaConf
from torch import Tensor
from nemo.utils import logging
try:
from clearml import OutputModel, Task
HAVE_CLEARML_LOGGER = True
except (ImportError, ModuleNotFoundError):
HAVE_CLEARML_LOGGER = False
@dataclass
class ClearMLParams: # pylint: disable=C0115
project: Optional[str] = None
task: Optional[str] = None
connect_pytorch: Optional[bool] = False
model_name: Optional[str] = None
tags: Optional[List[str]] = None
log_model: Optional[bool] = False
log_cfg: Optional[bool] = False
log_metrics: Optional[bool] = False
class ClearMLLogger(Logger): # pylint: disable=C0115
@property
def name(self) -> str: # pylint: disable=C0116
return self.clearml_task.name
@property
def version(self) -> str: # pylint: disable=C0116
return self.clearml_task.id
def __init__(
self, clearml_cfg: DictConfig, log_dir: str, prefix: str, save_best_model: bool, postfix: str = ".nemo"
) -> None: # pylint: disable=C0116
if not HAVE_CLEARML_LOGGER:
raise ImportError(
"Found create_clearml_logger is True."
"But ClearML not found. Please see the README for installation instructions:"
"https://github.com/clearml/clearml"
)
self.clearml_task = None
self.clearml_model = None
self.clearml_cfg = clearml_cfg
self.path_nemo_model = os.path.abspath(
os.path.expanduser(os.path.join(log_dir, "checkpoints", prefix + postfix))
)
self.save_best_model = save_best_model
self.prefix = prefix
self.previos_best_model_path = None
self.last_metrics = None
self.save_blocked = True
self.project_name = os.getenv("CLEARML_PROJECT", clearml_cfg.project if clearml_cfg.project else "NeMo")
self.task_name = os.getenv("CLEARML_TASK", clearml_cfg.task if clearml_cfg.task else f"Trainer {self.prefix}")
tags = ["NeMo"]
if clearml_cfg.tags:
tags.extend(clearml_cfg.tags)
self.clearml_task: Task = Task.init(
project_name=self.project_name,
task_name=self.task_name,
auto_connect_frameworks={"pytorch": clearml_cfg.connect_pytorch},
output_uri=True,
tags=tags,
)
if clearml_cfg.model_name:
model_name = clearml_cfg.model_name
elif self.prefix:
model_name = self.prefix
else:
model_name = self.task_name
if clearml_cfg.log_model:
self.clearml_model: OutputModel = OutputModel(
name=model_name, task=self.clearml_task, tags=tags, framework="NeMo"
)
def log_hyperparams(self, params, *args, **kwargs) -> None: # pylint: disable=C0116
if self.clearml_model and self.clearml_cfg.log_cfg:
if isinstance(params, Namespace):
params = vars(params)
elif isinstance(params, AttributeDict):
params = dict(params)
params = apply_to_collection(params, (DictConfig, ListConfig), OmegaConf.to_container, resolve=True)
params = apply_to_collection(params, Path, str)
params = OmegaConf.to_yaml(params)
self.clearml_model.update_design(config_text=params)
def log_metrics(self, metrics: Mapping[str, float], step: Optional[int] = None) -> None: # pylint: disable=C0116
if self.clearml_model and self.clearml_cfg.log_metrics:
metrics = {
k: {
"value": str(v.item() if type(v) == Tensor else v),
"type": str(type(v.item() if type(v) == Tensor else v)),
}
for k, v in metrics.items()
}
self.last_metrics = metrics
# pylint: disable=C0116
def log_table(
self,
key: str,
columns: List[str] = None,
data: List[List[Any]] = None,
dataframe: Any = None,
step: Optional[int] = None,
) -> None:
table: Optional[Union[pd.DataFrame, List[List[Any]]]] = None
if dataframe is not None:
table = dataframe
if columns is not None:
table.columns = columns
if data is not None:
table = data
assert len(columns) == len(table[0]), "number of column names should match the total number of columns"
table.insert(0, columns)
if table is not None:
self.clearml_task.logger.report_table(title=key, series=key, iteration=step, table_plot=table)
def after_save_checkpoint(self, checkpoint_callback: Checkpoint) -> None: # pylint: disable=C0116
if self.clearml_model:
if self.save_best_model:
if self.save_blocked:
self.save_blocked = False
return None
if not os.path.exists(checkpoint_callback.best_model_path):
return None
if self.previos_best_model_path == checkpoint_callback.best_model_path:
return None
self.previos_best_model_path = checkpoint_callback.best_model_path
self._log_model(self.path_nemo_model)
def finalize(self, status: Literal["success", "failed", "aborted"] = "success") -> None: # pylint: disable=C0116
if status == "success":
self.clearml_task.mark_completed()
elif status == "failed":
self.clearml_task.mark_failed()
elif status == "aborted":
self.clearml_task.mark_stopped()
def _log_model(self, save_path: str) -> None: # pylint: disable=C0116
if self.clearml_model:
if os.path.exists(save_path):
self.clearml_model.update_weights(
weights_filename=save_path,
upload_uri=self.clearml_task.storage_uri or self.clearml_task._get_default_report_storage_uri(),
auto_delete_file=False,
is_package=True,
)
if self.clearml_cfg.log_metrics and self.last_metrics:
self.clearml_model.set_all_metadata(self.last_metrics)
self.save_blocked = True
else:
logging.warning((f"Logging model enabled, but cant find .nemo file!" f" Path: {save_path}"))
+104
View File
@@ -0,0 +1,104 @@
# Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from argparse import Namespace
from dataclasses import dataclass
from pathlib import Path
from typing import Optional
from lightning.pytorch.loggers import Logger
from lightning.pytorch.utilities import rank_zero_only
from lightning.pytorch.utilities.parsing import AttributeDict
from lightning_utilities.core.apply_func import apply_to_collection
from omegaconf import DictConfig, ListConfig, OmegaConf
from nemo.utils import logging
try:
import dllogger
from dllogger import Verbosity
HAVE_DLLOGGER = True
except (ImportError, ModuleNotFoundError):
HAVE_DLLOGGER = False
try:
from lightning.fabric.utilities.logger import _convert_params, _flatten_dict, _sanitize_callable_params
PL_LOGGER_UTILITIES = True
except (ImportError, ModuleNotFoundError):
PL_LOGGER_UTILITIES = False
@dataclass
class DLLoggerParams:
verbose: Optional[bool] = False
stdout: Optional[bool] = False
json_file: Optional[str] = "./dllogger.json"
class DLLogger(Logger):
@property
def name(self):
return self.__class__.__name__
@property
def version(self):
return None
def __init__(self, stdout: bool, verbose: bool, json_file: str):
if not HAVE_DLLOGGER:
raise ImportError(
"DLLogger was not found. Please see the README for installation instructions: "
"https://github.com/NVIDIA/dllogger"
)
if not PL_LOGGER_UTILITIES:
raise ImportError(
"DLLogger utilities were not found. You probably need to update PyTorch Lightning>=1.9.0. "
"pip install pytorch-lightning -U"
)
verbosity = Verbosity.VERBOSE if verbose else Verbosity.DEFAULT
backends = []
if json_file:
Path(json_file).parent.mkdir(parents=True, exist_ok=True)
backends.append(dllogger.JSONStreamBackend(verbosity, json_file))
if stdout:
backends.append(dllogger.StdOutBackend(verbosity))
if not backends:
logging.warning(
"Neither stdout nor json_file DLLogger parameters were specified." "DLLogger will not log anything."
)
dllogger.init(backends=backends)
@rank_zero_only
def log_hyperparams(self, params, *args, **kwargs):
if isinstance(params, Namespace):
params = vars(params)
elif isinstance(params, AttributeDict):
params = dict(params)
params = apply_to_collection(params, (DictConfig, ListConfig), OmegaConf.to_container, resolve=True)
params = apply_to_collection(params, Path, str)
params = _sanitize_callable_params(_flatten_dict(_convert_params(params)))
dllogger.log(step="PARAMETER", data=params)
@rank_zero_only
def log_metrics(self, metrics, step=None):
if step is None:
step = tuple()
dllogger.log(step=step, data=metrics)
def save(self):
dllogger.flush()
+36
View File
@@ -0,0 +1,36 @@
# Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from dataclasses import dataclass
from typing import Any, Dict, Optional
@dataclass
class MLFlowParams:
"""ML Flow Configuration Dataclass."""
# name of experiment, if none, defaults to the globally set experiment name
experiment_name: Optional[str] = None
run_name: Optional[str] = None
# if no run_name is set, it's set by version
# local or remote tracking seerver. If tracking_uri is not set, it defaults to save_dir
tracking_uri: Optional[str] = None
tags: Optional[Dict[str, Any]] = None
save_dir: Optional[str] = "./mlruns"
prefix: str = ""
artifact_location: Optional[str] = None
# provide run_id if resuming a previously started run
run_id: Optional[str] = None
# Log checkpoints created by ModelCheckpoint as MLFlow artifacts.
log_model: bool = False