ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

如何用 annotated_deep_learning_paper_implementations 的 Zero3 显存优化微调 GPT-NeoX 小模型

如何用 annotated_deep_learning_paper_implementations 的 Zero3 显存优化微调 GPT-NeoX 小模型 如何用 annotated_deep_learning_paper_implementations 的 Zero3 显存优化微调 GPT-NeoX 小模型【免费下载链接】annotated_deep_learning_paper_implementations‍ 60 Implementations/tutorials of deep learning papers with side-by-side notes ; including transformers (original, xl, switch, feedback, vit, ...), optimizers (adam, adabelief, sophia, ...), gans(cyclegan, stylegan2, ...), reinforcement learning (ppo, dqn), capsnet, distillation, ... 项目地址: https://gitcode.com/gh_mirrors/an/annotated_deep_learning_paper_implementationsannotated_deep_learning_paper_implementationslabml-nn提供了一套 Zero-DP 显存优化实现代码里叫Zero3可以把 GPT-NeoX 的参数、梯度和优化器状态切分到多张 GPU 上从而在显存装不下整模型时仍能做多卡微调。本文的任务就是在多张 CUDA GPU 上用仓库里的 finetune_neox.py 脚本借助 Zero-DP 优化器对 GPT-NeoX 做偏差参数bias微调并用filter_layers把模型缩到只加载部分层的小模型。前提是你有可用的多张 NVIDIA GPU 和 NCCL 支持并且本地已经拿到 GPT-NeoX 的 checkpoint 文件。环境与前提先安装库依赖。仓库 readme.md 给出的安装方式是pip install labml-nn除了依赖还要满足三个前提缺任一项脚本都跑不起来多张 CUDA GPU NCCL。脚本用torch.distributed.init_process_group(nccl, ...)组建进程组每个 rank 绑定一张cuda:{rank}。脚本启动时会打印nccl可用性需要先确认是True。GPT-NeoX checkpoint 文件已就位。层权重从本地数据路径加载见 checkpoint.py加载用的是torch.load不会自动下载。该模块提供了download()其__main__会执行download()默认n_layers44用于拉取这些文件。训练文本会自动下载。text_dataset.py 首次运行会下载tiny_shakespeare语料这块不用手动准备。微调的对象是bias 参数。finetune.py 里FineTuneBiases把每个TransformerLayer整层设成requires_gradFalse再单独放开attention.output.bias、attention.qkv_lin.bias、ffn.dense_h_h4.bias三个 bias 让它们可训练。这正好对应 Zero3 文档里“只实现 Zero-DP、支持只训练一部分参数”的说明。用 Zero-DP 包住 GPT-NeoX 的每一层脚本的 finetune_neox.html 文档里模型和 optimizer 各用一个option覆盖option(Configs.model, Zero3) def _model(c: Configs): from labml_nn.scaling.zero3 import Zero3Layer, Zero3Sequential _ c.fine_tuner # 确保 fine tuner 先把可训练参数设好 modules [] for m in monit.iterate(Zero3, c.layers): modules.append(Zero3Layer(m.to(c.device), c.rank, c.world_size, c.device, c.dtype)) model Zero3Sequential(modules) return model option(Configs.optimizer, Zero3Adam) def _optimizer(c: Configs): from labml_nn.optimizers.adam_fp16 import AdamFP16 return AdamFP16(c.model.get_trainable_chunk(), lrc.learning_rate)这里要做两件事逐层包装c.layers是 GPT-NeoX 的各层每层被Zero3Layer包住再一起塞进Zero3Sequential。zero3 实现 中Zero3Layer在__init__里把该层的可训练/固定参数合并、按world_size切分并scatter到各设备然后resize_(0)释放本地完整参数的显存Zero3Sequential再为所有层挂上fetch_stream、backup_stream以及前/后层指针。只把分片喂给优化器get_trainable_chunk()返回的是当前 rank 上那一份可训练 shardAdamFP16只对这一份分片维护状态而不是完整参数。这就是 Zero-DP 省显存的来源。index.html 给出的公式是显存降到原模型的(2 2 K)·Ψ / N_d其中Ψ是参数量、N_d是分片数、K是每参数的优化器字节数2 2指 16-bit 的参数与梯度Adam 下K 12fp32 参数副本 两个 fp32 动量。对应地通信量是O(3Ψ)而普通数据并行是O(2Ψ)。这是文档给出的期望关系不是某次跑出来的固定数值实际占用随层数与N_d变化。缩小模型只加载部分层filter_layers默认Configs继承自 PipelineParallelTrainerConf会加载全部 44 层。要跑“小模型”用 model.py 里LayerGenerator的filter_layers参数——文档原文说明它是“用来测试只有更少层的更小模型版本”并给了{0, 1}这种“只加载前两层”的示例见 generate 文档。配置里c.layers由filter_layers透传进LayerGenerator(...).load()所以可以直接在配置里指定一个子集例如只加载前两个 transformer 层# 在 experiment.configs 的字典里追加这一项把模型缩到只有指定层 filter_layers: {0, 1}不写filter_layers或为None时加载全部层写成set时只加载集合里索引对应的层层数越少显存越小。注意filter_layers只影响加载哪些已存在的层文件这些层的 checkpoint 文件仍需先在本地见上一节的download()。配置项与启动方式脚本在 finetune_neox.py 里用experiment.configs灌入运行时参数experiment.configs(conf, { model: Zero3, optimizer: Zero3Adam, device: device, rank: rank, world_size: world_size, learning_rate: 3e-4, max_seq_len: 128, batch_size: 16, })其中model/optimizer选中的是上面两个optionZero3、Zero3Adamdevice、rank、world_size在main里按当前进程填好learning_rate、max_seq_len、batch_size是脚本选定的训练值覆盖基类默认epochs沿用TrainerConf默认 16需要小模型时在此字典里加filter_layers: {0, 1}。多卡启动由torch.multiprocessing.spawn负责脚本对本机每张 GPU 起一个进程n_gpu torch.cuda.device_count() # 每张 GPU 起一个进程跨多台机器需要额外的 launcher torch.multiprocessing.spawn(main, args(n_gpu,), nprocsn_gpu, joinTrue)于是world_size就等于本机 GPU 数rank是spawn的下标0 .. n_gpu-1。每个进程在main里先初始化分布式、再绑定cuda:{rank}torch.distributed.init_process_group(nccl, timeoutdatetime.timedelta(seconds30), init_methodinit_method, # 默认 tcp://localhost:23456 rankrank, world_sizeworld_size) device torch.device(fcuda:{rank}) torch.cuda.set_device(device)文档明确提醒本机一卡一进程用spawn即可跨多台机器时需要另外的 launcher——默认脚本不覆盖多机场景。判断运行是否正常按顺序看这几个信号即可确认 Zero-DP 微调真的在多卡上跑起来启动配置日志。脚本入口会用inspect打印每张 GPU 名称、n_gpus、mpi、nccl。先确认nccl为True、n_gpus与你的卡数一致——否则 NCCL 进程组建不起来。Distributed段完成。init_process_group(nccl)成功、随后逐层构建Zero3Layer模型脚本特意在进训练循环前触发conf.model为了让日志更清晰。每个 step 有 loss/acc 记录。训练循环走 trainer.py 的train_epoch()tracker每步记录loss.train、acc.train本脚本writers{screen, labml}即屏幕和 labml 面板都能看到 loss 随 step 变化。显存按分片占用。每张卡只保留自己那份 shard文档给出的期望占用是(2 2 K)·Ψ / N_d卡数越多单卡占用越低。看到 NCCL 可用、Distributed段跑完、loss.train随 step 更新即说明多卡 Zero-DP 微调成功运行显存是否低于普通数据并行可用你机器上的实际占用对照上面的公式判断而不是去比对某个固定数字。这套实现的边界用之前先认清 index.html 明确写出的限制虽然名字叫Zero3只实现了 Zero-DP 部分没有实现针对残余显存的 Zero-R 优化。支持只训练一部分参数——这也决定了它天然贴合“只调 bias”这种场景而不是全参训练。通信量O(3Ψ)高于普通数据并行的O(2Ψ)多卡间有额外通信开销。必须NCCL一卡一进程用spawn即可多机要自备 launcher。把filter_layers调小、world_size调大是仓库文档给出、且都落到当前脚本上的两个直接手段前者减少要切分的层数后者增加分片数从而摊薄单卡显存。【免费下载链接】annotated_deep_learning_paper_implementations‍ 60 Implementations/tutorials of deep learning papers with side-by-side notes ; including transformers (original, xl, switch, feedback, vit, ...), optimizers (adam, adabelief, sophia, ...), gans(cyclegan, stylegan2, ...), reinforcement learning (ppo, dqn), capsnet, distillation, ... 项目地址: https://gitcode.com/gh_mirrors/an/annotated_deep_learning_paper_implementations创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表