RustInPractice(03):String、切片与 UTF-8
Rust 不支持 text[0] 这种字符串下标,不是少了功能,而是拒绝把“第 0 个元素”伪装成一个没有歧义的操作。UTF-8 的一个字符可能占多个字节,字符、人眼看到的字形、字节索引也未必是一回事。 这是 RustInPractice 的第 03 篇。regex_demo 使用了字符串切片和原始字符串。下一篇进入数组、Vec、元组与迭代器。 一、String 和 &str 的边界 类型 含义 常见来源 String 拥有文本,可增长、可修改 文件、网络、拼接、String::from &str 借用的 UTF-8 文本切片 字符串字面量、String 的只读视图 12345let mut name = String::from("Rust");name.push_str(" language");let first_word: &str = &name[..4];println!("{first_word}"); 函数如果只需要读取文本,...
RustInPractice(02):Struct、枚举与模式匹配
很多程序把“状态”藏在整数、空指针或几个布尔字段中。Rust 更倾向于让状态直接出现在类型里:用 struct 聚合固定字段,用 enum 表达“若干种不同形状的可能性”,再用 match 强制处理所有分支。 这是 RustInPractice 的第 02 篇。对应 demo:enum_demo 与 oop_demo。下一篇解释 String、&str、切片和 UTF-8。 一、struct:数据与行为分开声明1234567891011121314struct Server { host: String, port: u16,}impl Server { fn new(host: String, port: u16) -> Self { Self { host, port } } fn address(&self) -> String { format!("{}:{...
RustInPractice(01):变量、类型、函数与控制流
Rust 初看有不少符号:let、mut、->、末尾分号。真正值得先建立的直觉只有一句:Rust 用不可变绑定做默认值,并把很多控制结构设计成会产生值的表达式。 这是 RustInPractice 的第 01 篇。上一篇完成 Cargo 环境;本篇的示例可以直接放进任意 main.rs 运行。下一篇进入 struct、enum 和模式匹配。 一、绑定默认不可变let 创建的是一个绑定。默认不能通过该绑定修改值: 12345let retries = 3;// retries += 1; // 编译错误let mut remaining = 3;remaining -= 1; 这不是说数据永远不能变,而是要求修改意图写在 mut 上。读到函数时,读者能先判断哪些局部状态会变化。 Rust 也允许 shadowing:同名新绑定遮住旧绑定。 12let input = "42";let input: u32 = input.parse().expect("literal is a valid integer"); 这里前一个 ...
RustInPractice(00):环境搭建、Cargo 与 Demo 工作区
学 Rust 的第一道门槛通常不是所有权,而是「这段代码到底该怎么编译、依赖放哪里、为什么一个仓库里能有这么多程序」。本篇先不讲语法,只完成三件事:装好工具链、认识 Cargo、跑通本系列的 demo 工作区。 这是 RustInPractice 的第 00 篇。系列主线共 28 篇,按基础、所有权、工程并发、应用算法四季推进;另有 5 篇终端 UI 番外。下一篇从变量、类型、函数和控制流开始。 一、Rust 工具链由什么组成?Rust 的官方安装器是 rustup。它负责安装和切换编译器;日常真正高频使用的是 Cargo。 工具 职责 rustc Rust 编译器,负责把源代码编译为可执行文件或库 cargo 包管理、构建、测试、运行与文档工具 rustfmt 统一代码格式 clippy 静态检查器,专门提示常见 Rust 误用和可改进写法 rust-analyzer 编辑器语言服务,提供补全、跳转和诊断 安装完成后先确认版本: 12rustc --versioncargo --version 本系列 demo 使用 Rust 2021...
大模型数学速成(19):DPO 与 RLHF 目标函数速览
第 12 篇 的交叉熵让模型学会「接龙」;但高似然 ≠ 有用、无害、听话。AI 安全与对齐 从产品侧讲过故事,本篇补 目标函数长什么样——RLHF 与 DPO 的速览版。 这是「大模型数学速成」续篇的收官篇。 续篇第 19 篇(收官)。建议先读第 12 篇 CE,并可选读对齐科普。 一、为什么 CE 不够?预训练 / SFT 的主损失仍是 next-token 交叉熵: \[\mathcal{L}_{\mathrm{CE}} = -\log \pi_\theta(y^\star \mid x)\] 问题在于:许多 不该鼓励 的回答(有害、谄媚胡说、泄露)在语料里仍可能有不低的似然;许多 该鼓励 的回答(拒答、澄清、谨慎)未必是最大似然路径。 对齐阶段换问题: 给定同一提示 $x$,人(或 AI)更偏好回答 $y_w$ 还是 $y_l$?如何把「偏好」写进可优化的损失? 二、RLHF 三步鸟瞰RLHF(Reinforcement Learning from Human Feedback) 经典流水线: 阶段 在做什么 1. SFT 指令数据上继续 ...
大模型数学速成(18):MoE——稀疏 FFN 与路由
第 06 篇 的 FFN 对每个 token 做同一套「升维 → 非线性 → 降维」。模型想更大时,若继续把 FFN 做厚,参数量和每 token 算力一起涨。MoE(Mixture of Experts,混合专家) 换思路:总参数可以很多,但每个 token 只激活少数专家。 这是「大模型数学速成」续篇第 18 篇。建议先读第 06 篇 FFN。下一篇(收官)讲 DPO / RLHF 目标函数。 一、稠密 FFN 的成本标准 Transformer 块里,FFN 往往占参数大头。稠密(dense)含义是: 每个 token 都完整跑同一套 FFN 权重。 于是: 放大方式 参数 每 token FLOPs 加宽 / 加深稠密 FFN ↑ ↑(同步) MoE 稀疏 FFN ↑(多专家) 主要随 激活的专家数 涨 MoE 追求的是:参数规模与单次前向算力部分解耦。 二、专家与门控把原来的一个 FFN 换成 $N$ 个结构相同的 专家 $E_1,\ldots,E_N$,再加一个 路由器(router / gate)。 对 ...
大模型数学速成(17):Flash Attention——不物化注意力矩阵
第 05 篇 的公式是 (\mathrm{softmax}(QK^\top/\sqrt{d}),V)。第 11 篇 又看到长序列下 (T\times T) 的代价。Flash Attention 不改这个数学定义,却尽量不把整张分数矩阵 $S$ 写进高带宽显存——用分块在更快的片上存储里完成 Softmax 归约。 本篇只建立 IO 与分块直觉,不写 CUDA kernel。 这是「大模型数学速成」续篇第 17 篇。建议先读第 05、11 篇。下一篇讲 MoE。 一、标准 Attention 的痛点单头、序列长 $T$、头维 $d$: \[S = \frac{QK^\top}{\sqrt{d}} \in \mathbb{R}^{T\times T}, \quad P = \mathrm{softmax}(S),\quad O = PV\] 对象 规模 问题 $S$ 或 $P$ $O(T^2)$ 显存随长度平方涨 读写 $S$ 多次经过 HBM(大而慢的显存) 带宽墙,往往比算力先爆 长上下文时,很多实现的瓶颈不是「乘加次数」,而是 反复搬运那...
大模型数学速成(16):LoRA——低秩适配在算什么
全参数微调要更新整网权重,贵且易伤通用能力。AI 系列的 Fine-tuning vs RAG 从产品视角对比过两条路;本篇补 LoRA(Low-Rank Adaptation)在算什么——冻住巨大的 $W$,只训练两个瘦矩阵 $A,B$。 这是「大模型数学速成」续篇第 16 篇。建议先读 第 02 篇矩阵乘 与 第 15 篇量化。下一篇讲 Flash Attention。 一、全参微调为什么贵?一层线性变换(第 02 篇): \[\mathbf{h}' = W \mathbf{x}\] 若 $W \in \mathbb{R}^{d \times d}$(示意方阵),可训练参数量是 $d^2$。$d=4096$ 时单层已约 $1.7\times 10^7$ 个参数;模型有几十上百层、还有多组投影——微调 = 存优化器状态 + 梯度 + 可能的全精度副本,显存与存储都爆炸。 更麻烦的是:在小领域数据上拧全体权重,容易 灾难性遗忘——通用能力掉点。 二、低秩假设:更新往往「很扁」微调时我们真正需要的,常常不是一张全新的满秩 $W$,而是一个增量: \[W' = W_...
大模型数学速成(15):量化——从 FP16 到 INT4 的尺度
第 10 篇 GQA 和 第 11 篇 KV Cache 从结构上省显存;推理时还有一条更「硬」的路——用更少比特存同一个数。这就是 量化(Quantization)。 本篇只讲数学直觉:实数如何落在整数网格上、scale / zero-point 是什么、粒度与误差从哪来。不写安装教程,公开格式名(如 GGUF)仅作索引。 这是「大模型数学速成」续篇第 15 篇。建议先读第 10–11 篇(显存动机)与 第 02 篇矩阵乘。下一篇讲 LoRA。 一、为什么要量化?大模型的权重与激活本质上是大量浮点数。推理时瓶颈经常是: 压力 含义 显存 / 内存容量 装不下整模,或 Concurrent 请求装不下 KV 带宽 算力够,但读权重/读 Cache 太慢(「算得动、搬不动」) 若把 FP16(2 字节)换成 INT4(0.5 字节),同样参数量体积约变为 1/4——在误差可接受时,这是极高杠杆。 本篇范围:以权重量化为主,兼提 KV Cache 量化;训练中的量化感知训练(QAT)只点名、不展开。 二、均匀量化:尺...
大模型数学速成(14):采样——Temperature、top-k 与 top-p
第 12 篇 给出词表上的 logits;第 13 篇 保证每一步只基于合法前缀。推理的最后一跳是:从概率分布里选出下一个 token——永远 $\arg\max$ 会又稳又无聊,完全乱抽又会胡言乱语。 本篇讲清三条最常用旋钮:Temperature、top-k、top-p(nucleus),并用 4 词小例子手算对照。 这是「大模型数学速成」续篇第 14 篇。建议先读第 12、13 篇。下一篇讲 量化(FP16 → INT4)。 一、贪心 vs 采样设 Softmax 后概率为 $\mathbf{p}$(第 05、第 12 篇)。 策略 做法 典型观感 贪心(greedy) $i^\star = \arg\max_i p_i$ 稳、重复、模板腔 纯采样 按 $\mathbf{p}$ 多项式抽样 多样,但易抽到长尾怪词 截断 + 温度后再采 本篇重点 生产里最常见 解码循环(接第 13 篇 Decode)每步都是: \[\text{logits } \mathbf{z} \;\xrightarrow{\text{改分布}}\; \mathbf{p}...















