Files
wehub-resource-sync ba4be087d5
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
chore: import upstream snapshot with attribution
2026-07-13 13:28:58 +08:00

114 lines
4.6 KiB
Python

# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. 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 lightning.pytorch as pl
import torch.multiprocessing as mp
from omegaconf import OmegaConf, open_dict
from nemo.collections.tts.models import (
MagpieTTSModel,
MagpieTTSModelOfflinePO,
MagpieTTSModelOfflinePODataGen,
MagpieTTSModelOnlinePO,
OnlineCFGDistillation,
)
from nemo.core.config import hydra_runner
from nemo.utils import logging
from nemo.utils.exp_manager import exp_manager
_TRAIN_MODES: list[str] = [
"train",
"online_cfg_distillation_train",
"dpo_train",
"onlinepo_train",
]
@hydra_runner(config_path="conf/magpietts", config_name="magpietts_lhotse")
def main(cfg):
logging.info('\nConfig Params:\n%s', OmegaConf.to_yaml(cfg, resolve=True))
# forcing "spawn" method for multiprocessing over "fork" when choosing multiple
# worker processes for dataloaders. By default, multiprocessing uses "fork" to create
# worker processes, which inherit the memory state of the main process, including its
# already initialized CUDA state. When the worker processes trieds to use
# CUDA, it runs into conflicts with the inherited, now potentially invalid,
# CUDA context, resuling in the CUDA initialization error. When
# num_workers=0, all dataloading happens in the main process, so there is no
# process forking and no CUDA context conflict. When num_workers>0, the standard way
# to fix this is to use "spawn" to create a completely new and clean python process for
# each worker, avoding the problematic CUDA state inheritance.
mp.set_start_method("spawn", force=True)
trainer = pl.Trainer(**cfg.trainer)
trainer.callbacks.append(pl.callbacks.LearningRateMonitor(logging_interval='step', log_weight_decay=True))
exp_manager(trainer, cfg.get("exp_manager", None))
seed = cfg.get('seed', None)
if seed is not None:
# Option to seed for debugging
logging.info(f"Setting seed to {seed}")
pl.seed_everything(seed, workers=True)
mode = cfg.get('mode', 'train')
train_modes_msg = ", ".join(_TRAIN_MODES)
if mode == 'train':
model = MagpieTTSModel(cfg=cfg.model, trainer=trainer)
elif mode == 'online_cfg_distillation_train':
model = OnlineCFGDistillation(cfg=cfg.model, trainer=trainer)
elif mode == 'dpo_train':
model_cfg = cfg.model
with open_dict(model_cfg):
model_cfg.reference_model_ckpt_path = cfg.init_from_ptl_ckpt
model = MagpieTTSModelOfflinePO(cfg=model_cfg, trainer=trainer)
elif mode == 'onlinepo_train':
model_cfg = cfg.model
with open_dict(model_cfg):
model_cfg.reference_model_ckpt_path = cfg.init_from_ptl_ckpt
model = MagpieTTSModelOnlinePO(cfg=model_cfg, trainer=trainer)
elif mode == 'test':
model = MagpieTTSModelOfflinePODataGen(cfg=cfg.model, trainer=trainer)
else:
raise NotImplementedError(f"Only {train_modes_msg} and test modes are supported. Got {mode}")
model.maybe_init_from_pretrained_checkpoint(cfg=cfg)
try:
if mode in _TRAIN_MODES:
logging.info("Starting training...")
trainer.fit(model)
elif mode == 'test':
logging.info("Starting testing...")
trainer.test(model)
else:
raise NotImplementedError(f"Only {train_modes_msg} and test modes are supported. Got {mode}")
logging.info("Training/testing completed successfully.")
finally:
# Ensure WandB completes all uploads before Python thread shutdown
# Critical when num_workers=0 during debugging - the main process can become
# overwhelmed and fail to properly coordinate with WandB's background threads
try:
import wandb
if wandb.run is not None:
logging.info("Finishing WandB run to prevent threading shutdown hang...")
wandb.finish()
except Exception as e:
logging.warning(f"Error finishing WandB: {e}")
if __name__ == '__main__':
main() # noqa pylint: disable=no-value-for-parameter