|
11 | 11 | import pytest |
12 | 12 | from transformers import AutoConfig |
13 | 13 |
|
| 14 | +from winml.modelkit.export.io import _get_onnx_config |
| 15 | +from winml.modelkit.loader import resolve_loader_config |
14 | 16 | from winml.modelkit.loader.resolution import TaskSource, resolve_task |
15 | 17 | from winml.modelkit.loader.task import to_optimum_task |
16 | 18 |
|
@@ -106,6 +108,86 @@ def test_user_class_unknown_raises_friendly_error(): |
106 | 108 | resolve_task(cfg, model_class="NotARealClass") |
107 | 109 |
|
108 | 110 |
|
| 111 | +@pytest.mark.parametrize( |
| 112 | + ("model_type", "model_class", "io_config_class", "expected_inputs"), |
| 113 | + [ |
| 114 | + ( |
| 115 | + "sam", |
| 116 | + "SAMMaskGeneration", |
| 117 | + "SamMaskGenerationIOConfig", |
| 118 | + {"input_points", "input_labels", "image_embeddings", "mask_input"}, |
| 119 | + ), |
| 120 | + ( |
| 121 | + "sam2", |
| 122 | + "SAM2MaskGeneration", |
| 123 | + "Sam2MaskGenerationIOConfig", |
| 124 | + {"input_points", "image_embeddings", "high_res_features0", "high_res_features1"}, |
| 125 | + ), |
| 126 | + ( |
| 127 | + "sam2_video", |
| 128 | + "SAM2MaskGeneration", |
| 129 | + "Sam2MaskGenerationIOConfig", |
| 130 | + {"input_points", "image_embeddings", "high_res_features0", "high_res_features1"}, |
| 131 | + ), |
| 132 | + ], |
| 133 | +) |
| 134 | +def test_user_class_custom_wrapper_preserves_task_and_round_trips_loader_config( |
| 135 | + model_type, model_class, io_config_class, expected_inputs |
| 136 | +): |
| 137 | + loader_config, hf_config, _, resolution = resolve_loader_config( |
| 138 | + model_type=model_type, |
| 139 | + task="mask-generation", |
| 140 | + model_class=model_class, |
| 141 | + ) |
| 142 | + |
| 143 | + assert loader_config.task == "mask-generation" |
| 144 | + assert resolution.optimum_task == "mask-generation" |
| 145 | + |
| 146 | + round_trip = resolve_task( |
| 147 | + hf_config, |
| 148 | + task=loader_config.task, |
| 149 | + model_class=loader_config.model_class, |
| 150 | + ) |
| 151 | + assert round_trip.task == "mask-generation" |
| 152 | + assert round_trip.optimum_task == "mask-generation" |
| 153 | + assert round_trip.model_class.__name__ == model_class |
| 154 | + |
| 155 | + onnx_config = _get_onnx_config(loader_config.model_type, loader_config.task, hf_config) |
| 156 | + assert type(onnx_config).__name__ == io_config_class |
| 157 | + assert expected_inputs <= onnx_config.inputs.keys() |
| 158 | + |
| 159 | + |
| 160 | +@pytest.mark.parametrize("model_type", ["sam2", "sam2_video"]) |
| 161 | +def test_user_class_custom_wrapper_tries_normalized_task_after_name_mismatch(model_type): |
| 162 | + r = resolve_task( |
| 163 | + _cfg(model_type, ["Sam2Model"]), |
| 164 | + task="mask-generation", |
| 165 | + model_class="Sam2VisionEncoder", |
| 166 | + ) |
| 167 | + |
| 168 | + assert r.task == "image-feature-extraction" |
| 169 | + assert r.optimum_task == "feature-extraction" |
| 170 | + assert r.model_class.__name__ == "Sam2VisionEncoder" |
| 171 | + |
| 172 | + |
| 173 | +@pytest.mark.parametrize("model_type", ["sam2", "sam2_video"]) |
| 174 | +def test_user_class_custom_wrapper_preserves_modality_for_canonical_task(model_type): |
| 175 | + config = _cfg(model_type, ["Sam2Model"]) |
| 176 | + expected = resolve_task( |
| 177 | + config, |
| 178 | + task="mask-generation", |
| 179 | + model_class="Sam2VisionEncoder", |
| 180 | + ) |
| 181 | + |
| 182 | + resolution = resolve_task( |
| 183 | + config, |
| 184 | + task=expected.optimum_task, |
| 185 | + model_class=expected.model_class.__name__, |
| 186 | + ) |
| 187 | + |
| 188 | + assert resolution == expected |
| 189 | + |
| 190 | + |
109 | 191 | def test_user_task_unsupported_raises_friendly_error(): |
110 | 192 | cfg = _cfg("bert", ["BertModel"]) |
111 | 193 | with pytest.raises(ValueError, match="not supported by TasksManager"): |
@@ -173,9 +255,7 @@ def test_user_class_explicit_feature_extraction_is_modality_aware(): |
173 | 255 | surface image-feature-extraction (-> ImageDataset), not the modality-blind |
174 | 256 | feature-extraction (-> TextDataset). optimum_task still collapses for the Optimum |
175 | 257 | class lookup.""" |
176 | | - r = resolve_task( |
177 | | - _cfg("vit", ["ViTModel"]), model_class="ViTModel", task="feature-extraction" |
178 | | - ) |
| 258 | + r = resolve_task(_cfg("vit", ["ViTModel"]), model_class="ViTModel", task="feature-extraction") |
179 | 259 | assert r.source == TaskSource.USER_CLASS |
180 | 260 | assert r.task == "image-feature-extraction" |
181 | 261 | assert r.optimum_task == "feature-extraction" |
|
0 commit comments