llm-action Documentation

本项目旨在分享大模型相关技术原理以及实战经验(大模型工程化、大模型应用落地)

25,186 stars HTML HTML 207 files · ~96,395 tokens #llm#llm-inference#llm-serving#llm-training#llmops
RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy llm-action on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name llm-action --restart always liguodongiot/llm-action:latest

File: ai-compiler/Treebeard/README.md

Treebeard: An Optimizing Compiler for Decision Tree Based ML Inference

流程

输入一个决策树数据结构,compiler通过一系列 IR 转化,将决策树数据结构转化为对CPU来说更加友好的数据结构,从而加速决策树上的推理过程。然后,因为自己有关于决策树的domain knowledge,因此在做codegen比如循环展开,循环交换的时候,可以选择到更好的codegen方式。整个项目基于MLIR实现,因此一些简单的优化比如使用 OpenMP 做并行,可以直接用MLIR。

图片

TREEBEARD IR lowering 和 optimization 细节

显示了 TREEBEARD IR 中的三个抽象级别。 高级 IR 是基于树的 IR,用于执行模型级优化,中级 IR 用于独立于内存布局的循环优化,低级 IR 允许我们执行向量化和其他与内存布局相关的优化。

Figure 6: Sparse representation with tile size nt = 3. Leaves l4, l5, l6 and l7 are moved into the leaves array. Extra hops are added for l1, l2 and l3 as T2 is a non-leaf tile. The new leaves added as children of l1, l2 and l3 are moved to the leaves array.

Figure 9: Geomean speedup (over all benchmarks) of TREEBEARD over XGBoost and Treelite on single-core over several batch sizes.

Table I: List of benchmark datasets and their parameters. The column Leaf-biased reports the number of leaf-biased trees per benchmark with 〈α = 0.075,β = 0.9〉 .

Table II: Space of optimizations explored.


File: ai-compiler/treelit/README.md

text
conda create -n model-inference-venv python=3.9 -y


conda activate model-inference-venv

File: ai-compiler/README.md

树模型编译器

Treelite是用于有效部署决策树集合的模型编译器。

深度学习编译器

深度学习编译原理

AI 编译器前端优化

前端优化作为AI编译器的整体架构主要模块,主要优化的对象是计算图,而计算图是通过AI框架产生的,值得注意的是并不是所有的AI框架都会生成计算图,有了计算图就可以结合深度学习的原理知识进行图的优化。

  • 计算图层(Graph IR)
  • 算子融合(OP Fusion)
  • 布局转换(Layout Transform)
  • 内存分配(Memory Allocation)
  • 常量折叠(Constant Fold)
  • 公共子表达式消除(CSE)
  • 死代码消除(DCE)
  • 代数简化(ARM)

AI 编译器后端优化

后端优化作为AI编译器跟硬件之间的相连接的模块,更多的是算子或者Kernel进行优化,而优化之前需要把计算图转换称为调度树等IR格式,然后针对每一个算子/Kernel进行循环优化、指令优化和内存优化等技术。

  • 算子循环优化
  • 指令和内存优化

深度学习编译工具

TVM

XLA

Glow

深度学习编译优化

计算图优化:XLA、TVM、nGraph

算子生成:AutoTVM、TC、Halide

图优化

目标:通过图的等价变换化简计算图,从而降低计算复杂度或内存开销。

数据流图作为深度学习框架中的高层中间表示,可以允许任何等价图优化Pass去化简计算流图或提高执行效率

图优化 (1):算术表达式化简

通过代数运算等价变换化简计算图,如:

text
a * 0 -> 0
a * broadcast(0) ->  broadcast(0)
a * 1 -> a
a * broadcast(1)-> a
a + 0 -> a
a + broadcast(O)-> a
log(exp(x)/y)->x-log(y)

图优化 (2):公共子表达式消除

目的是将相同输入的表达式进行消除,由一个节点来代替,复用计算结果

图优化 (3):常数传播

如果一个算子的所有输入张量都是常数的话,那么该算子的结果也为常数张量

在编译器计算并化简

例子:假设参数0和参数1为常数张量,最终的图可以化简为什么?

注意:常数传播可能会引起内存的扩张,如:Broadcast

图优化 (4): GEMM自动融合

Batch same-type operators to leverage GPU massive parallelism

图优化 (4): GEMM自动融合

通过将输入张量合并成一个大的张量来实现将相同的算子合并成一个更大的算子,从而更好的利用硬件并行度

图优化(5):算子融合

向量化的多个算子的操作可以合并成一个向量化操作

减少内核启动开销

减少内存的读取,提高计算密度

图优化 (6):子图替换

利用子图匹配识别出可替换的复杂子图,替换为更高效的合并算子

图优化 (6):随机子图替换

TASO: Optimizing Deep Learning Computation with Automatic Generation of Graph Substitutions

小结: 图优化的总结

计算图作为深度学习编译框架的第一层中间表示

text
基于计算图的优化算法:
   算术表达式化简
   公共子表达式消除
   常数传播
   矩阵合并
   算子融合
   子图替换/随机子图替换

思考:
   你可以想到哪些其它的计算图上的优化?
   计算图还有哪些其它的好处

内存优化

内存优化

目标:通过对计算图的变化以及张量的合理分配来降低内存使用的总量。

内存优化 (1):基于拓扑序的最小内存分配

将计算流图按照某种拓扑序进行排序。如BFS,ReverseDFS等

按照节点的拓扑顺序依次分配其使用到的输出张量。

当一个张量后面没有其它算子使用时, 则回收到内存池。

当所有张量分配完成后,内存池的最大分配空间就是该计算图需要的最小内存

拓扑序的选择会同时影响模型的计算时间和最大内存占用

内存优化 (2):根据整数线性规划求解最优内存放置

text
目标:给定任意的计算图最小化执行时间
约束:有限的快速内存,如GPU内存
变量:每一个张量是否放置在快速内存中,还是较慢的外存中,如CPU内存
过程:最优化张量的移动                                                             
需求:每个内核计算的测量时间 
方法:将上述的优化问题建模为整数线性规划问题

内存优化 (3):张量换入换出与张量重计算

text
方法:
DRAM存储量相对GPU显存来说比较大,可以将数据在GPU与DRAM之间进行转移,或者直接重新计算

发现:
在训练过程中张量的访问模式比较规律

核心思想
根据运行时的张量访问来动态管理内存
替换+预取
重新计算

小结: 内存优化的总结

·基于计算图的内存优化算法:
基于拓扑序的最小内存分配
根据整数线性规划求解最优内存放置张量换入换出与张量重计算
·思考:
你可以想到哪些其它的内存优化方法?

内核优化

问题: 每个后端平台针对每个算子都需要单独实现至少一个内核

考虑:编程模型、数据排布、线程模型、缓存大小等等

张量运算编译

text
核心思想:分离计算逻辑与调度逻辑
    通过张量运算表达式表示每个算子的通用计算逻辑
    通过调度语言描述算子在映射到具体硬件上时的调度空间



相关工作:
TVM、 Halide、 TACO、 Tensor Comprehension, FlexTensor等

张量运算表达式:例:TVMIR

C=A*B
C= tvm.compute((m,n),lambda i,j:tvm.sum(A[i,k] * B[k,j], axis=k)

其它张量运算表达式

text
Affine Transformation

out = tvm.compute((n,m),lambda i, j: tvm.sum(data[i, k] * w[j, k], k))
out = tvm.compute((n,m),lambda i, j: out[i, j]十bias[i])

Convolution
out=tvm.compute(c, h, w), lambda i, x, y: tvm.sum(data[kc,x+kx,y+ky] * w[i, kx, ky], [kx, ky, kc]))


ReLu
out = tvm.compute(shape, lambda *i: tvm.max(0, out(*i))

其它算子调度优化

每一种优化都可能产生出多个内核代码的实现

利用自动机器学习 Auto Tuner 在给定时间内搜索出最高效的实现

小结: 内核优化的总结

内核优化与内核生成

算子表达式
算子表示与调度逻辑的分离
自动调度搜索与代码生成

调度优化

NNFusion:全局计算调度优化

目标:通过将多个算子进行协同调度以及精确映射每一个算子到硬件计算单元来充分利用硬件并行度

中间表示:数据流图+细粒度算子并行单元

结果:将每个子图编译成一个硬件计算内核

充分减少上层调度的开销

高效利用硬件并行度

通过引出新的调度原语来支持任务级调度

APEEND: 将一个算子中的一个任务调度到硬件的一个计算单元上

GROUP_SYNC: 维护任务间的依赖关系

text
挑战:调度算子的任务到GPU上的挑战

简单的任务级调度可能引起正确性问题
- 错误依赖
- 死锁



依赖关系的映射

通过将硬件计算单元抽象到软件可控计算单元,并引入细粒度任务级同步支持来保证计算正确性。



并行度的映射

任务级调度可以支持任意算子之间的并行调度,从而最大化硬件利用率。
text
本次课程总结

深度神经网络编译器的概念与架构
	中间表达、前端、后端、优化过程

计算图优化
   算术表达式化简、 公共子表达式消除、 常数传播、矩阵合并、 算子融合、 子图替换/随机子图替换
内存优化
   基于拓扑序的最小内存分配、 根据整数线性规划求解最优内存放置、 张量换入换出与张量重计算
内核优化
   算子表达式、  算子表示与调度逻辑的分离、  自动调度搜索与代码生成
调度优化

File: ai-framework/deepspeed/config-json/README.md

Batch Size 相关的参数

train_batch_size 必须等于 train_micro_batch_size_per_gpu * gradient_accumulation * gpu数量

train_batch_size

train_micro_batch_size_per_gpu

gradient_accumulation_steps

在平均和应用梯度之前进行累积梯度的训练step数。

此功能有时对于提高可扩展性很有用,因为它会降低step之间梯度通信的频率。

此功能的另一个影响是能够在每个 GPU 上使用更大的批量大小进行训练。

Optimizer 参数

Adam 优化器示例:

text
"optimizer": {
    "type": "Adam",
    "params": {
      "lr": 0.001,
      "betas": [
        0.8,
        0.999
      ],
      "eps": 1e-8,
      "weight_decay": 3e-7
    }
  }

参数:

  • torch_adam: Use torch’s implementation of adam instead of our fused adam implementation , 默认为false

Scheduler 参数

当执行 model_engine.step() 时,DeepSpeed 在每个训练步骤调用 scheduler 的 step() 方法。

  • type:学习率调度器名,DeepSpeed 提供了 LRRangeTest、OneCycle、WarmupLR、WarmupDecayLR 学习率调度器的实现。
  • params:用于实例化调度器的参数字典。参数名称应与调度程序构造函数签名匹配。

scheduler 示例:

text
"scheduler": {
      "type": "WarmupLR",
      "params": {
          "warmup_min_lr": 0,
          "warmup_max_lr": 0.001,
          "warmup_num_steps": 1000
      }
  }

通讯选项

communication_data_type

prescale_gradients

gradient_predivide_factor

sparse_gradients

FP16 训练选项

  • 注意:此模式不能与下述 amp 模式结合使用。
text
"fp16": {
    "enabled": true,
    "auto_cast": false,
    "loss_scale": 0,
    "initial_scale_power": 16,
    "loss_scale_window": 1000,
    "hysteresis": 2,
    "consecutive_hysteresis": false,
    "min_loss_scale": 1
}

BFLOAT16 训练选项

  • 注意:此模式不能与下述amp模式结合使用。
  • 注意:该模式不能与上述fp16模式结合使用。

使用 bfloat16 浮点格式作为 FP16 替代方案。

BFLOAT16 需要硬件支持(例如:NVIDIA A100)。

使用 bfloat16 进行训练不需要损失缩放。

示例如下所示。

text
"bf16": {
   "enabled": true
 }

自动混合精度 (AMP) 训练选项

注意:该模式不能与上述fp16模式结合使用。 此外,该模式目前与 ZeRO 不兼容。

text
"amp": {
    "enabled": true,
    ...
    "opt_level": "O1",
    ...
}

梯度裁剪(Gradient Clipping)

  • gradient_clipping

针对 FP16 训练的 ZeRO 优化

参数卸载(Parameter offloading)

启用和配置 ZeRO 优化,将参数卸载到 CPU/NVMe。 仅适用于 ZeRO 阶段 3。

  • 注意,如果"device"的值未指定或不支持,则会触发断言。
text
"offload_param": {
    "device": "[cpu|nvme]",
    "nvme_path": "/local_nvme",
    "pin_memory": [true|false],
    "buffer_count": 5,
    "buffer_size": 1e8,
    "max_in_cpu": 1e9
  }

优化器卸载

启用和配置 ZeRO 优化,将优化器计算卸载到 CPU 并将优化器状态卸载到 CPU/NVMe。

CPU 卸载适用于 ZeRO 阶段 1、2、3。NVMe 卸载仅适用于 ZeRO 阶段 3。

  • 注意,如果"device"的值未指定或不支持,则会触发断言。
text
"offload_optimizer": {
    "device": "[cpu|nvme]",
    "nvme_path": "/local_nvme",
    "pin_memory": [true|false],
    "buffer_count": 4,
    "fast_init": false
  }

Activation Checkpointing

text
"activation_checkpointing": {
    "partition_activations": false,
    "cpu_checkpointing": false,
    "contiguous_memory_optimization": false,
    "number_checkpoints": null,
    "synchronize_checkpoint_boundary": false,
    "profile": false
    }

稀疏注意力(Sparse Attention)

text
"sparse_attention": {
 "mode": "fixed",
 "block": 16,
 "different_layout_per_head": true,
 "num_local_blocks": 4,
 "num_global_blocks": 1,
 "attention": "bidirectional",
 "horizontal_global_attention": false,
 "num_different_global_patterns": 4,
 "num_random_blocks": 0,
 "local_window_blocks": [4],
 "global_block_indices": [0],
 "global_block_end_indices": None,
 "num_sliding_window_blocks": 3
}

Logging

steps_per_print

wall_clock_breakdown

dump_state

Flops 分析器(Flops Profiler)

  • detailed:是否打印详细的模型配置。
  • output_file:输出文件的路径。 如果没有,Profiler 将打印到标准输出。
text
{
  "flops_profiler": {
    "enabled": false,
    "profile_step": 1,
    "module_depth": -1,
    "top_modules": 1,
    "detailed": true,
    "output_file": null,
    }
}

监控模块(TensorBoard、WandB、CSV)

tensorboard

TensorBoard配置示例:

text
"tensorboard": {
    "enabled": true,
    "output_path": "output/ds_logs/",
    "job_name": "train_bert"
}

压缩(Compression)

Layer Reduction

权重量化(Weight Quantization)

激活量化(Activation Quantization)

稀疏剪枝(Sparse Pruning)

头剪枝(Head Pruning)

通道剪枝(Channel Pruning)

Checkpoint 选项

text
"checkpoint": {
    "tag_validation"="Warn",
    "load_universal"=false,
    "use_node_local_storage"=false,
    "parallel_write":{
        "pipeline_stage": false
    }
}

数据类型选项

text
"data_types": {
    "grad_accum_dtype"=["fp32"|"fp16"|"bf16"]
    }
}

Data Efficiency


File: ai-framework/deepspeed/hello_bert/README.md

HelloDeepSpeed

HF

text
model = create_model(
        num_layers=num_layers,
        num_heads=num_heads,
        ff_dim=ff_dim,
        h_dim=h_dim,
        dropout=dropout,
    )
model.train()

for step, batch in enumerate(data_iterator, start=start_step):
    optimizer.zero_grad()
    # Forward pass
    loss = model(**batch)
    # Backward pass
    loss.backward()
    # Optimizer Step
    optimizer.step()

运行命令:

text
python train_bert.py --checkpoint_dir ./experiments --local_rank 0

模型输出权重文件:

text
tree experiments/
experiments/
└── bert_pretrain.2023.6.13.5.34.39.addjtvxg
    ├── checkpoint.iter_1000.pt
    ├── checkpoint.iter_2000.pt
    ├── checkpoint.iter_3000.pt
    ├── checkpoint.iter_4000.pt
    ├── checkpoint.iter_5000.pt
    ├── checkpoint.iter_6000.pt
    ├── checkpoint.iter_7000.pt
    ├── checkpoint.iter_8000.pt
    ├── checkpoint.iter_9000.pt
    ├── gitdiff.log
    ├── githash.log
    ├── hparams.json
    └── tb_dir
        └── events.out.tfevents.1686659679.ai-app-2-46.54673.0

Deepspeed+HF

text
model = create_model(
        num_layers=num_layers,
        num_heads=num_heads,
        ff_dim=ff_dim,
        h_dim=h_dim,
        dropout=dropout,
    )
model, _, _, _ = deepspeed.initialize(model=model,
                                          model_parameters=model.parameters(),
                                          config=ds_config)
model.train()
for step, batch in enumerate(data_iterator, start=start_step):
    # Forward pass
    loss = model(**batch)
    # Backward pass
    model.backward(loss)
    # Optimizer Step
    model.step()

运行命令及模型输出权重文件:

text
# 默认使用当前服务器所有GPU卡
deepspeed train_bert_ds.py --checkpoint_dir ./experiments_ds

tree experiments_ds/
experiments_ds/
└── bert_pretrain.2023.6.13.18.58.44.addjtvxg
    ├── gitdiff.log
    ├── githash.log
    ├── global_step1000
    │   ├── mp_rank_00_model_states.pt
    │   ├── zero_pp_rank_0_mp_rank_00_optim_states.pt
    ...
    │   └── zero_pp_rank_7_mp_rank_00_optim_states.pt
    ├── global_step9000
    │   ├── mp_rank_00_model_states.pt
    │   ├── zero_pp_rank_0_mp_rank_00_optim_states.pt
    ...
    │   └── zero_pp_rank_7_mp_rank_00_optim_states.pt
    ├── hparams.json
    ├── latest
    ├── tb_dir
    │   └── events.out.tfevents.1686707924.ai-app-2-46.599.0
    └── zero_to_fp32.py



deepspeed --include localhost:2,3,4,5 train_bert_ds.py --checkpoint_dir ./experiments_multigpu --num_iterations=500 --checkpoint_every=250

tree -h ./experiments_multigpu
./experiments_multigpu
├── [  36]  bert_pretrain.2023.6.13.19.37.59.addjtvxg
│   └── [  63]  global_step250
│       └── [ 47M]  zero_pp_rank_3_mp_rank_00_optim_states.pt
└── [ 169]  bert_pretrain.2023.6.13.19.38.0.addjtvxg
    ├── [ 45K]  gitdiff.log
    ├── [  41]  githash.log
    ├── [ 207]  global_step250
    │   ├── [ 31M]  mp_rank_00_model_states.pt
    │   ├── [ 47M]  zero_pp_rank_0_mp_rank_00_optim_states.pt
    │   ├── [ 47M]  zero_pp_rank_1_mp_rank_00_optim_states.pt
    │   └── [ 47M]  zero_pp_rank_2_mp_rank_00_optim_states.pt
    ├── [ 298]  hparams.json
    ├── [  14]  latest
    ├── [  77]  tb_dir
    │   └── [2.4K]  events.out.tfevents.1686710280.ai-app-2-46.14672.0
    └── [ 18K]  zero_to_fp32.py

File: ai-framework/deepspeed/training/pipeline_parallelism/README.md

text
deepspeed --include localhost:3,4,5,6 train.py --deepspeed_config=ds_config.json -p 2 --steps=200

File: ai-framework/deepspeed/README.md


File: ai-framework/huggingface-accelerate/README.md

text
accelerate env 

# 
accelerate config default [arguments]



accelerate config update --config_file

huggingface 加载大模型

text
import torch
from transformers import AutoModelForCausalLM
​
checkpoint = "facebook/opt-13b"
model = AutoModelForCausalLM.from_pretrained(
    checkpoint, device_map="auto", offload_folder="offload", offload_state_dict = True, torch_dtype=torch.float16
)