Add various optimizations and Mega MoE benchmarks (#316)
* Merge with private repo * Add Mega MoE Benchmark * Minor fix * Update --------- Co-authored-by: Chenggang Zhao <chenggangz@deepseek.com>
This commit is contained in:
@@ -29,6 +29,7 @@ public:
|
||||
|
||||
// Runtime arguments
|
||||
void* y;
|
||||
int* cumulative_local_expert_recv_stats;
|
||||
int num_tokens;
|
||||
layout::SymBuffer<> sym_buffer_ptrs;
|
||||
|
||||
@@ -91,6 +92,7 @@ static void __instantiate_kernel() {{
|
||||
// TODO: optimize `args` copy
|
||||
DG_CUDA_UNIFIED_CHECK(launch_kernel(kernel, config,
|
||||
args.y,
|
||||
args.cumulative_local_expert_recv_stats,
|
||||
args.num_tokens,
|
||||
args.sym_buffer_ptrs,
|
||||
args.tensor_map_l1_acts,
|
||||
@@ -112,6 +114,7 @@ static void sm100_fp8_fp4_mega_moe(
|
||||
const torch::Tensor& l2_acts, const torch::Tensor& l2_acts_sf,
|
||||
const torch::Tensor& l1_weights, const torch::Tensor& l2_weights,
|
||||
const torch::Tensor& l1_weights_sf, const torch::Tensor& l2_weights_sf,
|
||||
const std::optional<torch::Tensor> cumulative_local_expert_recv_stats,
|
||||
const std::vector<int64_t>& sym_buffer_ptrs,
|
||||
const int& rank_idx, const int& num_max_tokens_per_rank,
|
||||
const int& num_experts_per_rank,
|
||||
@@ -122,11 +125,12 @@ static void sm100_fp8_fp4_mega_moe(
|
||||
) {
|
||||
const auto num_ranks = static_cast<int>(sym_buffer_ptrs.size());
|
||||
const auto num_experts = num_experts_per_rank * num_ranks;
|
||||
const auto num_padded_sf_pool_tokens = static_cast<int>(l1_acts_sf.size(0));
|
||||
|
||||
// Heuristics
|
||||
const auto config = get_mega_moe_config(
|
||||
num_ranks, num_experts, num_experts_per_rank,
|
||||
num_max_tokens_per_rank, num_tokens, num_topk, hidden, intermediate_hidden);
|
||||
num_max_tokens_per_rank, num_tokens, num_topk, hidden, intermediate_hidden, num_padded_sf_pool_tokens);
|
||||
|
||||
// Make tensormap
|
||||
constexpr int kGranK = 32;
|
||||
@@ -175,6 +179,11 @@ static void sm100_fp8_fp4_mega_moe(
|
||||
config.block_n, kGranK,
|
||||
num_experts_per_rank, 0);
|
||||
|
||||
// Stats can be optional
|
||||
int* cumulative_local_expert_recv_stats_ptr = nullptr;
|
||||
if (cumulative_local_expert_recv_stats.has_value())
|
||||
cumulative_local_expert_recv_stats_ptr = cumulative_local_expert_recv_stats->data_ptr<int>();
|
||||
|
||||
// Launch
|
||||
const auto num_sms = device_runtime->get_num_sms();
|
||||
const SM100FP8FP4MegaMoERuntime::Args args = {
|
||||
@@ -186,6 +195,7 @@ static void sm100_fp8_fp4_mega_moe(
|
||||
.fast_math = fast_math,
|
||||
.config = config,
|
||||
.y = y.data_ptr(),
|
||||
.cumulative_local_expert_recv_stats = cumulative_local_expert_recv_stats_ptr,
|
||||
.num_tokens = num_tokens,
|
||||
.sym_buffer_ptrs = layout::SymBuffer<>(sym_buffer_ptrs, rank_idx),
|
||||
.tensor_map_l1_acts = tensor_map_l1_acts,
|
||||
|
||||
@@ -14,11 +14,13 @@ public:
|
||||
int aligned_batch_size;
|
||||
int split_kv;
|
||||
int num_sms;
|
||||
|
||||
bool is_varlen;
|
||||
|
||||
int batch_size;
|
||||
int next_n;
|
||||
bool is_context_lens_2d;
|
||||
int* context_lens;
|
||||
int* indices;
|
||||
int* schedule_metadata;
|
||||
|
||||
LaunchArgs launch_args;
|
||||
@@ -32,10 +34,10 @@ using namespace deep_gemm;
|
||||
|
||||
static void __instantiate_kernel() {{
|
||||
auto ptr = reinterpret_cast<void*>(&sched::smxx_paged_mqa_logits_metadata<
|
||||
{}, {}, {}
|
||||
{}, {}, {}, {}
|
||||
>);
|
||||
}};
|
||||
)", args.aligned_batch_size, args.split_kv, args.num_sms);
|
||||
)", args.aligned_batch_size, args.split_kv, args.num_sms, args.is_varlen ? "true" : "false");
|
||||
}
|
||||
|
||||
static void launch_impl(const KernelHandle& kernel, const LaunchConfigHandle& config, Args args) {
|
||||
@@ -44,6 +46,7 @@ static void __instantiate_kernel() {{
|
||||
args.next_n,
|
||||
args.is_context_lens_2d,
|
||||
args.context_lens,
|
||||
args.indices,
|
||||
args.schedule_metadata
|
||||
));
|
||||
}
|
||||
@@ -53,14 +56,15 @@ static void smxx_paged_mqa_logits_metadata(const torch::Tensor& context_lens,
|
||||
const torch::Tensor& schedule_metadata,
|
||||
const int& batch_size, const int& next_n,
|
||||
const int& block_kv, const int& num_sms,
|
||||
const bool& is_context_lens_2d) {
|
||||
const bool& is_context_lens_2d,
|
||||
const bool& is_varlen, const int* indices_ptr) {
|
||||
constexpr int split_kv = 256;
|
||||
constexpr int num_threads = 32;
|
||||
const int aligned_batch_size = align(batch_size, 32);
|
||||
DG_HOST_ASSERT(split_kv % block_kv == 0);
|
||||
|
||||
// Calculate shared memory size
|
||||
const int smem_size = aligned_batch_size * static_cast<int>(sizeof(int));
|
||||
// Shared memory: prefix_sum[kAlignedBatchSize] + varlen_atom_token_start/context_len[kAlignedBatchSize] + varlen_num_atoms
|
||||
const int smem_size = (3 * aligned_batch_size + 1) * static_cast<int>(sizeof(int));
|
||||
DG_HOST_ASSERT(smem_size <= SM90ArchSpec::smem_capacity);
|
||||
DG_HOST_ASSERT(smem_size <= SM100ArchSpec::smem_capacity);
|
||||
|
||||
@@ -69,10 +73,12 @@ static void smxx_paged_mqa_logits_metadata(const torch::Tensor& context_lens,
|
||||
.aligned_batch_size = aligned_batch_size,
|
||||
.split_kv = split_kv,
|
||||
.num_sms = num_sms,
|
||||
.is_varlen = is_varlen,
|
||||
.batch_size = batch_size,
|
||||
.next_n = next_n,
|
||||
.is_context_lens_2d = is_context_lens_2d,
|
||||
.context_lens = context_lens.data_ptr<int>(),
|
||||
.indices = const_cast<int*>(indices_ptr),
|
||||
.schedule_metadata = schedule_metadata.data_ptr<int>(),
|
||||
.launch_args = LaunchArgs(1, num_threads, smem_size)
|
||||
};
|
||||
@@ -90,6 +96,7 @@ public:
|
||||
int head_dim;
|
||||
int block_kv;
|
||||
bool is_context_lens_2d;
|
||||
bool is_varlen;
|
||||
int block_table_stride;
|
||||
int logits_stride;
|
||||
|
||||
@@ -100,6 +107,7 @@ public:
|
||||
int* context_lens;
|
||||
void* logits;
|
||||
int* block_table;
|
||||
int* indices;
|
||||
int* schedule_meta;
|
||||
|
||||
CUtensorMap tensor_map_q;
|
||||
@@ -129,7 +137,7 @@ static void __instantiate_kernel() {{
|
||||
auto ptr = reinterpret_cast<void*>(&sm{}_fp8_paged_mqa_logits<
|
||||
{}, {},
|
||||
{}, {},
|
||||
{},
|
||||
{}, {},
|
||||
{}, {},
|
||||
{},
|
||||
{}, {},
|
||||
@@ -139,7 +147,7 @@ static void __instantiate_kernel() {{
|
||||
)", arch, arch,
|
||||
args.next_n, args.num_heads,
|
||||
args.head_dim, args.block_kv,
|
||||
args.is_context_lens_2d,
|
||||
args.is_context_lens_2d, args.is_varlen ? "true" : "false",
|
||||
args.num_q_stages, args.num_kv_stages,
|
||||
args.split_kv,
|
||||
args.num_specialized_threads, args.num_math_threads,
|
||||
@@ -151,7 +159,7 @@ static void __instantiate_kernel() {{
|
||||
args.batch_size,
|
||||
args.logits_stride, args.block_table_stride,
|
||||
args.context_lens, args.logits,
|
||||
args.block_table, args.schedule_meta,
|
||||
args.block_table, args.indices, args.schedule_meta,
|
||||
args.tensor_map_q, args.tensor_map_kv,
|
||||
args.tensor_map_kv_scales, args.tensor_map_weights
|
||||
));
|
||||
@@ -165,12 +173,14 @@ static void smxx_fp8_paged_mqa_logits(const torch::Tensor& q,
|
||||
const torch::Tensor& context_lens,
|
||||
const torch::Tensor& logits,
|
||||
const torch::Tensor& block_table,
|
||||
const torch::Tensor& indices,
|
||||
const torch::Tensor& schedule_meta,
|
||||
const at::ScalarType& logits_dtype,
|
||||
const int& batch_size, const int& next_n,
|
||||
const int& num_heads, const int& head_dim,
|
||||
const int& num_kv_blocks, const int& block_kv,
|
||||
const bool& is_context_lens_2d,
|
||||
const bool& is_varlen,
|
||||
const int& logits_stride,
|
||||
const int& block_table_stride,
|
||||
const int& num_sms,
|
||||
@@ -183,7 +193,7 @@ static void smxx_fp8_paged_mqa_logits(const torch::Tensor& q,
|
||||
DG_HOST_ASSERT(split_kv % mma_m == 0 and logits_stride % split_kv == 0);
|
||||
|
||||
// Construct TMAs
|
||||
const int next_n_atom = (next_n % 2 == 0) ? 2 : 1;
|
||||
const int next_n_atom = (is_varlen or next_n >= 2) ? 2 : 1;
|
||||
const auto tensor_map_q = make_tma_2d_desc(q, head_dim, batch_size * next_n * num_heads,
|
||||
head_dim, next_n_atom * num_heads,
|
||||
static_cast<int>(q.stride(2)),
|
||||
@@ -245,6 +255,7 @@ static void smxx_fp8_paged_mqa_logits(const torch::Tensor& q,
|
||||
.head_dim = head_dim,
|
||||
.block_kv = block_kv,
|
||||
.is_context_lens_2d = is_context_lens_2d,
|
||||
.is_varlen = is_varlen,
|
||||
.block_table_stride = block_table_stride,
|
||||
.logits_stride = logits_stride,
|
||||
.num_q_stages = num_q_stages,
|
||||
@@ -253,6 +264,7 @@ static void smxx_fp8_paged_mqa_logits(const torch::Tensor& q,
|
||||
.context_lens = context_lens.data_ptr<int>(),
|
||||
.logits = logits.data_ptr(),
|
||||
.block_table = block_table.data_ptr<int>(),
|
||||
.indices = is_varlen ? indices.data_ptr<int>() : nullptr,
|
||||
.schedule_meta = schedule_meta.data_ptr<int>(),
|
||||
.tensor_map_q = tensor_map_q,
|
||||
.tensor_map_kv = tensor_map_kv,
|
||||
@@ -279,6 +291,7 @@ public:
|
||||
int head_dim;
|
||||
int block_kv;
|
||||
bool is_context_lens_2d;
|
||||
bool is_varlen;
|
||||
int block_table_stride;
|
||||
int logits_stride;
|
||||
|
||||
@@ -289,6 +302,7 @@ public:
|
||||
int* context_lens;
|
||||
void* logits;
|
||||
int* block_table;
|
||||
int* indices;
|
||||
int* schedule_meta;
|
||||
|
||||
CUtensorMap tensor_map_q;
|
||||
@@ -314,7 +328,7 @@ static void __instantiate_kernel() {{
|
||||
auto ptr = reinterpret_cast<void*>(&sm100_fp4_paged_mqa_logits<
|
||||
{}, {},
|
||||
{}, {},
|
||||
{},
|
||||
{}, {},
|
||||
{}, {},
|
||||
{},
|
||||
{}, {},
|
||||
@@ -323,7 +337,7 @@ static void __instantiate_kernel() {{
|
||||
}};
|
||||
)", args.next_n, args.num_heads,
|
||||
args.head_dim, args.block_kv,
|
||||
args.is_context_lens_2d,
|
||||
args.is_context_lens_2d, args.is_varlen ? "true" : "false",
|
||||
args.num_q_stages, args.num_kv_stages,
|
||||
args.split_kv,
|
||||
args.num_specialized_threads, args.num_math_threads,
|
||||
@@ -335,7 +349,7 @@ static void __instantiate_kernel() {{
|
||||
args.batch_size,
|
||||
args.logits_stride, args.block_table_stride,
|
||||
args.context_lens, args.logits,
|
||||
args.block_table, args.schedule_meta,
|
||||
args.block_table, args.indices, args.schedule_meta,
|
||||
args.tensor_map_q, args.tensor_map_sf_q,
|
||||
args.tensor_map_kv, args.tensor_map_sf_kv,
|
||||
args.tensor_map_weights
|
||||
@@ -351,12 +365,14 @@ static void sm100_fp4_paged_mqa_logits(const torch::Tensor& q,
|
||||
const torch::Tensor& context_lens,
|
||||
const torch::Tensor& logits,
|
||||
const torch::Tensor& block_table,
|
||||
const torch::Tensor& indices,
|
||||
const torch::Tensor& schedule_meta,
|
||||
const at::ScalarType& logits_dtype,
|
||||
const int& batch_size, const int& next_n,
|
||||
const int& num_heads, const int& head_dim,
|
||||
const int& num_kv_blocks, const int& block_kv,
|
||||
const bool& is_context_lens_2d,
|
||||
const bool& is_varlen,
|
||||
const int& logits_stride,
|
||||
const int& block_table_stride,
|
||||
const int& num_sms,
|
||||
@@ -366,8 +382,8 @@ static void sm100_fp4_paged_mqa_logits(const torch::Tensor& q,
|
||||
DG_HOST_ASSERT(split_kv == 256 and logits_stride % split_kv == 0);
|
||||
|
||||
// TODO: tuning num_stages
|
||||
const int num_q_stages = 3, num_kv_stages = 6, num_tmem_stages = 3;
|
||||
const int next_n_atom = (next_n % 2 == 0) ? 2 : 1;
|
||||
const int num_q_stages = 3, num_kv_stages = 10, num_tmem_stages = 3;
|
||||
const int next_n_atom = (is_varlen or next_n >= 2) ? 2 : 1;
|
||||
|
||||
// `head_dim` must be 128 for 64B swizzling
|
||||
DG_HOST_ASSERT(head_dim == 128);
|
||||
@@ -416,6 +432,7 @@ static void sm100_fp4_paged_mqa_logits(const torch::Tensor& q,
|
||||
.head_dim = head_dim,
|
||||
.block_kv = block_kv,
|
||||
.is_context_lens_2d = is_context_lens_2d,
|
||||
.is_varlen = is_varlen,
|
||||
.block_table_stride = block_table_stride,
|
||||
.logits_stride = logits_stride,
|
||||
.num_q_stages = num_q_stages,
|
||||
@@ -424,6 +441,7 @@ static void sm100_fp4_paged_mqa_logits(const torch::Tensor& q,
|
||||
.context_lens = context_lens.data_ptr<int>(),
|
||||
.logits = logits.data_ptr(),
|
||||
.block_table = block_table.data_ptr<int>(),
|
||||
.indices = is_varlen ? indices.data_ptr<int>() : nullptr,
|
||||
.schedule_meta = schedule_meta.data_ptr<int>(),
|
||||
.tensor_map_q = tensor_map_q,
|
||||
.tensor_map_sf_q = tensor_map_sf_q,
|
||||
|
||||
Reference in New Issue
Block a user