gpu-serving

2 개의 포스트

kakao

음성 AI 모델을 프로덕션에 올리기까지: Kanana-O 서빙 최적화 여정 (새 탭에서 열림)

Kanana-O를 실시간 음성 대화 서비스로 제공하려면 모델 학습과는 별개의 서빙 최적화가 필요하다. 카카오는 Thinker·Talker·VoiceBox로 구성된 파이프라인에 특화된 Kanana-Omni Server를 구축해 임베딩 전달, 스트리밍 지연, 프로세스 안정성, 동시 요청 처리 문제를 해결했다. 그 결과 동시 사용자 64명 기준으로 vllm-omni 대비 상대 처리량 1.6배를 달성했다. ## Kanana-O의 멀티모달 음성 생성 구조 - **Thinker**는 텍스트·이미지·오디오 입력을 이해하고 텍스트를 생성하는 대형 언어 모델이다. - **Talker**는 Thinker의 텍스트 임베딩을 받아 음성 토큰을 순차적으로 생성한다. - **VoiceBox**는 음성 토큰을 실제 오디오 파형으로 변환한다. - 프로덕션 환경에서는 다음 조건을 동시에 만족해야 한다. - 수백 밀리초 안에 첫 음성을 제공해야 한다. - 여러 사용자의 요청을 동시에 처리해야 한다. - 텍스트와 오디오를 끊김 없이 스트리밍해야 한다. - 각 모델의 GPU 메모리 요구량 차이를 관리해야 한다. ## 범용 멀티모달 서빙 프레임워크의 한계 - Thinker가 Talker에 전달하는 값은 토큰 ID가 아니라 수천 차원의 **히든 스테이트 임베딩**이다. - 임베딩을 직렬화하거나 CPU로 복사하면 지연이 커지므로 GPU 메모리 주소를 직접 공유하는 zero-copy 방식이 필요했다. - Talker는 매 스텝 음성 토큰을 생성하지만 VoiceBox는 일정량의 토큰이 쌓인 뒤 청크 단위로 소비한다. - Talker의 입력에는 다음 값이 누적된다. - 화자 특성을 나타내는 스피커 임베딩 - Thinker의 출력 임베딩 - 이전 스텝에서 생성한 음성 임베딩 - 이처럼 생산자와 소비자의 속도가 다르고 입력 길이가 계속 증가하는 구조는 일반적인 LLM 서빙 패턴과 맞지 않았다. - 자체 서버를 구축한 결과 상대 처리량은 다음과 같았다. - naive 구현: 0.44 - vllm-omni: 1 - Kanana-Omni Server: 1.6 ## 공유 메모리와 CUDA IPC를 활용한 데이터 전달 - 프로세스 간 임베딩 전달을 매번 직렬화·역직렬화하면 토큰마다 큰 오버헤드가 발생한다. - 서버 시작 시 OS 레벨에서 공유 메모리 블록을 미리 할당해 런타임 할당·해제를 제거했다. - Thinker는 공유 메모리 풀의 블록에 데이터를 쓰고, Talker에는 실제 데이터 대신 블록 번호와 크기 같은 메타데이터만 전달한다. - 같은 노드의 GPU 간 텐서 전달에는 **CUDA IPC**를 사용했다. - GPU 텐서를 CPU로 내렸다가 다시 GPU로 올리는 `Device → Host → Device` 복사를 제거해 컴포넌트 간 통신 지연을 줄였다. ## Cascaded Streaming Pipeline - Thinker가 전체 텍스트를 생성한 뒤 Talker를 실행하는 순차 방식은 첫 음성 응답까지 수 초가 걸릴 수 있다. - 세 컴포넌트를 비동기 태스크와 큐로 연결해 파이프라인을 겹쳐 실행했다. - Thinker가 첫 청크를 생성하면 Talker는 즉시 음성 토큰 생성을 시작한다. - Talker가 앞선 토큰을 생성하는 동안 VoiceBox는 이전 토큰 청크를 오디오로 합성한다. - 각 단계가 동시에 진행되므로 전체 처리 시간보다 첫 음성까지의 체감 지연을 크게 줄일 수 있다. ## 프로세스 분리와 장애 격리 - Thinker와 Talker는 각각 독립적인 vLLM 엔진으로 실행된다. - 하나의 프로세스에서 두 엔진을 구동하면 CUDA 컨텍스트 충돌이나 GPU 메모리 관리 간섭이 발생할 수 있다. - 따라서 두 모델을 별도 프로세스로 분리하고 각자의 CUDA 컨텍스트에서 실행했다. - 프로세스 생성에는 `fork` 대신 `spawn`을 사용했다. - `fork`: 부모의 CUDA 상태와 메모리를 복제해 충돌 위험이 있다. - `spawn`: 깨끗한 Python 인터프리터에서 시작해 GPU 상태 오염을 줄인다. - Thinker가 OOM으로 종료되더라도 Talker와 API 서버까지 함께 영향을 받지 않아 독립적인 재시작과 장애 대응이 가능하다. ## vLLM continuous batching을 이용한 동시 처리 - 요청마다 이미지·오디오 입력 크기와 누적 임베딩 길이가 달라 직접 배치를 구성하기 어렵다. - 수동 배칭은 padding 낭비와 복잡한 동기화 문제를 유발한다. - Kanana-Omni Server는 배치 구성을 vLLM의 **continuous batching 스케줄러**에 위임했다. - 서버는 요청을 비동기로 빠르게 엔진에 제출하고, vLLM이 GPU 메모리와 요청 상태를 고려해 forward pass를 묶는다. - 각 요청은 `request_id`로 결과를 구분하므로 여러 요청이 하나의 배치에서 처리돼도 개별 응답을 독립적으로 스트리밍할 수 있다. - 내부 루프는 요청을 받자마자 `asyncio.create_task(generate(...))`로 실행해 다음 요청을 즉시 수락한다. ## FastAPI `workers=1`과 비동기 처리 - 일반적인 FastAPI 서버처럼 여러 워커를 실행하면 각 워커가 vLLM 모델을 별도로 로드한다. - 그 결과 GPU 메모리 사용량과 모델 로딩 시간이 워커 수만큼 증가해 멀티워커 구성이 현실적으로 어렵다. - 모델별 서버를 따로 두면 워커 확장은 가능하지만, Thinker와 Talker 사이의 임베딩이 네트워크를 거쳐 zero-copy 이점을 잃게 된다. - 따라서 API 서버는 `workers=1`로 운영하고, 단일 이벤트 루프가 블로킹되지 않도록 요청부터 오디오 생성까지 전체 경로를 `async/await`로 구성했다. - 단일 워커 환경에서는 동기 작업 하나가 모든 사용자의 처리를 막을 수 있으므로, 끝에서 끝까지 비동기 설계가 필수다. 실시간 멀티모달 모델을 서비스할 때는 모델 자체보다 모델 간 데이터 이동, 스트리밍 타이밍, GPU 메모리 관리, 장애 격리가 성능을 좌우한다. 특히 모델 간 임베딩 전달이 빈번하다면 공유 메모리와 CUDA IPC를 검토하고, 긴 생성 파이프라인은 비동기 스트리밍과 continuous batching으로 구성하는 것이 효과적이다.

pinterest

경량 광고 참여 예측을 위한 (새 탭에서 열림)

Pinterest는 광고 추천 시스템의 중간 단계인 경량 랭킹(Lightweight ranking)의 효율성을 극대화하기 위해, 기존 CPU 기반의 2-타워 모델을 GPU 기반의 MMOE-DCN 아키텍처로 전환했습니다. 이를 통해 모델의 복잡도를 높이면서도 지연 시간을 안정적으로 유지했으며, 오프라인 예측 오차 감소와 더불어 온라인 클릭률(CTR) 증가 및 클릭당 비용(CPC) 감소라는 실질적인 성과를 거두었습니다. **MMOE-DCN 아키텍처로의 전환** * 기존의 MTMD(Multi-Task Multi-Domain) 모델에서 MMOE(Multi-gate Mixture-of-Experts)와 DCN(Deep & Cross Networks)이 결합된 구조로 아키텍처를 변경했습니다. * MLP 게이팅 메커니즘을 적용한 MMOE 구조를 통해 별도의 도메인 전용 모듈 없이도 다중 도메인 및 다중 작업(Multi-task) 학습 문제를 효과적으로 해결했습니다. * 모델 내의 각 전문가(Expert) 유닛에 풀랭크(Full-rank) 및 로우랭크(Low-rank) DCN 레이어를 도입하여 특성 간의 교차 작용을 더 정교하게 학습하도록 설계했습니다. **GPU 학습 및 서빙 효율성 최적화** * 데이터 로더 최적화: GPU 프리패치(Prefetch) 기능을 활성화하여 GPU 연산과 데이터 준비를 병렬화하고, 대용량 CPU 메모리를 활용해 워커 스레드 수를 늘려 병목 현상을 제거했습니다. * 연산 효율성 증대: CPU에서의 메모리 할당을 최소화하고 GPU에서 직접 연산을 수행하며, 개별 커널들을 하나로 합친 퓨즈드 커널(Fused kernels)을 사용해 오버헤드를 줄였습니다. * 훈련 설정 개선: BF16(Brain Floating Point 16) 정밀도를 도입해 학습 속도를 높였으며, 배치 크기를 확대하여 GPU 메모리 활용도를 극대화했습니다. **데이터 분리 및 성과 분석** * 쇼핑 광고와 일반 광고 시나리오를 분리하고 각 데이터에 맞게 개별 학습을 진행함으로써 오프라인 손실(Loss)을 추가로 5~10% 더 절감했으며, 모델 반복 학습 속도를 2배 개선했습니다. * 오프라인 평가에서 이전 모델 대비 CTR 예측 손실이 총 10~20%가량 감소하는 결과를 확인했습니다. * 실제 온라인 서비스 적용 결과, 모든 광고 영역에서 사용자 클릭률(CTR)은 상승하고 광고주가 부담하는 클릭당 비용(CPC)은 낮아지는 지표 개선을 달성했습니다. GPU 인프라를 활용한 모델 복잡도 최적화는 대규모 추천 시스템에서 성능과 비용 효율성을 동시에 잡을 수 있는 핵심 전략입니다. 특히 단순한 하드웨어 교체를 넘어 하드웨어 가속에 최적화된 커널 사용과 데이터 파이프라인 튜닝을 병행할 때 복잡한 딥러닝 모델의 실무 적용 효과가 극대화됩니다.