본문으로 건너뛰기

[vllm] vLLM에서 Flashinfer 기반 Non-gated MoE bf16 지원 최적화 분석

PR 링크: vllm-project/vllm#43853 상태: Merged | 변경: +30 / -8

들어가며

vLLM은 대규모 언어 모델 서빙을 위한 고성능 엔진으로, 특히 Mixture-of-Experts(MoE) 모델의 효율적인 실행을 위해 다양한 커널 백엔드를 지원합니다. 기존의 vLLM은 BF16 데이터 타입의 Non-gated MoE 모델에 대해 제한적인 지원을 제공했으나, 이번 PR을 통해 Flashinfer-TRTLLM 백엔드를 활용한 최적화된 경로가 추가되었습니다. 이 변경은 특히 sm100 아키텍처에서 약 15%의 End-to-End 성능 향상을 가져옵니다.

코드 분석

1. trtllm_bf16_moe.py: 커널 지원 확장

기존에는 BF16 커널이 Non-gated MoE를 지원하지 않았으나, RELU2_NO_MUL 활성화 함수를 도입하여 이를 가능하게 했습니다.

# Before
@staticmethod
def _supports_no_act_and_mul() -> bool:
    return False

# After
@staticmethod
def _supports_no_act_and_mul() -> bool:
    return True

또한 apply 함수 내에서 activation_type을 Flashinfer가 이해할 수 있는 정수 형태로 변환하여 전달하도록 수정되었습니다.

2. unquantized.py: 가중치 정렬 및 패딩

Flashinfer 커널은 특정 블록 크기(BlockMajorK, 128) 정렬을 요구합니다. Non-gated MoE의 경우 중간 차원(intermediate_size)이 이 정렬을 만족하지 못할 때 성능 저하가 발생할 수 있어, 이를 자동으로 패딩하는 로직이 추가되었습니다.

# After
if not is_act_and_mul:
    w13_weight, w2_weight, padded_intermediate = align_moe_weights_for_fi(
        w13_weight, w2_weight, is_act_and_mul, min_alignment=128
    )
    layer.moe_config.intermediate_size_per_partition = padded_intermediate

3. flashinfer_utils.py: 범용 정렬 함수로 통합

기존의 FP8 전용 정렬 함수를 일반화하여 align_moe_weights_for_fi로 통합했습니다. 이는 코드 중복을 줄이고 유지보수성을 높였습니다.

왜 이게 좋은가

이번 최적화의 핵심은 하드웨어 가속기(Flashinfer)의 메모리 레이아웃 요구사항을 모델 가중치 로딩 단계에서 미리 충족시킨 점입니다.

  1. 성능 향상: 벤치마크 결과, 기존 Triton 백엔드 대비 약 15%의 처리량(throughput) 향상을 보였습니다. 이는 커널 실행 시 발생하는 정렬 오버헤드를 제거했기 때문입니다.
  2. 유연성: RELU2_NO_MUL 지원을 통해 더 다양한 MoE 아키텍처를 수용할 수 있게 되었습니다.
  3. 교훈: 고성능 커널(Flashinfer 등)을 사용할 때는 데이터 정렬(Alignment)이 성능의 병목이 되는 경우가 많습니다. 이를 런타임에 처리하기보다 모델 로드 시점에 미리 패딩하여 최적화하는 전략은 대규모 모델 서빙에서 매우 유효한 패턴입니다.

리뷰 피드백 반영

리뷰 과정에서 is_act_and_mul 여부에 따른 패딩 로직이 논의되었습니다. 초기에는 모든 경우에 128 패딩을 적용하려 했으나, 리뷰어들의 의견을 반영하여 Non-gated MoE에만 선택적으로 적용하도록 수정하여 불필요한 메모리 낭비를 방지했습니다.

참고 자료

⚠️ 알림: 이 분석은 AI가 실제 코드 diff를 기반으로 작성했습니다.

댓글

관련 포스트

PR Analysis 의 다른글