autogluon.multimodal 1.2.1b20250303__py3-none-any.whl → 1.2.1b20250304__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. autogluon/multimodal/__init__.py +4 -2
  2. autogluon/multimodal/configs/data/default.yaml +4 -2
  3. autogluon/multimodal/configs/{environment → env}/default.yaml +2 -3
  4. autogluon/multimodal/configs/model/default.yaml +58 -11
  5. autogluon/multimodal/configs/{optimization → optim}/default.yaml +21 -4
  6. autogluon/multimodal/constants.py +16 -5
  7. autogluon/multimodal/data/__init__.py +14 -2
  8. autogluon/multimodal/data/dataset.py +2 -2
  9. autogluon/multimodal/data/infer_types.py +16 -2
  10. autogluon/multimodal/data/label_encoder.py +3 -3
  11. autogluon/multimodal/{utils → data}/nlpaug.py +4 -4
  12. autogluon/multimodal/data/preprocess_dataframe.py +55 -38
  13. autogluon/multimodal/data/process_categorical.py +35 -6
  14. autogluon/multimodal/data/process_document.py +59 -33
  15. autogluon/multimodal/data/process_image.py +198 -163
  16. autogluon/multimodal/data/process_label.py +7 -3
  17. autogluon/multimodal/data/process_mmlab/process_mmdet.py +1 -8
  18. autogluon/multimodal/data/process_mmlab/process_mmlab_base.py +2 -9
  19. autogluon/multimodal/data/process_mmlab/process_mmocr.py +1 -9
  20. autogluon/multimodal/data/process_ner.py +192 -4
  21. autogluon/multimodal/data/process_numerical.py +32 -5
  22. autogluon/multimodal/data/process_semantic_seg_img.py +23 -28
  23. autogluon/multimodal/data/process_text.py +95 -58
  24. autogluon/multimodal/data/template_engine.py +7 -9
  25. autogluon/multimodal/data/templates.py +0 -2
  26. autogluon/multimodal/data/trivial_augmenter.py +2 -2
  27. autogluon/multimodal/data/utils.py +564 -338
  28. autogluon/multimodal/learners/__init__.py +2 -1
  29. autogluon/multimodal/learners/base.py +189 -189
  30. autogluon/multimodal/learners/ensemble.py +748 -0
  31. autogluon/multimodal/learners/few_shot_svm.py +6 -15
  32. autogluon/multimodal/learners/matching.py +59 -84
  33. autogluon/multimodal/learners/ner.py +23 -22
  34. autogluon/multimodal/learners/object_detection.py +26 -21
  35. autogluon/multimodal/learners/semantic_segmentation.py +16 -18
  36. autogluon/multimodal/models/__init__.py +12 -3
  37. autogluon/multimodal/models/augmenter.py +175 -0
  38. autogluon/multimodal/models/categorical_mlp.py +13 -8
  39. autogluon/multimodal/models/clip.py +92 -18
  40. autogluon/multimodal/models/custom_transformer.py +75 -75
  41. autogluon/multimodal/models/document_transformer.py +23 -9
  42. autogluon/multimodal/models/ft_transformer.py +40 -35
  43. autogluon/multimodal/models/fusion/base.py +2 -4
  44. autogluon/multimodal/models/fusion/fusion_mlp.py +82 -18
  45. autogluon/multimodal/models/fusion/fusion_ner.py +1 -1
  46. autogluon/multimodal/models/fusion/fusion_transformer.py +23 -23
  47. autogluon/multimodal/models/{huggingface_text.py → hf_text.py} +21 -2
  48. autogluon/multimodal/models/meta_transformer.py +336 -0
  49. autogluon/multimodal/models/mlp.py +6 -6
  50. autogluon/multimodal/models/mmocr_text_detection.py +1 -1
  51. autogluon/multimodal/models/mmocr_text_recognition.py +0 -1
  52. autogluon/multimodal/models/ner_text.py +1 -8
  53. autogluon/multimodal/models/numerical_mlp.py +14 -8
  54. autogluon/multimodal/models/sam.py +12 -2
  55. autogluon/multimodal/models/t_few.py +21 -5
  56. autogluon/multimodal/models/timm_image.py +74 -32
  57. autogluon/multimodal/models/utils.py +877 -16
  58. autogluon/multimodal/optim/__init__.py +17 -0
  59. autogluon/multimodal/{optimization → optim}/lit_distiller.py +2 -1
  60. autogluon/multimodal/{optimization → optim}/lit_matcher.py +4 -10
  61. autogluon/multimodal/{optimization → optim}/lit_mmdet.py +2 -10
  62. autogluon/multimodal/{optimization → optim}/lit_module.py +139 -14
  63. autogluon/multimodal/{optimization → optim}/lit_ner.py +3 -3
  64. autogluon/multimodal/{optimization → optim}/lit_semantic_seg.py +1 -1
  65. autogluon/multimodal/optim/losses/__init__.py +14 -0
  66. autogluon/multimodal/optim/losses/bce_loss.py +25 -0
  67. autogluon/multimodal/optim/losses/focal_loss.py +81 -0
  68. autogluon/multimodal/optim/losses/lemda_loss.py +39 -0
  69. autogluon/multimodal/optim/losses/rkd_loss.py +103 -0
  70. autogluon/multimodal/optim/losses/softmax_losses.py +177 -0
  71. autogluon/multimodal/optim/losses/structure_loss.py +26 -0
  72. autogluon/multimodal/optim/losses/utils.py +313 -0
  73. autogluon/multimodal/optim/lr/__init__.py +1 -0
  74. autogluon/multimodal/optim/lr/utils.py +332 -0
  75. autogluon/multimodal/optim/metrics/__init__.py +4 -0
  76. autogluon/multimodal/optim/metrics/coverage_metrics.py +42 -0
  77. autogluon/multimodal/optim/metrics/hit_rate_metrics.py +78 -0
  78. autogluon/multimodal/optim/metrics/ranking_metrics.py +231 -0
  79. autogluon/multimodal/optim/metrics/utils.py +359 -0
  80. autogluon/multimodal/optim/utils.py +284 -0
  81. autogluon/multimodal/predictor.py +51 -12
  82. autogluon/multimodal/utils/__init__.py +19 -45
  83. autogluon/multimodal/utils/cache.py +23 -2
  84. autogluon/multimodal/utils/checkpoint.py +58 -5
  85. autogluon/multimodal/utils/config.py +127 -55
  86. autogluon/multimodal/utils/device.py +120 -0
  87. autogluon/multimodal/utils/distillation.py +8 -8
  88. autogluon/multimodal/utils/download.py +1 -1
  89. autogluon/multimodal/utils/env.py +22 -0
  90. autogluon/multimodal/utils/export.py +3 -3
  91. autogluon/multimodal/utils/hpo.py +5 -5
  92. autogluon/multimodal/utils/inference.py +37 -4
  93. autogluon/multimodal/utils/install.py +91 -0
  94. autogluon/multimodal/utils/load.py +52 -47
  95. autogluon/multimodal/utils/log.py +6 -41
  96. autogluon/multimodal/utils/matcher.py +3 -2
  97. autogluon/multimodal/utils/onnx.py +0 -4
  98. autogluon/multimodal/utils/path.py +10 -0
  99. autogluon/multimodal/utils/precision.py +130 -0
  100. autogluon/multimodal/{presets.py → utils/presets.py} +259 -66
  101. autogluon/multimodal/{problem_types.py → utils/problem_types.py} +30 -1
  102. autogluon/multimodal/utils/save.py +47 -29
  103. autogluon/multimodal/utils/strategy.py +24 -0
  104. autogluon/multimodal/version.py +1 -1
  105. {autogluon.multimodal-1.2.1b20250303.dist-info → autogluon.multimodal-1.2.1b20250304.dist-info}/METADATA +5 -5
  106. autogluon.multimodal-1.2.1b20250304.dist-info/RECORD +163 -0
  107. autogluon/multimodal/optimization/__init__.py +0 -16
  108. autogluon/multimodal/optimization/losses.py +0 -394
  109. autogluon/multimodal/optimization/utils.py +0 -1054
  110. autogluon/multimodal/utils/cloud_io.py +0 -80
  111. autogluon/multimodal/utils/data.py +0 -701
  112. autogluon/multimodal/utils/environment.py +0 -395
  113. autogluon/multimodal/utils/metric.py +0 -500
  114. autogluon/multimodal/utils/model.py +0 -558
  115. autogluon.multimodal-1.2.1b20250303.dist-info/RECORD +0 -145
  116. /autogluon/multimodal/{optimization → optim}/deepspeed.py +0 -0
  117. /autogluon/multimodal/{optimization/lr_scheduler.py → optim/lr/lr_schedulers.py} +0 -0
  118. /autogluon/multimodal/{optimization → optim/metrics}/semantic_seg_metrics.py +0 -0
  119. /autogluon/multimodal/{registry.py → utils/registry.py} +0 -0
  120. /autogluon.multimodal-1.2.1b20250303-py3.9-nspkg.pth → /autogluon.multimodal-1.2.1b20250304-py3.9-nspkg.pth +0 -0
  121. {autogluon.multimodal-1.2.1b20250303.dist-info → autogluon.multimodal-1.2.1b20250304.dist-info}/LICENSE +0 -0
  122. {autogluon.multimodal-1.2.1b20250303.dist-info → autogluon.multimodal-1.2.1b20250304.dist-info}/NOTICE +0 -0
  123. {autogluon.multimodal-1.2.1b20250303.dist-info → autogluon.multimodal-1.2.1b20250304.dist-info}/WHEEL +0 -0
  124. {autogluon.multimodal-1.2.1b20250303.dist-info → autogluon.multimodal-1.2.1b20250304.dist-info}/namespace_packages.txt +0 -0
  125. {autogluon.multimodal-1.2.1b20250303.dist-info → autogluon.multimodal-1.2.1b20250304.dist-info}/top_level.txt +0 -0
  126. {autogluon.multimodal-1.2.1b20250303.dist-info → autogluon.multimodal-1.2.1b20250304.dist-info}/zip-safe +0 -0
@@ -0,0 +1,120 @@
1
+ import logging
2
+ import math
3
+ import warnings
4
+ from typing import Dict, List, Optional, Tuple, Union
5
+
6
+ import torch
7
+ from lightning.pytorch.accelerators import find_usable_cuda_devices
8
+ from torch import nn
9
+
10
+ from autogluon.common.utils.resource_utils import ResourceManager
11
+
12
+ from .env import is_interactive_env
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ def compute_num_gpus(config_num_gpus: Union[int, float, List], accelerator: str):
18
+ """
19
+ Compute the gpu number to initialize the lightning trainer.
20
+
21
+ Parameters
22
+ ----------
23
+ config_num_gpus
24
+ The gpu number provided by config.
25
+ accelerator
26
+ # "cpu", "gpu", or "auto".
27
+
28
+ Returns
29
+ -------
30
+ A valid gpu number for the current environment and config.
31
+ """
32
+ if isinstance(accelerator, str) and accelerator.lower() not in ["gpu", "auto"]:
33
+ return 0
34
+
35
+ config_num_gpus = (
36
+ math.floor(config_num_gpus) if isinstance(config_num_gpus, (int, float)) else len(config_num_gpus)
37
+ )
38
+ detected_num_gpus = ResourceManager.get_gpu_count_torch()
39
+
40
+ if config_num_gpus < 0: # In case config_num_gpus is -1, meaning using all gpus.
41
+ num_gpus = detected_num_gpus
42
+ else:
43
+ num_gpus = min(config_num_gpus, detected_num_gpus)
44
+ if detected_num_gpus < config_num_gpus:
45
+ warnings.warn(
46
+ f"Using the detected GPU number {detected_num_gpus}, "
47
+ f"smaller than the GPU number {config_num_gpus} in the config.",
48
+ UserWarning,
49
+ )
50
+
51
+ return num_gpus
52
+
53
+
54
+ def move_to_device(obj: Union[torch.Tensor, nn.Module, Dict, List, Tuple], device: torch.device):
55
+ """
56
+ Move an object to the given device.
57
+
58
+ Parameters
59
+ ----------
60
+ obj
61
+ An object, which can be a tensor, a module, a dict, or a list.
62
+ device
63
+ A Pytorch device instance.
64
+
65
+ Returns
66
+ -------
67
+ The object on the device.
68
+ """
69
+ if not isinstance(device, torch.device):
70
+ raise ValueError(f"Invalid device: {device}. Ensure the device type is `torch.device`.")
71
+
72
+ if torch.is_tensor(obj) or isinstance(obj, nn.Module):
73
+ return obj.to(device)
74
+ elif isinstance(obj, dict):
75
+ res = {}
76
+ for k, v in obj.items():
77
+ res[k] = move_to_device(v, device)
78
+ return res
79
+ elif isinstance(obj, list) or isinstance(obj, tuple):
80
+ res = []
81
+ for v in obj:
82
+ res.append(move_to_device(v, device))
83
+ return res
84
+ elif isinstance(obj, (int, float, str)):
85
+ return obj
86
+ else:
87
+ raise TypeError(
88
+ f"Invalid type {type(obj)} for move_to_device. "
89
+ f"Make sure the object is one of these: a Pytorch tensor, a Pytorch module, "
90
+ f"a dict or list of tensors or modules."
91
+ )
92
+
93
+
94
+ def get_available_devices(num_gpus: int, auto_select_gpus: bool):
95
+ """
96
+ Get the available devices.
97
+
98
+ Parameters
99
+ ----------
100
+ num_gpus
101
+ Number of GPUs.
102
+ auto_select_gpus
103
+ Whether to pick GPU indices that are "accessible". See here: https://github.com/Lightning-AI/lightning/blob/accd2b9e61063ba3c683764043030545ed87c71f/src/lightning/fabric/accelerators/cuda.py#L79
104
+
105
+ Returns
106
+ -------
107
+ The available devices.
108
+ """
109
+ if num_gpus > 0:
110
+ if auto_select_gpus:
111
+ if is_interactive_env():
112
+ devices = list(range(num_gpus))
113
+ else:
114
+ devices = find_usable_cuda_devices(num_gpus)
115
+ else:
116
+ devices = num_gpus
117
+ else:
118
+ devices = "auto"
119
+
120
+ return devices
@@ -5,9 +5,9 @@ from omegaconf import DictConfig, OmegaConf
5
5
  from torch import nn
6
6
 
7
7
  from ..constants import REGRESSION
8
- from ..optimization.losses import RKDLoss
9
- from ..utils.data import turn_on_off_feature_column_info
10
- from ..utils.model import modify_duplicate_model_names
8
+ from ..data import turn_on_off_feature_column_info
9
+ from ..models import modify_duplicate_model_names
10
+ from ..optim.losses import RKDLoss
11
11
 
12
12
  logger = logging.getLogger(__name__)
13
13
 
@@ -79,7 +79,7 @@ class DistillationMixin:
79
79
  else:
80
80
  raise ValueError(f"Unknown soft_label_loss_type: {config.distiller.softmax_regression_loss_type}")
81
81
 
82
- output_feature_loss_type = OmegaConf.select(config, "distiller.output_feature_loss_type", default="mse")
82
+ output_feature_loss_type = config.distiller.output_feature_loss_type
83
83
  if output_feature_loss_type == "cosine":
84
84
  output_feature_loss_func = nn.CosineEmbeddingLoss()
85
85
  elif output_feature_loss_type == "mse":
@@ -97,11 +97,11 @@ class DistillationMixin:
97
97
  else nn.Identity()
98
98
  )
99
99
 
100
- rkd_distance_loss_weight = OmegaConf.select(config, "distiller.rkd_distance_loss_weight", default=0.0)
101
- rkd_angle_loss_weight = OmegaConf.select(config, "distiller.rkd_angle_loss_weight", default=0.0)
100
+ rkd_distance_loss_weight = config.distiller.rkd_distance_loss_weight
101
+ rkd_angle_loss_weight = config.distiller.rkd_angle_loss_weight
102
102
  rkd_loss_func = RKDLoss(rkd_distance_loss_weight, rkd_angle_loss_weight)
103
- output_feature_loss_weight = OmegaConf.select(config, "distiller.output_feature_loss_weight", default=0.0)
104
- softmax_regression_weight = OmegaConf.select(config, "distiller.softmax_regression_weight", default=0.0)
103
+ output_feature_loss_weight = config.distiller.output_feature_loss_weight
104
+ softmax_regression_weight = config.distiller.softmax_regression_weight
105
105
 
106
106
  # turn on returning column information in data processors
107
107
  turn_on_off_feature_column_info(
@@ -12,7 +12,7 @@ import boto3
12
12
  import requests
13
13
  import tqdm
14
14
 
15
- from ..constants import AUTOMM, S3_PREFIX
15
+ from ..constants import S3_PREFIX
16
16
 
17
17
  logger = logging.getLogger(__name__)
18
18
 
@@ -0,0 +1,22 @@
1
+ import logging
2
+ import sys
3
+ from pathlib import Path
4
+ from typing import Any, Union
5
+
6
+ from fsspec.core import url_to_fs
7
+ from fsspec.implementations.local import AbstractFileSystem
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ def is_interactive_env():
13
+ """
14
+ Return whether the current process is running under the interactive mode.
15
+ Check also https://stackoverflow.com/a/64523765
16
+ """
17
+ return hasattr(sys, "ps1")
18
+
19
+
20
+ def get_filesystem(path: Union[str, Path], **kwargs: Any) -> AbstractFileSystem:
21
+ fs, _ = url_to_fs(str(path), **kwargs)
22
+ return fs
@@ -10,11 +10,11 @@ import torch
10
10
 
11
11
  from ..constants import CATEGORICAL, HF_TEXT, IMAGE_PATH, MMDET_IMAGE, NULL, NUMERICAL, TEXT, TIMM_IMAGE
12
12
  from ..models.fusion import AbstractMultimodalFusionModel
13
- from ..models.huggingface_text import HFAutoModelForTextPrediction
13
+ from ..models.hf_text import HFAutoModelForTextPrediction
14
14
  from ..models.mmdet_image import MMDetAutoModelForObjectDetection
15
15
  from ..models.timm_image import TimmAutoModelForImagePrediction
16
- from .environment import infer_precision
17
16
  from .onnx import OnnxModule, onnx_get_dynamic_axes
17
+ from .precision import infer_precision
18
18
 
19
19
  logger = logging.getLogger(__name__)
20
20
 
@@ -110,7 +110,7 @@ class ExportMixin:
110
110
  import torch.jit
111
111
 
112
112
  from ..models.fusion.fusion_mlp import MultimodalFusionMLP
113
- from ..models.huggingface_text import HFAutoModelForTextPrediction
113
+ from ..models.hf_text import HFAutoModelForTextPrediction
114
114
  from ..models.timm_image import TimmAutoModelForImagePrediction
115
115
 
116
116
  supported_models = (TimmAutoModelForImagePrediction, HFAutoModelForTextPrediction, MultimodalFusionMLP)
@@ -8,8 +8,8 @@ import yaml
8
8
  from autogluon.common.utils.context import set_torch_num_threads
9
9
 
10
10
  from ..constants import BEST_K_MODELS_FILE, RAY_TUNE_CHECKPOINT
11
+ from ..models import create_fusion_model
11
12
  from .matcher import create_siamese_model
12
- from .model import create_fusion_model
13
13
 
14
14
  logger = logging.getLogger(__name__)
15
15
 
@@ -92,10 +92,10 @@ def build_final_learner(
92
92
  The constructed learner.
93
93
  """
94
94
  if is_matching:
95
- from ..learners.matching import MultiModalMatcher
95
+ from ..learners import MatchingLearner
96
96
 
97
97
  # reload the learner metadata
98
- matcher = MultiModalMatcher._load_metadata(matcher=learner, path=best_trial_path)
98
+ matcher = MatchingLearner._load_metadata(matcher=learner, path=best_trial_path)
99
99
  # construct the model
100
100
  matcher._query_model, matcher._response_model = create_siamese_model(
101
101
  query_config=matcher._query_config,
@@ -106,7 +106,7 @@ def build_final_learner(
106
106
  matcher.top_k_average(
107
107
  save_path=best_trial_path,
108
108
  last_ckpt_path=last_ckpt_path,
109
- top_k_average_method=matcher._config.optimization.top_k_average_method,
109
+ top_k_average_method=matcher._config.optim.top_k_average_method,
110
110
  )
111
111
  matcher._save_path = save_path
112
112
 
@@ -130,7 +130,7 @@ def build_final_learner(
130
130
  learner.top_k_average(
131
131
  save_path=best_trial_path,
132
132
  last_ckpt_path=last_ckpt_path,
133
- top_k_average_method=learner._config.optimization.top_k_average_method,
133
+ top_k_average_method=learner._config.optim.top_k_average_method,
134
134
  standalone=standalone,
135
135
  clean_ckpts=clean_ckpts,
136
136
  )
@@ -3,7 +3,6 @@ from typing import Callable, Dict, List, Optional, Tuple, Union
3
3
 
4
4
  import pandas as pd
5
5
  import torch
6
- from omegaconf import OmegaConf
7
6
  from scipy.special import softmax
8
7
  from torch import nn
9
8
 
@@ -12,7 +11,6 @@ from ..constants import (
12
11
  COLUMN_FEATURES,
13
12
  FEATURES,
14
13
  IMAGE,
15
- IMAGE_META,
16
14
  LOGITS,
17
15
  MASKS,
18
16
  NER_ANNOTATION,
@@ -29,13 +27,48 @@ from ..constants import (
29
27
  from ..data.preprocess_dataframe import MultiModalFeaturePreprocessor
30
28
  from ..data.utils import apply_data_processor, apply_df_preprocessor, get_collate_fn, get_per_sample_features
31
29
  from ..models.utils import run_model
32
- from .environment import get_precision_context, move_to_device
30
+ from .device import move_to_device
33
31
  from .matcher import compute_matching_probability
34
32
  from .misc import tensor_to_ndarray
33
+ from .precision import get_precision_context
35
34
 
36
35
  logger = logging.getLogger(__name__)
37
36
 
38
37
 
38
+ def compute_inference_batch_size(
39
+ per_gpu_batch_size: int,
40
+ inference_batch_size_ratio: Union[int, float],
41
+ num_gpus: int,
42
+ strategy: str,
43
+ ):
44
+ """
45
+ Compute the batch size for inference.
46
+
47
+ Parameters
48
+ ----------
49
+ per_gpu_batch_size
50
+ Per gpu batch size from the config.
51
+ inference_batch_size_ratio
52
+ per_gpu_batch_size_for_inference = per_gpu_batch_size * inference_batch_size_ratio.
53
+ num_gpus
54
+ Number of GPUs.
55
+ strategy
56
+ A pytorch lightning strategy.
57
+
58
+ Returns
59
+ -------
60
+ Batch size for inference.
61
+ """
62
+ batch_size = per_gpu_batch_size * inference_batch_size_ratio
63
+
64
+ if num_gpus > 1 and strategy == "dp":
65
+ # If using 'dp', the per_gpu_batch_size would be split by all GPUs.
66
+ # So, we need to use the GPU number as a multiplier to compute the batch size.
67
+ batch_size = batch_size * num_gpus
68
+
69
+ return batch_size
70
+
71
+
39
72
  def extract_from_output(outputs: List[Dict], ret_type: str, as_ndarray: Optional[bool] = True):
40
73
  """
41
74
  Extract desired information, e.g., logits or features, from a list of model outputs.
@@ -334,7 +367,7 @@ class RealtimeMixin:
334
367
  per_sample_features_group = apply_data_processor(
335
368
  per_sample_features=per_sample_features_group,
336
369
  data_processors=per_processors_group,
337
- feature_modalities=modality_types[group_id],
370
+ data_types=modality_types[group_id],
338
371
  is_training=False,
339
372
  )
340
373
  per_sample_features.update(per_sample_features_group)
@@ -0,0 +1,91 @@
1
+ import logging
2
+ import warnings
3
+ from typing import Any, Dict, List, Optional, Tuple, Union
4
+
5
+ from ..constants import OBJECT_DETECTION, OCR
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+
10
+ def check_if_packages_installed(problem_type: str = None, package_names: List[str] = None):
11
+ """
12
+ Check if necessary packages are installed for some problem types.
13
+ Raise an error if an package can't be imported.
14
+
15
+ Parameters
16
+ ----------
17
+ problem_type
18
+ Problem type
19
+ """
20
+ if problem_type:
21
+ problem_type = problem_type.lower()
22
+ if any(p in problem_type for p in [OBJECT_DETECTION, OCR]):
23
+ try:
24
+ with warnings.catch_warnings():
25
+ warnings.simplefilter("ignore")
26
+ import mmcv
27
+ except ImportError as e:
28
+ raise ValueError(
29
+ f"Encountered error while importing mmcv: {e}. {_get_mmlab_installation_guide('mmcv')}"
30
+ )
31
+
32
+ try:
33
+ import mmdet
34
+ except ImportError as e:
35
+ raise ValueError(
36
+ f"Encountered error while importing mmdet: {e}. {_get_mmlab_installation_guide('mmdet')}"
37
+ )
38
+
39
+ if OCR in problem_type:
40
+ try:
41
+ import mmocr
42
+ except ImportError as e:
43
+ raise ValueError(
44
+ f'Encountered error while importing mmocr: {e}. Try to install mmocr: pip install "mmocr<1.0".'
45
+ )
46
+ if package_names:
47
+ for package_name in package_names:
48
+ if package_name == "mmcv":
49
+ try:
50
+ with warnings.catch_warnings():
51
+ warnings.simplefilter("ignore")
52
+ import mmcv
53
+ from mmcv import ConfigDict
54
+ from mmcv.runner import load_checkpoint
55
+ from mmcv.transforms import Compose
56
+ except ImportError as e:
57
+ f"Encountered error while importing {package_name}: {e}. {_get_mmlab_installation_guide(package_name)}"
58
+ elif package_name == "mmdet":
59
+ try:
60
+ import mmdet
61
+ from mmdet.datasets.transforms import ImageToTensor
62
+ from mmdet.registry import MODELS
63
+ except ImportError as e:
64
+ f"Encountered error while importing {package_name}: {e}. {_get_mmlab_installation_guide(package_name)}"
65
+ elif package_name == "mmengine":
66
+ try:
67
+ import mmengine
68
+ from mmengine.dataset import pseudo_collate as collate
69
+ from mmengine.runner import load_checkpoint
70
+ except ImportError as e:
71
+ warnings.warn(e)
72
+ raise ValueError(
73
+ f"Encountered error while importing {package_name}: {e}. {_get_mmlab_installation_guide(package_name)}"
74
+ )
75
+ else:
76
+ raise ValueError(f"package_name {package_name} is not required.")
77
+
78
+
79
+ def _get_mmlab_installation_guide(package_name):
80
+ if package_name == "mmdet":
81
+ err_msg = 'Please install MMDetection by: pip install "mmdet==3.2.0"'
82
+ elif package_name == "mmcv":
83
+ err_msg = 'Please install MMCV by: mim install "mmcv==2.1.0"'
84
+ elif package_name == "mmengine":
85
+ err_msg = "Please install MMEngine by: mim install mmengine"
86
+ else:
87
+ raise ValueError("Available package_name are: mmdet, mmcv, mmengine.")
88
+
89
+ err_msg += " Pytorch version larger than 2.1 is not supported yet. To use Autogluon for object detection, please downgrade PyTorch version to <=2.1."
90
+
91
+ return err_msg
@@ -1,59 +1,13 @@
1
1
  import logging
2
2
  import os
3
3
  import pickle
4
- from typing import Dict, List, Optional, Tuple, Union
4
+ import zipfile
5
5
 
6
6
  from ..constants import LAST_CHECKPOINT, MODEL_CHECKPOINT
7
- from ..data import DocumentProcessor, NerProcessor, TextProcessor
8
- from ..models.utils import get_pretrained_tokenizer
9
7
 
10
8
  logger = logging.getLogger(__name__)
11
9
 
12
10
 
13
- def load_text_tokenizers(
14
- text_processors: Union[List[TextProcessor], List[NerProcessor], List[DocumentProcessor]],
15
- path: str,
16
- ) -> Union[List[TextProcessor], List[NerProcessor], List[DocumentProcessor]]:
17
- """
18
- Load saved text tokenizers. If text/ner processors already have tokenizers,
19
- then do nothing.
20
-
21
- Parameters
22
- ----------
23
- text_processors
24
- A list of text/ner processors with tokenizers or their relative paths.
25
- path
26
- The root path.
27
-
28
- Returns
29
- -------
30
- A list of text/ner processors with tokenizers loaded.
31
- """
32
- for per_text_processor in text_processors:
33
- if isinstance(per_text_processor.tokenizer, str):
34
- per_path = os.path.join(path, per_text_processor.tokenizer)
35
- per_text_processor.tokenizer = get_pretrained_tokenizer(
36
- tokenizer_name=per_text_processor.tokenizer_name,
37
- checkpoint_name=per_path,
38
- )
39
- return text_processors
40
-
41
-
42
- class CustomUnpickler(pickle.Unpickler):
43
- """
44
- This is to make pickle loading df_preprocessor backward compatible.
45
- A df_preprocessor object saved with old name space `autogluon.text.automm` has errors
46
- when being loaded under the context of new name `autogluon.multimodal`.
47
- """
48
-
49
- def find_class(self, module, name):
50
- renamed_module = module
51
- if module.startswith("autogluon.text.automm"):
52
- renamed_module = module.replace("autogluon.text.automm", "autogluon.multimodal")
53
-
54
- return super(CustomUnpickler, self).find_class(renamed_module, name)
55
-
56
-
57
11
  def get_dir_ckpt_paths(path: str):
58
12
  """
59
13
  Get the dir path and ckpt path from a path.
@@ -138,3 +92,54 @@ def get_load_ckpt_paths(ckpt_path: str, dir_path: str, resume: bool):
138
92
  ckpt_path = None # must set None since we do not resume training
139
93
 
140
94
  return load_path, ckpt_path
95
+
96
+
97
+ class CustomUnpickler(pickle.Unpickler):
98
+ """
99
+ This is to make pickle loading an object backward compatible.
100
+ A df_preprocessor object saved with old name space `xxx.yyy` has errors
101
+ when being loaded under the context of new name `aaa.bbb`.
102
+ """
103
+
104
+ def find_class(self, module, name):
105
+ renamed_module = module
106
+ if module.startswith("autogluon.text.automm"):
107
+ renamed_module = module.replace("autogluon.text.automm", "autogluon.multimodal")
108
+
109
+ return super(CustomUnpickler, self).find_class(renamed_module, name)
110
+
111
+
112
+ def protected_zip_extraction(zipfile_path, sha1_hash, folder):
113
+ """
114
+ Extract zip file to the folder.
115
+
116
+ A signature file named ".SHA1HASH.sig" will be created if the extraction has been finished.
117
+
118
+ Returns
119
+ -------
120
+ folder
121
+ The directory to extract the zipfile
122
+ """
123
+ os.makedirs(folder, exist_ok=True)
124
+
125
+ if sha1_hash:
126
+ sha1_hash = sha1_hash[:6]
127
+ signature = ".{}.sig".format(sha1_hash)
128
+
129
+ if os.path.exists(os.path.join(folder, signature)):
130
+ # We have found the signature file. Thus, we will not extract again.
131
+ return folder
132
+ else:
133
+ signature = None
134
+
135
+ # Extract the file
136
+ logging.info("Extract files...")
137
+ with zipfile.ZipFile(zipfile_path, "r") as zip_ref:
138
+ zip_ref.extractall(folder)
139
+
140
+ if signature:
141
+ # Create the signature
142
+ with open(os.path.join(folder, signature), "w"):
143
+ pass
144
+
145
+ return folder
@@ -4,52 +4,13 @@ import os
4
4
  from contextlib import contextmanager
5
5
  from typing import Dict, List, Optional, Tuple, Union
6
6
 
7
- import pytz
8
7
  import torch
9
8
 
10
9
  from autogluon.common.utils.system_info import get_ag_system_info
11
10
 
12
- logger = logging.getLogger(__name__)
13
-
14
-
15
- def make_exp_dir(
16
- root_path: str,
17
- job_name: str,
18
- create: Optional[bool] = True,
19
- ):
20
- """
21
- Creates the exp dir of format e.g.,: root_path/2022_01_01/job_name_12_00_00/
22
- This function is to better organize the training runs. It is recommended to call this
23
- function and pass the returned "exp_dir" to "MultiModalPredictor.fit(save_path=exp_dir)".
24
-
25
- Parameters
26
- ----------
27
- root_path
28
- The basic path where to create saving directories for training runs.
29
- job_name
30
- The job names to name training runs.
31
- create
32
- Whether to make the directory.
33
-
34
- Returns
35
- -------
36
- The formatted directory path.
37
- """
38
- tz = pytz.timezone("US/Pacific")
39
- ct = datetime.datetime.now(tz=tz)
40
- date_stamp = ct.strftime("%Y_%m_%d")
41
- time_stamp = ct.strftime("%H_%M_%S")
42
-
43
- # Group logs by day first
44
- exp_dir = os.path.join(root_path, date_stamp)
45
-
46
- # Then, group by run_name and hour + min + sec to avoid duplicates
47
- exp_dir = os.path.join(exp_dir, "_".join([job_name, time_stamp]))
48
-
49
- if create:
50
- os.makedirs(exp_dir, mode=0o777, exist_ok=False)
11
+ from .strategy import is_interactive_strategy
51
12
 
52
- return exp_dir
13
+ logger = logging.getLogger(__name__)
53
14
 
54
15
 
55
16
  class LogFilter(logging.Filter):
@@ -200,6 +161,10 @@ def get_gpu_message(detected_num_gpus: int, used_num_gpus: int, strategy: str):
200
161
  return round((bytes / 1024) / 1024 / 1024, 2)
201
162
 
202
163
  gpu_message = f"GPU Count: {detected_num_gpus}\nGPU Count to be Used: {used_num_gpus}\n"
164
+
165
+ if is_interactive_strategy(strategy): # avoid pre-initializing cuda when using ddp_fork
166
+ return gpu_message
167
+
203
168
  try:
204
169
  import nvidia_smi
205
170
  except:
@@ -11,8 +11,8 @@ from torch import nn
11
11
  from torch.nn import functional as F
12
12
 
13
13
  from ..constants import FUSION, QUERY, RESPONSE
14
- from .data import data_to_df
15
- from .model import create_model
14
+ from ..data import data_to_df
15
+ from ..models import create_model
16
16
 
17
17
  logger = logging.getLogger(__name__)
18
18
 
@@ -103,6 +103,7 @@ def create_fusion_model_dict(
103
103
  model_name=model_name,
104
104
  model_config=model_config,
105
105
  pretrained=pretrained,
106
+ is_matching=True, # clip needs to use this to init attributes for both image and text
106
107
  )
107
108
  if model_name.lower().startswith(FUSION):
108
109
  fusion_model = model
@@ -2,10 +2,6 @@ import logging
2
2
  import os
3
3
  from typing import Dict, List, Optional, Tuple, Union
4
4
 
5
- from torch import tensor
6
-
7
- from ..constants import AUTOMM, FEATURE_EXTRACTION, MULTICLASS
8
-
9
5
  logger = logging.getLogger(__name__)
10
6
 
11
7
  # TODO: Try a better workaround to lazy import tensorrt package.
@@ -0,0 +1,10 @@
1
+ import logging
2
+ import os
3
+ from datetime import datetime
4
+ from typing import Dict, List, Optional, Tuple, Union
5
+
6
+ import pytz
7
+
8
+ from ..constants import LAST_CHECKPOINT, MODEL_CHECKPOINT
9
+
10
+ logger = logging.getLogger(__name__)