1. JVM GC 工作思路
📝 术语别名
GC: Garbage Collection, 自动垃圾回收;
STW: Stop-The-World, GC 期间所有应用线程被 JVM 冻住;
Heap: JVM 管理的对象内存区, 所有 new 出来的东西都在这里;
GC Roots: 一组"一定还活着"的引用起点, 可达性分析的种子;
前置: 为什么 Java 需要 GC
C/C++ 程序员是手动管内存的, 你 malloc 一块就要负责 free 一块, 漏了就内存泄漏, 重复 free 就 double-free crash; Java 把这个负担拿走了, 程序员只负责 new Foo(), 永远不主动释放;
那对象怎么消失? 答案是 JVM 启动了一个叫 GC 的后台机制, 周期性扫整个 heap, 把"再也不会被用到的对象"自动清掉, 这一行为的代价是: 扫的时候得短暂冻住应用线程 (STW), 这就是 GC 给你带来的延迟代价;
所以理解 GC 本质上要回答两个问题:
怎么判断一个对象"已经死了";
判断完之 ...
6. Unix ping 与 ICMP 协议
📝 术语别名
ICMP: Internet Control Message Protocol, IP 层的"控制/反馈"协议;
RTT: Round-Trip Time, 一来一回的总时延;
Echo Request / Echo Reply: ICMP type 8 / type 0, 就是 ping 用到的两种报文;
前置: ICMP 在协议栈中的位置
ICMP 经常被人当成"网络层之上的小协议", 但它实际上是 IP 协议的一个直接附庸, 跑在 IP 之上, 但属于 network layer 的控制平面;
IP 包的 header 里 Protocol 字段为 1 时, 上层就是 ICMP (对比 TCP=6, UDP=17);
ICMP 报文不走传输层, 没有端口号; 它的"复用"由 ICMP type + code 这两个字节自己完成;
ICMP 的存在意义是给 IP 这个 best-effort 协议一个反馈信道, 比如告诉 src “你这个包 TTL 跑光了”, “目标不可达 ...
Crawl-Me-Maybe Search Engine Tech Report
Crawl Me Maybe: Towards High Efficiency and Accuracy Information Retrieval
5. Docker 网络栈协议
📝 术语别名
NIC: Network Interface Card, 物理网卡, 真正的硬件;
net_device: Linux 内核里描述"一张网卡"的统一抽象, 虚拟和物理共用同一个数据结构;
虚拟网卡: 没有对应物理硬件、纯软件模拟的 net_device, 例如 lo / veth / tap / tun / bridge;
tap / tun: 给用户态进程收发包用的虚拟网卡, VM 和 VPN 的标配;
netns: Linux network namespace, 内核提供的网络栈隔离机制;
veth pair: virtual ethernet pair, 一对虚拟网卡, 一端发, 另一端收, 是连接两个 netns 的通道;
bridge: 内核虚拟二层交换机, 把若干网卡拉到同一广播域;
DNAT / SNAT: destination / source NAT, iptables 用来改包的 dst/src IP, 是端口映射和"出口走主机 IP"的核心;
前置 A: 物理网卡 (NIC ...
MemGPT - Towards LLMs as Operating Systems
[!MemGPT 的 OS 类比词典]
main context: LLM 的 context window, 类比物理 RAM
external context: 向量库 / 关系库 / 日志, 类比 disk
function call: 模型主动触发的 I/O, 类比 system call
queue manager: FIFO 驱逐器, 类比 page replacement policy
heartbeat: 定时唤醒, 类比 timer interrupt
Context Window 的硬上限
现有商用 LLM 每次 forward 能看到的 token 数是有限的, 比如 GPT-4 turbo 是 128K, Llama-2-chat 是 4K; 一旦 input + output 超出这个窗口, 后续内容要么被截断, 要么只能靠外部检索 (classic RAG) 在推理前硬塞进去;
这带来两个根本问题:
长对话: session 时间够长后, 早期轮次会被挤出窗口, 模型彻底"忘"掉用户之前说过的事实
长文档分析: 单份文档已经接近 ...
kubernetes
Load Balance
ZeRO - memory optimizations toward training trillion parameter models
📝 并行理论的黑称
Vertical Split: 竖切, PP
Horizontal Split: 横切, TP
消耗显存的模块分类
Part
Category
Included Items
Description
1
Model states
optimizer states, gradients, parameters
For large models, the majority of the memory is occupied by model states.
2
Residual states
activation, temporary buffers, unusable fragmented memory
The remaining memory is consumed by residual states.
Model State 不足分析 + ZeRO-DP 性能
Parallelism Method
Why Compute Efficiency Is High / Low
Why Memory Effi ...
Megatron-LM - Training Multi-Billion Parameter Language Models Using Model Parallelism
Attention 计算的线性代数问题
attention 和 FFN 的关系
如果记某层输入为 x, 那么可以粗略理解成:
attention 输出: 给 x 补充上下文信息, 像"开会听别人说话"
FFN 输出: 给 x 补充局部计算后的新特征, - 像"你自己在脑子里消化, 归纳, 形成判断"
如果我们尝试把一个 FFN 层变成一个 attention 层, 结果就是可能会更加适合长距离语义传输但是缺少本地语义特征变换器
多层 attention-FFN 结构
可以理解为不断重复"交换信息 →\rightarrow→ 消化信息 →\rightarrow→ 再交换 →\rightarrow→ 再消化"
也就是说各自对本 token 处于上下文的含义理解之后再次进行交换分享,让整体的文意理解更加深刻
Transformer 架构的训练计算
假设训练句子是:The capital of France is Paris.
训练时,decoder-only 模型会把它转成一种“前缀预测后一个 token”的形式, 比如模型看到 ...
Taming Throughput-Latency Tradeoff in LLM Inference with Sarathi-Serve
Prefill vs. Decode
Prefill 阶段做了什么
prefill = 对整个 prompt 做一次完整的 transformer forward。
包括了:
对所有输入 token 一起做 embedding
过每一层的 attention
过每一层的 FFN
同时把每层对应的 K/V 写入 KV cache
最后根据最后位置的 hidden state 过 lm head,得到 next-token logits
采样 / greedy / top-k / top-p,选出第一个输出 token
这个过程由于是有了所有的输入参数的计算,所以其可以在输入启动阶段就做所有启动处理,结果是 compute-bound.
Decode 阶段做了什么
对每一个新的 token (这里来看类似于一个单词的 向量表示), 来计算他们预测的下一个单词输出,这里应该会经过多个阶段,分别是
linear 阶段,也就是从 token X 处理得到 Q, K, V
attention 阶段,也就是通过 QKV, softmax 等计算得到 attention 得分
FFN 阶段,也就 ...
GPipe - efficient training of giant neural networks using pipeline parallelism
神经网络基础
如图是一个基础的神经网络结构, 我们这里首先要明确几个函数:
每一层内部的计算是 hi:=σ(zi)h_i := \sigma(z_i)hi:=σ(zi), zi:=Wihi−1+biz_i := W_i h_{i-1} + b_izi:=Wihi−1+bi
我们最终的输出函数是 L:=L :=L:=loss(sample; forward)
forward: 指的是从输入样本数据 h0h_0h0 到 最终输出 σ(z2)\sigma(z_2)σ(z2) 的所有计算过程
backward: 从 LLL 开始不断计算每一层中的 ∂L∂Wi\frac{\partial L}{\partial W_i}∂Wi∂L 和 ∂L∂bi\frac{\partial L}{\partial b_i}∂bi∂L 的方向梯度, 然后用这个来不断更新 Wi, biW_i,\ b_iWi, bi
现在来拆解一下反向传播的过程: 基本根据的是莱布尼茨链式法则 (chain-rule)
∂L∂W2=∂L∂z2∂z2∂W2=∂L∂z2h1T\frac{\partia ...
