# 1.3.llm\_archs

## 训练框架

mfu(Model Flops Utilization)模型算力利用率是分布式训练效率的优化目标。

一个模型定义好之后，前向和反向的**计算量**就是固定（不考虑动态图的话）的，除以**每个step的latency**就是mfu。以nanoGPT中的代码为例：

```python
def estimate_mfu(self, fwdbwd_per_iter, dt):
    """ estimate model flops utilization (MFU) in units of A100 bfloat16 peak FLOPS """
    # first estimate the number of flops we do per iteration.
    # see PaLM paper Appendix B as ref: https://arxiv.org/abs/2204.02311
    N = self.get_num_params()
    cfg = self.config
    L, H, Q, T = cfg.n_layer, cfg.n_head, cfg.n_embd//cfg.n_head, cfg.block_size
    flops_per_token = 6*N + 12*L*H*Q*T
    flops_per_fwdbwd = flops_per_token * T # 计算量（T是序列长度）
    flops_per_iter = flops_per_fwdbwd * fwdbwd_per_iter # 每个step的flops * 每一次更新梯度要多少个step
    # express our flops throughput as ratio of A100 bfloat16 peak flops
    flops_achieved = flops_per_iter * (1.0/dt) # per second 一轮的计算量/一轮的耗时
    flops_promised = 312e12 # A100 GPU bfloat16 peak flops is 312 TFLOPS
    mfu = flops_achieved / flops_promised
    return mfu

##...
def xxx():
    # timing and logging
    t1 = time.time()
    dt = t1 - t0 ## 一次gradient_accumulation_steps后 更新梯度
    t0 = t1
    if iter_num % log_interval == 0 and master_process:
        # get loss as float. note: this is a CPU-GPU sync point
        # scale up to undo the division above, approximating the true total loss
        # (exact would have been a sum)
        lossf = loss.item() * gradient_accumulation_steps
        if local_iter_num >= 5: # let the training loop settle a bit
            mfu = raw_model.estimate_mfu(batch_size * gradient_accumulation_steps, dt)
            running_mfu = mfu if running_mfu == -1.0 else 0.9*running_mfu + 0.1*mfu
        print(f"iter {iter_num}: loss {lossf:.4f}, time {dt*1000:.2f}ms, mfu {running_mfu*100:.2f}%")
    iter_num += 1
    local_iter_num += 1

```

一般分布式训练参数量越多->卡数越多->通信占比越高->MFU越低，所以要优化通信效率。

### 优化设置

* batchsize：通常用比较大的batchsize，提高训练**稳定性**和**吞吐量**。GPT-3和PaLM在训练时动态增加batshzie，最终达到百万级别，batchsize**从3.2w逐渐增加到320w个token**。
* 优化器：
  * Adam和[AdamW](https://arxiv.org/pdf/1711.05101v2.pdf)：基于**一阶梯度优化的低阶矩自适应估计**，用于GPT-3等，超参$$\beta\_1=0.9, \beta\_2=0.95, \epsilon=10^{-8}$$。
  * [Adafactor](https://arxiv.org/pdf/1804.04235.pdf)：在训练过程中节省显存，用于PaLM、T5等，超参$$\beta\_1=0.9, \beta\_2=1.0-k^{-0.8}$$
* 学习率：
  * 预热（warm-up）：在训练的**初始0.1%到0.5%的steps中，用线性预热策略**逐渐增加学习率到最大值（$$5 \times 10^{-5}$$到$$1 \times 10^{-4}$$之间，GPT-3是$$6 \times 10^{-5}$$）
  * 衰减（decay）：后续steps中**余弦衰减**，逐渐降低到**最大值的约10%**，直到收敛
* 稳定训练：
  * 权重衰减和梯度裁剪：**权重衰减率**设为0.1，**梯度裁剪阈值**设为1.0
  * 梯度检查点：容易出现loss突增，PaLM和OPT从**发生突增前的一个ckpt重新开始训练**，并**跳过可能有问题的数据**
  * 缩减emb梯度：GLM发现emb的异常梯度通常会导致loss突增，故**缩减emb梯度**以缓解

### 混合精度训练

&#x20;

#### FP16

&#x20;

[Mixed precision training](https://arxiv.org/pdf/1710.03740.pdf)提出了用16位float（FP16）训练，减少**内存使用和通信开销**。A100等GPU具有的**FP16计算单元**是**FP32的两倍**，故FP16的计算效率能进一步提高。

![mixed-precision-training](/files/CiHEgbVVci5x6OfQQOCC)

* **推理（预测）**：所有参数都是fp16，相对fp32，存储变成一半，速度提升1倍。
* **训练**：参数和梯度用**fp32存储**，但是在**计算前**会**转成fp16**，**计算后**再**转回fp32**。主要为了**防止溢出**，loss要乘一个scale，然后在fp16的梯度要除以scale。

以adam优化器为例，对于每1个参数来说，fp16的训练占用20bytes显存，包括（详见：<https://zhuanlan.zhihu.com/p/519264636>）

* fp16的参数：2bytes
* fp16的梯度：2bytes
* 优化器状态（optimizer state）：16bytes
  * fp32参数（4bytes）
  * fp32梯度（4bytes）([zero论文](https://arxiv.org/pdf/1910.02054v2.pdf)里提到的，用于reduce之类操作时需要的fp32内存，以1.5B的gpt2为例，需要6GB内存，倒推回来，就需要6/1.5byte=4byte)
  * fp32 variance【历史梯度平方和】（4bytes）
  * fp32 momentum【历史梯度滑动平均】（4bytes）

而在预测时只要存一个fp16的参数(2bytes)就行，所以**预测的显存是训练的1/10**，对应1.3B参数量的gpt2-xl，训练要占用$$20B\times 1.3\times 10^9=26GB$$，预测只要2.6GB

#### BF16

&#x20;

FP16可能导致**计算精度的损失**从而影响模型性能，BLOOM里用**BF16**(brain floating point)比FP16**分配更多指数位**和**更少的有效位**，在准确性方面更好

<https://blog.csdn.net/orangerfun/article/details/133106913>

![fp16-bf16](/files/62W3lx5GSU24mNJY8NYl)

bf16的指数位和fp32一样多

### 可扩展的训练

需要**提高训练吞吐量**和**加载更大模型到显存中**

#### 3D并行

&#x20;

如下三种并行（数据并行、流水线并行、张量并行）的组合

**数据并行（Data Parallelism）**

&#x20;

将**模型参数和优化器状态复制**到多个GPU上，每个GPU只处理分给它的数据，不同GPU算出的梯度进行**聚合**得到batch的梯度，再更新**所有GPU上的模型**。高度可扩展，增加GPU数就能提高训练吞吐。

torch的ddp

```python
from torch.nn.parallel import DistributedDataParallel as DDP

ddp = int(os.environ.get('RANK', -1)) != -1 # is this a ddp run?
if ddp:
    init_process_group(backend=backend)
    ddp_rank = int(os.environ['RANK'])
    ddp_local_rank = int(os.environ['LOCAL_RANK'])
    device = f'cuda:{ddp_local_rank}'
    torch.cuda.set_device(device)
    # this process will do logging, checkpointing etc.
    master_process = ddp_rank == 0
    seed_offset = ddp_rank # each process gets a different seed

# wrap model into DDP container
if ddp:
    model = DDP(model, device_ids=[ddp_local_rank])
```

可以一起搞的技巧——**梯度累积**，当显存不够跑较大的batchsize时，训练效果可能会很差，可以先跑**多个mini-batch的前向和反向**，把梯度累积起来，再**更新一次参数**，在数学上等价于**跑一个较大的batchsize**。

```python
# forward backward update, with optional gradient accumulation to simulate larger batch size
# and using the GradScaler if data type is float16
for micro_step in range(gradient_accumulation_steps):
    if ddp:
        # in DDP training we only need to sync gradients at the last micro step.
        # 最后一个micro step才要sync梯度
        model.require_backward_grad_sync = (micro_step == gradient_accumulation_steps - 1)
    with ctx:
        logits, loss = model(X, Y)
    loss.backward() # 只是计算梯度，并不真的更新
optimizer.step()
optimizer.zero_grad(set_to_none=True)
```

也可以用torch的no\_sync()：

```python
ddp = torch.nn.parallel.DistributedDataParallel(model, pg)
with ddp.no_sync():
    for input in inputs:
        ddp(input).backward()  # no synchronization, accumulate grads
ddp(another_input).backward()  # synchronize grads
```

**流水线并行（Pipeline Parallelism）**

&#x20;

将LLM的**不同层**分配到多个GPU上，一般Transformer模型中会**将连续的层加载到同一GPU上**，以减少在GPU间传输已计算的隐层状态或梯度的成本。简单的实现会导致**GPU利用率降低**，因为每个GPU要**等前一个完成计算**，导致不必要的**气泡开销**，如下方法可以提高流水线效率：

* GPipe：[Gpipe: Efficient training of giant neural networks using pipeline parallelism](https://arxiv.org/pdf/1811.06965.pdf)
* PipeDream：[PipeDream: Fast and Efficient Pipeline Parallel DNN Training](https://arxiv.org/pdf/1806.03377.pdf)，填充多个数据batch+异步梯度更新？看下paper先。。。

**1) GPipe**

&#x20;

![gpipe](/files/qRuf9dvp6MWl7G5Cw7Nm)

Gpipe主要思想：

* 图a：把模型不同layers顺序放在4张卡上，0->3卡流水线前向计算loss，3->0再反向计算gradients
* 图b：从时间顺序上看，**每张卡有3/4时间是空闲的**，GPU利用率非常低
* 图c：配合**梯度累积**，多个mini-batch可以同时跑在流水线里面，每张卡则有3/(3+4)的时间空闲（Bubble）

流水线并行的问题是中间有**Bubble**。当卡数$$K$$，梯度累积次数$$M$$，则$$Bubble=(K-1)/(K-1+M)$$

GPT里用[Weight Tying](https://paperswithcode.com/method/weight-tying)提升效果，输入和输出共享vocab embedding

**2) 重计算**

&#x20;

即gradient checkpointing，重计算(recomputation)是对于pipeline parallelism非常重要的一个优化，最开始在[Training Deep Nets with Sublinear Memory Cost](https://arxiv.org/pdf/1604.06174.pdf)一文中提到，在**flash attention**中也用了。

因为要做pipeline+梯度累积，前向过程中的**激活值**要保存，以留给反向过程使用，保存很多份的激活值对显存造成了很大压力。recomputation(也叫**checkpointing**)用时间来换空间（反向的时候进行一次激活值的重计算），可以缓解显存问题。

pytorch的[实现](https://github.com/pytorch/pytorch/blob/main/torch/utils/checkpoint.py)。大致逻辑是包了一个`autograd.Function`，前向时保存一些inputs/rng\_state(RNG state是Random Number Generator state的缩写，**随机数生成器的状态**。在深度学习和其他计算任务中，随机数生成器用于初始化参数、决定正则化技术如dropout的行为，以及在训练过程中选择样本等。RNG状态是指随机数生成器当前的内部状态，它可以用来在需要时重现或恢复特定的随机数序列，确保实验或模型训练的可重复性)，反向时重新计算

深度更深的时候，一般效果更好

cpu offload：层数很深的时候，可能可以把一些计算挪到cpu上去，再搞回gpu

**张量并行（Tensor Parallelism）**

&#x20;

[Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism](https://arxiv.org/pdf/1909.08053.pdf)

**分解LLM的张量（参数矩阵）**，例如矩阵乘法$$Y=X A$$，$$A$$可以按列分成两个子矩阵$$A\_1$$和$$A\_2$$，从而改为$$Y=\left\[X A\_1, X A\_2\right]$$，将$$A\_1$$和$$A\_2$$**放到不同GPU上**，然后就可能通过跨GPU通信将两个GPU的结果merge。

* Megatron-LM：能扩展到更高维度的张量
* Colossal-AI：
  * 为更高维度的张量实现了张量并行，[An efficient 2d method for training super-large deep learning models](https://arxiv.org/pdf/2104.05343.pdf)、[Tesseract: Parallelize the tensor parallelism efficiently](https://arxiv.org/pdf/2105.14500.pdf)和[Maximizing Parallelism in Distributed Training for Huge Neural Networks](https://arxiv.org/pdf/2105.14450.pdf)
  * 特别针对序列数据提出**序列并行**([Sequence Parallelism: Long Sequence Training from System Perspective](https://arxiv.org/pdf/2105.13120.pdf))，详见下一节

参考<https://zhuanlan.zhihu.com/p/622036840>

![tensor parallelism](/files/tDbWhOjwQkIBIsokletk)

原始矩阵乘法是`[m,k], [k, n] -> [m, n]`，有如下两种矩阵分解的等效：

* **列并行（column parallelism）**：第一个矩阵不变，第二个矩阵**竖着劈成两半**，即$$B=\[B\_1, B\_2]$$
  * `[m,k], [k, n/2] -> [m, n/2]`
  * `concat([m, n/2], [m, n/2]) -> [m, n]`
* **行并行（row parallelism）**：两个矩阵都横着劈成两半，即$$A=\left\[\begin{array}{l}A\_1 \A\_2\end{array}\right],B=\left\[\begin{array}{l}B\_1 \B\_2\end{array}\right]$$。从2推广到k，其实就是**split-k算法**，把两个矩阵都分成k个小块，两两相乘后，最后reduce\_sum一下。因为每个线程计算的矩阵更小了，开销小，可以通过加大线程数来提升并行效率。
  * `[m, k/2], [k/2, n] -> [m, n]`
  * `elemwise_add([m, n], [m, n]) -> [m, n]`

**行并行**还可以扩展到**推荐**里，假设user有k/2维，item也是k/2维，concat在一起，然后过一个k\*d的mlp，即`[1,k] * [k, d] -->[1,d]`，那么可以按行并行的方法，拆成2个`[1, k/2]`和`[k/2,d]`相乘，再相加。这样item侧的`[k/2,d]`可以把全库缓存过来，在线实时算user，排序时把对应item向量抽出来，和user加起来就行

![megatron-transformer](/files/A8xVGU1fX1vCpJrsRrIC)

megatron对transformer进行了如下优化：

* MLP第一个nn按**列分割**，第二个nn按**行分割**，中间省了一次通信
* Attention按照head来分割(类似**列分割**)，后面接的nn按**行分割**，中间也省了一次通信

图里面的通信算子

* $$f$$是前向identity，反向all-reduce
* $$g$$是前向all-reduce，反向identity

综合来看，一层transformer layer如下

![megatron-transformer-1layer](/files/xHH0Uxugcs5ZruRAhf2R)

具体的计算量可以参考<https://colossalai.org/docs/features/1D_tensor_parallel/#introduction>：

![clossal-ai-efficiency](/files/qVzqkEDNPHdkjr9jO2zg)

#### ZeRO

&#x20;

[ZeRO: Memory Optimization Towards Training A Trillion Parameter Models](https://arxiv.org/pdf/1910.02054v2.pdf)

zero的思想：减少显存，搜广推大部分还是数据并行，所以模型参数是复制多份的，所以zero比较有用

fp16那一节中，optimizer state的显存占用，在**前向**和**反向**的时候都**不用**，只有最后**optimizer step**的时候才用。

\===>zero的思想：把optimizer state**分shard存在不同的卡上**，只在**最后gather时才用**。

ZeRO（Zero Redundancy Optimizer）在DeepSpeed库中提出，解决**数据并行**中的**内存冗余**问题。数据并行其实并不需要每个GPU都存整个模型、梯度和优化器参数，ZeRO在每个GPU仅保存部分数据，当需要其余数据时从其他GPU检索。3种解决方案：

* 优化器状态分区：zero1，对显存最大开销的部分进行shard
* 梯度分区：zero2
* 参数分区：zero3

前两种方案不会增加通信开销，第三种方案增加约50%通信开销，但能节省和gpu数成比例的内存。

![zero](/files/WfJ4hcc4PjO2I8FqyLCx)

详见官方博客：[ZeRO & DeepSpeed: New system optimizations enable training models with over 100 billion parameters](https://www.microsoft.com/en-us/research/blog/zero-deepspeed-new-system-optimizations-enable-training-models-with-over-100-billion-parameters/)

```python
import deepspeed
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--local_rank", type=int, default=0)
deepspeed.add_config_arguments(parser)
args = parser.parse_args()

model, optimizer, _, _ = deepspeed.initialize(args=args,
                                              model=model,
                                              model_parameters=model.parameters())
X, Y = get_batch('train')
logits, loss = model(X, Y)
model.backward(loss)
model.step()
```

需要指定deepspeed的配置：

```python
{
  "train_batch_size": 64,
  "gradient_accumulation_steps": 1,
  "optimizer": {
    "type": "Adam",
    "params": {
      "lr": 6e-4,
      "weight_decay": 1e-2,
      "betas": [0.9, 0.95]
    }zer
  },
  "scheduler": {
    "type": "WarmupLR",
    "params": {
        "warmup_min_lr": 6e-5,
        "warmup_max_lr": 6e-4,
        "warmup_num_steps": 2000
    }
  },
  "bf16": {
    "enabled": true
  },
  "zero_optimization": {
    "stage": 1
  }
}
```

启动：

```shell
deepspeed --num_gpus=8 train.py --deepspeed_config xx.json
```

facebook的开源库**FSDP(full sharded data parallel)**([Fairscale: A general purpose modular pytorch library for high performance and large scale training](https://github.com/facebookresearch/fairscale))里基于pytorch实现了类似ZeRO的技术。

```python
from torch.distributed.fsdp import FullyShardedDataParallel as FSDP, ShardingStrategy
model = FSDP(model)  #, sharding_strategy=ShardingStrategy.SHARD_GRAD_OP)
```

还有一些paper也能降低内存，如

[Reducing activation recomputation in large transformer models](https://arxiv.org/pdf/2205.05198.pdf)

[Training deep nets with sublinear memory cost](https://arxiv.org/pdf/1604.06174.pdf)

#### 序列并行

&#x20;

**序列并行**([Sequence Parallelism: Long Sequence Training from System Perspective](https://arxiv.org/pdf/2105.13120.pdf))，可以进一步分解Transformer的注意力操作。

[Reducing Activation Recomputation in Large Transformer Models](https://arxiv.org/pdf/2205.05198.pdf)这个也是

对比TP：

![tensor-parallel](/files/EYiBk0J5bB6oMPuqAIUe)

SP：

![sequence-parallel](/files/UiLC1RM4MmEdbNREdtLK)

#### 综合对比各种并行

&#x20;

几个缩写：params（p）/gradients(g)/optimizer states(os)/activation(a)

| 并行方法            | 显存效率                                                                 | 计算效率                                                             | 限制                                                      |
| --------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------- | ------------------------------------------------------- |
| DP（数据并行）        | p/g/os都复制在每张卡上，显存效率很低                                                | 计算和通信可以overlap，如果都在一个minipod内扩展性很好；梯度累积可以提高计算效率                  | batchsize不能太大，否则模型效果有损；batchsize/dp不能太小，不然打不满tensorcore |
| ZeRO（解决DP的显存冗余） | zero1/2/3把os/g/p分别shard到每张卡上，显存效率很高                                  | 需要做prefetch来减少通信对计算效率的影响                                         | 同DP                                                     |
| PP（流水线并行）       | 切分p，提高显存效率；a需要存多次，降低显存效率                                             | 通信次数最少，只发生在多层之间的切分点，但是有Bubble                                    | 每个Stage之间需要负载均衡，对模型结构和卡数有限制                             |
| TP（张量并行）        | p/g/os/a被shard在每张卡上，显存效率也很高；有些层如layernorm是复制的，可以用sequence parallel优化 | 梯度不需要同步，提高计算效率；每层插入了4次通信，而且是跟计算有依赖的，会降低计算效率；每层的计算量进行了切分，也会降低计算效率 | 一般是单机内8卡使用nvlink时用TP                                    |

把神经网络看成是输入$$X$$和权重$$W$$的矩阵乘法$$XW$$，那么，**DP和PP其实是对**$$X$$**的拆分**，而**TP则是对**$$W$$**的拆分**

整体对比可以看

![megatron-results](/files/dhJCofhQVfkv5pGCicbu)

一般这么整合：

* 把机器分成N组，**不同组之间用DP**
* 一组机器有M台机器，**不同机器之间用PP**
* 一台机器有K张卡，**不同卡之间用TP**

### 编译优化

pytorch的TorchDynamo

<https://pytorch.org/docs/stable/torch.compiler_deepdive.html>

最简单的用法`torch.compile()`

![TorchDynamo](/files/YIdFA78zYPiCdhbGFsYu)

### flash attention

[Flashattention: Fast and memory-efficient exact attention with io-awareness](https://arxiv.org/abs/2205.14135)

FlashAttention其实是对$$softmax(QK^T)V$$的一种加速实现。

一般的实现：需要先 用矩阵$$C$$存$$QK^T$$的结果，然后对$$C$$按行做softmax得到新的$$C$$，再用$$C$$乘以$$V$$得到最后结果。

FlashAttention通过一些特殊技巧，不需要算出$$C$$这个临时变量，通过分块计算，**让临时变量总是可以放在cache里**，从而

* 减少Global Memory的大小
* 加速attenttion的计算，因为读cache比访问Global Memory快多了。

### flash attention2

[FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning](https://arxiv.org/pdf/2307.08691)

### flash attention3

[FlashAttention-3: Fast and Accurate Attention with Asynchrony and Low-precision](https://arxiv.org/pdf/2407.08608)

### flash attention4

[FlashAttention-4震撼来袭，原生支持Blackwell GPU，英伟达的护城河更深了？](https://mp.weixin.qq.com/s/1PaAaz8Fbt6sFKmD1hRQ7w)

<https://github.com/Dao-AILab/flash-attention>

### flexattention

[新PyTorch API：几行代码实现不同注意力变体，兼具FlashAttention性能和PyTorch灵活性](https://mp.weixin.qq.com/s/8uoZZf4hNSLQYLKFr95jTw?poc_token=HAynt2ajgl8xoDMpMWq0t8R-ubMokh17VRDwmacE)

### 训练稳定性

学习率+batchsize的一些经验：

<https://zhuanlan.zhihu.com/p/64864995>

另外，swiglu会让act\_norm变大，得加一些方式让模型能训动，一种方法是把weight\_decay调小：

* loss会变高==><https://poe.com/s/Cv6lODy94INz1ozQKJYJ>，正则项变大，L+norm中的L相对影响变小了，所以会变大，即为了防止过拟合，但可能eval的时候会更好
* act\_norm会降低20-30%，因为正则项更重要了，会让权重更接近0

层数加深时的稳定性调优：[Transformers Get Stable: An End-to-End Signal Propagation Theory for Language Models](https://arxiv.org/pdf/2403.09635)

### 数据/训练策略

#### 综述

[A Survey on Data Selection for Language Models](https://arxiv.org/pdf/2402.16827)

#### 高质量数据

[Llama架构比不上GPT2？神奇token提升10倍记忆？](https://mp.weixin.qq.com/s/TMkn6yMTUrrGhxCQnd7_2g)

[Physics of Language Models: Part 3.3, Knowledge Capacity Scaling Laws](https://arxiv.org/pdf/2404.05405.pdf)

制造**人工合成数据**，通过控制数据中知识的数量和类型，来严格调控数据中的**知识比特数 (bits)**。使用不同大小和架构的 LLM 在人工合成数据上进行训练，并给出数学定理，来精确计算训练好的模型从数据中**学到了多少比特的知识**。有如下几个发现：

* 如果**训练时间充足**，不论使用何种模型架构，模型的**存储效率**均可以达到**2bit/param**（即平均每个模型参数可以存储2比特的信息）。而且发现transformer中的知识**并非主要存储在MLP层**，因为即便移除所有MLP层，模型仍能达到 2bit/param 的存储效率。
* 如果**训练时间不充足**，GPT2模型能比LlaMA/Mistral存储超过30%的知识，主要是因为**GatedMLP(MoE)会导致训练不稳定**，因此对同样的知识，需要**更长的训练时间**。
* **压缩/量化**的影响：将训练好的模型从float32/16压缩到int8，对知识的存储**毫无影响**。LLM可以达到“**信息论极限**”的**1/4**——因为int8只有8比特，但平均每个参数可以存储2比特的知识。
* **高质量数据**的影响：如果我们的预训练数据中，有1/8来自高质量知识库（如百度百科），7/8来自低质量数据（如common crawl或论坛对话，甚至是完全随机的垃圾数据），会发现：
  * 即使对高质量数据的训练时间保持一致，**低质量数据的存在本身**可能会让模型对**高质量知识的存储量下降20倍**，即便将高质量数据的训练时间延长 3倍，知识储量仍会降低3倍
  * 解法：只需给所有的预训练数据**加上自己的网站域名token即可**，模型的知识存储量可以立即回升10倍，模型**不需要任何先验知识**来识别哪些网站上的知识是金子，而可以在预训练过程中，自动发现高质量知识的网站，并**自动为这些高质量数据腾出存储空间**。

#### DSIR

[Data Selection for Language Models via Importance Resampling](https://arxiv.org/pdf/2302.03169)

<https://github.com/p-lambda/dsir>

大致思路：

输入语料样本$$z\_i$$

* 学习语料的特征分布（target data是$$\hat{p}$$，raw data是$$\hat{q}$$）
* 利用语料样本衡量样本间的重要性权重$$w\_i=\frac{\hat{p}\left(z\_i\right)}{\hat{q}\left(z\_i\right)}$$
* 根据权重进行无放回的采样，兼顾多样性和分布一致性

#### DoReMi

[DoReMi: Optimizing Data Mixtures Speeds Up Language Model Pretraining](https://arxiv.org/pdf/2305.10429) NeurIPS2023的spotlight

<https://github.com/sangmichaelxie/doremi>

![doremi](/files/EtMamW0YbPPg2lDOFASx)

* 使用初始的reference domain weights来训练一个小的reference model $$p\_{ref}$$，可以用简单的方式合并，例如用样本量加权
* 用reference mnodel来指导一个小的proxy model的训练，proxy model使用group DRO（group distributionally robust optimization）来得到domain weights，即让最大的loss gap最小化

$$
\min *\theta \max *{\alpha \in \Delta^k} L(\theta, \alpha):=\sum*{i=1}^k \alpha\_i \cdot\left\[\frac{1}{\sum*{x \in D\_i}|x|} \sum\_{x \in D\_i} \ell\_\theta(x)-\ell\_{\mathrm{ref}}(x)\right]
$$

* domain weights: $$\alpha$$
* proxy model参数：$$\theta$$
* domain语料：$$D$$
* $$\ell\_\theta(x)=-\log p\_\theta(x)$$
* 使用tune完的domain weights来训练大模型
* 可以重复这个过程，用新的domain weights重新训练ref\_model，迭代下去

#### dataset decomposition

[Dataset Decomposition: Faster LLM Training with Variable Sequence Length Curriculum](https://arxiv.org/pdf/2405.13226)

LLM的训练语料大都是相同长度的sequence，一般是多篇文档concat到一起，然后再切分成等长的sequence，有可能一个sequence里有不同的毫不相关的文档，这样算attention就不太适合了。方法

* 将数据划分为多个桶，每个桶中的序列长度均为$$2^i$$，保证每个序列仅来自同一个文档
* 训练时可以给定一个固定的batch\_len，即直接从某个桶里采样，也可以用特定长度策略，从多个桶里采样，组合为特定长度

![dataset-decomposition](/files/lkuv5OjzJAwOF2bCBAB3)

#### RHO-1

[RHO-1: Not All Tokens Are What You Need](https://arxiv.org/pdf/2404.07965)

<https://github.com/microsoft/rho>

![rho-1](/files/1REvqlypf8HcnWTPgGR4)

把语料中的无用token从loss里删了

![slm](/files/51rcTVfCkb3IcndNOifN)

* 训练ref\_model，挑选少量高质量语料，建模语料的整体loss分布情况
* 拿ref\_model在整个预训练语料上计算每个token的ppl
* 训练LLM，只关注得分比较高的tokens

#### infinit lr

[Simple and Scalable Strategies to Continually Pre-train Large Language Models](https://arxiv.org/pdf/2403.08763)

linear warmup and cosine decay schedule：

* linear warmup阶段：前$$T\_{warmup}$$步线性增加学习率，即直到时间步$$t\_{\text {ann }}=T\_{\text {warmup }}$$，学习率设置为$$\eta\_t=\eta\_{\max } \cdot \frac{t}{T\_{\text {warmup }}}$$
* annealing阶段：对于接下来的$$T\_{ann}$$个时间步，改为cosine annealing方式，即对于时间步$$t\_{e n d}=T\_{a n n}+t\_{a n n}$$：

$$
\eta\_t=\eta\_{\min }+\frac{\left(\eta\_{\max }-\eta\_{\min }\right)}{2} \cdot\left(\cos \left(\pi \cdot \frac{t-t\_{a n n}}{t\_{\text {end }}-t\_{\text {ann }}}\right)+1\right)
$$

infinit lr decay：

* linear warmup阶段：同上
* cool down阶段：学习率逐渐decay到一个常量$$\eta\_{\text {const }}$$
* 常数阶段：学习率保持为这个常数，该阶段结束时的ckpt可以用于新数据集的继续pretrain
* annealing阶段：逐渐减小到最小值

$$
\eta\_t=\left{\begin{array}{lll}
\eta\_{\text {max }} \cdot \frac{t}{T\_{\text {warmup }}} & t \in\left\[0, t\_{c d}\right] & \text { (warm-up) } \\
f\_{c d}(t) & t \in\left(t\_{c d}, t\_{\text {const }}\right] & \text { (cooldown) } \\
\eta\_{\text {const }} & t \in\left(t\_{\text {const }}, t\_{\text {ann }}\right] & \text { (constant) } \\
\eta\_{\text {const }} \cdot\left(\frac{\eta\_{\min }}{\eta\_{\text {const }}}\right)^{\frac{t-t\_{\text {ann }}}{t\_{\text {end }}-t\_{\text {ann }}}} & t \in\left(t\_{\text {ann }}, t\_{\text {end }}\right] & \text { (annealing) }
\end{array}\right.
$$

#### JEST

[DeepMind新方法：训练时间减少13倍，算力降低90%](https://mp.weixin.qq.com/s/8rkE6Rp2yw31gw0XhFcZXg)

[Data curation via joint example selection further accelerates multimodal learning](https://arxiv.org/pdf/2406.17711)

现有的大规模预训练数据筛选方法速度慢、成本高，并且没有考虑到批次组成或训练过程中数据相关性的变化，这限制了多模态学习中的效率提升。因此，DeepMind团队研究了**联合选择数据批次**而非单个样本是否能够加速多模态学习。

* 挑选好的数据批次比单独挑选数据点更为有效
* 在线模型近似可用于更高效地过滤数据
* 可以引导小型高质量数据集以利用更大的非精选数据集

JEST能够在仅使用10%的FLOP预算的情况下超越之前的最先进水平。

### 硬件的可能影响

<https://zhuanlan.zhihu.com/p/701623664?utm_psn=1784500156948938753>

大模型训练（如InternLM-7B）实践中，曾经遇到过在A100集群上表现正常的代码和数据，迁移到A800集群却出现了模型准确度下降和梯度范数爆炸的问题。经过调查，我们发现这与**A800和A100 GPU的NVLink带宽差异**有关。通过在两个集群上使用nanoGPT模型进行的对照实验，我们确认了精度差异的原因在于**NCCL的Ring all-reduce算法实现**。进一步实验表明，设置环境变量NCCL\_ALGO=Tree或使用gloo作为backend可以解决精度对齐问题。最终，我们提出了一个解决方案：**在A800集群上设置NCCL\_ALGO=Tree**，强制使用Tree算法进行all-reduce操作，从而避免了Ring算法带来的精度问题，使得A800集群的模型能够正常收敛，并且与A100集群的训练精度对齐。

### fastpersist

[DeepSpeed 最新力作：大模型CKPT速度提升116倍](https://mp.weixin.qq.com/s/Gc-rMSMqWzycpn2Ye8lnIQ)

[FastPersist: Accelerating Model Checkpointing in Deep Learning](https://arxiv.org/pdf/2406.13768)

### pathways

[Pathways: Asynchronous Distributed Dataflow for ML](https://arxiv.org/pdf/2203.12533.pdf)

下载了，[pdf](https://github.com/daiwk/collections/blob/master/assets/LLM/pathways.pdf)

这个回答分析得不错 <https://www.zhihu.com/question/524596983/answer/2420225275>

Google的大规模稀疏模型设计

[DESIGNING EFFECTIVE SPARSE EXPERT MODELS](https://arxiv.org/pdf/2202.08906.pdf)

代码：<https://github.com/tensorflow/mesh/blob/master/mesh_tensorflow/transformer/moe.py>

### megatron-lm

<https://zhuanlan.zhihu.com/p/646406772>

### deepspeed

<https://zhuanlan.zhihu.com/p/343570325>

### ray-llm

<https://github.com/ray-project/ray/releases/tag/ray-2.4.0>

[Data+AI标配：Ray的2024年度总结](https://mp.weixin.qq.com/s/eiucaLEqcPyqoP17cjCr2w)

### Google的几大LLM加速工具

#### maxdiffusion

<https://github.com/google/maxdiffusion>

#### JetStream

<https://github.com/google/JetStream>

#### maxtext

<https://github.com/google/maxtext>

### Fire-Flyer AI-HPC

[用60%成本干80%的事，DeepSeek分享沉淀多年的高性能深度学习架构](https://mp.weixin.qq.com/s/-OeGYiN15vzwv0INPfIU5w)

[Fire-Flyer AI-HPC: A Cost-Effective Software-Hardware Co-Design for Deep Learning](https://arxiv.org/pdf/2408.14158)

### megatron-kwai

[万字干货！手把手教你如何训练超大规模集群下的大语言模型](https://mp.weixin.qq.com/s/SRwSnQtxx2Zyb6iIHOZPQw)

[Accelerating the Training of Large Language Models using Efficient Activation Rematerialization and Optimal Hybrid Parallelism](https://www.usenix.org/conference/atc24/presentation/yuan)

<https://github.com/kwai/Megatron-Kwai>

### DiPaCo

[DiPaCo | Google分布式训练和分布式MoE 新范式 （上）](https://mp.weixin.qq.com/s/_SdQy10mcUVLcW-r-VoTsw)

[DiPaCo | Google分布式训练和分布式MoE 新范式 （下）](https://mp.weixin.qq.com/s?__biz=MzA5MTQxMTM0Nw==\&mid=2247486316\&idx=1\&sn=467b6ae104b32f79d9e25d53a5771f97)

[DiPaCo: Distributed Path Composition](https://arxiv.org/pdf/2403.10616)

### ByteRobust

[豆包是如何炼成的？字节放出自研万卡训练系统ByteRobust论文](https://mp.weixin.qq.com/s/-KDhk_R4nj3C-uPG11VoYQ)

[Robust LLM Training Infrastructure at ByteDance](https://arxiv.org/abs/2509.16293)

## 推理框架

### KVCache

kvcache的原理：<https://zhuanlan.zhihu.com/p/670515231>

kvcache的量化：<https://zhuanlan.zhihu.com/p/691537237>

一些结论：

* 浅层KV cache相比于深层KV cache，对模型的重要性更大。

### 量化

[ZeroQuant-V2: Exploring Post-training Quantization in LLMs from Comprehensive Study to Low Rank Compensation](https://arxiv.org/pdf/2303.08302.pdf)和[Compression of generative pre- trained language models via quantization](https://arxiv.org/pdf/2203.10705.pdf)

* int8量化：[LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale](https://arxiv.org/pdf/2208.07339.pdf)
* int4量化：GLM中用了

### PPL.LLM

[高性能 LLM 推理框架的设计与实现](https://mp.weixin.qq.com/s/4o86rMuburB8jcbU0aYC7g)

<https://github.com/openppl-public/ppl.llm.serving>

### vLLM

<https://github.com/vllm-project/vllm>

各种特性的组合

<https://docs.vllm.ai/en/stable/features/?h=feature#feature-x-feature>

[图解Vllm V1系列1：整体流程](https://mp.weixin.qq.com/s/agtNbHsVZ9FuWxyK4Ttvdg)

[Efficient Memory Management for Large Language Model Serving with PagedAttention](https://arxiv.org/pdf/2309.06180.pdf)

```
As an example, for the 13B parameter OPT model, the KV cache of a single token demands 800 KB of space, calculated as 2 (key and value vectors) x 5120 (hidden state size) x 40 (number of layers) x 2 (bytes per FP16). 
```

对比sglang/trt-llm：<https://blog.vllm.ai/2024/09/05/perf-update.html>，看着和trt-llm差不多，sglang更菜

[我与vLLM的2024：清华大佬的vLLM开发之路](https://mp.weixin.qq.com/s/9WW4894LBIq72ormhlMJmA)

分布式infer：[YaRN: Efficient Context Window Extension of Large Language Models](https://arxiv.org/pdf/2309.00071)，Qwen用到了：<https://qwen.readthedocs.io/en/latest/deployment/vllm.html#multi-gpu-distributed-serving>

使用技巧：

参考<https://docs.vllm.ai/en/latest/features/compatibility_matrix.html>看所有特性的兼容性，还有<https://docs.vllm.ai/en/latest/performance/optimization.html>

* cudagraph一般来讲会比eager快，所以不要加`--enforce-eager`
* `--enable-prefix-caching`这个开起来
* `--enable-chunked-prefill`这个也开起来，配合`--max-num-batched-tokens`一起搞
* `--max-model-len`限制prompt+response的总长度，利于加速，说实话这个是最有效的参数
* `--max-num-seqs`可以设置一下，最好和实际的请求落到这个server实例的qps近似，需要实测
* `--swap-space`其实没啥用，只有一个prompt生成多个response的时候有用，即`best_of > 1`（参考github issue：<https://github.com/vllm-project/vllm/issues/2853>），也就是说根本不会用到cpu的kvcache
* 投机采样说实话比较鸡肋，特别是对于qwen系列模型来讲，因为不同大小的qwen的词表是不一样大的，所以其实用不了，而如果用最简单的ngram，速度又非常慢
* 请求里的`presence_penalty`设置一下，不然qwen容易出现死循环输出从而打爆tokens

示例：

```python
import subprocess
import time
import requests
import json
import socket
from concurrent.futures import ThreadPoolExecutor, as_completed

import openai


# 检查端口是否可用
def is_port_open(host, port, timeout=5):
    """
    检查指定端口是否可用
    :param host: 主机地址
    :param port: 端口号
    :param timeout: 超时时间（秒）
    :return: True 如果端口可用，否则 False
    """
    try:
        with socket.create_connection((host, port), timeout=timeout):
            return True
    except (socket.timeout, ConnectionRefusedError):
        return False

# 启动 vLLM 服务
def start_vllm_service():
#        "CUDA_VISIBLE_DEVICES=0 VLLM_WORKER_MULTIPROC_METHOD=spawn \
    port = 12345
    import os
    import tempfile

    # 创建临时目录并设置权限
    temp_dir = tempfile.mkdtemp()
    os.chmod(temp_dir, 0o755)
    
    # 设置环境变量
    env = os.environ.copy()
    env.update({
        "VLLM_WORKER_MULTIPROC_METHOD": "spawn",
        #"CUDA_VISIBLE_DEVICES": "0",
        "TMPDIR": temp_dir,
        "TEMP": temp_dir,
        "TMP": temp_dir
    })
    cur_port = port    
    tp_size = 1
    process = subprocess.Popen(
        ["python3", "-m", "vllm.entrypoints.openai.api_server",
                "--host", "0.0.0.0",
                "--port", str(cur_port),
                "--max-model-len", "2000",
                "--max-num-batched-tokens", "1024",
                "--max-num-seqs", "64",
                "--trust-remote-code",
                "--enable-reasoning",
                "--enable-prefix-caching",
                "--enable-chunked-prefill",
#                "--swap-space", "16",
#                "--speculative_model", "./DeepSeek-R1-Distill-Qwen-7B",
#                "--num_speculative_tokens","5",
#                "--speculative_draft_tensor_parallel_size", "1",
#                "--speculative_model", "[ngram]",
#                "--num_speculative_tokens", "5",
#                "--ngram_prompt_lookup_max", "4",
#                "--enforce-eager",
                "--reasoning-parser", "deepseek_r1",
                "--tensor-parallel-size", str(tp_size),
                "--served-model-name", "deepseek-reasoner",
        "--model", "./DeepSeek-R1-Distill-Qwen-32B-AWQ"
    ],
        #shell=True,
        env=env,
        stdout=open("./out.log", "w"),
        stderr=open("./err.log", "w")
    )
    #--max-num-batched-tokens 65536 
    #    --gpu-memory-utilization 0.97 \
    #    --uvicorn-log-level warning \
    return process

# 发送请求的函数
def send_request(client, model, prompt):
    """
    向 vLLM 服务发送请求
    :param prompt: 用户输入的提示
    :return: 模型生成的响应
    """
    try:
        messages = [{"role": "user", "content": prompt}]
        completion = client.chat.completions.create(
            model=model,
            messages=messages,
            temperature=0.3,
            presence_penalty=1.2,
#            top_p=0.1
            #   max_tokens=8
        )
        print(completion.choices[0])
        content = completion.choices[0].message.content
        reasoning_content = completion.choices[0].message.reasoning_content
        print(content)
        #print("reasoning:")
        #print(reasoning_content)
        return content
    except Exception as e:
        return {"error": str(e)}

# 主函数
def main():
    """
    主函数：启动服务、发送并发请求、处理结果
    """
    # 启动 vLLM 服务
    print("Starting vLLM service...")
    vllm_process = start_vllm_service()

    # 检查端口是否可用
    host = "localhost"
    port =12345 
    print(f"Waiting for service to start on {host}:{port}...")
    while not is_port_open(host, port):
        print("Service not ready yet, waiting...")
        time.sleep(2)  # 每 2 秒检查一次
    print("Service is ready!")

    all_p = []
    with open("./prompts", 'r') as fin:
        for line in fin:
            prompt = line.strip("\n")
            all_p.append(prompt)

    prompts = all_p[:68]

    client = openai.OpenAI(
        base_url=f"http://{host}:{port}/v1", # "http://<Your api-server IP>:port"
        api_key = "sk-no-key-required"
    )

    models = client.models.list()
    model = models.data[0].id

    # 使用 ThreadPoolExecutor 创建线程池并发发送请求
    print("Sending requests concurrently...")
    start = time.time()
    with ThreadPoolExecutor(max_workers=60) as executor:  # 最大线程数为 
        # 提交任务到线程池
        futures = [executor.submit(send_request, client, model, prompt) for prompt in prompts]
        # 获取任务结果
        for future in as_completed(futures):
            try:
                result = future.result()
                print("Response:", result)
            except Exception as e:
                print(f"Request failed: {e}")
    end = time.time()
    cost = end - start
    print(cost)
    # 关闭 vLLM 服务
    print("Stopping vLLM service...")
    vllm_process.terminate()
```

### 并行推理方法

[Efficiently scaling transformer inference](https://arxiv.org/pdf/2211.05102.pdf)

[3万字详细解析清华大学最新综述工作：大模型高效推理综述](https://mp.weixin.qq.com/s/U9ESiWehnoKc9SnDz7DVKg)

[万字综述大模型高效推理：无问芯穹与清华、上交最新联合研究全面解析大模型推理优化](https://mp.weixin.qq.com/s/7LKfamTnCyFih6_grf9m3A)

[A Survey on Efficient Inference for Large Language Models](https://arxiv.org/pdf/2404.14294)

[LLM后端推理引擎性能大比拼](https://mp.weixin.qq.com/s/dPd84P_VdKog8v2IcHDOrQ)

### medusa

decoder的并行化： <https://zhuanlan.zhihu.com/p/368592551>

<https://sites.google.com/view/medusa-llm>

用了tree-attention

<https://github.com/FasterDecoding/Medusa>

### CLLM

[3倍生成速度还降内存成本，超越Medusa2的高效解码框架终于来了](https://mp.weixin.qq.com/s/Aw_bjXIQFdOJvN22UvW9UA)

[CLLMs：Consistency Large Language Models](https://arxiv.org/pdf/2403.00835)

### fasterTransformer/TensorRTLLM

<https://github.com/NVIDIA/FasterTransformer>

<https://github.com/NVIDIA/TensorRT-LLM/>

remove padding的逻辑如下，把整个batch的数据变成一行数据，加上offset标注是哪一条样本的

![effective\_transformer](/files/jpMuUqzlX2EOcA2zdfKS)

源自<https://github.com/NVIDIA/FasterTransformer/blob/main/docs/bert_guide.md>，思想其实是<https://github.com/bytedance/effective_transformer>提出的

直接有这么个脚本：

<https://github.com/NVIDIA/TensorRT-LLM/blob/main/examples/recurrentgemma/convert_checkpoint.py>

<https://github.com/daiwk/TensorRT-LLM/blob/main/tensorrt_llm/models/recurrentgemma/model.py>

关于plugin：

* 自己加plugins：<https://github.com/NVIDIA/TensorRT-LLM/tree/main/examples/openai_triton>
* 已有plugins：<https://github.com/NVIDIA/TensorRT-LLM/tree/main/cpp/tensorrt_llm/plugins>

一些参数设置：

<https://www.bentoml.com/blog/tuning-tensor-rt-llm-for-optimal-serving-with-bentoml>

`--multiple_profiles` enables multiple TensorRT optimization profiles in the built engines, it will benefits the performance especially when GEMM plugin is disabled, because more optimization profiles help TensorRT have more chances to select better kernels. However, this feature will increase the engine build time.

#### trt-llm显存泄露解决

因为用到了kvcache，py的runner的memory管理有问题，改成cpp的runner就行了

<https://github.com/NVIDIA/TensorRT-LLM/issues/283>

<https://nvidia.github.io/TensorRT-LLM/reference/memory.html#python-runtime-not-recommended-to-be-used>

### huggingface/text-generation-inference

<https://huggingface.co/docs/text-generation-inference/index>

<https://github.com/huggingface/text-generation-inference/blob/main/server/text_generation_server/models/causal_lm.py>

<https://github.com/huggingface/text-generation-inference/blob/main/server/text_generation_server/models/seq2seq_lm.py>

<https://github.com/huggingface/text-generation-inference/blob/main/server/text_generation_server/models/mamba.py>

### block transformer

[KAIST-AI | 提出Block Transformer架构，大幅提升推理速度和内存效率，20倍增益！](https://mp.weixin.qq.com/s/H9qETDRwR9Q_3fG-XkBeeQ)

[Block Transformer: Global-to-Local Language Modeling for Fast Inference](https://arxiv.org/pdf/2406.02657)

<https://github.com/itsnamgyu/block-transformer>

### MoonCake

[月之暗面kimi底层推理系统方案揭秘](https://mp.weixin.qq.com/s/4SBRZKAjqcS2MkvnFPey_g)

[Mooncake: A KVCache-centric Disaggregated Architecture for LLM Serving](https://github.com/kvcache-ai/Mooncake/blob/main/Mooncake-v1.pdf)

<https://github.com/kvcache-ai/Mooncake/tree/main>

### MInference(microsoft)

[MInference 1.0: Accelerating Pre-filling for Long-Context LLMs via Dynamic Sparse Attention](https://arxiv.org/pdf/2407.02490)

![minference](/files/F9vyosNAnQ7wzSuwu1zf)

### Sarathi-Serve(microsoft)

[OSDI 2024系列-低延迟大模型推理服务1](https://mp.weixin.qq.com/s/lfIyLnR2l5KBeuvPzeLBnQ)

[Taming Throughput-Latency Tradeoff in LLM Inference with Sarathi-Serve](https://arxiv.org/pdf/2403.02310)

### SGLang(uc berkerley)

[贾扬清点赞：3K star量的SGLang上新，加速Llama 405B推理秒杀vLLM、TensorRT-LLM](https://mp.weixin.qq.com/s/FYwguU3USf12Wb5HXaHH3A)

[吞吐量提升5倍，联合设计后端系统和前端语言的LLM接口来了](https://mp.weixin.qq.com/s?__biz=MzA3MzI4MjgzMw==\&mid=2650904838\&idx=4\&sn=81a9f09f54f1b89b98fdc3d6be11ce51\&chksm=84e45d78b393d46e38fed5d7e1952c9f465488b6953b63206a077f9d886c1104028b06c987c4\&scene=21#wechat_redirect)

<https://github.com/sgl-project/sglang/>

[SGLang: Efficient Execution of Structured Language Model Programs](https://arxiv.org/pdf/2312.07104)

[三个程序员奋战三天重写推理堆栈，Grok-2 mini直接提速两倍，马斯克亲发贺电](https://mp.weixin.qq.com/s/prC4R1Jjhc7r6mMXv_ZNcw)

[当开源创新遇上推理革命：SGLang如何炼就DeepSeek最强开源推理引擎？](https://mp.weixin.qq.com/s/Yo71XCYZUHxwYDQmkWsjoA)

### LazyLLM

[苹果让大模型学会偷懒：更快吐出第一个token，准确度还保住了](https://mp.weixin.qq.com/s/mAbiJEKd2zzNmt1pmGfmnQ)

[LazyLLM: Dynamic Token Pruning for Efficient Long Context LLM Inference](https://arxiv.org/pdf/2407.14057)

### 各框架对比

[最佳LLM推理引擎？TensorRT vs vLLM vs LMDeploy vs MLC-LLM](https://mp.weixin.qq.com/s/AnqaukudFukLYSi55w9r2Q)

### DuoAttention

[MIT韩松团队长上下文LLM推理高效框架DuoAttention：单GPU实现330万Token上下文推理](https://mp.weixin.qq.com/s/avM4jketPuNGzx-8tZvxIQ)

[DuoAttention: Efficient Long-Context LLM Inference with Retrieval and Streaming Heads](https://arxiv.org/abs/2410.10819)

<https://github.com/mit-han-lab/duo-attention>

### FlashInfer

[叶子豪、陈天奇等人开源项目FlashInfer入选，MLSys2025最佳论文奖公布](https://mp.weixin.qq.com/s/ifDaTpoo0VXCa6UutgSmMA)

[FlashInfer: Efficient and Customizable Attention Engine for LLM Inference Serving](https://arxiv.org/abs/2501.01005)

<https://github.com/flashinfer-ai/flashinfer>

### Multiverse

[逐个token太慢！大模型原生并行出token，CMU、英伟达新作Multiverse](https://mp.weixin.qq.com/s/ZkYvbsHkob5qO5GgTw2j9Q)

[Multiverse: Your Language Models Secretly Decide How to Parallelize and Merge Generation](https://arxiv.org/pdf/2506.09991v2)

<https://github.com/Multiverse4FM/Multiverse>

### MegaScale-Infer

[MegaScale-Infer: Serving Mixture-of-Experts at Scale with Disaggregated Expert Parallelism](https://arxiv.org/pdf/2504.02263)

在Decode阶段，如下图所示，其中“max”表示batch size增大至显存容量上限。

* Attention通常是访存瓶颈（memory access bound），因为有多个矩阵乘法，要读写多个矩阵（QKVO），有一些是串行的。当增大batch size时，Attention的算力需求基本保持不变，因其已达到数据加载的上限
* FFN则更多表现为计算瓶颈（compute bound），因为只需要读一次2个矩阵，做大矩阵乘法比较慢。当增大batch size时，FFN能够获得一定的性能提升，这一特点在MoE架构中尤为明显

![](/files/N7eEtlWeBrXMojLXULQu)

### Prefill-as-a-Service

[Prefill-as-a-Service: KVCache of Next-Generation Models Could Go Cross-Datacenter](https://arxiv.org/pdf/2604.15039)

## speculative-decoding

### 综述

[Unlocking Efficiency in Large Language Model Inference: A Comprehensive Survey of Speculative Decoding](https://arxiv.org/pdf/2401.07851v3)

![](/files/uxHbOPW1fTypAymuu9DB)

在auto-regressive decoding的过程中先采用**更小的draft model猜词**，然后送给**target model并行验证**，以通过在**访存限制**的情况下充分利用算力，提升模型的推理效率；并且保证decoding的分布与target model一致；

整体流程如下：

![](/files/Y7LR5BQvqwLBrp2jBbz0)

* draft model一次性猜出未来的K个draft token，概率是p，采样的token 是x
* target model**并行**生成K+1个token，概率是q，即输入之前序列的和前n个draft token，预测下一个token
* 从1到k，逐个验证，
  * 如果verify(x,p,q)正确，直接用x
  * 否则，用correct(p,q)，把后面的draft token都扔掉

![](/files/Bx4KXkIikFlA2Z1Zk2Lx)

### 几篇比较早期的

[Fast Inference from Transformers via Speculative Decoding](https://arxiv.org/pdf/2211.17192)

<https://github.com/feifeibear/LLMSpeculativeSampling>

[Accelerating Large Language Model Decoding with Speculative Sampling](https://arxiv.org/pdf/2302.01318)

[SpecInfer: Accelerating Generative Large Language Model Serving with Tree-based Speculative Inference and Verification](https://arxiv.org/abs/2305.09781)

<https://github.com/flexflow/flexflow-train>

### EAGLE系列

[大模型推理效率无损提升3倍，滑铁卢大学、北京大学等机构发布EAGLE](https://mp.weixin.qq.com/s?__biz=MzA3MzI4MjgzMw==\&mid=2650900466\&idx=5\&sn=3d893e95cef725a7acbdab5763870c36\&scene=21#wechat_redirect)

[EAGLE: Speculative Sampling Requires Rethinking Feature Uncertainty](https://arxiv.org/pdf/2401.15077)

[无损加速最高5x，EAGLE-2让RTX 3060的生成速度超过A100](https://mp.weixin.qq.com/s?__biz=MzA3MzI4MjgzMw==\&mid=2650926594\&idx=5\&sn=fe8b52b499e3d3a3ef73a543e77385f1\&scene=21#wechat_redirect)

[EAGLE-2: Faster Inference of Language Models with Dynamic Draft Trees](https://arxiv.org/pdf/2406.16858)

<https://github.com/SafeAILab/EAGLE>

[大模型推理无损加速6.5倍！EAGLE-3碾压一切、延续Scaling Law能力](https://mp.weixin.qq.com/s/4cq9f-_eB4znXRPEpKYAkA)

[EAGLE-3: Scaling up Inference Acceleration of Large Language Models via Training-Time Test](https://arxiv.org/abs/2503.01840)

### prompt-lookup decoding & REST

<https://www.zhihu.com/question/3266943961/answer/28177009964>

prompt-lookup decoding：<https://github.com/apoorvumang/prompt-lookup-decoding>

[REST: Retrieval-Based Speculative Decoding](https://arxiv.org/abs/2311.08252)

<https://zhuanlan.zhihu.com/p/685234708>

### LayerSkip

[LayerSkip: Enabling Early Exit Inference and Self-Speculative Decoding](https://arxiv.org/pdf/2404.16710)

<https://github.com/facebookresearch/LayerSkip>

### DISTILLSPEC

[DISTILLSPEC: IMPROVING SPECULATIVE DECODING VIA KNOWLEDGE DISTILLATION](https://arxiv.org/pdf/2310.08461)

### Graph-Structured Speculative Decoding

[Graph-Structured Speculative Decoding](https://arxiv.org/pdf/2407.16207)

## 算子加速

### Triton

[天下苦英伟达久矣！PyTorch官方免CUDA加速推理，Triton时代要来？](https://mp.weixin.qq.com/s/6gkPA-xc7GsltM1Ywui_XQ)

### Mirage

[告别CUDA无需Triton！Mirage零门槛生成PyTorch算子，人均GPU编程大师？](https://mp.weixin.qq.com/s/M3WFt17QErAt46VuqkFjFQ)

### MPK

[舍弃CUDA编程！CMU等用几十行代码将LLM编译成巨型内核，推理延迟可降6.7倍](https://mp.weixin.qq.com/s/D3fYjn8YksswteQE05Ohbw)

[blog](https://zhihaojia.medium.com/compiling-llms-into-a-megakernel-a-path-to-low-latency-inference-cf7840913c17)

<https://github.com/mirage-project/mirage/tree/mpk>

## 总结

[藏在海量参数背后的系统工程：7家顶尖实验室大模型训练内参](https://mp.weixin.qq.com/s/16PcWOeShR8R8OSQOPZa7A?scene=1)

[frontier model training methodologies](https://djdumpling.github.io/2026/01/31/frontier_training.html)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.daiwk.net/1.3.llm_archs.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
