fix(PROVEN): _moe_C compiles and runs on real BI-V100 hardware
Tested on real machine (cc-b2042074, BI-V100, IX-ML 3.2.3): _moe_C.topk_softmax() → SUCCESS, correct output Two fixes proven on hardware: 1. cuda_compat.h: WARP_SIZE=64 (BI-V100 warp is 64, not 32) 2. topk_softmax_kernels.cu: cub/block/block_reduce.cuh instead of cub/cub.cuh (cub.cuh pulls radix_sort which has WARP_SIZE conflict) Key finding: ixformer SDK on this base image does NOT have topk_softmax. The ixformer::infer namespace from xllm's ixformer.h is for newer SDK. We MUST compile our own _moe_C kernel — which now works. Build flags (clang 16, ivcore10): CUDA: -O3 -cl-fast-relaxed-math (NOT --use_fast_math) C++: -O2 -std=c++17 Dockerfile simplified: 3 steps (was 6) _custom_ops.py: _moe_C as Priority 0, in-place vllm API
This commit is contained in:
@@ -1008,15 +1008,39 @@ def _init_ix_bridge():
|
||||
def _init_moe_topk():
|
||||
global _moe_topk_ext, _moe_topk_init_done
|
||||
_moe_topk_init_done = True
|
||||
# 0. Try ix_bridge first (calls ixformer C++ SDK directly)
|
||||
# 0. Try _moe_C (CUB-based, proven on BI-V100 real hardware 2026-08-11)
|
||||
try:
|
||||
import _moe_C as ext
|
||||
if hasattr(ext, 'topk_softmax'):
|
||||
_moe_topk_ext = ext
|
||||
logger.info("topk_softmax: loaded _moe_C (CUB BlockReduce, WARP_SIZE=64)")
|
||||
return
|
||||
except ImportError:
|
||||
pass
|
||||
# 0b. Try loading from torch cache
|
||||
import glob as _glob
|
||||
for pattern in [
|
||||
"/root/.cache/torch_extensions/py310_cu102/_moe_C/_moe_C.so",
|
||||
"/root/.cache/torch_extensions/*/_moe_C/*.so",
|
||||
]:
|
||||
for so_path in _glob.glob(pattern):
|
||||
try:
|
||||
torch.ops.load_library(so_path)
|
||||
import _moe_C as ext
|
||||
_moe_topk_ext = ext
|
||||
logger.info("topk_softmax: loaded _moe_C from %s", so_path)
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
# 0c. Try ix_bridge (calls ixformer C++ SDK if available)
|
||||
_init_ix_bridge()
|
||||
if _ix_bridge_mod:
|
||||
return # ix_bridge loaded, no need for CUDA kernel
|
||||
# 1. Try import precompiled module (torch cache from Docker build)
|
||||
return
|
||||
# 1. Try import old precompiled module (torch cache from Docker build)
|
||||
try:
|
||||
import moe_topk_softmax_v3 as ext
|
||||
_moe_topk_ext = ext
|
||||
logger.info("topk_softmax: loaded precompiled CUDA kernel")
|
||||
logger.info("topk_softmax: loaded precompiled moe_topk_softmax_v3")
|
||||
return
|
||||
except ImportError:
|
||||
pass
|
||||
@@ -1088,15 +1112,21 @@ def topk_softmax(topk_weights: torch.Tensor, topk_ids: torch.Tensor,
|
||||
except Exception as e:
|
||||
logger.warning("topk_softmax ix_bridge failed (%s), trying CUDA kernel", e)
|
||||
|
||||
# Priority 1: Our CUDA kernel (fused warp-shuffle, ~5x faster than PyTorch)
|
||||
# Priority 1: CUDA kernel (_moe_C or moe_topk_softmax_v3)
|
||||
if _moe_topk_ext is not None:
|
||||
try:
|
||||
gating = gating_output if isinstance(gating_output, torch.Tensor) else gating_output
|
||||
topk_k = topk_weights.shape[1]
|
||||
results = _moe_topk_ext.moe_topk_softmax(gating, topk_k, False)
|
||||
topk_weights.copy_(results[0].to(topk_weights.dtype))
|
||||
topk_ids.copy_(results[1].to(topk_ids.dtype))
|
||||
token_expert_indicies.copy_(results[2].to(token_expert_indicies.dtype))
|
||||
if hasattr(_moe_topk_ext, 'topk_softmax'):
|
||||
# _moe_C style: in-place (vllm standard API)
|
||||
_moe_topk_ext.topk_softmax(topk_weights, topk_ids,
|
||||
token_expert_indicies, gating.float())
|
||||
elif hasattr(_moe_topk_ext, 'moe_topk_softmax'):
|
||||
# old v3 style: returns tuple
|
||||
topk_k = topk_weights.shape[1]
|
||||
results = _moe_topk_ext.moe_topk_softmax(gating, topk_k, False)
|
||||
topk_weights.copy_(results[0].to(topk_weights.dtype))
|
||||
topk_ids.copy_(results[1].to(topk_ids.dtype))
|
||||
token_expert_indicies.copy_(results[2].to(token_expert_indicies.dtype))
|
||||
return
|
||||
except Exception as e:
|
||||
logger.warning("topk_softmax CUDA kernel failed (%s), falling back to PyTorch", e)
|
||||
|
||||
Reference in New Issue
Block a user