一个3.16M参数的Transformer,在250美元的FPGA板上跑到59,965.5 tok/s。模型权重1.5MB。这个数字放在2026年,够让所有在高端GPU上跑推理的人先看一眼,然后退一步想:怎么回事?
它赢了显卡。同一模型在作者笔记本的RTX 3050 Ti上是719 tok/s。不是反过来,不是被GPU压着,而是一个几乎只能算玩具的板子追着显卡打。
但59,965.5 tok/s这个数有个前提你不能不知道:它是16路并行、注意力窗口为1的配置下测出来的。窗口为1的意思是模型只看一个token。它没有记忆,输出的是没有上下文的重复文本,he he he he he。对你没用,但对你不需要有用——这个数字本身就是个实验台,你用它观察一件事。
然后作者把它切回单流,带完整的训练上下文窗口和KV cache。这一组才是你真正在意的:按FPGA周期数是19,242 tok/s,实时负载约21,300 tok/s,峰值21,479 tok/s。和60k隔着差不多三倍,但仍然比RTX 3050 Ti高出约30倍,比Kria KV260板载的Arm Cortex-A53高出快两千倍——同一个模型,在板载CPU上只有11 tok/s。
所以我先把话说清楚:这个项目的“神迹”根本不出在AI模型本身。它出在:作者把模型的全部权重和KV缓存都放进了片上URAM/BRAM,token生成循环完全不访问板载DDR。他把模型放进了内存最快的那一层,然后让整个推理过程在那里跑完。
单流token生成是内存带宽瓶颈,不是算力瓶颈。每生成一个token,你都得把这套权重从存储里过一遍。权重在DDR里,你就受DDR带宽拖累;在片上SRAM里,你就能拿到数百GB/s到TB/s级的带宽。KV260的CPU和FPGA共用同一个DDR控制器,理论带宽约20GB/s。就这个水平。RTX 3050 Ti有大量算力,但单流解码天然没办法像训练或大批量batch那样把算力利用率提上去。单流就是一次一个token,靠数据喂,不靠GPU算力硬抗。同一个模型在板载CPU上11 tok/s、在RTX 3050 Ti上719 tok/s,两个都把权重放在DRAM或GDDR上。不是它们算不动,是数据得从DRAM反复读,一个token一次,没有任何batch去隐藏这些延迟。GPU的算力利用率在这种情况下跌到可悲,CPU更不用说。
所以真正的差距不是250美元打败了3000美元,而是有人在动手之前,先问了一句:权重到底住哪。
这事不新鲜。把整个模型放在离计算单元最近的地方,Groq在做,Cerebras在做,Taalas也在做,只不过Taalas是用定制ASIC把Llama 3.1 8B蚀刻进芯片,而这一位只有约3MB片上内存,只能放一个3.16M参数的小模型。这条思路不需要重新发明,它需要的是你先明白面前这堵墙立在哪。
这里有个特别关键的限制,不能装看不见:权重和KV cache必须全部放得进片上。这个模型约1.5MB权重,INT4量化,堆满了约3MB的片上SRAM。作者自己估的交叉点大概在6.3M参数,再大就溢出到DDR,然后速度掉回同一堵带宽墙。所以别幻想“下个月就能把70B跑在200美元的板子上”,那是半桶水才会画的饼。
但这个“窄”才是点。不是碰巧窄,而是他接受了窄,然后坐下来,把问题一直缩小到它能完全装进3MB。
你看他做这个项目的方式,就知道他不是在堆硬件,而是在重新定义问题。一开始设的目标是100k tok/s,最后证明在这块芯片上这个架构的极限大概是62k-78k tok/s。实测60k,差不多到目标线。你以为他会硬上、继续调优,非得把那个数字堆到100k?他没有。他把目标放回现实,然后写清楚这个限制从哪来。这是成熟工程里最稀缺的一步——接受一个真实的限制,不是去掩盖它。
有件事不展开讲我憋得慌。这个作者用的训练语料是TinyStories,但他过了一个叫Keviniser的流程,把语料压缩成只保留实义词的风格,把整个语料从371.7M词压到260.5M词。模型参数没变,但同一个故事的输出字符数少了约30%。他先让“要说的话”本身变短,然后再去压模型。这不是灵光一现的优化,这是一门快消失的手艺——知道什么时候该把问题缩小,而不是把硬件加满。这一笔带来的等效速度提升约1.5倍,跟上面那几个参数交叉点一样,都是被绝大多数写技术博客的人漏掉的。他们只会截图“看,我跑通了”。没人跟你说这些底下的账。
这话我承认说得有点重,但道理没变。现在太多人把“部署一个模型”理解成“找一个API,加一层缓存,部署完了”。他们不会去算权重到底占多少内存,不会想这一批权重读完要跨过几层总线,不会问KV cache最后躺在哪。结果就是他们卡在同样的地方,却反复以为是模型不够好、显卡不够大、框架不够新。这是半桶水晃荡得最响的时候。
而这个项目最让我想单独说的一点:所有RTL都是作者和Claude Code一起用Verilog手写的,没上HLS,也没在Vivado GUI里点点拖拖。在20核i7、32GB RAM的机器上,跑一次完整的综合布局布线约30分钟。
你先别急着把这理解成“看吧,AI工具又赢了”。我用的词是“和Claude Code一起”——工具在替他搬运,不替他判断。真正决定“权重必须全放片上”的人,不是AI。是那个在写下第一行Verilog之前,先把内存层级和带宽墙想清楚的人。AI给的代码再漂亮,也没法帮你回答“哪个瓶颈该先解决”。那个回答在项目开始前,就已经被那片3MB的片上内存定死了。
工具的定位应该就是这个:搬运,不判断。我见过太多人拿着Claude Code或Cursor把代码生成得飞快,却连自己这堆数据到底有没有机会碰到缓存都不知道。工具越好,这种人的幻觉越深,因为代码能跑了,他就以为自己懂了。能跑和做对,中间隔着的就是前面那六十几千个token每秒的距离。
别误会,我不是让你都去学Verilog、都去买Kria。不是。
我想说的是,单流decode这个具体问题,本质上是个内存问题,不是个模型问题。你把单个token生成想象成一个要从内存里取权重、算一遍、再吐出下一个token的机械过程,那权重每多一字节,每个token就得多等一拍。你可以在模型层面做任何魔法,但数据要跑多远这件事,由物理口径决定。这也就是为什么同一个小模型,放在CPU上11 tok/s,放在DDR旁边的FPGA上能上21k。不是同一个人跑得快,是同一个人换了条近路。
那么大多数做LLM应用的人在这里错在哪?错在他们优化的是模型的大小和参数量,而不是这条数据路径。他们在一个根本不可能喂满的硬件上硬上大模型,然后用恐怖的batch size把延迟藏着,最后告诉自己“吞吐量还是不错的”。这跟买一台超跑然后在早高峰里比谁先到公司是一个逻辑——问题从来不在引擎,在路。
而这位在Kria上跑60k tok/s的作者,选了另一条路:先看路,再选车。他知道自己的路是带宽,不是算力,所以选了片上存储做引擎,选了3.16M参数做车身,选了经过压缩的TinyStories做燃料。这些东西加起来,就是他能跑出数倍于RTX 3050 Ti的速度,而那台RTX的“引擎”其实还更强。
这个项目最该被记住的,不是那块250美元的板子,不是那个60k tok/s的数字,而是这种“先量路,再选车”的顺序感。这种顺序感能把一个预算只有几百美元的项目带到一个可笑的高度。反过来,每一支在数据中心里用极贵的机器跑着无人用的推理服务的团队,都缺这个顺序。
我的态度很明确:单流token生成,从来都是带宽问题,不是参数竞赛。别再去追什么“更快”的模型、更大的模型,如果你连第一个问题还没回答——你这个模型的权重,到底住哪。先把这件事搞清楚。搞清楚之后,模型大小、量化精度、批处理策略、硬件选择,这些都会按部就班地自己排出来。而你如果一开始就跳过这步,只顾着追参数量、追“大一统multimodal”、追所有看起来更重的东西——那叫本末倒置,不叫优化。这不是AI时代的新规矩,这是任何时代都一样的工程严谨性。工具能替你写更多的代码,不能替你回答这个问题。它只会让不回答这个问题的人,更晚地意识到自己错在哪。