Skip to content
sokldjs554Public

About

딥러닝 모델의 성능·지연·메모리를 반복 측정하며 NPU 최적화 전략을 탐색하는 모델 실험·경량화 프로젝트

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

npuloop — 가상 NPU 제약에 맞춘 모델 변경·학습·경량화

모델을 NPU의 연산 제약에 맞게 바꾸고, 재학습·양자화·프루닝한 뒤, 비트 정확한 정수 실행까지 직접 확인합니다.

tests

정확도는 저장된 실험의 측정값이고 NPU 사이클은 가상 프리셋의 추정값입니다. 실제 칩에서 측정한 값은 없습니다.

공개 데모

Live: https://sokldjs554.github.io/npuloop/ — 설치·서버·API 키 없이 열립니다. 로컬은 docs/index.html.

npuloop 워크벤치 둘러보기

52초 · 컷 12장. 저장된 실험 기록을 헤드리스로 실제 조작해 캡처했습니다(python tools/record_walkthrough.py). 화면의 모든 숫자에는 원본 JSON 보기 버튼이 붙어 있습니다.

처음 보는 분: 3분 확인 순서

  1. 모델 실험 — 구조를 바꾼 뒤 정확도가 어떻게 무너지고 회복되는지 봅니다. 기본 화면에서 E4의 변경 전 → 교체 직후 → 회복 학습 결과를 확인할 수 있습니다.
  2. NPU 분석 — 같은 모델이 가상 NPU 제약에서 어떤 연산을 호스트로 넘기고, 비용이 어디에 생기는지 확인합니다.
  3. 정수 검증 — fake-quant와 실제 integer execution의 정확도뿐 아니라 내부 정수 출력이 얼마나 다른지 확인합니다.
  4. 실험 기록 — 궁금한 수치를 E1–E20 원본 JSON과 검증 범위 문서까지 내려가 확인합니다.

빠르게 볼 때는 모델 실험 → NPU 분석 → 정수 검증 → 실험 기록 순서만 따라가면 됩니다. 브라우저는 저장된 실험 결과를 탐색하며, 새 학습과 실제 NPU 실행은 수행하지 않습니다.

왜 이렇게 설계했나

  • fake-quant 정확도만으로는 실제 정수 rounding·requantization 차이를 볼 수 없어 NumPy/C++ explicit integer execution을 따로 만들었습니다.
  • FLOPs/MACs 감소가 NPU 비용 감소와 같지 않아 pruning 판단에 가상 NPU cost model을 함께 넣었습니다.
  • 모델별 이름을 하드코딩하지 않기 위해 pruning은 torch.fx graph에서 channel dependency를 추적합니다.
  • SCALE-Sim은 수식 구현 검증, Arm Vela는 compiler-aware 외부 비교에 사용했으며 둘을 실리콘 실측으로 해석하지 않습니다.

설계 선택의 이유, 실패한 가설, 실제 NPU가 있을 때의 다음 검증 순서는 설계 판단 기록에 정리했습니다.

5분 코드 검토 경로

requant.py → prune/structured.py → npu/cost.py → study_runner.py → VALIDATION_SCOPE.md

각 파일에서 무엇을 확인해야 하는지는 docs/DECISIONS.md에 적었습니다.

하는 일

  • PyTorch 모델을 torch.fx로 추적해 BN을 접고 정적 그래프로 만듭니다
  • 가상 NPU 프리셋 4종에 대고 사이클·활용률·에너지를 추정하고, 온칩 실행 가능 여부를 lint로 판정합니다
  • 지원하지 않는 활성함수를 교체하고 채널을 프루닝한 뒤 회복 학습으로 정확도를 되찾습니다
  • 프루닝 채널 선택에 비용 모델을 루프 안에서 호출합니다 — MACs가 아니라 추정 사이클을 줄입니다
  • PTQ 7종·QAT·CLE·바이어스 보정·AdaRound로 INT8 양자화합니다
  • 정수 그래프를 내보내 NumPy와 C++ 두 엔진으로 비트 동일하게 실행하고, fake-quant와 연산자 단위로 대조합니다
  • 가상 고객 시나리오의 체크포인트를 받아 진단 → 처방 → 적용까지 하는 인테이크 리포트를 냅니다
  • 모든 숫자를 결과 JSON에서 생성해 문서·표·브라우저 데모에 주입합니다

구조

flowchart LR
    A[PyTorch 모델<br>ResNet-20 · MobileNetV2 · ViT] --> B[graph.trace<br>fx IR · BN folding]
    B --> C[npu.estimate<br>cycles · util · roofline]
    B --> D[lint<br>준비도 점수 · findings]
    C --> E[prune / surgery<br>array-aligned · act swap]
    D --> E
    E --> F[quant.prepare<br>PTQ · QAT · CLE · AdaRound]
    F --> G[intengine.export<br>int8 W · int32 b · M0,shift]
    G --> H[NumPy ⇄ C++ 정수 엔진<br>bit-exact]
    H --> I[verify<br>fake-quant vs integer<br>국소 vs 전파]
    I -. 결과가 다시 결정으로 .-> E
Loading

점선이 이 저장소의 성격입니다. 압축 결정을 FLOPs와 fake-quant가 아니라 비용 모델과 비트 정확한 정수 실행에 대고 내립니다.

찾은 것

  • 정확도가 같다고 텐서가 같지는 않습니다. 분류 6종 × 양자화 2종에서 모의·정수 정확도 차이는 최대 0.20%p였지만 출력 정수 코드의 **28.5–72.7%**가 달랐습니다(E15).
  • 원인을 지목하고 제거해 봤습니다. 가장 큰 국소 원천은 ViT의 LayerNorm(국소 불일치 24.8%)이고, 그것만 정수 산술로 바꿔 국소를 0%로 만들어도 전체 불일치는 **72.7% → 65.7%**까지만 내려갑니다(E16).
  • 같은 처방도 칩이 다르면 값이 달라집니다. GELU→ReLU 교체는 LUT가 있는 프리셋에서 0.37%, 없는 프리셋에서 −32%. 이 판정을 재학습 전에 합니다(E9).
  • 부정 결과를 지우지 않았습니다. AdaRound는 194개 계층 전부에서 재구성 오차를 줄였지만 8비트 top-1은 움직이지 않았고(E19), 이 저장소의 비용 모델은 Arm Vela 대비 5/5 낙관적입니다(E13).

검증 범위

무엇을 무엇에 대고 결과
정수 엔진 TFLite reference 커널 1,000장 × 모든 텐서 0 불일치 (E11)
NumPy 엔진 C++ 커널 모든 중간 텐서 비트 일치 — 테스트가 강제
비용 모델 SCALE-Sim v3 12개 조합 합계 오차 ≤ 0.08% (E8)
비용 모델 Arm Vela(벤더 추정기) 5/5 낙관적. 원인의 74.1%가 평균 풀링 (E13)

각 항목이 검증하지 않은 것까지 적은 표는 docs/VALIDATION_SCOPE.md에 있습니다. 실제 NPU에서 측정한 적은 없고, E8의 일치는 하드웨어 충실도가 아니라 같은 이상화를 공유하는 두 모델이 같은 식을 같게 구현했다는 확인입니다.

CPU 학습 중 만난 oneDNN의 1×1 conv backward-weights 오버플로는 benchdnn으로 단독 재현하고 2줄 패치까지 검증해 uxlfoundation/oneDNN#6035로 보고했습니다.

기술 구성

Python 3.11 · PyTorch(torch.fx · QAT · AdaRound) · NumPy · C++17 · TensorFlow Lite · pytest · GitHub Actions

실험 20개(E1–E20) · 가상 NPU 프리셋 4종 · 정수 커널 두 벌(NumPy·C++)과 파이썬 없는 독립 실행기 · fx 의존성 그래프 기반 구조적 프루너 · 브라우저 워크벤치.

실행

git clone https://github.com/sokldjs554/npuloop && cd npuloop && pip install -e .[dev]
make quickstart      # intake → quantize/verify → export + C++ 실행기
python -m pytest -q

데이터 다운로드도 학습도 없이 CPU 4코어 1분 안팎입니다(번들 체크포인트 2개 + CIFAR-10 샘플 1,012장, 6 MB). CLI는 여섯 동사입니다: npuloop cost | lint | intake | quantize | export | bench. 그중 npuloop quantize가 fake-quant와 정수 엔진을 노드별로 대조하는 명령입니다.

문서

범위

가상 NPU입니다. 실제 칩의 컴파일러(fusion·타일링·메모리 스케줄링)와 다르고, 비용 모델은 dense GEMM 사이클만 외부 대조했습니다. 주 평가는 CIFAR-10 5종·Imagenette 1종·초해상 2종이며, ImageNet 규모 결과(E20)는 ImageNet-1k 검증 정확도가 아닙니다. 혼합 정밀도는 없고(INT8 고정), 프루닝 대상은 residual 밖의 내부 채널뿐이며, CLE의 이득은 이 체크포인트들에서 보이지 못했습니다. 체크포인트를 바꾸면 결론 일부가 흔들립니다 — E3의 레이어 수준 상관과 E7의 3비트 곱셈기 손실이 재학습 후 달라졌습니다. 항목별 근거와 나머지 한계는 docs/EXPERIMENTS.md의 해당 실험 절에 있습니다.

데이터: CIFAR-10 (Krizhevsky, 2009) · Imagenette (fast.ai). SCALE-Sim은 E8, ethos-u-vela는 E13 검증에서만 씁니다.

About

딥러닝 모델의 성능·지연·메모리를 반복 측정하며 NPU 최적화 전략을 탐색하는 모델 실험·경량화 프로젝트

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages