Skip to content

Commit 62dca3b

Browse files
authored
fix: vllm and vllm-omni tasks in routing logic (#6007)
Signed-off-by: DWarez <dario.salvati@huggingface.co>
1 parent 0e3e7c0 commit 62dca3b

6 files changed

Lines changed: 55 additions & 13 deletions

File tree

‎sagemaker-serve/src/sagemaker/serve/constants.py‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,18 @@
7171
ModelServer.LLAMACPP,
7272
}
7373

74-
# HuggingFace pipeline tags that should route to the vLLM-omni (multimodal) server.
75-
# Note: visual-question-answering is folded into image-text-to-text as of transformers v5.
76-
OMNI_TASKS: Set[str] = {
74+
# HuggingFace pipeline tags for models that generate text and should prefer vLLM.
75+
VLLM_TASKS: Set[str] = {
76+
"text-generation",
7777
"image-text-to-text",
78-
"any-to-any",
7978
"audio-text-to-text",
8079
}
8180

81+
# HuggingFace pipeline tags for models that can generate multiple output modalities.
82+
OMNI_TASKS: Set[str] = {
83+
"any-to-any",
84+
}
85+
8286
# ========================================
8387
# Framework Enum
8488
# ========================================
@@ -130,4 +134,3 @@ class Framework(Enum):
130134
Framework.NTM: (RecordSerializer(), JSONDeserializer()),
131135
Framework.SMD: (JSONSerializer(), JSONDeserializer()),
132136
}
133-

‎sagemaker-serve/src/sagemaker/serve/model_builder.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@
143143
LOCAL_MODES,
144144
SUPPORTED_MODEL_SERVERS,
145145
OMNI_TASKS,
146+
VLLM_TASKS,
146147
Framework,
147148
)
148149
from sagemaker.core.workflow.pipeline_context import PipelineSession, runnable_by_pipeline
@@ -3608,7 +3609,7 @@ def _build_single_modelbuilder(
36083609
# Task-based auto-selection. SGLang is not auto-selected by task; it is
36093610
# opt-in only via model_server=ModelServer.SGLANG, which is handled earlier
36103611
# by the _build_for_model_server() short-circuit above.
3611-
if model_task == "text-generation":
3612+
if model_task in VLLM_TASKS:
36123613
self.built_model = self._build_for_vllm()
36133614
return self.built_model
36143615
elif model_task in OMNI_TASKS:

‎sagemaker-serve/src/sagemaker/serve/model_builder_utils.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ def build(self):
6363
from sagemaker.serve.constants import (
6464
DEFAULT_SERIALIZERS_BY_FRAMEWORK,
6565
OMNI_TASKS,
66+
VLLM_TASKS,
6667
Framework,
6768
)
6869
from sagemaker.serve.builder.schema_builder import SchemaBuilder
@@ -680,7 +681,7 @@ def _detect_huggingface_image(self) -> None:
680681
)
681682
model_task = hf_model_md.get("pipeline_tag")
682683

683-
if model_task == "text-generation":
684+
if model_task in VLLM_TASKS:
684685
effective_model_server = ModelServer.VLLM
685686
elif model_task in OMNI_TASKS:
686687
effective_model_server = ModelServer.VLLM_OMNI

‎sagemaker-serve/tests/unit/test_constants.py‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
from sagemaker.serve.constants import (
33
Framework,
44
LOCAL_MODES,
5+
OMNI_TASKS,
56
SUPPORTED_MODEL_SERVERS,
6-
DEFAULT_SERIALIZERS_BY_FRAMEWORK
7+
DEFAULT_SERIALIZERS_BY_FRAMEWORK,
8+
VLLM_TASKS,
79
)
810
from sagemaker.serve.mode.function_pointers import Mode
911
from sagemaker.serve.utils.types import ModelServer
@@ -52,6 +54,14 @@ def test_supported_model_servers(self):
5254
self.assertEqual(SUPPORTED_MODEL_SERVERS, expected_servers)
5355

5456

57+
class TestHuggingFaceRoutingTasks(unittest.TestCase):
58+
def test_text_output_multimodal_tasks_route_to_vllm(self):
59+
self.assertIn("image-text-to-text", VLLM_TASKS)
60+
self.assertIn("audio-text-to-text", VLLM_TASKS)
61+
self.assertNotIn("image-text-to-text", OMNI_TASKS)
62+
self.assertNotIn("audio-text-to-text", OMNI_TASKS)
63+
64+
5565
class TestDefaultSerializersByFramework(unittest.TestCase):
5666
def test_all_frameworks_have_serializers(self):
5767
for framework in Framework:

‎sagemaker-serve/tests/unit/test_model_builder_utils_extended_coverage.py‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,24 @@ def test_detect_hf_image_vllm(self, mock_metadata, mock_retrieve):
171171
self.assertEqual(utils.framework, Framework.HUGGINGFACE)
172172
self.assertEqual(mock_retrieve.call_args.args[0], "huggingface-vllm")
173173

174+
@patch('sagemaker.core.image_uris.retrieve')
175+
@patch.object(_ModelBuilderUtils, 'get_huggingface_model_metadata')
176+
def test_detect_hf_image_multimodal_text_routes_to_vllm(self, mock_metadata, mock_retrieve):
177+
"""Test image-text-to-text models resolve the vLLM framework."""
178+
utils = _ModelBuilderUtils()
179+
utils.model = "google/gemma-4-E2B-it"
180+
utils.region = "us-west-2"
181+
mock_metadata.return_value = {"pipeline_tag": "image-text-to-text"}
182+
mock_retrieve.return_value = (
183+
"763104351884.dkr.ecr.us-west-2.amazonaws.com/huggingface-vllm:latest"
184+
)
185+
186+
utils._detect_huggingface_image()
187+
188+
self.assertIsNotNone(utils.image_uri)
189+
self.assertEqual(utils.framework, Framework.HUGGINGFACE)
190+
self.assertEqual(mock_retrieve.call_args.args[0], "huggingface-vllm")
191+
174192
@patch('sagemaker.core.image_uris.retrieve')
175193
@patch.object(_ModelBuilderUtils, 'get_huggingface_model_metadata')
176194
def test_detect_hf_image_sglang(self, mock_metadata, mock_retrieve):

‎sagemaker-serve/tests/unit/test_model_builder_workflows.py‎

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -415,19 +415,28 @@ def test_build_single_with_hf_text_generation(self, mock_schema_init, mock_use_j
415415

416416
@patch('sagemaker.serve.model_builder.ModelBuilder._is_huggingface_model')
417417
@patch('sagemaker.serve.model_builder.ModelBuilder.get_huggingface_model_metadata')
418-
@patch('sagemaker.serve.model_builder.ModelBuilder._build_for_vllm_omni')
418+
@patch('sagemaker.serve.model_builder.ModelBuilder._build_for_vllm')
419419
@patch('sagemaker.serve.model_builder.ModelBuilder._get_client_translators')
420420
@patch('sagemaker.serve.model_builder.ModelBuilder._is_jumpstart_model_id')
421421
@patch('sagemaker.serve.model_builder.ModelBuilder._use_jumpstart_equivalent')
422422
@patch('sagemaker.serve.model_builder.ModelBuilder._hf_schema_builder_init')
423-
def test_build_single_with_hf_multimodal(self, mock_schema_init, mock_use_js, mock_is_js, mock_get_trans, mock_build_omni, mock_get_md, mock_is_hf):
424-
"""Test _build_single_modelbuilder routes HF multimodal models to vLLM-omni."""
423+
def test_build_single_with_hf_multimodal(
424+
self,
425+
mock_schema_init,
426+
mock_use_js,
427+
mock_is_js,
428+
mock_get_trans,
429+
mock_build_vllm,
430+
mock_get_md,
431+
mock_is_hf,
432+
):
433+
"""Test _build_single_modelbuilder routes HF multimodal text models to vLLM."""
425434
mock_is_hf.return_value = True
426435
mock_is_js.return_value = False
427436
mock_use_js.return_value = False
428437
mock_get_md.return_value = {"pipeline_tag": "image-text-to-text"}
429438
mock_model = Mock(spec=Model)
430-
mock_build_omni.return_value = mock_model
439+
mock_build_vllm.return_value = mock_model
431440
mock_get_trans.return_value = (None, None)
432441

433442
builder = ModelBuilder(
@@ -441,7 +450,7 @@ def test_build_single_with_hf_multimodal(self, mock_schema_init, mock_use_js, mo
441450
result = builder._build_single_modelbuilder()
442451

443452
self.assertEqual(result, mock_model)
444-
mock_build_omni.assert_called_once()
453+
mock_build_vllm.assert_called_once()
445454

446455
@patch('sagemaker.serve.model_builder.ModelBuilder._is_huggingface_model')
447456
@patch('sagemaker.serve.model_builder.ModelBuilder._build_for_sglang')

0 commit comments

Comments
 (0)