배우기 · 8
디버깅
WebGPU 는 조용히 실패한다. 잘못 만든 파이프라인에 예외를 안 던지고 명령 버퍼를 버린 다음, 그냥 틀린 수를 준다. 이 강의는 장치에 물어볼 수 있는 것들이고, 하나하나가 이 저장소에서 무언가 조용히 잘못됐기 때문에 생겼다.
이게 진짜 GPU 인가
헤드리스 브라우저는 소프트웨어 래스터라이저를 준다. 그것도 어댑터라 아무것도 안
던진다. 거기서 잰 시간은 이 라이브러리의 수가 아니라 그 래스터라이저의 수다.
probe() 는 초기화 전에 답하고, "브라우저에 WebGPU 가 없다" 와
"드라이버가 거절했다" 를 갈라 준다.
GPU 가 무언가를 거절했나
검증 오류는 예외가 아니라 이벤트로 온다. 장치가 그것을 세고 첫 메시지를 붙잡아 둔다 — 셰이더 하나가 깨지면 그 뒤 dispatch 마다 같은 오류가 다시 나서 진짜 원인이 화면 밖으로 밀리기 때문이다. 실제로 벤치가 무효한 명령 버퍼를 안고 ms/step 을 냈고, 그 수는 측정이 아니라 학습이 안 되는 상태의 벽시계였다.
무엇을 쥐고 있나
묻는 것이 둘이라 수도 둘이다. memory 는 "새는가" 를 묻고 통을 일부러
빼며, pooled 는 "얼마나 쥐고 있는가" 를 묻고 다시 쓰려고 기다리는
것까지 센다. 통은 모양이 바뀔 때 자란다 — 버퍼가 크기별로 나뉘어 있어서 배치 16 의
것은 배치 32 에 못 쓰인다.
기울기가 정말 흘렀나
값만 대조하는 검사가 못 보는 함정이다. 연산이 옳은 수를 내면서 기울기를 조용히
떨어뜨린다. GPU 쪽의 roll 과 maskedSelect 가 그렇게
끊겨 있었고 그때 골든은 전부 초록이었다. 묻는 것은 싸다 — 역방향을 돌리고
.grad 가 도착했는지만 보면 된다.
오류는 torch 가 하는 말을 한다
borch 가 거절할 때는 torch 가 쓰는 문구로 거절한다. 검색창에 붙여 넣을 그 문장이 같아야 하기 때문이다. 그 동등성은 검사한다 — 오류 12 건, 검색 가능한 메시지 9 건.
라이브러리가 먼저 하는 말
첫 페이지가 저지르는, 조용히 느려지거나 틀려지는 일 다섯 가지가 있고, 라이브러리는 각각에
한 문장을 콘솔에 말한다 — 숫자가 틀리기 전에, 한 번만: scope 없는 추론
루프(밖에서 붙든 버퍼가 2,000 개째일 때), gradient 가 켜진 채 돈 eval()
모델, 빠른 커널이 원하는 8 의 배수에서 벗어난 큰 행렬곱, 배터리로 도는 노트북, 그리고
오래 걸린 첫 호출(커널 컴파일). Device.advised 가 말한 것을 들고 있고,
Device.advice = false 는 무엇을 하는지 아는 벤치를 조용히 시킨다.
기억할 것
- 수가 틀렸는데 아무것도 안 터졌을 때는 장치에 물어라: 모양·dtype·NaN/Inf 를 확인.
- 기울기가 실제로 흐르는지 확인 — 0 이거나 없는
.grad는 끊긴 그래프. - 중간 값을 읽어라(print 또는
show); 추측하지 말 것. - 평평하거나 폭발하는 손실은 미스터리가 아니라 신호다(버그 고쳐 보기 참고).
- 콘솔을 한 번 읽어라: 흔한 함정 다섯을 라이브러리가 먼저, 각각 한 번 말한다.
docs/BOOK.md)의
「Seven places where green can be a lie」다. 위의 계측 손잡이들은 그중 셋을 어렵게
배운 결과로 생겼다.