Arganzheng's Blog

stay hungry, stay foolish

通信与互联(03):RDMA 与 GPUDirect——绕过 CPU 和主机内存的数据通路

RDMA and GPUDirect: Bypassing the CPU and Host Memory

上一篇给出了节点间链路的物理上限:一张 NDR InfiniBand 网卡 400 Gb/s,约 50 GB/s 单向;一张 HDR 200 Gb/s,约 25 GB/s。也给出了它挂在哪里:每张 GPU 配一张网卡,两者在同一个 PCIe switch 下(nvidia-smi topo -m 里的 PIX 或 PXB),走 PCIe 4.0 x16(单向约 32 GB/s)或 PCIe 5.0 x16(单向约 64 GB/s)。这些数字是链路的能力,不是软件能拿到的带宽。软件拿到多少,取决于数据从显存到网线之间经过了什么。 TCP/IP 的路径上有内核协议栈、至少两次内存拷贝和一个必须参与每个包收发的 CPU。这条路径在 10 Gb/s 时代设计得很合理,到 ...

通信与互联(02):硬件互联——PCIe、NVLink、NVSwitch 与网络拓扑

Hardware Interconnect: PCIe, NVLink, NVSwitch and Network Topology

上一篇把一次通信的时间写成 \(T = \alpha + S/\beta\):α 是固定开销,β 是带宽,S 是字节数;ring all_reduce 在 n 个参与者上的时间是 \(T_{\text{ring}} = 2(n-1)\,\alpha + \frac{2(n-1)}{n}\cdot\frac{S}{\beta}\)。这个模型能算出”8 卡 1 GB 的 all_reduce 在 25 GB/s 的链路上大约 70 ms”,但它有两个空位:α 和 β 是多少,取决于数据走的是哪条链路。同一台机器上,两张 GPU 之间的 β 可能是 450 GB/s,也可能是 25 GB/s,也可能只有 10 GB/s,差 40 倍;α 可能是 2 微秒,也可能是 20 ...

通信与互联(01):集合通信原语与代价模型——α-β 模型与 ring all-reduce

Collective Communication Primitives and the Alpha-Beta Cost Model: Deriving Ring All-Reduce

总纲把这个系列要回答的问题定为一句话:一次 all_reduce 从调用到完成,数据在 PCIe、NVLink、InfiniBand 上是怎么流动的,为什么有时候是带宽的问题、有时候是延迟的问题。要回答它,先得有一把尺子。没有尺子,nccl-tests 打出来的 busbw 23.1 GB/s 只是一个数字,profiler 里 ncclDevKernel_AllReduce 的 145 µs 也只是一个数字,你不知道它们是好是坏、离上限多远、差的那部分该去哪一层找。 这一篇造这把尺子。它不碰任何硬件、不读 NCCL 的源码,只做三件事:把集合通信的原语定义清楚,把描述一条链路的 α-β 模型建立起来,再把 ring 和 tree 两个最基本的 all_reduc...

通信与互联:从 NCCL 到 RDMA(总纲)

Communication and Interconnect for AI-Infra, from NCCL to RDMA

内容简介 《通信与互联:从 NCCL 到 RDMA》是一组共八篇的系列文章,面向已经跑过多卡训练或多卡推理、准备向下进入通信层的工程师,系统讲解 GPU 之间的数据是怎么流动的:经过哪些硬件链路、由哪些软件层驱动、每一层的代价是什么、出问题时到哪里去看。 它回答的问题是: 一次 all_reduce 从调用到完成,数据在 PCIe、NVLink、InfiniBand 上是怎么流动的?为什么有时候是带宽的问题,有时候是延迟的问题?1 站在框架的层面看,通信是一行代码:dist.all_reduce(t)。它返回得很快,然后在某个时刻”完成”。Profiler 里它是一段 ncclDevKernel_AllReduce_* 的时间条;nccl-tests...

LoRA 专题(04):系列总结与通关自测

LoRA Series: Recap and Final Self-Test

三篇正文回答了一个问题:为什么给一个几十亿参数的模型加两个瘦矩阵就能把它微调好,每个旋钮该取多少,训完的东西怎么上线。第一篇讲低秩假设、\(W + \frac{\alpha}{r}BA\) 的梯度与四本账,并直接检验全量微调的 \(\Delta W\) 有多低秩;第二篇把十三种配置在同一份数据上各训 80 步,每个旋钮给一组数字;第三篇从 adapter 文件走到 multi-LoRA 服务。本文把三篇压成一张速查表,拎出贯穿三篇的四条线,列常见误区,再给一套自测。 一、总览 为什么 怎么配 怎么上线 ┌──...

LoRA 专题(03):工程:adapter 文件、合并、多 LoRA 服务与参考模型

LoRA 03: In Production — Adapter Files, Merging, Multi-LoRA Serving and the Free Reference Model

更新 @2026-09-30:实验用 peft 0.21.1、transformers 5.17.0、bitsandbytes 0.50.2、PyTorch 2.14(CPU),模型 Qwen2.5-0.5B,adapter 是第二篇训出的 r16_all(\(r = 16\) 全部线性层)与 r16_attn(\(r = 16\) 只挂 attention)。配套脚本 ai-learning-labs/lora/03_deploy.py(子实验 files / merge / quant / multi / tokens)。 前两篇回答了”为什么”与”怎么配”,训出来的东西是一个目录:adapter_config.json 加一个几十 MB 的 adap...

LoRA 专题(02):选参:r、target_modules、alpha、lr 与 QLoRA / DoRA / PiSSA 各让模型变成什么

LoRA 02: Choosing r, target_modules, alpha and lr — and What QLoRA, DoRA and PiSSA Each Change

更新 @2026-09-30:实验用 peft 0.21.1、trl 1.14.1、transformers 5.17.0、bitsandbytes 0.50.2、PyTorch 2.14(CPU,8 线程),模型 Qwen2.5-0.5B(base),数据 HuggingFaceH4/no_robots。配套脚本 ai-learning-labs/lora/02_knobs.py,--list 列出全部配置名;正文给出每种配置的数字。 LoraConfig(r=16, lora_alpha=32, target_modules="all-linear", lora_dropout=0.05) 加 learning_rate=2e-4——这一行出现在几乎每...

LoRA 专题(01):低秩假设:为什么两个瘦矩阵够用,以及它省了哪几本账

LoRA 01: The Low-Rank Hypothesis — Why Two Thin Matrices Suffice, and Exactly What They Save

更新 @2026-09-30:实验用 peft 0.21.1、trl 1.14.1、transformers 5.17.0、PyTorch 2.14(CPU,8 线程),模型 Qwen2.5-0.5B(base),数据 no_robots。配套脚本 ai-learning-labs/lora/01_low_rank.py(子实验 hand / account / speed / init / spectrum);正文给出理解所需的全部数字。 LoRA 的全部内容是一句话:冻结 \(W\),只训一对瘦矩阵 \(B\)、\(A\),让 \(W' = W + \frac{\alpha}{r} BA\)。这一句里有三个不显然的地方:为什么改动可以只有秩 \(r\)...

LoRA 专题:SFT 的默认微调方式,从低秩假设到多租户服务(总纲)

LoRA, the Default Way to Fine-Tune: From the Low-Rank Hypothesis to Multi-Tenant Serving — Series Overview

更新 @2026-09-30:本系列的实验用 peft 0.21.1、trl 1.14.1、transformers 5.17.0、bitsandbytes 0.50.2、PyTorch 2.14(CPU),模型是本地缓存的 Qwen2.5-0.5B,数据是 HuggingFaceH4/no_robots。文中的参数名(r、lora_alpha、target_modules、use_rslora、init_lora_weights……)以这组版本为准;LoRA 的数学与账目不随版本变。 内容简介 《LoRA 专题》是一组共三篇正文加一篇总结的系列文章,是《AI 算法工程师学习地图》 L5 后训练层的专题篇。LoRA(Low-Rank Adaptation...

读 Hugging Face 源码(05):系列总结与通关自测

Reading the Hugging Face Source: Series Recap and Final Self-Test

四篇正文回答了一个问题:工具箱第五篇那六行代码,执行时各经过哪些文件的哪些函数。第一篇读模型的加载与一次前向,第二篇读 generate 的循环,第三篇读文本与数据两条流水线,第四篇读 LoRA 怎么挂上去与三种 loss 各在哪一行。本文把四篇压成一张「问题 → 文件 → 函数」的索引表,拎出贯穿五个库的四条设计线,再给一套自测。 读完这四篇,你应该能回答哪些问题?1 哪些文件名、函数名与数字必须能脱口而出?2 怎么判断自己是”读过”还是”掌握”了?3 先把整个系列放在一张图上——箭头是调用或数据上的依赖,不是阅读顺序: %%{init: {"flowchart": {"wrappingWidth": 230}}}%% %% 图:四篇的依赖:03 造...

×