94057c3d3e
PR Test (NPU) / check-changes (push) Has been cancelled
PR Test (NPU) / pr-gate (push) Has been cancelled
PR Test (NPU) / set-image-config (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-4-npu-a3 (push) Has been cancelled
PR Test (NPU) / stage-b-test-16-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-1-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-2-npu-a3 (push) Has been cancelled
PR Test (Arm64) / pr-gate (push) Has been cancelled
PR Test (Arm64) / check-changes (push) Has been cancelled
PR Test (Arm64) / build-test (push) Has been cancelled
PR Test (sgl-router) / gate (push) Has been cancelled
PR Test (sgl-router) / tier-1 — lint (push) Has been cancelled
PR Test (sgl-router) / tier-2 — build + test (push) Has been cancelled
PR Test (sgl-router) / tier-3 — docker (placeholder) (push) Has been cancelled
PR Test (sgl-router) / tier-3 — k8s integration (push) Has been cancelled
PR Test (sgl-router) / tier-3 — e2e (push) Has been cancelled
PR Test (sgl-router) / finish (push) Has been cancelled
PR Test (NPU) / single-node-poc (map[name:qwen3_6_27b_w8a8_1p_in64k_out1k_50ms runner:linux-aarch64-a3-2 test_case:test/registered/ascend/performance/qwen3_6_27b/test_npu_qwen3_6_27b_w8a8_1p_in64k_out1k_50ms.py test_type:perf]) (push) Has been cancelled
PR Test (NPU) / pr-test-npu-finish (push) Has been cancelled
PR Test (Xeon) / pr-gate (push) Has been cancelled
PR Test (Xeon) / check-changes (push) Has been cancelled
PR Test (Xeon) / build-test (, xeon-gnr, base-b-test-cpu) (push) Has been cancelled
PR Test (XPU) / check-changes (push) Has been cancelled
PR Test (XPU) / pr-gate (push) Has been cancelled
PR Test (XPU) / stage-a-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / wait-for-stage-a (push) Has been cancelled
PR Test (XPU) / stage-b-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / finish (push) Has been cancelled
CI Model Inventory / build-inventory (push) Has been cancelled
Lint / lint (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Compilation Check (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Manual Policy (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Request Processing (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Summary (push) Has been cancelled
PR Test (SMG) / build-wheel (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on windows (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (x86_64 - auto) (push) Has been cancelled
PR Test (SMG) / python-unit-tests (push) Has been cancelled
PR Test (SMG) / unit-tests (push) Has been cancelled
PR Test (SMG) / benchmarks (push) Has been cancelled
PR Test (SMG) / chat-completions (push) Has been cancelled
PR Test (SMG) / chat-completions-4gpu (push) Has been cancelled
PR Test (SMG) / e2e (push) Has been cancelled
PR Test (SMG) / docker-build-test (push) Has been cancelled
PR Test (SMG) / k8s-integration (push) Has been cancelled
PR Test (SMG) / finish (push) Has been cancelled
PR Test (SMG) / summarize-benchmarks (push) Has been cancelled
Release SGLang Model Gateway Docker Image / publish (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Build SDist (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Upload to PyPI (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (aarch64, 12.9, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (x86_64, 12.9, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu129 (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (aarch64, 13.0, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (x86_64, 13.0, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu130 (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 700) (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 720) (push) Has been cancelled
Release SGLang Kernels / release-rocm700 (push) Has been cancelled
Release SGLang Kernels / release-rocm720 (push) Has been cancelled
Release SGLang Kernels / build-musa43 (43, 3.10) (push) Has been cancelled
Release SGLang Kernels / release-musa43 (push) Has been cancelled
137 lines
5.1 KiB
Python
137 lines
5.1 KiB
Python
# SPDX-License-Identifier: Apache-2.0
|
|
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
|
# Adapted from https://github.com/vllm-project/vllm/blob/v0.10.0/vllm/compilation/fix_functionalization.py
|
|
|
|
import logging
|
|
import operator
|
|
from collections.abc import Iterable
|
|
from typing import Optional, Union
|
|
|
|
import torch
|
|
from torch._higher_order_ops.auto_functionalize import auto_functionalized
|
|
|
|
from sglang.srt.compilation.fx_utils import is_func
|
|
from sglang.srt.compilation.inductor_pass import SGLangInductorPass
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class FixFunctionalizationPass(SGLangInductorPass):
|
|
"""
|
|
This pass defunctionalizes certain nodes to avoid redundant tensor copies.
|
|
After this pass, DCE (dead-code elimination) should never be run,
|
|
as de-functionalized nodes may appear as dead code.
|
|
|
|
To add new nodes to defunctionalize, add to the if-elif chain in __call__.
|
|
"""
|
|
|
|
def __call__(self, graph: torch.fx.Graph):
|
|
self.begin()
|
|
self.dump_graph(graph, "before_fix_functionalization")
|
|
|
|
self.nodes_to_remove: list[torch.fx.Node] = []
|
|
count = 0
|
|
for node in graph.nodes:
|
|
if not is_func(node, auto_functionalized):
|
|
continue # Avoid deep if-elif nesting
|
|
count += 1
|
|
|
|
self.dump_graph(graph, "before_fix_functionalization_cleanup")
|
|
|
|
# Remove the nodes all at once
|
|
count_removed = len(self.nodes_to_remove)
|
|
for node in self.nodes_to_remove:
|
|
graph.erase_node(node)
|
|
|
|
logger.debug(
|
|
"De-functionalized %s nodes, removed %s nodes", count, count_removed
|
|
)
|
|
self.dump_graph(graph, "after_fix_functionalization")
|
|
self.end_and_log()
|
|
|
|
def _remove(self, node_or_nodes: Union[torch.fx.Node, Iterable[torch.fx.Node]]):
|
|
"""
|
|
Stage a node (or nodes) for removal at the end of the pass.
|
|
"""
|
|
if isinstance(node_or_nodes, torch.fx.Node):
|
|
self.nodes_to_remove.append(node_or_nodes)
|
|
else:
|
|
self.nodes_to_remove.extend(node_or_nodes)
|
|
|
|
def defunctionalize(
|
|
self,
|
|
graph: torch.fx.Graph,
|
|
node: torch.fx.Node,
|
|
mutated_args: dict[int, Union[torch.fx.Node, str]],
|
|
args: Optional[tuple[Union[torch.fx.Node, str], ...]] = None,
|
|
):
|
|
"""
|
|
De-functionalize a node by replacing it with a call to the original.
|
|
It also replaces the getitem users with the mutated arguments.
|
|
See replace_users_with_mutated_args and insert_defunctionalized.
|
|
"""
|
|
self.replace_users_with_mutated_args(node, mutated_args)
|
|
self.insert_defunctionalized(graph, node, args=args)
|
|
self._remove(node)
|
|
|
|
def replace_users_with_mutated_args(
|
|
self, node: torch.fx.Node, mutated_args: dict[int, Union[torch.fx.Node, str]]
|
|
):
|
|
"""
|
|
Replace all getitem users of the auto-functionalized node with the
|
|
mutated arguments.
|
|
:param node: The auto-functionalized node
|
|
:param mutated_args: The mutated arguments, indexed by getitem index.
|
|
If the value of an arg is a string, `node.kwargs[arg]` is used.
|
|
"""
|
|
for idx, user in self.getitem_users(node).items():
|
|
arg = mutated_args[idx]
|
|
arg = node.kwargs[arg] if isinstance(arg, str) else arg
|
|
user.replace_all_uses_with(arg)
|
|
self._remove(user)
|
|
|
|
def getitem_users(self, node: torch.fx.Node) -> dict[int, torch.fx.Node]:
|
|
"""
|
|
Returns the operator.getitem users of the auto-functionalized node,
|
|
indexed by the index they are getting.
|
|
"""
|
|
users = {}
|
|
for user in node.users:
|
|
if is_func(user, operator.getitem):
|
|
idx = user.args[1]
|
|
users[idx] = user
|
|
return users
|
|
|
|
def insert_defunctionalized(
|
|
self,
|
|
graph: torch.fx.Graph,
|
|
node: torch.fx.Node,
|
|
args: Optional[tuple[Union[torch.fx.Node, str], ...]] = None,
|
|
):
|
|
"""
|
|
Insert a new defunctionalized node into the graph before node.
|
|
If one of the kwargs is 'out', provide args directly,
|
|
as node.kwargs cannot be used.
|
|
See https://github.com/pytorch/pytorch/blob/a00faf440888ffb724bad413f329a49e2b6388e7/torch/_inductor/lowering.py#L351
|
|
|
|
:param graph: Graph to insert the defunctionalized node into
|
|
:param node: The auto-functionalized node to defunctionalize
|
|
:param args: If we cannot use kwargs, specify args directly.
|
|
If an arg is a string, `node.kwargs[arg]` is used.
|
|
""" # noqa: E501
|
|
assert is_func(
|
|
node, auto_functionalized
|
|
), f"node must be auto-functionalized, is {node} instead"
|
|
|
|
# Create a new call to the original function
|
|
with graph.inserting_before(node):
|
|
function = node.args[0]
|
|
if args is None:
|
|
graph.call_function(function, kwargs=node.kwargs)
|
|
else:
|
|
# Args passed as strings refer to items in node.kwargs
|
|
args = tuple(
|
|
node.kwargs[arg] if isinstance(arg, str) else arg for arg in args
|
|
)
|
|
graph.call_function(function, args=args)
|