본문 바로가기

dev_AI_framework

행렬 곱, bias 문제 내용

1) GEMM 출력 레이아웃을 잘못 가정

  • 증상: 임의 W/B에서 forward 오차 큼. W=0(=bias만) 또는 one-hot(W[0,0,0,0]=1)일 때만 맞음.
  • 원인: A @ W 결과를 **[HWo, Cout]**로 만들고도, 최종 출력 버퍼 y_n(NCHW 연속)을 **[HWo, Cout]**처럼 써버림.
    NCHW에서는 한 배치의 y_n 메모리가 [Cout, HWo] (채널이 행, HWo가 연속) 이어야 한다.
  • 해결: GEMM은 임시 Y_tmp[HWo, Cout]에 뽑고 → transpose 해서 y_n[Cout, HWo]에 기록.

2) W 패킹 시 K축 전개 순서(kh/kw) 뒤바뀜

  • 증상: bias만/one-hot은 통과하지만, 랜덤 W에서만 크게 틀림.
  • 원인: im2col이 K를 (ci, kh, kw)(그리고 kw가 최속)로 전개하는데, W pack 커널이 **(ci, kw, kh)**로 해석(=kh/kw 스왑).
  • 해결: W pack/unpack 커널 전부 kw → kh → ci 순서(= kw fastest)로 통일.

3) GEMM bias 브로드캐스트 축이 틀림

  • 증상: W=0, B≠0에서 오차(혹은 반대).
  • 원인: gemm_run의 bias를 열(column) 기준으로 더한다는 가정으로 넣었는데, 실제 최종 출력 버퍼는 **[Cout, HWo]**여서 행(row=채널) 기준으로 더해야 맞음.
  • 해결: gemm_run의 bias 사용 비활성화하고, 최종 y_n[Cout, HWo]에 대해 **row-wise(채널 축)**로 직접 더하는 커널(add_bias_rows) 사용.

4) Backward에서 dY 레이아웃 오해

  • 증상: numeric grad에서 dW, dB 불일치.
  • 원인: forward에서 최종 Y를 [Cout, HWo]로 저장했는데, backward에서 dY를 **[HWo, Cout]**인 것처럼 처리:
    • dB: reduce_db가 [HWo, Cout] 가정 → 채널 합산 축 잘못.
    • dW: dY에 불필요한 transpose 적용.
    • dX: 전치 없이 [HWo,Cout]로 가정하고 곱함.
  • 해결:
    • dB: dY[Cout, HWo]를 HWo로 합산(row-wise reduce).
    • dW: dY[Cout, HWo] @ X_col[HWo,K]로 그대로 곱함(전치 제거).
    • dX: transpose(dY) → [HWo, Cout] 만든 뒤 @ W_CK 수행.

한 줄 요약

  • 행렬 곱: 출력/그라디언트 텐서를 **실제 메모리 레이아웃([Cout, HWo])**에 맞추지 않고 [HWo, Cout]로 취급한 게 근본 원인.
  • bias: 채널(row) 축으로 브로드캐스트해야 하는데 열(column) 축처럼 더한 게 문제.
  • W pack: im2col의 K 전개 순서와 불일치(kh/kw 뒤바뀜).
  • Backward: dY의 레이아웃 해석 오류로 dB/dW/dX 축 처리 전부 어긋남.