Apple M3 Neural Engine에서 DRAM 대역폭 50 GB/s 되찾기
Getting 50 GB/S Back from the Apple Neural Engine
TL;DR Highlight
ANE 가중치를 1MiB 배수로 보내면 느려져, 쪼개 보냈더니 Llama 3.2 1B가 10→24.3 tok/s
Who Should Read
Apple Silicon M3에서 ANEMLL로 온디바이스 LLM을 돌리는데 토큰 속도가 기대보다 낮아 고민인 개발자
Core Mechanics
- 가중치가 1MiB 배수면 대역폭이 급락
- M3 Neural Engine에서 코어당 가중치 총량이 1MiB의 정수배이면 DRAM 스트리밍이 17–19 GB/s로 떨어진다.
- 정상일 때는 45–60 GB/s이고, ANEMLL 15개 모델 중 7개가 해당된다.
- D=2048이 D=2016보다 훨씬 느리다
- 같은 M3 Air에서 40회 반복 측정한 결과 D=2016은 44.5 GB/s, D=2048은 16.93 GB/s였다.
- 레지스터 파일에서는 주소와 크기만 바뀌었고, 전송 자체는 정상 완료되는 성능 문제다.
- 코어 수나 주소 배치 탓이 아니었다
- 활성 코어를 1~16개로 바꿔도 지연이 같아서 코어 간 경합이 아니라 코어 단위에서 이미 생기는 문제였다.
- 주소를 무작위로 섞어도 중앙값이 31.37 대 32.29 GB/s로 거의 같아 DRAM 뱅크 충돌 가설은 기각됐다.
- D와 N을 반대로 바꿔도 코어당 1MiB면 느려진다
- 코어당 가중치 총량만 1MiB로 맞추면 D, N 조합과 무관하게 17 GB/s로 떨어졌다.
- 1MiB는 64바이트 라인 0x4000개이고, 회복 구간은 정확히 ±256라인(16KiB, 페이지 하나)이다.
- 원인은 커널 DMA 선행 읽기(prefetch) 링의 14비트 포인터로 추정된다
- 글쓴이는 14비트 head/tail 계산에 랩 구분 비트가 없어 한 바퀴가 '비어 있음'으로 보인다고 본다.
Community Reactions
- M1과 M5 Max는 영향이 없다는 정보
- 댓글에서 모든 칩이 해당되는 것은 아니고 M1과 M5 Max는 정상이라는 링크가 공유됐다.
- 소프트웨어로 해결 가능한지에 대한 질문
- 앱이 직접 우회하지 않으면 M3 사용자는 그대로 느린 건지 묻는 댓글이 있었다.
- 10에서 24 tok/s로 오르는 폭이 놀랍다는 반응이었다.
- 글에 나온 RTL이 가설인지 실제인지 묻는 의견
- 댓글에서 SystemVerilog 코드가 실제 소스가 아니라 글쓴이의 추측인지 확인하려는 질문이 나왔다.
- 용어 사용에 대한 지적
- 'erratum'은 보통 문서 오류 정정 공지를 가리키는 말이라 이 맥락에 맞는지 의문이라는 의견이 있었다.
How to Apply
- 모델의 코어당 가중치 크기를 계산해 1MiB 배수를 찾기
- 오늘 각 projection의 Cin×Cout×2바이트÷16을 계산해 1MiB의 정수배인지 확인하라.
- Llama 3.2 1B의 2048×8192 같은 항목이 해당된다.
- 1MiB 배수 projection은 둘 이상의 태스크로 쪼개기
- 컴파일 단계에서 코어당 1MiB가 되는 kernel DMA 태스크를 512KiB 이하 조각으로 나누어라.
- 글의 표처럼 Llama 3.2 1B는 4조각, 0.5MiB/lane으로 나누었다.
- 쪼개기 전후 tok/s와 GB/s를 같은 조건에서 비교하기
- 같은 기기에서 같은 열 조건으로 원본과 쪼갠 버전을 번갈아 측정하라.
- 1MiB 배수가 아닌 레이어를 대조군으로 넣어 효과를 확인하라.
- 패딩은 쪼개기가 어려울 때만 쓰기
- 전송 크기를 1MiB에서 ±8KiB(256라인) 이상 떨어뜨리면 회복된다.
- 계산 그래프가 바뀌므로 쪼개기를 먼저 시도하라.
Try It
# Claude 또는 ChatGPT에 붙여넣기 (원문 방법의 간이 버전: 모델 크기 점검용)
나는 Apple M3 Neural Engine에서 LLM을 돌린다. ANE는 가중치를 16개 코어로 나눠 읽고, 코어당 가중치 총량이 정확히 1MiB의 정수배이면 DRAM 읽기가 17-19 GB/s로 느려지는 문제가 보고됐다. 정상 속도는 45-60 GB/s다.
아래 projection 목록에서 코어당 바이트를 (Cin × Cout × 2 ÷ 16)으로 계산해라. 1MiB(1048576바이트)의 정수배인 항목을 표로 표시하고, 각각 512KiB 이하로 쪼개는 개수를 제안해라.
{{projection 목록: 이름, Cin, Cout}}
이어서 해 볼 것: 쪼갠 뒤 tok/s를 원본과 같은 조건에서 비교하는 측정 계획을 써 줘.Terminology
관련 논문
Mercury 3: 규모를 키운 diffusion LLM, 초당 1,000토큰 이상
Diffusion LLM을 40배 키웠더니 속도 4~8배, 품질은 속도 특화 모델 수준
Timestral: Mistral의 시계열 파운데이션 모델
209M 파라미터 시계열 모델이 3대 벤치마크 1위, CPU에서도 돌아간다
DeepSeek V4.1 Flash 1017 (Max) 성능·속도·가격 분석
DeepSeek V4.1 Flash 1017 Max는 지능 지수 45에 211 tok/s, 입력 $0.30
LLM 프록시를 직접 안 돌리면 무슨 일이 벌어지는지 어떻게 아나
자체 LLM 프록시를 세웠더니 키·모델·캐시 미스를 직접 볼 수 있다
DeepSeek V4.1 Flash 1017: 싼 가격에 1M 컨텍스트를 주는 에이전트용 모델
DeepSeek V4.1 Flash 1017은 입력 $0.05/M, 1M 컨텍스트의 에이전트용 모델
DeepSeek-V4.1-Flash-1017 공개: 더 짧게 생각하고 더 빠르게 일하는 에이전트용 모델
DeepSeek V4.1 Flash 마이너 업데이트로 코딩·에이전트 벤치 점수↑, 실행 시간·출력 길이↓
Llmspeed: 로컬 LLM 속도를 하드웨어 구매 전에 체감해 보는 시뮬레이터
GPU·모델을 고르면 로컬 LLM 속도를 미리 체감하게 해 주는 시뮬레이터