Soul Player C64 – 在 1 MHz Commodore 64 上运行的真正 Transformer

Hacker News Top 工具

摘要

# 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/

暂无内容
查看原文 导出为 Word 导出为 PDF
查看缓存全文

缓存时间: 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

准备语料库

创建一个文本文件,每行格式为 inputresponse(中间换行),代表一组对话:

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.binmodels/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.prgdisk/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.

相似文章

Transformer 数学探索器 [P]

Reddit r/MachineLearning

这个交互式工具通过数据流图可视化 Transformer 模型的数学基础,涵盖了从 GPT-2 到 Qwen 3.6 的架构以及各种注意力机制。

PC Engine CPU

Hacker News Top

关于PC Engine (TurboGrafx-16) CPU HuC6280的详细技术概述,这是一款基于65C02的快速8位处理器,涵盖其架构、时钟速度以及与NES和SNES CPU的差异。

为代理式编码扩展测试时计算

Hugging Face Daily Papers

一种面向代理式编码的测试时扩展框架,可将 rollout 轨迹压缩为结构化摘要,并通过递归投票/PDR 将 Claude-4.5-Opus 在 SWE-Bench Verified 上的成绩提升至 77.6%。