본문으로 건너뛰기

© 2026 Molayo

llama.cpp헤드라인2026. 05. 14. 04:12

CUDA provider를 위한 내부 AllReduce 커널 ( #22299 ) ggml-cuda: 텐서 병렬화 (tensor paralleli

요약

본 업데이트는 CUDA provider를 위한 내부 AllReduce 커널을 도입하여, NCCL 없이도 GPU 간의 텐서 병렬화(tensor parallelism)에 필요한 AllReduce 기능을 구현합니다. 이 새로운 internal provider는 단일 단계 CUDA 커널과 파이프라이닝 기법을 사용하여 효율적인 통신을 제공하며, `ggml-cuda` 라이브러리와 `llama-bench` 도구 모두에서 이를 지원하고 있습니다. 또한, 사용자가 NCCL 또는 내부 Provider를 명시적으로 선택할 수 있도록 환경 변수 및 플래그가 추가되었습니다.

핵심 포인트

  • NCCL이 필요 없는 자체 AllReduce 커널을 CUDA provider로 구현하여 텐서 병렬화 기능을 강화했습니다.
  • 새로운 internal provider는 단일 단계 파이프라이닝 CUDA 커널과 핸드셰이크 메커니즘을 사용하여 효율성을 높였습니다.
  • 사용자는 `GGML_CUDA_ALLREDUCE` 환경 변수 또는 `--allreduce` 플래그를 통해 NCCL 또는 내부 Provider를 선택할 수 있습니다.
  • 지원 범위는 현재 2개의 GPU, FP32 데이터 타입, 그리고 256 KB 이하의 텐서로 제한됩니다.
  • llama-bench 도구에서 AllReduce 관련 플래그가 `--reduction-provider` / `-rp`로 이름이 변경되어 일관성이 높아졌습니다.

CUDA provider를 위한 내부 AllReduce 커널 ( #22299 )

ggml-cuda: 텐서 병렬화 (tensor parallelism)를 위한 내부 AllReduce provider 추가

LLAMA_SPLIT_MODE_TENSOR를 위해 D2H 복사, pinned-memory volatile flags를 통한 GPU 간 핸드셰이크 (handshake), 그리고 reduction을 GPU당 한 번의 커널 실행(kernel launch) 내에서 파이프라이닝하는 단일 단계(single-phase) CUDA 커널을 사용하여 NCCL이 필요 없는 AllReduce 구현을 도입합니다.

새로운 파일:

  • ggml/src/ggml-cuda/comm.cuh — ggml_cuda_allreduce_provider enum
  • ggml/src/ggml-cuda/allreduce.cuh — 파이프라인 (pipeline) API 선언
  • ggml/src/ggml-cuda/allreduce.cu — 커널 + 파이프라인 초기화/디스패치 (init/dispatch)

ggml-cuda.cu 변경 사항:

  • ggml_backend_cuda_comm_context에 ar_pipeline 필드 추가
  • GGML_CUDA_ALLREDUCE 환경 변수를 통한 provider 선택 ("nccl" / "internal")
  • INTERNAL provider는 comm_init 시점에 파이프라인을 초기화합니다.
  • 디스패치는 ggml_cuda_ar_allreduce()로 라우팅됩니다. 지원되지 않는 크기나 GPU 개수(> 2)의 경우 meta-backend CPU reduce로 폴백(fallback)합니다.
  • 현재 범위: 2개의 GPU, FP32, 256 KB 이하의 텐서. NOTES-allreduce.md에 참고 사항 기재.
    Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

lama-bench: AllReduce provider를 선택하기 위한 --allreduce 플래그 추가

lama-bench에 --allreduce <auto|nccl|internal>를 추가합니다 (공유 필드 패턴을 통해 다른 다중 값 플래그와 일관성을 유지함).
텐서 병렬 모드에서의 중단(hangs) 또는 성능 저하(regressions)를 격리하는 데 유용합니다: --allreduce nccl을 전달하여 NCCL을 강제하고 내부 provider를 우회할 수 있습니다.
또한, GGML_CUDA_ALLREDUCE 환경 변수가 비어 있는 경우를 설정되지 않은 것과 동일하게 처리하도록 ggml_cuda_select_allreduce_provider()를 수정합니다 (llama-bench가 "auto" 케이스를 위해 이를 ""로 설정할 때 발생하는 불필요한 경고를 방지함).
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

xt는 ar_pipeline 필드를 가집니다.
GGML_CUDA_ALLREDUCE 환경 변수를 통한 provider 선택 ("nccl" / "internal")
INTERNAL provider는 comm_init 시점에 파이프라인을 초기화합니다.
디스패치는 ggml_cuda_ar_allreduce()로 라우팅됩니다. 지원되지 않는 크기나 GPU 개수(> 2)의 경우 meta-backend CPU reduce로 폴백합니다.
현재 범위: 2개의 GPU, FP32, 256 KB 이하의 텐서. NOTES-allreduce.md에 참고 사항 기재.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com llama-bench: --allreduce를 --reduction-provider / -rp로 이름 변경 (다른 다중 값 플래그(multi-value flags)와 일관되게 공유 필드 패턴을 통해 적용). 텐서 병렬(tensor-parallel) 모드에서의 행(hang) 또는 회귀(regression)를 격리하는 데 유용함: --allreduce nccl을 전달하여 NCCL을 강제하고 내부 프로바이더(internal provider)를 우회할 수 있음. 또한 ggml_cuda_select_allreduce_provider()를 수정하여 비어 있는 GGML_CUDA_ALLREDUCE 환경 변수를 설정되지 않은 상태와 동일하게 처리함 (llama-bench가 "auto" 케이스를 위해 이를 ""로 설정할 때 발생하는 잘못된 경고를 방지함). Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com xt gains ar_pipeline 필드 GGML_CUDA_ALLREDUCE 환경 변수를 통한 프로바이더(Provider) 선택 ("nccl" / "internal") INTERNAL 프로바이더는 comm_init 시점에 파이프라인(pipeline)을 초기화함. 디스패치(Dispatch)는 ggml_cuda_ar_allreduce()로 라우팅되며, 지원되지 않는 크기나 GPU 개수(> 2)의 경우 메타-백엔드(meta-backend) CPU reduce로 폴백(fallback)함. 현재 범위: 2개의 GPU, FP32, 256 KB 이하의 텐서. NOTES-allreduce.md에 참고 사항 기재. Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com llama-bench: 비상세(non-verbose) 모드에서 WARN/ERROR 로그 메시지를 그대로 전달함. null 로그 콜백(log callback)이 모든 메시지를 조용히 누락시키고 있었음. WARN 및 ERROR는 실제 문제(예: 요청된 리덕션 프로바이더(reduction provider)를 사용할 수 없는 경우)를 나타내므로 항상 표시되어야 함. Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com vider. 또한 ggml_cuda_select_allreduce_provider()를 수정하여 비어 있는 GGML_CUDA_ALLREDUCE 환경 변수를 설정되지 않은 상태와 동일하게 처리함 (llama-bench가 "auto" 케이스를 위해 이를 ""로 설정할 때 발생하는 잘못된 경고를 방지함). Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com xt gains ar_pipeline 필드 GGML_CUDA_ALLREDUCE 환경 변수를 통한 프로바이더(Provider) 선택 ("nccl" / "internal") INTERNAL 프로바이더는 comm_init 시점에 파이프라인(pipeline)을 초기화함. 디스패치(Dispatch)는 ggml_cuda_ar_allreduce()로 라우팅되며, 지원되지 않는 크기나 GPU 개수(> 2)의 경우 메타-백엔드(meta-backend) CPU reduce로 폴백(fallback)함. 현재 범위: 2개의 GPU, FP32, 256 KB 이하의 텐서. NOTES-allreduce.md에 참고 사항 기재.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com cmake: 소스 트리 빌드(source-tree builds)를 위한 NCCL 탐지 기능 개선, 정적/동적 스위치 추가. FindNCCL.cmake는 이제 Windows NCCL 포트에서 사용되는 cmake 소스 빌드 레이아웃(정적 라이브러리의 경우 cmake/lib/Release, 동적 라이브러리의 import lib의 경우 cmake/src/Release)을 검색하며, 생성된 nccl.h 헤더를 위해 src/include도 확인합니다. 새로운 옵션인 GGML_CUDA_NCCL_STATIC (기본값 OFF)은 정적(static) 대 동적(dynamic) 링크를 선택하고 어떤 경로와 라이브러리 이름을 검색할지 제어합니다. Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com "auto" 케이스를 위해). Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com xt 이득 ar_pipeline 필드 GGML_CUDA_ALLREDUCE 환경 변수를 통한 프로바이더(Provider) 선택 ("nccl" / "internal"). INTERNAL 프로바이더는 comm_init 시점에 파이프라인(pipeline)을 초기화합니다. 디스패치(Dispatch)는 ggml_cuda_ar_allreduce()로 라우팅되며, 지원되지 않는 크기나 GPU 개수(> 2)의 경우 메타-백엔드(meta-backend) CPU reduce로 백(fallback)함. 현재 범위: 2개의 GPU, FP32, 256 KB 이하의 텐서. NOTES-allreduce.md에 참고 사항 기재. Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com ggml-cuda: AllReduce 행(hang) 와치독(watchdog) 추가 (GGML_CUDA_AR_WATCHDOG). -DGGML_CUDA_AR_WATCHDOG=ON으로 컴파일하면, GPU별 스핀 진단(spin diagnostics)을 고정된 호스트 메모리(pinned host memory)에 기록하는 디버그 커널 변형(debug kernel variant)을 사용합니다. 호스트 측 차단 폴링(blocking poll, cudaEventQuery + volatile reads)이 행(hang)을 감지하고, 마지막으로 관찰된 도착 카운터(arrival counters) 및 스핀 횟수(spin counts)와 함께 WARN 로그를 남깁니다. 이는 런타임 시 GGML_CUDA_AR_WATCHDOG (ms 타임아웃) 및 GGML_CUDA_AR_MAX_SPIN (커널 베일아웃, kernel bailout) 환경 변수에 의해 제어됩니다. 프로덕션 경로(production path)에서의 오버헤드는 제로입니다 — 모든 디버그 코드는 #ifdef 뒤에 위치합니다. Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com ar_pipeline 필드 GGML_CUDA_ALLREDUCE 환경 변수를 통한 프로바이더(Provider) 선택 ("nccl" / "internal"). INTERNAL 프로바이더는 comm_init 시점에 파이프라인(pipeline)을 초기화합니다. 디스패치(Dispatch)는 ggml_cuda_ar_allreduce()로 라우팅되며, 지원되지 않는 크기나 GPU 개수(> 2)의 경우 메타-백엔드(meta-backend) CPU reduce로 백(fallback)함. 현재 범위: 2개의 GPU, FP32, 256 KB 이하의 텐서. NOTES-allreduce.md에 참고 사항 기재.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com ggml-cuda: Blackwell PCIe에서 간헐적인 AllReduce 행(hang) 현상 수정

signal_set 내의 도착 신호(arrival signal) 쓰기 작업 이전에 __threadfence_system()을 추가하여, 피어(peer)가 도착 플래그(arrival flag)를 관찰하기 전에 D2H 데이터가 전역적으로 가시화(globally visible)되도록 보장함. 이 펜스(fence)가 없으면, 피어가 데이터가 완전히 안착하기 전에 Phase 3 호스트 읽기(host reads) 단계로 진입할 수 있으며, 이는 RTX 5090 (Blackwell, PCIe-only)에서 간헐적인 데드락(deadlock)을 유발함. 또한, 워치독(watchdog)을 차단형(blocking) 디스패치 스레드 폴링(dispatch-thread poll) 방식에서 비차단형(non-blocking) 백그라운드 스레드 방식으로 재설계하여, 기존 설계에서 슬롯당 추가되었던 약 20ms의 지연 시간(latency)을 제거함. 검증 완료: 30/30 소크 테스트(soak test) 실행 결과 약 50 t/s에서 정상 작동 (이전에는 약 15회당 1회꼴로 행 발생).

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com INTERNAL

프로바이더(provider)는 comm_init 시점에 파이프라인(pipeline)을 초기화함
디스패치(Dispatch)는 ggml_cuda_ar_allreduce()로 라우팅되며, 지원되지 않는 크기나 GPU 개수(> 2)의 경우 meta-backend CPU 리듀스(reduce)로 폴백(fallback)함
현재 범위: 2개의 GPU, FP32, 256 KB 이하의 텐서. NOTES-allreduce.md에 참고 사항 기재.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com ggml-cuda: 워치독 종료 순서 및 pipeline_free 드레인(drain) 수정

파괴된 핸들(handles)을 폴링하여 잘못된

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com ggml-cuda: 이벤트 기반 워치독(watchdog)을 GPU별 링 버퍼(ring buffer)로 교체

GGML_CUDA_AR_WATCHDOG 시스템을 완전히 재설계: 공유된 debug_buf + 이벤트 폴링(event-polling) + 큐(queue) 설계를 고정된 호스트 메모리(pinned host memory) 내의 GPU별 링 버퍼로 교체

커널은 스핀 제한(spin-limit) 탈출(bailout) 시에만 디버그 레코드를 작성: atomicAdd를 통해 링 슬롯을 점유(RTX 5090에서 단일 GPU 호스트 원자적 연산(atomics) 작동), 필드 작성, 펜스(fences), 완료 플래그 설정 후 모든 스레드 종료

워치독(Watchdog) 스레드는 단순히 1ms마다 링 헤드 카운터(ring head counters)를 폴링하여 새로운 완료 레코드를 출력 — CUDA 이벤트 쿼리(queries), 뮤텍스(mutex), 큐(queue) 없음

디스패치 경로(dispatch path) 상의 오버헤드 제로 (큐 포스팅(queue posting) 및 memset 없음)

워치독 종료는 ~1ms 이내에 반환 (atomic bool, 드레인(drain) 없음)

탈출(bailout) 시 커널은 Phase 3를 완전히 건너뛰고 깔끔하게 종료됨

검증 완료: 20/20 프리필(prefill) 소크 테스트(soak test) 통과, ~1112 t/s에서 중단(hang) 없음.
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com P32, 텐서(tensors) <= 256 KB. NOTES-allreduce.md에 노트 기재.
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com fix: 줄 바꿈(line endings)을 LF로 정규화 (Windows CRLF 변환 취소)

Windows 개발 환경에 의해 5개의 파일이 의도치 않게 CRLF로 변환되어, master 브랜치와의 diff에서 모든 줄이 변경된 것으로 표시됨.
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com imit bailout: atomicAdd를 통해 링 슬롯을 점유(RTX 5090에서 단일 GPU 호스트 원자적 연산(atomics) 작동), 필드 작성, 펜스(fences), 완료 플래그 설정 후 모든 스레드 종료

워치독(Watchdog) 스레드는 단순히 1ms마다 링 헤드 카운터(ring head counters)를 폴링하여 새로운 완료 레코드를 출력 — CUDA 이벤트 쿼리(queries), 뮤텍스(mutex), 큐(queue) 없음

디스패치 경로(dispatch path) 상의 오버헤드 제로 (큐 포스팅(queue posting) 및 memset 없음)

워치독 종료는 ~1ms 이내에 반환 (atomic bool, 드레인(drain) 없음)

탈출(bailout) 시 커널은 Phase 3를 완전히 건너뛰고 깔끔하게 종료됨

검증 완료: 20/20 프리필(prefill) 소크 테스트(soak test) 통과, ~1112 t/s에서 중단(hang) 없음.
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com P32, 텐서(tensors) <= 256 KB. NOTES-allreduce.md에 노트 기재.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com .gitattributes: Windows CRLF 변환을 방지하기 위해 LF 줄 바꿈 강제. Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com 개발 환경에서 모든 줄이 master 대비 diff에서 변경된 것으로 표시되는 문제 발생. Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com bailout(탈출) 메커니즘: atomicAdd를 통해 ring 슬롯을 점유하며(단일-GPU 호스트 원자적 연산은 RTX 5090에서 작동함), 필드를 작성하고, fence를 수행하며, 완료 플래그(completion flag)를 설정한 후 모든 스레드가 종료됨. Watchdog(감시) 스레드는 단순히 1ms마다 ring head 카운터를 폴링(poll)하여 새로운 완료 레코드를 출력함 — CUDA 이벤트 쿼리, 뮤텍스(mutex), 큐(queue)를 사용하지 않음. 디스패치(dispatch) 경로에서 오버헤드 제로 (큐 포스팅 없음, memset 없음). Watchdog 종료는 ~1ms 이내에 반환됨 (atomic bool 사용, drain 없음). Bailout 발생 시 커널은 Phase 3를 완전히 건너뛰고 깔끔하게 종료됨. 검증 완료: ~1112 t/s에서 20/20 prefill soak 테스트 통과, 중단(hang) 없음. Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com P32, 텐서(tensors) <= 256 KB. NOTES-allreduce.md에 노트 기재. Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com ggml-cuda: GGML_CUDA_AR_WATCHDOG를 CMake 옵션에서 로컬 정의(local define)로 이동. Watchdog은 개발 전용이므로, 전역 CMake 옵션은 과함. 토글(toggle)을 allreduce.cu 상단의 #define으로 이동하고(기본값 0으로 설정), ggml/CMakeLists.txt 및 CUDA CMakeLists.txt의 add_compile_definitions 블록에서 해당 옵션을 제거함. Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com fence를 수행하고, 완료 플래그를 설정한 후 모든 스레드가 종료됨. Watchdog 스레드는 단순히 1ms마다 ring head 카운터를 폴링(poll)하여 새로운 완료 레코드를 출력함 — CUDA 이벤트 쿼리, 뮤텍스(mutex), 큐(queue)를 사용하지 않음. 디스패치(dispatch) 경로에서 오버헤드 제로 (큐 포스팅 없음, memset 없음). Watchdog 종료는 ~1ms 이내에 반환됨 (atomic bool 사용, drain 없음). Bailout 발생 시 커널은 Phase 3를 완전히 건너뛰고 깔끔하게 종료됨. 검증 완료: ~1112 t/s에서 20/20 prefill soak 테스트 통과, 중단(hang) 없음. Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com P32, 텐서(tensors) <= 256 KB. NOTES-allreduce.md에 노트 기재.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

unify kernel debug paths

__threadfence_system을 명시적으로 사용하여 커널 디버그 경로 통합 (ggml_cuda_ar_signal_set에는 포함되지 않음)

2개 이하의 GPU인 경우 내부 리덕션 (internal reduction)을 우선적으로 사용

fp16/bf16 지원을 위해 메인 커널을 템플릿화 (templatize)

llama-bench.cpp 변경 사항 복구

CMakeLists 변경 사항 되돌리기

리포지토리(repo)에서 노트 제거

불필요한 웜업 (warmup) 코드 제거

주석 수정

리덕션 프로바이더 (reduction provider) 폴백 (fallback) 코드 개선

allreduce 폴백을 위한 메시지 추가

내부 프로바이더 (internal provider)를 사용하는 경우 ncclCommInitAll을 호출하지 않도록 리덕션 프로바이더 초기화 (init) 재작업

주어진 텐서 (tensor)가 계산되지 않은 경우 발생하는 케이스 수정

무제한 벡터 (vec)를 위해 커널에 청크 모드 (chunked mode) 추가

AI 자동 생성 콘텐츠

본 콘텐츠는 llama.cpp Releases의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0