实现可扩展人工智能的便捷之路:英特尔 Tiber 开发者云 + MinIO 对象存储

当今组织在 AI 和数据管理方面面临的最大挑战之一是获得可靠的基础设施和计算资源。英特尔 Tiber 开发人员云专为需要概念验证、实验、模型训练和服务部署环境的工程师而构建。与其他难以接近且复杂的云不同,英特尔 Tiber 开发人员云简单易用。该平台对于开发各种类型模型的 AI/ML 工程师特别有价值。使用英特尔的云,AI/ML 工程师可以轻松获取计算和存储,以运行训练和推理工作负载,以及部署应用程序和服务。英特尔选择 MinIO 作为其云的对象存储,因为它带来了简单性、可扩展性、性能以及与云和 AI 生态系统的原生集成。我们很高兴成为首选的对象存储,并很高兴制作此“操作方法”帖子,以加速您采用此平台。我将展示如何使用英特尔 Gaudi AI 加速器训练模型,以及如何在英特尔 Tiber 开发人员云中设置和使用 MinIO(对象存储)。让我们开始吧。本文的完整代码演示可以在这里找到。

创建账户并启动实例

英特尔的云文档包含设置帐户和获取 AI/ML 实验、优化和部署资源的分步指南。本文中提供的代码假定您已完成以下指南。

开始使用 - 本指南将指导您完成创建和登录账户的过程。它还向您展示如何使用云的 Jupyter 服务器。Jupyter Lab 的优点在于您不需要 SSH 密钥即可启动和使用它。

SSH 密钥 - 要创建计算实例,您需要将 SSH 公钥上传到您的账户。本指南介绍如何根据云的规范创建密钥并将其上传到您的账户。请务必将公钥和私钥保存在安全的地方。您将需要私钥才能通过 SSH 连接到计算实例。本指南还介绍了用于连接到实例的 SSH 命令。

Manage Instance (管理实例) – 本指南介绍如何在完成实验后选择、启动和关闭计算节点。

Object Storage (对象存储) – 本指南将指导您在账户中创建存储桶。

拥有帐户后,您将可以访问硬件、软件和服务选项,如下所示。在本文中,我们将使用计算实例和对象存储。

为 MinIO 编程访问做好准备

下面的屏幕截图显示了用于创建存储桶的对话框。请注意,您的存储桶名称以唯一标识符为前缀。这是必要的,因为 MinIO 是 Intel 云的平台服务,它支持云区域中的所有帐户。因此,唯一标识符可防止与其他账户发生名称冲突。

输入存储桶的名称,并根据需要启用版本控制。单击 Create (创建) 按钮后,您应该会看到您的新存储桶,如下所示。本文将使用 MNIST 数据集并以编程方式访问它以训练模型。因此,访问我们的新存储桶需要终端节点、访问密钥和私有密钥。

要查看终端节点地址,请单击新存储桶,然后选择 Details (详细信息) 选项卡,如下图所示。复制此对话框中显示的私有终端节点,因为在设置 MinIO SDK 配置文件时需要它。

由于您需要以编程方式访问存储桶,因此请创建一个委托人并将访问密钥和私有密钥与其关联。为此,请单击 Principles 选项卡。所有现有原则都会显示出来。

接下来,单击 Manage Principles and permissions 按钮。这将打开一个对话框,您可以在其中编辑上面显示的原则。

单击 Create principle 按钮。您现在应该看到用于创建原则的对话框(请参阅下文)。为新原则选择所需的权限,然后单击 Create 按钮。

创建主体后,转到 Manage Principals and Permissions 页面,然后单击新创建的原则。

单击原则后,您应该会看到如下所示的对话框。

您可以在此处创建访问密钥和密钥,以使用 MinIO SDK(或任何其他 S3 投诉库)访问存储桶。单击 Generate password 按钮创建密钥,如下所示。立即将它们复制到配置文件中,因为您无法再次显示它们。

本文的代码示例使用的配置文件是用于设置环境变量的 .env 文件。如下所示,将您的私有终端节点、访问密钥、私有密钥和存储桶名称放入此文件中。

MINIO_URL=s3-phx04-5.tenantiglb.us-region-2.cloud.intel.com:9000
MINIO_ACCESS_KEY={Put access key here.}
MINIO_SECRET_KEY={Put secret key here.}
MINIO_SECURE=false
BUCKET_NAME={Put full bucket name here.}

现在,为训练数据创建计算实例和存储桶后,您就可以编写一些代码了。让我们将 MNIST 数据集上传到我们的新存储桶。

将数据上传到 MinIO

torchvision 软件包使检索 MNIST 数据集中的图像变得容易。下面的函数使用此包下载一组压缩的文件,提取图像,并将其发送到 MinIO。这如下面的代码示例所示。为简洁起见,省略了一些支持功能。完整的代码可以在本文的代码下载中的 data_utlities.py 模块中找到。

import PIL.Image
from dotenv import load_dotenv
from minio import Minio
from minio.error import S3Error
import numpy as np
import PIL
import torch
from torchvision import datasets, transformsdef load_mnist_to_minio(bucket_name: str) -> Tuple[int,int]:''' Download and load the training and test samples.'''logger = create_logger()train = datasets.MNIST('./mnistdata/', download=True, train=True)test = datasets.MNIST('./mnistdata/', download=True, train=False)train_count = 0for sample in train:random_uuid = uuid.uuid4()object_name = f'/train/{sample[1]}/{random_uuid}.jpeg'put_image_to_minio(bucket_name, object_name, sample[0])train_count += 1if train_count % 100 == 0:logger.info(f'{train_count} training objects added to {bucket_name}.')test_count = 0for sample in test:random_uuid = uuid.uuid4()object_name = f'/test/{sample[1]}/{random_uuid}.jpeg'put_image_to_minio(bucket_name, object_name, sample[0])test_count += 1if test_count % 100 == 0:logger.info(f'{test_count} testing objects added to {bucket_name}.')return train_count, test_countdef put_image_to_minio(bucket_name: str, object_name: str, image: PIL.Image.Image) -> None:'''Puts an image byte stream to MinIO.'''logger = create_logger()url, access_key, secret_key, secure = get_minio_credentials()try:# Create client with access and secret keyclient = Minio(url,  # host.docker.internalaccess_key, secret_key,secure=secure)image_byte_array = image_to_byte_stream(image)content_type = 'application/octet-stream'response = client.put_object(bucket_name, object_name, image_byte_array,-1, content_type, part_size = 1024*1024*5)except S3Error as s3_err:logger.error(f'S3 Error occurred: {s3_err}.')raise s3_errexcept Exception as err:logger.error(f'Error occurred: {err}.')raise err

现在,您的数据集已加载到存储桶中,让我们看看如何访问它以训练模型。

从 Data Loader 使用 MinIO

在模型训练管道中,有两个位置可以从持久存储加载数据。如果您的数据完全适合内存,则可以在调用训练函数之前,在训练管道开始时将所有内容加载到内存中。(我们将在下一节中创建此训练函数。如果您的数据集足够小,可以完全放入内存中,则此方法有效。如果您以这种方式加载数据,您的训练函数将是计算绑定的,因为它不必进行任何 IO 调用即可从对象存储中获取数据。但是,如果您的数据集太大而无法放入内存,则每次将新批次样本发送到模型进行训练时,都需要检索数据。这将产生 IO 绑定的训练函数。由于我们想演示使用 Gaudi 加速器进行模型训练的好处,因此我们将创建一个计算绑定的训练函数。用于创建自定义 Dataset 并将其加载到 Dataloader 中的 Pytorch 代码如下所示。请注意,所有数据都加载到 ImageDatasetFull 类的构造函数中。所有 MNIST 图像都从 MinIO 中检索,并存储在从此类创建的对象的属性中。这一切都发生在首次创建对象时。如果我们想在每次将一批数据发送到我们的模型进行训练时加载图像,那么我们需要只使用对象名称列表创建此对象,并将实际图像的加载移动到 getitem() 函数。

class ImageDatasetFull(Dataset):def __init__(self, bucket_name: str, X, y, transform=None):self.bucket_name = bucket_nameself.y = yself.transform = transformraw_images = du.get_images_from_minio(bucket_name, X)images = torch.stack([transform(x) for x in raw_images], dim=0)self.X = imagesdef __len__(self):return len(self.y)def __getitem__(self, index):return self.X[index], self.y[index]
def create_mnist_training_loader(bucket_name: str, loader_type:str, batch_size:int, smoke_test_size: float=0) -> Tuple[Any]:# Start of load time.start_time = time.perf_counter()# Define a transform to normalize the datatransform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,), (0.5,))])# Get a list of objects and split them according to train and test.   X_train, y_train, _, _ = du.get_mnist_lists(bucket_name)if smoke_test_size > 0:train_size = int(smoke_test_size*len(X_train))X_train = X_train[0:train_size]y_train = y_train[0:train_size]train_dataset = ImageDatasetFull(bucket_name, X_train, y_train, transform=transform)train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=1)return train_loader, (time.perf_counter()-start_time)   

现在我们已经将数据加载到内存中,让我们看看如何使用 Gaudi2 和英特尔 Developer Cloud 来训练模型。

使用 PyTorch 的 Intel Gaudi 加速器

PyTorch HPU 软件包支持 Intel 的多架构处理 (HPU) 实用程序。通常,HPU 允许开发人员编写针对 Intel 硬件范围优化的 PyTorch 应用程序,例如 CPU、Gaudi 加速器、GPU 以及 Intel 可能构建的任何未来加速器。HPU 抽象使用 PyTorch 提供的通用接口。因此,开发人员可以编写在不同硬件加速器之间动态切换的代码,而无需进行大量重构。这篇文章将使用它来检测 Gaudi 并将张量移动到 Gaudi 的内存中。使用任何类型的加速器时,一种常见的编码模式是首先检查 GPU 或 AI 加速器(如果存在),然后将模型、训练集、验证集和测试集移动到处理器的内存中。这通常是在训练模型的函数中完成的。下面的函数来自本文的代码下载。(这个函数就是我之前提到的训练函数。突出显示的代码显示了如何检查是否存在 Intel 加速器并将模型和训练集移动到设备。要使此检查在 Gaudi 中正常工作,您需要以下导入。您不会直接使用此模块,但需要导入它。

将 habana_frameworks.torch.core 导入为 htcore

请注意,从训练集中移动保存特征和标签的张量是在批处理循环中完成的。PyTorch 数据加载器没有用于将整个数据集移动到目标设备的“to”函数。这是有充分理由的:大型数据集会很快耗尽处理器的内存。对于内存比新 GPU 少的旧 GPU 尤其如此。最佳做法是,在模型需要进行训练之前,仅将当前训练批次所需的张量移动到加速器。

def train_model(model: nn.Module, loader: DataLoader, training_parameters: Dict[str, Any]) -> List[float]:logger = du.create_logger()device = torch.device('hpu' if torch.hpu.is_available() else 'cpu')model.to(device)logger.info(f'Model created on device {device}')loss_func = nn.NLLLoss()optimizer = optim.SGD(model.parameters(), lr=training_parameters['lr'], momentum=training_parameters['momentum'])# Epoch loop.compute_time_by_epoch = []for epoch in range(training_parameters['epochs']):total_loss = 0batch_count = 0total_epoch_compute_time = 0# Batch loop.for images, labels in loader:# Start of compute time for the batch.start = time.perf_counter()# Move to the specified device.# shape = [32, 1, 28, 28]images, labels = images.to(device), labels.to(device)# Flatten MNIST images into a 784 long vector.# shape = [32, 784]images = images.view(images.shape[0], -1)# Training passoptimizer.zero_grad()output = model(images)loss = loss_func(output, labels)loss.backward()optimizer.step()# Loss calculations           total_loss += loss.item()batch_count +=1# Track compute timetotal_epoch_compute_time += time.perf_counter() - startcompute_time_by_epoch.append(total_epoch_compute_time)logger.info(f'Epoch {epoch+1} - Training loss: {total_loss/batch_count}.')return compute_time_by_epoch

现在,我们已经知道如何将模型和张量从数据加载器移动到 Gaudi,并有办法从对象存储中获取数据,让我们把所有东西放在一起并运行几个实验。

把它们放在一起

下面的函数将所有内容整合在一起。它将创建我们的数据加载器并将它们传递给我们的 train_model 函数。请注意,所有内容都经过检测,以便从我们的代码中获取性能指标。运行此函数后,我们将看到 IO 时间与计算时间的关系。我们还将能够仅使用 CPU,然后再次使用 Gaudi 运行相同的代码。

def setup_local_training(training_parameters: Dict[str, Any], loader_type: str):logger = du.create_logger()device = torch.device('hpu' if torch.hpu.is_available() else 'cpu')logger.info(f'PyTorch Version: {torch.__version__}')logger.info(f'Using device: {device}')#train_data, test_data, load_time_sec = ru.get_ray_dataset(training_parameters)train_loader, load_time_sec = tu.create_mnist_training_loader(training_parameters['bucket_name'], loader_type, training_parameters['batch_size'])logger.info(f'Data Loader Creation Time (in seconds) = {load_time_sec}')# Train the model and log training metrics.model = tu.MNISTModel(training_parameters['input_size'], training_parameters['hidden_sizes'], training_parameters['output_size'])start_time = time.perf_counter()compute_time_by_epoch = train_model(model, train_loader, training_parameters)training_time_sec = time.perf_counter() - start_timecompute_time_sec = 0for epoch_time in compute_time_by_epoch:compute_time_sec += epoch_timelogger.info(f'Compute Time (in seconds) = {compute_time_sec}')logger.info(f'I/O Time (in seconds) = {training_time_sec - compute_time_sec}')logger.info(f'Total Training Time (in seconds) = {training_time_sec}')test_loader, load_time_sec = tu.create_mnist_testing_loader(training_parameters['bucket_name'], loader_type, training_parameters['batch_size'])tu.test_model_local(model, test_loader, training_parameters)

下面的代码段将调用此函数并传入相应的超参数。

# Hyperparameterstraining_parameters = {'batch_size': 32,'bucket_name': BUCKET_NAME,'epochs': 3,'hidden_sizes': [1024, 1024, 1024, 1024],'input_size': 784,'lr': 0.025,'momentum': 0.5,'output_size': 10,'smoke_test_size': 0,'use_gpu': False,}setup_local_training(training_parameters, 'full')

使用 use_gpu = False 在我们的计算实例上运行上面的 setup 函数会产生以下输出。

INFO | Data Set Size: 60000 samples.INFO | Using device: cpuINFO | Model moved to device: cpuINFO | Epoch 1 - Training loss: 0.4534 - Compute time: 15.3998 IO time: 7.3033.INFO | Epoch 2 - Training loss: 0.1475 - Compute time: 14.7520 IO time: 7.4030.INFO | Epoch 3 - Training loss: 0.1046 - Compute time: 15.1024 IO time: 7.6316.INFO | Compute Time (in seconds) = 45.2544INFO | I/O Time (in seconds) = 22.3410INFO | Total Training Time (in seconds) = 67.5955INFO | Total Experiment Time (in seconds) = 67.6832

使用 Gaudi 运行相同的代码会导致输出显示我们的计算时间显著减少。

INFO | Data Set Size: 60000 samples.INFO | Using device: hpuINFO | Model moved to device: hpuINFO | Epoch 1 - Training loss: 0.4521 - Compute time: 3.5001 IO time: 8.0007.INFO | Epoch 2 - Training loss: 0.1481 - Compute time: 3.4549 IO time: 7.8584.INFO | Epoch 3 - Training loss: 0.1035 - Compute time: 3.8153 IO time: 8.0103.INFO | Compute Time (in seconds) = 10.7705INFO | I/O Time (in seconds) = 29.7047INFO | Total Training Time (in seconds) = 40.4752INFO | Total Experiment Time (in seconds) = 40.5629

上述结果特别有趣,因为快速加速器可以将计算受限的训练工作负载(计算耗时最长)转变为 IO 受限的训练工作负载(数据访问耗时最长)。证明快速加速器必须与快速网络和快速存储携手使用。

总结

在本文中,我展示了如何设置英特尔 Tiber Developer Cloud 进行机器学习实验。这需要创建一个帐户、设置计算实例、创建 MinIO 存储桶和设置 SSH 密钥。创建资源后,我演示了如何编写一些函数来上传和检索数据。我还讨论了可以放入内存的小型数据集和无法放入内存的大型数据集的数据加载注意事项。使用 Intel 的 Gaudi 加速器非常简单,开发人员将识别 PyTorch 中 hpu 包的接口。我展示了检测 Gaudi 并将张量移动到它的基本代码。在这篇文章的最后,我同时使用 CPU 和 Gaudi 加速器训练了一个实际模型。这两个实验展示了 Gaudi 的性能提升,并为使用快速存储和带有快速加速器的快速网络提供了理由。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

信息安全工程师(67)网络流量清洗技术与应用

前言 网络流量清洗技术是现代网络安全领域中的一项关键技术,它主要用于过滤和清理网络流量中的恶意部分,确保正常的网络通信。 一、网络流量清洗技术的定义与原理 网络流量清洗技术,也称为流量清理(Traffic Scrubbing)…

csdn要打开或者无法刷新内容管理,文章无法发布或者未保存成功(服务器超时)-->先保存在自己的电脑里

今天突然想到以前看网页小说的时候改变网页链接后面的页数能够直接跳转,那么能不能不能改一下1000.2115.3001.5448 https://mp.csdn.net/mp_blog/manage/article?spm1000.2115.3001.5448 https://mp.csdn.net/mp_blog/manage/article?spm1000.2115.3001.5448 后…

计算机使用梯子后关机,再次使用计算机时未开启梯子,无法正常上网

问题:使用计算机时开启了梯子,使用完毕后关闭计算机,再次打开计算机但是没有开启梯子时无法正常上网; 原因:使用梯子时可能将手动设置代理处设置成了梯子的代理服务器地址,所以再次使用计算机但是没有使用…

报表系统-连接数据库操作

本专栏用于解析自己开源的项目代码,作为复盘和学习使用。欢迎大家一起交流 本样例说明源码开源在: ruoyi-reoprt gitee仓库 ruoyi-report github仓库 欢迎大家到到项目中多给点star支持,对项目有建议或者有想要了解的欢迎一起讨论 连接数据库…

初学者指南:软件测试

目录 初学者软件开发流程中的测试指南一、什么是软件测试?二、软件测试的重要性三、软件测试的类型四、软件测试的流程五、软件测试工具六、软件测试工程师的技能要求七、如何上手软件测试八、结语 初学者软件开发流程中的测试指南 欢迎来到软件测试的世界&#xf…

公司章程拟定,定制公司章程

公司章程是指公司依法制定的、规定公司名称、住所、经营范围、经营管理制度等重大事项的基本文件,也是公司必要的规定公司组织及活动基本规则的书面文件。公司章程是股东共同一致的意思表示,载明了公司组织和活动的基本准则,是公司的宪章。关…

基于HEC-Ras及ArcGIS的泥石流数值模拟与灾害风险评估典型案例

泥石流是一种破坏性极强的自然灾害,对人类社会和自然环境都构成了巨大的威胁。由于泥石流的发生通常突然且难以预测,因此,采取有效的预防措施和进行科学的风险评估显得尤为重要。为了减少泥石流可能带来的损害,可以建立高效的监测…

LVGL第二篇-组件创建与显示(以slider为例)

一、LVGL 中组件加载步骤 分配内存与初始化: 首先,通过调用相应组件的创建函数来分配内存并初始化组件对象。例如,若要创建一个按钮组件,可使用lv_XXX_create函数。这些创建函数会返回一个指向新创建组件对象(lv_obj_t…

百度文心一言接入流程-java版

百度文心一言接入流程-java版 一、准备工作二、API接口调用-java三、百度Prompt工程参考资料: 百度文心一言:https://yiyan.baidu.com/百度千帆大模型:https://qianfan.cloud.baidu.com/百度千帆大模型文档:https://cloud.baidu.com/doc/WENXINWORKSHOP/index.html千tokens…

Modbus TCP报错:Response length is only 0 bytes

问题描述: 使用modbus_tk库,通过Modbus tcp连接PLC时,python中的一个报错信息: Response length is only 0 bytes报错原因: 与Modbus TCP 服务端建立连接后没有断开,继续作为长连接使用,客户端…

时序数据库 TDengine 支持集成开源的物联网平台 ThingsBoard

Thingsboard 中“设备配置”和“设备”的关系是一对多的关系,通过设备配置为每个设备设置不同的配置,每个设备都会有一个与其关联的设备配置文件。等等,这不就是TDengine 中超级表的概念: 超级表是一种特殊的表结构,用…

Unity3D学习FPS游戏(4)重力模拟和角色跳跃

前言:前面两篇文章,已经实现了角色的移动和视角转动,但是角色并没有办法跳跃,有时候还会随着视角移动跑到天上。这是因为缺少重力系统,本篇将实现重力和角色跳跃功能。觉得有帮助的话可以点赞收藏支持一下!…

Spring Cloud:构建高可用分布式系统的利器

摘要:本文将介绍Spring Cloud,一个基于Spring Boot的开源微服务架构工具集。我们将探讨Spring Cloud的核心组件、特性以及如何使用Spring Cloud构建高可用、分布式系统。通过本文,读者将了解到Spring Cloud在实现微服务架构中的应用和优势。 …

ResNet-RS 乳腺癌识别

一、模型结构 1.1 模型思路 ResNet-RS是一种改进的ResNet架构,它在2021年由谷歌大脑和UC Berkeley的研究者们提出。ResNet-RS的提出基于对现有ResNet架构的深入研究,研究者们重新审视了ResNet的结构、训练方法以及缩放策略,并提出了一些改进…

git入门操作(2)

文章目录 git入门操作(2)git diff 查看差异git diff gitignore忽略文件1.在代码仓库创建这个文件2.添加对 log 文件过滤 连接远程仓库与ssh配置远程仓库和本地仓库关联步骤分支基本操作步骤命令: 合并冲突分支合并逻辑1.新建分支 dev&#xf…

MySQL查看当前客户端连接数的方法

每当有客户端连接到 MySQL 时,MySQL 会为该连接创建一个新的线程来处理所有与该连接相关的查询和操作。所以通过查看MySQL当前的连接线程数量就可以知道有多少客户端连接到MySQL。 方法一 Threads_connected 仅显示活跃的客户端连接数 SHOW STATUS LIKE Threads_…

H7-TOOL的LUA小程序教程第15期:电压,电流,NTC热敏电阻以及4-20mA输入(2024-10-21,已经发布)

LUA脚本的好处是用户可以根据自己注册的一批API(当前TOOL已经提供了几百个函数供大家使用),实现各种小程序,不再限制Flash里面已经下载的程序,就跟手机安装APP差不多,所以在H7-TOOL里面被广泛使用&#xff…

Go语言中三个输入函数(scanf,scan,scanln)的区别

Go语言中三个输入函数(scanf,scan,scanln)的区别 在 Go 语言中,fmt 包提供了三种输入函数:Scanf、Scan 和 Scanln。这三个函数都是用于从标准输入读取数据并存储到变量中,但是它们在处理输入的方式上有所不同。下面详细解读每个函数的特点和…

网站被浏览器提示“不安全”,如何快速解决

当网站被浏览器提示“不安全”时,这通常意味着网站存在某些安全隐患,需要立即采取措施进行解决。 一、具体原因如下: 1.如果网站使用的是HTTP协议,应立即升级HTTPS。HTTPS通过使用SSL证书加密来保护数据传输,提高了网…

CSS设置层叠样式时报红(identifier expected css/selector expected css)

不规范语法 如上图所示,在一个 css 文件中添加层叠样式时报红:at-rule or selector expected,意思就是说我们的语句不符合 css 的语法书写规范,虽然不会导致启动报错并且还能达到预期的样式效果,但是对于有强迫症的同学…