十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

FPGA上跑通MoE大模型:稀疏专家架构部署实战与带宽优化

FPGA上跑通MoE大模型:稀疏专家架构部署实战与带宽优化 最近我在评估一个边缘侧大模型部署项目需要把基于MoE架构的生成模型往FPGA平台上搬。这个想法一提出来团队里就有两种声音一边说MoE是如今大模型提效的明星架构激活参数少、推理开销低值得尝试另一边说FPGA这玩意儿做做接口、跑跑信号处理还行跑大模型纯属自找麻烦不如直接上GPU工控机。两边说得其实都有道理。这个标题的来源是我把这两拨人的争论整理成了自己的实验记录一方面把MoE模型的基本原理吃透另一方面把FPGA上的可行性逐个拆开验证。今天这篇我打算把这段时间的调研和实测心得完整写下来既讲MoE的核心机制也讲FPGA实现时要面对的真实问题。重点是让手里正在做模型部署、或者想了解FPGA在大模型时代能干什么的工程师拿到一份可以直接当参考的架构分析。1. MoE架构稀疏专家模型靠什么省算力1.1 稀疏激活为什么大模型也要省着用算力Moe全称Mixture of Experts中文一般叫“专家混合”或“混合专家模型”。核心思想并不复杂一个大规模神经网络不再让每个输入都流过全部参数而是把模型内部拆成若干“专家”子网络输入数据通过一个门控路由机制每次只激活其中一小部分专家。传统Dense模型比如早期的LLaMA、GPT系列前馈网络FFN层里所有参数都会参与计算。一个7B参数的模型每个token推理时几乎要把所有权重都过一遍。MoE改变了这个逻辑把原来一个大FFN换成了多个并行的小FFN比如8个专家每个专家2B参数总数是16B但每个token只走其中两个专家实际参与计算的参数是4B左右。于是“总参数16B、激活参数4B”的模型就诞生了推理开销和4B模型接近但表达能力向16B靠拢。这种“稀疏激活”的思路本质上是在算力和能力之间做了一次更聪明的取舍。FPGA上算力资源有限不可能一次性容纳一个超大Dense模型的全部计算需求但MoE把计算需求动态降到总参数的一小部分这就给了FPGA入场的机会。1.2 门控与Top-K模型如何决定谁来回答MoE层里最关键的两个部件是Router路由/门控网络和专家集合。Router本身通常是一个线性层输入当前token的隐藏状态输出每个专家的得分。这些得分经过Softmax归一化之后取Top-K个专家作为本token实际要经过的子网络。很多MoE模型用Top-2也就是每个token选两个专家。比如Mixtral 8x7B8个专家每次激活2个。也有一些变体用Top-1比如部分版本的Switch Transformer但Top-1对Router的错误更敏感Top-2比较均衡。Google Gemma 3 26B也就是热词里那个gemma4 26b a4b用的是更极致的A4B形态约26B总参数单token只激活约4B参数背景里同样是几百个小专家加共享专家的混合结构。这里有一个容易被忽略的细节Router本身也消耗算力虽然它的参数量通常只是专家网络的几十分之一但对于极小规模部署而言这一步同样要流经FPGA不能当作不存在。后面我会讲到Router的计算流水线设计和专家计算一样重要。1.3 工业界经典Mixtral、Gemma 3 26B与DeepSeek的MoE实践如果说MoE只是学术界概念那它不会这么热。MoE真正走进工程师视野是2023到2025年之间的事几个典型模型把架构验证得很彻底。Mixtral 8x7B是Mistral公司推出的首个开源MoE大模型。它把7B规模的参数重复8份但每次推理只用2份实际效果全面超过同参数级别的Dense模型而速度接近小模型。Gemma 3 26B则在移动端和边缘设备上展示了MoE的另一面参数量很大但经过量化之后A4B的激活开销让它能在消费级硬件上运行。我在部署测试中模拟过它的层结构单层FFN包含多个细粒度专家和一个共享专家共享专家永远激活细粒度专家由Router挑选这种设计对FPGA特别友好因为共享专家可以做成常驻片上计算单元路由专家的调度则可以缓一点处理。DeepSeek系列把MoE推到了另一个高度。它在MoE里用了细粒度专家切分、偏置调整、sigmoid门控等方式同时把KV缓存和显存调度结合得极深。对FPGA部署来说DeepSeek这种“极细粒度专家共享专家”的结构反而让硬件设计更灵活因为专家越小越容易塞进片上存储和计算单元。1.4 一句话解释MoE的代价MoE不是免费的午餐。它把“总计算量”省下来了代价是“访存调度复杂度”上去了不同token走不同专家专家的负载天然不均衡缓存命中率也可能下降。这个特点对CPU和GPU来说都需要精细设计对FPGA更是如此。FPGA不像GPU那样有极高的线程并发度也没有成熟的运行时调度器所以需要我们自己用状态机构造调度逻辑。到此MoE本身的机制算是交代清楚了。接下来进入FPGA侧。2. FPGA做MoE加速适合与不适合先说结论2.1 FPGA的定位低延迟、确定性与可定制数据通路很多朋友一听到“FPGA实现大模型”就摇头原因不难理解HBM带宽、Tensor Core这些GPU的看家本领FPGA上都没有。如果一套MoE模型的计算模式完全和GPU一致FPGA确实很难占到便宜。但FPGA有一项特点是GPU比不了的确定性延迟和完全定制化的数据通路。GPU运行模型时内存访问和计算任务调度由驱动和硬件调度器统一管理延迟会有波动时序不可控。FPGA则可以把数据通路做成完全固定的流水线从DMA搬运权重到MAC阵列计算到结果回写全部在寄存器级拉通。一旦流水线建立每一拍干什么都是确定性的。这对于车载、工控、医疗器械等对时延抖动有硬性要求的场景极其重要。MoE模型在某几层是稀疏激活的而FPGA恰恰擅长做“按需算数据”的逻辑对于没被Router选中的专家可以完全跳过整块存储读取和计算每一跳省下来的能耗都实打实。2.2 MoE给FPGA带来的优势与挑战MoE对于FPGA最直接的诱惑当然是激活参数大幅下降。26B总参数看起来吓人A4B却只需要每次处理4B参数的计算和访存。FPGA虽然慢但架的住“每次只干一点点活”的模型结构。但要真正落地挑战同样复杂专家权重不连续。不同token路由到不同专家专家分布在DDR的不同地址区域缓存预取策略要重新设计。动态工作负载。每个batch内落到同一专家的token数量不一样计算阵列的利用率会随负载波动需要动态组批来兜底。片上内存容量不足。专家权重即便量化到8bit或4bit一个26B模型也要13GB到26GB权重FPGA板上DDR4一般只有4GB到16GB更别说BRAM/URAM级别的片上存储只有几十MB。所以权重全量驻留片上不可能必须走DDR或PCIe交换。算子粒度不统一。MoE层不是单一算子而是Router、Permute、专家FFN、Unpermute、残差相加的组合每个环节都要在FPGA里做成独立模块。第一个问题是架构选择的根本约束第二个和第三个问题是工程落地最耗时间的地方。2.3 几种见效最快的硬件部署位置选择不是所有模块都适合放进FPGA。我按“见效速度快”拆了三个位置Router加速Router是MoE层里计算量小但依赖链很重的部分所有token都必须先过Router才知道后续往哪里走。FPGA用纯组合逻辑做矩阵乘加能把这个关键路径压到几百纳秒以内。共享专家计算共享专家永远激活可以预先加载到片上存储做成长期稳定运行的流水线计算单元贡献稳定的低延迟吞吐。稀疏专家调度被Router选中的专家权重从DDR搬过来进入计算阵列。这一部分最难但收益最大整个MoE层的计算密集区域都在这里。如果你的项目只需要“让MoE模型跑起来”而不是极致的吞吐优先做前两件事第三件事可以慢慢演进。先把确定性低延迟的体验跑出来再考虑利用稀疏性压成本。3. 从Roofline模型看FPGA边缘部署MoE的边界3.1 算一算参数26B激活4BFPGA缓冲区够不够部署任何模型之前先别听宣传自己动手算一遍Roofline模型看看计算强度每字节数据对应多少次计算落在FPGA平台的哪个区间。算完你就能明确瓶颈是算力、带宽还是存储容量。拿Gemma 3 26B的A4B风格MoE举例设单token激活4B参数单token需要约2×4B8B FLOPs每参数约2次乘加计算。假设我们目标单token延迟5ms对应算力要求是8B FLOPs/0.005s1.6 TFLOPs。这个数字并不夸张一块中高端FPGA例如Xilinx KU115或A100级别以下的各类加速卡在INT8下能突破这个数值但只算FP32会吃力。权重访存呢激活4B参数如果权重用INT8存储每次推理必须从外部DDR读取4GB数据4B参数4GB8bit。按5ms延迟目标看需要的外存带宽是4GB/0.005s800GB/s。这个数字对DDR4来说几乎不可能双通道DDR4-2400约38GB/s对DDR5也勉强只有HBM才能轻松承载。这个粗略计算直接表明了FPGA部署MoE的第一条铁律瓶颈大概率是带宽而不是算力。因此FPGA设计必须以数据复用和带宽优化为核心而不是堆DSP。3.2 DDR与PCIe带宽是关键约束上面那个800GB/s的带宽需求是一个非常乐观的估算实际中要打折扣因为FPGA侧不能把所有时间都花在等待权重上还要计算、搬运中间激活值、和其它模块共享带宽。常见FPGA板的DDR资源如下表平台存储类型理论带宽实际可用带宽能容纳的模型规模低端边缘板Zynq-7020DDR3 1066x217GB/s10-12GB/s4bit量化的小MoE1B激活中端加速卡KU060DDR4 2400x476GB/s50-60GB/s4bit量化 1-4B激活高端加速卡Alveo U280HBM2 8CH460GB/s350GB/s8bit量化 2-8B激活旗舰卡Versal/AGPHBM2e/DDR5组合800GB/s600GB/s8bit量化 8-16B激活实际项目中如果外存带宽只有60GB/s那么A4B模型的单token推理延迟基本会被按在70ms以上除非做权重重复利用或批量处理。所以选型前先做好带宽预算别被“FPGA低功耗”“FPGA低延迟”的宣传冲昏头脑。3.3 对照GPU为什么不是谁算得快谁就赢GPU的Tensor Core算力动辄几百TFLOPsFPGA桌面级加速卡哪怕做到INT8也只有几十到一百多TFLOPs看起来毫无胜算。但真实部署还要看功耗和时延。功耗方面一片中高端FPGA加速卡功耗在40-80WRTX 4090满载450WA100也有400W左右。在车载、嵌入式机箱、无人设备里这个差距比峰值算力更致命。时延方面GPU因为驱动和调度开销端到端推理延迟的最小值往往在几毫秒到十几毫秒FPGA则可以把固定路径的关键路径压到几百纳秒。所以正确的结论是在绝对吞吐场景MoE依然选GPU。在功耗受限、延迟抖动敏感、接口定制化需求高的场景FPGA才有不可替代性。如果你手头项目符合后者继续往下看才有意义。4. 管线落地路由、分组、稀疏计算与DDR预取设计4.1 总体硬件架构Router、专家阵列与聚合单元FPGA上设计MoE加速器一般按模块拆Router模块接收token向量做矩阵乘加产生所有专家的logits取Top-K输出目标专家ID列表和路由权重。Permute/Scatter模块把当前batch内路由到同一专家的token重新编排保证送到专家计算阵列的数据是紧凑的。专家计算阵列Expert Array一组可复用的MAC计算单元单个专家FFN可以映射成若干次矩阵乘。由于专家规模和激活单元数不匹配需要做时分复用。结果聚合Aggregate/Unpermute把每个专家输出的结果按原始token位置汇总乘上Router权重并相加。残差与归一化残差Add、LayerNorm/RMSNorm这些算子很小但影响整体数据流。最核心的设计判断在于不要给每个专家分配一套独立计算单元。FPGA资源撑不住几十上百个并行专家阵列正确做法是设计数量较少的物理计算阵列用状态机控制专业复用。例如8个专家模型物理阵列做2条FFN流水线轮转处理每个被路由到的专家。4.2 分组与组批让路由结果变成高效指令直接按“一个token、一个专家、一组矩阵运算”来做效率会惨不忍睹。因为矩阵乘的循环展开需要连续数据流单token过小会浪费流水线。解决办法是组批batching——在FPGA内部维护一个小型token队列运行Router后按专家ID分组同一专家的token凑到一定数量后一次性送入该专家的FFN计算。这一层逻辑在硬件里通常用Buffer Memory 状态机实现。收到一批token后Router先算完所有专家ID硬件将token按专家ID写入不同Buffer区每个Buffer攒到深度N比如8或16就向对应专家调度器发一个“可计算”脉冲调度器控制PRAM权重加载和FFN执行。攒不满N的怎么办目前我采用的做法是等一个固定的时间窗口超时后哪怕只有2个token也直接启动保证延迟可控。组批的深度要权衡太深则延迟大太浅则计算单元利用率低。实测下来8左右是个不错的起点。4.3 DDR预取与Ping-Pong缓冲MoE专家权重在DDR里通常是按层、按专家顺序连续存储的。由于Router的结果要等token进入模块后才能确定权重不能提前太多预取但可以在上一层计算尚未完成时提前把下一层需要的专家权重从DDR搬到片上。我习惯采用两级缓冲方案A/B两块BRAM或URAM区域交替工作。计算阵列正在用A区权重计算时DMA同时把B区填上下一轮需要的专家权重。这种Ping-Pong结构能把DDR延迟完全隐藏在计算后面前提是每次搬运的数据量不要太大否则DDR带宽会瞬间被占满。表格可以参考上面带宽表这里给出一个DMA搬运时序说明阶段动作总线占用T0-T1搬Expert 3权重到B区DDR高负载T1-T4计算Expert 3DDR空闲/可做其它读取T4-T5预取Expert 7权重到A区DDR高负载T5-T8计算Expert 7DDR空闲这个方案最关键的设计点是计算单元必须能跑到比DMA传输更久才能充分重叠。如果每个专家算得太快DMA反而成了瓶颈Ping-Pong也救不回来需要增加组批深度来拉长计算时间。4.4 稀疏计算的核心RTL流程简述上面提到了用MAC计算阵列做FFN具体到RTL实现我简单总结流程解析Router结果得到expert_id和对应的路由权重gating_weight。生成权重地址base_addr expert_id * expert_weight_size offset送交DMA控制器。权重流进URAM缓存后按行顺序送给MAC阵列做矩阵乘。每个专家FFN有2层线性变换gated up投影加激活函数。激活函数用查表法或分段线性拟合实现避免直接用复杂的指数/对数电路。结果乘上gating_weight再按token原始位置回写。中间穿插一个常见阻断DDR上的权重地址对齐问题。很多FPGA DDR控制器要求burst长度是固定值的整数倍专家权重如果size不是突发对齐搬运时要么填充哑数据要么全串行读后者会大幅折损带宽。因此预处理时把每个专家的权重pad固定大小是特别值得做的优化。5. 实操复盘导出权重、量化、烧入FPGA时遇到的坑5.1 导出权重的预处理FPGA工具链支持不了PyTorch直接导出的一堆自定义算子这是第一个大坑。我的做法是先用ONNX把模型切分到细粒度算子再逐层转成自己设计的固定指令格式。MoE层的导出顺序去掉训练专用的BatchNorm/Dropout或者把它们fold进前层。把Router和专家网络分别导出成独立ONNX图。把权重按“专家ID layer_id 参数名”的规则重排后存储成二进制文件。对每个专家权重做pad使字节长度对齐到DDR突发长度比如64字节或128字节。为什么要重新排序而不是直接沿PyTorch顺序存因为推理时是按专家随机访问的如果DDR上权重排列乱七八糟DMA会产生大量随机读带宽利用率会掉到30%以下。实测下来重排后带宽利用率能从30%恢复到70%以上。5.2 量化与BF16/INT8取舍FPGA上做通用全精度FP32是不现实的面积、功耗都受不了。常见路线是BF16或INT8。BF16对FPGA友好因为指数位和FP32一致不需要复杂的动态范围校准尾数少了7位乘法器面积减小。但BF16仍需较大资源来做浮点运算。INT8则可以把MAC阵列做到最紧凑用DSP48E1直接就能拼出高效的乘法累加。量化校准一定要用真实的验证集不能只看权重分布。MoE模型里Router和专家激活很容易出现离群值简单per-tensor量化会导致某些Token结果严重偏差。我建议per-channel或per-group量化尤其对Router输出保持高精度BF16或者16bit量化因为路由权重直接影响专家选择错一点结果就全偏了。当前实测组合是Router用BF16专家矩阵用INT8 per-group量化激活用INT8并加scale修正。这个组合在26B级别模型上把效果损失压在1%以内而计算资源只占FP32方案的不到四分之一。5.3 仿真阶段常见问题我在这部分踩的坑最多列几个最典型的第一DDR带宽打不满。仿真时总以为DDR理论带宽能用上实际HLS或Verilog仿真里没做Ping-Pong所有DDR读等待都变成空泡。把搬运和计算重叠起来之后有效吞吐才上来。第二Router和专家计算竞态。两个模块同时访问同一块BRAM偶尔读到的数据是旧版本。原因是Router写专家ID和专家计算单元读token数据之间缺少握手信号。处理办法是加valid/ready握手协议所有模块间的通信都按AXI-Stream风格设计。第三Top-K选择的logits相等。Router输出完全相同分数时不同实现可能随机选一个。这个行为在RTL里必须固定否则帧间一致性对不上调试时无法复现。我在硬件里固定了取“最小专家ID优先”的策略。第四乘法器时序收敛问题。INT8 MAC阵列拼得大了组合路径太长导致时序不收敛。后来在乘法器输出加了两级流水寄存器流水线延迟增加但频率从200MHz拉到300MHz总吞吐反而升了。5.4 实测数据分析与调优顺序最后给出一个我第一次完整跑通的实验数据你们可以拿去做基准对比。项目参数模型约26B参数A4B风格MoE自建实验模型目标延迟10ms/token计算精度Router BF16 Expert INT8计算单元INT8 MAC阵列 x8路DDR板载4通道DDR4-2400实际带宽利用47GB/s理论稳定28-35GB/s专家平均组批深度约6-10端到端单token延迟实测16-22ms一次性延迟没达到目标主要瓶颈就在带宽利用率只到六成左右。之后的优化顺序是先调DMA突发对齐和Ping-Pong深度再看Router与计算阵列的握手机制最后才是提升MAC阵列频率。反过来的优化先堆频率是常见误区因为换来的算力会被带宽瓶颈吃掉。调优过程中还发现一个有意思的现象MoE的专家负载不均衡在真实输入里非常明显大约20%的热门专家承担了超过60%的流量。所以我在DDR预取策略里加了一个小表记录最近1万次路由的专家访问频率对高频专家常驻缓存低频专家才走DMA。这个改造简单但收益明显实测把端到端延迟又往下压了3到4毫秒。FPGA做MoE本质上是拿定制化换效率的长期工程。我的体会是先别指望一步到位复现GPU的全能力把路由、带宽、组批这三件事做扎实MoE在FPGA上的表现会稳定且可控这是传统GPU工控机方案给不了的东西。
返回列表