NeMo_Canary / nemo /core /utils /optional_libs.py
Respair's picture
Upload folder using huggingface_hub
b386992 verified
# Copyright (c) 2025, 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.
"""
Module with guards for optional libraries, that cannot be listed in `requirements.txt`.
Provides helper constants and decorators to check if the library is available in the system.
"""
__all__ = ["KENLM_AVAILABLE", "K2_AVAILABLE", "TRITON_AVAILABLE", "kenlm_required", "k2_required", "triton_required"]
import importlib.util
from functools import wraps
from nemo.core.utils.k2_utils import K2_INSTALLATION_MESSAGE
def is_lib_available(name: str) -> bool:
"""
Checks if the library/package with `name` is available in the system
NB: try/catch with importlib.import_module(name) requires importing the library, which can be slow.
So, `find_spec` should be preferred
"""
return importlib.util.find_spec(name) is not None
KENLM_AVAILABLE = is_lib_available("kenlm")
KENLM_INSTALLATION_MESSAGE = "Try installing kenlm with `pip install kenlm`"
TRITON_AVAILABLE = is_lib_available("triton")
TRITON_INSTALLATION_MESSAGE = "Try installing triton with `pip install triton`"
try:
from nemo.core.utils.k2_guard import k2 as _ # noqa: F401
K2_AVAILABLE = True
except (ImportError, ModuleNotFoundError):
K2_AVAILABLE = False
def identity_decorator(f):
"""Identity decorator for further using in conditional decorators"""
return f
def _lib_required(is_available: bool, name: str, message: str | None = None):
"""
Decorator factory. Returns identity decorator if lib `is_available`,
otherwise returns a decorator which returns a function that raises an error when called.
Such decorator can be used for conditional checks for optional libraries in functions and methods
with zero computational overhead.
"""
if is_available:
return identity_decorator
# return wrapper that will raise an error when the function is called
def function_stub_with_error_decorator(f):
"""Decorator that replaces the function and raises an error when called"""
@wraps(f)
def wrapper(*args, **kwargs):
error_msg = f"Module {name} required for the function {f.__name__} is not found."
if message:
error_msg += f" {message}"
raise ModuleNotFoundError(error_msg)
return wrapper
return function_stub_with_error_decorator
kenlm_required = _lib_required(is_available=KENLM_AVAILABLE, name="kenlm", message=KENLM_INSTALLATION_MESSAGE)
triton_required = _lib_required(is_available=TRITON_AVAILABLE, name="triton", message=TRITON_INSTALLATION_MESSAGE)
k2_required = _lib_required(is_available=K2_AVAILABLE, name="k2", message=K2_INSTALLATION_MESSAGE)