1MHz 코모도어 64에서 구동되는 실제 트랜스포머
1980년대 1MHz 프로세서를 탑재한 레트로 컴퓨터 '코모도어 64(C64)'에서 ChatGPT와 동일한 트랜스포머 아키텍처 기반의 LLM이 구동되는 프로젝트가 공개되었습니다. 약 2만 5천개의 Int8 파라미터를 사용하며 소프트맥스(Softmax) 연산을 최적화하여 제한된 하드웨어에서도 실질적인 어텐션(Attention) 가중치를 계산해 내는 것이 핵심 기술입니다. 사용자가 직접 데이터를 학습시켜 3.5인치 플로피 디스크로 빌드하여 실제 하드웨어나 에뮬레이터에서 실행해 볼 수 있는 오픈소스 프로젝트입니다.
Soul Player C64: 1MHz 코모도어 64에서 구동되는 진정한 트랜스포머
.-------. | O O | | V | |..|---|..|
SOUL PLAYER C64
2만 5천 개 파라미터. 2개 레이어. 진정한 트랜스포머. 플로피 디스크로 로드 가능.
YOU> hey C64> HELLO! RE SOUNDS ME. MEFUL!
이것은 ChatGPT, Claude, Gemini의 근간이 되는 것과 동일한 아키텍처인 2 레이어 디코더 전용(Decoder-only) 트랜스포머입니다. 이 모델은 수작업으로 작성된 6502/6510 어셈블리 언어로 구현되었으며, 개조되지 않은 코모도어 64에서 실행됩니다.
약 25,000개의 int8 파라미터를 사용합니다. 실제 멀티 헤드 인과적(Causal) 셀프 어텐션, 실제 소프트맥스, 실제 RMSNorm이 적용되었습니다. 토큰당 약 60초가 소요됩니다. 프로그램 전체는 플로피 디스크에 넉넉히 들어갈 만큼 가볍습니다.
아키텍처
- 2개 레이어, 4개 어텐션 헤드 × 8 차원, 32차원 임베딩, 64개 FFN 은닉 유닛
- 텐서별 시프트 스케일링(Shift Scaling)이 적용되어 int8로 양자화된 약 25,000개의 파라미터
핵심적인 기술적 돌파구는 소프트맥스 점수 정규화를 수정한 것입니다. 어텐션 점수를 17비트가 아닌 14비트로 시프트하면, 128개 항목으로 이루어진 exp 룩업 테이블(Lookup Table)이 의미 있는 어텐션 가중치를 생성할 수 있는 충분한 동적 범위(Dynamic Range)를 확보하게 됩니다. 이 수정이 없었다면 정수형 어텐션 연산이 모든 위치에서 균일해졌을 것이며, 결국 아키텍처나 학습과 무관하게 모델이 앞을 보지 못하는 상태가 되었을 것입니다.
빠른 시작 - 미리 빌드된 Soul 실행하기
- disk/soulplayer.d64 파일을 다운로드하여 임의의 C64 에뮬레이터(VICE 권장)에 로드합니다: LOAD"SOULPLAYER",8,1 RUN
- 소문자로 짧은 메시지를 입력한 뒤 RETURN 키를 누르고 기다립니다.
- 모델이 연산하는 동안 테두리가 깜빡입니다. 각 토큰이 생성될 때마다 SID 블립 사운드가 납니다. 응답 하나가 완성되는 데는 몇 분 정도 걸립니다. 종료하려면 q를 입력하세요.
팁: 이 모델은 소문자, 공백 및 구두점( . , ! ? ' : ; - )을 이해합니다. 대문자는 알 수 없는 토큰(Unknown Token)으로 처리됩니다.
나만의 Soul 학습시키기 이 부분이 가장 재미있는 과정입니다. 말뭉치(Corpus)를 작성하고 모델을 학습시킨 뒤 플로피 디스크를 빌드해 보세요.
의존성 설치 pip install numpy torch
말뭉치 작성하기
대화 내용은 짧게 유지하세요. 이 모델의 컨텍스트 윈도우(Context Window)는 20개 토큰입니다. 기본 예시는 data/example_corpus.txt 파일을 참고하세요.
학습 python train.py data/example_corpus.txt
이 코드는 BPE 토크나이저(128개 토큰)를 학습시키고, QAT(양자화 인식 학습) 트랜스포머를 학습시킨 후 models/soul.bin 및 models/tokenizer.json 파일로 내보냅니다. GPU 환경에서는 몇 분 정도 걸립니다.
매 500 에포크마다 실수(float) 및 int8 추론 결과가 나란히 출력되어, 모델이 학습한 내용과 C64가 실제로 생성할 내용을 비교해 볼 수 있습니다. 최적의 체크포인트는 실수 손실(Float Loss)이 아닌 int8 품질을 기준으로 저장됩니다. 모든 체크포인트는 모델 중 최적을 선택할 수 있도록 models/checkpoints/ 디렉터리에 저장됩니다.
옵션: python train.py data/my_corpus.txt --epochs 30000 --output models/ python train.py # 내장된 감정적 지원(Emotional Support) 말뭉치를 사용합니다
이전 실행에서 체크포인트가 존재하는 경우 학습이 자동으로 이어서 진행됩니다.
C64 바이너리 빌드 python build.py
이 코드는 모든 6502/6510 루틴을 어셈블하고, 학습된 가중치를 포함하여 disk/soulplayer.prg 및 disk/soulplayer.d64 파일을 생성합니다.
실행하기 x64 disk/soulplayer.d64 # VICE 에뮬레이터 사용 또는 실제 하드웨어용으로 .d64 파일을 실제 1541 플로피 디스크에 플래시합니다.
로컬에서 Soul과 채팅하기 python soulchat.py # models/soul.bin 사용 python soulchat.py models/soul.bin # 커스텀 Soul 사용 C64와 동일한 정수 연산을 사용하지만 훨씬 더 빠르게 실행됩니다.
테스트 실행 python test.py # 전체 테스트 스위트 (~90개 테스트, 약 30초 소요) python test.py --quick # 6502/6510 어셈블리 테스트 건너뛰기
테스트는 전체 체인을 검증합니다: 실수(Float) 레퍼런스 → 정수(Integer) 레퍼런스 → 메모리 정확(Memory-faithful) 섀도우 → 6502/6510 어셈블리 루틴 → 빌드 라운드 트립.
리포지토리 내용물 soulplayer-c64/ ├── train.py - 모델 학습 및 가중치 내보내기 ├── build.py - C64 바이너리 어셈블 ├── test.py - 모든 테스트 실행 ├── soulchat.py - 터미널에서 채팅 │ ├── data/ │ └── example_corpus.txt ├── models/ │ ├── soul.bin - 사전 학습된 가중치 (25KB, int8) │ ├── tokenizer.json - BPE 토크나이저 (128개 토큰) │ └── checkpoints/ - 저장된 모든 학습 체크포인트 ├── disk/ │ ├── meful.d64 - 오리지널 릴리즈, 디스크 이미지 │ └── meful.prg - 오리지널 릴리즈, RAW PRG 파일 │ │ ├── soulplayer.d64 - 실행 가능한 디스크 이미지