☰
verilog-推理-comms
2026/10/24 4:04:18 网站建设 项目流程

跳到内容

llama2.c · Communication Lens

记忆模型容量与干扰信号链Lane1 / Lane0Trace 证据取舍完整地图源文件

COMMUNICATION ENGINEER EDITION · ASSOCIATIVE MEMORY → TRANSFORMER LAYER

Transformer 不是神秘黑盒,
而是一台抗干扰的联想存储器

通信工程师可以这样看:key 是扩频码,value 是符号,query 是接收信号;q·k 是相关/匹配滤波,其他 key 的串扰就是多址干扰。Softmax 是干扰抑制与归一化,capacity 是能同时记住多少个 key-value 而不被串扰淹没。

KEYdim 64 · 8 heads · head_size 8QUERYx[64] Q12.20MEMORYKV cache 5 × 512 × 4 × 8LANE 1transformer_layer · 静态码本LANE 0transformer_layer_runtime · 时分复用OUTx[64]

从“记忆”开始 →直接看完整地图

用通信语言重述 build 顺序:

  1. 先有key / value的叠加记忆
  2. 用相关器检索:q·k
  3. 其他 key 造成多址干扰
  4. 非线性 / softmax压制干扰
  5. 8 heads = 多条接收支路,4 KV heads = 共享码本组
  6. 5 层 = 5 套码本,runtime 用TDM复用一套接收机
  7. 容量提升不是免费:相关器、LUT、控制、面积都要付成本

01 / STORE → QUERY

先存得下,才查得出

线性层先被看成外积记忆:每个训练样本把 value 写到 key 的方向上。检索就是拿 query 去和所有 key 做相关。

02 / SIGNAL → INTERFERENCE

干扰先于架构

不是先有 attention 再解释它;而是先有“多个记忆互相串扰”的问题,才有抑制干扰的 MLP、softmax 和容量设计。

03 / CAPACITY → COST

容量是收益,也是成本

线性记忆容量约等于 key 维度;非线性与指数加权能把容量推高,但相关器、exp LUT、reciprocal LUT 和调度都更贵。

04 / MEMORY → RTL

RTL 是相关器 + 归一化器 + TDM

权重 bank 是码本,score 是相关峰,softmax 是干扰归一化,KV cache 是延迟线;layer_idx 是码本选择,runtime 是五套码本共用一个接收机。

这篇新版不复述模块名,而是借用一篇“从记忆推导 Transformer”的文章视角:线性层、MLP、self-attention 都可以看成不同容量的联想存储器。
对通信工程师来说,最有共鸣的不是公式本身,而是这些老概念:相关、多址干扰、处理增益、容量、归一化、时分复用。说明:文章里的 64 → 1.2M 是理想随机向量记忆实验下的容量估计,不等于真实模型记住了多少知识;本页用它作为理解透镜,再落到本项目的 lane1 / lane0 RTL。

00 / MEMORY MODEL

先把 Transformer 看成存储器

一个 key-value 记忆,就是一次外积写入;一次查询,就是一次相关

这篇新版从“机器怎么记住很多事实”出发。线性层、MLP、self-attention 都可以被看成不同容量的联想记忆。对通信工程师,这几乎就是熟悉的码本、相关器和多址干扰问题。

ASSOCIATIVE MEMORY · 最简数学模型

M= Σi vi kiT // 查询 q:拿 query 和所有 key 做相关y= M q = Σi (ki · q) vi // 把它拆成“目标信号 + 其他记忆的干扰” =(kj · q) vj+ Σi≠j (ki · q) vi

第一项是想要的记忆;第二项是其他 key 和 query 的互相关,也就是干扰。容量讨论的就是:存储多少个 key 之后,干扰会强到与目标信号相当。

COMMUNICATION TRANSLATION · 通信工程师的词典

Key = 扩频码 / 签名

key 决定“用哪个方向写入、用哪个相关器读出”。好的 key 之间互相关低,干扰就小。

Value = 发送符号

value 是真正想取回的信息;在硬件里它来自权重行、V cache 或 FFN hidden。

Query = 接收信号

query 和每个 key 做相关;相似度越高,权重越大。其他 key 的相关输出就是多址干扰。

Capacity = 可分辨记忆数

容量不是存储比特数,而是“在干扰淹没信号之前,能同时记住并可靠取回多少个 key-value”。

通信概念联想记忆本项目 RTL在哪一层
扩频码 / 签名key k_i权重行 / K cacheqkv_weight_bank、attention_score
发送符号value v_iV cache / weight value rowattention_value_sum、ffn
接收信号 / 匹配滤波输入query qx[64] / q vectorx_in_flat、q_out_wire
相关器 / 匹配滤波q · k_iint8_group_dot + fixed_scale_mulint8_matvec_core、attention_score
多址干扰 MAIΣ_{i≠j}(k_i·q)v_i其他历史 token 的 score 干扰attention_score
信号干扰比 SIR目标相关 / 干扰相关logit 大小、缩放系数softmax 前的 score
分集合并按相似度加权求和prob × V 累加attention_value_sum
归一化 / AGC权重归一化softmax、RMSNormsoftmax_core、rmsnorm_core
码本选择哪一层记忆layer_idx 选择权重 bankqkv_weight_bank_runtime
时分复用 TDM一套接收机处理多套码本五层复用同一 datapathtransformer_layer_runtime

不要过度映射:文章实验里用 64 维随机 key 得到容量估计;本模型里 dim=64、head_size=8、8 个 head。64 是整个 hidden 维度,不是单个 head 的 key 维度。这里借用的是“相关 + 干扰 + 容量”的直觉,不是把每个数字一一对应。

01 / CAPACITY & INTERFERENCE

为什么一层能记住多少,取决于干扰怎么被压下去

从 64 到约 1.2M:不是魔法,是干扰抑制方式变了

文章用理想随机 key/value 做实验来估计单层能可靠取回多少条记忆。容量数字不是“模型记住多少事实”,而是“在串扰淹没目标前,能放多少个 key-value”。这个视角对通信工程师很自然:容量由相关器、处理增益和干扰抑制能力共同决定。

CAPACITY LADDER · 图示按对数直觉,不是线性比例

外积线性记忆≈ d ≈ 64

最优线性记忆≈ 2d ≈ 128

ReLU 门控≈ 128

Square ReLU / GLU≈ 2,700

Softmax attention≈ 1.2M(理想实验)

数字来自文章中的随机向量记忆实验,用来比较不同结构的“容量量级”,不是 stories260K 模型实际记住的知识量。

INTERFERENCE-TO-SIGNAL · 为什么容量会卡住

// 随机单位 key 时,干扰项像随机游走叠加 ISR ≈ (n − 1) / d // 令 ISR ≈ 1,得到线性记忆的容量 n ≈ d // 如果先把 key 白化 / 消相关,可到 2d n ≈ 2d

通信里的直觉:用户数 n 增加,多址干扰累积;处理增益 d 增加,相关器能把目标从干扰里拉出来。这里的 d 就是 key 空间的维度。

非线性的作用:ReLU / square ReLU / SiLU 把低相似度和负相似度的项压小,相当于软干扰抑制。相似度 0.1 经过平方变成 0.01,目标相似度 1 仍然是 1,于是干扰被压得比信号更快。

Softmax 的作用:把 score 变成指数权重再归一化,强相关路径保留、弱相关路径被指数压小。文章把这看成容量从多项式增长跳到指数增长的关键一步;硬件上对应 exp LUT、求和、reciprocal LUT。

线性相关器

最便宜:一次 dot + scale + accumulate。容量约等于 key 维度,所有干扰项都按相似度原样进入输出。

非线性门控

加一个阈值/平方/门控,把低相似度项压掉。代价是额外乘法、激活函数和更复杂的量化。

Softmax 选择

指数加权 + 归一化,让强相关路径接近 one-hot,弱路径被压到很小;同时保持可微,能训练。

通信类比不是严格证明:“attention 是记忆检索”能帮助建立直觉,但训练动力学、优化和真实知识存储都不能只靠这个类比解释。它是有用的第一层透镜,不是完整理论。

02 / SIGNAL CHAIN

把一层 Transformer 走成通信接收链

query → 相关器 → 干扰抑制 → 分集合并 → 非线性检测

把 self-attention 看成一个接收机:query 是收到的信号,K/V cache 是码本和符号历史,score 是相关输出,softmax 是干扰归一化,value sum 是分集合并。FFN 则是后级的非线性检测/门控。这样看,每个 RTL 模块都有通信语义。

ONE HEAD · 从相关到合并

01 QUERYx / q当前 token 产生的 query 向量信号

02 MEMORYK / V cache历史 token 的 key/value,像延迟线/码本记忆

03 CORRELATORq · k和每个历史 key 做相关,输出 score匹配滤波

04 SCALE× 1/√8head_size 归一化,避免相关值过大处理增益

05 SOFTMAXexp + normalize强相关路径保留,弱相关/干扰被压小干扰抑制

06 COMBINEΣ prob × V按权重合并历史 value,像分集合并合并

07 DETECTWO / FFN投影 + 残差 + SwiGLU 非线性门控检测/门控

COMMUNICATION READING · 为什么这些结构会出现

相关器:每个 head 的 Q 和 K cache 逐项点积,就是在做匹配滤波。目标 key 给出大的相关峰;其他 key 给出较小的互相关,形成多址干扰。

处理增益:1/√head_size把相关值缩放到合适范围,避免 softmax 过早饱和。通信里类似用处理增益/噪声功率做归一化,让判决器工作在线性区。

分组共享:8 个 Q head 只有 4 个 KV head,每 2 个 Q head 共享一套 K/V 码本。这不是“少算一点”而已,而是用码本共享换取存储和带宽。

干扰抑制:softmax 的 exp LUT 和 reciprocal LUT 把弱相关项压小,再做归一化。文章把它看成容量跃升的来源;在 RTL 里它是明确的 LUT + 乘加 + 倒数。

RTL 对应 · 点击定位完整地图

qkv_projection_mem把 query/key/value 从 x 投影出来

attention_scoreq · K 相关器 + scale

softmax_coreexp LUT + sum + reciprocal LUT

attention_value_sumprob × V 分集合并

kv_cache_multi_layer历史码本/延迟线,多 layer bank

ffn_block_memSwiGLU 非线性检测/门控

地图:相关器地图:softmax地图:KV 记忆

03 / LANE 1 → LANE 0

从固定码本到 TDM 码本复用

lane1 是单通道接收机;lane0 是五套码本共用一个接收机

静态层像一个固定在某个频点/码本上的接收机:先证明相关、softmax、合并都算对。runtime 层像 TDM 接收机:同一套相关器和归一化器在五个时间片里切换五套码本。算法没变,变的是码本选择和调度。

Lane 1 · transformer_layer

固定码本接收机。参数LAYER_IDX在 elaboration 时钉死权重文件;端口没有layer_idx。它最适合先做单层验证:输入一个 x,检查相关、softmax、value sum、FFN 是否逐项对齐 golden reference。

Lane 0 · transformer_layer_runtime

TDM 接收机。多一个layer_idx[2:0],每次启动从五套码本 bank 中选一套;KV cache 也按层分成五个 bank。同一套 datapath 依次处理五层,面积换延迟。

通信视角lane1 静态lane0 runtime
码本固定一套 _l0 / 对应层 memall.mem 五套,layer_idx 选 bank
接收机数量每个静态层一套 datapath一套 datapath 分时复用
KV 记忆单层 K/V 延迟线五层 K/V 延迟线,layer × seq 展平
调度局部 FSM局部 FSM + 父级 TDM 循环
延迟可并行实例化,但面积高五层串行,延迟更长
面积控制/运算/布线复制一份相关器与归一化器
代价面积和布线TDM 控制、地址加法、LUT 复用

layer_idx 的唯一作用 · 把 base address 变成运行时变量

// 权重码本:从固定 row 变成 layer base + row q_addr = (layer_idx × DIM) + row_idx kv_addr = (layer_idx × KV_ROWS) + row_idx // KV 延迟线:五层共用一段大地址空间 flat_write_pos = (write_layer_idx × SEQ_LEN) + write_pos flat_read_pos = (read_layer_idx × SEQ_LEN) + read_pos

这不是新的数学,而是“同一套相关器,运行时换码本”。

父级 TDM · 谁决定下一个时间片

ST_LAYER_WAIT: if (done) { x_work_reg = layer_out_flat if (layer_idx == 4) final_norm() else { layer_idx++; start() } }

父级 forward_core_5layer 负责把上一层输出写回 x,再启动下一层;runtime 层只负责一次 x → x。

地图:lane1 静态地图:lane0 TDM地图:五层循环

通信工程师的复述:lane1 是单码本接收机,先验证解调/合并链路;lane0 是 TDM 多码本接收机,用同一个相关器在五个时隙里处理五层。layer_idx 是时隙/码本选择字,不是新的调制方式。

04 / TRACE EVIDENCE

用信号关系验证通信类比

相关器 → softmax → 合并,不是比喻,是 RTL 里真实连着的线

下面是从当前 RTL 用 trace_signal.py 追出来的信号方向:attention_score 输出 score 进入 softmax;softmax 用 exp LUT 和 reciprocal LUT 生成概率;概率再进入 attention_value_sum。layer_idx 则真实地连接到六个 runtime bank 与多层 KV cache。

EVIDENCE 01 · 相关器 → 干扰抑制

attention_score.scores_flat [output] ├─ transformer_layer_runtime.scores_flat_wire │ └─ softmax_core.score_in_flat │ └─ softmax_core.score_sel └─ transformer_layer.scores_flat_wire └─ softmax_core.score_in_flat

这就是通信链里的“相关器输出 → 判决/归一化器输入”。scores_flat 是每个历史位置的 q·k 相关值,被 softmax_core 当作干扰与目标信号一起处理。

EVIDENCE 02 · softmax 内部的 exp / reciprocal

softmax_core.prob_out_flat ├─ exp_neg_lut_12b.data // 指数查表 ├─ recip_lut_12b.data // 倒数查表 └─ attention_value_sum.probs_flat └─ attention_value_sum.prob_reg

softmax 不是抽象口号:它真的用 exp LUT 把 score 变成指数权重,再用 reciprocal LUT 做归一化;输出概率随即进入 value sum 的分集合并。

EVIDENCE 03 · layer_idx = 码本选择 / TDM 控制

transformer_layer_runtime.layer_idx ├─ rms_weight_bank_runtime.layer_idx ├─ qkv_weight_bank_runtime.layer_idx │ └─ q_addr / kv_addr ├─ kv_cache_multi_layer.write_layer_idx ├─ kv_cache_multi_layer.read_layer_idx ├─ attention_outproj_bank_runtime.layer_idx ├─ ffn_inproj_bank_runtime.layer_idx └─ ffn_outproj_bank_runtime.layer_idx

同一个 layer_idx 同时进入六个 bank 与多层 cache 的地址。这是 lane0 TDM 的硬证据:一套相关器,运行时切换码本。

EVIDENCE 04 · 谁把 x 递回下一个时间片

transformer_layer_runtime.x_in_flat └─ forward_core_5layer.x_work_reg ├─ token_embedding_bank.embed_flat_wire // 第一层 └─ transformer_layer_runtime.out_flat // 后续层 transformer_layer_runtime.done └─ forward_core_5layer.layer_done_wire

接收机算完一个时间片后,done 回到父级;父级把 out 写回 x_work_reg,再切下一个码本。这就是五层 TDM 循环。

REPRODUCE · 本次新增 trace

python C:/Users/PC/Downloads/trace_signal.py attention_score scores_flat --data-only --depth 3 -o lane01_comm_assets/traces/comm_attention_scores.txt rtl python C:/Users/PC/Downloads/trace_signal.py softmax_core prob_out_flat --data-only --depth 3 -o lane01_comm_assets/traces/comm_softmax_probs.txt rtl python C:/Users/PC/Downloads/trace_signal.py transformer_layer_runtime layer_idx --data-only --depth 4 -o lane01_comm_assets/traces/lane0_layer_idx.txt rtl

TRACE FILES

comm_attention_scores.txt · 相关器 → softmaxTRACE ↗comm_softmax_probs.txt · exp / recip / value sumTRACE ↗lane0_layer_idx.txt · TDM 码本 fan-outTRACE ↗lane0_x_in_flat.txt · x_work_reg 循环TRACE ↗lane0_done.txt · done → 父级TRACE ↗

05 / TRADEOFF

容量、算力、面积一起定价

不是“softmax 更高级”,而是它用更多计算换更强的干扰抑制

通信系统里没有免费容量:要更高的处理增益、更强的干扰抑制、更低的误码率,就要更多带宽、算力、存储或延迟。Transformer 也一样。理解每个结构解决了哪个干扰问题,才能理解 RTL 为什么长这样。

1. 写入 key / value先有外积记忆,才有查询对象data

2. 用 query 做相关匹配滤波得到每个 key 的相似度correlator

3. 干扰出现其他 key 的互相关叠加,容量受 ISR 限制problem

4. 非线性门控ReLU / square ReLU / SwiGLU 压低弱相关项MLP

5. 指数加权 + 归一化softmax 把强相关路径选中,把弱干扰压小attention

6. 多头 / GQA多支路相关器;4 个 KV head 共享 K/V 码本heads

7. lane1 静态一层先把单码本接收机验证正确level 3

8. lane0 runtime TDM同一套接收机分时处理五层码本level 4

9. 父级五层循环done → x 写回 → layer_idx++ → 再启动forward_core

容量靠抑制干扰

线性相关器便宜,但容量≈d;非线性与 softmax 用更多计算把弱相关项压下去,容量才跃升。

Softmax 有真实硬件成本

exp LUT、求和、reciprocal LUT、定点归一化都要面积和延迟;它不是一个免费的函数调用。

TDM 省面积,不省时间

runtime 复用一套 datapath,但五层串行;权重 ROM 和 KV cache 容量也没有因为复用而消失。

最重要的结论:不要问“为什么这里要一个 softmax 模块”,而要问“如果不做干扰抑制,容量会掉到哪里”;不要问“为什么 layer_idx 要进 bank”,而要问“同一套相关器怎么在五套码本之间切换”。前者是通信问题,后者是资源调度问题。

06 / FULL MAP

基于 top_full_link_cc_zoom.svg

在完整信号地图里找相关器、记忆和 TDM

地图节点名采用“模块__父级__实例”格式,连线是 AI 注释后的数据流。用下方按钮分别在 lane1、lane0、相关器、softmax、KV memory 和五层循环之间切换。

FOCUS总览lane1 码本lane0 TDM相关器干扰抑制KV 记忆五层循环+-总览

lane0 runtime 相关器/码本选择lane1 静态单层记忆 相关器与 KV 记忆干扰抑制 score / softmax / value combine

滚轮缩放 · 拖拽平移 · 悬停节点看 title 注释 · 按钮切聚焦

先找相关器

qkv_projection_mem、attention_score 是相关器链;它们的输出 scores_flat 直接进入 softmax_core。

再找记忆

kv_cache_multi_layer 是历史 K/V 延迟线;layer_idx 决定读写哪个 layer 的 bank。

最后找 TDM

transformer_layer_runtime 是同一套接收机;forward_core_5layer 用 done 和 layer_idx 驱动五个时间片。

原始可缩放地图:top_full_link_cc_zoom.svgSVG ↗地图数据与连接注释:top_full_link_cc.txtTXT ↗

07 / SOURCES

把新透镜落回可验证文件

文章给视角,项目给实例,trace 给证据

新版不替代原来的 RTL build 页,而是补一层“通信工程师更熟悉”的解释。当前旧页面保持不动;这一页独立使用 lane01_comm_assets 下的样式、地图和 trace。

READING · 记忆视角

原文博客:You could have invented the Transformer from memoryWEB ↗golden_reference.py · forward_one_tokenALGO ↗transformer_layer.v · lane1 静态单层RTL ↗transformer_layer_runtime.v · lane0 TDMRTL ↗forward_core_5layer.v · 五层循环RTL ↗softmax_core.v · exp LUT + reciprocal LUTRTL ↗attention_score.v · q · K 相关器RTL ↗kv_cache_multi_layer.v · 多层延迟线RTL ↗

RUN & VERIFY

python golden_reference.py --max-new-tokens 20 --stream python sim/level3_transformer_layer/run_transformer_layer.py python sim/level4_forward_core/run_transformer_layer_runtime.py python sim/level4_forward_core/run_forward_core_5layer.py

trace 生成命令见上一节;完整 trace 文本在 lane01_comm_assets/traces/。地图和旧版页面都保留原文件,互不改动。

通信工程师的一句话版本:Transformer 用 key/value 记忆存储事实,用 q·k 相关器取回,用非线性与 softmax 压制多址干扰;lane1 是单码本接收机,lane0 是把同一套接收机 TDM 到五套码本。

FINAL TAKEAWAY

先有记忆和干扰,才有 attention 的结构;先有单层接收机,才有五层 TDM 复用。

如果一篇讲解让你先记住模块名,再看 RTL,那它还是在“从结果反推问题”。新版希望你先看到:为什么需要记住;为什么多个记忆会互相干扰;为什么非线性与 softmax 能提高容量;为什么五层同构后,layer_idx 和多层 cache 才会出现。RTL 是这些问题在面积、时序和存储约束下的一个具体答案。

communication lens · lane1 transformer_layer / lane0 transformer_layer_runtime
从联想记忆到 TDM 接收机:另一种理解 Transformer 的方式。

page: lane0_lane1_transformer_layer_comm_view.html · map: lane01_comm_assets/top_full_link_cc_zoom.svg
trace: lane01_comm_assets/traces/ · old page untouched

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询