[VLM][LLM] Optimize fused_moe triton kernel tma (#18782)

Co-authored-by: luoyuan.luo <luoyuan.luo@antgroup.com>
This commit is contained in:
Yuan Luo
2026-02-14 14:35:26 +08:00
committed by GitHub
parent f6c18c3a85
commit fa0ef6e4f7

View File

@@ -2,6 +2,7 @@ from __future__ import annotations
import functools
import os
from collections import OrderedDict
from typing import Any, Dict, List, Optional
import torch
@@ -610,6 +611,67 @@ def fused_moe_kernel(
tl.store(c_ptrs, accumulator, mask=c_mask)
# -----------------------------------------------------------------------------
# TMA allocator: set once per process (avoid per-call triton.set_allocator)
# -----------------------------------------------------------------------------
_TMA_ALLOCATOR_SET = False
def _set_triton_tma_allocator():
"""TMA descriptors require a global allocator; set it once to avoid per-call overhead."""
global _TMA_ALLOCATOR_SET
if _TMA_ALLOCATOR_SET:
return
# TMA descriptors require a global memory allocation
def alloc_fn(size: int, alignment: int, stream: Optional[int]):
# NOTE: keep this allocation on CUDA device
return torch.empty(size, device="cuda", dtype=torch.int8)
triton.set_allocator(alloc_fn)
_TMA_ALLOCATOR_SET = True
# --- B TensorDescriptor cache (LRU) ---
_B_DESC_CACHE_MAX = 64
_B_DESC_CACHE: "OrderedDict[tuple, TensorDescriptor]" = OrderedDict()
def _get_b_tma_desc_cached(B: torch.Tensor, block_n: int, block_k: int):
"""
Cache TensorDescriptor for constant weight B.
Keyed by storage ptr + shape/stride/dtype + tile shape.
"""
key = (
int(B.data_ptr()),
tuple(B.shape),
tuple(B.stride()),
str(B.dtype),
int(block_n),
int(block_k),
)
desc = _B_DESC_CACHE.get(key, None)
if desc is not None:
_B_DESC_CACHE.move_to_end(key)
return desc
# Create outside lock to reduce lock hold time (ok if duplicated rarely)
desc = TensorDescriptor(
B,
B.shape,
B.stride(),
[1, block_n, block_k],
)
_B_DESC_CACHE[key] = desc
_B_DESC_CACHE.move_to_end(key)
if len(_B_DESC_CACHE) > _B_DESC_CACHE_MAX:
_B_DESC_CACHE.popitem(last=False)
return desc
def invoke_fused_moe_kernel(
A: torch.Tensor,
B: torch.Tensor,
@@ -754,11 +816,8 @@ def invoke_fused_moe_kernel(
else:
if a_use_tma or b_use_tma:
# TMA descriptors require a global memory allocation
def alloc_fn(size: int, alignment: int, stream: Optional[int]):
return torch.empty(size, device="cuda", dtype=torch.int8)
_set_triton_tma_allocator()
triton.set_allocator(alloc_fn)
if a_use_tma:
a_desc = TensorDescriptor(
A, A.shape, A.stride(), [config["BLOCK_SIZE_M"], config["BLOCK_SIZE_K"]]
@@ -766,11 +825,11 @@ def invoke_fused_moe_kernel(
else:
a_desc = None
if b_use_tma:
b_desc = TensorDescriptor(
# B is constant weights -> cache descriptor
b_desc = _get_b_tma_desc_cached(
B,
B.shape,
B.stride(),
[1, config["BLOCK_SIZE_N"], config["BLOCK_SIZE_K"]],
config["BLOCK_SIZE_N"],
config["BLOCK_SIZE_K"],
)
else:
b_desc = None