地图 《AI 算法工程师学习地图》 第 9 / 12 个系列
- 算法工程师的数学
- 算法工程师的工具箱
- LLM 时代的经典机器学习
- 深度学习基础
- Transformer 原理与实现
- 现代 LLM 结构
- 预训练
- 后训练
- 读 Hugging Face 源码
- LoRA 专题
- 高效推理与压缩(算法侧)
- 多模态
更新 @2026-09-30:本系列对着 transformers 5.17.0(2026-09-09 发布)、tokenizers 0.23.2、datasets 5.0.1、peft 0.21.0、trl 1.13.0 的源码读,模型用本地缓存的 Qwen2.5-0.5B。文中的文件路径、类名、函数名以这组版本为准,不引用行号;读别的版本请以本地源码对照——找入口的方法不变。
内容简介
《读 Hugging Face 源码》是一组共四篇的系列文章,是《AI 算法工程师学习地图》 L4–L5 两层的深入篇。工具箱第五篇用六行代码组装了一次 LoRA SFT,并在末尾列了六个读源码的入口。本系列沿这六个入口,把源码读一遍。
它回答的问题是:
AutoModelForCausalLM.from_pretrained、model.generate、tok.apply_chat_template、load_dataset(...).map、get_peft_model、SFTTrainer/DPOTrainer/GRPOTrainer——工具箱第五篇那六行代码的每一行,执行时经过了哪些文件的哪些函数?L0 的公式与 L4 / L5 的结构图,各对应源码里的哪几行?[^q0]
Hugging Face 的五个库加起来几十万行,本系列不通读,只沿一次 LoRA SFT 会走到的调用链读:模型怎么加载、一次前向怎么走到 loss、generate 的循环长什么样、文本怎么变成 input_ids、数据怎么从 Arrow 文件到一个 batch、LoRA 怎么挂到 nn.Linear 上、SFT 的 -100 在哪一步填、DPO 与 GRPO 的公式各是哪十几行。每一篇的写法相同:先用一张调用链图给出骨架,再逐段贴源码——只贴那一段真正在做事的几行,其余用文件名 + 函数名指路——最后把它与本地图前面各层的公式或结构图对上。
举一个例子说明这个系列的取法。「LoRA 是给权重加一个低秩增量 \(BA\)」是 《算法工程师的数学(03):正交与旋转、特征值与 SVD——从 RoPE 到 LoRA》的数学;到了源码里它是三件可查验的事:
inject_adapter用named_modules逐个匹配target_modules,命中的nn.Linear被setattr换成lora.Linear,all-linear会排除lm_head;update_layer建lora_A(kaiming)与lora_B(全零),scaling = α/r——所以训练开始时增量恰好为零;forward只多一行result + lora_B(lora_A(dropout(x))) * scaling,先算瘦的那一半,永远不物化 \(BA\)。
Qwen2.5-0.5B 上 r=16 挂七类线性层,可训练参数 8.8M(1.8%),state_dict 里只有 adapter。
系列覆盖的范围是那六行代码的四段,每段一篇:
| 段 | 主题 | 读的源码 | 篇 |
|---|---|---|---|
| 第一段 | 模型 |
|
第一篇 |
| 第二段 | 生成 |
|
第二篇 |
| 第三段 | 数据 |
|
第三篇 |
| 第四段 | 微调与后训练 |
|
第四篇 |
缩写
本系列的 85 个缩写(展开)
| 缩写 | 全称 | 一句话解释 |
|---|---|---|
| accelerate | — | HF 的设备分配与分布式训练库 |
| actor | — | RL 里被训练、负责生成回答的策略模型 |
| AdaLoRA | Adaptive LoRA | 按重要性给各层自适应分配秩的 LoRA 变体 |
| Adam | adaptive moment estimation | 按梯度一阶、二阶矩自适应步长的优化器 |
| AdamW | Adam with decoupled weight decay | 带解耦权重衰减的 Adam 优化器,每个参数存两份矩 |
| adapter | — | 挂在冻结基座上的一小组可训参数,这里就是 LoRA 的 A、B |
| assistant mask | — | 0/1 列表,标出哪些 token 属于 assistant 回合 |
| beam search | — | 每步保留得分最高的若干条前缀 |
| bf16 | bfloat16 | 16 位浮点,指数位与 fp32 一样、尾数只有 8 位 |
| bitsandbytes | — | 做 4 / 8 bit 量化的库,Linear4bit 来自它 |
| BPE | byte-pair encoding | 字节对编码:反复合并最常见的相邻 pair 得到词表 |
| ByteLevel | — | 把每个字节映射成一个可见字符的预分词 / 解码方式 |
| cDPO | conservative DPO | 给 DPO 加标签平滑,对标注噪声更鲁棒 |
| chunked prefill | — | 把长 prompt 切块依次前向,降低显存峰值 |
| clip-higher | — | DAPO 的做法:裁剪上界 ε_high 设得比下界大 |
| continuous batching | — | 一条序列结束就把位置让给新请求的动态调度 |
| CTRL | Conditional Transformer Language Model | Salesforce 的可控生成模型,重复惩罚出自其论文 |
| CUDA graph | — | 把一串 kernel 录成图一次提交,省 CPU 发射开销 |
| DAPO | Decoupled Clip and Dynamic sAmpling Policy Optimization | GRPO 的改进:clip-higher、过滤全对 / 全错组等 |
| DDP | Distributed Data Parallel | 数据并行:每卡一份完整模型,梯度做 all-reduce |
| decode | — | prefill 之后每步只喂一个新 token 的生成阶段 |
| DoLa | Decoding by Contrasting Layers | 用深层与浅层 logits 之差来解码 |
| DoRA | Weight-Decomposed Low-Rank Adaptation | 把权重拆成幅度和方向,方向用 LoRA 更新 |
| DPO | Direct Preference Optimization | 直接用好 / 差回答对训模型,不单独训奖励模型 |
| Dr. GRPO | GRPO Done Right | 去掉按长度、按组标准差归一的 GRPO 修正版 |
| dynamic sampling | — | DAPO 的做法:丢掉全对 / 全错的组再补采 |
| eos | end of sequence | 序列结束 token,生成到它就停 |
| FFN | feed-forward network | 前馈网络,block 里 attention 之后那个子层 |
| FlashAttention | — | 分块计算、不物化 T×T 矩阵的 attention kernel |
| fp32 | 32-bit floating point | 单精度浮点 |
| FSDP | Fully Sharded Data Parallel | 把参数、梯度、优化器状态切到各卡的数据并行 |
| GQA | grouped-query attention | 多个 q 头共用一组 k、v 头,KV cache 更小 |
| GRPO | Group Relative Policy Optimization | 同一 prompt 采一组回答,组内归一化奖励当优势 |
| GSPO | Group Sequence Policy Optimization | 重要性比按整条序列算,而不是按 token |
| hinge | — | DPO 的变体,用 relu(1 − βΔ) 代替 logsigmoid |
| IA3 | Infused Adapter by Inhibiting and Amplifying Inner Activations | 只学几个逐元素缩放激活的向量 |
| Jinja | — | Python 模板引擎,chat template 用它写 |
| k3 | — | Schulman 给的一种 KL 估计式,非负、方差小 |
| kaiming | — | Kaiming(He)初始化:按输入维度缩放的随机初始化 |
| KL | Kullback–Leibler divergence | KL 散度,衡量两个分布差多远 |
| Liger | — | LinkedIn 的融合 kernel 库,省 logits 显存 |
| logits | — | softmax 之前、每个词表位置一个的未归一化分数 |
| LoRA | Low-Rank Adaptation | 给权重加一个低秩增量 BA,只训 A、B 两个小矩阵 |
| meta device | — | 只记形状和 dtype、不分配存储的虚拟设备 |
| meta 设备 | — | 只记形状和 dtype、不分配存储的虚拟设备 |
| micro-batch | — | 梯度累积里每次前向的那一小份 batch |
| min-p | — | 去掉概率低于「最大概率 × p」的 token |
| MLP | multi-layer perceptron | 多层感知机,这里指每层 attention 之后的前馈子层 |
| mmap | memory map | 把文件映射进内存,读到哪页才从磁盘加载哪页 |
| n-gram | — | 连续 n 个 token 的片段 |
| nanoGPT | — | Karpathy 写的极简 GPT 训练代码 |
| NER | named entity recognition | 命名实体识别:标出人名、地名这类片段 |
| NFC | Normalization Form C | Unicode 规范化形式:组合字符合成一个码位 |
| OOV | out of vocabulary | 词表外:输入里有词表表示不了的部分 |
| packing | — | 把多条短样本拼进一条序列,省掉 padding |
| PagedAttention | — | vLLM 按固定大小块管理 KV cache 的 attention |
| parquet | — | Apache Parquet 列式存储文件,Hub 上的数据集常用 |
| peft | Parameter-Efficient Fine-Tuning | HF 的参数高效微调库,LoRA 就在这里 |
| PiSSA | Principal Singular values and Singular vectors Adaptation | 用 W 的前 r 个奇异向量初始化 A、B |
| PPO | Proximal Policy Optimization | 把新旧策略的概率比裁剪在 1±ε 内的策略梯度算法 |
| pre-norm | — | 先归一化再进子层、残差绕过归一化的写法 |
| prefill | — | 生成前把整段 prompt 一次前向、填满 KV cache |
| prompt tuning | — | 只训一段拼在输入前面的软提示向量 |
| QA | question answering | 问答;抽取式 QA 从原文里划出答案 |
| REINFORCE | — | 最基本的策略梯度:loss = −A·log π |
| repetition penalty | — | 降低已出现过的 token 的分数 |
| RMSNorm | Root Mean Square Layer Normalization | 只除以均方根、不减均值的归一化 |
| rollout | — | 用当前策略生成回答的阶段 |
| RoPE | rotary position embedding | 旋转位置编码:按位置把 q、k 的每对维度旋转一个角度 |
| RPO | Regularized Preference Optimization | DPO loss 再加一项 chosen 的 SFT loss |
| rsLoRA | Rank-Stabilized LoRA | scaling 用 α/√r 代替 α/r,秩大时更稳 |
| safetensors | — | HF 的权重格式:JSON 头 + 原始字节,可 mmap |
| SDPA | scaled dot-product attention | PyTorch 的融合 attention 函数,自选 kernel |
| SFT | supervised fine-tuning | 有监督微调:拿标注好的回答训模型 |
| SiLU | Sigmoid Linear Unit | 激活函数 x·sigmoid(x),又叫 Swish |
| SSE | Server-Sent Events | HTTP 上服务端单向推送的流式协议 |
| SVD | singular value decomposition | 奇异值分解 |
| SwiGLU | Swish-Gated Linear Unit | 用 SiLU 做门控的 FFN:两路相乘再降维 |
| top-k | — | 只保留分数最高的 k 个 token |
| top-p | — | nucleus 采样:只留累计概率达到 p 的那些高分 token |
| trl | Transformer Reinforcement Learning | HF 的后训练库:SFT、DPO、GRPO 的 Trainer |
| value head | — | 模型上额外加的输出标量价值的头,PPOTrainer 要用 |
| varlen | variable-length | 按每段长度切开拼接序列算 attention 的接口 |
| verl | Volcano Engine Reinforcement Learning | 字节开源的 LLM 强化学习训练框架 |
| vLLM | — | 开源的 LLM 推理引擎 |
为什么写这个系列?
六行代码,四个黑盒
工具箱第五篇的六行里,from_pretrained 进去一个 Hub 名字、出来一个 nn.Module;get_peft_model 进去一个模型、出来一个只有 1.8% 参数可训的模型;SFTTrainer(...).train() 进去一个 Dataset、出来一个训好的模型;generate 进去一段 prompt、出来一段文本。会用它们不需要知道里面是什么;但调不出、报错、结果与预期差 \(10^{-4}\) 或差 1.0 的时候,每一个问题的答案都在某个具体的文件里。
代码比论文准,比教程全
L4 讲了 RoPE 的公式、L5 推了 DPO 的 loss、L0 写了 GRPO 的 \((R - \text{mean}) / \text{std}\)。论文写的是想法,代码写的是实际做法:apply_rotary_pos_emb 用的是前后两半配对而不是相邻两维;dpo_loss 的 loss_type 列表一眼看出 IPO、hinge 各改了哪一行;GRPO 的 loss_type 决定按什么归一,正是后训练系列讨论的长度偏差在代码里的位置。这些细节教程通常不写,读源码是唯一的来源。
这几个库的骨架很稳,只是名字在变
transformers 有 518 个模型目录,但 decoder-only 语言模型几乎全是 modeling_llama.py 的变体;generate 四千行,骨架只有「配置 → 处理器 → 停止条件 → 循环」四段;trl 一年三十多个版本,SFTTrainer 的数据契约改过数次,但 -100、compute_loss 往下追的路没变。本系列教的是找入口的方法:从 Auto 类的表、从 compute_loss、从 forward 里那一行注册表调用往下追。
系列的整体主线
四篇沿着一次 LoRA SFT 的数据流走:模型先加载起来(第一篇),它的两端是整数 input_ids——出的一端是 generate(第二篇),进的一端是 tokenizer 与 datasets(第三篇)——最后把 LoRA 挂上去、把三种 loss 算出来(第四篇)。
%%{init: {"flowchart": {"wrappingWidth": 260}}}%%
%% 图:四篇沿一次 LoRA SFT 的数据流:第三篇的 tokenizers / datasets 造 input_ids 与 labels,第一篇的 transformers 模型算前向与 loss,第四篇的 peft 挂 LoRA、trl 给三种 Trainer,第二篇的 generate 是推理侧的出口
flowchart LR
D["03 tokenizers · datasets<br/>messages → input_ids / labels<br/>Arrow 文件 → collate_fn"] --> M["01 transformers 模型侧<br/>from_pretrained → nn.Module<br/>forward → logits → ForCausalLMLoss"]
M --> G["02 generate<br/>LogitsProcessor 一串<br/>_sample 的 while 循环"]
P["04 peft · trl<br/>lora.Linear 的一行<br/>SFT 的 -100 · dpo_loss · GRPO"] --> M
D --> P
贯穿四篇的几条设计线,在系列总结里单独拎出来:
- 注册表 + 字符串键:
model_type→ 模型类、_attn_implementation→ attention 函数、loss_type→ loss 函数、target_modules→ 要换的层——模型代码不改,实现随便换。 - Rust / Arrow 内核 + Python 壳:tokenizers 与 datasets 的 Python 源码里要知道哪一行之下是另一种语言。
-100一个约定串起三个库:tokenizers 的 assistant mask、trl 的build_labels、transformers 的ForCausalLMLoss。- 一个上下文省一份模型:peft 的
disable_adapter()让 DPO 与 GRPO 不用再加载参考模型。
章节结构与分章导读
1. transformers 模型侧:from_pretrained 怎么把三个文件变成 nn.Module,forward 怎么走到 loss
第一篇读 models/auto/、modeling_utils.py、models/llama/modeling_llama.py 与 loss/loss_utils.py。加载的六步:AutoConfig 读 model_type → modeling_auto.py 的表选类 → 解析 safetensors → torch.device("meta") 下建骨架 → safe_open mmap 按名字填 → tie_weights、初始化缺失键、eval()。前向:一个 DecoderLayer 的 RMSNorm、RoPE、MLP、两条残差与 《Transformer 原理与实现(01):Transformer 长什么样——从一句话到下一个 token》的公式逐行对应;attention 是 ALL_ATTENTION_FUNCTIONS[config._attn_implementation] 的一次函数指针调用;loss 不在建模文件里,按类名分派到 ForCausalLMLoss。最后读 modular_qwen2.py,看 518 个模型怎么维护。
它回答的问题:from_pretrained 加载 8B bf16 模型时峰值内存为什么约等于最终的 16 GB 而不是 32 GB?attn_implementation="sdpa" 与 "eager" 的 logits 为什么在 fp32 下差 \(10^{-4}\)、bf16 下差 1.0?labels 传进去之后,-100 与 num_items_in_batch 各在哪一行起作用?
2. generate:一次采样的完整调用链
第二篇读 generation/ 目录:utils.py、logits_process.py、stopping_criteria.py、configuration_utils.py。骨架四段:GenerationConfig 三层优先级(kwargs > 仓库的 generation_config.json > 全局默认)→ _get_logits_processor 按非空字段装配一串 LogitsProcessor(processor 在前、warper 在后,顺序由代码决定)→ 三个停止条件 → _sample 的 while 循环(prefill 与 decode 是同一个 forward,第一次 logits_to_keep=1,之后每步只喂最后一个 token)。temperature、top_k、top_p、repetition_penalty 各是十行代码。
它回答的问题:不传 do_sample 只传 temperature=0.2,输出是随机的吗?top_k=50, top_p=0.9 同时设置,保留的是交集还是并集、顺序能换吗?batch 里先停的那条序列在后面的步里发生了什么?
3. tokenizers 与 datasets:从 messages 到 input_ids,从 Arrow 文件到 collate_fn
第三篇读两条流水线。tokenizer.json 的五段(normalizer → pre_tokenizer → BPE model → post_processor → decoder)由 Rust 库执行,Python 壳 PreTrainedTokenizerFast 只做加载对齐、__call__ → encode_batch、padding;chat template 是沙箱 Jinja,{% generation %} 标记给出 assistant mask——SFT loss mask 的第一种来源,Qwen2.5 的模板没有它。load_dataset 把文件转成 .arrow 缓存,Dataset 是 mmap 视图;map 逐批取、调函数、写新文件,文件名是 fingerprint;shuffle / select 只改索引;变长 padding 在 collate_fn 里、纯 Python。
它回答的问题:len(tok)、tok.vocab_size、config.vocab_size 三个数为什么不同(151665 / 151643 / 151936)?"12345" 为什么是 5 个 token 而 "hello" 是 1 个?改了 map 函数里一个 print 为什么整个 10 分钟重跑?
4. peft 与 trl:LoRA 怎么挂上去,SFT / DPO / GRPO 的 loss 各在哪一行
第四篇读 peft/tuners/lora/ 与 trl/trainer/ 的三个 Trainer。peft:get_peft_model 返回 PeftModel(LoraModel(原模型)),原模型被原地改;lora.Linear 的 forward 一行;merge 把 \(\frac{\alpha}{r}BA\) 加进 weight.data。trl:SFT 三种数据格式,labels 在 _prepare_dataset 的 build_labels 这一次 map 里造,collator 只 pad,padding_free 时把每段首 token 置 -100;dpo_loss 的 sigmoid 分支就是 \(-\log\sigma(\beta\Delta)\),参考模型有三种来源;GRPO 的采样、组内优势、PPO 裁剪与 KL、四种 loss_type 的归一。
它回答的问题:target_modules=["q_proj", "v_proj"] 与 "q_proj|v_proj" 哪一种能匹配到 model.layers.3.self_attn.q_proj?LoRA 只训 8.8M 参数,反向为什么仍要经过冻结的 base_layer,省下的到底是什么?GRPO 一组 8 条全对的回答对梯度贡献多少、beta=0 时 trl 省掉了什么?
5. 系列总结与通关自测
第五篇把四篇压成一张「问题 → 文件 → 函数」的索引表,回顾贯穿五个库的四条设计线,再给一套三段式自测。
贯穿全系列的源码阅读线
每一篇都从工具箱第五篇的一行代码进入,读到它与本地图前面各层的对应处为止:
| 六行里的哪一行 | 入口文件 | 读到哪里为止 | 对应的前置篇 | 篇 |
|---|---|---|---|---|
AutoModelForCausalLM.from_pretrained(name) |
models/auto/auto_factory.py → modeling_utils.py → models/llama/modeling_llama.py |
ForCausalLMLoss(loss/loss_utils.py) |
《Transformer 原理与实现(01):Transformer 长什么样——从一句话到下一个 token》的结构图、《算法工程师的数学(05):从最大似然到交叉熵——第一个要会推的 loss》的交叉熵 | 01 |
model.generate(**inputs, do_sample=True, top_p=0.9) |
generation/utils.py |
_sample 循环里的 multinomial 与 stopping_criteria |
《算法工程师的数学(05):从最大似然到交叉熵——第一个要会推的 loss》「七、softmax」的采样公式 | 02 |
tok.apply_chat_template(messages) / load_dataset(name).map(fn) |
tokenization_utils_tokenizers.py、utils/chat_template_utils.py / arrow_dataset.py、load.py |
Rust 的 encode_batch / ArrowWriter 与 collate_fn |
预训练第二篇的 BPE | 03 |
get_peft_model(model, LoraConfig(...)) |
peft/mapping_func.py → tuners/lora/model.py → tuners/lora/layer.py |
Linear.forward 的一行 |
《算法工程师的数学(03):正交与旋转、特征值与 SVD——从 RoPE 到 LoRA》的 \(W + BA\) | 04 |
SFTTrainer(...).train()(及 DPO / GRPO) |
trl/trainer/sft_trainer.py、dpo_trainer.py、grpo_trainer.py |
build_labels、dpo_loss、_compute_loss |
后训练系列第一、三、四篇 | 04 |
每篇给出的输出——Loading weights: 290/290、装配出的 LogitsProcessorList、cache-<fingerprint>.arrow 的文件名、trainable params: 8.8M——都来自 Qwen2.5-0.5B 上的一次实际运行,脚本在 ai-learning-labs/hf-source-reading;正文已给出读懂所需的全部代码,读本系列不需要它。
前置要求与说明
前置要求
| 需要 | 到什么程度 | 在哪里学 |
|---|---|---|
| 工具箱第五篇的六行代码 | 跑过一次,知道 config.json / tokenizer.json / safetensors 各是什么 |
工具箱第五篇 |
nn.Module、state_dict、DataLoader |
知道键名从属性路径来、collate_fn 做什么 |
工具箱第三篇 |
| Transformer 的结构 | 能画出一个 decoder block,知道 RoPE、GQA、KV cache 各在哪 | 《Transformer 原理与实现(01):Transformer 长什么样——从一句话到下一个 token》 |
| SFT / DPO / GRPO 的目标函数 | 认得 \(-\log\sigma(\beta\Delta)\) 与 \((R - \text{mean}) / \text{std}\) | 后训练系列第一、三、四篇 |
第二篇只依赖第一篇;第三篇独立;第四篇用到前三篇(ForCausalLMLoss、apply_chat_template、map)。
版本与基线
transformers 5.17.0、tokenizers 0.23.2、datasets 5.0.1、peft 0.21.0、trl 1.13.0;模型 Qwen/Qwen2.5-0.5B,数据集 HuggingFaceH4/no_robots。引用只给文件路径与类名 / 函数名,不给行号——这几个库的目录结构改得快,行号几个月就失效,找入口的方法不会。
章节目录
最终目标
读完四篇,对工具箱第五篇的六行代码,你应该能:
- 说出
from_pretrained的六步,并解释为什么 8B 模型的加载峰值内存等于权重大小; - 在
modeling_llama.py里指出 L4 结构图上每个方框对应的类,并说出 attention 实现是怎么切换的; - 写出
temperature/top_k/top_p各自的十行代码,说出_sample循环每步做的六件事; - 解释
tokenizer.json的五段与map的 fingerprint,判断一次map为什么命中或没命中缓存; - 从
get_peft_model追到lora.Linear.forward的那一行,从SFTTrainer追到-100被填的那一次map,从dpo_loss与_compute_loss里各指出论文公式对应的几行。
之后遇到任何一个新的 Trainer、新的 LogitsProcessor、新的模型目录,方法相同:找到注册表、找到 compute_loss、找到 forward 里那一行调用,往下追。
[^q0]: 每行一条调用链,各对应一篇:from_pretrained → AutoConfig 读 config.json 查架构映射 → 构造 Qwen2ForCausalLM → safetensors 按 state_dict 键名加载(L4 结构图的七样东西就是 modeling_qwen2.py 里的七个类);model.generate → GenerationMixin.generate 的循环:prepare_inputs_for_generation → forward 取最后位置 logits → LogitsProcessor → 采样 → 更新 KV cache(DynamicCache)(对应 《Transformer 原理与实现(02):一个 token 的旅程——训练侧与推理侧》的 decode);apply_chat_template → Jinja 模板渲染成字符串 → tokenizer 的预分词 + BPE 合并 → input_ids;load_dataset(...).map → Arrow 文件 → Dataset.map 的批处理 / 多进程 / 缓存指纹;get_peft_model → inject_adapter 匹配 target_modules 把 nn.Linear 换成 lora.Linear(scaling = α/r、lora_B 全零,对应 《算法工程师的数学(03):正交与旋转、特征值与 SVD——从 RoPE 到 LoRA》);SFTTrainer 在 DataCollator 里填 -100 做 loss mask,DPOTrainer 的 dpo_loss 十几行是 $$-\log\sigma(\beta(\log\pi/\pi_{ref} |
w - \log\pi/\pi{ref} | _l))$$,GRPOTrainer 的组内相对优势与裁剪比率各十几行(对应 L5 的公式)。 |
地图 《AI 算法工程师学习地图》 第 9 / 12 个系列
- 算法工程师的数学
- 算法工程师的工具箱
- LLM 时代的经典机器学习
- 深度学习基础
- Transformer 原理与实现
- 现代 LLM 结构
- 预训练
- 后训练
- 读 Hugging Face 源码
- LoRA 专题
- 高效推理与压缩(算法侧)
- 多模态
本文由 arganzheng 创作,采用 CC BY 4.0 许可协议。在保留原文作者、署名以及完整原文链接(https://arganzheng.life/reading-hugging-face-source-code.html)的前提下,欢迎各种形式的转载、翻译或商业引用。
COMMENTS
评论存放在 GitHub Discussions, 用 GitHub 账号登录即可发表,支持 Markdown。 想针对正文某句话说?选中那段文字,点浮出的「评论」即可划线评论;觉得哪里写错了,发表时勾上「同时提交 Issue」。 有人回复你时 GitHub 会按你的通知设置发邮件,不用守在这里。