rebase: align vllm-omni with vLLM 0a0a1a198be8
Signed-off-by: tzhouam <tzhouam@connect.ust.hk>
This commit is contained in:
1 parent
0eccb77c4f
commit
722ad6bbae
7 files changed
+200
-41
No files matched your search
@@ -14,12 +14,15 @@ RUN apt-get update && \
|
||||
RUN uv pip uninstall --system -y vllm || true
|
||||
|
||||
# Install vLLM from source at the selected commit using precompiled artifacts
|
||||
ENV VLLM_PRECOMPILED_WHEEL_COMMIT=2754231ba3a72f41e62922d1552c33e8f3f6a9d1
|
||||
RUN uv pip install --system --force-reinstall --prerelease=allow vllm --extra-index-url https://wheels.vllm.ai/${VLLM_PRECOMPILED_WHEEL_COMMIT}
|
||||
|
||||
RUN uv pip install --system ".[dev]"
|
||||
|
||||
RUN uv pip install --system --upgrade \
|
||||
ENV VLLM_PRECOMPILED_WHEEL_COMMIT=0a0a1a198be88e1782b52fa31738896468200a76
|
||||
RUN git clone https://github.com/vllm-project/vllm.git /workspace/vllm && \
|
||||
cd /workspace/vllm && \
|
||||
git checkout ${VLLM_PRECOMPILED_WHEEL_COMMIT} && \
|
||||
(uv pip uninstall --system -y vllm || true) && \
|
||||
VLLM_USE_PRECOMPILED=1 uv pip install --system -e . && \
|
||||
cd ${APP_DIR} && \
|
||||
uv pip install --system ".[dev]" && \
|
||||
uv pip install --system --upgrade \
|
||||
"flashinfer-cubin==0.6.6" \
|
||||
"nvidia-cublas-cu12==12.9.1.4" \
|
||||
"numpy==2.2.6"
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
stage_args:
|
||||
- stage_id: 0
|
||||
runtime: {process: true, devices: '0', max_batch_size: 1}
|
||||
engine_args: {model_stage: thinker, model_arch: Qwen2_5OmniForConditionalGeneration,
|
||||
worker_type: ar, scheduler_cls: vllm_omni.core.sched.omni_ar_scheduler.OmniARScheduler,
|
||||
max_model_len: 16384, max_num_batched_tokens: 16384, max_num_seqs: 1, gpu_memory_utilization: 0.9,
|
||||
skip_mm_profiling: true, enforce_eager: 'true', trust_remote_code: true, engine_output_type: latent,
|
||||
enable_prefix_caching: false, mm_processor_cache_gb: 0}
|
||||
is_comprehension: true
|
||||
final_output: true
|
||||
final_output_type: text
|
||||
default_sampling_params: {temperature: 0.0, top_p: 1.0, top_k: -1, max_tokens: 128,
|
||||
seed: 42, detokenize: true, repetition_penalty: 1.1}
|
||||
- stage_id: 1
|
||||
runtime: {process: true, devices: '1', max_batch_size: 1}
|
||||
engine_args: {model_stage: talker, model_arch: Qwen2_5OmniForConditionalGeneration,
|
||||
worker_type: ar, scheduler_cls: vllm_omni.core.sched.omni_ar_scheduler.OmniARScheduler,
|
||||
max_model_len: 16384, max_num_batched_tokens: 16384, max_num_seqs: 1, gpu_memory_utilization: 0.4,
|
||||
skip_mm_profiling: true, enforce_eager: 'true', trust_remote_code: true, enable_prefix_caching: false,
|
||||
engine_output_type: latent}
|
||||
engine_input_source: [0]
|
||||
custom_process_input_func: vllm_omni.model_executor.stage_input_processors.qwen2_5_omni.thinker2talker
|
||||
default_sampling_params:
|
||||
temperature: 0.9
|
||||
top_p: 0.8
|
||||
top_k: 40
|
||||
max_tokens: 4096
|
||||
seed: 42
|
||||
detokenize: true
|
||||
repetition_penalty: 1.05
|
||||
stop_token_ids: [8294]
|
||||
- stage_id: 2
|
||||
runtime: {process: true, devices: '1', max_batch_size: 1}
|
||||
engine_args: {model_stage: code2wav, model_arch: Qwen2_5OmniForConditionalGeneration,
|
||||
worker_type: generation, scheduler_cls: vllm_omni.core.sched.omni_generation_scheduler.OmniGenerationScheduler,
|
||||
gpu_memory_utilization: 0.5, enforce_eager: true, trust_remote_code: true, enable_prefix_caching: false,
|
||||
engine_output_type: audio, max_num_batched_tokens: 4096, max_model_len: 4096}
|
||||
engine_input_source: [1]
|
||||
final_output: true
|
||||
final_output_type: audio
|
||||
default_sampling_params: {temperature: 0.0, top_p: 1.0, top_k: -1, max_tokens: 4096,
|
||||
seed: 42, detokenize: true, repetition_penalty: 1.1}
|
||||
runtime:
|
||||
enabled: true
|
||||
defaults: {window_size: -1, max_inflight: 1}
|
||||
edges:
|
||||
- {from: 0, to: 1, window_size: -1}
|
||||
- {from: 1, to: 2, window_size: -1}
|
||||
@@ -0,0 +1,48 @@
|
||||
stage_args:
|
||||
- stage_id: 0
|
||||
runtime: {process: true, devices: '0', max_batch_size: 1}
|
||||
engine_args: {model_stage: thinker, model_arch: Qwen2_5OmniForConditionalGeneration,
|
||||
worker_type: ar, scheduler_cls: vllm_omni.core.sched.omni_ar_scheduler.OmniARScheduler,
|
||||
max_model_len: 16384, max_num_batched_tokens: 16384, max_num_seqs: 1, gpu_memory_utilization: 0.9,
|
||||
skip_mm_profiling: true, enforce_eager: 'true', trust_remote_code: true, engine_output_type: latent,
|
||||
enable_prefix_caching: false, mm_processor_cache_gb: 0}
|
||||
is_comprehension: true
|
||||
final_output: true
|
||||
final_output_type: text
|
||||
default_sampling_params: {temperature: 0.0, top_p: 1.0, top_k: -1, max_tokens: 128,
|
||||
seed: 42, detokenize: true, repetition_penalty: 1.1}
|
||||
- stage_id: 1
|
||||
runtime: {process: true, devices: '1', max_batch_size: 1}
|
||||
engine_args: {model_stage: talker, model_arch: Qwen2_5OmniForConditionalGeneration,
|
||||
worker_type: ar, scheduler_cls: vllm_omni.core.sched.omni_ar_scheduler.OmniARScheduler,
|
||||
max_model_len: 16384, max_num_batched_tokens: 16384, max_num_seqs: 1, gpu_memory_utilization: 0.4,
|
||||
skip_mm_profiling: true, enforce_eager: 'true', trust_remote_code: true, enable_prefix_caching: false,
|
||||
engine_output_type: latent}
|
||||
engine_input_source: [0]
|
||||
custom_process_input_func: vllm_omni.model_executor.stage_input_processors.qwen2_5_omni.thinker2talker
|
||||
default_sampling_params:
|
||||
temperature: 0.9
|
||||
top_p: 0.8
|
||||
top_k: 40
|
||||
max_tokens: 4096
|
||||
seed: 42
|
||||
detokenize: true
|
||||
repetition_penalty: 1.05
|
||||
stop_token_ids: [8294]
|
||||
- stage_id: 2
|
||||
runtime: {process: true, devices: '1', max_batch_size: 1}
|
||||
engine_args: {model_stage: code2wav, model_arch: Qwen2_5OmniForConditionalGeneration,
|
||||
worker_type: generation, scheduler_cls: vllm_omni.core.sched.omni_generation_scheduler.OmniGenerationScheduler,
|
||||
gpu_memory_utilization: 0.5, enforce_eager: true, trust_remote_code: true, enable_prefix_caching: false,
|
||||
engine_output_type: audio, max_num_batched_tokens: 4096, max_model_len: 4096}
|
||||
engine_input_source: [1]
|
||||
final_output: true
|
||||
final_output_type: audio
|
||||
default_sampling_params: {temperature: 0.0, top_p: 1.0, top_k: -1, max_tokens: 4096,
|
||||
seed: 42, detokenize: true, repetition_penalty: 1.1}
|
||||
runtime:
|
||||
enabled: true
|
||||
defaults: {window_size: -1, max_inflight: 1}
|
||||
edges:
|
||||
- {from: 0, to: 1, window_size: -1}
|
||||
- {from: 1, to: 2, window_size: -1}
|
||||
@@ -0,0 +1,45 @@
|
||||
stage_args:
|
||||
- stage_id: 0
|
||||
runtime: {devices: '0', max_batch_size: 5}
|
||||
engine_args: {model_stage: thinker, model_arch: Qwen3OmniMoeForConditionalGeneration,
|
||||
worker_type: ar, scheduler_cls: vllm_omni.core.sched.omni_ar_scheduler.OmniARScheduler,
|
||||
gpu_memory_utilization: 0.9, enforce_eager: false, trust_remote_code: true, engine_output_type: latent,
|
||||
distributed_executor_backend: mp, max_num_batched_tokens: 32768, max_model_len: 32768,
|
||||
enable_prefix_caching: false, mm_processor_cache_gb: 0, hf_config_name: thinker_config,
|
||||
tensor_parallel_size: 1, load_format: dummy, custom_process_next_stage_input_func: vllm_omni.model_executor.stage_input_processors.qwen3_omni.thinker2talker_async_chunk}
|
||||
final_output: true
|
||||
final_output_type: text
|
||||
is_comprehension: true
|
||||
default_sampling_params: {temperature: 0.4, top_p: 0.9, top_k: 1, max_tokens: 100,
|
||||
seed: 42, ignore_eos: false, detokenize: true, repetition_penalty: 1.05}
|
||||
- stage_id: 1
|
||||
runtime: {devices: '1', max_batch_size: 5}
|
||||
engine_args: {model_stage: talker, model_arch: Qwen3OmniMoeForConditionalGeneration,
|
||||
worker_type: ar, scheduler_cls: vllm_omni.core.sched.omni_ar_scheduler.OmniARScheduler,
|
||||
gpu_memory_utilization: 0.5, enforce_eager: false, trust_remote_code: true, engine_output_type: latent,
|
||||
enable_prefix_caching: false, max_num_batched_tokens: 32768, max_model_len: 32768,
|
||||
distributed_executor_backend: mp, hf_config_name: talker_config, load_format: dummy,
|
||||
custom_process_next_stage_input_func: vllm_omni.model_executor.stage_input_processors.qwen3_omni.talker2code2wav_async_chunk}
|
||||
engine_input_source: [0]
|
||||
custom_process_input_func: vllm_omni.model_executor.stage_input_processors.qwen3_omni.thinker2talker
|
||||
default_sampling_params:
|
||||
temperature: 0.9
|
||||
top_k: 50
|
||||
max_tokens: 1000
|
||||
seed: 42
|
||||
detokenize: false
|
||||
repetition_penalty: 1.05
|
||||
stop_token_ids: [2150]
|
||||
- stage_id: 2
|
||||
runtime: {devices: '1', max_batch_size: 1}
|
||||
engine_args: {model_stage: code2wav, model_arch: Qwen3OmniMoeForConditionalGeneration,
|
||||
worker_type: generation, scheduler_cls: vllm_omni.core.sched.omni_generation_scheduler.OmniGenerationScheduler,
|
||||
enforce_eager: true, trust_remote_code: true, enable_prefix_caching: false, engine_output_type: audio,
|
||||
gpu_memory_utilization: 0.1, distributed_executor_backend: mp, max_num_batched_tokens: 100000,
|
||||
hf_config_name: thinker_config, async_scheduling: false, load_format: dummy}
|
||||
engine_input_source: [1]
|
||||
final_output: true
|
||||
final_output_type: audio
|
||||
default_sampling_params: {temperature: 0.0, top_p: 1.0, top_k: -1, max_tokens: 2000,
|
||||
seed: 42, detokenize: true, repetition_penalty: 1.1}
|
||||
async_chunk: true
|
||||
@@ -0,0 +1,45 @@
|
||||
stage_args:
|
||||
- stage_id: 0
|
||||
runtime: {devices: '0', max_batch_size: 5}
|
||||
engine_args: {model_stage: thinker, model_arch: Qwen3OmniMoeForConditionalGeneration,
|
||||
worker_type: ar, scheduler_cls: vllm_omni.core.sched.omni_ar_scheduler.OmniARScheduler,
|
||||
gpu_memory_utilization: 0.9, enforce_eager: false, trust_remote_code: true, engine_output_type: latent,
|
||||
distributed_executor_backend: mp, max_num_batched_tokens: 32768, max_model_len: 32768,
|
||||
enable_prefix_caching: false, mm_processor_cache_gb: 0, hf_config_name: thinker_config,
|
||||
tensor_parallel_size: 1, load_format: dummy, custom_process_next_stage_input_func: vllm_omni.model_executor.stage_input_processors.qwen3_omni.thinker2talker_async_chunk}
|
||||
final_output: true
|
||||
final_output_type: text
|
||||
is_comprehension: true
|
||||
default_sampling_params: {temperature: 0.4, top_p: 0.9, top_k: 1, max_tokens: 100,
|
||||
seed: 42, ignore_eos: false, detokenize: true, repetition_penalty: 1.05}
|
||||
- stage_id: 1
|
||||
runtime: {devices: '1', max_batch_size: 5}
|
||||
engine_args: {model_stage: talker, model_arch: Qwen3OmniMoeForConditionalGeneration,
|
||||
worker_type: ar, scheduler_cls: vllm_omni.core.sched.omni_ar_scheduler.OmniARScheduler,
|
||||
gpu_memory_utilization: 0.5, enforce_eager: false, trust_remote_code: true, engine_output_type: latent,
|
||||
enable_prefix_caching: false, max_num_batched_tokens: 32768, max_model_len: 32768,
|
||||
distributed_executor_backend: mp, hf_config_name: talker_config, load_format: dummy,
|
||||
custom_process_next_stage_input_func: vllm_omni.model_executor.stage_input_processors.qwen3_omni.talker2code2wav_async_chunk}
|
||||
engine_input_source: [0]
|
||||
custom_process_input_func: vllm_omni.model_executor.stage_input_processors.qwen3_omni.thinker2talker
|
||||
default_sampling_params:
|
||||
temperature: 0.9
|
||||
top_k: 50
|
||||
max_tokens: 1000
|
||||
seed: 42
|
||||
detokenize: false
|
||||
repetition_penalty: 1.05
|
||||
stop_token_ids: [2150]
|
||||
- stage_id: 2
|
||||
runtime: {devices: '1', max_batch_size: 1}
|
||||
engine_args: {model_stage: code2wav, model_arch: Qwen3OmniMoeForConditionalGeneration,
|
||||
worker_type: generation, scheduler_cls: vllm_omni.core.sched.omni_generation_scheduler.OmniGenerationScheduler,
|
||||
enforce_eager: true, trust_remote_code: true, enable_prefix_caching: false, engine_output_type: audio,
|
||||
gpu_memory_utilization: 0.1, distributed_executor_backend: mp, max_num_batched_tokens: 100000,
|
||||
hf_config_name: thinker_config, async_scheduling: false, load_format: dummy}
|
||||
engine_input_source: [1]
|
||||
final_output: true
|
||||
final_output_type: audio
|
||||
default_sampling_params: {temperature: 0.0, top_p: 1.0, top_k: -1, max_tokens: 2000,
|
||||
seed: 42, detokenize: true, repetition_penalty: 1.1}
|
||||
async_chunk: true
|
||||
@@ -58,10 +58,6 @@ from vllm.multimodal.inputs import (
|
||||
MultiModalKwargsItems,
|
||||
)
|
||||
from vllm.multimodal.parse import MultiModalDataItems
|
||||
from vllm.multimodal.processing import (
|
||||
ProcessorInputs,
|
||||
TimingContext,
|
||||
)
|
||||
from vllm.multimodal.processing.processor import (
|
||||
MultiModalPromptUpdates,
|
||||
PlaceholderFeaturesInfo,
|
||||
@@ -80,16 +76,6 @@ class Qwen2_5OmniThinkerMultiModalProcessor(
|
||||
):
|
||||
"""Override to fix use_audio_in_video detection when mm cache returns None."""
|
||||
|
||||
def _cached_apply_hf_processor(
|
||||
self,
|
||||
inputs: ProcessorInputs,
|
||||
timing_ctx: TimingContext,
|
||||
):
|
||||
mm_processor_kwargs = inputs.hf_processor_mm_kwargs
|
||||
if mm_processor_kwargs.get("use_audio_in_video", False):
|
||||
return self._apply_hf_processor(inputs, timing_ctx)
|
||||
return super()._cached_apply_hf_processor(inputs, timing_ctx)
|
||||
|
||||
def _maybe_apply_prompt_updates(
|
||||
self,
|
||||
mm_items: MultiModalDataItems,
|
||||
|
||||
@@ -498,19 +498,13 @@ class Qwen3OmniMoeThinkerMultiModalProcessor(
|
||||
mm_item_counts,
|
||||
)
|
||||
else:
|
||||
if use_audio_in_video:
|
||||
# When use_audio_in_video=True, audio is extracted from video and embedded
|
||||
# in the video placeholder tokens. We should:
|
||||
# 1. Filter out audio from prompt updates (audio has no separate placeholder)
|
||||
# 2. Apply remaining updates (video, image, etc.)
|
||||
# 3. Derive audio placeholders from video placeholders
|
||||
if use_audio_in_video and "audio" in mm_prompt_updates:
|
||||
filtered_updates = {k: v for k, v in mm_prompt_updates.items() if k != "audio"}
|
||||
prompt_ids, mm_placeholders = self._apply_prompt_updates(
|
||||
prompt_ids,
|
||||
filtered_updates,
|
||||
)
|
||||
# Derive audio placeholders from video placeholders
|
||||
mm_placeholders = self._derive_audio_from_video_placeholders(mm_placeholders, mm_item_counts)
|
||||
mm_placeholders = self._derive_audio_from_video_placeholders(mm_placeholders, mm_prompt_updates)
|
||||
else:
|
||||
prompt_ids, mm_placeholders = self._apply_prompt_updates(
|
||||
prompt_ids,
|
||||
@@ -629,7 +623,7 @@ class Qwen3OmniMoeThinkerMultiModalProcessor(
|
||||
|
||||
def get_replacement_qwen2_use_audio_in_video(item_idx: int):
|
||||
nonlocal audio_in_video_item_idx
|
||||
audio_num_features = audio_output_lengths[audio_in_video_item_idx + item_idx]
|
||||
audio_num_features = audio_output_lengths[audio_in_video_item_idx]
|
||||
video_grid_thw = out_mm_data["video_grid_thw"][item_idx]
|
||||
|
||||
audio_in_video_item_idx += 1
|
||||
@@ -675,27 +669,17 @@ class Qwen3OmniMoeThinkerMultiModalProcessor(
|
||||
def _derive_audio_from_video_placeholders(
|
||||
self,
|
||||
placeholders: Mapping[str, list[PlaceholderFeaturesInfo]],
|
||||
mm_item_counts: Mapping[str, int],
|
||||
mm_prompt_updates: MultiModalPromptUpdates,
|
||||
) -> Mapping[str, list[PlaceholderFeaturesInfo]]:
|
||||
"""
|
||||
Helper to derive audio placeholders from video placeholders when
|
||||
use_audio_in_video=True.
|
||||
|
||||
In use_audio_in_video mode, audio is extracted from video and embedded
|
||||
within the video placeholder tokens. This function creates audio placeholder
|
||||
info by extracting the audio token positions from video placeholders.
|
||||
|
||||
Args:
|
||||
placeholders: Current placeholders (should contain "video")
|
||||
mm_item_counts: Counts of multimodal items from mm_items.get_all_counts()
|
||||
"""
|
||||
if "video" not in placeholders:
|
||||
return placeholders
|
||||
|
||||
# Validate audio and video counts match
|
||||
# In use_audio_in_video mode, audio count comes from mm_items (extracted from video)
|
||||
num_videos = len(placeholders["video"])
|
||||
num_audios = mm_item_counts.get("audio", 0)
|
||||
num_audios = len(mm_prompt_updates.get("audio", []))
|
||||
if num_audios != num_videos:
|
||||
raise ValueError(
|
||||
f"use_audio_in_video requires equal number of audio and video items, got {num_audios=}, {num_videos=}"
|
||||
|
||||
Reference in new issue
Block a user