尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

MOE路由:路由(logits: top-k/8)

MOE路由:路由(logits: top-k/8) 路由.h// 路由.h —— MoE 专家路由选择声明// 用途从路由门控输出256 维 logits选择 top-8 专家并计算权重// 说明路由是 MoE 的核心决策——每个 token 只激活一小部分专家8/256// 权重 softmax 后 top-k 的重新归一化#pragmaonce// 引入基础类型浮点/无符号/向量#include公共/基础定义.h// 路由条目一个被选中的专家及其权重struct路由条目{// 专家索引被选中的专家编号0..专家数-1无符号 专家索引0;// 权重该专家输出的加权系数top-k 归一化后总和为 1浮点 权重0.0f;};// Softmax朴素数值稳定的 softmax先减最大值再指数// 公式softmax(z)_i e^{z_i - max(z)} / Σ_j e^{z_j - max(z)}// 参数输入 logits 数组输出 概率数组可与输入同一缓冲数量 元素个数voidSoftmax朴素(constfloat*输入,float*输出,size_t 数量);// 路由选择从门控输出选 top-k 专家并归一化权重// 参数门控输出 路由 logits长度 专家数专家数 全部专家个数256// 激活数 要选择的专家个数8// 返回按权重降序的路由条目列表长度 激活数权重总和为 1// 步骤1. softmax → 2. 选 top-k部分选择→ 3. top-k 权重重新归一化和为 1向量路由条目路由选择(constfloat*门控输出,size_t 专家数,size_t 激活数);路由.cpp// 路由.cpp —— MoE 专家路由选择实现// 用途从路由门控输出256 维 logits选择 top-8 专家并计算归一化权重// 说明路由决策是 MoE 的核心——每个 token 只激活一小部分专家8/256// 其余专家权重不参与计算稀疏计算这是 MoE 效率的关键// 数学// p softmax(W_gate · x) —— 路由概率分布256 维// 选 top-kk8保留概率最大的 8 个专家// 权重重新归一化w_e p_e / Σ_{e∈top8} p_e —— 保证权重和为 1#include内核/MoE/路由.h// 引入算法库部分排序#includealgorithm// 引入标准头数学函数指数/最大#includecmath// 引入错误处理参数校验#include公共/错误处理.h// Softmax朴素数值稳定的 softmax先减最大值再指数// 说明减最大值保证 exp 不溢出e^{大数} 会变 inf减 max 后指数 ≤1voidSoftmax朴素(constfloat*输入,float*输出,size_t 数量){// 防御数量必须 ≥1if(数量0){抛出运行错误(Softmax朴素数量必须大于 0);}// 找最大值数值稳定减最大值后再指数float最大值输入[0];for(size_t i1;i数量;i){if(输入[i]最大值){最大值输入[i];}}// 指数并求和float总和0.0f;for(size_t i0;i数量;i){输出[i]std::exp(输入[i]-最大值);总和输出[i];}// 归一化总和可能为 0 仅当全部输入为 -inf防御除零if(总和0.0f){for(size_t i0;i数量;i){输出[i]/总和;}}else{// 全部 -inf 的退化情况均匀分布防御for(size_t i0;i数量;i){输出[i]1.0f/static_castfloat(数量);}}}// 路由选择从门控输出选 top-k 专家并归一化权重// 步骤1. softmax → 2. 选 top-k部分选择→ 3. top-k 权重重新归一化和为 1向量路由条目路由选择(constfloat*门控输出,size_t 专家数,size_t 激活数){// 防御参数合法if(专家数0||激活数0){抛出运行错误(路由选择专家数与激活数必须大于 0);}// 激活数不能超过专家总数constsize_t 有效激活数std::min(激活数,专家数);// 步骤 1softmax 得到路由概率向量浮点概率(专家数);Softmax朴素(门控输出,概率.data(),专家数);// 步骤 2选 top-k按概率降序取前 k 个专家的索引// 用部分排序构造 (概率, 索引) 对排序后取前 k向量std::pair浮点,size_t候选(专家数);for(size_t i0;i专家数;i){候选[i]{概率[i],i};}// 降序部分排序最大的 有效激活数 个在前std::partial_sort(候选.begin(),候选.begin()有效激活数,候选.end(),[](constautoa,constautob){returna.firstb.first;});// 步骤 3top-k 权重重新归一化和为 1浮点 权重总和0.0f;for(size_t i0;i有效激活数;i){权重总和候选[i].first;}// 防御权重总和为 0全 -inf 退化时均匀分配const浮点 归一化系数(权重总和0.0f)?1.0f/权重总和:1.0f/static_cast浮点(有效激活数);// 构建返回列表按权重降序向量路由条目结果(有效激活数);for(size_t i0;i有效激活数;i){结果[i].专家索引static_cast无符号(候选[i].second);结果[i].权重候选[i].first*归一化系数;}return结果;}
返回列表