大模型数学速成(03):Q/K/V 投影——同一输入,三种角色
上一篇我们学会了 $y = W \cdot x + b$ 的「握手规则」。在 Transformer 的注意力层里,同一份输入特征会连乘三次——分别得到 Q、K、V。为什么要三套权重?权重 $W_q$ 和激活 Q 有什么区别? 这一篇把 Q/K/V 投影一次讲透,为第 05 篇的注意力与 Softmax 铺路。 这是「大模型数学速成」系列的第 3 篇。建议先读 第 02 篇:矩阵乘法。下一篇讲 LayerNorm、RMS Norm 与残差连接。 一、三次投影:同一输入,三种「角色眼镜」LayerNorm 之后,每个 token 有一列通用特征 $X$,形状 [768, S](S 为 token 数)。注意力层对 同一 X 做三次线性变换: $$Q = W_q \cdot X + b_q,\quadK = W_k \cdot X + b_k,\quadV = W_v \cdot X + b_v$$ 12345678910 同一份 X(Norm 后的特征) [768...
现代 C++ 实战(06):Lambda 与类型推导
智能指针解决「谁拥有资源」,Lambda 解决「怎么写小段逻辑」——回调、算法谓词、闭包、延迟执行,现代 C++ 里无处不在。从 C++11 的 [](){} 到 C++20 的模板 Lambda,每一版标准都在把它变强。 这一篇系统梳理 Lambda 语法、捕获方式、与 auto/decltype 的类型推导,并对比函数指针与 std::function 的取舍。 这是「现代 C++ 实战」系列的第 6 篇。对应 demo:ref/cpp_demo/basics/lambda_demo/。建议先读 第 05 篇:智能指针(下)。 一、基本语法:[](){} 四部分Lambda 的完整形式: 1[捕获列表](参数列表) 可选说明符 -> 返回类型 { 函数体 } 部分 含义 可省略? [...] 捕获列表:把外部变量「带进」闭包 空 [] 表示不捕获 (...) 参数列表,同普通函数 无参时可写 () 或省略 -> T 显式返回类型 可省略,编译器推导 {...} 函数体 不可省略 最小例子: 12a...
x86 汇编入门(05):函数调用与递归阶乘
call 和 ret 是汇编里最重要的「接力棒」。没有它们,代码只能从上到下一条道走到黑。这一篇我们拆开函数调用的完整机制,并用递归计算 5 的阶乘——在汇编里亲眼看到栈是怎么一层层长高的。 这是「x86 汇编入门」系列的第 5 篇。上一篇用跳转实现了循环。这一篇通过 05_function.asm,理解 call / ret、栈帧和 x86_64 调用约定。 一、call 和 ret 做了什么?123call factorial ; ① 把「下一条指令地址」压栈 ② 跳到 factorial...ret ; 从栈弹出地址,跳回去 可以把它想成:call 留下回城坐标,ret 按坐标回去。栈就是存放这些坐标的地方。 二、栈帧:函数自己的「工作台」每次进入函数,标准开场是: 12345678factorial: push rbp ; 保存调用者的帧指针 mov rbp, rsp ; 建立当前帧 push rbx ; 保存要用的 callee...
大模型数学速成(02):矩阵乘法——神经网络的基本变换
上一篇我们约定:列 = token,形状 [768, 1024] 表示 768 维特征 × 1024 个 token。接下来几乎所有 Transformer 层都在做同一件事——矩阵乘法:对每个 token 的特征向量做线性变换。 这一篇搞懂 $y = W \cdot x + b$ 在算什么、「握手规则」为什么必须成立,并用 3 维 × 2 token 的手算例子建立直觉。Q/K/V 三次投影留到下一篇。 这是「大模型数学速成」系列的第 2 篇。建议先读 第 01 篇:张量、维度与「列 = token」。下一篇讲 Q/K/V 投影——同一输入,三种角色。 一、一句话概括矩阵乘法 = 对每个 token 的特征向量做一次线性变换(旋转 + 拉伸 + 平移),把信息从一个「语义空间」映射到另一个「语义空间」。 神经网络里一层线性层,本质上就是一次矩阵乘法加偏置;堆叠多层非线性激活,才形成复杂的表达能力。 二、生活类比:调咖啡1234567输入向量 x = [咖啡豆量, 水量, 奶量] ← ...
现代 C++ 实战(05):智能指针(下)——模式与循环引用
上一篇我们掌握了 unique_ptr 和 shared_ptr 的基本用法。但在真实项目里,智能指针不只是替代 new/delete——循环引用、工厂函数、Pimpl、Observer 等场景会逼你思考「谁该拥有、谁该观察」。 这一篇是智能指针的下半场:weak_ptr 如何打破循环引用,以及几种经典设计模式如何用智能指针落地。 这是「现代 C++ 实战」系列的第 5 篇。对应 demo:ref/cpp_demo/smart_pointers/ 第 05–09 节。建议先读 第 04 篇:智能指针(上)。 一、weak_ptr 与循环引用shared_ptr 的引用计数是双向的:A 持有 B,B 也持有 A 时,计数永远不归零——内存泄漏。 12345struct Node { std::shared_ptr<Node> next; // std::shared_ptr<Node> parent; // 危险:与子节点形成环 std::weak_ptr<Node> parent; // 安...
x86 汇编入门(04):循环与条件跳转
高级语言里写 for (i = 1; i <= 10; i++) 一行搞定。汇编里没有 for,只有比较 + 跳转。这一篇用 04_loop.asm 打印 1 到 10,把循环拆成你能看见的每一步。 这是「x86 汇编入门」系列的第 4 篇。上一篇实现了算术和数字打印。这一篇通过 04_loop.asm,学习条件跳转指令和循环结构的汇编写法。 一、比较与跳转cmp a, b 做减法但不保存结果,只设置 CPU 标志位。然后根据标志位跳转: 指令 条件 je 相等 (ZF=1) jne 不相等 jl 小于(有符号) jle 小于等于 jg 大于 jge 大于等于 jmp 无条件跳转 二、用跳转拼出循环04_loop.asm 的逻辑等价于: 123for (int i = 1; i <= 10; i++) { printf("当前数字: %d\n", i);} 汇编实现: 1234567891011121314mov r12, 1 ...
大模型数学速成(01):张量、维度与「列 = token」
你在文档里看到 [768, 1024],第一反应可能是:768 是行还是列?1024 是 token 数还是特征维?PyTorch 教程写 [batch, seq, hidden],推理引擎源码写 [n_embd, n_tokens]——同一套数据,括号顺序不同,读错维度后面所有公式都会对不上。 这一篇只解决一件事:在本系列采用的约定下,张量形状怎么读、矩阵图怎么画、常见运算后维度怎么变。 搞懂它,后面矩阵乘法、Q/K/V 投影才有共同语言。 这是「大模型数学速成」系列的第 1 篇。建议先读 第 00 篇:读 Transformer 前需要哪些数学?。下一篇我们讲 矩阵乘法——神经网络的「基本变换器」。 一、什么是张量?在深度学习里,张量(tensor) 就是存放数字的多维数组。维度越高,结构越丰富,但读法有统一套路: 维度 生活类比 大模型中的例子 1D 向量 一行成绩:[语文, 数学, 英语, …] 某一个 token 的 768 维 embedding 2D 矩阵 Excel 表格 [n_embd, n_tokens] 整段序列的...
现代 C++ 实战(04):智能指针(上)——所有权与 RAII
上一篇我们搞懂了移动语义——资源可以在对象之间「搬家」。但还有一个更根本的问题:这块内存到底谁负责释放? C++ 没有垃圾回收,手动 new / delete 一旦配对出错,就是泄漏或 double-free。 现代 C++ 的答案是 RAII + 智能指针:把所有权写进类型系统,让编译器和析构函数帮你收尾。这一篇聚焦 unique_ptr 与 shared_ptr 的上半场——独占 vs 共享、什么时候该用谁、以及 make_unique / make_shared 为什么更推荐。 这是「现代 C++ 实战」系列的第 4 篇。对应 demo:ref/cpp_demo/smart_pointers/ 第 01–04 节。建议先读 第 03 篇:移动语义与右值引用。 一、RAII:资源获取即初始化RAII(Resource Acquisition Is Initialization) 是 C++ 资源管理的核心惯用法: 阶段 做什么 构造 获取资源(内存、文件句柄、锁……) 使用 通过对象访问资源 析构 自动释放资源——无论正常返回还...
x86 汇编入门(03):算术运算与数字转字符串
终端只能显示字符,不能直接显示数字 42。所以汇编里做算术只是第一步,更麻烦的是把结果「翻译」成 '4' 和 '2' 再送出去。这一篇我们练四则运算,并实现一个可复用的 print_number 子程序。 这是「x86 汇编入门」系列的第 3 篇。前两篇解决了输出字符串和读取输入。这一篇通过 03_calc.asm,掌握算术指令和整数转 ASCII 的核心技巧。 一、基本算术指令对两个常数 42 和 8 演示四则运算: 指令 含义 示例结果 add dst, src 加法 42 + 8 = 50 sub dst, src 减法 42 - 8 = 34 imul dst, src 有符号乘法 42 × 8 = 336 idiv src 有符号除法 42 ÷ 8 = 5 … 2 除法要特别注意:idiv 用 rdx:rax 作为被除数。执行前需要 cqo 把 rax 符号扩展到 rdx: 1234mov rax, num_acqo ...
大模型数学速成(00):读 Transformer 前需要哪些数学?
你可能已经读过「Attention Is All You Need」的科普版,知道 Transformer 靠「注意力」连接 token;也可能看过 LLM 是「预测下一个词」的接龙游戏。但一旦打开技术文章或论文,公式里突然出现 $QK^\top$、LayerNorm、RoPE、KV Cache——矩阵维度对不上、符号各说各话,读几段就想关掉页面。 这一篇不讲任何具体公式,只回答一件事:接下来 11 篇数学速成,各自解决什么困惑、该怎么读。 把它当成进入 Transformer 计算世界的地图。 这是「大模型数学速成」系列的第 0 篇。本系列与「现代 C++ 实战」并行日更:同一天还会有一篇 C++ 文章,两线互不干扰。下一篇我们从最基础的约定说起——张量、维度,以及为什么「列 = token」。 一、为什么需要这个系列?「小白讲 AI」系列刻意零公式:用图书馆、接龙、投票来类比 Transformer 和 LLM,降低入门门槛。那套讲法足够建立直觉,但不足以回答下面这类问题: 困惑 典型场景 $Q \cdot K^\top$ 到底在算什么? 读论文...















