Soul Player C64 – 在 1 MHz Commodore 64 上运行的真正 Transformer
摘要
# gizmo64k/soulplayer-c64 来源:[https://github.com/gizmo64k/soulplayer-c64](https://github.com/gizmo64k/soulplayer-c64) # Soul Player C64 **一款在 1 MHz Commodore 64 上运行的真实 Transformer。** ``` .-------. | O O | | V | |..|---|..| # SOUL PLAYER C64 2.5万个参数。 2 层网络。 真实的 Transformer。 从软盘加载运行。 你> 嗨 C64> 你好!这声音不错。真神奇! ``` 一个 2 层仅解码器(Decoder-Only)Transformer —— 与 ChatGPT、Claude 和 Gemini 背后的架构相同 —— 采用手写 6502/
查看缓存全文
缓存时间: 2026/04/21 04:48
gizmo64k/soulplayer-c64 源码:https://github.com/gizmo64k/soulplayer-c64 # Soul Player C64
A real transformer running on a 1 MHz Commodore 64.
.—––. | O O | | V | |..|—|..|
SOUL PLAYER C64
25K PARAMETERS. 2 LAYERS. REAL TRANSFORMER. LOADED OFF A FLOPPY DISK.
YOU> hey C64> HELLO! RE SOUNDS ME. MEFUL!
A 2-layer decoder-only transformer - the same architecture behind ChatGPT, Claude, and Gemini - implemented in hand-written 6502/6510 assembly and running on an unmodified Commodore 64. ~25,000 int8 parameters. Real multi-head causal self-attention, real softmax, real RMSNorm. About 60 seconds per token. The whole thing fits on a floppy disk with room to spare.
架构
2 层结构,4 个注意力头 × 8 维,32 维词嵌入,64 个 FFN 隐藏单元。约 25,000 个参数被量化为 int8,采用按张量位移缩放(per-tensor shift scaling)。
关键突破在于修复了 Softmax 分数归一化问题——将注意力分数右移 14 位而非 17 位,使仅有 128 项的 Exp 查找表获得了足够的动态范围来生成有意义的注意力权重。若未修复此问题,整数运算下的注意力分布会在所有位置上趋于均匀,导致模型“失明”,无论架构或训练如何优化都无济于事。
快速开始 - 运行预构建的模型
获取 disk/soulplayer.d64,并在任意 C64 模拟器中加载(推荐 VICE (https://vice-emu.sourceforge.io/)):
LOAD"SOULPLAYER",8,1
RUN
输入一行小写英文短句,按 RETURN 键,然后等待。思考过程中边框会闪烁。每生成一个 Token 会伴随一声 SID 音效提示音。完整回复需要几分钟。输入 q 退出。
提示: 模型能识别小写字母、空格及标点符号(
. , ! ? ' : ; -)。大写字母会被识别为未知 Token。
训练你自己的模型
这是最有趣的部分。编写语料,训练模型,制作软盘。
安装依赖
pip install numpy torch
准备语料库
创建一个文本文件,每行格式为 input 和 response(中间换行),代表一组对话:
hello
hey!
nice to see you!
i'm sadi hear you. i care about you.
tell me a joke
why did the bit flip? it was tired!
保持对话简短——模型的上下文窗口仅为 20 个 Token。可参考 data/example_corpus.txt 作为示例。
训练模型
python train.py data/example_corpus.txt
该命令会训练一个 BPE 分词器(128 个 Token),训练基于 QAT(量化感知训练)的 Transformer 模型,并导出 models/soul.bin 和 models/tokenizer.json。在 GPU 上运行仅需数分钟。
每经过 500 个 Epoch,你都会看到 浮点型 和 int8 推理结果并排显示——即模型学到的知识 vs Commodore 64 实际输出的效果。最佳检查点将根据 int8 质量而非浮点损失保存。所有检查点均保存至 models/checkpoints/ 供挑选。
选项示例:
python train.py data/my_corpus.txt --epochs 30000 --output models/
python train.py # 使用内置的情感支持语料库
训练会在检测到已有检查点时自动断点续训。
构建 C64 可执行文件
python build.py
此步骤将汇编所有 6502/6510 例程,嵌入训练好的权重,并生成 disk/soulplayer.prg 和 disk/soulplayer.d64。
运行程序
x64 disk/soulplayer.d64 # 使用 VICE 模拟器
或者将 .d64 镜像烧录到真实的 1541 软驱中,在真机上运行。
在本地终端与模型聊天
python soulchat.py # 使用 models/soul.bin
python soulchat.py models/soul.bin # 指定自定义模型
使用与 C64 相同的整数运算逻辑,只是在 PC 上运行速度更快。
运行测试
python test.py # 完整测试套件(约 90 项测试,耗时约 30 秒)
python test.py --quick # 跳过 6502/6510 汇编测试
测试涵盖完整链路:浮点参考值 → 整数参考值 → 内存忠实映射的 Python 影子程序 → 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 个 Token)
│ └── checkpoints/ # 所有保存的训练检查点
├── disk/
│ ├── meful.d64 # 原版发布版磁盘镜像
│ ├── meful.prg # 原版发布版原始 PRG 文件
│ ├── soulplayer.d64 # 开箱即用的磁盘镜像
│ └── soulplayer.prg # 原始 PRG 文件
└── src/ # 核心引擎
├── numerics.py # 基准验证:定点数数学运算 + 前向传播
├── soul_io.py # .bin 权重文件格式处理
├── shadow.py # 高度还原 6502/6510 行为的 Python 影子程序
├── assembler.py # 轻量级 6502 汇编器(支持标签、补丁、远跳转)
├── cpu6502.py # 用于测试的最小化 6502 解释器
├── asm_matvec.py # 6502 矩阵-向量乘法汇编
├── asm_rms_norm.py# 6502 RMSNorm 实现(整数开方 + 除法)
├── asm_attn_head.py# 6502 注意力头实现(基于 LUT 的 Softmax)
├── asm_simple.py # 6502 Embedding、残差连接、ReLU、Argmax 实现
└── build.py # PRG 与 D64 镜像构建脚本
规格参数
| 参数 | 说明 |
|---|---|
| 词表大小 | 128 个 Token(4 个特殊 Token + 34 个字符/标点 + 90 个 BPE 合并词) |
| 词嵌入维度 | 32 维 |
| 网络层数 | 2 层 |
| 注意力机制 | 4 个头 × 8 维/头 |
| 前馈网络 (FFN) | 64 个隐藏单元 |
| 上下文长度 | 20 个 Token |
| 参数量 | 约 25,000(全部为 int8) |
| 权重体积 | 25 KB |
| 解码方式 | 贪心解码(Argmax) |
单层结构流程:RMSNorm → 多头因果自注意力 → 残差连接 → RMSNorm → ReLU MLP → 残差连接。最终层:RMSNorm → 输出投影 → Argmax。
所有激活值均采用 Q8.8 定点数表示(int16)。权重为 int8,采用按张量 2 的幂次进行位移缩放。偏置量为预缩放至矩阵乘法累加器的 int16。Softmax 基于 128 项的指数函数查找表,并使用 >>14 的分数归一化。6502 处理器缺乏乘法指令——所有计算均通过移位和加法实现。
内存映射
$0801-$20FF:代码与分词器表(约 6 KB)
$2100-$85A0:模型权重(25.3 KB)
$8600-$9D00:激活缓存区(5.8 KB)
$C000-$C3FF:Token 缓冲区、输入数据与临时空间
$D000-:VIC-II、SID、CIA(外设 I/O)
训练原理
模型采用量化感知训练(QAT)。训练期间,权重会通过 FakeQuantI8 模块——使用连续的浮点数缩放进行伪量化,并结合直通估计器(STE)进行梯度估算。
训练时使用的连续缩放与导出时强制采用的 2 的幂次位移网格之间的人为不匹配,充当了隐式噪声的作用,迫使模型学习到具有更大 Logits 安全边界的权重,从而能够适应量化带来的精度损失。偏置量使用简单的 fq() 进行伪量化。每次矩阵乘法后都会执行 × 0.5 的后置移位操作,以模拟 6502 处理器的 >> 1 行为。标签平滑(0.15)防止模型将 Logits 分布过度锐化,避免超出 int8 算术运算所能可靠区分的范围。
训练循环每 500 个 Epoch 会评估一次实际的整数前向传播(numerics.forward()),并根据 int8 Argmax 准确率(而非浮点损失)保存最佳检查点。训练日志中会并排显示浮点数与 int8 推理结果——即模型的理论学习成果 vs Commodore 64 的实际输出效果。
注意事项
- 它并不“智能”。 2.5 万参数量比 GPT-4 少了约 7000 万倍。它生成的句子可能会支离破碎。但这正是本项目的意义所在——证明在此等规模下架构依然有效。
- 它是
慢速“深思熟虑”型。 在真机上前推一个 Token 约需 60 秒。完整回复通常需要数分钟。 - 大写字母会失效。 请始终使用小写字母。
- 词表极小且上下文短。 仅 128 个 Token 和 20 个 Token 的上下文窗口——训练时的对话务必简短。
致谢
- 代码开发与训练: gizmo64k (http://www.indiepixel.de/)
- 调试、单元测试与“橡皮鸭”代码审查: Anthropic 旗下的 Claude (Opus 4.6)
- 幸运载体: Commodore 64(Commodore Business Machines, 1982)
许可证
GNU General Public License v3。详见 LICENSE。
The future came back for the past. And now it has a soul.
相似文章
@tetsuoai: 四十分钟的白板讲解。完整的Transformer架构。然后打开Vim并用C语言编写。
一段40分钟的讲解通过白板图完整介绍了Transformer架构,并演示了如何在Vim中使用C语言进行实际实现。
Transformer 数学探索器 [P]
这个交互式工具通过数据流图可视化 Transformer 模型的数学基础,涵盖了从 GPT-2 到 Qwen 3.6 的架构以及各种注意力机制。
PC Engine CPU
关于PC Engine (TurboGrafx-16) CPU HuC6280的详细技术概述,这是一款基于65C02的快速8位处理器,涵盖其架构、时钟速度以及与NES和SNES CPU的差异。
为代理式编码扩展测试时计算
一种面向代理式编码的测试时扩展框架,可将 rollout 轨迹压缩为结构化摘要,并通过递归投票/PDR 将 Claude-4.5-Opus 在 SWE-Bench Verified 上的成绩提升至 77.6%。
@NielsRogge: 我们已在 Transformers 库中新增对 SAM-3 Lite-Text 的支持!> 将 SAM-3 中笨重的文本编码器替换为……
Hugging Face 的 Transformers 库新增了对 SAM-3 Lite-Text 的支持,将原本笨重的文本编码器替换为一个轻量的 MobileCLIP 学生模型,该模型通过知识蒸馏训练,在保持性能的同时将参数量减少了 88%。