ROCm上运行预训练BERT

176 篇文章 2 订阅
112 篇文章 0 订阅
79 篇文章 0 订阅

14.10. 预训练BERT — 动手学深度学习 2.0.0 documentation (d2l.ai)

下载数据集

~/d2l-zh/pytorch/data\$ unzip wikitext-2-v1.zip
Archive:  wikitext-2-v1.zip
creating: wikitext-2/
inflating: wikitext-2/wiki.test.tokens
inflating: wikitext-2/wiki.valid.tokens
inflating: wikitext-2/wiki.train.tokens


代码

import torch
from torch import nn
from d2l import torch as d2l

batch_size, max_len = 512, 64

net = d2l.BERTModel(len(vocab), num_hiddens=128, norm_shape=[128],
num_layers=2, dropout=0.2, key_size=128, query_size=128,
value_size=128, hid_in_features=128, mlm_in_features=128,
nsp_in_features=128)
devices = d2l.try_all_gpus()
loss = nn.CrossEntropyLoss()

#@save
def _get_batch_loss_bert(net, loss, vocab_size, tokens_X,
segments_X, valid_lens_x,
pred_positions_X, mlm_weights_X,
mlm_Y, nsp_y):
# 前向传播
_, mlm_Y_hat, nsp_Y_hat = net(tokens_X, segments_X,
valid_lens_x.reshape(-1),
pred_positions_X)
# 计算遮蔽语言模型损失
mlm_l = loss(mlm_Y_hat.reshape(-1, vocab_size), mlm_Y.reshape(-1)) *\
mlm_weights_X.reshape(-1, 1)
mlm_l = mlm_l.sum() / (mlm_weights_X.sum() + 1e-8)
# 计算下一句子预测任务的损失
nsp_l = loss(nsp_Y_hat, nsp_y)
l = mlm_l + nsp_l
return mlm_l, nsp_l, l
def train_bert(train_iter, net, loss, vocab_size, devices, num_steps):
net = nn.DataParallel(net, device_ids=devices).to(devices[0])
step, timer = 0, d2l.Timer()
animator = d2l.Animator(xlabel='step', ylabel='loss',
xlim=[1, num_steps], legend=['mlm', 'nsp'])
# 遮蔽语言模型损失的和，下一句预测任务损失的和，句子对的数量，计数
metric = d2l.Accumulator(4)
num_steps_reached = False
while step < num_steps and not num_steps_reached:
for tokens_X, segments_X, valid_lens_x, pred_positions_X,\
mlm_weights_X, mlm_Y, nsp_y in train_iter:
tokens_X = tokens_X.to(devices[0])
segments_X = segments_X.to(devices[0])
valid_lens_x = valid_lens_x.to(devices[0])
pred_positions_X = pred_positions_X.to(devices[0])
mlm_weights_X = mlm_weights_X.to(devices[0])
mlm_Y, nsp_y = mlm_Y.to(devices[0]), nsp_y.to(devices[0])
timer.start()
mlm_l, nsp_l, l = _get_batch_loss_bert(
net, loss, vocab_size, tokens_X, segments_X, valid_lens_x,
pred_positions_X, mlm_weights_X, mlm_Y, nsp_y)
l.backward()
trainer.step()
timer.stop()
(metric[0] / metric[3], metric[1] / metric[3]))
step += 1
if step == num_steps:
num_steps_reached = True
break

print(f'MLM loss {metric[0] / metric[3]:.3f}, '
f'NSP loss {metric[1] / metric[3]:.3f}')
print(f'{metric[2] / timer.sum():.1f} sentence pairs/sec on '
f'{str(devices)}')

train_bert(train_iter, net, loss, len(vocab), devices, 50)

def get_bert_encoding(net, tokens_a, tokens_b=None):
tokens, segments = d2l.get_tokens_and_segments(tokens_a, tokens_b)
token_ids = torch.tensor(vocab[tokens], device=devices[0]).unsqueeze(0)
segments = torch.tensor(segments, device=devices[0]).unsqueeze(0)
valid_len = torch.tensor(len(tokens), device=devices[0]).unsqueeze(0)
encoded_X, _, _ = net(token_ids, segments, valid_len)
return encoded_X

tokens_a = ['a', 'crane', 'is', 'flying']
encoded_text = get_bert_encoding(net, tokens_a)
# 词元：'<cls>','a','crane','is','flying','<sep>'
encoded_text_cls = encoded_text[:, 0, :]
encoded_text_crane = encoded_text[:, 2, :]
encoded_text.shape, encoded_text_cls.shape, encoded_text_crane[0][:3]

tokens_a, tokens_b = ['a', 'crane', 'driver', 'came'], ['he', 'just', 'left']
encoded_pair = get_bert_encoding(net, tokens_a, tokens_b)
# 词元：'<cls>','a','crane','driver','came','<sep>','he','just',
# 'left','<sep>'
encoded_pair_cls = encoded_pair[:, 0, :]
encoded_pair_crane = encoded_pair[:, 2, :]
encoded_pair.shape, encoded_pair_cls.shape, encoded_pair_crane[0][:3]


代码解析

1. 加载数据集:

train_iter, vocab = d2l.load_data_wiki(batch_size, max_len)

这行代码将会加载一个预处理过的维基百科数据集作为BERT的训练数据，每个批次的大小为512，最大长度为64个词元。
2. 创建BERT模型:

   net = d2l.BERTModel(len(vocab), ...)

这里定义了一个BERT模型实例，其中包含有几种参数配置：词汇表大小、隐藏特征表示的维数、前馈神经网络层的参数等。
3. 设定损失函数和训练设备:
- 损失函数使用了交叉熵损失。
- 训练设备可以是GPU（如果可用）。
4. 定义BERT的批量损失计算函数_get_batch_loss_bert:
计算给定批次数据的损失值，包括遮蔽语言模型损失和下一个句子预测损失。
5. 定义BERT的训练函数train_bert:
设置BERT模型训练的相关参数和流程。
6. 执行训练:

   train_bert(train_iter, net, loss, len(vocab), devices, 50)

运行训练函数，进行50步训练。
7. 用get_bert_encoding函数获得BERT模型编码的词元表示:
函数接受一对句子（tokens_a和tokens_b），对它们进行编码，并返回编码后的词元表示。如果只有一个句子，tokens_b=None，默认tokens_b不提供。
8. 最后，通过编码两个示例句子，展示如何使用BERT模型来获取词元的嵌入表示。

1. 安装Anaconda：首先，您需要在您的Linux系统上安装Anaconda，这是一个用于科学计算的Python发行版，它包含了运行BERT所需的许多库和工具。
2. 安装TensorFlow：在ROCm上运行BERT需要使用TensorFlow的特定版本，即支持ROCm的版本。您可以从TensorFlow官方网站或者通过其他渠道获取适合ROCm的TensorFlow版本。
3. 硬件配置：确保您的硬件配置满足运行BERT的要求。一般来说，需要有足够的GPU内存和计算能力。例如，有案例使用了配置为4*V100 (16G)，8核CPU，128G内存的硬件配置。
4. 数据准备：根据您的NLP任务需求，准备或收集相应的训练数据。如果是特定的领域，如金融领域，您可能需要金融新闻、研究报告等数据。
5. 模型调整：由于BERT是一个大规模的模型，您可能需要根据实际情况对模型进行调整，比如调整模型的大小、学习率等参数，以适应您的硬件条件和训练数据。
6. 性能优化：在预训练过程中，您可能需要对性能进行优化，这包括使用混合精度训练、优化器选择等技术来提高训练效率和速度。
7. 训练和评估：最后，您需要实际运行预训练过程，并在完成后对模型进行评估和调优，以确保其在您的特定任务上能够达到最佳性能。

1. 安装ROCm：首先，你需要在你的AMD GPU支持的机器上安装ROCm。这包括安装驱动程序、运行时库、编译器（如HIP）等。确保你按照ROCm的官方文档进行了正确的安装和配置。
2. 选择深度学习框架：选择一个支持ROCm的深度学习框架，如PyTorch或TensorFlow。这些框架提供了在GPU上运行深度学习模型的接口。你需要安装这些框架的ROCm版本。
3. 下载预训练的BERT模型：从可靠的来源（如Hugging Face的Transformers库）下载预训练的BERT模型。确保你选择了与你的深度学习框架兼容的模型版本。
4. 加载预训练的BERT模型：使用你选择的深度学习框架加载预训练的BERT模型。这通常涉及调用框架提供的特定函数或API来加载模型的权重和配置。
5. 准备数据和预处理：准备你要用于自然语言处理任务的数据，并进行必要的预处理，如分词、编码等。确保你的数据格式与BERT模型的输入要求相匹配。
6. 在ROCm上运行BERT模型：将你的数据和BERT模型传递给深度学习框架，并指定使用ROCm作为计算后端。这通常涉及设置环境变量或调用框架的特定函数来指定GPU加速。然后，你可以运行你的自然语言处理任务，并观察BERT模型在ROCm上的性能。

1. 安装ROCm环境：确保你的系统已经安装了ROCm，包括所需的内核驱动、ROCm平台和相关的依赖库。根据 22，可以通过 amdgpu-install 命令来安装ROCm环境。

2. 安装支持ROCm的深度学习框架：选择一个与ROCm兼容的深度学习框架，比如PyTorch。根据 22，建议使用AMD提供的Docker镜像来安装PyTorch，这样可以确保与ROCm的兼容性。

3. 获取BERT预训练模型：你可以从Hugging Face的模型库或其他资源获取预训练的BERT模型。根据 24，有多种中文BERT预训练模型可供选择。

4. 转换模型格式：如果BERT模型不是为ROCm优化的格式，你可能需要将其转换为ROCm兼容的格式。这可能涉及到将模型权重从一种格式转换为另一种格式，比如从TensorFlow的.ckpt转换为ONNX或直接支持ROCm的PyTorch模型格式。

5. 在ROCm上运行BERT模型：加载模型并在ROCm加速的GPU上运行推理或进一步的训练。根据 23，可以使用专为大型语言模型设计的部署工具LM Studio，它支持ROCm加速。

6. 性能优化：利用ROCm提供的性能分析工具，如rocprof、roctracer等，来分析和优化模型的性能。

• 33
点赞
• 20
收藏
觉得还不错? 一键收藏
• 打赏
• 1
评论
12-05 2288
11-15 5964
03-31
11-30

“相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

109702008

¥1 ¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。