Skip to content

Restored metric logging to third-party loggers #2489

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/anomalib/cli/pipelines.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
import logging

from jsonargparse import Namespace
from lightning_utilities.core.imports import package_available
from lightning_utilities.core.imports import module_available

from anomalib.cli.utils.help_formatter import get_short_docstring

logger = logging.getLogger(__name__)

if package_available("anomalib.pipelines"):
if module_available("anomalib.pipelines"):
from anomalib.pipelines import Benchmark
from anomalib.pipelines.components.base import Pipeline

Expand Down
4 changes: 2 additions & 2 deletions src/anomalib/cli/utils/openvino.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
import logging

from jsonargparse import ArgumentParser
from lightning_utilities.core.imports import package_available
from lightning_utilities.core.imports import module_available

logger = logging.getLogger(__name__)


if package_available("openvino"):
if module_available("openvino"):
from openvino.tools.ovc.cli_parser import get_common_cli_parser
else:
get_common_cli_parser = None
Expand Down
4 changes: 2 additions & 2 deletions src/anomalib/deploy/inferencers/openvino_inferencer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import cv2
import numpy as np
from lightning_utilities.core.imports import package_available
from lightning_utilities.core.imports import module_available
from omegaconf import DictConfig
from PIL import Image

Expand Down Expand Up @@ -94,7 +94,7 @@ def __init__(
task: str | None = None,
config: dict | None = None,
) -> None:
if not package_available("openvino"):
if not module_available("openvino"):
msg = "OpenVINO is not installed. Please install OpenVINO to use OpenVINOInferencer."
raise ImportError(msg)

Expand Down
4 changes: 2 additions & 2 deletions src/anomalib/loggers/wandb.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
from lightning.fabric.utilities.types import _PATH
from lightning.pytorch.loggers.wandb import WandbLogger
from lightning.pytorch.utilities import rank_zero_only
from lightning_utilities.core.imports import package_available
from lightning_utilities.core.imports import module_available
from matplotlib.figure import Figure

from .base import ImageLoggerBase

if package_available("wandb"):
if module_available("wandb"):
import wandb

if TYPE_CHECKING:
Expand Down
6 changes: 3 additions & 3 deletions src/anomalib/models/components/base/export_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import numpy as np
import torch
from lightning_utilities.core.imports import package_available
from lightning_utilities.core.imports import module_available
from torch import nn
from torchmetrics import Metric
from torchvision.transforms.v2 import Transform
Expand Down Expand Up @@ -245,7 +245,7 @@ def to_openvino(
... task="segmentation",
... )
"""
if not package_available("openvino"):
if not module_available("openvino"):
logger.exception("Could not find OpenVINO. Please check OpenVINO installation.")
raise ModuleNotFoundError

Expand Down Expand Up @@ -294,7 +294,7 @@ def _compress_ov_model(
Returns:
model (CompiledModel): Model in the OpenVINO format compressed with NNCF quantization.
"""
if not package_available("nncf"):
if not module_available("nncf"):
logger.exception("Could not find NCCF. Please check NNCF installation.")
raise ModuleNotFoundError

Expand Down
4 changes: 2 additions & 2 deletions src/anomalib/models/image/vlm_ad/backends/chat_gpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
from typing import TYPE_CHECKING

from dotenv import load_dotenv
from lightning_utilities.core.imports import package_available
from lightning_utilities.core.imports import module_available

from anomalib.models.image.vlm_ad.utils import Prompt

from .base import Backend

if package_available("openai"):
if module_available("openai"):
from openai import OpenAI
else:
OpenAI = None
Expand Down
4 changes: 2 additions & 2 deletions src/anomalib/models/image/vlm_ad/backends/huggingface.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from pathlib import Path
from typing import TYPE_CHECKING

from lightning_utilities.core.imports import package_available
from lightning_utilities.core.imports import module_available
from PIL import Image

from anomalib.models.image.vlm_ad.utils import Prompt
Expand All @@ -18,7 +18,7 @@
from transformers.modeling_utils import PreTrainedModel
from transformers.processing_utils import ProcessorMixin

if package_available("transformers"):
if module_available("transformers"):
import transformers
else:
transformers = None
Expand Down
4 changes: 2 additions & 2 deletions src/anomalib/models/image/vlm_ad/backends/ollama.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
import logging
from pathlib import Path

from lightning_utilities.core.imports import package_available
from lightning_utilities.core.imports import module_available

from anomalib.models.image.vlm_ad.utils import Prompt

from .base import Backend

if package_available("ollama"):
if module_available("ollama"):
from ollama import chat
from ollama._client import _encode_image
else:
Expand Down
57 changes: 57 additions & 0 deletions src/anomalib/pipelines/benchmark/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,21 @@

logger = logging.getLogger(__name__)

# Import external loggers
try:
from anomalib.loggers import (
AnomalibCometLogger,
AnomalibMLFlowLogger,
AnomalibTensorBoardLogger,
AnomalibWandbLogger,
)

LOGGERS_AVAILABLE = True
logger.info("Successfully imported logger modules.")
except ImportError:
LOGGERS_AVAILABLE = False
logger.warning("To use external loggers, install required packages using `anomalib install -v`")


class BenchmarkJob(Job):
"""Benchmarking job.
Expand Down Expand Up @@ -69,6 +84,7 @@ def run(
accelerator=self.accelerator,
devices=devices,
default_root_dir=temp_dir,
logger=self._initialize_loggers(self.flat_cfg or {}) if LOGGERS_AVAILABLE else None,
)
fit_start_time = time.time()
engine.fit(self.model, self.datamodule)
Expand All @@ -89,8 +105,49 @@ def run(
**test_results[0],
}
logger.info(f"Completed with result {output}")

# Logging metrics to External Loggers
trainer = engine.trainer()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure that you can call trainer?

for logger_instance in trainer.loggers:
if isinstance(logger_instance, AnomalibCometLogger | AnomalibWandbLogger | AnomalibMLFlowLogger):
logger_instance.log_metrics(test_results[0])
logger.debug(f"Successfully logged metrics to {logger_instance.__class__.__name__}")
return output

@staticmethod
def _initialize_loggers(logger_configs: dict[str, dict[str, Any]]) -> list[Any]:
"""Initialize configured external loggers.

Args:
logger_configs: Dictionary mapping logger names to their configurations.

Returns:
Dictionary of initialized loggers.
"""
logger_mapping = {
"tensorboard": AnomalibTensorBoardLogger,
"comet": AnomalibCometLogger,
"wandb": AnomalibWandbLogger,
"mlflow": AnomalibMLFlowLogger,
}

active_loggers = []
default_configs = {
"tensorboard": {"save_dir": "logs/benchmarks"},
"comet": {"project_name": "anomalib"},
"wandb": {"project": "anomalib"},
"mlflow": {"experiment_name": "anomalib"},
}

for logger_name, logger_class in logger_mapping.items():
# Use provided config or fall back to defaults
config = logger_configs.get(logger_name, default_configs.get(logger_name, {}))
logger_instance = logger_class(**config)
active_loggers.append(logger_instance)
logger.info(f"Successfully initialized {logger_name} logger")

return active_loggers

@staticmethod
def collect(results: list[dict[str, Any]]) -> pd.DataFrame:
"""Gather the results returned from run."""
Expand Down
2 changes: 1 addition & 1 deletion src/anomalib/utils/exceptions/imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def try_import(import_path: str) -> bool:

warnings.warn(
"The 'try_import' function is deprecated and will be removed in v2.0.0. "
"Use 'package_available' from lightning-utilities instead.",
"Use 'module_available' from lightning-utilities instead.",
DeprecationWarning,
stacklevel=2,
)
Expand Down