Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"export": {
"opset_version": 17,
"batch_size": 1,
"export_params": true,
"do_constant_folding": true,
"verbose": false,
"dynamo": false,
"enable_hierarchy_tags": true,
"clean_onnx": false,
"hierarchy_tag_format": "full",
"input_tensors": [
{
"name": "input_values",
"dtype": "float32",
"shape": [
1,
16000
],
"value_range": [
-1,
1
]
}
],
"output_tensors": [
{
"name": "logits"
}
]
},
"optim": {},
"quant": {
"precision": "fp16",
"op_types_to_quantize": null,
"nodes_to_exclude": null
},
"compile": null,
"loader": {
"task": "automatic-speech-recognition",
"model_class": "AutoModelForCTC",
"model_type": "wav2vec2"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"export": {
"opset_version": 17,
"batch_size": 1,
"export_params": true,
"do_constant_folding": true,
"verbose": false,
"dynamo": false,
"enable_hierarchy_tags": true,
"clean_onnx": false,
"hierarchy_tag_format": "full",
"input_tensors": [
{
"name": "input_values",
"dtype": "float32",
"shape": [
1,
16000
],
"value_range": [
-1,
1
]
}
],
"output_tensors": [
{
"name": "logits"
}
]
},
"optim": {},
"quant": null,
"compile": null,
"loader": {
"task": "automatic-speech-recognition",
"model_class": "AutoModelForCTC",
"model_type": "wav2vec2"
}
}
4 changes: 3 additions & 1 deletion src/winml/modelkit/loader/resolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,9 @@ def resolve_task(
resolved = _get_custom_model_class(model_type_norm, opt_task)
if resolved is None:
try:
resolved = TasksManager.get_model_class_for_task(opt_task, framework="pt")
resolved = TasksManager.get_model_class_for_task(
opt_task, framework="pt", model_type=model_type_norm or None
)
except Exception:
resolved = _resolve_model_class_from_config(config) # arch fallback

Expand Down
41 changes: 41 additions & 0 deletions tests/unit/loader/test_resolve_task_and_model_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,44 @@ def test_task_normalized_with_model_class(self):
# Task is normalized (unlike the user-task path which preserves the original)
assert r.task == "fill-mask"
assert r.source == TaskSource.USER_CLASS


class TestCTCModelClassResolution:
"""CTC ASR models resolve to AutoModelForCTC, not AutoModelForSpeechSeq2Seq.

When automatic-speech-recognition maps to multiple candidate classes,
passing model_type enables Optimum to select the correct class per
architecture family.
"""

@pytest.mark.parametrize(
"model_type,arch_name",
[
("wav2vec2", "Wav2Vec2ForCTC"),
("hubert", "HubertForCTC"),
("data2vec-audio", "Data2VecAudioForCTC"),
],
)
def test_ctc_architecture_resolves_to_auto_model_for_ctc(self, model_type, arch_name):
"""ForCTC architectures resolve to AutoModelForCTC via model_type."""
config = MagicMock()
config.model_type = model_type
config.architectures = [arch_name]
config._name_or_path = ""

r = resolve_task(config)

assert r.task == "automatic-speech-recognition"
assert r.model_class.__name__ == "AutoModelForCTC"

def test_whisper_still_resolves_to_speech_seq2seq(self):
"""Non-CTC ASR models (Whisper) still get AutoModelForSpeechSeq2Seq."""
config = MagicMock()
config.model_type = "whisper"
config.architectures = ["WhisperForConditionalGeneration"]
config._name_or_path = ""

r = resolve_task(config)

assert r.task == "automatic-speech-recognition"
assert r.model_class.__name__ == "AutoModelForSpeechSeq2Seq"
Loading