#020

moe_count_and_sort

int32 vllm · both · vllm::moe::count_and_sort_expert_tokens_kernel via vllm.moe_align_block_size · importance 0.5%

Reference Implementation

reference.py
import torch
import torch.nn as nn

class Model(nn.Module):

    def __init__(self, num_experts: int=128, block_size: int=128) -> None:
        super().__init__()
        self.num_experts = int(num_experts)
        self.block_size = int(block_size)

    def forward(self, topk_ids: torch.Tensor) -> dict[str, torch.Tensor]:
        flat_ids = topk_ids.flatten()
        counts = torch.bincount(flat_ids.to(torch.long), minlength=self.num_experts)[:self.num_experts].to(torch.int32)
        cumsum = torch.empty(self.num_experts + 1, dtype=torch.int32, device=topk_ids.device)
        cumsum[0] = 0
        cumsum[1:] = torch.cumsum(counts, dim=0)
        sorted_chunks = []
        for expert in range(self.num_experts):
            token_ids = torch.nonzero(flat_ids == expert, as_tuple=False).flatten().to(torch.int32)
            if token_ids.numel():
                sorted_chunks.append(token_ids)
        if sorted_chunks:
            sorted_token_ids = torch.cat(sorted_chunks)
        else:
            sorted_token_ids = torch.empty((0,), dtype=torch.int32, device=topk_ids.device)
        return {'sorted_token_ids': sorted_token_ids, 'expert_token_counts': counts, 'cumsum': cumsum}

Shapes

TSOL hardware:
# token_counttop_knum_experts TSOL(XPU-A)TProdS
0 18128 0.00 us 12.80 us 0.0%
1 768128 0.00 us 12.70 us 0.0%
2 5208128 0.01 us 16.60 us 0.1%
3 10198128 0.01 us 18.80 us 0.1%
4 20448128 0.02 us 21.20 us 0.1%

Input Generation

input.py
import torch

def _make_inputs(token_count: int, top_k: int, num_experts: int) -> dict[str, torch.Tensor]:
    topk_ids = torch.randint(0, int(num_experts), (int(token_count), int(top_k)), dtype=torch.int32, device='cuda')
    return {'topk_ids': topk_ids}