[Feature] Support text encoder Disaggregation for H3 (#5885)

Signed-off-by: Canlin Guo <canlinguosdu@gmail.com>
Signed-off-by: lishunyang12 <lishunyang12@163.com>
Signed-off-by: yuanwu <yuan.wu@intel.com>
Co-authored-by: lishunyang12 <lishunyang12@163.com>
Co-authored-by: yuanwu <yuan.wu@intel.com>
This commit is contained in:
authored and GitHub committed 2026-08-28 14:27:05 +08:00
1 parent ed837e350e
commit b6a4baa659
61 files changed
+2952 -366

No files matched your search

@@ -47,7 +47,13 @@ def _build_test_app(
engine_client.abort = mocker.AsyncMock()
engine_client.submit_interaction_async = mocker.AsyncMock()
engine_client.default_sampling_params_list = [OmniDiffusionSamplingParams()]
engine_client.stage_configs = [SimpleNamespace(stage_type="diffusion")]
engine_client.stage_configs = [
SimpleNamespace(
stage_type="diffusion",
final_output=True,
final_output_type="video",
)
]
engine_client.generate = mock_generate
class FakeStreamingVideoEncoder:
@@ -72,10 +78,6 @@ def _build_test_app(
"vllm_omni.entrypoints.openai.serving_video_output_stream.create_streaming_video_encoder",
encoder_factory,
)
mocker.patch(
"vllm_omni.entrypoints.openai.serving_video_output_stream.get_stage_type",
return_value="diffusion",
)
mocker.patch(
"vllm_omni.entrypoints.openai.serving_video_output_stream.build_stage_sampling_params_list",
return_value=[OmniDiffusionSamplingParams()],
@@ -398,7 +400,13 @@ def _build_handler_for_async_tests(
engine_client.abort = mocker.AsyncMock()
engine_client.submit_interaction_async = mocker.AsyncMock()
engine_client.default_sampling_params_list = [OmniDiffusionSamplingParams()]
engine_client.stage_configs = [SimpleNamespace(stage_type="diffusion")]
engine_client.stage_configs = [
SimpleNamespace(
stage_type="diffusion",
final_output=True,
final_output_type="video",
)
]
engine_client.generate = mock_generate
chunks = streaming_chunks or [(b"mp4-chunk-0", True)]
@@ -421,10 +429,6 @@ def _build_handler_for_async_tests(
"vllm_omni.entrypoints.openai.serving_video_output_stream.create_streaming_video_encoder",
encoder_factory,
)
mocker.patch(
"vllm_omni.entrypoints.openai.serving_video_output_stream.get_stage_type",
return_value="diffusion",
)
mocker.patch(
"vllm_omni.entrypoints.openai.serving_video_output_stream.build_stage_sampling_params_list",
return_value=[OmniDiffusionSamplingParams()],
@@ -0,0 +1,66 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
from types import SimpleNamespace
import pytest
from vllm_omni.diffusion.io_support import get_diffusion_output_type
from vllm_omni.entrypoints.openai.utils import is_video_generation_pipeline
pytestmark = [pytest.mark.core_model, pytest.mark.cpu]
def test_video_pipeline_requires_declared_final_video_stage():
assert is_video_generation_pipeline(
[
SimpleNamespace(
stage_type="llm",
final_output=False,
final_output_type=None,
),
SimpleNamespace(
stage_type="diffusion",
final_output=True,
final_output_type="video",
),
]
)
@pytest.mark.parametrize(
"stage_configs",
[
[SimpleNamespace(stage_type="diffusion")],
[
SimpleNamespace(
stage_type="diffusion",
final_output=True,
final_output_type="image",
)
],
[
{
"stage_type": "diffusion",
"final_output": False,
"final_output_type": "video",
}
],
],
)
def test_video_pipeline_rejects_non_video_final_outputs(stage_configs):
assert not is_video_generation_pipeline(stage_configs)
@pytest.mark.parametrize(
"model_class_name",
[
"LTX2TwoStagePipeline",
"LTX2DistilledOneStagePipeline",
"WanDMDPipeline",
"LingBotWorldCausalDMDPipeline",
"LongCatVideoAvatarPipeline",
],
)
def test_registered_video_aliases_declare_video_output(model_class_name):
assert get_diffusion_output_type(model_class_name) == "video"
@@ -64,7 +64,13 @@ class MockVideoResult:
class FakeAsyncOmni:
def __init__(self):
self.stage_configs = [SimpleNamespace(stage_type="diffusion")]
self.stage_configs = [
SimpleNamespace(
stage_type="diffusion",
final_output=True,
final_output_type="video",
)
]
self.default_sampling_params_list = [OmniDiffusionSamplingParams()]
self.model_class_name = "WanPipeline"
self.captured_prompt = None
@@ -828,6 +834,18 @@ def test_multi_video_generation_preserves_uploaded_files_until_generation(
assert engine.captured_sampling_params_list[0].extra_args["duration"] == 15.0
def test_mixed_reference_capability_uses_model_metadata_when_config_defaults_false(test_client):
handler = test_client.app.state.openai_serving_video
handler._engine_client.model_class_name = None
handler._engine_client.stage_configs = [
SimpleNamespace(engine_args={"model_class_name": "MiniMaxH3TextEncoder"}),
SimpleNamespace(engine_args={"model_class_name": "MiniMaxH3Pipeline"}),
]
handler._stage_configs = handler._engine_client.stage_configs
assert handler.supports_mixed_reference_inputs
def test_decode_video_bytes_can_keep_first_frames():
from vllm_omni.entrypoints.openai.video_api_utils import _decode_video_bytes