2026년 10월 14일 (UTC) 자 arXiv 신규 논문 공지에서 4비트 통신과 오차 보상(Error Compensation)을 다루는 Echo라는 논문을 접했습니다. 전달하는 값을 작게 만들면 가벼워집니다. 하지만, 0.02와 같은 업데이트를 10번 전달하더라도 수신 측의 합계가 계속 0으로 남게 되는 조건이 있습니다.
저는 오늘 이 반올림(rounding) 문제만을 파이썬으로 추출하여 잔차(residual)를 되돌리기 전후의 배열을 비교해 보았습니다. 10개 모두 0이었던 배열에 1이 2개 나타나는 것을 확인했습니다. 사소하지만, 저정밀화(low-precision) 검증에서는 개별적인 오차보다 이런 패턴을 먼저 보고 싶습니다.
여기서 확인하는 것은 일정한 간격으로 반올림하는 작은 실험입니다. Echo의 통신 알고리즘 재현이나 GPU에서의 속도/학습 정밀도 검증은 포함하지 않습니다.
간격을 0.1로 고정하고, 정수 부호를 포함한 4비트 범위에서 대칭적인 15단계인 '-77'을 사용합니다. 복원 가능한 값은 '-0.70.7'입니다. 나머지 한 가지 경우는 사용하지 않습니다. 정수 코드를 반환하는 것만으로 충분하며, 실제로 4비트씩 바이트 배열에 채워 넣는 처리는 생략했습니다.
0.02를 0.1 단위로 맞추면 0.2가 됩니다. 이것을 반올림하여 정수로 만들면 0이 됩니다. 10번 분량을 먼저 더하면 0.2가 남지만, 매회 반올림한 후 더하면 모두 사라집니다.
파이썬 3.14.8로 실행했습니다. 표준 라이브러리만으로 작동합니다. Fraction을 사용하는 이유는 이진 부동 소수점 표현 오차를 섞지 않고 반올림의 영향을 보기 위함입니다. round 함수의 정확히 중간값은 짝수 쪽으로 반올림됩니다.
from fractions import Fraction as F
STEP = F(1, 10)
def run(updates, feedback):
...
출력은 다음과 같습니다. 마지막 두 열은 복원된 값의 합계와 마지막에 손에 남은 오차입니다.
False [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 0 0
True [0, 0, 1, 0, 0, 0, 0, 1, 0, 0] 1/5 0
clipped: 21/10 3/10
feedback=True일 경우, 해당 회차에 복원하지 못한 분량을 residual에 저장합니다. 다음 번에는 새로운 입력에 더한 후 반올림을 합니다.
3회차에는 입력 0.02와 이월된 0.04가 합쳐져 0.06이 됩니다. 코드 1, 즉 0.1을 전달하고 잔차에는 '-0.04'를 남깁니다. 많이 전달한 분량도 다음 번 반올림에 반영됩니다.
잔차에는 음수 값도 들어갑니다.
초기 잔차가 0이라면, 각 회차의 residual = u - q * STEP을 더하면 중간 잔차가 상쇄됩니다. 결과적으로 '입력의 누적 합계 = 복원값의 누적 합계 + 마지막 잔차'가 유지됩니다. 코드의 첫 번째 assert에서 보는 것이 바로 이 관계입니다. 이번에는 10회차 잔차가 0이 되었기 때문에, 복원값의 누적 합계도 원래의 0.2와 일치했습니다.
Fraction의 출력이 1/5인 것도 로그를 읽을 때는 다소 번거롭습니다. 이번에는 소수점 표시로 변환하는 처리를 넣지 않아 계산 과정을 그대로 추적할 수 있도록 했습니다.
하지만 잔차를 가지고 있다고 해서 무엇이든 해결되는 것은 아닙니다.
마지막 입력은 0.8을 3회입니다. 상한인 0.7에 매번 잘라내기(clipping) 때문에, 입력 합계 2.4에 대해 전달할 수 있었던 값은 2.1이었고, 잔차는 0.3이었습니다. 입력이 계속 상한을 초과하면, 이월되는 양이 늘어납니다. 같은 관계식이 성립하더라도, 수신자에게 도달하지 못한 값은 남게 됩니다.
양자화 테스트에는 작은 동일 부호의 입력을 반복하는 시퀀스와, 상한을 초과하는 시퀀스를 모두 넣어보고 싶습니다. 전자는 업데이트가 사라지는 조건, 후자는 잔차가 쌓이는 조건을 분리하여 확인할 수 있습니다. 이 실험만으로는 학습 정밀도 유지까지는 말할 수 없으며, 업데이트가 도달하는 타이밍도 달라집니다. 구현을 빠르게 하는 단계에서도, 전달된 값의 누적 합계와 잔차를 함께 추적할 수 있는 검사는 남겨둘 생각입니다.