[sglang] H200 NVL에서 Qwen3.8-Flash-Next FP8 성능 극대화하기: Fused MoE Triton 설정 최적화
PR 링크: sgl-project/sglang#38116 상태: Merged | 변경: +147 / -0
들어가며
LLM(Large Language Model) 서비스의 효율성을 결정짓는 핵심 요소 중 하나는 하드웨어 가속기를 얼마나 극한까지 활용하느냐에 있습니다. 특히 MoE(Mixture of Experts) 구조를 가진 모델은 전문가(Expert) 선택과 연산 과정에서 발생하는 오버헤드가 크기 때문에, 커널 수준의 최적화가 필수적입니다.
최근 SGLang 프로젝트에 반영된 한 PR은 NVIDIA의 최신 워크스테이션급 GPU인 H200 NVL 환경에서 Qwen/Qwen3.8-Flash-Next-FP8 모델을 서빙할 때 발생하는 성능 저하 문제를 해결했습니다. 기존 시스템은 H200 NVL을 일반적인 H200 SXM 모델과 다르게 인식하여 최적화된 설정을 찾지 못하고 성능이 낮은 '기본 휴리스틱(Default Heuristic)' 설정을 사용하고 있었습니다.
이 글에서는 Triton 커널 튜닝을 통해 어떻게 Decode 단계의 성능을 최대 23%까지 끌어올렸는지, 코드 변경 사항과 벤치마크 결과를 통해 살펴보겠습니다.
코드 분석: 무엇이 바뀌었는가?
1. 모델 인식 로직 개선 (common_utils.py)
가장 먼저 해결해야 할 문제는 튜너(Tuner)가 Qwen의 최신 모델 타입을 인식하지 못해 Mixtral의 기본 로직으로 빠지는 현상이었습니다. 이로 인해 num_local_experts 속성을 찾지 못하는 AttributeError가 발생하고 있었습니다.
Before:
# benchmark/kernels/fused_moe_triton/common_utils.py
if model_type in [
"Qwen2MoeForCausalLM",
"Qwen2_5MoeForCausalLM",
"Qwen3VLMoeForConditionalGeneration",
"Qwen3_5MoeForCausalLM",
"Qwen3_5MoeForConditionalGeneration",
"InternS2PreviewForConditionalGeneration",
"MellumForCausalLM",
]:
# Qwen specific logic...
After:
# benchmark/kernels/fused_moe_triton/common_utils.py
if model_type in [
"Qwen2MoeForCausalLM",
"Qwen2_5MoeForCausalLM",
"Qwen3VLMoeForConditionalGeneration",
"Qwen3_5MoeForCausalLM",
"Qwen3_5MoeForConditionalGeneration",
"Qwen4ExpForConditionalGeneration", # 추가됨
"InternS2PreviewForConditionalGeneration",
"MellumForCausalLM",
]:
# Qwen specific logic...
Qwen4ExpForConditionalGeneration (내부적으로 qwen4_exp 타입 사용)을 명시적으로 추가함으로써, 튜너가 올바른 전문가 수(E)와 중간 크기(N)를 계산할 수 있게 되었습니다. 이 PR에서는 E=256, N=640이라는 구체적인 형상을 도출해냈습니다.
2. H200 NVL 전용 Triton 설정 파일 추가
이 PR의 핵심은 튜닝된 하이퍼파라미터를 담은 JSON 설정 파일입니다. 기존에는 NVIDIA_H200 설정만 존재했으나, 실제 디바이스 이름이 NVIDIA_H200_NVL로 보고되면서 이를 찾지 못하는 문제가 있었습니다.
새로 추가된 설정 파일(E=256,N=640,device_name=NVIDIA_H200_NVL...json)의 내용을 보면, 배치 사이즈(M)에 따라 최적의 블록 크기와 워프(Warp) 수를 정의하고 있습니다.
Tuned Config Snippet (M=16):
"16": {
"BLOCK_SIZE_M": 16,
"BLOCK_SIZE_N": 64,
"BLOCK_SIZE_K": 128,
"GROUP_SIZE_M": 1,
"num_warps": 4,
"num_stages": 3
},
기존의 기본값(Heuristic)은 보통 BLOCK_SIZE_M=64를 사용했습니다. 하지만 튜닝된 결과에서는 작은 배치 사이즈(M ≤ 256)에서 BLOCK_SIZE_M=16을 사용하도록 설정되었습니다.
왜 이게 좋은 최적화인가?
1. Decode 단계의 효율성 극대화
LLM 추론은 크게 Prefill(입력 토큰 처리)과 Decode(다음 토큰 생성) 단계로 나뉩니다. Decode 단계는 배치 사이즈(M)가 상대적으로 작습니다.
기존의 기본 설정인 BLOCK_SIZE_M=64를 사용하면, 실제 처리할 토큰이 16개뿐이라도 64개 분량의 타일(Tile)을 할당하게 되어 연산 자원이 낭비됩니다. 이번 최적화에서 BLOCK_SIZE_M을 16으로 낮춤으로써, 작은 배치에서도 GPU의 SM(Streaming Multiprocessor) 점유율을 높이고 불필요한 패딩 연산을 줄였습니다.
2. 하드웨어 특성 반영 (H200 NVL)
H200 NVL은 SXM 버전과 메모리 대역폭이나 전력 프로필이 미세하게 다를 수 있습니다. 단순히 "H200이니까 똑같겠지"라고 가정하지 않고, 실제 디바이스 이름(NVIDIA_H200_NVL)에 맞춰 별도의 튜닝 값을 제공한 것은 엔지니어링 측면에서 매우 정교한 접근입니다.
3. 실질적인 성능 향상 수치
PR에 포함된 벤치마크 결과는 놀랍습니다.
| Batch (M) | Default µs | Tuned µs | Speedup |
|---|---|---|---|
| 1 | 30.40 | 26.76 | 1.14x |
| 16 | 203.57 | 166.79 | 1.22x |
| 48 | 352.75 | 285.90 | 1.23x |
| 256 | 430.73 | 362.01 | 1.19x |
특히 실시간 서빙에서 가장 중요한 구간인 M ≤ 256 범위에서 14% ~ 23%의 속도 향상을 보였습니다. Prefill 구간(M ≥ 1024)에서는 기본 설정과 수렴하며 1~5%의 이득을 보는데, 이는 대규모 배치에서는 이미 타일 효율이 충분히 높기 때문입니다.
리뷰 피드백 및 교훈
리뷰어 pinkgom은 CI 테스트가 실행되지 않는 문제를 지적하며 run-ci 라벨 추가를 요청했습니다. 또한, 이 PR이 단순히 설정값만 추가하는 것이 아니라 튜너가 새로운 모델 구조(Qwen4Exp)를 인식할 수 있게 한 점을 높게 평가했습니다.
이 사례를 통해 얻을 수 있는 교훈은 다음과 같습니다:
- Heuristic은 만능이 아니다: 라이브러리가 제공하는 기본값은 안전하지만 최적은 아닙니다. 실제 프로덕션 환경의 하드웨어와 모델 형상에 맞는 전용 튜닝이 필요합니다.
- 디바이스 네이밍의 중요성: 하드웨어 드라이버가 보고하는 정확한
device_name을 확인하고, 설정 파일의 매칭 로직이 이를 지원하는지 점검해야 합니다. - 작은 배치의 최적화: LLM 서빙의 병목은 종종 Decode 단계에서 발생하며, 타일 크기를 줄이는 것만으로도 큰 이득을 볼 수 있습니다.
SGLang과 같은 고성능 추론 엔진에서 이러한 세밀한 커널 설정 최적화는 사용자 경험(Latency)과 운영 비용(Throughput) 모두에 직접적인 영향을 미치는 매우 가치 있는 작업입니다.
참고 자료
- https://triton-lang.org/main/index.html
- https://github.com/sgl-project/sglang
- https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#fused-operations
⚠️ 알림: 이 분석은 AI가 실제 코드 diff를 기반으로 작성했습니다.
관련 포스트
- [sglang] SGLang에서 Qwen3-Next FP8 MoE 최적화: H200을 위한 Shared-Expert Fusion
- [sglang] SGLang: LFM2-MoE 모델을 위한 SM90 커널 퓨전 최적화 분석
- [sglang] [MoE] SwiGLU 퓨전: Triton 커널 최적화로 메모리 대역폭 한계 돌파하기
- [sglang] [SGLang] MoE Prefill의 혁신: DWDP(Distributed Weight Data Parallelism) 도입 분석
- [sglang] SGLang DFlash 최적화: 호스트-디바이스 동기화 제거를 통한 추론 성능 향상
PR Analysis 의 다른글
- 이전글 [ultralytics] Ultralytics YOLO에 INT8 Quantization-Aware Training(QAT) 도입하기
- 현재글 : [sglang] H200 NVL에서 Qwen3.8-Flash-Next FP8 성능 극대화하기: Fused MoE Triton 설정 최적화
- 다음글 [vllm] vLLM Qwen3.8-Flash-Next: QSA Indexer 캐시를 위한 FP8 지원으로 메모리 효율 및 성능 최적화
댓글