إشعار
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تسجيل الدخول أو تغيير الدلائل.
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تغيير الدلائل.
Horovod هو إطار عمل تدريبي موزع لمكتبات مثل TensorFlow وPyTorch. باستخدام Horovod، يمكن للمستخدمين توسيع نطاق برنامج نصي للتدريب موجود للتشغيل على مئات وحدات معالجة الرسومات في بضعة أسطر فقط من التعليمات البرمجية.
داخل Azure Synapse Analytics، يمكن للمستخدمين البدء بسرعة في Horovod باستخدام وقت تشغيل Apache Spark 3 الافتراضي. بالنسبة لتطبيقات البنية الأساسية لبرنامج ربط العمليات التجارية ل Spark ML باستخدام PyTorch، يمكن للمستخدمين استخدام واجهة برمجة تطبيقات مقدر horovod.spark. يستخدم دفتر الملاحظات هذا إطار بيانات Apache Spark لإجراء تدريب موزع لنموذج شبكة عصبية موزعة (DNN) على مجموعة بيانات MNIST. يستخدم هذا البرنامج التعليمي PyTorch و Horovod Estimator لتشغيل عملية التدريب.
المتطلبات الأساسية
- مساحة عمل Azure Synapse Analytics مع حساب تخزين Azure Data Lake Storage Gen2 الذي تم تكوينه كمخزن افتراضي. يجب أن تكون Storage Blob Data Contributor لنظام ملفات Data Lake Storage Gen2 التي تعمل معها.
- قم بإنشاء تجمع Apache Spark ممكّن بواسطة GPU في مساحة عمل تحليلات Azure Synapse. للحصول على التفاصيل، راجع إنشاء تجمع Apache Spark ممكّن بواسطة GPU في Azure Synapse. بالنسبة لهذا البرنامج التعليمي، نقترح استخدام حجم نظام مجموعة GPU-Large مع 3 عقد.
إشعار
تم إهمال معاينة التجمعات الممكنة ل Azure Synapse GPU.
تكوين جلسة Apache Spark
في بداية الجلسة، نحتاج إلى تكوين بعض إعدادات Apache Spark. في معظم الحالات، نحتاج فقط إلى تعيين numExecutors وspark.rapids.memory.gpu.reserve. بالنسبة للنماذج الكبيرة، قد يحتاج المستخدمون أيضا إلى تكوين spark.kryoserializer.buffer.max الإعداد. بالنسبة لنماذج TensorFlow، يحتاج المستخدمون إلى تعيين spark.executorEnv.TF_FORCE_GPU_ALLOW_GROWTH ليكون صحيحا.
في المثال، يمكنك أن ترى كيف يمكن تمرير تكوينات Spark باستخدام %%configure الأمر . يتم شرح المعنى التفصيلي لكل معلمة في وثائق تكوين Apache Spark. القيم المقدمة هي قيم أفضل الممارسات المقترحة لتجمعات Azure Synapse GPU الكبيرة.
%%configure -f
{
"driverMemory": "30g",
"driverCores": 4,
"executorMemory": "60g",
"executorCores": 12,
"numExecutors": 3,
"conf":{
"spark.rapids.memory.gpu.reserve": "10g",
"spark.executorEnv.TF_FORCE_GPU_ALLOW_GROWTH": "true",
"spark.kryoserializer.buffer.max": "2000m"
}
}
لهذا البرنامج التعليمي، سنستخدم التكوينات التالية:
%%configure -f
{
"numExecutors": 3,
"conf":{
"spark.rapids.memory.gpu.reserve": "10g"
}
}
إشعار
عند التدريب باستخدام Horovod، يجب على المستخدمين تعيين تكوين Spark ليكون numExecutors أقل أو مساويًا لعدد العقد.
استيراد التبعيات
في هذا البرنامج التعليمي، نستخدم PySpark لقراءة مجموعة البيانات ومعالجتها. ثم نستخدم PyTorch وHorovod لبناء نموذج الشبكة العصبية الموزعة (DNN) وتشغيل عملية التدريب. للبدء، نحتاج إلى استيراد التبعيات التالية:
# base libs
import sys
import uuid
# numpy
import numpy as np
# pyspark related
import pyspark
import pyspark.sql.types as T
from pyspark.ml.evaluation import MulticlassClassificationEvaluator
from pyspark.sql import SparkSession
from pyspark.sql.functions import udf
# pytorch related
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
# horovod related
import horovod.spark.torch as hvd
from horovod.spark.common.backend import SparkBackend
from horovod.spark.common.store import Store
# azure related
from azure.synapse.ml.horovodutils import AdlsStore
الاتصال بحساب تخزين بديل
نحن بحاجة إلى حساب Azure Data Lake Storage (ADLS) لتخزين البيانات المتوسطة والنموذجية. إذا كنت تستخدم حساب تخزين بديلا، فتأكد من إعداد الخدمة المرتبطة للمصادقة والقراءة تلقائيا من الحساب. بالإضافة إلى ذلك، تحتاج إلى تعديل الخصائص التالية: remote_urlو account_nameو.linked_service_name
num_proc = 3 # equal to numExecutors
batch_size = 128
epochs = 3
lr_single_node = 0.01 # learning rate for single node code
uuid_str = str(uuid.uuid4()) # with uuid, each run will use a new directory
work_dir = '/tmp/' + uuid_str
# create adls store for model training, use your own adls account info
remote_url = "<<ABFS path to storage account>>"
account_name = "<<name of storage account>>"
linked_service_name = "<<name of linked service>>"
sas_token = TokenLibrary.getConnectionString(linked_service_name)
adls_store_path = remote_url + work_dir
store = AdlsStore.create(adls_store_path,
storage_options={
'account_name': account_name,
'sas_token': sas_token
},
save_runs=True)
print(adls_store_path)
إعداد مجموعة البيانات
بعد ذلك، سنقوم بإعداد مجموعة البيانات للتدريب. في هذا البرنامج التعليمي، سنستخدم مجموعة بيانات MNIST من Azure Open Datasets.
# Initialize SparkSession
spark = SparkSession.builder.getOrCreate()
# Download MNIST dataset from Azure Open Datasets
from azureml.opendatasets import MNIST
mnist = MNIST.get_tabular_dataset()
mnist_df = mnist.to_pandas_dataframe()
mnist_df.info()
# Preprocess dataset
mnist_df['features'] = mnist_df.iloc[:, :784].values.tolist()
mnist_df.drop(mnist_df.iloc[:, :784], inplace=True, axis=1)
mnist_df.head()
معالجة البيانات باستخدام Apache Spark
الآن، سنقوم بإنشاء إطار بيانات Apache Spark. سيتم استخدام إطار البيانات هذا مع HorovodEstimator للتدريب.
# Create Spark DataFrame for training
df = spark.createDataFrame(mnist_df)
# repartition DataFrame for training
train_df = df.repartition(num_proc)
# Train/test split
train_df, test_df = train_df.randomSplit([0.9, 0.1])
# show the dataset
train_df.show()
train_df.count()
تعريف نموذج DNN
بمجرد الانتهاء من معالجة مجموعة البيانات الخاصة بنا، يمكننا الآن تحديد نموذج PyTorch. يمكن أيضًا استخدام نفس التعليمة البرمجية لتدريب نموذج PyTorch أحادي العقدة.
# Define the PyTorch model without any Horovod-specific parameters
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
self.conv2_drop = nn.Dropout2d()
self.fc1 = nn.Linear(320, 50)
self.fc2 = nn.Linear(50, 10)
def forward(self, x):
x = x.float()
x = F.relu(F.max_pool2d(self.conv1(x), 2))
x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
x = x.view(-1, 320)
x = F.relu(self.fc1(x))
x = F.dropout(x, training=self.training)
x = self.fc2(x)
return F.log_softmax(x)
model = Net()
optimizer = optim.SGD(model.parameters(),
lr=lr_single_node * num_proc,
momentum=0.5) # notice the lr is scaled up
loss = nn.NLLLoss()
نموذج التدريب
الآن، يمكننا تدريب مقدر Horovod Spark على أعلى إطار بيانات Apache Spark.
# Train a Horovod Spark Estimator on the DataFrame
backend = SparkBackend(num_proc=num_proc,
stdout=sys.stdout,
stderr=sys.stderr,
prefix_output_with_timestamp=True)
torch_estimator = hvd.TorchEstimator(
backend=backend,
store=store,
partitions_per_process=1, # important for GPU training
model=model,
optimizer=optimizer,
loss=lambda input, target: loss(input, target.long()),
input_shapes=[[-1, 1, 28, 28]],
feature_cols=['features'],
label_cols=['label'],
batch_size=batch_size,
epochs=epochs,
validation=0.1,
verbose=2)
torch_model = torch_estimator.fit(train_df).setOutputCols(['label_prob'])
تقييم النموذج المدرب
بمجرد اكتمال عملية التدريب، يمكننا بعد ذلك تقييم النموذج على مجموعة بيانات الاختبار.
# Evaluate the model on the held-out test DataFrame
pred_df = torch_model.transform(test_df)
argmax = udf(lambda v: float(np.argmax(v)), returnType=T.DoubleType())
pred_df = pred_df.withColumn('label_pred', argmax(pred_df.label_prob))
evaluator = MulticlassClassificationEvaluator(predictionCol='label_pred',
labelCol='label',
metricName='accuracy')
print('Test accuracy:', evaluator.evaluate(pred_df))
تنظيف الموارد
لضمان إيقاف تشغيل مثيل Spark، قم بإنهاء أي جلسات عمل متصلة (دفاتر ملاحظات). يتم إيقاف تشغيل التجمع عند الوصول إلى وقت الخمول المحدد في تجمع Apache Spark. يمكنك أيضا تحديد "stop session" من شريط المعلومات في أسفل دفتر الملاحظات.