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.
- autogluon/multimodal/__init__.py +4 -2
- autogluon/multimodal/configs/data/default.yaml +4 -2
- autogluon/multimodal/configs/{environment → env}/default.yaml +2 -3
- autogluon/multimodal/configs/model/default.yaml +58 -11
- autogluon/multimodal/configs/{optimization → optim}/default.yaml +21 -4
- autogluon/multimodal/constants.py +16 -5
- autogluon/multimodal/data/__init__.py +14 -2
- autogluon/multimodal/data/dataset.py +2 -2
- autogluon/multimodal/data/infer_types.py +16 -2
- autogluon/multimodal/data/label_encoder.py +3 -3
- autogluon/multimodal/{utils → data}/nlpaug.py +4 -4
- autogluon/multimodal/data/preprocess_dataframe.py +55 -38
- autogluon/multimodal/data/process_categorical.py +35 -6
- autogluon/multimodal/data/process_document.py +59 -33
- autogluon/multimodal/data/process_image.py +198 -163
- autogluon/multimodal/data/process_label.py +7 -3
- autogluon/multimodal/data/process_mmlab/process_mmdet.py +1 -8
- autogluon/multimodal/data/process_mmlab/process_mmlab_base.py +2 -9
- autogluon/multimodal/data/process_mmlab/process_mmocr.py +1 -9
- autogluon/multimodal/data/process_ner.py +192 -4
- autogluon/multimodal/data/process_numerical.py +32 -5
- autogluon/multimodal/data/process_semantic_seg_img.py +23 -28
- autogluon/multimodal/data/process_text.py +95 -58
- autogluon/multimodal/data/template_engine.py +7 -9
- autogluon/multimodal/data/templates.py +0 -2
- autogluon/multimodal/data/trivial_augmenter.py +2 -2
- autogluon/multimodal/data/utils.py +564 -338
- autogluon/multimodal/learners/__init__.py +2 -1
- autogluon/multimodal/learners/base.py +189 -189
- autogluon/multimodal/learners/ensemble.py +748 -0
- autogluon/multimodal/learners/few_shot_svm.py +6 -15
- autogluon/multimodal/learners/matching.py +59 -84
- autogluon/multimodal/learners/ner.py +23 -22
- autogluon/multimodal/learners/object_detection.py +26 -21
- autogluon/multimodal/learners/semantic_segmentation.py +16 -18
- autogluon/multimodal/models/__init__.py +12 -3
- autogluon/multimodal/models/augmenter.py +175 -0
- autogluon/multimodal/models/categorical_mlp.py +13 -8
- autogluon/multimodal/models/clip.py +92 -18
- autogluon/multimodal/models/custom_transformer.py +75 -75
- autogluon/multimodal/models/document_transformer.py +23 -9
- autogluon/multimodal/models/ft_transformer.py +40 -35
- autogluon/multimodal/models/fusion/base.py +2 -4
- autogluon/multimodal/models/fusion/fusion_mlp.py +82 -18
- autogluon/multimodal/models/fusion/fusion_ner.py +1 -1
- autogluon/multimodal/models/fusion/fusion_transformer.py +23 -23
- autogluon/multimodal/models/{huggingface_text.py → hf_text.py} +21 -2
- autogluon/multimodal/models/meta_transformer.py +336 -0
- autogluon/multimodal/models/mlp.py +6 -6
- autogluon/multimodal/models/mmocr_text_detection.py +1 -1
- autogluon/multimodal/models/mmocr_text_recognition.py +0 -1
- autogluon/multimodal/models/ner_text.py +1 -8
- autogluon/multimodal/models/numerical_mlp.py +14 -8
- autogluon/multimodal/models/sam.py +12 -2
- autogluon/multimodal/models/t_few.py +21 -5
- autogluon/multimodal/models/timm_image.py +74 -32
- autogluon/multimodal/models/utils.py +877 -16
- autogluon/multimodal/optim/__init__.py +17 -0
- autogluon/multimodal/{optimization → optim}/lit_distiller.py +2 -1
- autogluon/multimodal/{optimization → optim}/lit_matcher.py +4 -10
- autogluon/multimodal/{optimization → optim}/lit_mmdet.py +2 -10
- autogluon/multimodal/{optimization → optim}/lit_module.py +139 -14
- autogluon/multimodal/{optimization → optim}/lit_ner.py +3 -3
- autogluon/multimodal/{optimization → optim}/lit_semantic_seg.py +1 -1
- autogluon/multimodal/optim/losses/__init__.py +14 -0
- autogluon/multimodal/optim/losses/bce_loss.py +25 -0
- autogluon/multimodal/optim/losses/focal_loss.py +81 -0
- autogluon/multimodal/optim/losses/lemda_loss.py +39 -0
- autogluon/multimodal/optim/losses/rkd_loss.py +103 -0
- autogluon/multimodal/optim/losses/softmax_losses.py +177 -0
- autogluon/multimodal/optim/losses/structure_loss.py +26 -0
- autogluon/multimodal/optim/losses/utils.py +313 -0
- autogluon/multimodal/optim/lr/__init__.py +1 -0
- autogluon/multimodal/optim/lr/utils.py +332 -0
- autogluon/multimodal/optim/metrics/__init__.py +4 -0
- autogluon/multimodal/optim/metrics/coverage_metrics.py +42 -0
- autogluon/multimodal/optim/metrics/hit_rate_metrics.py +78 -0
- autogluon/multimodal/optim/metrics/ranking_metrics.py +231 -0
- autogluon/multimodal/optim/metrics/utils.py +359 -0
- autogluon/multimodal/optim/utils.py +284 -0
- autogluon/multimodal/predictor.py +51 -12
- autogluon/multimodal/utils/__init__.py +19 -45
- autogluon/multimodal/utils/cache.py +23 -2
- autogluon/multimodal/utils/checkpoint.py +58 -5
- autogluon/multimodal/utils/config.py +127 -55
- autogluon/multimodal/utils/device.py +120 -0
- autogluon/multimodal/utils/distillation.py +8 -8
- autogluon/multimodal/utils/download.py +1 -1
- autogluon/multimodal/utils/env.py +22 -0
- autogluon/multimodal/utils/export.py +3 -3
- autogluon/multimodal/utils/hpo.py +5 -5
- autogluon/multimodal/utils/inference.py +37 -4
- autogluon/multimodal/utils/install.py +91 -0
- autogluon/multimodal/utils/load.py +52 -47
- autogluon/multimodal/utils/log.py +6 -41
- autogluon/multimodal/utils/matcher.py +3 -2
- autogluon/multimodal/utils/onnx.py +0 -4
- autogluon/multimodal/utils/path.py +10 -0
- autogluon/multimodal/utils/precision.py +130 -0
- autogluon/multimodal/{presets.py → utils/presets.py} +259 -66
- autogluon/multimodal/{problem_types.py → utils/problem_types.py} +30 -1
- autogluon/multimodal/utils/save.py +47 -29
- autogluon/multimodal/utils/strategy.py +24 -0
- autogluon/multimodal/version.py +1 -1
- {autogluon.multimodal-1.2.1b20250303.dist-info → autogluon.multimodal-1.2.1b20250304.dist-info}/METADATA +5 -5
- autogluon.multimodal-1.2.1b20250304.dist-info/RECORD +163 -0
- autogluon/multimodal/optimization/__init__.py +0 -16
- autogluon/multimodal/optimization/losses.py +0 -394
- autogluon/multimodal/optimization/utils.py +0 -1054
- autogluon/multimodal/utils/cloud_io.py +0 -80
- autogluon/multimodal/utils/data.py +0 -701
- autogluon/multimodal/utils/environment.py +0 -395
- autogluon/multimodal/utils/metric.py +0 -500
- autogluon/multimodal/utils/model.py +0 -558
- autogluon.multimodal-1.2.1b20250303.dist-info/RECORD +0 -145
- /autogluon/multimodal/{optimization → optim}/deepspeed.py +0 -0
- /autogluon/multimodal/{optimization/lr_scheduler.py → optim/lr/lr_schedulers.py} +0 -0
- /autogluon/multimodal/{optimization → optim/metrics}/semantic_seg_metrics.py +0 -0
- /autogluon/multimodal/{registry.py → utils/registry.py} +0 -0
- /autogluon.multimodal-1.2.1b20250303-py3.9-nspkg.pth → /autogluon.multimodal-1.2.1b20250304-py3.9-nspkg.pth +0 -0
- {autogluon.multimodal-1.2.1b20250303.dist-info → autogluon.multimodal-1.2.1b20250304.dist-info}/LICENSE +0 -0
- {autogluon.multimodal-1.2.1b20250303.dist-info → autogluon.multimodal-1.2.1b20250304.dist-info}/NOTICE +0 -0
- {autogluon.multimodal-1.2.1b20250303.dist-info → autogluon.multimodal-1.2.1b20250304.dist-info}/WHEEL +0 -0
- {autogluon.multimodal-1.2.1b20250303.dist-info → autogluon.multimodal-1.2.1b20250304.dist-info}/namespace_packages.txt +0 -0
- {autogluon.multimodal-1.2.1b20250303.dist-info → autogluon.multimodal-1.2.1b20250304.dist-info}/top_level.txt +0 -0
- {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 ..
|
9
|
-
from ..
|
10
|
-
from ..
|
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 =
|
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 =
|
101
|
-
rkd_angle_loss_weight =
|
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 =
|
104
|
-
softmax_regression_weight =
|
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(
|
@@ -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.
|
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.
|
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
|
95
|
+
from ..learners import MatchingLearner
|
96
96
|
|
97
97
|
# reload the learner metadata
|
98
|
-
matcher =
|
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.
|
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.
|
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 .
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
15
|
-
from
|
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.
|