fix: ex_engine.python subpackage + flash_qla_sm70 deploy + vllm v0.5.5 MoE kernels
真机验证发现的问题: 1. qwen3_5.py 做 'from ex_engine.python.ix_bridge' 但包结构是 ex_engine.ix_bridge → 创建 python/ 子目录 + symlinks 2. flash_qla_sm70 只部署到 /workspace 没有到 vllm models 目录 → 显式 cp -r 到 VLLM/model_executor/models/ 3. 从 vllm v0.5.5 搬 MoE CUDA kernels (torch::Tensor API): - topk_softmax_kernels.cu (506行, CUB BlockReduce) - moe_align_block_size_kernels.cu (134行) - moe_pybind.cpp (pybind11 入口) 真机验证结果: ✓ ix_bridge import OK, available=True ✓ topk_softmax (64 experts, top8) OK — CUDA kernel 命中 ✓ ix_full_bridge silu_and_mul OK ✓ qwen3_5.py import OK ✓ ex_engine build 2/2 factors ✓ moe_topk_softmax_v3.so 编译成功 ✓ flash_qla_sm70_gdn_strided.so 编译成功 ✗ 单卡 32GB OOM (正常, 竞赛 4卡 tp=4)
This commit is contained in:
@@ -18,6 +18,83 @@ logger = init_logger(__name__)
|
||||
|
||||
supports_moe_ops = True
|
||||
|
||||
# ============================================================================
|
||||
# MoE CUDA kernels — JIT-compiled from vllm v0.5.5 (torch::Tensor API)
|
||||
# topk_softmax + moe_align_block_size compiled as moe_kernels.so
|
||||
# ============================================================================
|
||||
_moe_kernels = None
|
||||
_moe_kernels_loaded = False
|
||||
|
||||
def _load_moe_kernels():
|
||||
"""Load pre-compiled moe_kernels.so or JIT compile on demand."""
|
||||
global _moe_kernels, _moe_kernels_loaded
|
||||
if _moe_kernels_loaded:
|
||||
return _moe_kernels
|
||||
_moe_kernels_loaded = True
|
||||
|
||||
import os, glob, importlib.util
|
||||
|
||||
# Try pre-compiled .so from torch extensions cache
|
||||
try:
|
||||
import moe_kernels
|
||||
_moe_kernels = moe_kernels
|
||||
logger.info("[EX] moe_kernels loaded from cache")
|
||||
return _moe_kernels
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Try to find .so in known locations
|
||||
search_paths = [
|
||||
os.path.expanduser('~/.cache/torch_extensions'),
|
||||
'/root/.cache/torch_extensions',
|
||||
'/workspace/ex_engine/build',
|
||||
]
|
||||
for sp in search_paths:
|
||||
for so in glob.glob(os.path.join(sp, '**/moe_kernels*.so'), recursive=True):
|
||||
try:
|
||||
spec = importlib.util.spec_from_file_location('moe_kernels', so)
|
||||
mod = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(mod)
|
||||
_moe_kernels = mod
|
||||
logger.info(f"[EX] moe_kernels loaded from {so}")
|
||||
return _moe_kernels
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
# JIT compile as last resort
|
||||
moe_dir = None
|
||||
for candidate in [
|
||||
'/workspace/ex_engine/csrc/moe_v055',
|
||||
os.path.join(os.path.dirname(__file__), '..', 'model_executor', 'models',
|
||||
'ex_engine', 'csrc', 'moe_v055'),
|
||||
]:
|
||||
if os.path.isdir(candidate):
|
||||
moe_dir = candidate
|
||||
break
|
||||
|
||||
if moe_dir and os.path.isfile(os.path.join(moe_dir, 'moe_pybind.cpp')):
|
||||
try:
|
||||
from torch.utils.cpp_extension import load
|
||||
_moe_kernels = load(
|
||||
name='moe_kernels',
|
||||
sources=[
|
||||
os.path.join(moe_dir, 'moe_pybind.cpp'),
|
||||
os.path.join(moe_dir, 'topk_softmax_kernels.cu'),
|
||||
os.path.join(moe_dir, 'moe_align_block_size_kernels.cu'),
|
||||
],
|
||||
extra_include_paths=[moe_dir],
|
||||
extra_cflags=['-O2', '-std=c++17'],
|
||||
extra_cuda_cflags=['-O2', '--expt-relaxed-constexpr'],
|
||||
verbose=False,
|
||||
)
|
||||
logger.info(f"[EX] moe_kernels JIT compiled from {moe_dir}")
|
||||
return _moe_kernels
|
||||
except Exception as e:
|
||||
logger.warning(f"[EX] moe_kernels JIT compile failed: {e}")
|
||||
|
||||
logger.warning("[EX] moe_kernels NOT available — MoE will use PyTorch path")
|
||||
return None
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
||||
def register_fake(fn):
|
||||
|
||||
@@ -143,4 +143,27 @@ cp ./_custom_ops.py "$VLLM/_custom_ops.py" 2>/dev/null && \
|
||||
echo "[patch_ops] _custom_ops.py deployed" || true
|
||||
[ -n "$VLLM2" ] && cp ./_custom_ops.py "$VLLM2/_custom_ops.py" 2>/dev/null || true
|
||||
|
||||
# ---- 6. ex_engine.python subpackage (qwen3_5.py does "from ex_engine.python.ix_bridge") ----
|
||||
# The flat ex_engine package has ix_bridge.py at top level, but qwen3_5.py imports from .python subdir
|
||||
_EX_PKG=$(python3 -c "import ex_engine; import os; print(os.path.dirname(ex_engine.__file__))" 2>/dev/null)
|
||||
if [ -n "$_EX_PKG" ] && [ -d "$_EX_PKG" ]; then
|
||||
mkdir -p "$_EX_PKG/python"
|
||||
touch "$_EX_PKG/python/__init__.py"
|
||||
for f in ix_bridge.py corex_moe.py corex_gdn.py corex_fa2.py; do
|
||||
[ -f "$_EX_PKG/$f" ] && ln -sf "$_EX_PKG/$f" "$_EX_PKG/python/$f"
|
||||
done
|
||||
echo "[patch_ops] ex_engine.python subpackage linked"
|
||||
fi
|
||||
|
||||
# ---- 7. flash_qla_sm70 deployment to BOTH vllm paths ----
|
||||
_FLASH_SRC="/workspace/qwen3_6_scripts/flash_qla_sm70"
|
||||
if [ -d "$_FLASH_SRC" ]; then
|
||||
for _VPATH in "$VLLM" "$VLLM2"; do
|
||||
[ -z "$_VPATH" ] && continue
|
||||
_FLASH_DST="$_VPATH/model_executor/models/flash_qla_sm70"
|
||||
cp -r "$_FLASH_SRC" "$_FLASH_DST" 2>/dev/null || true
|
||||
done
|
||||
echo "[patch_ops] flash_qla_sm70 deployed to vllm model dirs"
|
||||
fi
|
||||
|
||||
echo "[patch_ops] DONE"
|
||||
|
||||
Reference in New Issue
Block a user