#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_count | top_k | num_experts | TProd | S |
| 0 | 1 | 8 | 128 | 0.00 us | 12.80 us | 0.0% |
| 1 | 76 | 8 | 128 | 0.00 us | 12.70 us | 0.0% |
| 2 | 520 | 8 | 128 | 0.01 us | 16.60 us | 0.1% |
| 3 | 1019 | 8 | 128 | 0.01 us | 18.80 us | 0.1% |
| 4 | 2044 | 8 | 128 | 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}