-
Notifications
You must be signed in to change notification settings - Fork 79
Enable exact-batch CUDA Graph for strict rollout #367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c57a8ae
8e32313
9b95e34
0aa1d63
afccecc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,7 +12,11 @@ | |
|
|
||
| import torch | ||
|
|
||
| from rl_engine.distributed.collectives import DETERMINISTIC_ALL_REDUCE_OP | ||
| from rl_engine.distributed.collectives import ( | ||
| DETERMINISTIC_ALL_REDUCE_OP, | ||
| collective_for_group, | ||
| deterministic_all_reduce_inplace, | ||
| ) | ||
| from rl_engine.integrations.ablation import ( | ||
| Implementation, | ||
| IntegrationPlan, | ||
|
|
@@ -40,6 +44,8 @@ | |
| _STRICT_RMS_NORM_INIT_MARKER = "__rl_kernel_original_strict_rms_norm_init__" | ||
| _STRICT_ROTARY_INIT_MARKER = "__rl_kernel_original_strict_rotary_init__" | ||
| _STRICT_LM_HEAD_LINEAR_PATCH_MARKER = "__rl_kernel_original_lm_head_linear_apply__" | ||
| _STRICT_O_PROJ_COLLECTIVE_MARKER = "__rl_kernel_o_proj_collective__" | ||
| _STRICT_ROW_PARALLEL_PATCH_MARKER = "__rl_kernel_original_row_parallel_forward__" | ||
| _RLK_ATTENTION_BACKEND: type[Any] | None = None | ||
| _RLK_ATTENTION_IMPL: type[Any] | None = None | ||
| _RLK_ATTENTION_BUILDER: type[Any] | None = None | ||
|
|
@@ -367,21 +373,23 @@ def _patch_qwen3_strict_model( | |
| rotary_cls: type[Any] | None = None, | ||
| linear_method_cls: type[Any] | None = None, | ||
| attention_cls: type[Any] | None = None, | ||
| row_parallel_cls: type[Any] | None = None, | ||
| det_gemm: Any | None = None, | ||
| ) -> None: | ||
| """Align vLLM's RMSNorm and Attention projections with Megatron.""" | ||
|
|
||
| production_classes = rms_norm_cls is None or linear_method_cls is None or attention_cls is None | ||
| if production_classes: | ||
| from vllm.model_executor.layers.layernorm import RMSNorm | ||
| from vllm.model_executor.layers.linear import UnquantizedLinearMethod | ||
| from vllm.model_executor.layers.linear import RowParallelLinear, UnquantizedLinearMethod | ||
| from vllm.model_executor.layers.rotary_embedding import RotaryEmbedding | ||
| from vllm.model_executor.models.qwen3 import Qwen3Attention | ||
|
|
||
| rms_norm_cls = RMSNorm | ||
| rotary_cls = RotaryEmbedding | ||
| linear_method_cls = UnquantizedLinearMethod | ||
| attention_cls = Qwen3Attention | ||
| row_parallel_cls = RowParallelLinear | ||
| assert rms_norm_cls is not None | ||
| assert linear_method_cls is not None | ||
| assert attention_cls is not None | ||
|
|
@@ -435,6 +443,62 @@ def strict_rms_norm_forward_cuda( | |
| eps=instance.variance_epsilon, | ||
| ) | ||
|
|
||
| def bind_o_proj_collective(module: Any) -> None: | ||
| if int(getattr(module, "tp_size", 1)) <= 1: | ||
| return | ||
| from vllm.distributed.parallel_state import get_tp_group | ||
|
|
||
| coordinator = get_tp_group() | ||
| group = getattr(coordinator, "device_group", coordinator) | ||
| collective = collective_for_group(group) | ||
| if collective is None: | ||
| raise RuntimeError("strict rollout o_proj requires an initialized TP process group") | ||
| setattr(module, _STRICT_O_PROJ_COLLECTIVE_MARKER, collective) | ||
|
|
||
| if row_parallel_cls is not None and not hasattr( | ||
| row_parallel_cls, _STRICT_ROW_PARALLEL_PATCH_MARKER | ||
| ): | ||
| row_parallel_forward = row_parallel_cls.forward | ||
|
|
||
| def strict_row_parallel_forward(instance: Any, input_: torch.Tensor) -> Any: | ||
| collective = getattr(instance, _STRICT_O_PROJ_COLLECTIVE_MARKER, None) | ||
| if collective is None: | ||
| return row_parallel_forward(instance, input_) | ||
|
|
||
| if instance.input_is_parallel: | ||
| input_parallel = input_ | ||
| else: | ||
| from vllm.distributed import split_tensor_along_last_dim | ||
|
|
||
| input_parallel = split_tensor_along_last_dim( | ||
| input_, num_partitions=instance.tp_size | ||
| )[instance.tp_rank].contiguous() | ||
|
|
||
| assert instance.quant_method is not None | ||
| bias_ = ( | ||
| None | ||
| if (instance.tp_rank > 0 or instance.skip_bias_add) | ||
| else instance.bias | ||
| ) | ||
| output_parallel = instance.quant_method.apply(instance, input_parallel, bias_) | ||
|
|
||
| if instance.reduce_results and instance.tp_size > 1: | ||
| deterministic_all_reduce_inplace( | ||
| output_parallel, | ||
| collective_handle=int(collective._handle), | ||
| ) | ||
| output = output_parallel | ||
| else: | ||
| output = output_parallel | ||
|
|
||
| if not instance.return_bias: | ||
| return output | ||
|
Comment on lines
+494
to
+495
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -euo pipefail
# Confirm the repository declares vLLM 0.6.0.
rg -n --glob 'pyproject.toml' --glob 'requirements*.txt' --glob '*lock*' \
'vllm([<>=!~ ]|$)'
# Inspect the upstream vLLM 0.6.0 RowParallelLinear ABI.
curl -fsSL \
https://raw.githubusercontent.com/vllm-project/vllm/v0.6.0/vllm/model_executor/layers/linear.py \
| sed -n '936,965p'Repository: RL-Align/RL-Kernel Length of output: 156 🏁 Script executed: #!/bin/bash
set -u
printf '%s\n' '--- changed hunk ---'
sed -n '430,510p' rl_engine/integrations/vllm_runtime.py
printf '%s\n' '--- vLLM references and dependency declarations ---'
rg -n -i --glob 'pyproject.toml' --glob 'requirements*.txt' --glob '*lock*' 'vllm' . || true
printf '%s\n' '--- local RowParallelLinear bindings/callers ---'
rg -n -C 4 'RowParallelLinear|return_bias|bind_o_proj_collective|o_proj' rl_engine/integrations/vllm_runtime.py
printf '%s\n' '--- upstream vLLM 0.6.0 source ---'
curl -fsSL https://raw.githubusercontent.com/vllm-project/vllm/v0.6.0/vllm/model_executor/layers/linear.py \
| rg -n -A 35 -B 12 'class RowParallelLinear|def forward' | head -160Repository: RL-Align/RL-Kernel Length of output: 13965 🏁 Script executed: #!/bin/bash
set -u
printf '%s\n' '--- vLLM 0.6.0 RowParallelLinear implementation ---'
curl -fsSL https://raw.githubusercontent.com/vllm-project/vllm/v0.6.0/vllm/model_executor/layers/linear.py \
| sed -n '926,1035p'
printf '%s\n' '--- project dependency context ---'
sed -n '1,40p' pyproject.toml
printf '%s\n' '--- consumers of the patched forward result ---'
rg -n -C 6 'o_proj\(|qkv_proj\(|return .*bias|skip_bias_add' rl_engine/integrations/vllm_runtime.pyRepository: RL-Align/RL-Kernel Length of output: 8867 🏁 Script executed: #!/bin/bash
set -u
curl -fsSL https://raw.githubusercontent.com/vllm-project/vllm/v0.6.0/vllm/model_executor/layers/linear.py \
| sed -n '1030,1095p'Repository: RL-Align/RL-Kernel Length of output: 2011 Match the vLLM 0.6.0 return contract. The declared minimum is 🤖 Prompt for AI Agents |
||
| output_bias = instance.bias if instance.skip_bias_add else None | ||
| return output, output_bias | ||
|
|
||
| setattr(row_parallel_cls, _STRICT_ROW_PARALLEL_PATCH_MARKER, row_parallel_forward) | ||
| row_parallel_cls.forward = strict_row_parallel_forward | ||
|
|
||
| if not hasattr(rms_norm_cls, _STRICT_RMS_NORM_INIT_MARKER): | ||
| rms_norm_init = rms_norm_cls.__init__ | ||
|
|
||
|
|
@@ -463,6 +527,7 @@ def attention_init_wrapped(instance: Any, *args: Any, **kwargs: Any) -> None: | |
| attention_init(instance, *args, **kwargs) | ||
| setattr(instance.qkv_proj, _STRICT_PROJECTION_MARKER, "qkv") | ||
| setattr(instance.o_proj, _STRICT_PROJECTION_MARKER, "o_proj") | ||
| bind_o_proj_collective(instance.o_proj) | ||
|
|
||
| setattr(attention_cls, _STRICT_MODEL_PATCH_MARKER, attention_init) | ||
| linear_method_cls.apply = deterministic_linear_apply | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Validate
attention_headsbefore derivinghead_dim.If args provide neither
num_attention_headsnorkv_channels, Line 316 divides by zero before the guard at lines 318-326 runs. This terminates CUDA worker initialization instead of skipping precompilation.Proposed fix
attention_heads = int(getattr(args, "num_attention_heads", 0) or 0) query_groups = int(getattr(args, "num_query_groups", 0) or attention_heads) tp_size = int(getattr(args, "tensor_model_parallel_size", 1) or 1) + if attention_heads <= 0 or query_groups <= 0 or tp_size <= 0: + return head_dim = int( getattr(args, "kv_channels", 0) or (int(getattr(args, "hidden_size", 0) or 0) // attention_heads) ) if ( - attention_heads <= 0 - or query_groups <= 0 - or tp_size <= 0 - or attention_heads % tp_size + attention_heads % tp_size or query_groups % tp_size or head_dim <= 0 ):📝 Committable suggestion
🤖 Prompt for AI Agents