2. 애플 실리콘에서는 왜 쓸 수 없었는가?
CUDA가 없는 하드웨어
맥에서 CUDA를 사용할 수 없다는 말은, CUDA로 하던 일을 다른 것으로 해야 한다는 뜻이다. 애플 실리콘 맥에서 그 역할을 맡은 것이 MPS(Metal Performance Shaders) 백엔드다.
문제는 CUDA로 할 수 있는 일과 MPS로 할 수 있는 일이 같지 않다는 데 있다.
어디에 무엇이 있는가
[ Application / Framework Layer ]
PyTorch User Code (Python)
│
▼
[ PyTorch C++ Core (LibTorch / ATen) ]
Dispatcher (CPU / CUDA / MPS 연산 분기)
│
▼
┌-------------------------------------------------------------┐
│ [ PyTorch Internals: MPS Backend ] │
│ - aten/src/ATen/mps (장치, 스트림, 메모리 할당기) │
│ - aten/src/ATen/native/mps (연산 구현, 커스텀 Metal 커널) │
│ - torch/csrc/mps (torch.mps 파이썬 바인딩) │
└-----------------------------┬------------------------------┘
│ (호출)
═════════════════════════════════════════════════════════════════
[ macOS System Frameworks ] │
▼
┌---------------------------------------┐
│ MPSGraph (연산 그래프 융합 및 최적화) │
│ │ │
│ ▼ │
│ MPS (Metal Performance Shaders) │
└-----------------┬--------------------┘
│
▼
[ Low-level Graphics & Compute Layer ]
Metal Framework / Metal Shading Language (MSL)
Metal Driver
│
▼
[ Hardware Layer ]
Apple Silicon GPU Core
파이토치에서 사용하는 MPS 백엔드는 애플이 제공하는 프레임워크 위에 얹혀 있다. CUDA처럼 하드웨어 바로 위에서 커널을 작성하는 구조가 아니다.
제약은 어디에 있는가
이 구조를 이렇게 정리할 수도 있다. "애플이 제공하지 않는 기능은 파이토치도 제공할 수 없다." 절반만 맞는 말이다.
파이토치는 MPSGraph에만 의존하지 않는다. 자체 Metal 셰이더를 직접 작성해 애플의 고수준 프레임워크를 우회하기도 하며, 최근에는 그 비중을 늘리고 있다. 올 7월의 2.13 릴리스 노트에는 bernoulli, native_dropout, uniform 같은 연산을 MPSGraph에서 네이티브 Metal 커널로 옮겼다는 항목이 줄줄이 들어 있다. 애플이 만들어 준 그래프 엔진을 쓰는 대신 직접 셰이더를 쓰겠다는 선택이다.
그래서 진짜 제약은 한 단계 아래에 있다. 셰이딩 언어와 하드웨어가 지원하지 않는 것은 어느 경로로도 우회할 수 없다. 그래프 엔진에 없으면 셰이더를 직접 쓰면 되지만, 셰이딩 언어에 자료형이 없으면 셰이더를 쓸 방법 자체가 없다.
무엇이 없었고, 언제 생겼는가
bf16이 정확히 그런 경우였다.
애플 실리콘에서 bf16을 쓸 수 없었던 것은 파이토치의 게으름이나 버그 때문이 아니었다. MPS 백엔드 아래의 프레임워크와 저수준 계층에 bfloat 자료형이 아예 없었기 때문이다. 애플이 제공하는 API에는 fp16에 해당하는 half와 fp32에 해당하는 float가 있었지만, bf16의 설계에 대응하는 자료형은 없었다. MPSGraph에도 없고, 그 아래 셰이딩 언어에도 없었다. 우회할 곳이 없다는 뜻이다.
애플은 그들이 의도한 맥의 활용 방향에 따라 bfloat의 필요성을 간과했다. 애플 실리콘의 GPU와 뉴럴 엔진은 오랫동안 온디바이스 추론을 목표로 발전해 왔다. 사진 분류, 얼굴 인식, 음성 처리 같은 작업이다. 이런 용도에서는 fp16의 좁은 표현 범위가 거의 문제가 되지 않는다. 학습이 아니라 이미 학습된 모델을 실행하는 일이기 때문이다. 기울기 소실을 걱정할 필요가 없는 상황에서는 오히려 가수부가 3비트 더 넉넉한 fp16이 정밀도 면에서 유리하다.
그래서 애플은 fp16을 하드웨어와 셰이딩 언어 양쪽에서 먼저 지원해 왔다. 맥에서 큰 모델을 학습하거나 미세 조정하려는 수요는 뒤늦게 인정한 셈이다.
결국 애플은 macOS 14 소노마에서 bf16을 도입했다. Metal Shading Language 3.1에 bfloat 타입이 생기고, MPSGraph에 MPSDataTypeBFloat16이 추가되었다. 파이토치는 2.3 릴리스에서 이를 받았다. 릴리스 노트에 한 줄로 적혀 있다.
Enable bfloat16 support on MacOS 14 (#119641)
즉 애플 실리콘 맥에서 macOS 14 이상, 파이토치 2.3 이상이면 이제 bf16을 사용할 수 있다. 2024년의 일이다.
3. 그래도 아직 부족하다
문제가 bf16에만 있었던 것은 아니다. MPS 백엔드가 제공하지 않는 기능, CUDA에서만 되는 기능은 지금도 남아 있다.
목록에는 있고 구현되지 않은 연산들
파이토치는 MPS 백엔드에 구현되기를 바라는 연산을 투표로 모으고 있다(링크). 2025년 5월에 만들어진 목록이다. 이후 구현된 항목에는 취소선이 그어졌는데, 아직 다수가 남아 있다.
남은 것을 보면 linalg_eig, linalg_qr, _linalg_eigh, linalg_matrix_exp처럼 선형대수 분해가 압도적이다. 고윳값 분해와 QR 분해, 촐레스키가 MPS의 가장 큰 공백이다.
목록에조차 없는 것
이 목록이 전부도 아니다.
<멀티모달까지 직접 구현하는 딥러닝 with 파이토치> 10-1절의 예제는 MPS 백엔드에서 다음과 같은 예외가 발생한다.
NotImplementedError: The operator 'aten::_nested_tensor_from_mask_left_aligned' is not currently implemented for the MPS device.
이 연산(_nested_tensor_from_mask_left_aligned)은 투표 집계 목록에 없다. 목록에 오르려면 셋 이상의 요청이 필요한데, 두 건의 요청만 받았기 때문이다. 그 두 표 중 하나를 남긴 사람이 <Hands-On Machine Learning>의 저자 오렐리앙 제롱이다. 용례도 똑같이 "Training a Transformer"라고 적혀 있다. 2025년 3월의 일이고, 1년 반이 지난 지금도 구현되지 않았다.
이 연산 자체는 대단한 것이 아니다. 패딩 마스크가 좌측 정렬인지 판정하는 연산일 뿐이다. 문제는 nn.TransformerEncoder의 기본 설정이 이 연산을 사용한다는 데 있다. 패딩을 건너뛰어 연산량을 줄이는 경로인데, 이를 위해 MPS에 없는 연산을 사용한다.
다행히 우회할 방법이 있다. torch.backends.mha.set_fastpath_enabled(False)를 호출해 전역 스위치를 끄면 된다. MPS 백엔드 대신 CPU를 사용하는 것도 한 가지 쉬운 대안이 될 수 있다.
늘 한 발 늦는다
이런 사례들을 보면 MPS 백엔드 지원의 패턴을 가늠할 수 있다. 언젠가 지원되지만 늘 한 발 늦는다는 점이다. 예를 들어 지난 7월 2.13 릴리즈에 포함된 MPS 백엔드의 FlexAttention은 CUDA 백엔드는 2.5 릴리즈(2024년 10월)에 포함되었다.
어쩔 수 없다. 현재 딥러닝 개발의 표준은 CUDA라는 사실은 부인하기 어렵다. 새 기능은 CUDA에서 나오고, MPS는 여러 릴리스 뒤에 따라온다. 개발자 친화적인 하드웨어와 운영체제라 해도, 파이토치로 딥러닝을 하는 사람에게 맥을 선뜻 권하기 어려운 이유가 이것이다.
애플이 직접 내놓은 대안으로 MLX가 있지만 파이토치만큼 널리 쓰이지는 않는다.
기대감
그래도 조금씩 좋아지고 있다.
올 7월의 2.13 릴리스에는 MPS 관련 항목이 스무 개 넘게 들어갔다. CUDA에 2.5부터 있던 FlexAttention이 MPS에서도 동작하게 되었고, 릴리스 노트는 "희소 패턴에서 SDPA 대비 최대 12배"라고 적었다. 늦게 왔지만 올 때는 제대로 온 셈이다.
더 눈에 띄는 것은 앞서 이야기한 흐름이다. 파이토치가 MPSGraph에서 벗어나 자체 Metal 커널을 늘려 가고 있다. 애플이 만들어 주기를 기다리는 대신 직접 만드는 쪽으로 무게가 옮겨 가는 중이다. 그렇게 되면 "애플이 제공하지 않으면 못 한다"는 제약이 닿는 범위도 그만큼 줄어든다.
언젠가는 애플 실리콘의 좋은 하드웨어를 파이토치에서 온전히 활용할 수 있는 시기가 올 것이라는 기대를 가져 본다.
No comments:
Post a Comment