Accurate Models of AMD Matrix Cores
AMD Matrix Core의 정확한 모델 — 문서화되지 않은 수치 동작을 실험으로 밝혀내다
최근 GPU의 행렬 곱셈 유닛은 IEEE 754를 따르지 않으며 누적기 폭, 반올림 방식, 서브노멀 처리 등이 공급사와 세대마다 달라 장치 간 결과 재현이 불가능합니다. 연구팀은 CDNA 1~3 세대(MI100~MI300X)의 수치 동작을 특성화하고, 1,000만 개의 무작위 테스트로 비트 단위 일치를 검증한 MATLAB 모델을 만들어 NVIDIA tensor core와의 정확도 차이까지 정량화했습니다.
- 주제
본문
최근 GPU에 탑재된 행렬 곱셈 유닛(matrix multiplier)은 IEEE 754 부동소수점 표준을 따르지 않습니다. 누적기(accumulator) 폭, 반올림 동작, 정규화 지점, 중간 언더플로·오버플로 로직, 서브노멀(subnormal) 처리, 특수 입력 취급 방식이 공급사마다, 그리고 같은 공급사의 아키텍처 세대마다 다릅니다. 그 결과 작은 행렬 곱셈 결과를 장치 간에 재현하는 것은 불가능하며 소프트웨어 제어로도 달성할 수 없고, 구현 세부사항이 문서화되지 않아 계산 결과의 불일치를 해석하기도 어렵습니다. 이 논문은 이러한 비공개 수치 동작을 실험적으로 밝혀내 정확한 소프트웨어 모델로 만든 연구입니다.
세 세대의 AMD GPU를 대상으로 한 특성화
연구팀은 CDNA 1, CDNA 2, CDNA 3의 세 AMD GPU 아키텍처에 걸쳐 행렬 곱셈기의 수치 동작을 특성화했으며, 사용된 하드웨어는 각각 MI100, MI210/250, MI300A/300X입니다. 지원되는 모든 입력 형식에 대해 수치적 특징을 겨냥한 테스트 벡터를 설계했고, 각 벡터가 장치의 출력을 근거로 왜 특정 수치 특징을 판별할 수 있는지에 대한 유도 과정과 추론을 함께 제시했습니다.
비트 단위 일치를 검증한 MATLAB 모델
이어서 각 아키텍처별로 MATLAB 기반 소프트웨어 모델을 개발하고, 1,000만 개의 무작위 입력 벡터 집합으로 구성된 랜덤 테스트 스위트로 하드웨어와의 비트 단위 재현성을 검증했습니다. 이를 위해 이전에 개발된 기법을 적용해, 무작위 테스트와 테스트-정제를 모든 테스트 케이스에서 모델이 하드웨어와 일치할 때까지 반복하는 루프로 모델의 정확도를 점진적으로 개선했습니다.
응용 수준의 정확도 차이 정량화
모델로 어떤 실험적 연구가 가능한지 보여주는 개념 증명으로, 두 개의 시연용 수치 응용에서 모델을 활용해 AMD matrix core와 NVIDIA tensor core 사이의 응용 수준 정확도 차이를 정량화했습니다. 문서화되지 않은 하드웨어 동작을 소프트웨어로 정확히 모사할 수 있게 되면, 서로 다른 GPU에서 결과가 달라지는 원인을 추적하거나 장치 이식 시 수치 안정성을 미리 평가하는 식의 연구가 가능해집니다.
Hacker News 반응
- @peter_d_sherman — "행렬 곱셈기의 특징은 공급사마다, 같은 공급사의 아키텍처마다 다르다 […] 그 결과 장치 간 작은 행렬 곱셈 결과의 재현은 불가능하며 소프트웨어 제어로도 달성할 수 없다. 구현 세부사항이 문서화되지 않아 계산 결과의 불일치를 해석하기 어렵다." 저는 (확실하지는 않지만) 서로 다른 공급사 아키텍처 간, 그리고 한 공급사 아키텍처의 세대 간에 존재하는 행렬 곱셈의 작고 미묘한 차이가 상당 부분의 소프트웨어 크래시 원인이 아닐까 추측합니다.
- @varispeed — 같은 아키텍처끼리도 그렇지 않나요? 예를 들어 모델 학습 스크립트를 만들었을 때 RTX 5080에서는 잘 돌아갔는데, 학습 완료 시간을 줄이려고 H100을 빌렸더니 몇 에폭 만에 학습이 붕괴했습니다. 계산 방식이 다르다는 뜻이죠(RTX 5080은 수천 에폭을 붕괴 없이 돌았습니다. 같은 스크립트, 같은 데이터였는데요).
- @stymaar — "상당 부분의 소프트웨어 크래시 원인"이라는 데는 회의적입니다. 로짓과 생성 토큰이 약간 달라지는 결과는 나오겠지만 크래시로 이어지지는 않을 겁니다. 겪고 계신 문제는 그냥 드라이버 버그일 가능성이 높아 보입니다.
- @rfgplk — 메모리/타일링 정렬 문제와 잘못된 명령어/기능입니다.
- @rfgplk — 맞아요, 100%입니다. 사실 GPU 코프로세서 관련 코드 작성은 CPU 코드 포팅과는 전혀 다릅니다. 같은 공급사의 GPU 세대를 바꿀 때도 커널 전체를 아예 새로 써야 하는 경우가 있습니다. 정밀도 같은 것들도 차이가 큽니다. 보통 이런 아키텍처 차이는 중간 플랫폼 계층이 처리하는데, 로우레벨 커널을 직접 작성한다면 적용되지 않는 경우가 많습니다.
원문: arXiv / 번역·요약: Trawling