六、Accelerate + Deepspeed

帮up宣传一下,优质up值得信赖!

B站UP:你可是处女座啊
在这里插入图片描述

文章目录

  • 理论知识
    • DP&DDP
    • Deepspeed
      • 介绍
      • 注意事项
      • 多机多卡
  • 实战
    • ddp_accelerate.py
      • 原先显存
      • DDP 运行
      • Deepspeed 运行
        • 方式一-zero2
        • 方式二 -zero2
        • 方式一 -zero3
        • 方式二 -zero3
    • ddp_trainer.py
      • zero2
      • zero3
      • 注意事项

理论知识

https://huggingface.co/docs/accelerate/usage_guides/deepspeed

DP&DDP

image.png

Deepspeed

介绍

image.png
image.png
image.png
image.png
image.png

注意事项

image.png

多机多卡

image.png


实战

ddp_accelerate.py

  • ddp_accelerate.py
import time
import math
import torch
import pandas as pd

from torch.optim import Adam
from accelerate import Accelerator
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
from torch.utils.data import random_split
from peft import LoraConfig, get_peft_model
from transformers import BertTokenizer, BertForSequenceClassification


class MyDataset(Dataset):

    def __init__(self) -> None:
        super().__init__()
        self.data = pd.read_csv("./ChnSentiCorp_htl_all.csv")
        self.data = self.data.dropna()

    def __getitem__(self, index):
        return self.data.iloc[index]["review"], self.data.iloc[index]["label"]
    
    def __len__(self):
        return len(self.data)


def prepare_dataloader():

    dataset = MyDataset()

    trainset, validset = random_split(dataset, lengths=[0.9, 0.1], generator=torch.Generator().manual_seed(42))

    tokenizer = BertTokenizer.from_pretrained("rbt3")

    def collate_func(batch):
        texts, labels = [], []
        for item in batch:
            texts.append(item[0])
            labels.append(item[1])
        inputs = tokenizer(texts, max_length=128, padding="max_length", truncation=True, return_tensors="pt")
        inputs["labels"] = torch.tensor(labels)
        return inputs

    trainloader = DataLoader(trainset, batch_size=32, collate_fn=collate_func, shuffle=True)
    validloader = DataLoader(validset, batch_size=64, collate_fn=collate_func, shuffle=False)

    return trainloader, validloader


def prepare_model_and_optimizer():

    model = BertForSequenceClassification.from_pretrained("rbt3")

    lora_config = LoraConfig(target_modules=["query", "key", "value"])

    model = get_peft_model(model, lora_config)

    model.print_trainable_parameters()

    optimizer = Adam(model.parameters(), lr=2e-5, weight_decay=0.001)

    return model, optimizer


def evaluate(model, validloader, accelerator: Accelerator):
    model.eval()
    acc_num = 0
    with torch.no_grad():
        for batch in validloader:
            output = model(**batch)
            pred = torch.argmax(output.logits, dim=-1)
            pred, refs = accelerator.gather_for_metrics((pred, batch["labels"]))
            acc_num += (pred.long() == refs.long()).float().sum()
    return acc_num / len(validloader.dataset)


def train(model, optimizer, trainloader, validloader, accelerator: Accelerator, resume, epoch=3, log_step=10):
    global_step = 0
    start_time = time.time()

    resume_step = 0
    resume_epoch = 0

    if resume is not None:
        accelerator.load_state(resume)
        steps_per_epoch = math.ceil(len(trainloader) / accelerator.gradient_accumulation_steps)
        resume_step = global_step = int(resume.split("step_")[-1])
        resume_epoch = resume_step // steps_per_epoch
        resume_step -= resume_epoch * steps_per_epoch
        accelerator.print(f"resume from checkpoint -> {resume}")

    for ep in range(resume_epoch, epoch):
        model.train()
        if resume and ep == resume_epoch and resume_step != 0:
            active_dataloader = accelerator.skip_first_batches(trainloader, resume_step * accelerator.gradient_accumulation_steps)
        else:
            active_dataloader = trainloader
        for batch in active_dataloader:
            with accelerator.accumulate(model):
                optimizer.zero_grad()
                output = model(**batch)
                loss = output.loss
                accelerator.backward(loss)
                optimizer.step()

                if accelerator.sync_gradients:
                    global_step += 1

                    if global_step % log_step == 0:
                        loss = accelerator.reduce(loss, "mean")
                        accelerator.print(f"ep: {ep}, global_step: {global_step}, loss: {loss.item()}")
                        accelerator.log({"loss": loss.item()}, global_step)

                    if global_step % 50 == 0 and global_step != 0:
                        accelerator.print(f"save checkpoint -> step_{global_step}")
                        accelerator.save_state(accelerator.project_dir + f"/step_{global_step}")
                        accelerator.unwrap_model(model).save_pretrained(
                            save_directory=accelerator.project_dir + f"/step_{global_step}/model",
                            is_main_process=accelerator.is_main_process,
                            state_dict=accelerator.get_state_dict(model),
                            save_func=accelerator.save
                        )
        acc = evaluate(model, validloader, accelerator)
        accelerator.print(f"ep: {ep}, acc: {acc}, time: {time.time() - start_time}")
        accelerator.log({"acc": acc}, global_step)

    accelerator.end_training()


def main():

    accelerator = Accelerator(log_with="tensorboard", project_dir="ckpts")

    accelerator.init_trackers("runs")

    trainloader, validloader = prepare_dataloader()

    model, optimizer = prepare_model_and_optimizer()

    model, optimizer, trainloader, validloader = accelerator.prepare(model, optimizer, trainloader, validloader)

    train(model, optimizer, trainloader, validloader, accelerator, resume=None)


if __name__ == "__main__":
    main()

原先显存

image.png

DDP 运行

accelerate launch ddp_accelerate.py

image.png

Deepspeed 运行

pip install deepspeed

方式一-zero2

image.png

accelerate config 

image.png
image.png
image.pngimage.png
image.png

~/.cache/huggingface/accelerate/default_config.yaml
compute_environment: LOCAL_MACHINE
debug: false
deepspeed_config:
  gradient_accumulation_steps: 1
  offload_optimizer_device: none
  offload_param_device: none
  zero3_init_flag: false
  zero_stage: 2
distributed_type: DEEPSPEED
downcast_bf16: 'no'
machine_rank: 0
main_training_function: main
mixed_precision: bf16
num_machines: 1
num_processes: 2
rdzv_backend: static
same_network: true
tpu_env: []
tpu_use_cluster: false
tpu_use_sudo: false
use_cpu: false
  • 运行
accelerate launch --config_file default_config.yaml ddp_accelerate.py

image.png


方式二 -zero2

image.png
https://huggingface.co/docs/accelerate/usage_guides/deepspeed#deepspeed-config-file

  • default_config.yaml
compute_environment: LOCAL_MACHINE
debug: false
deepspeed_config:
  # gradient_accumulation_steps: 1
  # offload_optimizer_device: none
  # offload_param_device: none
  # zero3_init_flag: false
  # zero_stage: 2
  deepspeed_config_file: zero_stage2_config.json
  zero3_init_flag: false
distributed_type: DEEPSPEED
downcast_bf16: 'no'
machine_rank: 0
main_training_function: main
# mixed_precision: bf16 #注释掉
num_machines: 1
num_processes: 2
rdzv_backend: static
same_network: true
tpu_env: []
tpu_use_cluster: false
tpu_use_sudo: false
use_cpu: false
  • zero_stage2_config.json
{
    "bf16": {
        "enabled": true
    },
    "zero_optimization": {
        "stage": 2,
        "allgather_partitions": true,
        "allgather_bucket_size": 2e8,
        "overlap_comm": true,
        "reduce_scatter": true,
        "reduce_bucket_size": "auto",
        "contiguous_gradients": true
    },
    "gradient_accumulation_steps": 1,
    "gradient_clipping": "auto",
    "steps_per_print": 2000,
    "train_batch_size": "auto",
    "train_micro_batch_size_per_gpu": "auto",
    "wall_clock_breakdown": false
}
  • 运行
accelerate launch --config_file default_config.yaml ddp_accelerate.py
  • mixed_precision: bf16 需要注释掉,否则报错

image.png
image.png


方式一 -zero3
  • zero3
  • default_config.yaml
compute_environment: LOCAL_MACHINE
debug: false
deepspeed_config:
  gradient_accumulation_steps: 1
  offload_optimizer_device: none
  offload_param_device: none
  zero3_init_flag: false
  zero_stage: 3
  zero3_save_16bit_model: true
  # deepspeed_config_file: zero_stage2_config.json
  # zero3_init_flag: false
distributed_type: DEEPSPEED
downcast_bf16: 'no'
machine_rank: 0
main_training_function: main
mixed_precision: bf16 
num_machines: 1
num_processes: 2
rdzv_backend: static
same_network: true
tpu_env: []
tpu_use_cluster: false
tpu_use_sudo: false
use_cpu: false
  • 运行
accelerate launch --config_file default_config.yaml ddp_accelerate.py

image.png

  • 不加 zero3_save_16bit_model: true 训练正常,保存模型会报错

image.png

  • zero3_save_16bit_model: true 训练正常,保存模型正常,评估会报错
# 评估部分要使用 with torch.no_grad():,而不是with torch.inference_mode():

def evaluate(model, validloader, accelerator: Accelerator):
    model.eval()
    acc_num = 0
    with torch.no_grad():
        for batch in validloader:
            output = model(**batch)
            pred = torch.argmax(output.logits, dim=-1)
            pred, refs = accelerator.gather_for_metrics((pred, batch["labels"]))
            acc_num += (pred.long() == refs.long()).float().sum()
    return acc_num / len(validloader.dataset)

方式二 -zero3
  • default_config.yaml
compute_environment: LOCAL_MACHINE
debug: false
deepspeed_config:
  # gradient_accumulation_steps: 1
  # offload_optimizer_device: none
  # offload_param_device: none
  # zero3_init_flag: false
  # zero_stage: 3
  # zero3_save_16bit_model: true
  deepspeed_config_file: zero_stage3_config.json
  zero3_init_flag: false
distributed_type: DEEPSPEED
downcast_bf16: 'no'
machine_rank: 0
main_training_function: main
# mixed_precision: bf16 # 使用accelerate config 记得注释AMP
num_machines: 1
num_processes: 2
rdzv_backend: static
same_network: true
tpu_env: []
tpu_use_cluster: false
tpu_use_sudo: false
use_cpu: false
  • zero_stage3_config.json
{
    "bf16": {
        "enabled": true
    },
    "zero_optimization": {
        "stage": 3,
        "allgather_partitions": true,
        "allgather_bucket_size": 2e8,
        "overlap_comm": true,
        "reduce_scatter": true,
        "reduce_bucket_size": "auto",
        "contiguous_gradients": true,
        "stage3_gather_16bit_weights_on_model_save": true # 保存模型
    },
    "gradient_accumulation_steps": 1,
    "gradient_clipping": "auto",
    "steps_per_print": 2000,
    "train_batch_size": "auto",
    "train_micro_batch_size_per_gpu": "auto",
    "wall_clock_breakdown": false
}
  • 运行
accelerate launch --config_file default_config.yaml ddp_accelerate.py

image.png


ddp_trainer.py

# %% [markdown]
# # 文本分类实例

# %% [markdown]
# ## Step1 导入相关包

# %%
from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments, BertTokenizer, BertForSequenceClassification
from datasets import load_dataset

# %% [markdown]
# ## Step2 加载数据集

# %%
dataset = load_dataset("csv", data_files="./ChnSentiCorp_htl_all.csv", split="train")
dataset = dataset.filter(lambda x: x["review"] is not None)
dataset

# %% [markdown]
# ## Step3 划分数据集

# %%
datasets = dataset.train_test_split(test_size=0.1, seed=42)
datasets

# %% [markdown]
# ## Step4 数据集预处理

# %%
import torch

tokenizer = BertTokenizer.from_pretrained("/gemini/code/model")

def process_function(examples):
    tokenized_examples = tokenizer(examples["review"], max_length=128, truncation=True)
    tokenized_examples["labels"] = examples["label"]
    return tokenized_examples

tokenized_datasets = datasets.map(process_function, batched=True, remove_columns=datasets["train"].column_names)
tokenized_datasets

# %% [markdown]
# ## Step5 创建模型

# %%
model = BertForSequenceClassification.from_pretrained("/gemini/code/model")

# %%
model.config

# %% [markdown]
# ## Step6 创建评估函数

# %%
import evaluate

acc_metric = evaluate.load("./metric_accuracy.py")
f1_metirc = evaluate.load("./metric_f1.py")

# %%
def eval_metric(eval_predict):
    predictions, labels = eval_predict
    predictions = predictions.argmax(axis=-1)
    acc = acc_metric.compute(predictions=predictions, references=labels)
    f1 = f1_metirc.compute(predictions=predictions, references=labels)
    acc.update(f1)
    return acc

# %% [markdown]
# ## Step7 创建TrainingArguments

# %%
train_args = TrainingArguments(output_dir="./ckpts",      # 输出文件夹
                               per_device_train_batch_size=32,  # 训练时的batch_size
                               per_device_eval_batch_size=128,  # 验证时的batch_size
                               logging_steps=10,                # log 打印的频率
                               evaluation_strategy="epoch",     # 评估策略
                               save_strategy="epoch",           # 保存策略
                               save_total_limit=3,              # 最大保存数
                               bf16=True,
                               learning_rate=2e-5,              # 学习率
                               weight_decay=0.01,               # weight_decay
                               metric_for_best_model="f1",      # 设定评估指标
                               load_best_model_at_end=True)     # 训练完成后加载最优模型

# %% [markdown]
# ## Step8 创建Trainer

# %%
from transformers import DataCollatorWithPadding
trainer = Trainer(model=model, 
                  args=train_args, 
                  train_dataset=tokenized_datasets["train"], 
                  eval_dataset=tokenized_datasets["test"], 
                  data_collator=DataCollatorWithPadding(tokenizer=tokenizer),
                  compute_metrics=eval_metric)

# %% [markdown]
# ## Step9 模型训练

# %%
trainer.train()

zero2

accelerate launch --config_file default_config.yaml ddp_trainer.py

image.png

zero3

accelerate launch --config_file default_config.yaml ddp_trainer.py

image.png


注意事项

  • accelerate deepspeed 部分的 config 里面的参数(方式一)要和 hf trainer 中的参数保持一致,否则会报错

image.png

  • 使用 deepspeed config 文件(方式二)问题同上

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/801656.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在 Windows 上运行 Linux:WSL2 完整指南(一)

系列文章目录 在 Windows 上运行 Linux:WSL2 完整指南(一)🚪 在 Windows 上运行 Linux:WSL2 完整指南(二) 文章目录 系列文章目录前言一、什么是 WSL?1.1 WSL 的主要特性1.2 WSL 的…

[WUSTCTF2020]level4题解 入土为安的第三天

二叉树 Practice my Data Structure code..... Typing....Struct.....char....*left....*right............emmmmm...OK! Traversal! Traversal type 1:2f0t02T{hcsiI_SwA__r7Ee} Traversal type 2:20f0Th{2tsIS_icArE}e7__w Traversal type 3: //type3(&x[22]); No w…

Schematics,一个牛逼的python库用于数据验证和转换的库

目录 什么是Schematics? 为什么使用Schematics? 安装Schematics 定义模式 验证数据 自定义验证 转换数据 结语 什么是Schematics? 在Python的世界中,Schematics是一个用于数据验证和转换的库。它通过定义数据结构的模式(…

Windows搭建RTMP视频流服务器

参考了一篇文章,见文末。 博客中nginx下载地址失效,附上一个有效的地址: Index of /download/ 另外,在搭建过程中,遇到的问题总结如下: 1 两个压缩包下载解压并重命名后,需要 将nginx-rtmp…

轻松搞定GIS场景编辑,这款免费工具你一定要试试

如果你正苦恼于如何搞定GIS场景编辑,不妨来试试这款免费可视化工具——山海鲸可视化。经过本人测试,这款软件在GIS场景编辑上完全可以做到“零代码”操作,即使没有任何编程技能也可以在三维GIS世界中如鱼得水。现在,让我们一起来看…

美团收银Android一面凉经(2024)

美团收银Android一面凉经(2024) 笔者作为一名双非二本毕业7年老Android, 最近面试了不少公司, 目前已告一段落, 整理一下各家的面试问题, 打算陆续发布出来, 供有缘人参考。今天给大家带来的是《美团收银Android一面凉经(2024)》。 应聘岗位: 美团餐饮PaaS平台Android开发工程师…

Docker 基本管理及部署

目录 1.Docker概述 1.1 Docker是什么? 1.2 Docker的宗旨 1.3 容器的优点 1.4 Docker与虚拟机的区别 1.5 容器在内核中支持的两种技术 1.6 namespace的六大类型 2.Docker核心概念 2.1 镜像 2.2 容器 2.3 仓库 3.安装Docker 3.1 查看 docker 版本信息 4.…

【嵌入式DIY实例-ESP8266篇】-LCD ST7789显示DS1307 RTC时间数据

LCD ST7789显示DS1307 RTC时间数据 文章目录 LCD ST7789显示DS1307 RTC时间数据1、硬件准备与接线2、代码实现本文将介绍如何使用 ESP8266 NodeMCU 板和 DS1307 RTC 集成电路构建简单的实时时钟和日历 (RTCC),其中时间和日期打印在 ST7789 TFT 显示模块上。 ST7789 TFT 模块包…

C# 基于共享内存实现跨进程队列

C# 进程通信系列 第一章 共享内存 第二章 共享队列(本章) 文章目录 C# 进程通信系列前言一、实现原理1、用到的主要对象2、创建共享内存3、头部信息4、入队5、出队6、释放资源 二、完整代码三、使用示例1、传输byte[]数据2、传输字符串3、传输对象 总结…

持续集成03--Jenkins的安装与配置

前言 在持续集成/持续部署(CI/CD)的实践中,Jenkins作为一个开源的自动化服务器,扮演着至关重要的角色。本篇“持续集成03--Jenkins的安装配置”将带您走进Jenkins的世界,深入了解如何在Linux环境中安装并配置Jenkins。…

window下安装go环境

一、go官网下载安装包 官网地址如下:https://golang.google.cn/dl/ 选择对应系统的安装包,这里是window系统,可以选择zip包,下载完解压就可以使用 二、配置环境变量 这里的截图配置以win11为例 我的文件解压目录是 D:\Software…

web自动化测试selenium的基本使用

目录 初始化浏览器并打开网页 定位网页元素 定位的方法 模拟键盘操作 模拟鼠标操作 xpath方法 xpath结点 路径表达式 轴 selenium是一个很流行的自动化测试的库,主要用于模拟浏览器的运行,是web应用测试的工具。 在使用selenium时,…

C++基础篇(2)

目录 前言 1.缺省参数 2.函数重载 2.1函数重载的基本规则 ​编辑2.2注意事项 2.3 重载解析(Overload Resolution)--补充内容 3.引用 3.1引用的概念和定义 3.2引用的特性 3.3引用的使用 3.4const引用 4.指针和引用的关系 结束语 前言 上节小编…

16_Shell好用工具:sed

16_Shell好用工具:sed 零、语法解析 sed [选项参数] [模式匹配/sed命令] 文件 命令说明aadd,新增iinsert,新增cchange,修改ssubstitute,替换ddelete,删除pprint, 打印 通常与 -n 连用 一、增(…

【JavaScript】聊一聊js中的浅拷贝与深拷贝与手写实现

前言 什么是深拷贝与浅拷贝?深拷贝与浅拷贝是js中处理对象或数据复制操作的两种方式。‌在聊深浅拷贝之前咱得了解一下js中的两种数据类型: 基本数据类型(6种)String、Number、Object、Boolean、null、undefined、symbol&#xff…

数据结构——线性表(C语言实现)

写在前面: 在前面C语言的结构体学习中,我提及了链表的操作, 学习数据结构我认为还是需要对C语言的数组、函数、指针、结构体有一定的了解,不然对于结构体的代码可能很难理解,特别是一些书籍上面用的还是伪代码&#xf…

Day07-员工管理-上传下载

1.员工管理-导出excel 导出员工接口返回的是二进制axios配置responseType为blob接收二进制流文件为Blob格式按装file-saver包,实现下载Blob文件npm install add file-saver导出员工excel的接口 (src/api/employee.js) export function exportEmployee(){return req…

普通人还有必要学习 Python 之类的编程语言吗?

在开始前分享一些编程的资料需要的同学评论888即可拿走 是我根据网友给的问题精心整理的对于编程的重要性,这里就不详谈了。 未来,我们和机器的交流会越来越多,编程可以简单看作是和机器对话并分发给机器任务。机器不仅越来越强大&#xff0…

芯课堂 | Synwit_UI_Creator(ugui)平台之PC端界面设计篇

​今天小编给大家介绍的是华芯微特面向小尺寸TFT-LCD屏驱市场量身打造的Synwit_UI_Creator(ugui)自研开发套件。 UI_Creator(ugui)开发套件分为上位机和下位机,以下如无特指,上位机即为PC端设计器/仿真器&…

【香橙派AiPro】基于VGG16的火灾检测模型预测

目录 引言开发板介绍开发板使用准备工作工具文档 拨码开关镜像烧录连接开发板下载MobaXterm网线-SSH连接开发板设置WIFI连接WIFI-SSH连接开发板确定开发板IP方法 Vnc可视化WindowsiPad 开发工具安装 散热风扇基于VGG16的火灾检测模型预测数据集准备目录结构代码操作 安装宝塔最…