esp32-ai 소개
마이크로컨트롤러에서 언어 모델을 돌릴 때 모델 크기를 결정하는 것은 연산량이 아니라 빠른 메모리의 양입니다. ESP32-S3에 들어 있는 내부 SRAM은 512KB뿐이고, 토큰마다 수없이 읽히는 값들이 그 안에 들어가야 합니다. 임베딩 표는 보통 파라미터의 대부분을 차지하기 때문에, 표를 어디에 둘 것인가가 곧 모델 크기의 상한이 됩니다.
esp32-ai는 그 상한을 메모리 계층으로 우회한 프로젝트입니다. 2,890만 개 파라미터 가운데 2,500만 개를 조회 표(lookup table)로 만들어 느린 플래시에 남겨 두고, 한 토큰을 만들 때 그 표에서 필요한 여섯 줄 정도, 약 450바이트만 꺼내 씁니다. 모델 대부분은 실행을 위해 메모리로 올라오지 않고 플래시에 앉은 채 조금씩 샘플링됩니다.
이 배치를 가능하게 하는 것이 Google이 Gemma 3n에서 제시한 계층별 임베딩(Per-Layer Embeddings, PLE) 입니다. 원래는 휴대폰과 GPU를 염두에 둔 설계인데, esp32-ai는 같은 아이디어를 마이크로컨트롤러의 메모리 배치 위에서 구현했습니다.
esp32-ai가 내놓은 수치
| 항목 | 값 |
|---|---|
| 파라미터 | 2,890만 개 저장 (그중 2,500만 개는 플래시 조회 표) |
| 칩 | ESP32-S3, SRAM 512KB, PSRAM 8MB, 플래시 16MB |
| 속도 | 종단간 초당 9.88토큰, 토큰당 연산 94.9ms |
| 연결성 | 없음, 전부 기기 위에서 동작 |
| 모델 크기 | 4비트 양자화 기준 14.9MB |

esp32-ai의 세 계층 메모리 배치
각 계층에는 그 계층의 읽기 빈도에 맞는 것만 들어갑니다. 저장소는 이 배치를 다음과 같이 정리하고 있습니다.
SRAM (빠르고 작음) 활성값과 정규화 가중치, 토큰마다 여러 번 읽힘
PSRAM (중간) 코어와 출력 헤드, 위치마다 한 번 읽힘
FLASH (크고 느림) 2,500만 파라미터 표, 토큰당 약 6줄(450B) 읽음
실제 ESP32-S3 N16R8에서 Xtensa 사이클 카운터로 측정한 대역폭은 이 설계가 성립하는 근거입니다. 조회 표를 플래시에 두는 비용이 얼마나 되는지가 프로젝트 전체가 걸려 있던 숫자였습니다.
| 측정 항목 | 값 |
|---|---|
| PSRAM 순차 읽기 | 60.7 MB/s |
| 내부 SRAM 순차 읽기 | 240 MB/s |
| 플래시 무작위 읽기 (512바이트 한 줄) | 20.3 마이크로초 |
| 토큰당 표 비용 (무작위 6줄) | 약 0.12ms |
| 토큰당 출력 헤드 비용 (PSRAM 1.5MB 스캔) | 약 17.3ms |
| 대역폭만 고려한 상한 | 약 58 tok/s |
표를 읽는 비용은 토큰당 메모리 시간의 약 0.7%에 그칩니다. 오히려 시간을 잡아먹는 쪽은 기준 모델도 똑같이 치르는 출력 헤드입니다. 저장소는 이 0.7%를 "표의 합성 대역폭 점유율" 로 인용하라고 못 박고 있으며, 이것이 관측된 추론 처리량이 아니라 대역폭 기준 상한이라는 점도 함께 적어 두었습니다.
esp32-ai가 검증한 계층별 임베딩의 효과
배포 구성은 어휘 32,768, d_model 96, 6개 층, ple_dim 128이고 코어는 약 559K 파라미터입니다. 코어 크기를 맞춘 상태에서 두 개의 시드로 비교한 결과가 RESULTS.md 에 정리되어 있습니다.
| 구성 | 코어 | 전체 | 퍼플렉서티 | 기준 대비 |
|---|---|---|---|---|
baseline |
559K | 3.7M | 12.58 | — |
ple |
558K | 28.9M | 11.41 | 0.098 nats 개선 |
fatembed |
559K | 28.9M | 11.94 | 0.052 nats 개선 |
같은 코어를 쓰면서 SRAM에 들어가는 기준 모델보다 퍼플렉서티가 12.58에서 11.41로 내려갔고, 저장소는 이 차이가 시드 잡음의 약 16배라고 밝히고 있습니다. 임베딩을 아래쪽에 한 번에 주입하는 fatembed 와 비교하면 층마다 주입하는 쪽이 0.046 nats 더 좋았습니다.
어휘 크기가 이 효과를 좌우한다는 점도 대조군으로 확인되어 있습니다. 어휘 4,096에서는 PLE의 이득이 0.025 nats에 그치지만 어휘 32,768에서는 0.098 nats로 네 배가 됩니다. 어휘가 커질수록 표는 커지는 동시에 토큰마다 읽는 양은 그대로라서, 표를 느린 저장소에 두는 전략이 유리해지는 구간에 들어갑니다.
저장소는 "2,890만 파라미터" 라는 표현이 무엇을 뜻하는지도 분명히 해 두었습니다. 이것은 저장된 파라미터 수이고, "메모리 계층 분할로 상주시킨 파라미터" 로 인용해야 하며 능력의 배수로 읽어서는 안 된다고 적고 있습니다.
esp32-ai로 직접 돌려보기
내려받기와 배포가 서로 다른 명령으로 분리되어 있습니다. 한쪽은 네트워크에 닿고 다른 쪽은 보드를 건드립니다.
scripts/fetch_model.sh <tinystories|barista> # 내려받기, 검증, artifacts/ 에 설치
scripts/deploy.sh <tinystories|barista> # 헤더 생성, 게이트 실행, 컴파일, 플래시
scripts/fetch_model.sh 는 추론 자산을 스크립트에 고정된 SHA-256과 바이트 크기로 검사하고, 릴리스가 함께 배포하는 metadata.json 도 같은 값과 교차 확인합니다. 모든 검사를 통과해야만 설치하므로 내려받기가 실패해도 기존 파일은 그대로 남습니다. scripts/deploy.sh 는 네트워크에 전혀 접근하지 않고 artifacts/<model>/ 에 있는 것만으로 동작합니다. 보드가 한 번에 하나의 모델만 담기 때문에 두 명령 모두 모델 이름을 반드시 받습니다.
공개된 모델은 두 가지입니다. 이야기 생성용 TinyStories 모델 과 에스프레소 관련 질의응답용 Barista 모델 이 각각 Hugging Face에 올라와 있습니다. 재사용 가능한 아키텍처는 src/ 에, 공개된 수치를 재현하는 학습과 절제 실험, 양자화 코드는 research/tinystories/ 에 있습니다.
esp32-ai는 누구에게 유용한가
임베디드 환경에서 모델을 어떻게 쪼개 배치할지 고민하는 사람에게 참고 자료로 잘 맞습니다. 대역폭 측정과 절제 실험이 함께 공개되어 있어서 "왜 되는가" 를 숫자로 따라갈 수 있고, C 런타임이 내보낸 PyTorch 기준값과 32,768개 로짓 전부에서 최대 절대 오차 0.00001로 일치한다는 검증 절차도 그대로 드러나 있습니다.
반대로 쓸 만한 챗봇이나 비서를 기대하고 접근하면 맞지 않습니다. 학습 데이터가 TinyStories라서 짧고 단순한 이야기를 그럭저럭 일관되게 쓰는 정도이고, 질문에 답하거나 지시를 따르거나 코드를 쓰거나 사실을 아는 일은 하지 못합니다. 이 한계는 추론을 담당하는 작은 코어에서 오는 것이라 메모리 배치 기법으로는 바뀌지 않습니다. 흥미로운 지점은 2,890만 파라미터 모델이 무슨 말을 할 수 있는가가 아니라, 큰 모델을 작은 칩에 앉히는 구조 자체에 있습니다.
esp32-ai가 딛고 선 자료
학습에 쓰인 TinyStories는 작은 모델도 일관된 글쓰기를 배울 수 있을 만큼 단순한 합성 이야기 모음으로, Microsoft Research의 Ronen Eldan과 Yuanzhi Li가 공개했습니다. 다른 한 축인 계층별 임베딩은 Gemma 3n의 설계이고, 작은 언어 모델을 학습해 순수 C로 돌리는 부분은 Andrej Karpathy의 llama2.c 를 참고했습니다.
esp32-ai의 라이선스
esp32-ai는 MIT 라이선스로 공개되어 있어 개인 및 상업적 목적으로 자유롭게 사용할 수 있습니다.
TinyStories 논문
Google Gemma 3n 계층별 임베딩 문서
esp32-ai 프로젝트 GitHub 저장소
esp32-ai 모델 다운로드
더 읽어보기
-
Llama2.c: 순수 C로 작성된 Llama 2 추론 코드 (Llama2.c: Inference Llama 2 in one file of pure C)
-
Cactus: 스마트폰, 웨어러블 기기 등에서의 On-Device AI를 위한 고성능 추론 엔진 및 커널 라이브러리
-
TurboFieldfare: 8GB 맥북에서 Gemma 4 26B를 약 2GB 메모리로 돌리는 Swift 런타임
이 글은 GPT 모델로 정리한 초안을 바탕으로 한 것으로, 원문의 내용 또는 의도와 다르게 정리된 내용이 있을 수 있습니다. 관심있는 내용이시라면 원문도 함께 참고해주세요! 읽으시면서 어색하거나 잘못된 내용을 발견하시면 댓글로 알려주시기를 부탁드립니다. ![]()
이 도구를 직접 설치해 사용해보셨다면, 파이토치 한국 사용자 모임
회원들을 위해 경험이나 팁을 댓글로 남겨주세요! ![]()

