Repository navigation
[Kernels] Native CUDA SiLU-and-Mul with unified dispatch and automatic builds - #160
Merged
Merged
Conversation
bjf-frz
marked this pull request as ready for review
October 31, 2026 09:43
kunkunblueberry
added a commit
to kunkunblueberry/vllm-rlt
that referenced
this pull request
Oct 31, 2026
Brings in InferMatrixLab#159 (scheduler wavefront selection / prefill progress) and InferMatrixLab#160 (native CUDA SiLU-and-Mul) so the branch is measured against current main.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Required human contributor answers
These record the author's stated development requirements, summarized from the author-directed implementation work.
1. What outcome are you trying to achieve?
Add the first native CUDA SiLU-and-Mul implementation and a complete, reusable structure for developing further CUDA operators in vllm-rlt, including build, tests, comparisons, and model integration.
2. What is the highest-leverage variable for that outcome?
Activation memory movement, kernel launches, and efficient parallel computation, while preserving the existing numerical contract.
3. How will this work move that variable rather than create busywork?
Fuse SiLU and multiplication, vectorize the aligned body while handling the scalar tail in the same kernel, and use packed FP16/BF16 multiplication. Verify numerical behavior and measure against Torch, vLLM, and real-model inference rather than relying on intermediate metrics.
4. Who is the customer or user, and what do they actually need?
The author is developing native CUDA operators from vllm-rlt and needs a complete implementation/build/validation path that also supports adding more operators later.
PR necessity and bugfix evidence
Yes: the author requested a PR for the completed first operator and framework. This requires repository changes to native compilation, operator registration, and the Ouro MLP call site.
A separate prerequisite commit fixes an observed benchmark import failure with the configured
lm-eval==0.4.9.2and existing Transformers 5.14.1. On clean base9ad03fce,pytest tests/test_gsm8k_accuracy.py::test_run_refuses_the_stored_baseline_at_another_depthfails withAttributeError: module transformers has no attribute AutoModelForVision2Seq: importing stopping helpers initializes lm-eval's unrelated model registry. The fix loads the installed standalone helper module without that registry, retaining the harness's exact stopping/postprocessing functions, and performs protocol validation before loading generation backends. A fresh-process regression checks this import path. No package pins or stored accuracy baseline are changed; this does not qualify the official HF release model's full generation path on Transformers 5.Purpose
Ouro's CUDA MLP replaces separate SiLU and multiplication with one native operator on its separate gate/up projection outputs. Model code is simply:
Test Plan
vllm-rlt Version / Commit: base
9ad03fce4aa92839a5fcc9a5bf4ae7f9c36d101d; tested working-tree contents match this PR's commit trees.pre-commit run --all-files: Ruff lint/format and full CPU regression suite passed after the import fix. GPU skips in this hook are not GPU verification.pytest tests/test_activation.py tests/test_ouro.py tests/test_cuda_graph.py --run-gpu -k 'not flash' -q: 218 passed, 12 FlashAttention combinations deselected. Includes real CUDA execution, FP16/BF16 exhaustive gate storage patterns with multiple up factors, tails/misalignment, numerical boundaries, streams, model dispatch/fallback, graph capture/replay, cancellation, KV release, and request ID reuse. Native tests require the built extension so fallback cannot hide a missing kernel.2b678ac739166bd0356883048673bbd1c34a3b0ecompiled as a standalone baseline. All tested native outputs match eager Torch exactly. A staged FP64 oracle is also recorded.Test Result
Kernel comparison
Median CUDA Graph device latency in microseconds, shape [4096,5632]. vLLM receives packed input and a preallocated output prepared before timing; the native operator receives separate inputs and allocates output. These are kernel comparisons, not E2E speedups.
Real Ouro-1.4B BF16 inference
One B300, public LLM worker, greedy, fixed 4 loops and ignore-EOS; three unprofiled interleaved A/B repeats after workload-specific warmup. Both backends use the unified API; the baseline uses its Torch implementation with native discovery disabled before worker imports. Scheduler max sequences=16, token budget=4096, prefill chunk=1024; last_exited KV, 4416 blocks × 16 tokens; synchronous scheduling, Graph max rows=16. Input IDs derive from 32 GSM8K questions repeated/cropped to exact lengths. Timing includes local IPC and generation; these are short closed-loop bursts, not saturation measurements. Physical GPU 5 was monitored for foreign processes throughout this final run.
Model-level benefit is limited: eager single-request improves, while concurrent and Graph results are around the run-to-run variation; this is not a general throughput-speedup claim. TTFT/E2E/TPOT samples and per-run distributions were retained locally. All 240 fixed-length requests / 7680 output tokens per backend match in generated token IDs and exit depths. An additional 8 natural GSM8K questions, up to 64 output tokens with adaptive exits, match on both execution modes; this is output consistency, not a newly scored GSM8K task result. All requests and KV blocks return to zero after each batch.
Attribution and limits
Four separate complete profiles were captured after timing: Torch/native × ops-only/full (CPU+CUDA; full adds shapes, memory, stacks). For a 16-token prefill plus one decode, 24 layers × 4 loops × 2 submissions gives 192 MLP activations. Separate 192 SiLU + 192 Mul kernels become 192 fused kernels; all device kernels fall from 11288 to 11096. Full traces contain [16,5632]/[1,5632] shapes and OuroMLP stacks. Total temporary allocation/free volume falls by exactly 18,382,848 bytes, matching the removed SiLU intermediate; this is cumulative allocation volume, not peak-memory savings. Launch counts are not a latency breakdown.
Final traces, raw runs, wheel checks, source fingerprints and environment records are retained locally under ignored
artifacts/silu-and-mul-pr-20261031/; large artifacts are not committed or publicly uploaded. Only B300 was exercised; FlashAttention, other GPUs, other model integrations, autograd and torch.compile are not qualified here.Code-quality review reused Torch dispatch, kept process-wide registration/availability in the kernel modules, and avoided per-layer flags, speculative adapters and unrelated runtime changes.
Build and reproduce
Use an existing compatible CUDA PyTorch and toolkit; keep the allocated GPU visible.
--no-build-isolationexposes that environment's PyTorch to the build. An isolated build without PyTorch cannot compile the extension and produces Python-only output. Without a GPU, an optional standardTORCH_CUDA_ARCH_LISToverride enables cross-compilation; ordinary GPU installs detect architectures automatically.