8달러 ESP32에 2,890만 매개변수 LLM을 넣은 방법

512KB SRAM을 가진 ESP32-S3에서 2,890만 매개변수 언어 모델이 돌아갔어요. 모델 전체를 빠른 메모리에 올리는 대신, 토큰마다 필요한 데이터만 플래시에서 읽는 구조로 약 초당 9.5토큰을 만들었어요. 다만 이 모델은 질문에 답하는 챗봇이 아니라 짧은 이야기를 생성하는 실험용 모델이에요. 1
핵심 요약
| 구분 | 확인된 내용 | 눈여겨볼 점 |
| 하드웨어 | 약 8달러인 ESP32-S3 N16R8 한 개를 사용해요 | 서버 없이 기기 안에서 추론해요 |
| 모델 | 4비트 기준 14.9MB, 저장 매개변수 2,890만 개예요 | 매개변수 수와 추론 능력을 같은 뜻으로 보면 안 돼요 |
| 메모리 | 512KB SRAM, 8MB PSRAM, 16MB 플래시를 나눠 써요 | 2,500만 매개변수 테이블은 플래시에 남겨요 |
| 속도 | 전체 출력 기준 약 9.5tok/s, 순수 연산은 9.72tok/s예요 | 작은 화면에서 문장을 읽을 만한 속도예요 |
| 한계 | TinyStories 형식의 짧은 이야기만 생성해요 | 질의응답, 코딩, 사실 검색에는 맞지 않아요 |
1. 작은 칩에 큰 저장 모델을 넣은 메모리 설계
2,500만 매개변수는 플래시에서 기다려요
ESP32-S3의 내부 SRAM은 512KB예요. 일반적인 방식으로 14.9MB 모델 전체를 올릴 수 없어요. 제작자는 2,890만 매개변수 가운데 2,500만 개를 플래시의 조회 테이블에 두고, 매 토큰에 필요한 약 6개 행만 가져오도록 설계했어요. 한 토큰을 만들 때 플래시에서 읽는 양은 약 450바이트예요. 2
이 구조는 Google Gemma 계열의 Per-Layer Embeddings를 마이크로컨트롤러 메모리에 맞게 적용한 방식이에요. 큰 임베딩 테이블을 매번 통째로 읽지 않고, 현재 토큰과 각 레이어에 필요한 행만 골라요. 자주 계산하는 작은 코어는 빠른 메모리 가까이에 두고, 크지만 드물게 읽는 테이블은 느린 플래시에 남겨요.
SRAM, PSRAM, 플래시가 다른 일을 맡아요
메모리 역할도 분명하게 나뉘어요. 연산 코어는 모든 토큰에서 반복해서 쓰여요. 출력 헤드와 작업 메모리는 8MB PSRAM을 사용해요. 2,500만 매개변수의 레이어별 임베딩 테이블은 16MB 플래시에 머물러요. 완성된 모델 파일은 14,912,332바이트이고, 별도로 잡은 약 15.6MB 플래시 파티션에 들어갔어요. 3
실측 결과를 보면 플래시 조회가 전체 병목은 아니었어요. 6개 행을 무작위로 읽는 데 약 0.12ms가 걸렸고, 합성 대역폭 측정에서 테이블 조회가 토큰당 메모리 시간의 약 0.7%를 차지했어요. 반면 출력 헤드는 토큰마다 PSRAM에서 더 많은 바이트를 읽어요. 현재 구현은 출력 헤드의 메모리 대역폭 영향을 더 크게 받아요.
약 9.5tok/s는 여러 최적화를 거친 결과예요
첫 번째로 정확하게 동작한 C 포트는 초당 0.57토큰에 그쳤어요. 출력 헤드를 PSRAM에 배치하고 계산을 정리한 뒤 4.61~4.77tok/s로 올라갔어요. 두 코어를 함께 쓰자 5.67~6.22tok/s가 나왔고, 출력 헤드와 활성값을 int8로 처리한 현재 구현은 전체 출력 기준 약 9.5tok/s에 도달했어요. 순수 모델 연산 시간은 토큰당 102.9ms예요. 3
4비트 양자화도 저장 공간을 줄이는 데 쓰였어요. 제작자가 공개한 두 시드 실험에서는 양자화 뒤에도 Per-Layer Embeddings 모델과 같은 크기의 연산 코어를 쓴 기준 모델 사이의 perplexity 차이가 유지됐어요. 이 결과는 큰 조회 테이블을 플래시에 두는 방식이 저장 공간뿐 아니라 모델 품질 비교에서도 작동했음을 보여줘요.
매개변수 수가 곧 성능은 아니에요
2,890만이라는 숫자 가운데 2,500만은 토큰별로 선택해서 읽는 임베딩 테이블이에요. 실제로 복잡한 추론을 맡는 조밀한 코어는 약 55만 9,000개 매개변수 규모예요. 저장된 전체 매개변수가 이전 ESP32 실험보다 약 110배 많아도, 추론 능력이 110배 늘었다고 해석할 수 없는 이유예요.
모델은 TinyStories 데이터로 학습했어요. "Once upon a time" 같은 시작 문장 뒤에 짧고 단순한 이야기를 이어 쓸 수 있어요. 질문 답변, 명령 수행, 코드 작성, 세계 지식, 산술, 여러 단계 추론은 지원하지 않아요. 제작자도 이번 결과의 가치를 생성 품질보다 메모리 계층을 나눈 배치 방법에 두고 있어요. 4
인터넷 없는 작은 기기에 적용할 여지가 있어요
이 설계는 대형 챗봇을 가전제품에 그대로 넣는 방법과는 거리가 있어요. 대신 어휘와 작업 범위가 좁은 로컬 기능을 검토할 때 참고할 만해요. 네트워크를 쓰지 않으므로 입력을 서버로 보내지 않고, 연결이 끊겨도 정해진 범위의 텍스트 생성을 이어갈 수 있어요.
제품에 쓰려면 정확도와 실패 범위를 먼저 정해야 해요. 지금 모델은 사실을 확인하거나 지시를 안정적으로 따르지 못해요. 사용 설명, 상태 안내, 제한된 문장 생성처럼 범위를 좁히더라도 잘못된 출력을 막는 규칙 기반 장치가 필요해요. 전력 소비, 플래시 수명, 시작 시간, 다국어 토크나이저 비용도 실제 제품에서는 따로 측정해야 해요.
코드와 실험 기록은 공개돼 있어요. 저장소에는 펌웨어, 배선과 플래싱 절차, 훈련 코드, 제거 실험, 양자화 코드, 온칩 측정값이 함께 들어 있어요. 초기 매개변수 계산 오류와 수정 이력도 남아 있어 숫자가 바뀐 과정을 확인할 수 있어요. 2
왜 중요한가요
온디바이스 AI에서 모델 크기만 줄이는 방법 외에 메모리 접근 패턴을 바꾸는 선택지를 보여줘요. 모든 가중치를 같은 속도의 메모리에 둘 필요가 없다면, 자주 계산하는 부분과 드물게 조회하는 부분을 나눠 값싼 칩의 플래시를 더 적극적으로 쓸 수 있어요. 이번 측정에서는 2,500만 매개변수 테이블의 조회 비용이 적었고, 출력 헤드가 더 큰 병목으로 나타났어요. 다음 최적화 대상을 정할 수 있는 구체적인 측정 결과예요. 3
개발자가 봐야 할 기준도 명확해요. 저장 매개변수 수, 실제 연산 코어 크기, 토큰 속도, 메모리별 배치, 모델이 처리할 수 있는 작업을 따로 비교해야 해요. "ESP32에서 2,890만 매개변수 LLM 실행"이라는 수치만 보면 범용 챗봇을 떠올리기 쉽지만, 공개된 결과는 좁은 데이터 영역의 이야기 생성 모델과 새로운 메모리 배치 실험에 가까워요.
참고 자료
- 8달러짜리 마이크로컨트롤러에서 2,890만 매개변수 LLM 실행하기 — GeekNews
- Running a 28.9M parameter LLM on an $8 microcontroller — GitHub, slvDev
- ESP32 AI Results — GitHub, slvDev
- TinyStories: How Small Can Language Models Be and Still Speak Coherent English? — arXiv
'IT & AI' 카테고리의 다른 글
| 개발자 재능은 코딩 속도 하나로 설명되지 않아요 (0) | 2026.07.27 |
|---|---|
| Fly.io는 왜 클라우드 대신 에이전트용 컴퓨터에 승부를 걸었을까요 (0) | 2026.07.27 |
| Cerebras가 사내 지식 검색을 하루 1만 5천 건까지 키운 설계 (0) | 2026.07.27 |
| Slack은 왜 EC2를 고치지 않고 통째로 바꾸기 시작했을까요 (0) | 2026.07.27 |
| CodeAlmanac, AI 코딩 도구가 코드 밖의 맥락까지 읽게 해요 (0) | 2026.07.27 |