sgl-project/sglang · error · NotImplementedError

{self._op_label()}: no triton backend

Error message

{self._op_label()}: no triton backend

What it means

The FusedOp dispatcher routes by backend name to methods like forward_triton. The base class implements them as NotImplementedError stubs so an unimplemented backend fails loudly instead of silently falling back, telling you exactly which op lacks a Triton path.

Source

Thrown at python/sglang/kernels/fused_op.py:426

            if klass is BaseFusedOp:
                return None
            if method_name in klass.__dict__:
                return getattr(self, method_name)
        return None

    # --- kernel backends: native is required; the rest are opt-in overrides ---

    @abstractmethod
    def forward_native(self, *args, **kwargs):
        """Pure-``torch`` reference implementation (correctness ground truth)."""

    def forward_torch_compile(self, *args, **kwargs):
        if self._compiled_native is None:
            self._compiled_native = torch.compile(self.forward_native)
        return self._compiled_native(*args, **kwargs)

    def forward_triton(self, *args, **kwargs):
        raise NotImplementedError(f"{self._op_label()}: no triton backend")

    def forward_jit(self, *args, **kwargs):
        raise NotImplementedError(f"{self._op_label()}: no jit backend")

    def forward_aot(self, *args, **kwargs):
        raise NotImplementedError(f"{self._op_label()}: no aot backend")

    def forward_cute_dsl(self, *args, **kwargs):
        raise NotImplementedError(f"{self._op_label()}: no cute_dsl backend")

    def forward_flashinfer(self, *args, **kwargs):
        raise NotImplementedError(f"{self._op_label()}: no flashinfer backend")

    def forward_deepgemm(self, *args, **kwargs):
        raise NotImplementedError(f"{self._op_label()}: no deepgemm backend")

    def forward_aiter(self, *args, **kwargs):
        raise NotImplementedError(f"{self._op_label()}: no aiter backend")

View on GitHub (pinned to 0132848349)

Solutions

  1. Use a supported backend for the op (check the subclass for which forward_* methods are overridden, e.g. 'native' or 'aot')
  2. Implement forward_triton for your op if Triton support is required
  3. Check for an existing op-specific Triton implementation to delegate to instead of the base stub

Example fix

# before
class MyOp(FusedOp):
    def forward_native(self, x): return x * 2
out = MyOp()(x, backend='triton')
# after
out = MyOp()(x, backend='native')
Defensive patterns

Strategy: fallback

Validate before calling

backend = 'triton' if type(op).forward_triton is not FusedOp.forward_triton else 'native'

Type guard

def has_backend(op, name): return getattr(type(op), f'forward_{name}') is not getattr(FusedOp, f'forward_{name}')

Try / catch

except NotImplementedError: op(x, backend='native')

Prevention

When it happens

Trigger: A FusedOp instance without an overridden forward_triton is invoked with backend='triton' (or the dispatcher selects triton), e.g. an op that only implements forward_native/forward_aot.

Common situations: Selecting a backend via config/env (SGLANG kernel backend flags) for an op that was never ported to it; running new ops on a backend where porting is still pending.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/d22e9f6842422f13. Report an issue: GitHub.