모든 이야기

혼합 정밀도 누산: 작은 항 100개가 사라지는 계산을 되살릴까

낮은 정밀도 입력으로 계산하면서 누산기만 넓히면 정확도를 얼마나 회복할 수 있을까. 혼합 정밀도 누산의 목적은 입력 저장과 곱셈의 비용을 줄이면서, 많은 항을 더할 때 반복되는 반올림 손실을 줄이는 데 있다. 다만 입력에서 이미 사라진 정보와 누산 중에 사라질 정보는 서로 다르다.

여기서는 binary16 입력과 binary32 누산을 생각한다. HardFloat의 표준 형식 표는 binary16의 유효숫자 정밀도를 11비트, binary32를 24비트로 구분한다. 지수 범위와 유효숫자 폭이 모두 다르므로 비트 수만으로 오차를 설명할 수 없다.

작은 항 100개가 모두 사라지는 예

초기 누산 값이 1이고, 새 항은 모두 2⁻¹¹이라고 하자. 두 값은 binary16과 binary32로 정확히 표현할 수 있다. round-to-nearest-even을 사용한다.

binary16에서 1 위쪽의 인접한 값 간격은 2⁻¹⁰이다. 2⁻¹¹을 더하면 정확히 그 간격의 절반이다. 현재 1의 마지막 보존 비트가 even이므로 결과는 다시 1로 반올림된다. 다음 항도 같은 상황을 만들고, 100번 반복해도 매번 binary16으로 저장하면 누산 값은 1이다.

binary32로 누산하면 이 항의 크기는 충분히 보존된다. 정확한 합은 1+100×2⁻¹¹ = 1.048828125이고 이 값은 binary32에서 정확히 표현된다. 이 예에서 최종적으로 binary16으로 바꾸어도 1.048828125는 표현 가능한 값이다. 차이는 마지막 저장이 아니라 각 덧셈 뒤의 반복 반올림에서 생겼다.

누산 계약100개 항을 더한 결과
매번 binary16으로 반올림1
binary32로 유지1.048828125

표는 통제된 자체 예제다. 실제 모델의 정확도 개선율이나 특정 가속기의 결과가 아니다. 입력 값과 중간 합이 이진수로 정확한 경우를 골라 누산 폭의 영향만 드러냈다.

넓은 누산기가 입력 오차를 되돌리지는 못한다

입력을 binary16으로 변환할 때 원래 수가 두 표현 값 사이에 있었다면 이미 반올림 오차가 생긴다. 넓은 누산기는 변환된 입력들을 더 정확하게 합할 수 있지만, 원래의 낮은 비트를 복원할 정보가 없다.

곱셈에서 어느 폭으로 반올림하는지도 중요하다. binary16 두 입력의 정확한 곱을 binary32에서 더하는 계약과, 곱을 먼저 binary16으로 반올림한 뒤 binary32에 누산하는 계약은 다르다. 곱 결과가 binary16 범위를 넘거나 매우 작으면 먼저 반올림한 정보 손실이 커질 수 있다.

또 fused 연산이면 각 곱과 현재 합 사이의 중간 반올림이 줄어들 수 있다. SoftFloat의 FMA 설명은 곱과 합에 single rounding을 적용하는 의미를 명시한다. 입력·곱·누산·최종 변환의 형식과 반올림 경계를 모두 알아야 혼합 정밀도의 실제 함수를 정의할 수 있다.

“입력 FP16, 누산 FP32”라는 표지만으로 모든 accelerator의 중간 연산이 같다고 추정해서는 안 된다. 지원 문서에 정해진 입력 변환과 곱의 정확도, 누산 순서와 특별값 정책을 확인해야 한다.

항의 크기와 합의 순서가 남기는 오차

binary32 누산도 유한한 정밀도다. 누산 값이 매우 커지면 그 주변 간격보다 작은 항은 다시 사라질 수 있다. 넓어진 폭은 손실 경계를 멀리 옮기지만 없애지는 않는다.

양수·음수 항이 서로 상쇄하면 누산 중에 잃은 작은 차이가 최종 결과에서 중요한 부분이 될 수 있다. 입력들을 다른 묶음으로 합하는 병렬 구조는 반올림 순서도 바꾸므로 같은 누산 형식이어도 결과가 달라질 수 있다. 출력 tolerance를 정할 때 입력 개수와 scale, 상쇄 정도를 함께 고려해야 한다.

초기값 1에 같은 작은 양수만 더한 예는 누산 폭의 효과를 명확히 보여 주지만, 모든 실제 dot product의 오차 상한을 제공하지 않는다. 실제 데이터 분포가 얼마나 다양한지, 어떤 범위에서 overflow나 underflow가 생길 수 있는지도 따로 보아야 한다.

회로는 저장 폭뿐 아니라 경로도 넓어진다

넓은 누산기는 결과 상태와 정렬·덧셈·반올림 경로의 비용을 늘릴 수 있다. 낮은 정밀도 입력을 쓰는 장점은 입력 전달과 곱셈 자원에서 얻을 수 있지만, 누산기의 상태와 피드백 경로가 처리율을 제한할 수 있다.

여러 독립 누산을 교대로 실행하면 pipeline을 활용할 수 있고, 같은 합을 연속 갱신하는 의존 사슬은 이전 결과를 기다려야 한다. peak 연산 수가 같아도 실제 처리율은 누산 dependency와 결과 전달 경로에 달린다. 정확도와 성능을 비교할 때 작업 형태를 고정해야 한다.

최종 출력이 다시 낮은 정밀도라면 마지막 변환의 saturation·rounding 또는 특별값 규칙도 명시한다. 넓게 계산한 결과를 잘못된 방식으로 줄이면 누산 중 확보한 이득을 다른 계약으로 바꾸어 버릴 수 있다.

검증에서는 넓은 누산의 정상 예에 더해 작은 항이 반복되는 입력, 큰 항 뒤 작은 항, 부호 상쇄와 최종 형식의 경계를 넣어 본다. 기준 모델에는 실제 입력으로 변환된 값부터 넣어, 입력 오차와 누산 오차를 분리하면 비교가 명확해진다.

혼합 정밀도 누산의 장점은 작은 입력을 무손실 숫자로 바꾸는 마법이 아니라, 더하는 동안 반복해서 버릴 정보를 줄이는 데 있다. 비교의 기준은 입력 정밀도 다음에 곱과 누산의 반올림 위치, 항의 크기와 최종 변환을 확인하는 것이다. 그 계약을 고정해야 넓은 누산기가 실제로 무엇을 회복했는지 알 수 있다.