↓ Skip to main content

Posts

2026

从 Dense FFN 到 MoE:Router、Token Dispatch 与 Grouped GEMM

·5127 words·11 mins
上一篇 MoE 笔记把架构家族理了一遍——稀疏、稠密、Soft MoE,gate 在前还是在后,决定了算力形态和适用场景。 但那篇有一段伪代码一直让我不太舒服: 1for prob, idx in zip(topk_probs.unbind(1), topk_idx.unbind(1)): 2 out += prob.unsqueeze(1) * self.experts[idx](x) 逻辑上没问题。但想象一下真实场景:一个 batch 有几千个 token,每个 token 选 2 个 expert,就是上万个 token-expert 计算任务。用 Python for loop 逐个调 expert 的 forward,GPU 利用率会低得离谱。

为什么 Self-Attention 不能偷看未来?从 Causal Mask 到自回归训练

·4700 words·10 mins
最近在看 MIT 6.S191 Lecture 9 讲 Context Parallelism 的时候,碰到了一个词:Causal Attention。 我对 Self-Attention 的公式并不陌生——之前那篇已经把 QKV 和 routing score table 拆得比较清楚了。但 Causal Attention 这个概念我一直没有认真想过。回头看,我写 Attention 公式、写 Multi-Head、写 FlashAttention 的时候,脑子里跑的都是"所有 token 都能看到所有 token"的 Full Self-Attention。

预测正确,策略为何仍可能亏钱?——从 Markout 到执行感知回测

上一篇写到,预测对价格方向,不等于交易能赚钱。主动成交要付执行成本,挂单等成交又可能筛出对自己不利的行情。 顺着这个问题往下想,我还有一个疑问:如果把手续费算进去,回测里也只让一部分挂单成交,是不是就离真实收益很近了?

从 RVO 到 Guaranteed Copy Elision:C++ 返回值优化的演进

·4193 words·9 mins
一道我答错的题 # 最近做了一个 Modern C++ 水平测试,碰到这样一道题: 1#include <utility> 2 3struct Widget { 4 Widget() = default; 5 Widget(const Widget&) = delete; 6 Widget(Widget&&) = delete; 7}; 8 9Widget createA() { return Widget{}; } 10 11Widget createB() { 12 Widget w; 13 return w; 14} 15 16Widget createC() { 17 Widget w; 18 return std::move(w); 19} 问:在 C++17 下,哪些函数能通过编译?

深入理解 PyTorch DDP:为什么更少的通信,不一定意味着更快的训练?

起因 # 上一篇讨论完 Checkpointing 和 Offloading 之后,结尾留了一句:单卡优化的代价已经不可接受时,下一步自然是考虑让多张 GPU 分担训练状态。 于是我开始看 DDP(DistributedDataParallel)。一开始觉得 DDP 的核心思想很直白——每张卡各算各的梯度,然后 All-Reduce 同步一下,用平均梯度更新参数。看起来最朴素的做法就是把所有梯度打包成一个大 tensor 做一次 All-Reduce,简单干净。

7B 模型只有 14 GB 权重,一张 80 GB GPU 为什么仍可能 OOM?

起因 # 之前分别写了推理和训练的显存心智模型和混合精度训练中的显存组成,反复出现一个粗估:BF16 mixed precision + AdamW 大约 16 bytes/parameter。但这个数字每次都只是"1B × 16 = 16 GB"的单位换算,没有真正对着一个具体的 Transformer 架构把账从头到尾算一遍。