본문으로 건너뛰기

[sglang] SGLang: HPC-Ops 백엔드에서 BF16 디코딩을 위한 동적 스케줄링 도입

PR 링크: sgl-project/sglang#32304 상태: Merged | 변경: +73 / -38

들어가며

대규모 언어 모델(LLM) 서빙에서 디코딩 단계의 성능은 전체 처리량과 지연 시간에 큰 영향을 미칩니다. 특히 다양한 길이의 요청이 섞여 있을 때, 기존의 정적 Split-K 방식은 특정 시퀀스가 디코딩 지연 시간을 독점하는 문제를 야기했습니다. 이번 SGLang 업데이트에서는 Tencent의 HPC-Ops 커널을 활용하여, 기존 FP8에서만 지원하던 동적 스케줄링(Dynamic-scheduled) 기능을 BF16 디코딩까지 확장했습니다. 이를 통해 불균일한 KV 길이를 가진 환경에서 효율적인 태스크 분배가 가능해졌습니다.

코드 분석

1. hpc_ops_backend.py: 동적 스케줄링 로직 통합

핵심 변경 사항은 hpc.attention_decode_bf16 함수에 task_map을 전달하여 동적 스케줄링을 활성화하는 것입니다. _bf16_decode_supports_task_map 함수를 통해 설치된 hpc 패키지가 해당 기능을 지원하는지 런타임에 확인합니다.

# Before
o = hpc.attention_decode_bf16(
    q.view(-1, layer.tp_q_head_num, layer.head_dim),
    k_cache,
    # ... (생략)
    splitk=True,
)

# After
task_map_kwargs = (
    {"task_map": metadata.hpc_task_map}
    if metadata.hpc_task_map is not None
    else {}
)
o = hpc.attention_decode_bf16(
    # ... (생략)
    splitk=True,
    **task_map_kwargs,
)

또한, init_cuda_graph_state에서 _decode_task_map을 초기화하여, 요청된 배치 크기에 맞춰 태스크를 동적으로 할당할 수 있도록 구조를 개선했습니다.

2. 하드웨어 제약 조건 강화

HPC-Ops 커널이 현재 SM90(Hopper) 아키텍처에 최적화되어 있다는 점을 반영하여, 런타임에 아키텍처를 확인하고 지원하지 않는 GPU에서는 명시적인 에러를 발생시키도록 변경되었습니다.

major, minor = torch.cuda.get_device_capability()
if major != 9:
    raise ValueError(
        "The hpc_ops attention backend requires an SM90 (Hopper) GPU "
        f"(the HPC-Ops kernels ship sm90a only), got sm{major}{minor}."
    )

왜 이게 좋은가

이번 최적화의 핵심은 '불균일한 시퀀스 길이 처리'에 있습니다. 기존 정적 Split-K 방식은 모든 CTA(Cooperative Thread Array)가 동일한 작업을 수행하도록 강제했으나, 동적 스케줄링은 KV 캐시의 길이에 따라 태스크를 재분배합니다.

실제 H200 GPU 환경에서 벤치마크 결과, 배치 사이즈 1에서 디코딩 토큰 처리량이 4.3% 향상되었으며, 혼합된 길이의 요청 처리 시 평균 지연 시간이 2.8% 감소하는 성과를 거두었습니다. 이는 특히 실시간 추론 서비스에서 P99 지연 시간을 개선하는 데 매우 효과적입니다.

교훈

  1. 런타임 기능 감지: inspect.signature를 활용하여 라이브러리의 버전에 따라 기능을 유연하게 활성화하는 패턴은 하위 호환성을 유지하는 좋은 예시입니다.
  2. Early Failure: 하드웨어 제약이 명확한 커널의 경우, 런타임 초기화 단계에서 아키텍처를 체크하여 불필요한 에러를 방지하는 것이 운영 안정성에 필수적입니다.

리뷰어 피드백 반영

리뷰 과정에서 HPC-Ops 커널이 현재 SM90 전용임을 명확히 하라는 피드백이 있었습니다. 이에 따라 hpc_ops_backend.pymoe_runner 양쪽 모두에 아키텍처 가드를 추가하고, 관련 문서의 "Hopper+ (SM90+)" 표현을 "Hopper (SM90) only"로 수정하여 사용자 혼선을 방지했습니다.

참고 자료

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

댓글

관련 포스트

PR Analysis 의 다른글