用huggingface.Accelerate进行分布式训练

news2025/1/13 13:41:10

诸神缄默不语-个人CSDN博文目录

本文属于huggingface.transformers全部文档学习笔记博文的一部分。
全文链接:huggingface transformers包 文档学习笔记(持续更新ing…)

本部分网址:https://huggingface.co/docs/transformers/main/en/accelerate
本文介绍如何使用huggingface.accelerate(官方文档:https://huggingface.co/docs/accelerate/index)进行分布式训练。

此外还参考了accelerate的安装文档:https://huggingface.co/docs/accelerate/basic_tutorials/install

一个本文代码可用的Python环境:Python 3.9.7, PyTorch 2.0.1, transformers 4.31.0, accelerate 0.22.0

parallelism能让我们实现在硬件条件受限时训练更大的模型,训练速度能加快几个数量级。

文章目录

  • 1. 安装与配置
  • 2. 在代码中使用

1. 安装与配置

安装:pip install accelerate

配置:accelerate config
然后它会给出一些问题,通过上下键更换选项,用Enter确定
在这里插入图片描述

选错了也没啥关系,反正能改

accelerate env命令可以查看配置环境。

2. 在代码中使用

用accelerate之前的脚本(具体讲解可见我之前写的博文:用huggingface.transformers.AutoModelForSequenceClassification在文本分类任务上微调预训练模型 用的是原生PyTorch那一版,因为Trainer会自动使用分布式训练。metric部分改成新版,并用全部数据来训练):

from tqdm.auto import tqdm

import torch
from torch.utils.data import DataLoader
from torch.optim import AdamW

import datasets,evaluate
from transformers import AutoTokenizer,AutoModelForSequenceClassification,get_scheduler

dataset=datasets.load_from_disk("download/yelp_full_review_disk")

tokenizer=AutoTokenizer.from_pretrained("/data/pretrained_models/bert-base-cased")

def tokenize_function(examples):
    return tokenizer(examples["text"], padding="max_length",truncation=True,max_length=512)

tokenized_datasets=dataset.map(tokenize_function, batched=True)

#Postprocess dataset
tokenized_datasets=tokenized_datasets.remove_columns(["text"])
#删除模型不用的text列

tokenized_datasets=tokenized_datasets.rename_column("label", "labels")
#改名label列为labels,因为AutoModelForSequenceClassification的入参键名为label
#我不知道为什么dataset直接叫label就可以啦……

tokenized_datasets.set_format("torch")  #将值转换为torch.Tensor对象

small_train_dataset=tokenized_datasets["train"].shuffle(seed=42)
small_eval_dataset=tokenized_datasets["test"].shuffle(seed=42)

train_dataloader=DataLoader(small_train_dataset,shuffle=True,batch_size=32)
eval_dataloader=DataLoader(small_eval_dataset,batch_size=64)

model=AutoModelForSequenceClassification.from_pretrained("/data/pretrained_models/bert-base-cased",
                                                         num_labels=5)

optimizer=AdamW(model.parameters(),lr=5e-5)

num_epochs=3
num_training_steps=num_epochs*len(train_dataloader)
lr_scheduler=get_scheduler(name="linear",optimizer=optimizer,num_warmup_steps=0,num_training_steps=num_training_steps)

device=torch.device("cuda:1") if torch.cuda.is_available() else torch.device("cpu")
model.to(device)

progress_bar = tqdm(range(num_training_steps))

model.train()
for epoch in range(num_epochs):
    for batch in train_dataloader:
        batch={k:v.to(device) for k,v in batch.items()}
        outputs=model(**batch)
        loss=outputs.loss
        loss.backward()

        optimizer.step()
        lr_scheduler.step()
        optimizer.zero_grad()
        progress_bar.update(1)

metric=evaluate.load("accuracy")
model.eval()
for batch in eval_dataloader:
    batch={k:v.to(device) for k,v in batch.items()}
    with torch.no_grad():
        outputs=model(**batch)

    logits=outputs.logits
    predictions=torch.argmax(logits, dim=-1)
    metric.add_batch(predictions=predictions, references=batch["labels"])

print(metric.compute())

懒得跑完了,总之预计要跑11个小时来着,非常慢。

添加如下代码:

from accelerate import Accelerator

accelerator = Accelerator()

#去掉将模型和数据集放到指定卡上的代码

#在建立好数据集、模型和优化器之后:
train_dataloader, eval_dataloader, model, optimizer = accelerator.prepare(
    train_dataloader, eval_dataloader, model, optimizer
)

#训练阶段将loss.backward()替换成
accelerator.backward(loss)

添加后的代码(我用全部数据集出来预计训练时间是4小时(3张卡),但我懒得跑这么久了,我就还是用1000条跑跑,把整个流程跑完意思一下):
accelerate launch Python脚本路径运行
验证部分的情况见代码后面

from tqdm.auto import tqdm

import torch
from torch.utils.data import DataLoader
from torch.optim import AdamW

import datasets
from transformers import AutoTokenizer,AutoModelForSequenceClassification,get_scheduler

from accelerate import Accelerator

accelerator = Accelerator()

dataset=datasets.load_from_disk("download/yelp_full_review_disk")

tokenizer=AutoTokenizer.from_pretrained("/data/pretrained_models/bert-base-cased")

def tokenize_function(examples):
    return tokenizer(examples["text"], padding="max_length",truncation=True,max_length=512)

tokenized_datasets=dataset.map(tokenize_function, batched=True)

#Postprocess dataset
tokenized_datasets=tokenized_datasets.remove_columns(["text"])
#删除模型不用的text列

tokenized_datasets=tokenized_datasets.rename_column("label", "labels")
#改名label列为labels,因为AutoModelForSequenceClassification的入参键名为label
#我不知道为什么dataset直接叫label就可以啦……

tokenized_datasets.set_format("torch")  #将值转换为torch.Tensor对象

small_train_dataset=tokenized_datasets["train"].shuffle(seed=42).select(range(1000))
small_eval_dataset=tokenized_datasets["test"].shuffle(seed=42).select(range(1000))

train_dataloader=DataLoader(small_train_dataset,shuffle=True,batch_size=32)
eval_dataloader=DataLoader(small_eval_dataset,batch_size=64)

model=AutoModelForSequenceClassification.from_pretrained("/data/pretrained_models/bert-base-cased",
                                                         num_labels=5)

optimizer=AdamW(model.parameters(),lr=5e-5)

train_dataloader, eval_dataloader, model, optimizer = accelerator.prepare(
    train_dataloader, eval_dataloader, model, optimizer
)

num_epochs=3
num_training_steps=num_epochs*len(train_dataloader)
lr_scheduler=get_scheduler(name="linear",optimizer=optimizer,num_warmup_steps=0,num_training_steps=num_training_steps)

progress_bar = tqdm(range(num_training_steps))

model.train()
for epoch in range(num_epochs):
    for batch in train_dataloader:
        outputs=model(**batch)
        loss=outputs.loss
        accelerator.backward(loss)

        optimizer.step()
        lr_scheduler.step()
        optimizer.zero_grad()
        progress_bar.update(1)

验证部分是这样的,直接用原来的验证部分就也能跑,但是因为脚本会被运行2遍,所以验证部分也会运行2遍。
所以我原则上建议用accelerate的话就光训练,验证的部分还是单卡实现。
如果还是想在训练过程中看一下验证效果,可以正常验证;也可以将验证部分限定在if accelerator.is_main_process:里,这样就只有主进程(通常是第一个GPU)会执行验证代码,而其他GPU不会,这样就只会打印一次指标了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Layui快速入门之第一节Layui的基本使用

目录 一:Layui的基本概念 二:Layui使用的基本步骤 1.在官网下载layui的基本文件,引入css和js文件 ①:普通方式引入 ②:第三方 CDN 方式引入 2.在script标签体中编写代码 3.测试 一:Layui的基本概念 …

Mac m1 安装rabbitmq+php-amqplib

rabbitmq 官方地址 https://www.rabbitmq.com mac 软件包 Downloading and Installing RabbitMQ — RabbitMQ 一.这里我选择 homebrew brew updatebrew install rabbitmq二.php代码 用composer 安装 10年软件开发经验,结交朋友! 分销商城系统开发,App商城开发 商务合作 s…

eclipse进入断点之后,一直卡死,线程一直在运行【记录一种情况】

问题描述: 一直卡死在某个断点处,取消断点也是卡死在这边的进程处。 解决方式: 将JDK的使用内存进行了修改 ① 打开eclipse,window->preference->Java->Installed JREs,选中使用的jdk然后点击右侧的edit,在…

打造基于终端命令行的IDE,Termux配置Vim C++开发环境

Termux配置Vim C开发环境,打造基于终端命令行的IDE 主要利用VimCoc插件,配置C的代码提示等功能。 Termux换源 打开termux,输入termux-change-repo 找到mirrors.tuna.tsinghua.edu.cn,清华源,空格选中,回…

LeetCode(力扣)40. 组合总和 IIPython

LeetCode40. 组合总和 II 题目链接代码 题目链接 https://leetcode.cn/problems/combination-sum-ii/ 代码 class Solution:def backtrackingz(self, candidates, target, result, total, path, startindex):if target total:result.append(path[:])return for i in range…

elasticsearch访问9200端口 提示需要登陆

项目场景: 提示:这里简述项目相关背景: elasticsearch访问9200端口 提示需要登陆 问题描述 提示:这里描述项目中遇到的问题: 在E:\elasticsearch-8.9.1-windows-x86_64\elasticsearch-8.9.1\bin目录下输入命令 ela…

手写Spring:第5章-注入属性和依赖对象

文章目录 一、目标:注入属性和依赖对象二、设计:注入属性和依赖对象三、实现:注入属性和依赖对象3.0 引入依赖3.1 工程结构3.2 注入属性和依赖对象类图3.3 定义属性值和属性集合3.3.1 定义属性值3.3.2 定义属性集合 3.4 Bean定义补全3.5 Bean…

Flutter实用工具Indexer列表索引和Search搜索帮助。

1.列表索引 效果图: indexer.dart import package:json_annotation/json_annotation.dart;abstract class Indexer {///用于排序的字母JsonKey(includeFromJson: false, includeToJson: false)String? sortLetter;///用于排序的拼音JsonKey(includeFromJson: fal…

学习笔记|计数器|Keil软件中 0xFD问题|I/O口配置|STC32G单片机视频开发教程(冲哥)|第十二集:计数器的作用和意义

文章目录 1.计数器的用途2.计数器的配置官方例程开始Tips:编译时提示错误FILE DOES NOT EXIST: 3.计数器的应用本例完整代码:总结课后练习: 1.计数器的用途 直流有刷的电机,后面两个一正一负的电接上,电机就可以转 到底是转子个…

NLP(六十八)使用Optimum进行模型量化

本文将会介绍如何使用HuggingFace的Optimum,来对微调后的BERT模型进行量化(Quantization)。   在文章NLP(六十七)BERT模型训练后动态量化(PTDQ)中,我们使用PyTorch自带的PTDQ&…

李宏毅-机器学习hw4-self-attention结构-辨别600个speaker的身份

一、慢慢分析学习pytorch中的各个模块的参数含义、使用方法、功能: 1.encoder编码器中的nhead参数: self.encoder_layer nn.TransformerEncoderLayer( d_modeld_model, dim_feedforward256, nhead2) 所以说,这个nhead的意思,就…

使用Maven创建父子工程

📚目录 创建父工程创建子模块创建子模块示例创建认证模块(auth) 结束 创建父工程 选择空项目: 设置:项目名称,组件名称,版本号等 创建完成后的工程 因为我们需要设置这个工程为父工程所以不需要src下的所有文件 在pom…

WPF Flyout风格动画消息弹出消息提示框

WPF Flyout风格动画消息弹出消息提示框 效果如图&#xff1a; XAML: <Window x:Class"你的名称控件.FlyoutNotication"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xam…

java八股文面试[数据库]——索引覆盖

覆盖索引是一种避免回表查询的优化策略: 只需要在一棵索引树上就能获取SQL所需的所有列数据&#xff0c;无需回表&#xff0c;速度更快。 具体的实现方式: 将被查询的字段建立普通索引或者联合索引&#xff0c;这样的话就可以直接返回索引中的的数据&#xff0c;不需要再通过聚…

肖sir__设计测试用例方法之因果图07_(黑盒测试)

设计测试用例方法之因果图 一、定义&#xff1a;因果图提供了一个把规格转化为判定表的系统化方法&#xff0c;从该图中可以产生测试数据。其 中&#xff0c;原因是表示输入条件&#xff0c;结果是对输入执 行的一系列计算后得到的输出。 二、因果图方法最终生成的就是判定表。…

rhcsa4 进程和SSH

tree命令。用于以树状结构显示目录和文件。通过运行 “tree” 命令可视化地查看文件系统中的目录结构。 tree / systemd是第一个系统进程&#xff08;pid1&#xff09;不启动&#xff0c;其他进程也没法启动&#xff0c; 用pstree查看进程树 我们可以看到所有进程都是syste…

蓝桥杯打卡Day3

文章目录 吃糖果递推数列 一、吃糖果IO链接 本题思路:本题题意就是斐波那契数列&#xff01; #include <bits/stdc.h>typedef uint64_t i64;i64 f(i64 n) {if(n1) return 1;if(n2) return 2;return f(n-1)f(n-2); }signed main() {std::ios::sync_with_stdio(false);s…

GRU门控循环单元

GRU 视频链接 https://www.bilibili.com/video/BV1Pk4y177Xg?p23&spm_id_frompageDriver&vd_source3b42b36e44d271f58e90f86679d77db7Zt—更新门 Rt—重置门 控制保存之前一层信息多&#xff0c;还是保留当前神经元得到的隐藏层的信息多。 Bi-GRU GRU比LSTM参数少 …

服务器数据恢复-阵列崩溃导致LVM结构破坏的数据恢复案例

服务器数据恢复环境&#xff1a; 一台服务器中有两组分别由4块SAS硬盘组建的raid5阵列&#xff0c;两组阵列上层划分LUN组建LVM结构&#xff0c;并被格式化为EXT3文件系统。 服务器故障&检测&#xff1a; RIAD5阵列中有一块硬盘故障离线&#xff0c;热备盘激活上线顶替离线…

西门子PLC的优势在哪呢?

今日话题&#xff0c;西门子PLC有何优势以至于能够在竞争中超越三菱和欧姆龙&#xff1f;西门子PLC作为德国品牌&#xff0c;具有独特的优势。视频后方有学习资料免费发放&#xff0c;有兴趣的移步自取。首先&#xff0c;尽管其指令相对抽象&#xff0c;学习难度较高&#xff0…