来源公布的内容
开发者 SimEdw 在个人博客公布了 WorldTUI:一个只有 360M 参数的语言模型,专门“扮演”一台终端。它背后没有真正的 shell,也没有文件系统——你的每一次按键输入进去,模型预测的是“屏幕接下来会变成什么样”。它能创建文件、运行 vim 和 tmux、玩一局贪吃蛇,还常常记得你几分钟前写过的内容。作者说,最大的两处突破是教会模型自己纠正错误,以及把屏幕按行并行解码。
这件事的起点是作者看到 Google 的 Genie 3 后产生的想法:如果未来的应用不是写出来的,而是“学”出来的呢?游戏引擎渲染画面的位置,被模型预测的下一帧取代。他没有大算力集群和海量视频数据,就把野心缩小:不做游戏世界,做一台终端。终端恰好合适——它只是一块字符网格而非像素画面,训练数据可以用跑真实 shell 的方式无限生成,而且预训练模型本来就知道 ls、cat 该输出什么。作者真正想验证的是:模型能不能维持一个一致的世界,而不只是生成看起来像终端的输出。
现在有一个可以直接玩的网页 demo:模型被量化到 int4,只有 208MB,完全在浏览器本地运行。建议用桌面版 Chrome 或 Edge(需要 WebGPU 和实体键盘),手机上也能打开但会慢得难受。作者邀请大家去“搞破坏”:进去之后先故意输错一个 pythoon,看看它是不是真 shell。
跟着做:把这台假终端玩坏的顺序
- 打开原文里的 demo 链接(Try it),等 208MB 模型下载完——全程在浏览器 tab 本地运行,不上传任何东西。建议用桌面版 Chrome 或 Edge。
- 先测“记忆”:用 echo 把一串随机字符写进文件,中间执行几条别的命令,再 cat 读出来,看它记不记得住。
- 再玩全屏程序:在 vim 里按 esc 切换模式、保存退出;在 tmux 里开两个窗格来回切换;在 snake 里吃几个豆子。
- 试试它的脾气:把 python 打成 pythoon,看它容不容错;嵌套建几个目录再 cd 出来,看它会不会迷路;把两条它大概率没见过的命令组合起来,看它怎么翻车。
- 想复刻思路的话按这个顺序走:Docker 里跑真程序、逐键录屏造数据 → 把终端建模成字符网格(333 个 token 的小词表)→ 监督微调起步 → 跑三轮“自我纠错”训练 → 按行并行解码提速 → int4 量化塞进 WebGPU。
资料:[1]
正文详解:数据、训练、加速、瘦身
数据是整件事的根基。作者没找到现成的、按键与屏幕严格对齐的终端录屏数据集,于是自己造:在 Docker 里跑真实程序,记录每一次按键和按键之后的屏幕。配方是:随机用户名、主机名、提示符风格和终端尺寸;按虚构人设(开发者、运维等)随机生成目录和文件;每轮挑 6 到 24 个加权活动(改文件、vim、python、tmux 等);跟踪状态,保证打开的文件大都是真实存在的;像人一样逐键输入、带 tab 补全,打字错误率设为 1.2%;35% 的会话从半程开始,逼模型学会从任意状态接手。最后攒了 336k 个 episode,约 20 亿 token——对比之下基座模型预训练见过约 18 万亿 token。
建模上,作者把终端看作字符网格。每个会话从一张“快照”开始:屏幕尺寸、内容和光标位置;尺寸是输入的一部分(以 32×96 为主,也有 24×80、40×120),demo 里还能自定义起始画面。之后每次按键按真实终端的原始字节送入(回车是换行符、左箭头是 ESC [ D),模型输出要重写的行和光标落点;无输入时则给一个带时长的 WAIT 标记,贪吃蛇就是这样自己动的。为了省 token 还加了 COPY 操作:滚屏时不再逐行重写(约 3000 token),而是发“旧第 1 行变成新第 0 行”这类复制指令,一行只要 3 个 token。整个词表只有 333 个:256 个字节 token、64 个行号 token 加少量特殊操作,解码时做语法约束,保证每次输出都是合法的屏幕更新。
训练分两大步。先以 Qwen2.5-Coder-0.5B 为起点(代码模型本来就见过大量命令行),做普通监督微调:给屏幕历史加按键,预测真实终端的屏幕变化。普通打字学得很快,但长会话里错误会累积——文件名错一个字母,后面全错。于是作者借鉴 DAgger 搞了“自我纠错”:在录制会话中取一点,让模型往前预测 1 到 4 步,把结果屏幕和真实录屏对比,差得不多就构造一个“在下一次按键时修复”的修正,继续在修正帧和后续真实事件上训练;一共三轮,每轮都用最新模型的错误重新采样。关键限制是:修正引入的词必须在早先的真实屏幕或用户输入里出现过,不能是模型自己编的,否则等于奖励幻觉。这一步加上补充数据,把 PresetBench 从 24/47 拉到 38/47。总计约 75 张 RTX 4090 小时。
速度是另一场硬仗。整屏重绘约 3000 token,逐个生成在 4090 上要 12 秒。作者发现各行大多互不依赖,就把解码改成按行并行:每行一个 batch 元素,共享同一份历史(含 KV 缓存),只生成自己的更新,成本从“所有行之和”降到“最长行约 100 步”,大帧 p95 从 6.7 秒降到 0.87 秒。行间无法协调会出怪事(vim 开在第 3 行而不是第 0 行、贪吃蛇一次长出好几节食物),解决办法是用同一个模型做 speculative decoding:并行行先出草稿,再顺序校验,保留到第一个分歧点为止重写。浏览器里 M4 Mac 打字约 60ms 一个字符,man 这类大更新从 2.5 秒压到 0.9 秒。瘦身方面:只保留用得到的 333 个 token 的 embedding(原 15 万词表占了 136M 参数),模型从 494M 降到约 360M;再 int4 量化到 208MB。网页 demo 用作者手写的 JS 版 Qwen 解码器,WGSL 写 compute shader 跑 WebGPU,4-bit 权重在推理时解包,激活和注意力缓存用 32 位浮点,全在本地 tab 里。蒸馏实验很有意思:删掉第 7 层,next-token 准确率几乎不动(99.3% 降到 98.9%),但记忆测试从 64/64 直接掉到 0/64——学生看起来一切正常,却悄悄丢了记忆,作者最后放弃了蒸馏。
测试用三套:ShellBench 是 106 条命令、24 个手写 bash 会话,按精确输出打分;PresetBench 是 47 个从 demo 翻车现场收集的脚本 case;记忆测试是 32 个世界,每个写两个随机值到两个文件再跨会话读回。WorldTUI 拿到 ShellBench 80/106(纯 prompt 基线是 52 和 60)、记忆 9/13。局限作者也列得很实在:Docker 没给网络,lynx 这类工具很无聊;Python 只会简单运算,难一点就开始 GPT-3 时代的幻觉;嵌套目录多了会迷路;Firefox 下比 Chrome 慢约 20 倍。
如何解读
这篇文章的价值不在“又一个用模型装终端的玩具”,而在于它把“世界模型”这个宏大想法降维成普通人能复现的工程:训练数据可以无限合成(Docker 录屏),一块 4090、75 小时就能训出可玩的东西。2022 年人们还在用 prompt 让 ChatGPT 扮演 Linux 终端;GameNGen 用扩散做 Doom 帧预测;NeuralOS 啃桌面 GUI——WorldTUI 站在中间:专门对按键和屏幕更新训练,连 vim、tmux 这类全屏程序都覆盖。
最值得琢磨的是“一致性”从哪来:模型没有实现任何文件系统规则,却能跨会话记住写过的文件、在 tmux 多窗格里各干各的事。这说明状态保持能力可以在字符层面涌现;但代价是组合泛化很弱——两条没见过的命令一组合就翻车。所以别把它当生产工具,它是一个漂亮的概念验证:小模型加合成数据加自我纠错,到底能走多远。
对订阅者来说,启发是直接的:如果你也想做类似的玩具(游戏帧预测、某个小众软件的模拟器),这套配方可以直接抄——数据合成、DAgger 式纠错、按行并行解码、int4 进浏览器,每一步原文都给了可照做的细节。玩 demo 只需要浏览器,复刻需要一块还不错的显卡和耐心。
阅读要点
- WorldTUI 是 360M 参数的小模型,专职“扮演”终端:没有真实 shell,输入按键、输出屏幕变化;能建文件、跑 vim 和 tmux、玩贪吃蛇。
- 数据全合成:Docker 里跑真程序逐键录屏,336k 个 episode 约 20 亿 token,含 1.2% 打字错误和 35% 半程开局。
- 训练关键是三轮“自我纠错”(DAgger 思路):让模型先预测、对比真实屏幕、再学着在下一次按键时修复;PresetBench 从 24/47 提到 38/47。
- 按行并行解码把大帧延迟从 6.7 秒压到 0.87 秒,再用同模型 speculative decoding 解决行间协调;int4 量化后 208MB 在浏览器本地跑。
- 蒸馏教训:删掉一层,token 准确率几乎不动,记忆测试却从 64/64 掉到 0/64——小模型的记忆藏在特定层里,砍层前先测记忆。
- 局限:无网络、Python 只会简单题、嵌套目录会迷路;demo 用桌面 Chrome/Edge 最快,Firefox 慢约 20 倍。
资料:[1]

