Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
d7848ed
refactor stage proc and client
chickeyton Jul 16, 2026
a1915dc
Fix StageLLMCoreProcManager kwarg key to match run_stage_core param
chickeyton Jul 16, 2026
40d1c0a
bugfix
chickeyton Jul 17, 2026
f6590a8
enhancement
chickeyton Jul 17, 2026
1f1d0d9
fix arg name
chickeyton Jul 22, 2026
25a1e19
Port main's post-refactor stage changes into vllm_omni/engine/stage
chickeyton Jul 23, 2026
af0fdf6
Fix rebase gap: rename OmniEngineCoreRequest in model_intermediate_bu…
chickeyton Jul 24, 2026
a52cc79
Fix stale test doubles in test_orchestrator for refactored stage pool…
chickeyton Jul 24, 2026
ab41b0c
Remove 6 legacy stage modules superseded by engine/stage subpackage
chickeyton Jul 24, 2026
31e347f
Remove stage_client.py by dropping its type-only Protocol surface
chickeyton Jul 24, 2026
73175dc
Make InlineStageDiffusionClient a true StageCoreClientBase subclass
chickeyton Jul 24, 2026
4d997f1
Fix test_run_llm_to_diffusion assertion for typed diffusion request
chickeyton Jul 24, 2026
d4c85aa
Simplify engine/stage/__init__.py: drop unused re-export layer
chickeyton Jul 24, 2026
0b01b0d
Relocate diffusion stage modules to vllm_omni/diffusion/stage/
chickeyton Jul 24, 2026
0846abe
Port main's preprocess_add_request into relocated StageLLMCoreProc
chickeyton Jul 24, 2026
1a9178a
Fix post-rebase stage test breakage surfaced on server 1
chickeyton Jul 27, 2026
9734b1b
Drop redundant quotes on make_async_mp_client annotations
chickeyton Jul 27, 2026
78e6fb8
Apply pre-commit: ruff format/lint, wrap long log lines, add test marks
chickeyton Jul 27, 2026
06b45c1
Adopt centralized vllm_omni.metrics helpers in StageReplicaPool
chickeyton Jul 27, 2026
693a869
Port submit_interaction (midway prompt update #4652) into relocated s…
chickeyton Jul 27, 2026
f807bf6
Merge branch 'main' into clean_stage_proc_rebase
chickeyton Jul 27, 2026
ba9e3dd
update doc
chickeyton Jul 27, 2026
78c7fad
Merge branch 'clean_stage_proc_rebase' of https://github.com/chickeyt…
chickeyton Jul 27, 2026
759e580
fix review comments
chickeyton Jul 28, 2026
42fe2f2
Merge remote-tracking branch 'origin/main' into clean_stage_proc_rebase
chickeyton Jul 28, 2026
2712a63
Merge remote-tracking branch 'origin/main' into clean_stage_proc_rebase
chickeyton Jul 29, 2026
cf4288e
Apply ruff-format to deprecation warning string
chickeyton Jul 29, 2026
ae8320a
[docs] Add stage type extensibility example to async omni architecture
chickeyton Jul 29, 2026
ea167a1
Merge remote-tracking branch 'origin/main' into clean_stage_proc_rebase
chickeyton Jul 30, 2026
0fef82f
[refactor] Replace Any with concrete types in stage client/pool signa…
chickeyton Jul 30, 2026
44ddf83
Merge branch 'main' into clean_stage_proc_rebase
chickeyton Jul 31, 2026
8d389d9
Merge branch 'main' into clean_stage_proc_rebase
chickeyton Jul 31, 2026
455865e
Merge remote-tracking branch 'origin/main' into clean_stage_proc_rebase
chickeyton Aug 3, 2026
268b1b3
Merge branch 'main' into clean_stage_proc_rebase
chickeyton Aug 4, 2026
c9bf498
Merge remote-tracking branch 'origin/main' into clean_stage_proc_rebase
chickeyton Aug 5, 2026
8e6af27
Merge remote-tracking branch 'origin/clean_stage_proc_rebase' into cl…
chickeyton Aug 5, 2026
40be871
Merge branch 'main' into clean_stage_proc_rebase
chickeyton Aug 7, 2026
0aa670e
Merge branch 'main' of https://github.com/vllm-project/vllm-omni into…
chickeyton Aug 7, 2026
90d4fad
Merge remote-tracking branch 'origin/clean_stage_proc_rebase' into cl…
chickeyton Aug 7, 2026
0802e23
Merge branch 'main' of https://github.com/vllm-project/vllm-omni into…
chickeyton Aug 7, 2026
2cdb989
Merge branch 'main' of https://github.com/vllm-project/vllm-omni into…
chickeyton Aug 10, 2026
fd880bf
Merge branch 'main' of https://github.com/vllm-project/vllm-omni into…
chickeyton Aug 11, 2026
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
8 changes: 4 additions & 4 deletions docs/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ Engine classes for offline and online inference.
- [vllm_omni.distributed.omni_connectors.connectors.mooncake_transfer_engine_connector.QueryResponse][]
- [vllm_omni.engine.AdditionalInformationEntry][]
- [vllm_omni.engine.AdditionalInformationPayload][]
- [vllm_omni.engine.OmniEngineCoreOutput][]
- [vllm_omni.engine.OmniEngineCoreOutputs][]
- [vllm_omni.engine.OmniEngineCoreRequest][]
- [vllm_omni.engine.PromptEmbedsPayload][]
- [vllm_omni.engine.arg_utils.OmniEngineArgs][]
- [vllm_omni.engine.async_omni_engine.AsyncOmniEngine][]
- [vllm_omni.engine.orchestrator.Orchestrator][]
- [vllm_omni.engine.orchestrator.OrchestratorRequestState][]
- [vllm_omni.engine.stage_engine_core_client.StageEngineCoreClient][]
- [vllm_omni.engine.stage.stage_core_types.StageLLMCoreOutput][]
- [vllm_omni.engine.stage.stage_core_types.StageLLMCoreOutputs][]
- [vllm_omni.engine.stage.stage_core_types.StageLLMCoreRequest][]
- [vllm_omni.engine.stage.stage_llm_core_client.StageLLMCoreClient][]
- [vllm_omni.engine.stage_init_utils.StageMetadata][]
- [vllm_omni.engine.stage_init_utils.StartedLlmStage][]
- [vllm_omni.outputs.mm_outputs.MultimodalCompletionOutput][]
Expand Down
4 changes: 2 additions & 2 deletions docs/configuration/composable_parallel.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ Effective `OmniParallelConfig` per stage after the overlay (see `OmniParallelCon

### Example 2 — `strategy_stage_replica.yaml`

Replicate the `thinker` stage across two independent engines and let omni's StagePool round-robin requests across them.
Replicate the `thinker` stage across two independent engines and let omni's StageReplicaPool round-robin requests across them.

```yaml
# examples/offline_inference/qwen2_5_omni/strategy_stage_replica.yaml
Expand Down Expand Up @@ -184,7 +184,7 @@ Overrides which layer owns request routing along this axis. `engine` means vLLM

### `stage_replica` and `omni_lb_policy`

`stage_replica` is *not* a vLLM world dimension; it spins up `size` independent engine replicas of one stage, coordinated by the omni `StagePool` load balancer. The axis writes both:
`stage_replica` is *not* a vLLM world dimension; it spins up `size` independent engine replicas of one stage, coordinated by the omni `StageReplicaPool` load balancer. The axis writes both:

- The stage's `num_replicas` (a per-stage deploy knob).
- The pipeline-wide `omni_lb_policy` string (an orchestrator-level knob).
Expand Down
68 changes: 33 additions & 35 deletions docs/contributing/model/adding_omni_model.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,69 +341,67 @@ Stage transitions happen automatically in the runtime orchestrator. Here's the d
2. **Trigger**: When a stage completes processing and produces outputs
3. **Execution Flow**:
```python
# In orchestrator.py
# In orchestrator.py (_forward_to_next_stage)
next_stage_id = stage_id + 1
next_client = self.stage_clients[next_stage_id]
next_pool = self.stage_pools[next_stage_id]
params = req_state.sampling_params_list[next_stage_id]

# Save current stage outputs so stage_input_processors can consume them.
self.stage_clients[stage_id].set_engine_outputs([output])

# THIS IS WHERE STAGE TRANSITION HAPPENS
next_inputs = next_client.process_engine_inputs(
stage_list=self.stage_clients,
prompt=req_state.prompt,
# The completed stage's outputs are passed straight into the next stage's
# input processor (there is no stored state on the client to read back).
next_inputs = next_client.process_core_inputs(
source_outputs,
req_state.prompt,
streaming_context=req_state.streaming,
)

# Build and submit request(s) to the next stage.
# Build and submit request(s) to the next stage via its replica pool.
for next_input in next_inputs:
request = build_engine_core_request_from_tokens(
request_id=req_id,
prompt=next_input,
params=params,
model_config=self.stage_vllm_configs[next_stage_id].model_config,
model_config=next_pool.stage_vllm_config.model_config,
)
await next_client.add_request_async(request)
await next_pool.submit_initial(req_id, req_state, request, prompt_text=None)
```

### How Stage Transitions Work

The stage transition process follows these steps:

1. **Stage Completion**: When a stage finishes processing a request, the orchestrator stores outputs via `stage_client.set_engine_outputs(...)`
1. **Stage Completion**: When a stage finishes processing a request, the orchestrator passes the completed stage's outputs straight into the next stage's `process_core_inputs(...)`

2. **Transition Detection**: The orchestrator checks if there's a next stage and calls `process_engine_inputs()` on it
2. **Transition Detection**: The orchestrator checks if there's a next stage and calls `process_core_inputs()` on it

3. **Input Processing**: The stage input processor configured in stage YAML (under `vllm_omni/model_executor/stage_input_processors/`) handles the transition:
```python
def process_engine_inputs(
self, stage_list: list[Any], prompt: OmniTokensPrompt | TextPrompt = None
) -> list[OmniTokensPrompt | TextPrompt]:
"""Process engine inputs for this stage from upstream stage outputs."""
def process_core_inputs(
self, source_outputs: list[Any], prompt: Any = None, streaming_context: Any | None = None
) -> list[OmniTokensPrompt]:
"""Process this stage's inputs from the upstream stage outputs."""

if self.custom_process_input_func is None:
# Default behavior: pass token IDs directly
# Extract outputs from source stage
source_stage_id = self.engine_input_source[0]
source_outputs = stage_list[source_stage_id].engine_outputs
# ... create OmniTokensPrompt from token_ids ...
# Default behavior: pass token IDs directly from source_outputs
# ... create OmniTokensPrompt from source_outputs token_ids ...
else:
# Custom transition function (YOUR CODE HERE)
return self.custom_process_input_func(
stage_list,
self.engine_input_source,
source_outputs,
prompt,
self.requires_multimodal_data
self.requires_multimodal_data,
streaming_context,
)
```
- If `custom_process_input_func` is configured, it calls that function
- Otherwise, it uses default behavior (passing token IDs directly)

4. **Custom Function Execution**: Your custom function receives:
- `stage_list`: List of all stage objects (to access upstream stage outputs)
- `engine_input_source`: List of source stage IDs (e.g., `[0]` for stage 0)
- `source_outputs`: The upstream stage's outputs (already extracted for you)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3] Update the later data-structures section too

This correctly documents source_outputs, but the “Data Structures in Stage Transitions” section immediately below still tells authors to read stage_list[source_stage_id].engine_outputs, which no longer exists after this refactor. Please update that section to describe source_outputs itself (and its element shape) so contributors do not implement the removed API.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. The "Data Structures in Stage Transitions" section and the "Key Points" list
no longer reference the removed stage_list[source_stage_id].engine_outputs. Both
now describe source_outputs directly and its element shape, which I verified
against a real consumer (stage_input_processors/dynin_omni.py:
for source_output in source_outputs: output = source_output.outputs[0]; output.multimodal_output):

  • each entry has request_id and outputs (per-sequence; typically outputs[0])
  • each per-sequence output has token_ids / cumulative_token_ids,
    multimodal_output, and prompt_token_ids

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thanks!

- `prompt`: Original prompt data (for preserving multimodal data)
- `requires_multimodal_data`: Whether multimodal data is required
- `streaming_context`: Streaming state for the request (passed only when the function accepts 4+ parameters)

5. **Output Format**: The function must return a list of `OmniTokensPrompt` objects ready for the next stage

Expand All @@ -412,12 +410,12 @@ The stage transition process follows these steps:
Understanding the data structures is crucial for implementing stage transitions:

**Input to your function:**
- `stage_list[source_stage_id].engine_outputs`: List of `EngineCoreOutput` objects
- - Each contains `outputs`: List of `RequestOutput` objects
- Each `RequestOutput` has:
- - - `token_ids`: Generated token IDs
- `multimodal_output`: Dict with keys like `"code_predictor_codes"`, etc.These are the hidden states or intermediate outputs from the model's forward pass
- `prompt_token_ids`: Original prompt token IDs
- `source_outputs`: the upstream stage's output objects, already extracted for you (one entry per request in the batch, plus any CFG companion outputs). You iterate this list directly — there is no `stage_list`/`engine_outputs` lookup anymore. Each entry has:
- `request_id`: The request this output belongs to
- `outputs`: List of per-sequence outputs (typically `source_output.outputs[0]`). Each has:
- `token_ids` / `cumulative_token_ids`: Generated token IDs
- `multimodal_output`: Dict with keys like `"code_predictor_codes"`, etc. — the hidden states or intermediate outputs from the model's forward pass
- `prompt_token_ids`: Original prompt token IDs

**Output from your function:**
- Must return `list[OmniTokensPrompt]` where each `OmniTokensPrompt` contains:
Expand Down Expand Up @@ -462,7 +460,7 @@ thinker_hidden_states = output.multimodal_output["24"]

### Key Points

1. **Accessing Upstream Outputs**: Use `stage_list[source_stage_id].engine_outputs` to get outputs from the source stage
1. **Accessing Upstream Outputs**: Iterate `source_outputs` directly — it already holds the source stage's outputs (the runtime extracts them for you; no `stage_list[source_stage_id].engine_outputs` lookup needed)
2. **Extracting Data**: Access `output.multimodal_output[key]` to get specific hidden states or intermediate results
- Keys are defined by your model's `forward()` method when it creates `multimodal_outputs`
3. **Device Management**: Move tensors to appropriate devices (CPU for serialization, GPU for processing)
Expand Down Expand Up @@ -504,7 +502,7 @@ def thinker2talker_token_only(
def thinker2talker_full_payload(
transfer_manager: Any,
pooling_output: dict[str, Any],
request: OmniEngineCoreRequest,
request: StageLLMCoreRequest,
) -> dict[str, Any] | None:
"""Pack accumulated thinker hidden states into OmniPayload for stage-1."""
...
Expand All @@ -513,7 +511,7 @@ def thinker2talker_full_payload(
def thinker2talker_async_chunk(
transfer_manager: Any,
multimodal_output: OmniPayload | dict[str, Any],
request: OmniEngineCoreRequest,
request: StageLLMCoreRequest,
is_finished: bool = False,
) -> OmniPayloadStruct | None:
"""Stream thinker rows to talker while async_chunk is enabled."""
Expand Down
6 changes: 3 additions & 3 deletions docs/design/module/archive/ar_module.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ classDiagram
- **Scheduler**: `OmniARScheduler` extends `vllm.v1.core.sched.scheduler.Scheduler` to enrich scheduled requests with omni-specific payloads
- **Worker**: `GPUARWorker` extends `vllm.v1.worker.gpu_worker.Worker` to initialize AR-specific model runners
- **ModelRunner**: `GPUARModelRunner` extends `OmniGPUModelRunner` → `vllm.v1.worker.gpu_model_runner.GPUModelRunner` to expose hidden states and handle multimodal outputs
- **InputProcessor**: Stage-0 uses upstream `vllm.v1.engine.input_processor.InputProcessor`; `AsyncOmniEngine` then restores omni-specific payloads (for example `additional_information` and `prompt_embeds`) when building `OmniEngineCoreRequest`
- **InputProcessor**: Stage-0 uses upstream `vllm.v1.engine.input_processor.InputProcessor`; `AsyncOmniEngine` then restores omni-specific payloads (for example `additional_information` and `prompt_embeds`) when building `StageLLMCoreRequest`
- **OutputProcessor**: `MultimodalOutputProcessor` extends `vllm.v1.engine.output_processor.OutputProcessor` to route and accumulate multimodal outputs

## 3. Scheduler Design
Expand All @@ -114,7 +114,7 @@ The following diagram illustrates the request flow through the AR module compone

```mermaid
flowchart TD
A[InputProcessor stage-0 in AsyncOmniEngine] -->|EngineCoreRequest then upgraded to OmniEngineCoreRequest| B[OmniARScheduler]
A[InputProcessor stage-0 in AsyncOmniEngine] -->|EngineCoreRequest then upgraded to StageLLMCoreRequest| B[OmniARScheduler]
B -->|schedule: OmniNewRequestData| C[GPUARWorker]
C -->|SchedulerOutput| D[GPUARModelRunner]
D -->|execute_model: None| E[Model Forward Pass]
Expand Down Expand Up @@ -318,7 +318,7 @@ sequenceDiagram

### Stage-0 Input Processing

Stage-0 now uses upstream `InputProcessor` directly, and `AsyncOmniEngine` upgrades the request to `OmniEngineCoreRequest` while restoring omni-specific payloads.
Stage-0 now uses upstream `InputProcessor` directly, and `AsyncOmniEngine` upgrades the request to `StageLLMCoreRequest` while restoring omni-specific payloads.

```python
request = self.input_processor.process_inputs(
Expand Down
Loading
Loading