+
+
+## About
+
+[vLLM](https://github.com/vllm-project/vllm) was originally designed to support large language models for text-based autoregressive generation tasks. vLLM-Omni extends its support for omni-modality model inference and serving:
+
+- **Omni-modality**: Text, image, video, and audio data processing
+- **Non-autoregressive Architectures**: extend the AR support of vLLM to Diffusion Transformers (DiT) and other parallel generation models
+- **Heterogeneous outputs**: from traditional text generation to multimodal outputs
+
+
+
+
+
+
+
+vLLM-omni is fast with:
+
+- Seamless AR support for efficient KV Cache management with vLLM
+- Pipelined stage execution overlapping
+- Fully disaggregation based on omniConnector and dynamic resource allocation across stages
+
+vLLM-omni is flexible and easy to use with:
+
+- Seamless integration with popular Hugging Face models
+- High-throughput serving with various decoding algorithms, including *parallel sampling*, *beam search*, and more
+- Tensor, pipeline, data and expert parallelism support for distributed inference
+- Streaming outputs
+- OpenAI-compatible API server
+
+vLLM-Omni seamlessly supports most popular open-source models on HuggingFace, including:
+
+- Multi-modality generation models (e.g. Qwen-image)
+- Omni-modality models (e.g. Qwen-omni)
+
+For more information, checkout the following:
diff --git a/docs/api/README.md b/docs/api/README.md
new file mode 100644
index 000000000..9398fea11
--- /dev/null
+++ b/docs/api/README.md
@@ -0,0 +1,88 @@
+# Summary
+
+## Entry Points
+
+Main entry points for vLLM-omni inference and serving.
+
+- [vllm_omni.entrypoints.async_omni_llm.AsyncOmniLLM][]
+- [vllm_omni.entrypoints.async_omni_llm.AsyncOmniStageLLM][]
+- [vllm_omni.entrypoints.chat_utils.OmniAsyncMultiModalContentParser][]
+- [vllm_omni.entrypoints.chat_utils.OmniAsyncMultiModalItemTracker][]
+- [vllm_omni.entrypoints.chat_utils.parse_chat_messages_futures][]
+- [vllm_omni.entrypoints.cli.serve.OmniServeCommand][]
+- [vllm_omni.entrypoints.log_utils.OrchestratorMetrics][]
+- [vllm_omni.entrypoints.omni_llm.OmniLLM][]
+- [vllm_omni.entrypoints.omni_llm.OmniStageLLM][]
+- [vllm_omni.entrypoints.omni_stage.OmniStage][]
+- [vllm_omni.entrypoints.openai.serving_chat.OmniOpenAIServingChat][]
+
+## Inputs
+
+Input data structures for multi-modal inputs.
+
+- [vllm_omni.inputs.data.OmniEmbedsPrompt][]
+- [vllm_omni.inputs.data.OmniTokenInputs][]
+- [vllm_omni.inputs.data.OmniTokensPrompt][]
+- [vllm_omni.inputs.parse.parse_singleton_prompt_omni][]
+- [vllm_omni.inputs.preprocess.OmniInputPreprocessor][]
+
+## Engine
+
+Engine classes for offline and online inference.
+
+- [vllm_omni.engine.AdditionalInformationEntry][]
+- [vllm_omni.engine.AdditionalInformationPayload][]
+- [vllm_omni.engine.OmniEngineCoreRequest][]
+- [vllm_omni.engine.PromptEmbedsPayload][]
+- [vllm_omni.engine.arg_utils.AsyncOmniEngineArgs][]
+- [vllm_omni.engine.arg_utils.OmniEngineArgs][]
+- [vllm_omni.engine.output_processor.MultimodalOutputProcessor][]
+- [vllm_omni.engine.output_processor.OmniRequestState][]
+- [vllm_omni.engine.processor.OmniProcessor][]
+
+## Core
+
+Core scheduling and caching components.
+
+- [vllm_omni.core.dit_cache_manager.DiTCacheManager][]
+- [vllm_omni.core.sched.diffusion_scheduler.DiffusionScheduler][]
+- [vllm_omni.core.sched.output.OmniNewRequestData][]
+- [vllm_omni.core.sched.scheduler.OmniScheduler][]
+
+## Model Executor
+
+Model execution components.
+
+- [vllm_omni.model_executor.models.qwen2_5_omni.qwen2_5_omni.OmniOutput][]
+- [vllm_omni.model_executor.models.qwen2_5_omni.qwen2_5_omni.Qwen2_5OmniForConditionalGeneration][]
+- [vllm_omni.model_executor.models.qwen2_5_omni.qwen2_5_omni_talker.Qwen2_5OmniTalkerForConditionalGeneration][]
+- [vllm_omni.model_executor.models.qwen2_5_omni.qwen2_5_omni_thinker.Qwen2_5OmniAudioFeatureInputs][]
+- [vllm_omni.model_executor.models.qwen2_5_omni.qwen2_5_omni_thinker.Qwen2_5OmniConditionalGenerationMixin][]
+- [vllm_omni.model_executor.models.qwen2_5_omni.qwen2_5_omni_thinker.Qwen2_5OmniThinkerDummyInputsBuilder][]
+- [vllm_omni.model_executor.models.qwen2_5_omni.qwen2_5_omni_thinker.Qwen2_5OmniThinkerForConditionalGeneration][]
+- [vllm_omni.model_executor.models.qwen2_5_omni.qwen2_5_omni_thinker.Qwen2_5OmniThinkerMultiModalDataParser][]
+- [vllm_omni.model_executor.models.qwen2_5_omni.qwen2_5_omni_thinker.Qwen2_5OmniThinkerMultiModalProcessor][]
+- [vllm_omni.model_executor.models.qwen2_5_omni.qwen2_5_omni_thinker.Qwen2_5OmniThinkerProcessingInfo][]
+- [vllm_omni.model_executor.models.qwen2_5_omni.qwen2_5_omni_token2wav.Qwen2_5OmniToken2WavBigVGANModel][]
+- [vllm_omni.model_executor.models.qwen2_5_omni.qwen2_5_omni_token2wav.Qwen2_5OmniToken2WavDiTModel][]
+- [vllm_omni.model_executor.models.qwen2_5_omni.qwen2_5_omni_token2wav.Qwen2_5OmniToken2WavForConditionalGenerationVLLM][]
+- [vllm_omni.model_executor.models.qwen2_5_omni.qwen2_5_omni_token2wav.Qwen2_5OmniToken2WavModel][]
+- [vllm_omni.model_executor.models.qwen2_5_omni.qwen2_old.Qwen2EmbeddingModel][]
+- [vllm_omni.model_executor.models.qwen2_5_omni.qwen2_old.Qwen2ForCausalLM][]
+- [vllm_omni.model_executor.models.qwen2_5_omni.qwen2_old.Qwen2Model][]
+
+## Configuration
+
+Configuration classes.
+
+- [vllm_omni.config.model.OmniModelConfig][]
+
+## Workers
+
+Worker classes and model runners for distributed inference.
+
+- [vllm_omni.worker.gpu_ar_model_runner.GPUARModelRunner][]
+- [vllm_omni.worker.gpu_ar_worker.GPUARWorker][]
+- [vllm_omni.worker.gpu_diffusion_model_runner.GPUDiffusionModelRunner][]
+- [vllm_omni.worker.gpu_diffusion_worker.GPUDiffusionWorker][]
+- [vllm_omni.worker.gpu_model_runner.OmniGPUModelRunner][]
diff --git a/docs/api/overview.md b/docs/api/overview.md
deleted file mode 100644
index 8a33a9095..000000000
--- a/docs/api/overview.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# Summary
-
-## Entry Points
-
-Main entry points for vLLM-omni inference and serving.
-
-- [vllm_omni.entrypoints.omni_llm.OmniLLM][]
-- [vllm_omni.entrypoints.omni_llm.OmniStageLLM][]
-- [vllm_omni.entrypoints.omni_stage.OmniStage][]
-- [vllm_omni.entrypoints.cli.serve.OmniServeCommand][]
-
-## Inputs
-
-Input data structures for multi-modal inputs.
-
-- [vllm_omni.inputs.data.OmniTokenInputs][]
-- [vllm_omni.inputs.data.OmniTokensPrompt][]
-- [vllm_omni.inputs.data.OmniEmbedsPrompt][]
-- [vllm_omni.inputs.parse.parse_singleton_prompt_omni][]
-- [vllm_omni.inputs.preprocess.OmniInputPreprocessor][]
-
-## Engine
-
-Engine classes for offline and online inference.
-
-- [vllm_omni.engine.arg_utils.OmniEngineArgs][]
-- [vllm_omni.engine.processor.OmniProcessor][]
-- [vllm_omni.engine.output_processor.OmniRequestState][]
-- [vllm_omni.engine.output_processor.MultimodalOutputProcessor][]
-- [vllm_omni.engine.PromptEmbedsPayload][]
-- [vllm_omni.engine.AdditionalInformationPayload][]
-- [vllm_omni.engine.OmniEngineCoreRequest][]
-
-## Core
-
-Core scheduling and caching components.
-
-- [vllm_omni.core.sched.scheduler.OmniScheduler][]
-- [vllm_omni.core.sched.diffusion_scheduler.DiffusionScheduler][]
-- [vllm_omni.core.sched.output.OmniNewRequestData][]
-- [vllm_omni.core.dit_cache_manager.DiTCacheManager][]
-
-## Model Executor
-
-Model execution components.
-
-- [vllm_omni.model_executor.models.qwen2_5_omni.Qwen2_5OmniForConditionalGeneration][]
-- [vllm_omni.model_executor.models.qwen2_5_omni_talker.Qwen2_5OmniTalkerForConditionalGeneration][]
-- [vllm_omni.model_executor.models.qwen2_5_omni_thinker.Qwen2_5OmniThinkerForConditionalGeneration][]
-- [vllm_omni.model_executor.models.qwen2_5_omni_token2wav.Qwen2_5OmniToken2WavForConditionalGenerationVLLM][]
-- [vllm_omni.model_executor.layers.mrope.MRotaryEmbedding][]
-- [vllm_omni.model_executor.models.registry.OmniModelRegistry][]
-
-## Configuration
-
-Configuration classes.
-
-- [vllm_omni.config.OmniModelConfig][]
-
-## Workers
-
-Worker classes and model runners for distributed inference.
-
-- [vllm_omni.worker.gpu_ar_worker.GPUARWorker][]
-- [vllm_omni.worker.gpu_diffusion_worker.GPUDiffusionWorker][]
-- [vllm_omni.worker.gpu_model_runner.OmniGPUModelRunner][]
-- [vllm_omni.worker.gpu_ar_model_runner.GPUARModelRunner][]
-- [vllm_omni.worker.gpu_diffusion_model_runner.GPUDiffusionModelRunner][]
diff --git a/docs/cli/README.md b/docs/cli/README.md
new file mode 100644
index 000000000..8069110b3
--- /dev/null
+++ b/docs/cli/README.md
@@ -0,0 +1,24 @@
+# vLLM-Omni CLI Guide
+
+The CLI for vLLM-Omni inherits from vllm with some additional arguments.
+
+## serve
+
+Starts the vLLM-Omni OpenAI Compatible API server.
+
+Start with a model:
+
+```bash
+vllm serve Qwen/Qwen2.5-Omni-7B --omni
+```
+
+Specify the port:
+
+```bash
+vllm serve Qwen/Qwen2.5-Omni-7B --omni --port 8091
+```
+
+If you have custom stage configs file, launch the server with command below
+```bash
+vllm serve Qwen/Qwen2.5-Omni-7B --omni --stage-configs-path /path/to/stage_configs_file
+```
diff --git a/docs/community/contact_us.md b/docs/community/contact_us.md
new file mode 100644
index 000000000..d1a0fbccf
--- /dev/null
+++ b/docs/community/contact_us.md
@@ -0,0 +1,6 @@
+# Contact Us
+
+- For technical questions and feature requests, please use GitHub [Issues](https://github.com/vllm-project/vllm-omni/issues)
+- For discussing with fellow users, please use the [vLLM Forum](https://discuss.vllm.ai/)
+- For coordinating contributions and development, please use [Slack](https://slack.vllm.ai/)
+- For security disclosures, please use GitHub's [Security Advisories](https://github.com/vllm-project/vllm/security/advisories) feature
diff --git a/docs/community/meetups.md b/docs/community/meetups.md
new file mode 100644
index 000000000..3374fe711
--- /dev/null
+++ b/docs/community/meetups.md
@@ -0,0 +1 @@
+# Meetups
diff --git a/docs/configuration/README.md b/docs/configuration/README.md
new file mode 100644
index 000000000..02f164a03
--- /dev/null
+++ b/docs/configuration/README.md
@@ -0,0 +1,11 @@
+# Configuration Options
+
+This section lists the most common options for running vLLM-Omni.
+
+For options within a vLLM Engine. Please refer to [vLLM Configuration](https://docs.vllm.ai/en/v0.11.0/configuration/index.html)
+
+Currently, the main options are maintained by stage configs for each model.
+
+For specific example, please refer to [Qwen2.5-omni stage config](stage_configs/qwen2_5_omni.yaml)
+
+For introduction, please check [Introduction for stage config](./stage_configs.md)
diff --git a/docs/configuration/stage_configs.md b/docs/configuration/stage_configs.md
new file mode 100644
index 000000000..48ceac159
--- /dev/null
+++ b/docs/configuration/stage_configs.md
@@ -0,0 +1,267 @@
+# Stage configs for vLLM-Omni
+
+In vLLM-Omni, it divides models in vLLM-omni into multiple stages, which are processed by different LLMEngines, DiffusionEngines or other kinds of engines. According to different types of stages, such as AR stage or DiT stage, each stage can choose corresponding schedulers, model workers to load into Engines with a plug-in way.
+
+Therefore, the stage configs for a model have several main functions:
+
+- Claim partition of stages and corresponding class implementation in the folder model_executor/models.
+- The disaggregated configuration for each stage and the communication topology among them.
+- Engine arguments for each engine within the stage.
+- Input and output dependencies for each stage.
+- Default input parameters.
+
+If users want to modify some part of it. The custom stage_configs file can be input as input argument in both online and offline. Just like examples below:
+
+For offline (Assume necessary dependencies have ben imported):
+```python
+model_name = "Qwen/Qwen2.5-Omni-7B"
+omni_llm = OmniLLM(model=model_name, stage_configs_path="/path/to/custom_stage_configs.yaml")
+```
+
+For online serving:
+```bash
+vllm serve Qwen/Qwen2.5-Omni-7B --omni --port 8091 --stage-configs-path /path/to/stage_configs_file
+```
+
+Below is a specific example of stage_configs.yaml in Qwen2.5-omni.
+```python
+# stage config for running qwen2.5-omni with architecture of OmniLLM.
+stage_args:
+ - stage_id: 0 # mark the unique id for each stage
+ runtime: # The disaggregated configuration
+ process: true # Run this stage in a separate process
+ devices: "0" # Visible devices for this stage (CUDA_VISIBLE_DEVICES/torch.cuda.set_device)
+ max_batch_size: 1 # the batch_size for offline inference
+ engine_args: # Engine arguments for a certain engine
+ model_stage: thinker
+ model_arch: Qwen2_5OmniForConditionalGeneration # The model implementation registered in model_executor/models/registry.py
+ worker_cls: vllm_omni.worker.gpu_ar_worker.GPUARWorker # The specific worker used
+ scheduler_cls: vllm_omni.core.sched.scheduler.OmniScheduler # The specific scehduler used
+ gpu_memory_utilization: 0.8 # The gpu memory allocation for the stage within a single chip
+ enforce_eager: true # Now we only support eager mode
+ trust_remote_code: true # Needed by huggingface config parsing
+ engine_output_type: latent # It claims that the stage will input latent hiddenstates besides token ids
+ enable_prefix_caching: false # For request with hiddenstates output, the prefix caching is not supported now
+ is_comprehension: true # If the stage is a text or multimodal comprehension module. If it is, the AsyncOmniLLM will use its tokenizer as default
+ final_output: true # If the stage has output as part of final outputs. If it is false, which means that the stage only works as a intermediate role.
+ final_output_type: text # What is the final output type. It can be text and audio now.
+ default_sampling_params: # sampling parameters for the stage. Their meaning aligns with vLLM.
+ temperature: 0.0
+ top_p: 1.0
+ top_k: -1
+ max_tokens: 2048
+ seed: 42
+ detokenize: True
+ repetition_penalty: 1.1
+ - stage_id: 1
+ runtime:
+ process: true
+ devices: "1"
+ max_batch_size: 3
+ engine_args:
+ model_stage: talker
+ model_arch: Qwen2_5OmniForConditionalGeneration
+ worker_cls: vllm_omni.worker.gpu_ar_worker.GPUARWorker
+ scheduler_cls: vllm_omni.core.sched.scheduler.OmniScheduler
+ gpu_memory_utilization: 0.8
+ 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: 2048
+ seed: 42
+ detokenize: True
+ repetition_penalty: 1.05
+ stop_token_ids: [8294]
+ - stage_id: 2
+ runtime:
+ process: true
+ devices: "0" # Example: use a different GPU than the previous stage; use "0" if single GPU
+ max_batch_size: 1
+ engine_args:
+ model_stage: code2wav
+ model_arch: Qwen2_5OmniForConditionalGeneration
+ worker_cls: vllm_omni.worker.gpu_diffusion_worker.GPUDiffusionWorker
+ scheduler_cls: vllm_omni.core.sched.diffusion_scheduler.DiffusionScheduler
+ gpu_memory_utilization: 0.15
+ enforce_eager: true
+ trust_remote_code: true
+ enable_prefix_caching: false
+ engine_output_type: audio
+ 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: 2048
+ seed: 42
+ detokenize: True
+ repetition_penalty: 1.1
+
+# Top-level runtime config (concise): default windows and stage edges
+runtime:
+ enabled: true
+ defaults:
+ window_size: -1 # Simplified: trigger downstream only after full upstream completion
+ max_inflight: 1 # Simplified: process serially within each stage
+ edges:
+ - from: 0 # thinker β talker: trigger only after receiving full input (-1)
+ to: 1
+ window_size: -1
+ - from: 1 # talker β code2wav: trigger only after receiving full input (-1)
+ to: 2
+ window_size: -1
+
+```
+
+## Stage Configuration Arguments
+
+Each stage in the `stage_args` list contains the following configuration options:
+
+### `stage_id`
+
+A unique identifier for each stage in the multi-stage pipeline. Stages are numbered sequentially starting from 0, and this ID is used to reference stages in inter-stage dependencies (e.g., `engine_input_source`).
+
+### `runtime`
+
+Configuration for disaggregated execution of the stage, controlling how the stage is deployed and executed.
+
+#### `runtime.process`
+
+Whether to run this stage in a separate process. When set to `true`, the stage will be executed in an isolated process, enabling better resource isolation and parallel execution across different stages. This is essential for multi-GPU deployments where different stages run on different devices.
+
+Default: `true`
+
+#### `runtime.devices`
+
+Visible devices for this stage, specified as a string. This controls which GPU devices are available to the stage process, similar to setting `CUDA_VISIBLE_DEVICES` or using `torch.cuda.set_device()`. For example, `"0"` uses GPU 0, `"1"` uses GPU 1, and `"0,1"` makes both GPUs 0 and 1 visible.
+
+Default: `"0"`
+
+#### `runtime.max_batch_size`
+
+The maximum batch size for offline inference in this stage. This limits how many sequences can be processed together in a single batch during offline inference operations.
+
+Default: `1`
+
+### `engine_args`
+
+Engine arguments for configuring the LLM engine, diffusion engine, or other engine types used by this stage.
+
+#### `engine_args.model_stage`
+
+The name identifier for this model stage within the multi-stage architecture. This is used internally to distinguish different stages of the same model (e.g., "thinker", "talker", "code2wav" in Qwen2.5-Omni).
+
+#### `engine_args.model_arch`
+
+The model architecture class name that is registered in `model_executor/models/registry.py`. This specifies which model implementation to use for this stage. The class must be registered in the model registry for vLLM-Omni to locate and instantiate it.
+
+#### `engine_args.worker_cls`
+
+The specific worker class to use for this stage. This determines how the model computations are executed. Examples include `vllm_omni.worker.gpu_ar_worker.GPUARWorker` for autoregressive stages and `vllm_omni.worker.gpu_diffusion_worker.GPUDiffusionWorker` for diffusion-based stages.
+
+#### `engine_args.scheduler_cls`
+
+The scheduler class to use for this stage. The scheduler manages request queuing, batching, and execution order. Examples include `vllm_omni.core.sched.scheduler.OmniScheduler` for standard stages and `vllm_omni.core.sched.diffusion_scheduler.DiffusionScheduler` for diffusion stages.
+
+#### `engine_args.gpu_memory_utilization`
+
+The fraction of GPU memory to allocate for this stage within a single GPU chip. This is a value between 0.0 and 1.0, where 0.8 means 80% of the GPU memory will be used by this stage. This allows fine-grained control over memory allocation when multiple stages share the same GPU or when reserving memory for other operations.
+
+Default: `0.8`
+
+#### `engine_args.enforce_eager`
+
+Whether to enforce eager execution mode. When set to `true`, the engine will run in eager mode without using CUDA graphs or other compilation optimizations. Currently, vLLM-Omni only supports eager mode.
+
+Default: `true`
+
+#### `engine_args.trust_remote_code`
+
+Whether to trust remote code when loading models from Hugging Face. This is required for models that use custom code in their configuration files. Set to `true` when loading models that require custom model implementations.
+
+Default: `true`
+
+#### `engine_args.engine_output_type`
+
+Specifies the type of output produced by this stage's engine. This determines what kind of data flows to downstream stages. Possible values include `latent` (hidden states), `text` (tokenized text), and `audio` (audio waveforms). When set to `latent`, the stage outputs latent hidden states in addition to token IDs, which are consumed by downstream stages.
+
+Default: `latent`
+
+#### `engine_args.enable_prefix_caching`
+
+Whether to enable prefix caching for this stage. Prefix caching can improve performance by caching KV cache for common prompt prefixes. However, for requests that output hidden states (when `engine_output_type` is `latent`), prefix caching is not currently supported and should be set to `false`.
+
+Default: `false`
+
+### `is_comprehension`
+
+Whether this stage is a text or multimodal comprehension module. When set to `true`, the stage acts as a comprehension module that processes input text or multimodal content. If this is the first comprehension stage, `AsyncOmniLLM` will use its tokenizer as the default tokenizer for the entire pipeline.
+
+Default: `true`
+
+### `final_output`
+
+Whether this stage produces output that is part of the final outputs returned to the user. When set to `false`, the stage only works as an intermediate stage, processing data that flows to downstream stages but not contributing directly to the final response.
+
+Default: `true`
+
+### `final_output_type`
+
+The type of final output produced by this stage. This specifies what format the output will be in when returned to the user. Currently supported values are `text` (for text generation) and `audio` (for audio generation).
+
+Default: `text`
+
+### `default_sampling_params`
+
+Default sampling parameters for this stage. These parameters control the generation behavior and align with vLLM's sampling parameter semantics. These defaults are used when no explicit sampling parameters are provided in the request.
+
+#### `default_sampling_params.temperature`
+
+Sampling temperature for controlling randomness. Lower values (e.g., 0.0) make the output more deterministic and focused, while higher values increase randomness.
+
+Default: `0.0`
+
+#### `default_sampling_params.top_p`
+
+Nucleus sampling parameter. Only tokens with cumulative probability mass up to `top_p` are considered. This helps filter out low-probability tokens while maintaining diversity.
+
+Default: `1.0`
+
+#### `default_sampling_params.top_k`
+
+Top-k sampling parameter. Only the top `k` most likely tokens are considered. Set to `-1` to disable top-k filtering and consider all tokens.
+
+Default: `-1`
+
+#### `default_sampling_params.max_tokens`
+
+Maximum number of tokens to generate in this stage. This limits the length of the output sequence.
+
+Default: `2048`
+
+#### `default_sampling_params.seed`
+
+Random seed for reproducible generation. When set, the random number generator will be initialized with this seed to ensure consistent outputs across runs.
+
+Default: `42`
+
+#### `default_sampling_params.detokenize`
+
+Whether to detokenize the output tokens into text. When set to `true`, token IDs are converted back to readable text strings.
+
+Default: `True`
+
+#### `default_sampling_params.repetition_penalty`
+
+Penalty applied to tokens that have already appeared in the generated sequence. Values greater than 1.0 discourage repetition, while values less than 1.0 encourage it. A value of 1.0 applies no penalty.
+
+Default: `1.1`
diff --git a/docs/configuration/stage_configs/qwen2_5_omni.yaml b/docs/configuration/stage_configs/qwen2_5_omni.yaml
new file mode 100644
index 000000000..e4f6b8e7b
--- /dev/null
+++ b/docs/configuration/stage_configs/qwen2_5_omni.yaml
@@ -0,0 +1,94 @@
+# stage config for running qwen2.5-omni with architecture of OmniLLM.
+stage_args:
+ - stage_id: 0
+ runtime:
+ process: true # Run this stage in a separate process
+ devices: "0" # Visible devices for this stage (CUDA_VISIBLE_DEVICES/torch.cuda.set_device)
+ max_batch_size: 1
+ engine_args:
+ model_stage: thinker
+ model_arch: Qwen2_5OmniForConditionalGeneration
+ worker_cls: vllm_omni.worker.gpu_ar_worker.GPUARWorker
+ scheduler_cls: vllm_omni.core.sched.scheduler.OmniScheduler
+ gpu_memory_utilization: 0.8
+ enforce_eager: true # Now we only support eager mode
+ trust_remote_code: true
+ engine_output_type: latent
+ enable_prefix_caching: false
+ 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: 2048
+ seed: 42
+ detokenize: True
+ repetition_penalty: 1.1
+ - stage_id: 1
+ runtime:
+ process: true
+ devices: "1"
+ max_batch_size: 3
+ engine_args:
+ model_stage: talker
+ model_arch: Qwen2_5OmniForConditionalGeneration
+ worker_cls: vllm_omni.worker.gpu_ar_worker.GPUARWorker
+ scheduler_cls: vllm_omni.core.sched.scheduler.OmniScheduler
+ gpu_memory_utilization: 0.8
+ 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: 2048
+ seed: 42
+ detokenize: True
+ repetition_penalty: 1.05
+ stop_token_ids: [8294]
+ - stage_id: 2
+ runtime:
+ process: true
+ devices: "0" # Example: use a different GPU than the previous stage; use "0" if single GPU
+ max_batch_size: 1
+ engine_args:
+ model_stage: code2wav
+ model_arch: Qwen2_5OmniForConditionalGeneration
+ worker_cls: vllm_omni.worker.gpu_diffusion_worker.GPUDiffusionWorker
+ scheduler_cls: vllm_omni.core.sched.diffusion_scheduler.DiffusionScheduler
+ gpu_memory_utilization: 0.15
+ enforce_eager: true
+ trust_remote_code: true
+ enable_prefix_caching: false
+ engine_output_type: audio
+ 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: 2048
+ seed: 42
+ detokenize: True
+ repetition_penalty: 1.1
+
+# Top-level runtime config (concise): default windows and stage edges
+runtime:
+ enabled: true
+ defaults:
+ window_size: -1 # Simplified: trigger downstream only after full upstream completion
+ max_inflight: 1 # Simplified: process serially within each stage
+ edges:
+ - from: 0 # thinker β talker: trigger only after receiving full input (-1)
+ to: 1
+ window_size: -1
+ - from: 1 # talker β code2wav: trigger only after receiving full input (-1)
+ to: 2
+ window_size: -1
diff --git a/docs/DOCS_GUIDE.md b/docs/contributing/DOCS_GUIDE.md
similarity index 100%
rename from docs/DOCS_GUIDE.md
rename to docs/contributing/DOCS_GUIDE.md
diff --git a/docs/contributing/README.md b/docs/contributing/README.md
index 43bccdc5b..c27b7f32c 100644
--- a/docs/contributing/README.md
+++ b/docs/contributing/README.md
@@ -4,7 +4,7 @@ Thank you for your interest in contributing to vLLM-omni! This document provides
## Getting Started
-### Development Environment
+### Development Environment for vLLM
vLLM-omni uses `uv` as the environment manager, to create and manage Python environments. Please follow the documentation to install `uv`. After installing `uv`, you can create a new Python environment using the following commands:
@@ -19,8 +19,24 @@ Install vLLM from source:
git clone https://github.com/vllm-project/vllm.git
cd vllm
git checkout v0.11.0
-VLLM_USE_PRECOMPILED=1 uv pip install -e .
```
+Set up environment variables to get pre-built wheels. If there are internet problems, just download the whl file manually. And set VLLM_PRECOMPILED_WHEEL_LOCATION as your local absolute path of whl file.
+```bash
+export VLLM_PRECOMPILED_WHEEL_LOCATION=https://github.com/vllm-project/vllm/releases/download/v0.11.0/vllm-0.11.0-cp38-abi3-manylinux1_x86_64.whl
+```
+Install vllm with command below (If you have no existing PyTorch).
+```bash
+uv pip install --editable .
+```
+
+Install vllm with command below (If you already have PyTorch).
+```bash
+python use_existing_torch.py
+uv pip install -r requirements/build.txt
+uv pip install --no-build-isolation --editable .
+```
+
+### Development Environment for vLLM-Omni
Install vLLM-omni from source:
@@ -49,7 +65,7 @@ vLLM-omni's `pre-commit` hooks will now run automatically every time you commit.
```bash
pre-commit run # runs on staged files
- pre-commit run -a # runs on all files (short for --all-files)
+ pre-commit run --show-diff-on-failure --color=always --all-files # runs on all files (short for --all-files)
```
### Documentation
@@ -163,7 +179,7 @@ The goal of the vLLM-omni team is to be a _transparent reviewing machine_. We wo
## Additional Resources
-- [Design Documents](design_documents/index.md) - Architecture and design documentation
+- [Design Documents](../design/index.md) - Architecture and design documentation
## Thank You
diff --git a/docs/contributing/ci/failures.md b/docs/contributing/ci/failures.md
new file mode 100644
index 000000000..d64d98a60
--- /dev/null
+++ b/docs/contributing/ci/failures.md
@@ -0,0 +1,4 @@
+# CI Failures
+
+What should I do when a CI job fails on my PR, but I don't think my PR caused
+the failure?
diff --git a/docs/contributing/model/README.md b/docs/contributing/model/README.md
new file mode 100644
index 000000000..ac9323cbc
--- /dev/null
+++ b/docs/contributing/model/README.md
@@ -0,0 +1 @@
+# Summary
diff --git a/docs/contributing/design_documents/api_design_doc.md b/docs/design/api_design_doc.md
similarity index 100%
rename from docs/contributing/design_documents/api_design_doc.md
rename to docs/design/api_design_doc.md
diff --git a/docs/contributing/design_documents/api_design_template.md b/docs/design/api_design_template.md
similarity index 100%
rename from docs/contributing/design_documents/api_design_template.md
rename to docs/design/api_design_template.md
diff --git a/docs/contributing/design_documents/architecture_overview.md b/docs/design/architecture_overview.md
similarity index 100%
rename from docs/contributing/design_documents/architecture_overview.md
rename to docs/design/architecture_overview.md
diff --git a/docs/contributing/design_documents/index.md b/docs/design/index.md
similarity index 100%
rename from docs/contributing/design_documents/index.md
rename to docs/design/index.md
diff --git a/docs/mrs_design.md b/docs/design/mrs_design.md
similarity index 100%
rename from docs/mrs_design.md
rename to docs/design/mrs_design.md
diff --git a/docs/contributing/design_documents/vllm_omni_design.md b/docs/design/vllm_omni_design.md
similarity index 100%
rename from docs/contributing/design_documents/vllm_omni_design.md
rename to docs/design/vllm_omni_design.md
diff --git a/docs/examples/README.md b/docs/examples/README.md
new file mode 100644
index 000000000..4594d2bed
--- /dev/null
+++ b/docs/examples/README.md
@@ -0,0 +1,6 @@
+# Examples
+
+vLLM-Omni's examples are split into two categories:
+
+- If you are using vLLM-Omni from within Python code, see the *Offline Inference* section.
+- If you are using vLLM-Omni from an HTTP application or client, see the *Online Serving* section.
diff --git a/docs/features/README.md b/docs/features/README.md
new file mode 100644
index 000000000..c18fb056e
--- /dev/null
+++ b/docs/features/README.md
@@ -0,0 +1,3 @@
+# Features
+
+vLLM-Omni introduces new features to support multimodal comprehension and generation models inference and serving.
diff --git a/docs/getting_started/installation/.nav.yml b/docs/getting_started/installation/.nav.yml
new file mode 100644
index 000000000..0fcee9a00
--- /dev/null
+++ b/docs/getting_started/installation/.nav.yml
@@ -0,0 +1,4 @@
+nav:
+ - README.md
+ - gpu.md
+ - npu.md
diff --git a/docs/getting_started/installation/README.md b/docs/getting_started/installation/README.md
new file mode 100644
index 000000000..17f1b1f5c
--- /dev/null
+++ b/docs/getting_started/installation/README.md
@@ -0,0 +1,7 @@
+# Installation
+
+vLLM supports the following hardware platforms:
+
+- [GPU](gpu.md)
+ - [NVIDIA CUDA](gpu.md#nvidia-cuda)
+- [Ascend NPU](npu.md)
diff --git a/docs/getting_started/installation/gpu.md b/docs/getting_started/installation/gpu.md
new file mode 100644
index 000000000..5b7d080f7
--- /dev/null
+++ b/docs/getting_started/installation/gpu.md
@@ -0,0 +1,49 @@
+# GPU
+
+vLLM-Omni is a Python library that supports the following GPU variants. Select your GPU type to see vendor specific instructions:
+
+[](){ #nvidia-cuda }
+
+=== "NVIDIA CUDA"
+
+ --8<-- "docs/getting_started/installation/gpu/cuda.inc.md:installation"
+
+## Requirements
+
+- OS: Linux
+- Python: 3.12
+
+!!! note
+ vLLM-Omni does not support Windows natively.
+
+=== "NVIDIA CUDA"
+
+ --8<-- "docs/getting_started/installation/gpu/cuda.inc.md:requirements"
+
+## Set up using Python
+
+### Create a new Python environment
+
+--8<-- "docs/getting_started/installation/python_env_setup.inc.md"
+
+=== "NVIDIA CUDA"
+
+ --8<-- "docs/getting_started/installation/gpu/cuda.inc.md:set-up-using-python"
+
+### Pre-built wheels
+
+=== "NVIDIA CUDA"
+
+ --8<-- "docs/getting_started/installation/gpu/cuda.inc.md:pre-built-wheels"
+
+[](){ #build-from-source }
+
+### Build wheel from source
+
+=== "NVIDIA CUDA"
+
+ --8<-- "docs/getting_started/installation/gpu/cuda.inc.md:build-wheel-from-source"
+
+## Set up using Docker
+
+### Pre-built images
diff --git a/docs/getting_started/installation/gpu/cuda.inc.md b/docs/getting_started/installation/gpu/cuda.inc.md
new file mode 100644
index 000000000..59087cee7
--- /dev/null
+++ b/docs/getting_started/installation/gpu/cuda.inc.md
@@ -0,0 +1,73 @@
+# --8<-- [start:installation]
+
+vLLM-Omni mainly contains python implementations for framework and models.
+
+# --8<-- [end:installation]
+# --8<-- [start:requirements]
+
+- GPU: compute capability 7.0 or higher (e.g., V100, T4, RTX20xx, A100, L4, H100, etc.)
+
+# --8<-- [end:requirements]
+# --8<-- [start:set-up-using-python]
+
+vLLM-Omni depends vLLM. So please follow instructions below mainly for vLLM.
+
+!!! note
+ PyTorch installed via `conda` will statically link `NCCL` library, which can cause issues when vLLM tries to use `NCCL`. See for more details.
+
+In order to be performant, vLLM has to compile many cuda kernels. The compilation unfortunately introduces binary incompatibility with other CUDA versions and PyTorch versions, even for the same PyTorch version with different building configurations.
+
+Therefore, it is recommended to install vLLM and vLLM-Omni with a **fresh new** environment. If either you have a different CUDA version or you want to use an existing PyTorch installation, you need to build vLLM from source. See [build-from-source-vllm](https://docs.vllm.ai/en/stable/getting_started/installation/gpu/#build-wheel-from-source) for more details.
+
+# --8<-- [start:pre-built-wheels]
+
+## Installation of vLLM
+
+Now we build it based on vLLM v0.11.0. Please install it with command below.
+```bash
+uv pip install vllm==0.11.0 --torch-backend=auto
+```
+
+## Installation of vLLM-Omni
+
+```bash
+uv pip install vllm-omni
+```
+
+# --8<-- [end:pre-built-wheels]
+
+# --8<-- [start:build-wheel-from-source]
+
+## Installation of vLLM
+If you want to check or debug with source code of vLLM, install stable release version of vllm with 0.11.0 from source with pre-built wheel file.
+
+```bash
+git clone https://github.com/vllm-project/vllm.git
+cd vllm
+git checkout v0.11.0
+```
+Set up environment variables to get pre-built wheels. If there are internet problems, just download the whl file manually. And set VLLM_PRECOMPILED_WHEEL_LOCATION as your local absolute path of whl file.
+```bash
+export VLLM_PRECOMPILED_WHEEL_LOCATION=https://github.com/vllm-project/vllm/releases/download/v0.11.0/vllm-0.11.0-cp38-abi3-manylinux1_x86_64.whl
+```
+Install vllm with command below (If you have no existing PyTorch).
+```bash
+uv pip install --editable .
+```
+
+Install vllm with command below (If you already have PyTorch).
+```bash
+python use_existing_torch.py
+uv pip install -r requirements/build.txt
+uv pip install --no-build-isolation --editable .
+```
+
+## Installation of vLLM-omni
+Install additional requirements for vllm-omni
+```bash
+git clone https://github.com/vllm-project/vllm-omni.git
+cd vllm_omni
+uv pip install -e .
+```
+
+# --8<-- [end:build-wheel-from-source]
diff --git a/docs/getting_started/installation/npu.md b/docs/getting_started/installation/npu.md
new file mode 100644
index 000000000..d341c1504
--- /dev/null
+++ b/docs/getting_started/installation/npu.md
@@ -0,0 +1,3 @@
+# Ascend-NPU
+
+vLLM-Omni is a Python library that supports the following NPU variants. Select your NPU type to see vendor specific instructions:
diff --git a/docs/getting_started/installation/npu/npu.inc.md b/docs/getting_started/installation/npu/npu.inc.md
new file mode 100644
index 000000000..c20460ed9
--- /dev/null
+++ b/docs/getting_started/installation/npu/npu.inc.md
@@ -0,0 +1,5 @@
+# --8<-- [start:installation]
+
+vLLM-Omni mainly contains python implementations for framework and models.
+
+# --8<-- [end:installation]
diff --git a/docs/getting_started/installation/python_env_setup.inc.md b/docs/getting_started/installation/python_env_setup.inc.md
new file mode 100644
index 000000000..06794f8d3
--- /dev/null
+++ b/docs/getting_started/installation/python_env_setup.inc.md
@@ -0,0 +1,6 @@
+It's recommended to use [uv](https://docs.astral.sh/uv/), a very fast Python environment manager, to create and manage Python environments. Please follow the [documentation](https://docs.astral.sh/uv/#getting-started) to install `uv`. After installing `uv`, you can create a new Python environment using the following commands:
+
+```bash
+uv venv --python 3.12 --seed
+source .venv/bin/activate
+```
diff --git a/docs/getting_started/quickstart.md b/docs/getting_started/quickstart.md
new file mode 100644
index 000000000..c8fdf7665
--- /dev/null
+++ b/docs/getting_started/quickstart.md
@@ -0,0 +1,23 @@
+# Quickstart
+
+This guide will help you quickly get started with vLLM-Omni to perform:
+
+- Offline batched inference
+- Online serving using OpenAI-compatible server
+
+## Prerequisites
+
+- OS: Linux
+- Python: 3.12
+
+## Installation
+
+Please refer to [installation](installation/README.md)
+
+## Offline Inference
+
+Please refer to [offline inference](../user_guide/examples/offline_inference/qwen2_5_omni.md)
+
+## Online Serving with OpenAI-Completions API
+
+Please refer to [online serving](../user_guide/examples/online_serving/README.md)
diff --git a/docs/index.md b/docs/index.md
deleted file mode 100644
index 0db4f2908..000000000
--- a/docs/index.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# Welcome to vLLM-omni
-
-**vLLM-omni** extends vLLM capabilities to support multi-modality model inference and serving, particularly focusing on non-autoregressive structures and non-textual outputs. It aims to support:
-
-- **Multi-modal Models**: Text, image, video, audio, and sensor data processing
-- **Non-autoregressive Architectures**: Diffusion Transformers (DiT) and other parallel generation models
-- **Heterogeneous Outputs**: Beyond traditional text generation to multimodal outputs
-
-## π― Key Features
-
-### Multi-Engine Support
-
-- **Autoregressive Engine**: Traditional text generation with enhanced KV-caching
-- **Diffusion Engine**: Support for DiT models and iterative generation
-- **Hybrid Engine**: Combined AR+DiT processing pipelines
-
-### Modality Processing
-
-- **Text**: Advanced tokenization and embedding generation
-- **Image**: Vision encoder integration (CLIP, etc.)
-- **Audio**: Speech processing and audio embedding
-
-## π€ Supported Models
-
-- Qwen-omni (Thinker-Talker-Codec structure)
-- HunyunaImage 3.0 (Ongoing)
-- Qwen-Image (Ongoing)
-
-## π Documentation Navigation
-
-- To run open-source models on vLLM-Omni, we recommend starting with the [:material-code-tags: User Quide](user_guide/getting_started/quickstart.md)
-- To develop and contribute to vLLM-Omni, we recommend starting with the [:material-tools: Developer Guide](contributing/README.md)
diff --git a/docs/mkdocs/hooks/generate_api_readme.py b/docs/mkdocs/hooks/generate_api_readme.py
new file mode 100644
index 000000000..f1819cfc8
--- /dev/null
+++ b/docs/mkdocs/hooks/generate_api_readme.py
@@ -0,0 +1,268 @@
+# SPDX-License-Identifier: Apache-2.0
+# SPDX-FileCopyrightText: Copyright contributors to the vLLM-omni project
+"""
+Hook to automatically generate docs/api/README.md from the codebase.
+
+This script scans the vllm_omni module for public classes and functions,
+categorizes them, and generates a summary README file.
+"""
+
+import ast
+import logging
+from pathlib import Path
+
+logger = logging.getLogger("mkdocs")
+
+ROOT_DIR = Path(__file__).parent.parent.parent.parent
+API_README_PATH = ROOT_DIR / "docs" / "api" / "README.md"
+
+# Category mappings: module prefix -> category name and description
+CATEGORIES = {
+ "entrypoints": {
+ "name": "Entry Points",
+ "description": "Main entry points for vLLM-omni inference and serving.",
+ },
+ "inputs": {
+ "name": "Inputs",
+ "description": "Input data structures for multi-modal inputs.",
+ },
+ "engine": {
+ "name": "Engine",
+ "description": "Engine classes for offline and online inference.",
+ },
+ "core": {
+ "name": "Core",
+ "description": "Core scheduling and caching components.",
+ },
+ "model_executor": {
+ "name": "Model Executor",
+ "description": "Model execution components.",
+ },
+ "config": {
+ "name": "Configuration",
+ "description": "Configuration classes.",
+ },
+ "worker": {
+ "name": "Workers",
+ "description": "Worker classes and model runners for distributed inference.",
+ },
+}
+
+
+class APIVisitor(ast.NodeVisitor):
+ """AST visitor to extract public classes and module-level functions."""
+
+ def __init__(self, module_path: str):
+ self.module_path = module_path
+ self.classes: list[str] = []
+ self.functions: list[str] = []
+ self._class_stack: list[str] = [] # Track nested class definitions
+
+ def visit_ClassDef(self, node: ast.ClassDef) -> None:
+ """Visit class definitions."""
+ if not node.name.startswith("_"):
+ self.classes.append(f"{self.module_path}.{node.name}")
+ # Track that we're entering a class
+ self._class_stack.append(node.name)
+ self.generic_visit(node)
+ # Remove from stack when done visiting
+ self._class_stack.pop()
+
+ def visit_FunctionDef(self, node: ast.FunctionDef) -> None:
+ """Visit function definitions - only collect module-level functions."""
+ # Only collect if we're not inside a class (stack is empty)
+ if not self._class_stack and not node.name.startswith("_"):
+ self.functions.append(f"{self.module_path}.{node.name}")
+ self.generic_visit(node)
+
+ def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> None:
+ """Visit async function definitions - only collect module-level functions."""
+ # Only collect if we're not inside a class (stack is empty)
+ if not self._class_stack and not node.name.startswith("_"):
+ self.functions.append(f"{self.module_path}.{node.name}")
+ self.generic_visit(node)
+
+
+def parse_file_for_symbols(file_path: Path, module_path: str) -> tuple[list[str], list[str]]:
+ """
+ Parse a Python file and extract public classes and functions.
+
+ Returns:
+ Tuple of (classes, functions)
+ """
+ try:
+ # If this is __init__.py, use parent module path
+ if file_path.name == "__init__.py":
+ # Remove .__init__ from module path
+ if module_path.endswith(".__init__"):
+ module_path = module_path[:-9]
+
+ with open(file_path, encoding="utf-8") as f:
+ content = f.read()
+
+ tree = ast.parse(content, filename=str(file_path))
+ visitor = APIVisitor(module_path)
+ visitor.visit(tree)
+
+ return visitor.classes, visitor.functions
+ except Exception as e:
+ logger.debug(f"Could not parse {file_path}: {e}")
+ return [], []
+
+
+def scan_package(package_name: str = "vllm_omni") -> dict[str, list[str]]:
+ """
+ Scan the vllm_omni package and categorize public symbols.
+
+ Returns:
+ Dict mapping category names to lists of symbol full names
+ """
+ categorized: dict[str, list[str]] = {cat["name"]: [] for cat in CATEGORIES.values()}
+
+ try:
+ # Find the package directory
+ package_path = ROOT_DIR / package_name
+ if not package_path.exists():
+ logger.warning(f"Package path not found: {package_path}")
+ return categorized
+
+ # Walk through all Python files
+ for py_file in package_path.rglob("*.py"):
+ # Skip __init__.py and private modules
+ if py_file.name.startswith("_") and py_file.name != "__init__.py":
+ continue
+
+ # Get module path
+ relative_path = py_file.relative_to(ROOT_DIR)
+ module_path = str(relative_path.with_suffix("")).replace("/", ".").replace("\\", ".")
+
+ # Handle __init__.py - use parent module path
+ if py_file.name == "__init__.py":
+ # Remove .__init__ from module path
+ if module_path.endswith(".__init__"):
+ module_path = module_path[:-9]
+
+ # Determine category from module path
+ category = None
+ for prefix, cat_info in CATEGORIES.items():
+ if prefix in module_path:
+ category = cat_info["name"]
+ break
+
+ if not category:
+ continue
+
+ # Parse file for symbols
+ classes, functions = parse_file_for_symbols(py_file, module_path)
+
+ # Filter out internal implementation classes
+ # Skip classes that look like internal components (DiT layers, etc.)
+ internal_patterns = [
+ "Block",
+ "Layer",
+ "Net",
+ "Embedding",
+ "Norm",
+ "Activation",
+ "Solver",
+ "Pooling",
+ "Attention",
+ "MLP",
+ "DecoderLayer",
+ "InputEmbedding",
+ "TimestepEmbedding",
+ "CodecEmbedding",
+ "DownSample",
+ "UpSample",
+ "Res2Net",
+ "SqueezeExcitation",
+ "TimeDelay",
+ "TorchActivation",
+ "SnakeBeta",
+ "SinusPosition",
+ "RungeKutta",
+ "AMPBlock",
+ "AdaLayerNorm",
+ ]
+
+ # Add classes (filter out internal ones)
+ for class_name in classes:
+ class_short_name = class_name.split(".")[-1]
+ # Skip if it matches internal patterns (unless it's a main model class)
+ if any(pattern in class_short_name for pattern in internal_patterns):
+ # But include main model classes
+ if not any(
+ main_class in class_short_name
+ for main_class in [
+ "ForConditionalGeneration",
+ "Model",
+ "Registry",
+ "Worker",
+ "Runner",
+ "Scheduler",
+ "Manager",
+ "Processor",
+ "Config",
+ ]
+ ):
+ continue
+ categorized[category].append(class_name)
+
+ # Add important functions (parse, preprocess, etc.)
+ for func_name in functions:
+ # Include functions that match certain patterns
+ if any(keyword in func_name.lower() for keyword in ["parse", "preprocess"]):
+ categorized[category].append(func_name)
+
+ # Sort symbols within each category
+ for category in categorized:
+ categorized[category].sort()
+
+ except Exception as e:
+ logger.error(f"Error scanning package: {e}", exc_info=True)
+
+ return categorized
+
+
+def generate_readme(categorized: dict[str, list[str]]) -> str:
+ """Generate the API README markdown content."""
+ lines = ["# Summary", ""]
+
+ # Generate sections for each category
+ for prefix, cat_info in CATEGORIES.items():
+ category_name = cat_info["name"]
+ description = cat_info["description"]
+ symbols = categorized.get(category_name, [])
+
+ if not symbols:
+ continue
+
+ lines.append(f"## {category_name}")
+ lines.append("")
+ lines.append(description)
+ lines.append("")
+
+ for symbol in symbols:
+ lines.append(f"- [{symbol}][]")
+
+ lines.append("")
+
+ return "\n".join(lines)
+
+
+def on_startup(command, dirty: bool):
+ """MkDocs hook entry point."""
+ logger.info("Generating API README documentation")
+
+ # Scan the package
+ categorized = scan_package()
+
+ # Generate README content
+ content = generate_readme(categorized)
+
+ # Write to file
+ API_README_PATH.parent.mkdir(parents=True, exist_ok=True)
+ with open(API_README_PATH, "w", encoding="utf-8") as f:
+ f.write(content)
+
+ logger.info(f"API README generated: {API_README_PATH.relative_to(ROOT_DIR)}")
diff --git a/docs/mkdocs/hooks/url_schemes.py b/docs/mkdocs/hooks/url_schemes.py
new file mode 100644
index 000000000..8798b11db
--- /dev/null
+++ b/docs/mkdocs/hooks/url_schemes.py
@@ -0,0 +1,121 @@
+# SPDX-License-Identifier: Apache-2.0
+# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
+"""
+This is basically a port of MyST parserβs external URL resolution mechanism
+(https://myst-parser.readthedocs.io/en/latest/syntax/cross-referencing.html#customising-external-url-resolution)
+to work with MkDocs.
+
+It allows Markdown authors to use GitHub shorthand links like:
+
+ - [Text](gh-issue:123)
+ -
+ - [File](gh-file:path/to/file.py#L10)
+
+These are automatically rewritten into fully qualified GitHub URLs pointing to
+issues, pull requests, files, directories, or projects in the
+`vllm-project/vllm-omni` repository.
+
+The goal is to simplify cross-referencing common GitHub resources
+in project docs.
+"""
+
+import regex as re
+from mkdocs.config.defaults import MkDocsConfig
+from mkdocs.structure.files import Files
+from mkdocs.structure.pages import Page
+
+
+def on_page_markdown(markdown: str, *, page: Page, config: MkDocsConfig, files: Files) -> str:
+ """
+ Custom MkDocs plugin hook to rewrite special GitHub reference links
+ in Markdown.
+
+ This function scans the given Markdown content for specially formatted
+ GitHub shorthand links, such as:
+ - `[Link text](gh-issue:123)`
+ - ``
+
+ And rewrites them into fully-qualified GitHub URLs with GitHub icons:
+ - `[:octicons-mark-github-16: Link text](https://github.com/vllm-project/vllm/issues/123)`
+ - `[:octicons-mark-github-16: Pull Request #456](https://github.com/vllm-project/vllm/pull/456)`
+
+ Supported shorthand types:
+ - `gh-issue`
+ - `gh-pr`
+ - `gh-project`
+ - `gh-dir`
+ - `gh-file`
+
+ Args:
+ markdown (str): The raw Markdown content of the page.
+ page (Page): The MkDocs page object being processed.
+ config (MkDocsConfig): The MkDocs site configuration.
+ files (Files): The collection of files in the MkDocs build.
+
+ Returns:
+ str: The updated Markdown content with GitHub shorthand links replaced.
+ """
+ gh_icon = ":octicons-mark-github-16:"
+ gh_url = "https://github.com"
+ repo_url = f"{gh_url}/vllm-project/vllm-omni"
+ org_url = f"{gh_url}/orgs/vllm-project"
+
+ # Mapping of shorthand types to their corresponding GitHub base URLs
+ urls = {
+ "issue": f"{repo_url}/issues",
+ "pr": f"{repo_url}/pull",
+ "project": f"{org_url}/projects",
+ "dir": f"{repo_url}/tree/main",
+ "file": f"{repo_url}/blob/main",
+ }
+
+ # Default title prefixes for auto links
+ titles = {
+ "issue": "Issue #",
+ "pr": "Pull Request #",
+ "project": "Project #",
+ "dir": "",
+ "file": "",
+ }
+
+ # Regular expression to match GitHub shorthand links
+ scheme = r"gh-(?P.+?):(?P.+?)(#(?P.+?))?"
+ inline_link = re.compile(r"\[(?P[^\[]+?)\]\(" + scheme + r"\)")
+ auto_link = re.compile(f"<{scheme}>")
+
+ def replace_inline_link(match: re.Match) -> str:
+ """
+ Replaces a matched inline-style GitHub shorthand link
+ with a full Markdown link.
+
+ Example:
+ [My issue](gh-issue:123) β [:octicons-mark-github-16: My issue](https://github.com/vllm-project/vllm/issues/123)
+ """
+ url = f"{urls[match.group('type')]}/{match.group('path')}"
+ if fragment := match.group("fragment"):
+ url += f"#{fragment}"
+
+ return f"[{gh_icon} {match.group('title')}]({url})"
+
+ def replace_auto_link(match: re.Match) -> str:
+ """
+ Replaces a matched autolink-style GitHub shorthand
+ with a full Markdown link.
+
+ Example:
+ β [:octicons-mark-github-16: Pull Request #456](https://github.com/vllm-project/vllm/pull/456)
+ """
+ type = match.group("type")
+ path = match.group("path")
+ title = f"{titles[type]}{path}"
+ url = f"{urls[type]}/{path}"
+ if fragment := match.group("fragment"):
+ url += f"#{fragment}"
+
+ return f"[{gh_icon} {title}]({url})"
+
+ # Replace both inline and autolinks
+ markdown = inline_link.sub(replace_inline_link, markdown)
+ markdown = auto_link.sub(replace_auto_link, markdown)
+
+ return markdown
diff --git a/docs/mkdocs/javascript/edit_and_feedback.js b/docs/mkdocs/javascript/edit_and_feedback.js
new file mode 100644
index 000000000..0acbcfd96
--- /dev/null
+++ b/docs/mkdocs/javascript/edit_and_feedback.js
@@ -0,0 +1,47 @@
+/**
+ * edit_and_feedback.js
+ *
+ * Enhances MkDocs Material docs pages by:
+ *
+ * 1. Adding a "Question? Give us feedback" link
+ * below the "Edit" button.
+ *
+ * - The link opens a GitHub issue with a template,
+ * auto-filled with the current page URL and path.
+ *
+ * 2. Ensuring the edit button opens in a new tab
+ * with target="_blank" and rel="noopener".
+ */
+document.addEventListener("DOMContentLoaded", function () {
+ const url = window.location.href;
+ const page = document.body.dataset.mdUrl || location.pathname;
+
+ const feedbackLink = document.createElement("a");
+ feedbackLink.href = `https://github.com/vllm-project/vllm-omni/issues/new?template=100-documentation.yml&title=${encodeURIComponent(
+ `[Docs] Feedback for \`${page}\``
+ )}&body=${encodeURIComponent(`π **Reference:**\n${url}\n\nπ **Feedback:**\n_Your response_`)}`;
+ feedbackLink.target = "_blank";
+ feedbackLink.rel = "noopener";
+ feedbackLink.title = "Provide feedback";
+ feedbackLink.className = "md-content__button";
+ feedbackLink.innerHTML = `
+
+ `;
+
+ const editButton = document.querySelector('.md-content__button[href*="edit"]');
+
+ if (editButton && editButton.parentNode) {
+ editButton.insertAdjacentElement("beforebegin", feedbackLink);
+
+ editButton.setAttribute("target", "_blank");
+ editButton.setAttribute("rel", "noopener");
+ }
+ });
diff --git a/docs/mkdocs/javascript/mathjax.js b/docs/mkdocs/javascript/mathjax.js
new file mode 100644
index 000000000..eb89ace06
--- /dev/null
+++ b/docs/mkdocs/javascript/mathjax.js
@@ -0,0 +1,20 @@
+// Enables MathJax rendering
+window.MathJax = {
+ tex: {
+ inlineMath: [["\\(", "\\)"]],
+ displayMath: [["\\[", "\\]"]],
+ processEscapes: true,
+ processEnvironments: true
+ },
+ options: {
+ ignoreHtmlClass: ".*|",
+ processHtmlClass: "arithmatex"
+ }
+ };
+
+ document$.subscribe(() => {
+ MathJax.startup.output.clearCache()
+ MathJax.typesetClear()
+ MathJax.texReset()
+ MathJax.typesetPromise()
+ })
diff --git a/docs/mkdocs/javascript/slack_and_forum.js b/docs/mkdocs/javascript/slack_and_forum.js
new file mode 100644
index 000000000..320e44910
--- /dev/null
+++ b/docs/mkdocs/javascript/slack_and_forum.js
@@ -0,0 +1,56 @@
+/**
+ * slack_and_forum.js
+ *
+ * Adds a custom Slack and Forum button to the MkDocs Material header.
+ *
+ */
+
+window.addEventListener('DOMContentLoaded', () => {
+ const headerInner = document.querySelector('.md-header__inner');
+
+ if (headerInner) {
+ const slackButton = document.createElement('button');
+ slackButton.className = 'slack-button';
+ slackButton.title = 'Join us on Slack';
+ slackButton.style.border = 'none';
+ slackButton.style.background = 'transparent';
+ slackButton.style.cursor = 'pointer';
+
+ slackButton.innerHTML = `
+
+ `;
+
+ slackButton.addEventListener('click', () => {
+ window.open('https://slack.vllm.ai', '_blank', 'noopener');
+ });
+
+ const forumButton = document.createElement('button');
+ forumButton.className = 'forum-button';
+ forumButton.title = 'Join the Forum';
+ forumButton.style.border = 'none';
+ forumButton.style.background = 'transparent';
+ forumButton.style.cursor = 'pointer';
+
+ forumButton.innerHTML = `
+
+ `;
+
+ forumButton.addEventListener('click', () => {
+ window.open('https://discuss.vllm.ai/', '_blank', 'noopener');
+ });
+
+ const githubSource = document.querySelector('.md-header__source');
+ if (githubSource) {
+ githubSource.parentNode.insertBefore(slackButton, githubSource.nextSibling);
+ githubSource.parentNode.insertBefore(forumButton, slackButton.nextSibling);
+ }
+ }
+ });
diff --git a/docs/mkdocs/overrides/main.html b/docs/mkdocs/overrides/main.html
new file mode 100644
index 000000000..94d9808cc
--- /dev/null
+++ b/docs/mkdocs/overrides/main.html
@@ -0,0 +1 @@
+{% extends "base.html" %}
diff --git a/docs/mkdocs/overrides/partials/toc-item.html b/docs/mkdocs/overrides/partials/toc-item.html
new file mode 100644
index 000000000..656c21589
--- /dev/null
+++ b/docs/mkdocs/overrides/partials/toc-item.html
@@ -0,0 +1,21 @@
+
+