
上个月某天我扫了一眼网站后台发现一个小时内有几千人涌进一个我维护的开源页面。我愣了一下顺着来源找过去才看到是一位我非常尊敬的AI大牛在社交账号上转发了我做的“LLM架构画廊”配了一句话这个项目把散落在大量论文里的模型架构图整理成了统一、可交互的图谱值得看看。说实话那一刻我比收到任何奖项都开心。但开心归开心静下来想想这个项目最开始的出发点其实特别朴素我读论文时受够了那些形状各异、符号混乱、想表达的东西全靠个人发挥的架构图。这篇博文就聊聊这个画廊项目从想法到落地、再到被更多人看到的过程中我在分类逻辑、绘图约定、技术实现和项目维护上的一些真实经验。如果你也经常在论文配图面前卡住或者想给团队做技术分享但找不到一套统一讲法又或者单纯想把Transformer这类概念串成一张属于自己的知识地图都可以往下看。1. 起点为什么我要把所有LLM架构“画”出来1.1 论文里的架构图为什么越看越懵我最早接触LLM相关论文时最怕的不是数学推导而是那页配图。每篇论文的架构图都有自己的“方言”有的把归一化画成灰方块有的画成一条横杠加希腊字母有的把残差连接画成粗实线有的画成半圆弧有的在图上标注张量维度有的把所有信息都塞进一个“简洁大气”的示意图里看起来漂亮但看完根本不知道数据是怎么流的。时间久了你会发现一个更扎心的问题绝大多数人对架构的理解是碎片化的。你可能知道某个注意力机制变体是怎么回事但你未必知道它被放在一个Decoder块里的第几步你可能知道混合专家模型有一堆“专家”但你未必清楚路由模块到底改变了哪条数据通路。这种碎片化认知在读论文、做技术选型、给团队做技术分享时都会卡壳。我决定做一个“翻译层”把不同论文里的同一种东西用同一套视觉语言画出来这就是画廊项目的起点。1.2 从“一张图”到“一整个画廊”的动机起初我只是想画好一张Transformer架构图结果发现一个问题如果每张图都用一套临时设计的图例那换一篇论文我又得重新适应。索性我建了一个图例公约把LLM架构里常见的组件统一成标准符号——注意力块、归一化、残差流、KV缓存、路由、位置编码、嵌入层等等全都用固定的形状和颜色表示。然后我再把不同架构的图按照这套公约一张张画出来放到同一个站点里。这个项目我从一开始就想明白了两件事。第一它是给理解用的不是给复现用的。我不追求像素级还原某个开源实现只画主流语义下的“共性结构”帮助读者快速抓骨架。第二它的目标用户有三种快速扫盲的学生、做技术预研的工程师、准备分享材料的讲师。这三种人的共同痛点是“需要一套统一、清晰、可比较的架构图”而不是被几十种论文画风来回折腾。2. 画廊的分类学把几十种主流架构摆进一张“地图”2.1 我用来切分架构的四个坐标项目收录过几十种架构之后光靠一一列举已经没法看了必须有分类。我琢磨了很久最后确定用四个坐标把一个架构的基本性格描述出来。第一个坐标是信息可见范围。它决定了模型看到上下文的方式是只能从左往右看还是能左右同时看还是能前缀双向、后缀单向。这个坐标直接决定了绘制时数据流的箭头到底朝向哪个方向也是很多架构图一开始就画混的地方。第二个坐标是核心算子。注意力是Transformer系的家底但后来出现了一类用线性算子或类似方式替代注意力的架构。画图时这类架构的块内结构完全不一样——你把注意力那一大方块画出来读者就会产生误解。第三个坐标是结构组合方式。这里有稠密结构也有类似混合专家那样的稀疏路由结构。混合专家最吸引人的点在于它不是把网络做厚而是把网络做宽然后用一个路由模块决定每个token走哪些路径。这块如果不画清楚路由分叉就等于没画。第四个坐标是模态与训练目标。单模态语言模型和多模态融合模型的长相差别很大前者通常是一条干净的语言干路后者会有多个编码器入口然后再过一个融合模块。训练目标也影响绘制encoder-decoder架构在图上天然是两条腿走路decoder-only架构则是一条直线串到底。2.2 画廊目前收录的核心架构族基于这四个坐标我把画廊里的架构分成几个大族每个族在画图约定上有自己的主场颜色和组件组合方式。下面这张表是我常用的分类框架架构族核心特征绘制时最需要注意的地方双塔Encoder-Decoder系输入输出各走一条编码/解码路径中间通过交叉注意力相连编码器和解码器的信息流向不要画混交叉注意力要单独用一组连接线单塔Decoder-only系自回归生成一条主干链路串到底残差连接与子层顺序必须准确KV缓存的走向要标清楚双向Encoder系对上下文做双向建模适合理解类任务双向可见如何用箭头表达建议用“同层横向双重箭头”而不是两个单向箭头线性注意力系用线性算子近似全局注意力常配合更简化的状态更新块内不再是标准注意力结构不要硬画QKV三件套稀疏路由混合专家系注意力共享主干局部用路由切换多组专家路由分叉的汇聚点要画出“先分散后合并”说明token只会走部分路径多模态融合系多个模态编码器接入融合后进主干不同模态编码器的入口宽度不一致图上建议用不同色带区分来源2.3 这个分类学给我带来的“读论文加速”把几十种架构摆进同一张坐标地图之后我发现一个现象很多看起来“全新”的架构其实是旧组件的新组合。比如新出一篇论文看图时我会先尝试翻译成画廊这套符号体系问三个问题它的信息可见范围是什么它的核心算子是哪一类它在块结构上有没有额外分支三个问题答完这篇论文的架构差不多就能落到某个我已经画过的族里剩下的工作只是盯着变量细节和实验曲线。这种读法还有一个附加好处你不再被作者的“画风”牵着走。以前看论文我总会被一张华丽的架构图带偏觉得对方很高级现在我会直接把它剥成画廊里的组件序列技术水平反而更容易判断。3. 一张图的诞生从Transformer块到整条数据流3.1 绘制单位不是“一层网络”而是“一次token的处理过程”很多初学画架构图的人有一个误区把“一层网络”当成最小的绘制单位。但实际读图时读者脑子里希望看到的是“一个token从进来到出去经过了哪些操作”。所以我决定画廊里的每一张图最小绘制单位是“一个块内的一次完整计算过程”。以最典型的decoder-only架构为例整条链路画下来是输入token序列经过嵌入层投影成稠密向量进入一个循环堆叠的处理块每个块内部做归一化、注意力、归一化、前馈网络最后经过输出层映射为分布。这样画出来的图信息流非常清楚读者也可以拿着图对着代码一步步走。我会在每条连接线上标注张量的大致形状比如batch、sequence长度、hidden size能顺手标清多头注意力的head数量就更好。3.2 每个组件在画廊里的“标准画法”画图前我定了一套组件词典确保所有架构图里同一个东西长得一样。归一化画成小菱形注意力的核心画成一个大矩形里面横向切开分成若干个“头”的小格前馈网络画成一个带中间膨胀的窄矩形暗示隐藏层维度通常是4倍残差连接用粗实线画在主流程上分支用中等粗细的线条表示KV缓存用独立的窄条贴在大矩形侧边并用虚线连接到注意力部分。这些约定看起来琐碎但实际价值非常大。一旦读者用顺手了他走进画廊任何一张图都能用手指着方块说出组件名。我在第一次把某个线性注意力架构画出来时就发现一个好处因为画廊里没有画出QKV三件套很多第一次看到类似架构的读者反而立刻明白——原来这里发生了“注意力机制的替换”而不是“注意力模块内部的小改动”。3.3 最容易画错、最容易看错的两个细节我画废过好几版图最后发现有两个细节特别容易出问题也特别容易让读者误解。第一个是Pre-Norm和Post-Norm的区别。很多讲Transformer的图都不画这一点或者在残差跳线上含糊带过。我后来统一约定如果是Pre-Norm残差箭头从输入节点直接画到主干上子层内部的归一化画在子层前面如果是Post-Norm归一化画在子层之后。这个顺序直接影响训练稳定性和参数更新路径图上画错了读者就会对“为什么要做归一化”产生困惑。第二个是多头注意力的维度切分。假设隐藏层维度是4096多头数量是32那每个头的维度就是128。许多新读者在看图时经常忽略这个关系他们的疑问是既然隐藏层是4096为什么QKV矩阵里画出来的每个小格子是128所以我专门在图里标注head_dim的计算公式并在每个头的小格里标上形状。这样看的人一眼能明白多头不是复制32份参数而是把一个高维向量切成32段并行处理。3.4 交互层我想要做的三件事静态图做得再好也还是有局限。我在画廊上加了三层交互。第一悬停显示。鼠标悬停在某个组件上时右侧会浮动展示这个组件在主流实现里对应论文中的相关描述以及一张双语名词对照。这对那些“看懂了图但不知道怎么跟论文对上号”的读者非常有用。第二切换详细程度。画廊里的架构图分为“压缩版”和“完整版”。压缩版只显示主干数据流和关键组件名适合用来快速理解整体骨架完整版会补齐每个组件的内部结构、维度标注和输出形状。两个版本之间用一个按钮切换我不希望一张图同时塞进太多信息导致谁也看不清。第三缩放下保持信息稳定。图放大时标签跟着变大缩小时自动隐藏次要标签保留主干节点名。这需要在SVG渲染时做分级显示技术实现上有点麻烦但用户体验会好很多。4. 实现画廊站点时踩过的技术坑4.1 技术选型为什么这么“朴素”画廊这类项目最容易犯的毛病是过度设计。我也动过用重型前端框架配可视化大屏的心思后来冷静想了想项目真正的难点在内容维护而不是页面效果。最终我选了非常朴素的方案一个静态站点生成器负责页面结构架构图全部用SVG矢量图形手写渲染逻辑交互部分用原生JavaScript。这样做有三个好处。第一任何人只要懂一点前端基础fork下来就能改。内容型开源项目最怕贡献门槛太高。第二SVG是矢量格式既可以网页上缩放又能导出成高清图放进PDF和PPT里这正好服务了用户的需求。第三没有大量运行时依赖意味着不用三天两头升级框架项目长期可维护。4.2 数据与渲染分离的目录结构为了让新增一张架构图变得更加轻松我把数据和渲染逻辑拆开。每个架构对应一个JSON文件里面描述组件的类型、位置、连接关系、标签文本等渲染层只负责把JSON翻译成SVG。gallery/ ├─ data/ │ ├─ decoder_only.json │ ├─ encoder_decoder.json │ └─ linear_attention.json ├─ render/ │ ├─ node.js │ ├─ edge.js │ ├─ tooltip.js │ └─ label.js └─ site/ ├─ index.html └─ assets/JSON结构设计得尽可能扁平便于人工审阅。比如核心数据流部分我用一个nodes数组和一个edges数组分别维护组件块和连接线每条连接带上标注from、to、label三个字段。这样即使不看文档凭眼睛也能快速检查有没有连错线。4.3 SVG绘制中多次让我返工的问题SVG看起来是成熟技术真上手画复杂架构图时还是有一堆坑。第一个坑是文本换行。SVG里的text元素不支持自动换行一旦架构图里的节点名较长文字就会溢出矩形边界。我一开始写了个硬编码换行函数按字符数量切分后来发现中文和英文的字符宽度不一样又改成按测量文本宽度动态折行。第二个坑是事件覆盖。给组件区域绑定悬停事件时发现组件上的文字会挡住下层矩形的鼠标事件导致tooltip时隐时现。最后解决办法很简单给所有非交互的标签元素统一加pointer-events: none让事件只落在真正的组件容器上。第三个坑是移动端缩放。手机浏览器把双指缩放当作页面手势SVG内画的元素无法直接响应缩放。我的处理是给每张图单独提供“全屏阅读”模式进入该模式后禁用页面的默认手势只在SVG容器内部做缩放和平移。第四个坑是DOM节点膨胀。一张复杂架构图动辄上千个节点如果一次性全部渲染到SVG里性能明显下降。后来我用IntersectionObserver做懒渲染并且把次要层级的组件按需绘制首屏只显示主干和一级分支。4.4 性能与可访问性画廊本质是一个内容站点不是数据大屏所以性能标准按“普通笔记本上打开不卡、首屏不白屏”来定。我在列表页只渲染每个架构的缩略图缩略图是对完整SVG做轻量化裁剪后的低复杂度版本。进入详情页时才加载完整图形数据并按组件类型渐进渲染。亲测下来首屏加载时间基本能控制在一秒以内。可访问性方面我给每个组件区域都加了tabindex和语义描述键盘用户按Tab可以依次浏览各个块结构配合读屏软件能听到“注意力模块输入大小409632头”这样的描述信息。这部分工作量不大但对视障用户和习惯键盘操作的人来说体验差异很大。5. “被大牛点赞”之后流量来了问题也来了5.1 那几天我经历的“访客曲线暴涨”前面提到的那次转发成了整个项目的一个分水岭。我的明确定位一直是“给感兴趣的人看”所以之前没有做过多少宣传。但那位AI大牛的转发作用相当于给项目做了一次信用背书。当天下午到晚上后台访客曲线几乎是垂直上升一口气翻了好几十倍GitHub上的star数量也开始跳。这也带来一个问题原本我给画廊定的节奏是“一周整理一个新家族”结果那之后的一周我几乎全在回复issue、处理PR、做兼容性修复。那段时间我真实感受到一件事项目被看见了就不再是私人笔记而是一个需要对外负责的公共物品。维护者如果心理上没有准备好很容易被反馈淹没。5.2 用户反馈里的三件“没想到”流量带来了很多声音其中有三类反馈让我印象最深。第一类是教学场景。有个用户告诉我他把画廊里的几张图直接放进了课程PPT里前后对比比自己画的架构图清楚得多。这个反馈让我意识到图例公约的价值不只在于我个人读论文还能降低讲师准备材料的成本。第二类是翻译需求。有人想给画廊做多语言版本希望我更规范地管理文案字段。我原来把所有标签都写死在JSON里这一下就暴露问题了。我随即把与业务渲染无关的文案全部抽成语言资源文件为后续多语言铺路。第三类是纠错。有人指出某个混合专家架构图里路由分叉的方向画反了。我仔细核对后发现确实有问题。这个反馈让我特别高兴因为我一直希望项目能被“批判性使用”一个真正有人认真看的图才会有人帮你较真。5.3 我基于反馈做的重构经过那次流量冲击我做了一次系统性的重构核心是把“一个人说了算”改成“社区共同维护”。我补充了贡献指南明确规定一张新架构图进入画廊之前必须满足的三个条件组件必须符合图例公约必须标注数据流方向必须给出至少一个来自主流实现的对照来源。同时新增勘误机制任何人发现图形错误都可以提交issue页面底部也列出了已确认的勘误记录避免错误信息被反复复制。我还把绘制规范文档化了原来这些规范只存在于我的脑子里现在变成wiki页面社区成员可以直接照着画。说实话这一步比涨几千个star更有价值因为项目从“某个人的作品”变成了“一套可扩展的公共工具”。5.4 心态变化项目做大后的两个坚持有了流量之后我给自己定了两条不算正式的规矩。第一条坚持“为理解而画而不是为完备而画”。我不追求把所有架构的每一个变种都收录齐全。画廊不是论文索引而是一扇门让读者先看懂主流形态再有能力自己去读变体。如果每一张图都堆满细节那就又变成了一堆让人看不懂的复杂图纸。第二条不追热点。新架构层出不穷如果每个都急着上线只会让维护质量下降。我给自己定了一个相对稳定的更新节奏一个架构族至少经过半个月审校后才放出。热度会过去但一个被反复核对的图例体系才是大家持续回访的理由。6. 你也可以做出自己的架构画廊6.1 画架构图前先写一份“组件词典”如果你也想给自己所在的领域做一套可视化知识库我建议别急着打开画图软件先花一晚上写一份“领域组件词典”。把领域里所有高频名词全部列出来给每个名词指定唯一的视觉对应方式。比如序列模型领域残差流就是粗实线归一化就是菱形注意力模块就是带横向切分的矩形。规则只有一条同一功能永远只保留一种画法。这个词典就是你整个项目的宪法。以后画任何新图都不能违背它否则视觉体系会在第三张图开始崩塌。我在项目的早期吃过这个亏最初几张图的注意力画法并不一致后来花了整整一周统一重画非常痛苦。6.2 我总结的三层绘制法我给贡献者写绘制规范时把一张架构图的诞生过程拆成了三层。第一层是宏观数据流。在一张白纸上先确定数据从哪个端点进、从哪个端点出主干中间经过几个大块。这一层只画最重要的连接线和块名不看任何子组件细节目标是让缩略图都能看清。第二层是组件内部结构。把主干上的每个大块拆开画出内部的子组件以及它们之间的顺序。这一层是整张图的信息主体需要严格按照组件词典来画。第三层是标注层。在第二层基础上补充张量形状、维度关系、需要注意的算子位置。很多初学者看架构图看得很累就是因为在第二层和第三层混着看信息太密。分层绘制后图本身依然是完整的一幅但我的绘制过程会刻意按三层来思考和检查。6.3 从单体画廊到可复用的组件库做到现在画廊已经不再只是“几十张图”的集合而是一套可复用的绘图组件库。数据与渲染分离之后新增架构不需要重新画SVG只需要写一份JSON配置。这让社区的参与成本大大降低也让画廊具备了做“架构对比”功能的潜力——两个架构并排渲染组件可以跨图高亮差异点一目了然。我下一步的计划是把画图规范继续打磨得更细并开放模板供外部文档使用让其他技术团队也能在他们的博客或文档里嵌入这些标准化图形。这是一条更长的路但走完以后或许会形成一个小生态。最后再分享一点我个人的感受。被大牛点赞这件事带来的最大变化不是流量也不是数字上的满足感而是让我重新确认了一个朴素的事实可视化工具真正服务的人永远是那些还处在“看不懂”阶段的人。只要有人因为画廊里的某张图少花一晚上去猜一个方块的含义这个项目就值得继续画下去。