Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 31 additions & 29 deletions csrc/trtllm_fused_moe_kernel_launcher.cu
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class FusedMoeLauncher {
btg::Dtype mRoutingBiasDtype{
btg::Dtype::Bfloat16}; // Dtype for expert weights in routing, based on routing bias
ActivationType activation_type{ActivationType::Swiglu};
btg::Dtype mDtypeScore{btg::Dtype::Bfloat16};

public:
// Constructor that initializes all TensorView members
Expand Down Expand Up @@ -144,13 +145,19 @@ class FusedMoeLauncher {
int64_t weight_layout, ActivationType activation_type);

// Routing logits [num_tokens, num_experts]
void check_routing_logits_shape() const {
void check_routing_logits() const {
if (routing_logits.has_value()) {
// Check shape
TVM_FFI_ICHECK_EQ(routing_logits.value().ndim(), 2) << "routing_logits must be 2D.";
TVM_FFI_ICHECK_EQ(routing_logits.value().size(0), hidden_states.size(0))
<< "routing_logits and hidden_states must have the same number of tokens.";
TVM_FFI_ICHECK_EQ(routing_logits.value().size(1), args->num_experts)
<< "routing_logits dim1 must match num_experts.";

// Check dtype
TVM_FFI_ICHECK(routing_logits.value().dtype() == dl_float32 ||
routing_logits.value().dtype() == dl_bfloat16)
<< "routing_logits must be float or bfloat16.";
}
}

Expand Down Expand Up @@ -212,7 +219,7 @@ class FusedMoeLauncher {
args->local_expert_offset + args->local_num_experts <= args->num_experts)
<< "expert offset and count must be within valid range";

check_routing_logits_shape();
check_routing_logits();

if (routing_bias.has_value()) {
check_routing_bias_shape();
Expand Down Expand Up @@ -278,6 +285,17 @@ class FusedMoeLauncher {
workspace.cta_idx_xy_to_batch_idx = static_cast<int*>(cta_idx_xy_to_batch_idx.data_ptr());
workspace.cta_idx_xy_to_mn_limit = static_cast<int*>(cta_idx_xy_to_mn_limit.data_ptr());
workspace.num_non_exiting_ctas = static_cast<int*>(num_non_exiting_ctas.data_ptr());

// Set dtype of score
if (routing_logits.has_value()) {
if (static_cast<RoutingMethodType>(routing_method_type) == RoutingMethodType::DeepSeekV3) {
TVM_FFI_ICHECK_EQ(routing_logits.value().dtype(), dl_float32)
<< "routing_logits must be float.";
mDtypeScore = btg::Dtype::Fp32;
} else {
mDtypeScore = btg::Dtype::Bfloat16;
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

void check_moe_common() const {
Expand Down Expand Up @@ -355,8 +373,8 @@ class FusedMoeLauncher {
static_cast<int*>(num_tokens_per_expert.data_ptr()),
static_cast<int*>(cta_idx_xy_to_batch_idx.data_ptr()),
static_cast<int*>(cta_idx_xy_to_mn_limit.data_ptr()),
static_cast<int*>(num_non_exiting_ctas.data_ptr()), args->mDtypeElt, mRoutingBiasDtype,
use_routing_scales_on_input, use_deep_seek_fp8,
static_cast<int*>(num_non_exiting_ctas.data_ptr()), mDtypeScore, args->mDtypeElt,
mRoutingBiasDtype, use_routing_scales_on_input, use_deep_seek_fp8,
static_cast<RoutingMethodType>(routing_method_type), routing_stream);

check_moe();
Expand Down Expand Up @@ -970,8 +988,8 @@ class Fp8BlockScaleLauncher : public FusedMoeLauncher {
static_cast<int*>(num_tokens_per_expert.data_ptr()),
static_cast<int*>(cta_idx_xy_to_batch_idx.data_ptr()),
static_cast<int*>(cta_idx_xy_to_mn_limit.data_ptr()),
static_cast<int*>(num_non_exiting_ctas.data_ptr()), args->mDtypeElt, mRoutingBiasDtype,
use_routing_scales_on_input, use_deep_seek_fp8,
static_cast<int*>(num_non_exiting_ctas.data_ptr()), mDtypeScore, args->mDtypeElt,
mRoutingBiasDtype, use_routing_scales_on_input, use_deep_seek_fp8,
static_cast<RoutingMethodType>(routing_method_type), routing_stream);

check_moe();
Expand Down Expand Up @@ -1432,8 +1450,8 @@ class FP4BlockScaleLauncher : public FusedMoeLauncher {
static_cast<int*>(num_tokens_per_expert.data_ptr()),
static_cast<int*>(cta_idx_xy_to_batch_idx.data_ptr()),
static_cast<int*>(cta_idx_xy_to_mn_limit.data_ptr()),
static_cast<int*>(num_non_exiting_ctas.data_ptr()), args->mDtypeElt, mRoutingBiasDtype,
use_routing_scales_on_input, use_deep_seek_fp8,
static_cast<int*>(num_non_exiting_ctas.data_ptr()), mDtypeScore, args->mDtypeElt,
mRoutingBiasDtype, use_routing_scales_on_input, use_deep_seek_fp8,
static_cast<RoutingMethodType>(routing_method_type), routing_stream);

check_moe();
Expand Down Expand Up @@ -1562,13 +1580,12 @@ Tensor trtllm_fp8_per_tensor_scale_moe(
// Basic type validation
auto dtype = hidden_states.dtype();
auto activation = static_cast<ActivationType>(activation_type);
if (use_routing_scales_on_input) {
TVM_FFI_ICHECK_EQ(routing_logits.dtype(), dl_bfloat16) << "routing_logits must be bfloat16.";
} else if (static_cast<RoutingMethodType>(routing_method_type) == RoutingMethodType::DeepSeekV3) {
TVM_FFI_ICHECK_EQ(routing_logits.dtype(), dl_float32) << "routing_logits must be float.";
} else {
TVM_FFI_ICHECK_EQ(routing_logits.dtype(), dl_bfloat16) << "routing_logits must be bfloat16.";

if (static_cast<RoutingMethodType>(routing_method_type) == RoutingMethodType::DeepSeekV3) {
TVM_FFI_ICHECK_EQ(routing_logits.dtype(), dl_float32)
<< "routing_logits must be float for DeepSeekV3.";
}

TVM_FFI_ICHECK(dtype == dl_float8_e4m3fn || dtype == dl_float16 || dtype == dl_bfloat16)
<< "FP8 MoE: hidden_states must be float8_e4m3fn, float16, or bfloat16.";
TVM_FFI_ICHECK_EQ(gemm1_weights.dtype(), dl_float8_e4m3fn)
Expand Down Expand Up @@ -1666,9 +1683,6 @@ Tensor trtllm_fp8_block_scale_moe(
if (static_cast<RoutingMethodType>(routing_method_type) == RoutingMethodType::DeepSeekV3) {
TVM_FFI_ICHECK_EQ(routing_logits.value().dtype(), dl_float32)
<< "routing_logits must be float.";
} else {
TVM_FFI_ICHECK_EQ(routing_logits.value().dtype(), dl_bfloat16)
<< "routing_logits must be bfloat16.";
}
}
TVM_FFI_ICHECK(dtype == dl_float16 || dtype == dl_bfloat16 || dtype == dl_float8_e4m3fn)
Expand Down Expand Up @@ -1772,18 +1786,6 @@ Array<Tensor> trtllm_fp4_block_scale_moe(
<< "unsupported weight_scale_vec_size.";
auto mDtypeWeights = weight_scale_vec_size == 16 ? btg::Dtype::E2m1 : btg::Dtype::MxE2m1;

if (routing_logits.has_value()) {
TVM_FFI_ICHECK(routing_logits.value().dtype() == dl_float32 ||
routing_logits.value().dtype() == dl_bfloat16)
<< "routing_logits must be float or bfloat16.";
TVM_FFI_ICHECK_EQ(routing_logits.value().ndim(), 2) << "routing_logits must be 2D.";
TVM_FFI_ICHECK_EQ(routing_logits.value().size(1), num_experts)
<< "routing_logits has incorrect shape.";
if (static_cast<RoutingMethodType>(routing_method_type) == RoutingMethodType::DeepSeekV3) {
TVM_FFI_ICHECK_EQ(routing_logits.value().dtype(), dl_float32)
<< "routing_logits must be float.";
}
}
if (routing_bias.has_value()) {
TVM_FFI_ICHECK(routing_bias.value().dtype() == dl_bfloat16 ||
routing_bias.value().dtype() == dl_float32)
Expand Down
6 changes: 4 additions & 2 deletions csrc/trtllm_fused_moe_runner.cu
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ void Runner::run(void* routingLogits, void* routingBias, int32_t numTokens, int3
int32_t* expandedIdxToPermutedIdx, int32_t* permutedIdxToExpandedIdx,
int32_t* permutedIdxToTokenIdx, void* expertWeights, int32_t* numTokensPerExpert,
int32_t* ctaIdxXyToBatchIdx, int32_t* ctaIdxXyToMnLimit,
int32_t* numNonExitingCtas, btg::Dtype dtypeElt, btg::Dtype dtypeBias,
bool useRoutingScalesOnInput, bool useDeepSeekFp8,
int32_t* numNonExitingCtas, btg::Dtype dtypeScore, btg::Dtype dtypeElt,
btg::Dtype dtypeBias, bool useRoutingScalesOnInput, bool useDeepSeekFp8,
RoutingMethodType routingMethodType, cudaStream_t stream) {
if (routingMethodType == RoutingMethodType::DeepSeekV3) {
FLASHINFER_CHECK(topK <= 22, "For DeepSeek routing method, must have topK <= 22");
Expand Down Expand Up @@ -141,6 +141,8 @@ void Runner::run(void* routingLogits, void* routingBias, int32_t numTokens, int3
//

routingData.mDtypeExpW = btg::Dtype::Bfloat16;
routingData.mDtypeScore = dtypeScore;

// routingData.mDtypeElt = dtypeElt; // no-op for now as hidden_state is not input
routingData.mUsePdl = true;
routingData.mDoSoftmaxBeforeTopK = routingMethodType == RoutingMethodType::RenormalizeNaive;
Expand Down
29 changes: 24 additions & 5 deletions include/flashinfer/trtllm/fused_moe/DevKernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,20 +234,39 @@ namespace moe::dev {

#define LAUNCH_ROUTING_WITH_NUM_EXPERTS(data, coopLaunch, kernel, numBlocks, numThreads, smemSize, \
stream, extraFlag1, numExperts) \
if (data.mDtypeExpW == tg::Dtype::Fp32 && extraFlag1) { \
if (data.mDtypeScore == tg::Dtype::Fp32 && data.mDtypeExpW == tg::Dtype::Fp32 && extraFlag1) { \
LAUNCH_TILEN(data, coopLaunch, LAUNCH_ESC(float, float, numExperts, true), kernel, numBlocks, \
numThreads, smemSize, stream); \
} else if (data.mDtypeExpW == tg::Dtype::Fp32) { \
} else if (data.mDtypeScore == tg::Dtype::Fp32 && data.mDtypeExpW == tg::Dtype::Fp32 && \
!extraFlag1) { \
LAUNCH_TILEN(data, coopLaunch, LAUNCH_ESC(float, float, numExperts, false), kernel, numBlocks, \
numThreads, smemSize, stream); \
} else if (data.mDtypeExpW == tg::Dtype::Bfloat16 && extraFlag1) { \
} else if (data.mDtypeScore == tg::Dtype::Fp32 && data.mDtypeExpW == tg::Dtype::Bfloat16 && \
extraFlag1) { \
LAUNCH_TILEN(data, coopLaunch, LAUNCH_ESC(float, __nv_bfloat16, numExperts, true), kernel, \
numBlocks, numThreads, smemSize, stream); \
} else if (data.mDtypeScore == tg::Dtype::Fp32 && data.mDtypeExpW == tg::Dtype::Bfloat16 && \
!extraFlag1) { \
LAUNCH_TILEN(data, coopLaunch, LAUNCH_ESC(float, __nv_bfloat16, numExperts, false), kernel, \
numBlocks, numThreads, smemSize, stream); \
} else if (data.mDtypeScore == tg::Dtype::Bfloat16 && data.mDtypeExpW == tg::Dtype::Fp32 && \
extraFlag1) { \
LAUNCH_TILEN(data, coopLaunch, LAUNCH_ESC(__nv_bfloat16, float, numExperts, true), kernel, \
numBlocks, numThreads, smemSize, stream); \
} else if (data.mDtypeScore == tg::Dtype::Bfloat16 && data.mDtypeExpW == tg::Dtype::Fp32 && \
!extraFlag1) { \
LAUNCH_TILEN(data, coopLaunch, LAUNCH_ESC(__nv_bfloat16, float, numExperts, false), kernel, \
numBlocks, numThreads, smemSize, stream); \
} else if (data.mDtypeScore == tg::Dtype::Bfloat16 && data.mDtypeExpW == tg::Dtype::Bfloat16 && \
extraFlag1) { \
LAUNCH_TILEN(data, coopLaunch, LAUNCH_ESC(__nv_bfloat16, __nv_bfloat16, numExperts, true), \
kernel, numBlocks, numThreads, smemSize, stream); \
} else if (data.mDtypeExpW == tg::Dtype::Bfloat16) { \
} else if (data.mDtypeScore == tg::Dtype::Bfloat16 && data.mDtypeExpW == tg::Dtype::Bfloat16 && \
!extraFlag1) { \
LAUNCH_TILEN(data, coopLaunch, LAUNCH_ESC(__nv_bfloat16, __nv_bfloat16, numExperts, false), \
kernel, numBlocks, numThreads, smemSize, stream); \
} else { \
FLASHINFER_WARN("Unsupported dtypeExpW"); \
FLASHINFER_WARN("Unsupported combination of mDtypeScore and mDtypeExpW"); \
}

////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
1 change: 1 addition & 0 deletions include/flashinfer/trtllm/fused_moe/RoutingKernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ namespace routingRenormalize {

struct Data : public DataBase {
tg::Dtype mDtypeExpW{tg::Dtype::Fp32};
tg::Dtype mDtypeScore{tg::Dtype::Fp32};
tg::Dtype mDtypeElt{tg::Dtype::Bfloat16};

bool mDoSoftmaxBeforeTopK{false};
Expand Down
6 changes: 3 additions & 3 deletions include/flashinfer/trtllm/fused_moe/runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,9 @@ class Runner {
int32_t* expandedIdxToPermutedIdx, int32_t* permutedIdxToExpandedIdx,
int32_t* permutedIdxToTokenIdx, void* expertWeights, int32_t* numTokensPerExpert,
int32_t* ctaIdxXyToBatchIdx, int32_t* ctaIdxXyToMnLimit, int32_t* numNonExitingCtas,
batchedGemm::trtllm::gen::Dtype dtypeElt, batchedGemm::trtllm::gen::Dtype dtypeBias,
bool useRoutingScalesOnInput, bool useDeepSeekFp8, RoutingMethodType routingMethodType,
cudaStream_t stream);
batchedGemm::trtllm::gen::Dtype dtypeScore, batchedGemm::trtllm::gen::Dtype dtypeElt,
batchedGemm::trtllm::gen::Dtype dtypeBias, bool useRoutingScalesOnInput,
bool useDeepSeekFp8, RoutingMethodType routingMethodType, cudaStream_t stream);

private:
int32_t mTileTokensDim{8};
Expand Down
1 change: 1 addition & 0 deletions tests/moe/test_dpsk_fused_moe_fp8.py
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,7 @@ def __init__(self):
activation_type=ActivationType.Swiglu,
num_tokens=seq_len,
hidden_size=7168, # DeepSeek-V3 hidden size
logits_dtype=torch.float32,
intermediate_size=intermediate_size,
)

Expand Down
53 changes: 40 additions & 13 deletions tests/moe/test_trtllm_gen_fused_moe.py
Original file line number Diff line number Diff line change
Expand Up @@ -1203,11 +1203,7 @@ def call_moe(
# Use autotuner for optimal kernel selection
with autotune(enable_autotune):
output = trtllm_fp8_per_tensor_scale_moe(
(
expert_logits.to(torch.bfloat16)
if routing_method_type == RoutingMethodType.Llama4
else expert_logits
),
expert_logits,
routing_bias,
hidden_states_fp8,
static_data["gemm1_weights"],
Expand Down Expand Up @@ -2347,6 +2343,7 @@ def run_moe_test(
weight_processing,
activation_type,
cache_permute_indices,
logits_dtype,
zero_hidden_states=False,
):
"""Common test logic for all routing methods."""
Expand All @@ -2358,6 +2355,7 @@ def run_moe_test(
num_tokens,
hidden_size,
intermediate_size,
logits_dtype,
zero_hidden_states=zero_hidden_states,
)

Expand Down Expand Up @@ -2388,14 +2386,9 @@ def run_moe_test(
assert top_k < (top_k_groups * num_experts / n_groups)

# Create test data based on routing method
if routing_method_type == RoutingMethodType.DeepSeekV3:
expert_logits = torch.randn((num_tokens, num_experts), device="cuda").to(
torch.float
)
else:
expert_logits = torch.randn((num_tokens, num_experts), device="cuda").to(
torch.bfloat16
)
expert_logits = torch.randn((num_tokens, num_experts), device="cuda").to(
logits_dtype
)

if routing_config["has_routing_bias"]:
routing_bias = torch.randn(num_experts, device="cuda", dtype=torch.bfloat16)
Expand Down Expand Up @@ -2671,6 +2664,13 @@ def run_moe_test(
pytest.param(ActivationType.Geglu, id="Geglu"),
],
)
@pytest.mark.parametrize(
"logits_dtype",
[
pytest.param(torch.float32, id="FP32_logits"),
pytest.param(torch.bfloat16, id="BF16_logits"),
],
)
def test_renormalize_routing(
num_tokens,
hidden_size,
Expand All @@ -2680,6 +2680,7 @@ def test_renormalize_routing(
weight_processing,
activation_type,
cache_permute_indices,
logits_dtype,
zero_hidden_states,
):
"""Test Renormalize routing configurations."""
Expand All @@ -2692,6 +2693,7 @@ def test_renormalize_routing(
weight_processing,
activation_type,
cache_permute_indices,
logits_dtype,
zero_hidden_states=zero_hidden_states,
)

Expand Down Expand Up @@ -2860,6 +2862,12 @@ def test_renormalize_routing(
pytest.param(ActivationType.Relu2, id="Relu2"),
],
)
@pytest.mark.parametrize(
"logits_dtype",
[
pytest.param(torch.float32, id="FP32_logits"),
],
)
def test_deepseekv3_routing(
num_tokens,
hidden_size,
Expand All @@ -2868,6 +2876,7 @@ def test_deepseekv3_routing(
routing_config,
weight_processing,
activation_type,
logits_dtype,
cache_permute_indices,
):
"""Test DeepSeekV3 routing configurations."""
Expand All @@ -2879,6 +2888,7 @@ def test_deepseekv3_routing(
routing_config,
weight_processing,
activation_type,
logits_dtype,
cache_permute_indices,
)

Expand Down Expand Up @@ -2935,6 +2945,13 @@ def test_deepseekv3_routing(
pytest.param(ActivationType.Geglu, id="Geglu"),
],
)
@pytest.mark.parametrize(
"logits_dtype",
[
pytest.param(torch.float32, id="FP32_logits"),
pytest.param(torch.bfloat16, id="BF16_logits"),
],
)
def test_topk_routing(
num_tokens,
hidden_size,
Expand All @@ -2943,6 +2960,7 @@ def test_topk_routing(
routing_config,
weight_processing,
activation_type,
logits_dtype,
cache_permute_indices,
):
"""Test TopK routing configuration."""
Expand All @@ -2955,6 +2973,7 @@ def test_topk_routing(
weight_processing,
activation_type,
cache_permute_indices,
logits_dtype,
)


Expand Down Expand Up @@ -3008,6 +3027,12 @@ def test_topk_routing(
pytest.param(ActivationType.Swiglu, id="Swiglu"),
],
)
@pytest.mark.parametrize(
"logits_dtype",
[
pytest.param(torch.bfloat16, id="BF16_logits"),
],
)
def test_llama4_routing(
num_tokens,
hidden_size,
Expand All @@ -3016,6 +3041,7 @@ def test_llama4_routing(
routing_config,
weight_processing,
activation_type,
logits_dtype,
cache_permute_indices,
):
"""Test Llama4 routing configuration with FP8 per-tensor."""
Expand All @@ -3028,4 +3054,5 @@ def test_llama4_routing(
weight_processing,
activation_type,
cache_permute_indices,
logits_dtype,
)
Loading
Loading