hiyouga/LlamaFactory · error · ValueError

Unknown logging level: {env_level_str}.

Error message

Unknown logging level: {env_level_str}.

What it means

ValueError from _get_default_logging_level (logging.py:51) when the LLAMAFACTORY_VERBOSITY environment variable holds a string that is not a standard Python logging level name (checked against logging._nameToLevel after uppercasing). The whole library's logging setup fails at import/first-logger time, so this can break unrelated imports.

Source

Thrown at src/llamafactory/v1/utils/logging.py:51

    def info_rank0(self, *args, **kwargs) -> None:
        self.info(*args, **kwargs)

    def warning_rank0(self, *args, **kwargs) -> None:
        self.warning(*args, **kwargs)

    def warning_rank0_once(self, *args, **kwargs) -> None:
        self.warning(*args, **kwargs)


def _get_default_logging_level() -> "logging._Level":
    """Return the default logging level."""
    env_level_str = os.getenv("LLAMAFACTORY_VERBOSITY", None)
    if env_level_str:
        if env_level_str.upper() in logging._nameToLevel:
            return logging._nameToLevel[env_level_str.upper()]
        else:
            raise ValueError(f"Unknown logging level: {env_level_str}.")

    return _default_log_level


def _get_library_name() -> str:
    return ".".join(__name__.split(".")[:2])  # llamafactory.v1


def _get_library_root_logger() -> "_Logger":
    return logging.getLogger(_get_library_name())


def _configure_library_root_logger() -> None:
    """Configure root logger using a stdout stream handler with an explicit format."""
    global _default_handler

    with _thread_lock:
        if _default_handler:  # already configured

View on GitHub (pinned to f28afaf635)

Solutions

  1. Set LLAMAFACTORY_VERBOSITY to a standard level name: DEBUG, INFO, WARNING, ERROR, or CRITICAL.
  2. Unset the variable (unset LLAMAFACTORY_VERBOSITY) to fall back to the built-in default level.
  3. If a script must pass numbers, map them to names before export (20 -> 'INFO').

Example fix

# before
export LLAMAFACTORY_VERBOSITY=verbose

# after
export LLAMAFACTORY_VERBOSITY=DEBUG
Defensive patterns

Strategy: validation

Validate before calling

import logging, os
lvl = os.getenv("LLAMAFACTORY_VERBOSITY")
if lvl is not None and lvl.upper() not in logging._nameToLevel:
    raise SystemExit(f"LLAMAFACTORY_VERBOSITY must be one of {sorted(logging._nameToLevel)}")

Type guard

def is_valid_verbosity(v: str) -> bool:
    import logging
    return v.upper() in logging._nameToLevel

Prevention

When it happens

Trigger: Exporting LLAMAFACTORY_VERBOSITY to values like 'verbose', 'normal', '20', 'WARNING ' (trailing space) or 'DEBUG2'. Numeric levels are rejected because only names in _nameToLevel match.

Common situations: CI/containers setting verbosity to app-specific words; copy-pasting verbosity values from other tools (transformers uses different names); scripts that export an integer verbosity.

Related errors


AI-assisted analysis of hiyouga/LlamaFactory@f28afaf635 (2026-08-14). Data as JSON: /api/errors/ff8f4edec03bff59. Report an issue: GitHub.