想象你走进一家米其林后厨:每位主厨身边都有一只专属备料抽屉,里面放着今天要用到的全部食材。抽屉不大,但抬手就能拿到——厨师绝不会放下锅铲跑去地下冷库翻找,更不会在出菜高峰期跟别人抢一条取货通道。LPU(Language Processing Unit,语言处理单元)的内存设计,就是一座这样的“抽屉式后厨”:每个功能单元都自带一块 SRAM 当本地食材抽屉,抽屉之间通过高速传送带(片上网络)相连,整颗芯片完全不依赖外部 DRAM 冷库。这个设计换来两个结果:出菜时间永远确定(访存延迟可预测),翻台率极高(推理吞吐大);代价是抽屉总和有限,装不下“满汉全席”级别的大模型。接下来我们走进这座后厨:看看抽屉怎么摆、食材怎么分、宴席太大时又如何拆解。
看懂 LPU 的内存架构,就拿到了理解“推理快、训练难”这把钥匙——它直接决定你选型芯片、估算模型部署规模、设计分布式推理方案时的判断力。
可视化演示
展示LPU存储层次结构、数据流驻留模式及KV缓存管理三种核心模式,直观呈现LPU面向LLM推理的内存子系统设计与优化策略。
本节配有交互动效(进入视口后自动加载,约 3KB)。
存储层次结构 Reg→SRAM→DRAM→HBM四级存储带宽递减延迟递增 越靠近计算单元带宽越高延迟越低但容量越小 BW: Reg > SRM > DRM > HBM 层次化存储让高频数据驻留片上低频数据放片外
架构总览
后厨的第一张设计图很简单:与其让所有厨师共享一个中央仓库,不如给每人配一只专属抽屉。仓库越远,取料越慢;大家都挤在仓库门口,还得排队。LPU 的设计者选择了相反的路——把存储拆开,平均分到每一位“厨师”手边。这些“厨师”在芯片里叫功能单元(Functional Unit),负责矩阵乘法、激活函数等最基本的运算;“抽屉”就是分布式 SRAM(静态随机存储芯片,速度快、容量小、不需要周期性刷新);抽屉之间的“传送带”则是片上网络(NoC)。
在传统 GPU 或 CPU 里,运算单元和内存是分开的两栋楼:算得快,但数据要从 DRAM(动态随机存储,容量大、速度慢、要不断刷新防丢数据)搬来搬去。LPU 反其道行之:编译器在把程序烧进芯片之前,就已经像备菜一样,把模型的所有权重(神经网络里那些决定“菜味”的参数)静态地安排进各个功能单元的 SRAM 里。执行推理时,整个芯片就是一座自给自足的后厨,不需要走出门半步。
整颗芯片的存储总量不是一块大内存,而是所有“小抽屉”之和:
这张“抽屉分布图”看似简单,却奠定了后厨的一切性格:快、确定、但空间有限。
- 本地容量 \(C_i\)第 \(i\) 个功能单元配备的 SRAM 大小,好比一位厨师专属备料抽屉的容量。
- 求和符号 \(\sum_{i=1}^{N}\)把从第 1 个到第 N 个单元的抽屉容量全部累加。
- 片上总容量 \(C_{\text{总}}\)整颗 LPU 可供权重驻留的 SRAM 总量,是判断模型能不能装下的第一把尺子。
延迟优势
老式后厨最让主厨头疼的,是那句“仓库没货了,在等补货”。去地下室冷库(DRAM)取一次食材,快则几十步,慢则要排队、要等叉车,时间完全说不准。这种不确定性传导到菜品上,就是出菜时间忽快忽慢。LPU 的抽屉式设计直接取消了“去冷库”这个动作:所有数据都在手边,取一次数据的时间是固定的,就像抬手从抽屉里拿一颗鸡蛋,快慢只取决于你的手速,而手速是稳定不变的。
这种“确定性”是推理场景梦寐以求的。在大模型推理时,每一层 transformer 计算都要读取对应的权重。GPU 因为权重绝大部分在 DRAM 里,访存延迟随缓存命中率、内存总线拥堵情况不断抖动;而 LPU 上权重全在本地 SRAM,每条指令要读多少数据、读多久,在编译期就已经精确知道。于是每一层的执行时间都可预测,整个模型跑完的时间也基本恒定。
单看单次读取,SRAM 已经很快了;更关键的是,分布式布局让总带宽可以随单元数量线性扩展——N 个单元同时读各自的抽屉,互不干扰:
大厨的承诺能力由此而来:每一道菜(每一个 token)的出锅时间稳定可预测,这在面对真实用户时,意味着流畅的流式打字机体验,而不是忽快忽慢的“网络卡顿”。
- 数据位宽 \(W\)一次并行搬运的数据位数,好比传送带有多宽,能并排放多少块料。
- 时钟频率 \(f\)每秒运转的节拍数,好比传送带的运行速度。
- 带宽 \(B\)两者相乘,就是单位时间能从所有抽屉搬到运算单元的数据总量。
容量约束
抽屉式后厨唯一的软肋,是空间。一个厨师手边的抽屉再大,也放不下一个宴席的全部食材。SRAM 的物理特性决定了它密度很低:一个 SRAM 存储单元需要 6 个晶体管,而 DRAM 只需 1 个晶体管加 1 个电容,因此同等面积下 DRAM 能塞下的数据量是 SRAM 的好几倍。于是片上 SRAM 的总容量被卡死在数百 MB 量级(Groq 的第一代 LPU 芯片约为 200 MB),相比之下,一张普通显卡的显存都有 8-80 GB。
容量约束直接决定了 LPU 能“接多大的单”。推理时,模型的全部权重必须常驻片上 SRAM——因为无论哪一层被调用,它都得在本地现取现用,一旦放不下,程序就无法运行。我们来算一笔账:模型权重占用的存储空间等于参数数量乘以每个参数的字节数:
所以,容量约束不是设计缺陷,而是一道明确的边界:能装下的模型(通常在几十亿参数以内,取决于量化精度)可以获得极致的确定性推理;装不下的模型,要么换精度瘦身,要么走分片推理之路。
- 参数量 \(P\)模型有多少个参数,好比菜谱总共有多少页。
- 每参数字节数 \(b\)每个参数用什么精度存储,FP16 就是 2 字节,好比每页纸的厚度。
- 权重占用 \(M\)两者相乘得到模型权重所需总存储,直接和 \(C_{\text{总}}\) 比较决定放不放得下。
数据分配策略
抽屉既然有限,怎么分食材就成了后厨的核心手艺。如果所有厨师都把鸡蛋放在同一个抽屉里,做蛋羹的厨师就得不停喊传送带送货,传送带堵成一锅粥。LPU 的编译器在编译期就扮演“总备料师”,把每一层网络的权重切成方块(这就是“静态分配”:运行前定死,运行中不改变),逐个塞进最合适的功能单元抽屉里。
分配的目标有两个。第一是数据局部性最大化:让每个算子要用的权重尽量就在它自己所在的单元里,减少跨单元的片上网络搬运。第二是负载均衡:每个单元分到的权重量别差太远,否则有的抽屉塞满、有的空着,出菜节奏就被最满的那个拖累。激活值(推理过程中间产生的临时数据)生命周期短,更要就近存放在产生它的计算单元旁,用完即销毁,绝不跨网络“串门”。片上网络的流量在编译期就被精心编排,像后厨的传菜路线一样固定。
一个衡量分配是否均匀的简单指标是负载不均衡度——抽屉最满的厨师和平均水平的差距:
好的备料分工,决定了高峰期后厨能不能有条不紊——这也是 LPU 能把推理吞吐做到极致、却不需要程序员手工调优的底层原因。
- 单元负载 \(L_i\)第 \(i\) 个功能单元上驻留的数据量,好比某位厨师抽屉里食材的多少。
- 最大负载 \(\max_i L_i\)所有单元里最满的那一只抽屉。
- 平均负载 \(\bar{L}\)所有单元负载的平均值。
- 不均衡度 \(U\)最大值除以平均值,越接近 1 说明分配越均匀,传送带越通畅。
分片推理方案
当一场宴席的菜谱远超一间厨房的容量,答案不是放弃,而是“多厨房协奏”:把菜谱拆成几册,每个厨房领走一册,菜做好后通过传菜通道汇合到上菜口。对应到 LPU,这就是大模型分片推理。单颗芯片装不下的模型,被按层或按张量切分成若干块,分别驻留在多颗 LPU 的 SRAM 里,芯片之间通过高速互联(可以理解为后厨之间的传菜电梯)传递中间激活值。
张量切分是其中最常见的策略:把同一层的大矩阵按行或列切开,分给多颗芯片,每颗芯片只做自己那一份矩阵乘法,再把部分和拼起来。这样一来,每颗芯片所需的存储量就是模型总量除以芯片数。假设模型权重总占用为 \(M\),部署在 \(K\) 颗 LPU 上,那么每颗芯片至少需要:
分片让容量约束不再“一票否决”,但也把压力转移到片间通信上:每过一层,都要通过互联交换大量中间数据。厨房越多,传菜通道越忙,分片的收益会因通信开销而递减——这正是分布式推理工程需要精细调优的地方。
- 总权重 \(M\)完整模型权重占用的存储,等于前面算出的 \(P \times b\)。
- 芯片数 \(K\)部署分片的 LPU 数量,好比参与宴席的厨房数量。
- 向上取整 \(\lceil \cdot \rceil\)除法结果不是整数时,多出来的碎片也得占一个抽屉,所以向上取整。
SRAM扩展方向
抽屉不够用,后厨有三条升级思路:把抽屉做小做密、把抽屉叠成货架、把菜谱直接印在锅上。这三条路正是 SRAM 容量扩展的三个方向。第一条是先进制程微缩:芯片制造工艺从 14nm 走向 7nm、5nm、更小,晶体管越小,同样面积能塞下的 SRAM 单元就越多,抽屉不变大但“格子”更密了。第二条是 3D 堆叠封装:把多层 SRAM 晶圆垂直叠起来,用硅通孔相连,让抽屉从平房变成楼房。
第三条最激进,叫存算一体:让存储单元本身参与简单的计算,数据不搬出抽屉就能完成部分运算,相当于“菜谱直接印在锅盖上,边看边炒”。这条路线现在还处在早期,而混合存储层级是一个更现实的过渡方案——在保留分布式 SRAM 作为主力仓库的同时,挂一层容量较大的低功耗存储做冷备,把不常用的权重挪过去,用工程手段缓解容量焦虑。不论走哪条路,3D 堆叠对密度的提升可以简单估算:
抽屉可以升级换代,但“食材在手边、时间确定”的哲学不会变——容量扩展的一切努力,都是为了让这座抽屉式后厨能接更大的宴席,同时保住那份确定性的从容。
- 原始容量 \(C_{\text{old}}\)平铺单层 SRAM 的容量,好比原来的一层置物架。
- 堆叠层数 \(S\)垂直叠了几层 SRAM,好比货架层数。
- 集成效率 \(\alpha\)堆叠带来的散热、布线损耗系数,工程上永远小于 1。
- 新容量 \(C_{\text{new}}\)三者相乘得到 3D 堆叠后的总容量。
AI 应用场景
实时流式对话 AI 的低延迟推理
阶段:推理部署(在线推理)
解决的问题:传统 GPU 在生成式对话中,权重要从 DRAM 反复搬运,访存延迟的抖动让每个 token 的生成时间忽长忽短,用户感知为“打字机一卡一卡”。LPU 的分布式 SRAM 让权重读取时间固定,token 生成节奏稳定,延迟可预测。
具体案例:云端大模型对话服务使用 LPU 集群托管 7B-32B 量级的开源模型,流式输出做到每 token 延迟毫秒级且标准差极小,用户几乎感觉不到“等待生成”。
高吞吐离线批处理
阶段:推理服务化
解决的问题:离线摘要、分类、信息抽取任务量大,传统方案很难精确预估吞吐。LPU 的确定性执行让每个样本的处理时间是“固定常数”,调度器可以把批次像搭积木一样精确塞满硬件时间片。
具体案例:客服平台把海量历史工单按固定长度批次送入 LPU 集群做摘要,日均处理数百万条,吞吐曲线接近理论值,几乎没有排队毛刺。
大模型多芯片分片部署
阶段:分布式推理
解决的问题:单颗 LPU 的 SRAM 装不下数十亿参数模型时,需要把模型按层或按张量切分到多颗 LPU,通过片间互联协作推理,让容量约束不再成为部署障碍。
具体案例:将 32B 参数模型按张量并行切分到 8 颗 LPU,每颗芯片驻留约 4B 参数量级的权重,推理时逐层交换部分和,整体获得接近单芯片的确定性延迟。
Python 演示
"""模拟 LPU 分布式 SRAM 的权重分配与容量检查。"""from dataclasses import dataclass @dataclassclass Tensor: name: str size_mb: int class SRAMUnit: """功能单元的本地 SRAM 抽屉。""" def __init__(self, unit_id, capacity_mb): self.unit_id = unit_id self.capacity_mb = capacity_mb self.used_mb = 0 self.tensors = [] def can_fit(self, size_mb): return self.used_mb + size_mb <= self.capacity_mb def store(self, tensor): self.tensors.append(tensor) self.used_mb += tensor.size_mb class LPUChip: """带分布式 SRAM 的 LPU 芯片。""" def __init__(self, num_units, sram_per_unit_mb): self.units = [SRAMUnit(i, sram_per_unit_mb) for i in range(num_units)] self.unplaced = [] def allocate(self, tensors): for tensor in tensors: for unit in self.units: if unit.can_fit(tensor.size_mb): unit.store(tensor) break else: self.unplaced.append(tensor) def report(self): total = sum(u.capacity_mb for u in self.units) used = sum(u.used_mb for u in self.units) print(f"SRAM 总量 {total} MB,已分配 {used} MB") for u in self.units: print(f" 单元{u.unit_id}: {u.used_mb}/{u.capacity_mb} MB") if self.unplaced: names = ", ".join(t.name for t in self.unplaced) print(f"放不下的权重: {names}") def build_transformer_tensors(num_layers, hidden_size): tensors = [] for layer in range(num_layers): tensors.append(Tensor(f"L{layer}-QKV", 3 * hidden_size * hidden_size * 2 // 10**6)) tensors.append(Tensor(f"L{layer}-O", hidden_size * hidden_size * 2 // 10**6)) tensors.append(Tensor(f"L{layer}-MLP", 8 * hidden_size * hidden_size * 2 // 10**6)) return tensors def main(): chip = LPUChip(num_units=8, sram_per_unit_mb=40) tensors = build_transformer_tensors(num_layers=4, hidden_size=2048) chip.allocate(tensors) chip.report() if __name__ == "__main__": main()
chip = LPUChip(num_units=8, sram_per_unit_mb=40)创建一颗有 8 个功能单元、每个单元 40 MB 本地 SRAM 的虚拟 LPU,相当于 8 只小抽屉。build_transformer_tensors(num_layers=4, hidden_size=2048)按 QKV、输出投影、MLP 三块生成四层 Transformer 的权重张量,模拟一份“大菜谱”。for unit in self.units:依次尝试把当前权重块放进每一只抽屉,像备料师逐抽屉寻找空位。if unit.can_fit(tensor.size_mb):检查当前抽屉剩余空间是否装得下这块权重,放得下才正式入库。else:这个 else 挂在 for 循环上,意思是所有抽屉都试过且都没有 break,说明确实放不下。self.unplaced.append(tensor)记下放不下的权重,这正是单芯片 SRAM 容量约束的直接证据,也预告了分片推理的必要性。chip.report()打印每个单元的占用情况与未放置清单,帮助判断模型哪一部分“超纲”了。
常见误区
误区我以为 LPU 只是把缓存做得比较大,GPU 也有 L2 缓存,思路都一样,没什么新鲜的。
正解关键区别在“主存”角色。GPU 的缓存只是 DRAM 的临时缓冲,模型权重仍然住在 DRAM 里,缓存 miss 就要去访存;LPU 的 SRAM 是唯一主存,全部权重驻留其中,片上网络替代了内存总线。好比抽屉不只是“常用的临时架”,而是唯一的食材仓库——厨师根本不需要去地下室。
为何常见:计算机体系结构课里缓存层级的概念太深入人心,默认 SRAM 只是中间层,忽略了 LPU 彻底去掉 DRAM 的架构决断。
误区我觉得不接 DRAM 是偷工减料,几百 MB 容量远远小于 GPU 的几十 GB 显存,这芯片能干什么?
正解这是定位不同的取舍。把 DRAM 去掉,换来的是访存延迟确定性和极高的片上带宽,正好命中自回归推理“反复读权重、读得快就快”的特性。容量小是真实的边界,但在边界内,它把推理性能做到了极致。就像一间只做 10 道菜的厨房,反而比做什么都做不好的大饭店更受欢迎。
为何常见:人们习惯用训练场景的容量需求去衡量推理芯片,忽略了“模型能否驻留”与“访存是否确定”这两条完全不同的评价维度。
误区既然模型可以切分到多颗 LPU 上跑,那单芯片容量小就不是问题,分片就行了。
正解分片只是把容量压力转移成了通信压力。每过一层,芯片之间都要交换中间激活值,片间互联带宽是新的稀缺资源。芯片越多,通信占比越高,扩展收益递减。所以容量约束没有消失,只是换了种形式继续存在——后厨不够大可以多开几间,但传菜通道迟早会堵。
为何常见:只看到分布式并行“能跑更大的模型”这一面,忽略了通信开销随规模增长的另一面。
误区我觉得带宽不就取决于 SRAM 本身能跑多快吗,布局是分布式还是集中式影响不大。
正解分布式布局的核心优势是“并行读”。N 个功能单元同时读各自的本地 SRAM,总带宽近似是单块存储带宽的 N 倍;而集中式存储只有一条访问通路,所有单元挤在同一条总线上,带宽存在天花板。好比 N 个厨师各开一扇窗取食材,和所有人挤一个取菜窗口,吞吐完全不在一个量级。
为何常见:习惯了“一根内存条决定带宽”的思维,忽略了并行度对总带宽的线性放大作用。
面试题
Q1. LPU 用分布式 SRAM 替代了什么传统组件的角色?
- A.机械硬盘与文件缓存
- B.外部动态随机存取主存← 正确答案
- C.只读固件启动存储
- D.片内静态随机存储
答案:B。LPU 的核心决策是让模型权重全部驻留在片上分布式 SRAM,不依赖外部 DRAM 作为主存,从而消除访存延迟不确定性。硬盘和固件本来就不是主存角色;片内 SRAM 正是被采用的方案而非被替代对象。就像抽屉式后厨替代的是“下地下室拿菜”,不是替代厨师手里的刀。
Q2. LPU 消除访存延迟不确定性所依赖的关键设计是?
- A.权重全部驻留于片上存储← 正确答案
- B.引入统一内存寻址空间
- C.提高外部总线时钟频率
- D.增加多级缓存命中率
答案:A。只要权重全在片上 SRAM,每次读取都是“抬手拿抽屉”的固定时间,没有 DRAM 排队和刷新干扰,延迟自然确定。统一寻址、提高总线频率、增加缓存命中率都是在“减少访存次数”,并没有消灭不确定性本身。
Q3. 单颗 LPU 芯片的片上 SRAM 容量量级约为?
- A.数百 MB 的片上存储← 正确答案
- B.数百 GB 的外部内存
- C.数 TB 的固态硬盘空间
- D.数十 GB 的显存颗粒容量
答案:A。由于 SRAM 一个单元要 6 个晶体管,密度低、成本高,单颗 LPU 的片上 SRAM 只有数百 MB 量级。数百 GB、数 TB 都是 DRAM 或闪存的量级,不是片上 SRAM 的现实水平。
Q4. 一个 70 亿参数模型用 FP16(每参数 2 字节)存储,权重约占多少?
- A.大约 14 GB 内存空间← 正确答案
- B.大约 1.4 GB 内存空间
- C.大约 140 GB 内存空间
- D.大约 7 GB 内存空间
答案:A。权重占用 = 参数数量 × 每参数字节数 = 70 亿 × 2 字节 = 140 亿字节 ≈ 14 GB。这是单颗 LPU 数百 MB SRAM 的几十倍,直接说明了容量约束的严峻性,也解释了为什么 7B 模型必须分片或瘦身。
Q5. 分布式 SRAM 相比集中式大缓存,优势包括?
- A.总带宽随单元数而扩展← 正确答案
- B.消除缓存一致性开销← 正确答案
- C.支持任意大的模型权重
- D.降低单点访存排队压力← 正确答案
答案:ABD。每个单元并行读自己的本地 SRAM,总带宽随单元数线性扩展;没有共享缓存也就不需要一致性协议;访存请求分散到各单元,单点排队消失。但容量总和仍受物理限制,“支持任意大的模型”是错的——抽屉再多也填不满整本满汉全席菜谱。
Q6. 模型分片到多颗 LPU 推理后,新增的主要性能瓶颈是?
- A.跨芯片通信成为新瓶颈← 正确答案
- B.外部硬盘读写成为瓶颈
- C.模型编译时间大幅增加
- D.芯片散热功耗达到上限
答案:A。分片把容量压力转移到片间互联:每层计算都要交换中间激活值,跨芯片通信带宽有限且随芯片数增长而加剧,成为新的“传菜通道拥堵”。硬盘读写、编译时间、散热都不是分片架构带来的本质性新瓶颈。
Q7. 下列属于 SRAM 容量扩展方向的有?
- A.先进制程持续微缩工艺← 正确答案
- B.三维堆叠封装技术← 正确答案
- C.增加外部 DRAM 容量
- D.存算一体架构融合← 正确答案
答案:ABD。制程微缩让同样面积塞进更多 SRAM 单元;3D 堆叠把多层 SRAM 垂直集成;存算一体让存储单元参与计算减少搬运。增加外部 DRAM 等于走回“地下室取菜”的老路,与 LPU 的确定性哲学相悖。
Q8. 权重静态分配策略的核心目标是?
- A.最大化权重数据局部性← 正确答案
- B.最小化模型推理精度
- C.提高片上网络传输抖动
- D.降低编译器优化速度
答案:A。静态分配在编译期定死每个权重块的位置,核心目标是让每个算子要用的权重尽量在本地,最大化数据局部性,同时兼顾负载均衡。降低精度和增加抖动都是要避免的问题,编译器优化速度也不是运行时目标。
Q9. LPU 的架构特点决定了它最适合哪类场景?
- A.低延迟的大模型推演← 正确答案
- B.超大规模模型预训练
- C.海量数据离线清洗排序
- D.通用稀疏矩阵求解加速
答案:A。权重常驻 + 确定性访存 + 高带宽,正好匹配推理时“反复读取固定权重、追求低延迟高吞吐”的特点。预训练需要频繁更新海量权重,对存储容量和可写性要求极高,是 SRAM 容量约束最不擅长的场景。
Q10. 确定性执行带来的工程收益包括?
- A.推理延迟可提前预测← 正确答案
- B.批处理调度更加紧凑← 正确答案
- C.自动消除正则化误差
- D.服务端可承诺稳定吞吐← 正确答案
答案:ABD。每层执行时间固定,整个模型的延迟可以提前算出来;调度器能按精确时间片塞满硬件,批处理更紧凑;服务商可以对用户承诺稳定的吞吐 SLA。正则化误差是训练层面的概念,与推理时的确定性执行无关。