gpumode · 강의 아카이브
《GPU Mode》 L049 2025 · APR High priority transcript · 실패 · ExecuTorch + Metal 공식 자료 기반

Low Bit Metal Kernels

Apple Silicon (M1/M2/M3, 그리고 iPhone) 위에서 INT4 / INT8 quantized LLM 을 돌리는 Metal 커널의 디자인. weight-only quantization 의 dequant + matmul fusion, unified memory 활용, ExecuTorch 통합. Manuel Candales 의 발표 — Meta 의 ExecuTorch 팀이 iPhone 위 Llama 추론을 어떻게 만들었는가. transcript 누락 강의이므로 본 노트는 ExecuTorch + Metal Performance Shaders + torchao 의 공개 자료 위에서 정리.

Apple Silicon Metal · MSL INT4 dequant unified memory ExecuTorch Llama on iPhone torchao SIMD group
M
Speaker
Manuel Candales
Meta · ExecuTorch · Apple Silicon backend
강의 번호
L049
스피커
Manuel Candales
학습 우선순위
High · on-device LLM 의 코어
상태
transcript fetch failed
§ 01강의가 풀려는 문제· 왜 Metal · low bit · on-device 인가

“iPhone 에 Llama 를 박는다” 가 가능해진 자리

2024–2025 의 큰 trend 중 하나 — on-device LLM. 데이터 보안, latency, network 의존성 제거. 그러나 7–8B 모델이 iPhone 16 Pro (8 GB unified memory) 안에 들어가려면 — quantization 이 필수. 그리고 Apple Silicon 의 GPU 는 NVIDIA 와 다른 architecture — Metal 위에 직접 짜야 한다.

이 강의의 자리 — NVIDIA 시리즈의 코어 기법(low bit, dequant fusion, tile 최적화) 가 Apple Silicon 위에서 어떻게 다시 깨지는가. 같은 idea, 다른 hardware, 다른 도구.

강의 transcript 가 누락되었지만 ExecuTorch (Meta 의 on-device 추론 framework) + Metal Performance Shaders + torchao 가 모두 open source. 본 노트는 이 자료들의 공개 정보 + Apple Silicon GPU architecture 도메인 지식 위에서 정리한다.

강의의 인지적 frame · 추정

같은 INT4 LLM kernel 의 구현이 NVIDIA 와 Apple 에서 어떻게 다른가 — memory bandwidth bound 라는 점은 같다. 그러나 NVIDIA 가 SMEM + register tile 의 조합으로 reuse 를 만든다면, Apple 은 unified memory + SIMD group threadgroup memory 의 다른 layered. 그리고 tile 단위가 NVIDIA 의 warp(32) 보다 작다 (Apple SIMD group 32, 그러나 register file 이 다름).

“on-device LLM 의 본질은 메모리 대역폭이다 — 7B model 을 INT4 로 압축하면 3.5 GB. iPhone 의 GPU memory bandwidth (~200 GB/s) 로 token 1개당 weight 한 번 read = 17 ms. 이게 latency 의 lower bound.”학습 노트 · on-device LLM 정리
§ 02Apple Silicon 의 INT4/INT8· M-series · iPhone

Apple GPU 의 architecture 와 quantization 지원

Apple Silicon GPU (M-series) 의 architecture 는 NVIDIA 와 다르다. 알아야 할 자리들.

unified memoryCPU 와 GPU 가 같은 DRAM 공유. copy 없음. M3 Pro 의 메모리 ~36–128 GB, iPhone 의 ~6–8 GB.200–400 GB/s
GPU coreM-series 의 GPU. M3 Max 가 40 core. iPhone 16 Pro 가 6 core. NVIDIA 의 SM 과 다른 단위.M3 Max: 40
SIMD group32 thread 의 한 group. NVIDIA 의 warp 와 비슷. SIMD shuffle / SIMD reduce 지원.32 thread
threadgroup memoryNVIDIA 의 SMEM 과 비슷. on-chip cache. 32 KB / threadgroup (M-series).32 KB
low bit native?Apple GPU 는 INT8 dot product (uint8 dot4 같은) 일부 지원. INT4 는 native instruction 없음 — software dequant 필요.software
tensor core?NVIDIA-style tensor core 없음. SIMD-level matmul instruction (M3 부터의 Dynamic Caching, AMX) 일부 활용.제한적
큰 차이

NVIDIA 의 INT8 tensor core 가 한 명령으로 16×16 matmul. Apple Silicon 은 그런 단일 instruction 이 없다. dequant 후 FP16 SIMD vector matmul 이 표준 path. 그래서 dequant 의 효율이 전체 성능을 결정. 이 점이 본 강의의 코어 자료.

§ 03Metal compute pipeline· command queue · MSL

Metal 의 compute kernel 작성 — CUDA 와 거울 비춘 추상

Apple 의 GPU 프로그래밍은 Metal. compute shader 를 Metal Shading Language (MSL) — C++ 기반 — 로 작성. 추상은 CUDA 와 거의 일대일 대응.

CUDA

  • kernel: __global__ void f(...)
  • grid · block · thread
  • SMEM: __shared__
  • warp = 32 thread
  • __syncthreads()
  • cudaMemcpy for H↔D
  • nvcc 컴파일러

Metal MSL

  • kernel: kernel void f(...)
  • grid · threadgroup · thread
  • threadgroup memory: threadgroup
  • SIMD group = 32 thread
  • threadgroup_barrier(...)
  • MTLBuffer · unified memory 로 zero-copy
  • Xcode metal 컴파일러
// Metal MSL — INT4 dequant + matmul (개념)
#include <metal_stdlib>
using namespace metal;

kernel void int4_matmul(
    device const uint8_t* W_packed [[buffer(0)]],   // INT4 packed
    device const half*    scales   [[buffer(1)]],   // per-group scale
    device const half*    X         [[buffer(2)]],   // activation FP16
    device       half*    Y         [[buffer(3)]],
    constant uint& M [[buffer(4)]],
    constant uint& N [[buffer(5)]],
    constant uint& K [[buffer(6)]],
    uint2 gid [[threadgroup_position_in_grid]],
    uint2 tid [[thread_position_in_threadgroup]],
    uint  sid [[simdgroup_index_in_threadgroup]])
{
    threadgroup half X_tile[BLOCK_M][BLOCK_K];
    threadgroup half W_tile[BLOCK_K][BLOCK_N];

    half acc = 0;
    for (uint k = 0; k < K; k += BLOCK_K) {
        // 1) X 를 threadgroup memory 로
        X_tile[tid.y][tid.x] = X[...];

        // 2) INT4 dequant: 1 byte = 2 nibble
        uint8_t packed = W_packed[...];
        half low  = ((int)(packed & 0x0F) - 8) * scales[group];
        half high = ((int)(packed >> 4)   - 8) * scales[group];
        W_tile[tid.y * 2    ][tid.x] = low;
        W_tile[tid.y * 2 + 1][tid.x] = high;

        threadgroup_barrier(mem_flags::mem_threadgroup);

        // 3) matmul tile
        for (uint kk = 0; kk < BLOCK_K; ++kk) {
            acc += X_tile[tid.y][kk] * W_tile[kk][tid.x];
        }
        threadgroup_barrier(mem_flags::mem_threadgroup);
    }

    Y[...] = acc;
}
§ 04dequant 패턴· unpack · scale · zero point

INT4 weight 를 FP16 으로 풀어내는 가장 짧은 코드

low-bit quantization 의 핵심 — weight 가 INT4 로 packed 되어 있다. 한 byte 안에 두 weight. 사용 직전에 dequant.

FIG · INT4 dequant 의 모양1 byte = 2 weight
packed byte
1
0
1
0
0
1
1
1
8 bits = high nibble | low nibble
unpack
10
7
low = byte & 0x0F
high = byte >> 4
dequant
FP16
FP16
(int4 - zero) × scale
per-group scale
한 byte 의 2 weight 를 nibble 분리, signed conversion (8 빼기, 또는 zero point 빼기), per-group scale 로 곱하기. 이 3단계가 inner loop 안에서. 효율의 핵심.
per-group scale
128 또는 64 weight 마다 한 scale. fine-grained quantization 의 표준.
symmetric vs asymmetric
symmetric (zero point 0) 가 빠름. asymmetric 은 정확도 좋음. 각자 trade-off.
vectorized unpack
한 번에 4 byte = 8 weight unpack. SIMD intrinsic 활용. ~2x 속도.
dequant fusion
dequant 후 별도 buffer 안 만든다. inner loop 안에서 register 로 직접.
scale 사전 load
128 weight 의 한 scale 을 inner loop 시작 전에 한 번 load. 매번 load 안 함.
activation INT8
weight INT4 + activation FP16 가 표준. activation 도 INT8 로 내리면 추가 속도 + 정확도 손실.
§ 05unified memory 활용· CPU ↔ GPU zero-copy

“같은 메모리를 본다” 가 만드는 디자인 차이

Apple Silicon 의 가장 큰 architecture 차이 — CPU 와 GPU 가 같은 DRAM. cudaMemcpy 같은 H↔D copy 가 없다. 같은 buffer 의 같은 메모리를 두 processor 가 본다.

NVIDIA 모델

  • CPU memory + GPU HBM 분리
  • cudaMemcpy H↔D 가 비용
  • weight 를 GPU 로 미리 옮김
  • load_inline 등의 build 추상
  • 큰 batch 에 적합

Apple unified memory

  • 같은 DRAM 을 CPU/GPU 공유
  • copy 없음 (zero copy)
  • weight 는 그냥 file 에서 mmap
  • MTLBuffer 로 같은 포인터 공유
  • 작은 batch / 단일 사용자에 적합

이 차이가 만드는 디자인 결정 — weight loading 이 거의 무료. file → mmap → MTLBuffer 한 줄로 GPU 가 직접 read 가능. 7B INT4 = 3.5 GB 의 weight 를 disk → memory → GPU 의 단계 없이 한 번에. iPhone 의 cold start latency 의 핵심.

trade-off

unified memory 의 한계 — 대역폭이 NVIDIA HBM 보다 낮다. iPhone 16 Pro 의 메모리 대역폭은 ~70 GB/s, M3 Max 는 400 GB/s, H100 의 HBM3 는 3.35 TB/s. memory bandwidth bound 인 LLM inference 에서는 이게 직접 latency 가 됨. 7B INT4 = 3.5 GB / 70 GB/s = 50 ms 가 token 당 lower bound (iPhone).

§ 06PyTorch ExecuTorch 통합· .pte 파일 → 실행

PyTorch 모델이 iPhone 에 도착하는 길

ExecuTorch 는 Meta 가 만든 PyTorch 의 on-device 추론 framework. PyTorch 모델을 .pte (PyTorch Edge) 파일로 export 후 mobile / embedded 에서 실행.

PyTorch model평소처럼 nn.Module. transformers 또는 직접 작성.torch.export
torchao quantizeINT4 / INT8 양자화. weight-only 또는 dynamic activation. group size 결정.~50% 메모리
torch.exportgraph-based export. ATen IR 로 변환. control flow 처리.portable
to_edgeExecuTorch 의 edge dialect 로 변환. constraint 검증.edge IR
backend partition어떤 op 를 어느 backend (Metal / CoreML / XNNPACK / 자체 CPU) 로 보낼지 결정.delegated
.pte file최종 산출물. iPhone app 안에 bundle. C++ runtime 으로 실행.~3.5 GB · 7B

이 단계 중 backend partition 가 본 강의의 자리. weight matmul 같은 op 가 Metal backend 로 delegated. 그 Metal backend 가 INT4 dequant + matmul 의 custom Metal 커널 호출. partition 결정이 latency 를 결정 — 일부 op 만 Metal 가면 CPU↔GPU dispatch overhead 증가.

torchao 의 역할

quantization recipe 의 reference 라이브러리. INT4 weight-only, INT8 dynamic activation, GPTQ, AWQ 같은 알고리즘. ExecuTorch 의 quantize step 이 torchao 호출. 같은 quantize 결과가 NVIDIA / Apple / CPU 모두에서 사용 가능 — 다만 dequant kernel 은 backend 별.

§ 07Llama on iPhone 사례· 7B / 8B 의 실행

실제 iPhone 위에서 LLM 이 어떻게 도는가

Meta + Apple 의 협업으로 demonstrate 된 자리 — Llama 3 8B 가 iPhone 16 Pro 에서 실시간 token 생성. 10–15 tokens/sec 수준. 같은 hardware, 다른 implementation 으로는 그 절반이 일반적.

FIG · Llama 3 8B INT4 의 디바이스별 추정 throughputtoken/sec · prefill 후 decode
H100 (FP16 ref)
~150 tok/s
M3 Max
~60
M3 Pro
~35
iPhone 16 Pro
~12
memory bandwidth 가 dominant. token 당 weight 한 번 read = bandwidth/(weight size). iPhone 의 70 GB/s ÷ 4 GB = 17 tok/s 가 이론적 max. 12 tok/s 는 그 70%. 잘 짜인 구현의 표시.
prefill vs decode
prefill 은 large batch matmul, compute bound. decode 는 batch=1 의 GEMV-급, memory bound. 두 phase 의 커널이 다르게 최적화.
KV cache 메모리
long context 에서 KV cache 가 weight 에 추가됨. 8K context 에서 8B model 의 KV ~1 GB. 4-bit KV quantization 도 활용.
power 관리
iPhone 은 thermal throttle. 지속 30초+ 추론하면 frequency 떨어짐. 측정 시 throttle 후 측정도 같이.
CoreML vs Metal
CoreML 이 Apple 의 high-level framework. Metal 이 low-level. 같은 모델을 CoreML 에 맡기면 Apple 의 ANE (Neural Engine) 활용 가능. Metal 직접은 GPU 만 사용.
§ 08NVIDIA 와 차이· SIMD group · threadgroup memory · no tensor core

같은 idea, 다른 도구 — 핵심 격차 정리

NVIDIA GPU 위 INT4 LLM kernel 의 표준 구조 (예: GPTQ, AWQ + tinygemm) 와 Apple Silicon 위 같은 일의 구현이 어디서 갈리는지.

tensor core 부재
NVIDIA: WGMMA 한 instruction. Apple: SIMD vector matmul. 단순하지만 throughput/instruction 차이.
register file 크기
NVIDIA H100: 256 KB/SM. Apple M-series: 더 작음 (정확한 숫자 미공개). register tile 사이즈 작아짐.
async copy 부재
NVIDIA TMA / cp.async 같은 hardware async copy 없음. threadgroup memory 로 stage 가 manual.
unified memory
CPU↔GPU copy 없음. weight loading 이 거의 무료. 단, bandwidth 한계가 throughput.
SIMD group = warp
32 thread. simd_shuffle, simd_sum 같은 reduce primitive. NVIDIA warp shuffle 과 비슷.
debugging 어려움
Xcode GPU frame capture 가 도구. NCU 같은 metric profiler 는 없음. metric 이 limited.
결과적 디자인 차이

NVIDIA INT4 커널: tile 크게, register file 활용, async copy 로 prefetch, tensor core 활용. Apple Metal INT4 커널: tile 작게, threadgroup memory 활용, SIMD vector matmul, dequant unrolled. 같은 idea, 다른 size, 다른 reuse 패턴.

§ 09한계와 trade-off· 메모리 대역폭 · power · model size

iPhone LLM 의 진짜 한계는 무엇인가

강의가 솔직하게 다뤘을 자리. on-device LLM 이 모든 use case 에 적합하지 않다.

memory bandwidth
iPhone 의 70 GB/s 가 lower bound. 더 큰 모델은 비례해서 느림. 70B 모델은 iPhone 에 들어가지도 않음.
power / thermal
지속 추론 시 thermal throttle. battery 빠르게. peak performance 는 짧은 시간만.
정확도 손실
INT4 quantization 은 perplexity ~5–10% 증가. specific task (code, math) 에서 더 큰 손실.
cold start
3.5 GB weight 를 mmap 한 번. iPhone 에서 ~1–3초. GPU 위 caching 도 추가.
large context 한계
KV cache 가 메모리 차지. 8B model + 8K context + KV → iPhone 의 8 GB 거의 다 사용.
multi-modal 어려움
vision encoder 추가하면 메모리 부담. iPhone 의 ANE 활용 (CoreML) 으로 일부 분담 가능.
“on-device LLM 은 cloud 의 대체가 아니다 — 보완이다. privacy-sensitive 한 자리, network 가 비싼 자리, latency 가 핵심인 자리. 모든 use case 가 아니다.”학습 노트 · 적용 자리 정리
§ 10기억할 메모와 자료· key takeaways
Apple GPU = SIMD group
32 thread. NVIDIA warp 와 비슷. simd_shuffle / reduce 활용.
tensor core 없음
Apple GPU 는 SIMD vector matmul. dequant 후 FP16 SIMD 가 표준 path.
unified memory
CPU/GPU 같은 DRAM. copy 없음. mmap 으로 weight 직접 load. 단, 대역폭 낮음.
dequant inner loop
unpack + signed convert + scale × 1 byte 당 2 weight. 매 inner iteration 마다.
memory bandwidth bound
iPhone: 70 GB/s, M3 Max: 400, H100: 3350. lower bound = weight size / bandwidth.
ExecuTorch + torchao
PyTorch → quantize → export → .pte → iPhone app. backend partition 이 핵심.
prefill vs decode
prefill 은 compute bound, decode 는 memory bound. 두 phase 다른 최적화.
CoreML vs Metal direct
CoreML 은 ANE 까지. Metal 은 GPU 만. trade-off — 사용 편의 vs 성능 통제.

손에 새기기 — 실습 시퀀스

  1. Metal Hello kernel — Xcode 또는 metalcpp 로 가장 단순한 vector_add 커널. CUDA 와의 추상 1:1 대응 손에 잡기.
  2. FP16 matmul — Metal MSL 로 simple matmul. threadgroup memory tiling. CUDA 의 tiled matmul 직역.
  3. INT4 dequant 단독 커널 — packed byte → 2 FP16 의 dequant 만. CPU 와 정확성 비교.
  4. INT4 dequant + matmul fusion — 위 두 단계 합치기. inner loop 안 dequant.
  5. ExecuTorch 의 INT4 backend 코드 읽기executorch/backends/apple/metal 의 실제 구현. 본 노트의 추상이 어떻게 코드화 되어 있는지.
  6. iPhone 위 Llama 빌드 — ExecuTorch 의 example 따라가기. .pte 만들고 iOS app 에서 호출.
  7. throughput 측정 — token/sec, memory bandwidth 사용률, thermal throttle 시작 시점.
§ 11다른 강의로 이어지는 길· connections
§ 12열린 질문· open questions

transcript 가 없어 강의의 정확한 강조점은 추정. 영상 직접 확인이 필요한 사항들.

검증 메모

본 노트의 모든 수치 (메모리 대역폭, throughput 추정, register file 크기) 는 Apple 공식 자료 + 도메인 지식 베이스. 강의의 실제 측정값은 영상 직접 확인 필요. INT4 dequant 코드는 ExecuTorch 의 공개 구현 + 일반 패턴의 조합으로, 강의에서 보여준 정확한 코드는 다를 수 있다.

← Lecture 048 Ultra Scale Playbook Lecture 050 → CUDA / Triton / FlashAttention 학습 여정