본문 바로가기

dev_AI_framework

Low-level GEMM 직통 경로 사용 가이드 (ai::Tensor 기반)

이 문서는 graph_executor_v2.ops._ops_gemm 모듈에서 Zero-copy로 GPU 버퍼를 바로 넘겨 forward/backward를 호출하는 방법을 정리합니다. 고수준 forward_numpy 대비 파이썬/메모리 변환 오버헤드가 없어 작고 빈번한 호출에서 특히 유리합니다.


무엇이 다른가?

  • 이전: forward_numpy(A_np, B_np, bias_np, ...)
    ↳ NumPy 호스트 배열 → 내부에서 H2D 복사/검사/래핑 → 커널 실행 → (필요 시) D2H
  • 지금: forward(A, B, Bias, Y, attrs, stream)
    이미 GPU에 있는 버퍼의 포인터를 ai::Tensor로 Zero-copy 래핑 → 곧바로 커널 실행

전제 조건

  • 입력/출력 버퍼는 GPU(CUDA) 상에 있어야 합니다. (CuPy/Torch 텐서 권장)
  • 현재 경로는 f32, row-major, non-transpose만 지원(필요 시 attrs.trans_*는 있으나 기본은 false).
  • Bias 브로드캐스트: Scalar / PerN(N) / PerM(M) 지원. 직관적으로는 [1,N](row-major)로 잡으면 PerN으로 동작.

공개된 심벌 (re-export)

from graph_executor_v2.ops import _ops_gemm as gemm

  • 타입: gemm.ActKind, gemm.GemmAttrs, gemm.Device, gemm.DType, gemm.Layout, gemm.TensorDesc, gemm.Tensor
  • 팩토리: gemm.make_tensor_2d(ptr_u64, shape, dtype=F32, device=CUDA, device_index=0)
  • 함수:
    • gemm.forward(A, B, Bias_or_None, Y, attrs, stream_or_None) -> None
    • gemm.backward(A, B, C_or_None, gY, Z, gA_or_None, gB_or_None, gC_or_None, gBias_or_None, attrs, stream_or_None) -> None
    • (옵션) gemm.forward_ex(...), gemm.backward_ex(...) — 파라미터를 파이썬 프리미티브로 전달

스트림/에러 처리

  • stream 인자는 void*로 받습니다. CUDA 스트림 포인터를 그대로 int→ctypes.c_void_p로 캐스팅해 전달할 수 있습니다. 일반적 사용은 None(기본 스트림).
  • 실패 시 C++ ai::Status가 파이썬 예외로 변환됩니다. 메시지 예:
    • DeviceMismatch: CPU 텐서를 전달하거나, 디바이스 인덱스 불일치
    • DtypeMismatch: 현재 f32만 지원
    • LayoutMismatch: row-major만 지원
    • StrideMismatch: leading dimension(lda/ldb/ldd) 불일치
    • ShapeMismatch: M,K / K,N / Y(M,N) 검사 실패
    • MissingInput: 필수 입력 누락 (예: gC 필요 케이스)
    • Invalid: 범위/유효성 오류

성능 팁

  • Zero-copy를 유지하세요: GPU 텐서의 포인터를 직접 넘기면 H2D/D2H 전송이 없습니다.
  • 버퍼 재사용: 반복 호출에서 같은 출력 버퍼를 재사용해 할당/해제 오버헤드를 줄이세요.
  • 워밍업: 5–10회 워밍업 후 타이밍을 재면 클럭/캐시 안정화로 지터 감소.
  • 큰 행렬일수록 고수준 경로와의 격차는 줄고, 작은 행렬/짧은 시퀀스에서 직통 경로 이점이 큼.

문제 해결 (FAQ)

  • AttributeError: module ... _ops_common has no attribute 'Device'
    ↳ _ops_common이 구버전입니다. 중복 .pyd 제거 후 클린 빌드/재시작. (개발 노트 참조)
  • DeviceMismatch
    ↳ make_tensor_2d(..., device=CUDA, device_index=<GPU>)가 입력 간 일치하는지 확인.
  • Bias 크기/모양
    ↳ PerN이면 [1,N], PerM이면 [M,1]로 래핑(Stride는 row-major 기본: [ld,1]).
  • LeakyReLU 기울기
    ↳ attrs.leaky_slope를 0이 아닌 값으로 설정해야 반영됩니다.