Altifigence Academy

7 / 24 · 개념

누적 폭·반올림·포화

9개 signed int8 곱의 합을 담는 데 18비트 signed가 충분한가요? 바이어스는 0이라고 가정하세요.

출력 폭과 누적 폭은 다릅니다

8비트 입력과 8비트 가중치가 8비트 결과를 낸다고 해서 누적기까지 8비트로 만들 수는 없습니다. 부호 있는 8비트 코드의 절댓값은 최대 128입니다. zero point가 0이고 L개의 항을 누적한다면 보수적인 절댓값 경계는 L×128×128입니다. 바이어스의 절댓값도 더합니다. 이 경계를 담는 signed 누적기는 양수 최댓값이 경계 이상인 폭으로 선택합니다. 부호 비트가 필요한 점을 잊지 마세요.

폭 계산 예제

C=3,R=S=3이면 L=27입니다. 모든 입력과 가중치가 −128인 경우 곱은 +16384이고 총합은 442368입니다. 19비트 signed 최댓값은 262143이므로 부족합니다. 20비트 signed 최댓값 524287은 이 양의 경계를 담습니다. 바이어스 절댓값 1000을 포함한 경계 443368도 들어갑니다. 실제 입력 범위가 좁으면 더 작은 폭을 증명할 수 있지만 대표 입력 몇 개만 보고 폭을 줄이는 것은 증명이 아닙니다.

uint8 코드에 z=0이면 중심값은 0부터 255이므로 위의 128 경계를 쓸 수 없습니다. 두 중심값의 절댓값 범위를 먼저 구해야 합니다. 일반적으로 A=max(abs(qmin−zₓ),abs(qmax−zₓ)), B도 같은 방식으로 구해 L×A×B+abs(b)를 사용합니다. 중심값이 원래 저장 폭보다 넓어질 수 있으므로 뺄셈 결과 신호의 폭도 확인해야 합니다.

마지막 변환에서 순서 고정하기

정수 누적 A를 출력으로 바꾸는 multiplier는 sₓsᵥ/sᵧ입니다. 예를 들어 multiplier 0.5,zᵧ=128인 누적 9는 4.5를 짝수 4로 반올림해 출력 132를 만듭니다. 누적 11은 5.5를 6으로 반올림해 134입니다. 누적 −3은 −1.5를 −2로 반올림합니다. 단순 절삭, 0 쪽 절삭과 음수의 산술 시프트는 같은 연산이 아닙니다. JavaScript의 기본 Math.round도 음수 절반에서 이 계약과 다를 수 있으므로 실습에서는 별도 함수를 사용합니다.

범위가 int8이면 반올림한 300은 127로, −300은 −128로 포화합니다. 비트만 잘라내면 각각 44와 −44처럼 값이 뒤집힐 수 있습니다. 포화 전후 값과 포화 발생 횟수를 검증 로그에 남기세요. ReLU를 연결할 때 출력 zero point가 표현하는 0과 비교해야 하며 단계의 순서도 계약에 포함됩니다.

검증 기준

최대 양수 합, 큰 음수 합, 정확한 반올림 절반, 포화 직전·직후와 바이어스가 큰 경우를 모두 준비합니다. 넓은 기준 모델과 제한된 RTL 폭 모델의 차이를 의도적으로 재현하면 폭 오류를 쉽게 찾을 수 있습니다. 다음 실습의 예제는 값이 작은 안전한 정수 안에서 계산합니다. 큰 범위로 확장할 때는 기준 언어 자체의 정수 정확도도 검토해야 합니다.

직접 생각해 보기

9개 signed int8 곱의 합을 담는 데 18비트 signed가 충분한가요? 바이어스는 0이라고 가정하세요.

해설 보기

보수적인 양수 경계는 9×16384=147456입니다. 18비트 최댓값 131071보다 크므로 부족합니다. 19비트는 262143까지 담습니다.

선택은 이 브라우저에만 적용됩니다. 언제든 푸터에서 변경할 수 있습니다.