برنامه نویسی

استقرار Kubeflow و برنامه های استفاده از عملکرد اصلی

Summarize this content to 400 words in Persian Lang این مقاله به طور مختصر به معرفی kubeflow و روش های استقرار و استفاده از آن می پردازد. اخیراً در حال تحقیق بر روی پلت فرم kubeflow بودم و متوجه شدم که اطلاعات کمتری به صورت آنلاین وجود دارد. علاوه بر این، تکرار نسخه آن سریعتر است و برخی از روش های فراخوانی و استفاده تغییر کرده است. با توجه به محتوای کار، برخی از عملکردهای اصلی آن مانند تنظیم پارامتر katib، ساخت خط لوله kubeflow و ایجاد چند کاربر انجام شده است. منتظر موارد خاص باشید

kubeflow

Kubeflow یک پلتفرم منبع باز است که برای استقرار، مدیریت و مقیاس‌بندی جریان‌های کاری یادگیری ماشین (ML) در Kubernetes طراحی شده است، با هدف ساده‌سازی استقرار و عملیات پروژه‌های یادگیری ماشین در محیط‌های تولید. توابع ارکستراسیون کانتینر و مدیریت منابع بر اساس Kubernetes. Kubeflow با تقسیم گردش کار یادگیری ماشین به مجموعه‌ای از وظایف محفظه‌ای، می‌تواند از قابلیت‌های مقیاس‌بندی خودکار، تحمل خطا و زمان‌بندی Kubernetes برای اطمینان از اجرای کارآمد وظایف یادگیری ماشین استفاده کند. Kubeflow مجموعه کاملی از ابزارها و خدمات را برای پشتیبانی از همه چیز از کل چرخه زندگی یادگیری ماشین از آماده سازی داده ها، آموزش مدل، تنظیم تا استقرار ارائه می دهد. این راه حل انتها به انتها به دانشمندان و مهندسان داده کمک می کند تا به سرعت از توسعه به تولید منتقل شوند.

به طور کلی، kubeflow از اجزای زیر تشکیل شده است

داشبورد مرکزی Kubeflow یک رابط وب برای دسترسی به Kubeflow و اجزای آن فراهم می کند. این به عنوان یک مرکز متمرکز عمل می کند و ابزارها و خدمات مختلف را در داخل خوشه برای مدیریت آسان تر پلت فرم یادگیری ماشین یکپارچه می کند.
Kubeflow با نوت بوک های Jupyter برای ارائه یک محیط تعاملی برای اکتشاف داده، آزمایش و توسعه مدل. نوت‌بوک‌ها از چندین زبان مانند Python، R و Scala پشتیبانی می‌کنند و گردش‌های کاری ML مشترک و قابل تکرار را امکان‌پذیر می‌سازند.

خطوط لوله Kubeflow به کاربران اجازه می‌دهد تا گردش‌های کاری پیچیده ML را به‌عنوان نمودارهای غیر چرخه مستقیم (DAG) تعریف و اجرا کنند. این خطوط لوله به خودکارسازی و مدیریت فرآیندهای سرتاسری مانند پیش پردازش داده ها، آموزش مدل، ارزیابی و استقرار، افزایش تکرارپذیری و همکاری کمک می کند. Kubeflow Pipelines SDK مجموعه ای از بسته های پایتون برای تعریف و اجرای کارآمد گردش کار ML است.

اپراتور آموزش Kubeflow ابزارهایی را برای آموزش مدل‌های ML در مقیاس بزرگ فراهم می‌کند و از آموزش توزیع‌شده با چارچوب‌هایی مانند TensorFlow، PyTorch و XGBoost پشتیبانی می‌کند. از مقیاس پذیری و مدیریت منابع Kubernetes برای آموزش مدل کارآمد در سراسر خوشه ها استفاده می کند.

سرویس Kubeflow استقرار مدل‌های آموزش‌دیده ML را به‌عنوان سرویس‌های مقیاس‌پذیر، آماده تولید، چارچوب‌های پشتیبانی مانند TensorFlow Serving، Seldon Core یا سرورهای سفارشی امکان‌پذیر می‌کند. مدل ها را می توان برای پیش بینی های زمان واقعی یا دسته ای از طریق نقاط پایانی HTTP مستقر کرد.

فراداده Kubeflow یک مخزن متمرکز برای مدیریت ابرداده‌های مربوط به آزمایش‌ها، اجراها و مصنوعات ML است که از تکرارپذیری، همکاری و حاکمیت در سراسر گردش کار اطمینان می‌دهد.

راه اندازی محیط

شرط لازم برای استقرار Kubeflow داشتن یک کلاستر است. من از Kubernetes نسخه 1.26 استفاده می کنم که با kubeadm نصب و اجرا شده است. نسخه Kubeflow مربوطه 1.8.1 است.

نصب NFS

از آنجایی که استقرار Kubeflow به یک کلاس ذخیره سازی پیش فرض نیاز دارد، در اینجا نحوه نصب و استقرار فایل سیستم NFS با nfs-subdir-external-provisioner آورده شده است.

طبق اسناد رسمی، نصب Kubeflow با استفاده از مانیفست Kubeflow نیاز به یک پیش فرض دارد کلاس ذخیره سازی، سفارشی کردن، و کوبکتل ابزار. برای استفاده از کلاس ذخیره سازی پیش فرض، nfs-subdir-external-provisioner مستقر شده است. این می تواند به طور خودکار روابط PV و PVC را ایجاد و مدیریت کند. در زیر مراحل نصب و استقرار NFS و افزونه NFS آورده شده است.

با استفاده از دستور سرویس NFS را نصب کنید apt install -y nfs-kernel-server.

ایجاد دایرکتوری ذخیره سازی داده با mkdir -p /data/redis.

با افزودن دایرکتوری پیکربندی جدید، محتویات فایل /etc/exports را تغییر دهید: /data/redis 192.168.0.0/24(rw,sync,no_all_squash,no_subtree_check,no_root_squash).

پس از انجام مراحل بالا، سرویس NFS را مجددا راه اندازی کنید.

استقرار NFS-Subdir-External-Provisioner

NFS-Subdir-External-Provisioner یک ارائه دهنده حجم پویا است که از یک سرور NFS موجود و پیکربندی شده برای پشتیبانی از ارائه پویا حجم های پایدار Kubernetes از طریق ادعاهای حجم دائمی استفاده می کند.

قبل از استقرار سرویس NFS-subdir، مطمئن شوید که یک گره با سرویس NFS دارید و دایرکتوری ذخیره سازی مربوطه را می شناسید. در مثال بالا، گره و دایرکتوری هستند 192.168.0.208 و /data/redisبه ترتیب

یک حساب کاربری ایجاد کنید

apiVersion: v1

kind: ServiceAccount

metadata:

  name: nfs-client-provisioner

  namespace: default _#_ _替换成你要部署的_ _Namespace_

kind: ClusterRole

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: nfs-client-provisioner-runner

rules:

  – apiGroups: [“”]

    resources: [“persistentvolumes”]

    verbs: [“get”, “list”, “watch”, “create”, “delete”]

  – apiGroups: [“”]

    resources: [“persistentvolumeclaims”]

    verbs: [“get”, “list”, “watch”, “update”]

  – apiGroups: [“storage.k8s.io”]

    resources: [“storageclasses”]

    verbs: [“get”, “list”, “watch”]

  – apiGroups: [“”]

    resources: [“events”]

    verbs: [“create”, “update”, “patch”]

kind: ClusterRoleBinding

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: run-nfs-client-provisioner

subjects:

  – kind: ServiceAccount

    name: nfs-client-provisioner

    namespace: default

roleRef:

  kind: ClusterRole

  name: nfs-client-provisioner-runner

  apiGroup: rbac.authorization.k8s.io

kind: Role

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: leader-locking-nfs-client-provisioner

  namespace: default

rules:

  – apiGroups: [“”]

    resources: [“endpoints”]

    verbs: [“get”, “list”, “watch”, “create”, “update”, “patch”]

kind: RoleBinding

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: leader-locking-nfs-client-provisioner

  namespace: default

subjects:

  – kind: ServiceAccount

    name: nfs-client-provisioner

    namespace: default

roleRef:

  kind: Role

  name: leader-locking-nfs-client-provisioner

  apiGroup: rbac.authorization.k8s.io

NFS-Subdir-External-Provisioner را مستقر کنید و پارامترهای پیکربندی را در صورت نیاز تغییر دهید:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
labels:
app: nfs-client-provisioner
spec:
replicas: 1
strategy:
type: Recreate # Set upgrade strategy to Recreate (default is RollingUpdate)
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
– name: nfs-client-provisioner
# image: gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner:v4.0.0
image: registry.cn-beijing.aliyuncs.com/xngczl/nfs-subdir-external-provisione:v4.0.0
volumeMounts:
– name: nfs-client-root
mountPath: /persistentvolumes
env:
– name: PROVISIONER_NAME # Name of the provisioner, must match the name set in the storage class
value: nfs-client
– name: NFS_SERVER # NFS server address, must match the value in the volumes parameter
value: 192.168.0.208
– name: NFS_PATH # NFS server data storage directory, must match the value in the volumes parameter
value: /data/redis
volumes:
– name: nfs-client-root
nfs:
server: 192.168.0.208 # NFS server address
path: /data/redis # NFS server data storage directory

ایجاد NFS StorageClass:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storage
annotations:
storageclass.kubernetes.io/is-default-class: “true” # Set as the default storage class
provisioner: nfs-client # Must match the provisioner name set in the deployment
parameters:
archiveOnDelete: “true” # Set to “false” to delete PVC without retaining data; “true” retains data

سپس فایل های بالا را با استفاده از kubectl application -f اعمال کنید. همچنین، با chmod 777 /data/redis، به دایرکتوری ذخیره سازی NFS مجوز بدهید.

نصب Kubeflow

بسته باینری مربوطه skustomize_v5.0.3_linux_amd64.tar.gz را از مخزن رسمی GitHub پروژه مانیفست Kubeflow دانلود کرده و آن را در /usr/local/bin دایرکتوری بسته رسمی Kubeflow manifest mainfests-1.8.1.tar.gz را دانلود کنید.

StorageClass پیش فرض را تغییر دهید

فایل های YAML را با افزودن ویرایش کنید storageClassName: nfs-storage در فایل های زیر واقع در mainfests-1.8.1 دایرکتوری:

apps/katib/upstream/components/mysql/pvc.yaml
common/oidc-client/oidc-authservice/base/pvc.yaml
apps/pipeline/upstream/third-party/minio/base/minio-pvc.yaml
apps/pipeline/upstream/third-party/mysql/base/mysql-pv-claim.yaml

APP_SECURE_COOKIES را اصلاح کنید

فایل پیکربندی را برای تنظیم ویرایش کنید APP_SECURE_COOKIES=false، که استفاده از کوکی های امن را غیرفعال می کند.

باز کردن فایل با:
vim ./apps/jupyter/jupyter-web-app/upstream/base/params.env

تنظیم کنید APP_SECURE_COOKIES به false برای اطمینان از دسترسی داشبورد به Kubeflow پس از استقرار. همچنین می توانید نمونه های دیگری را که ممکن است به این تغییر نیاز داشته باشند با استفاده از دستور زیر بررسی کنید:

find ./ -type f -exec grep -l “APP_SECURE_COOKIES” {} ;
در بیشتر موارد، فقط پیکربندی Jupyter Web App (JWP) به این به‌روزرسانی نیاز دارد.

Kubeflow را مستقر کنید

پس از انجام تغییرات لازم در پیکربندی، به دایرکتوری مانیفست رفته و دستور زیر را برای استقرار خودکار Kubeflow اجرا کنید. به دلیل تعداد زیاد وابستگی ها، ممکن است مشکلاتی در حین نصب ایجاد شود. تنظیمات قبلی باید اکثر مشکلات را حل کنند، اما اگر نصب با مشکل مواجه شود یا پادها به درستی اجرا نشوند، ممکن است نیاز به عیب یابی بیشتری باشد.

while ! kustomize build example | kubectl apply -f -; do echo “Retrying to apply resources”; sleep 10; done

SVC را به NodePort Mode تغییر دهید

از آنجایی که سرویس های مستقر همه از نوع ClusterIP هستند، نمی توان به آنها دسترسی خارجی داشت. بنابراین، شما باید به صورت دستی تغییر دهید istio-ingressgateway سرویس به نوع NodePort.
k edit svc -n istio-system istio-ingressgateway

اعتبار پیش فرض ورود به سیستم عبارتند از:

نام کاربری: user@example.com

رمز عبور: 12341234

با استفاده از Kubeflow

در زیر مقدمه ای بر اجزای کلیدی Kubeflow آورده شده است:

سرورهای نوت بوک: این ابزارها به عنوان ابزاری برای مدیریت آزمایش‌های تعاملی عمل می‌کنند و به محققان کمک می‌کنند تا آزمایش‌های الگوریتمی را سریع انجام دهند. آنها همچنین قابلیت های یکپارچه مدیریت اسناد را ارائه می دهند.

AutoML: این کار فرآیندهایی مانند مهندسی ویژگی، انتخاب مدل، تنظیم فراپارامتر و ارزیابی مدل را خودکار می‌کند و تعداد آزمایش‌های دستی مورد نیاز را کاهش می‌دهد.

خط لوله: یک ابزار مهندسی که مراحل مختلف یک گردش کار الگوریتمی را در نمودار توپولوژی سازماندهی می کند. می توان آن را با Argo برای پیاده سازی MLO ها ترکیب کرد.

بدون سرور: این اجازه می دهد تا مدل ها به طور مستقیم به عنوان خدمات مستقر شوند و مسیر از آزمایش تا تولید را کوتاه کنند.

توسعه مدل – نوت بوک

نوت‌بوک‌های Kubeflow یک جزء حیاتی از پلتفرم Kubeflow است که به دانشمندان داده و مهندسان ML امکان می‌دهد تا نوت‌بوک‌های Jupyter را روی Kubernetes اجرا کنند. این امر به طور قابل توجهی مدیریت و استفاده از نوت بوک های Jupyter را در محیط های ابری ساده می کند. با Kubeflow Notebooks، کاربران به راحتی می توانند چندین نمونه Jupyter Notebook را در یک خوشه Kubernetes ایجاد و مدیریت کنند. این نمونه ها را می توان با منابع خاصی مانند CPU، حافظه و GPU پیکربندی کرد و از جداسازی و استفاده کارآمد از منابع در یک محیط چند کاربره اطمینان حاصل کرد.

یک کار جدید از طریق رابط نوت بوک ایجاد کنید:

در صفحه پیکربندی، می توانید نام را تنظیم کنید و منابعی مانند CPU و GPU را اختصاص دهید. پس از ایجاد، غلاف مربوطه ظاهر می شود. برای استفاده از GPU، به اسناد رسمی مراجعه کنید.

برای پیوند به پاد مربوطه، روی “اتصال” کلیک کنید. در این مرحله، ممکن است در کشیدن تصاویر با مشکلاتی مواجه شوید که قبل از اجرا شدن پاد، نیاز به کشیدن دستی تصویر به گره مشخص شده است.

آموزش مدل

هنگام ایجاد یک نوت بوک، می توانید یک تصویر را با TensorFlow انتخاب کنید و به شما امکان می دهد مستقیماً از چارچوب استفاده کنید. تصاویر دیگری مانند PyTorch-CUDA نیز در دسترس هستند. پس از راه اندازی، می توانید یک کد آموزشی ساده مانند شکل زیر اجرا کنید:

import numpy as np

import tensorflow as tf

from tensorflow.keras.datasets import mnist

from tensorflow.keras.utils import to_categorical

from tensorflow.keras.models import Sequential

from tensorflow.keras.layers import Dense, Flatten, Dropout, Conv2D, MaxPooling2D

_#_ _加载__MNIST__数据集_

(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

_#_ _预处理数据:调整形状并归一化_

train_images = train_images.reshape(-1, 28, 28, 1).astype(‘float32’) / 255.0

test_images = test_images.reshape(-1, 28, 28, 1).astype(‘float32′) / 255.0

_#_ _将标签转换为_ _one-hot_ _编码_

train_labels = to_categorical(train_labels, 10)

test_labels = to_categorical(test_labels, 10)

_#_ _构建模型_

model = Sequential([

    Conv2D(32, kernel_size=(3, 3), activation=’relu’, input_shape=(28, 28, 1)),

    MaxPooling2D(pool_size=(2, 2)),

    Conv2D(64, kernel_size=(3, 3), activation=’relu’),

    MaxPooling2D(pool_size=(2, 2)),

    Flatten(),

    Dense(128, activation=’relu’),

    Dropout(0.5),

    Dense(10, activation=’softmax’)

])

_#_ _编译模型_

model.compile(optimizer=”adam”,

              loss=”categorical_crossentropy”,

              metrics=[‘accuracy’])

_#_ _训练模型_

model.fit(train_images, train_labels, epochs=10, batch_size=64, validation_data=(test_images, test_labels))

_#_ _评估模型_

test_loss, test_accuracy = model.evaluate(test_images, test_labels, verbose=0)

print(f”Test accuracy: {test_accuracy:.4f}”)

# 保存模型

model.save(‘mnist_cnn_model.keras’)

print(“模型保存成功”)

و ما داریم

همچنین می‌توانیم کتاب‌های جدید ژوپیتر را ویرایش کنیم

import numpy as np

import tensorflow as tf

from PIL import Image, ImageOps, ImageFilter

import matplotlib.pyplot as plt

_#_ _加载保存的模型_

loaded_model = tf.keras.models.load_model(‘mnist_cnn_model.keras’)

定义你自己的图片文件名列表

image_files = [

    ‘mnist_test_0_label_9.png’,

    ‘mnist_test_2_label_8.png’,

    ‘mnist_test_4_label_2.png’,

    ‘mnist_test_1_label_0.png’,

    ‘mnist_test_3_label_7.png’

]

_#image_files = [‘__图片__.jpg’, ‘123.jpg’, ‘third.jpg’, ‘9.jpg’]_

def preprocess_image(img):

    _#_ _转换为灰度图像_

    img = img.convert(‘L’)

    _#_ _自动对比度增强_

    img = ImageOps.autocontrast(img)

    _#_ _裁剪数字的边缘并居中_

    img = img.crop(img.getbbox())  _#_ _裁剪非空白区域_

    img = img.resize((20, 20), Image.Resampling.LANCZOS)  _#_ _调整图像大小,保持最大信息_

    background = Image.new(‘L’, (28, 28), 0)  _#_ _创建黑色背景_

    offset = ((28 – img.size[0]) // 2, (28 – img.size[1]) // 2)

    background.paste(img, offset)  _#_ _将图像粘贴到背景上使其居中_

    return background

_#_ _创建一个图形,包含__5__行__2__列的子图_

fig, axs = plt.subplots(5, 2, figsize=(10, 25))

_#fig, axs = plt.subplots(4, 2, figsize=(10, 25))_

for i, file in enumerate(image_files):

    _#_ _加载图像_

    img = Image.open(file)

    _#_ _对图像进行预处理_

    processed_img = preprocess_image(img)

    _#_ _将图像转换为数组并进行标准化,确保形状为_ _(28, 28, 1)_

    img_array = np.array(processed_img).reshape(1, 28, 28, 1).astype(‘float32′) / 255.0

    _#_ _进行预测_

    predictions = loaded_model.predict(img_array)

    _#_ _获取预测结果_

    predicted_digit = np.argmax(predictions[0])

    _#_ _显示原始图片_

    axs[i, 0].imshow(img, cmap=’gray’)

    axs[i, 0].set_title(f’原始图片: {file}’)

    axs[i, 0].axis(‘off’)

    _#_ _显示处理后的图片_

    axs[i, 1].imshow(processed_img, cmap=’gray’)

    axs[i, 1].set_title(f’预测结果: {predicted_digit}’)

    axs[i, 1].axis(‘off’)

    print(f”{file} 预测的数字是: {predicted_digit}”)

plt.tight_layout()

plt.show()

آموزش GPU

استفاده از تصویر GPU به منابع GPU در خوشه ما نیاز دارد، همانطور که در زیر نشان داده شده است:

هنگام انتخاب یک تصویر GPU، اگر می‌خواهید یک GPU اضافه کنید اما پیامی دریافت می‌کنید که نشان می‌دهد هیچ GPU در خوشه موجود نیست، باید یک GPU را به صورت فیزیکی روی یک گره نصب کنید و سپس یک اپراتور به خوشه اضافه کنید تا از منابع GPU استفاده کند. .

در زیر روش نصب اپراتور NVIDIA GPU آورده شده است:
مرجع: راهنمای نصب اپراتور رسمی NVIDIA

Download and prepare Helm 3:

curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
&& chmod 700 get_helm.sh
&& ./get_helm.sh

Ensure NFD mode is disabled; if it’s enabled, manually turn it off:

kubectl get nodes -o json | jq ‘.items[].metadata.labels | keys | any(startswith(“feature.node.kubernetes.io”))’

Add the NVIDIA Helm repository:

helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
&& helm repo update

Deploy the GPU Operator:

helm install –wait –generate-name
-n gpu-operator –create-namespace
nvidia/gpu-operator
–set driver.version=535

توجه داشته باشید که نسخه درایور باید با مدل GPU خاص شما مطابقت داشته باشد. به عنوان مثال، من از نسخه 535 استفاده کردم زیرا پردازنده گرافیکی A800 دارم. اطمینان حاصل کنید که نسخه صحیح درایور را بر اساس مدل NVIDIA GPU خود انتخاب کنید.

پس از اجرای دستورات، باید موارد زیر را مشاهده کنید:

گره اکنون منابع قابل زمانبندی را به عنوان نشان می دهد nvidia.com/gpu:

Kubeflow را باز کنید تا از GPU برای کارهای آموزشی استفاده کنید. در این صفحه، تصویری را که شامل CUDA می‌شود، مشخص کنید و پردازنده گرافیکی NVIDIA موجود در خوشه در پیکربندی GPU را انتخاب کنید.

پس از راه اندازی، وارد Jupyter شوید و یک محیط Python 3 ایجاد کنید. سپس می توانید کد یادگیری ماشین را توسعه دهید و از آن استفاده کنید nvidia-smi دستور در پاد برای بررسی و استفاده از GPU.

در زیر کد آموزش با استفاده از GPU آورده شده است:

import os

import tensorflow as tf

import time

import numpy as np

from tensorflow.keras import layers, models

import matplotlib.pyplot as plt

print(“====检查 GPU 可用性====”)

os.environ[‘TF_FORCE_GPU_ALLOW_GROWTH’] = ‘true’

_#_ _检查_ _GPU_ _是否可用_

if tf.test.is_gpu_available():

    print(“\033[1;32m[GPU 可用] 将进行 GPU 和 CPU 训练对比\033[0m”)

    gpu_device = tf.config.list_physical_devices(‘GPU’)[0]

    print(f”可用的 GPU: {gpu_device}”)

else:

    print(“\033[1;31m[GPU 不可用] 只能使用 CPU 进行训练\033[0m”)

    exit()

print(“\n====加载和预处理数据====”)

(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()

train_images = train_images.reshape((60000, 28, 28, 1)).astype(‘float32’) / 255

test_images = test_images.reshape((10000, 28, 28, 1)).astype(‘float32′) / 255

def create_model():

    model = models.Sequential([

        layers.Conv2D(32, (3, 3), activation=’relu’, input_shape=(28, 28, 1)),

        layers.MaxPooling2D((2, 2)),

        layers.Conv2D(64, (3, 3), activation=’relu’),

        layers.MaxPooling2D((2, 2)),

        layers.Conv2D(64, (3, 3), activation=’relu’),

        layers.Flatten(),

        layers.Dense(64, activation=’relu’),

        layers.Dense(10, activation=’softmax’)

    ])

    model.compile(optimizer=”adam”,

                  loss=”sparse_categorical_crossentropy”,

                  metrics=[‘accuracy’])

    return model

_# GPU_ _训练_

print(“\n====开始 GPU 训练====”)

with tf.device(‘/GPU:0’):

    gpu_model = create_model()

    start_time = time.time()

    gpu_history = gpu_model.fit(train_images, train_labels, epochs=10,

                                validation_split=0.2, batch_size=64, verbose=1)

    gpu_time = time.time() – start_time

_# CPU_ _训练_

print(“\n====开始 CPU 训练====”)

os.environ[‘CUDA_VISIBLE_DEVICES’] = ‘-1’  _#_ _禁用_ _GPU_

with tf.device(‘/CPU:0’):

    cpu_model = create_model()

    start_time = time.time()

    cpu_history = cpu_model.fit(train_images, train_labels, epochs=10,

                                validation_split=0.2, batch_size=64, verbose=1)

    cpu_time = time.time() – start_time

_#_ _结果对比_

print(“\n====训练时间对比====”)

print(f”\033[1;34mGPU 训练时间: {gpu_time:.2f} 秒\033[0m”)

print(f”\033[1;34mCPU 训练时间: {cpu_time:.2f} 秒\033[0m”)

print(f”\033[1;32mGPU 加速比: {cpu_time / gpu_time:.2f}x\033[0m”)

_#_ _绘制训练过程的损失和准确率曲线_

def plot_history(history, title):

    acc = history.history[‘accuracy’]

    val_acc = history.history[‘val_accuracy’]

    loss = history.history[‘loss’]

    val_loss = history.history[‘val_loss’]

    epochs = range(1, len(acc) + 1)

    plt.figure(figsize=(12, 5))

    plt.subplot(1, 2, 1)

    plt.plot(epochs, loss, ‘bo-‘, label=”Training loss”)

    plt.plot(epochs, val_loss, ‘ro-‘, label=”Validation loss”)

    plt.title(f'{title} – Training and validation loss’)

    plt.xlabel(‘Epochs’)

    plt.ylabel(‘Loss’)

    plt.legend()

    plt.subplot(1, 2, 2)

    plt.plot(epochs, acc, ‘bo-‘, label=”Training accuracy”)

    plt.plot(epochs, val_acc, ‘ro-‘, label=”Validation accuracy”)

    plt.title(f'{title} – Training and validation accuracy’)

    plt.xlabel(‘Epochs’)

    plt.ylabel(‘Accuracy’)

    plt.legend()

    plt.show()

print(“\n====可视化 GPU 训练过程====”)

plot_history(gpu_history, “GPU Training”)

print(“\n====可视化 CPU 训练过程====”)

plot_history(cpu_history, “CPU Training”)

_#_ _评估_ _GPU_ _模型_

print(“\n====评估 GPU 训练的模型====”)

test_loss, test_acc = gpu_model.evaluate(test_images, test_labels, verbose=0)

print(f’\n\033[1;32mTest accuracy: {test_acc:.4f}\033[0m’)

_#_ _保存_ _GPU_ _训练的模型_

print(“\n====保存 GPU 训练的模型====”)

gpu_model.save(‘mnist_model_gpu.keras’)

print(“模型已保存为 mnist_model_gpu.keras”)

این کد قدرت محاسباتی قابل توجه GPU ها را در مقایسه با CPU ها به ویژه در وظایف یادگیری عمیق نشان می دهد. کد ابتدا GPU های موجود در محیط را بررسی می کند و سپس یک شبکه عصبی کانولوشنال ساده (CNN) را در هر دو GPU و CPU با استفاده از مجموعه داده ارقام دست نویس MNIST برای طبقه بندی آموزش می دهد.

در طول آموزش، می توانید استفاده از GPU را با استفاده از nvidia-smi دستور، که بینش‌های بی‌درنگ در مورد استفاده از GPU ارائه می‌کند.

همانطور که در تصویر نشان داده شده است، استفاده از GPU در طول آموزش حدود 9٪ است که نشان می دهد این کار با موفقیت GPU را برای محاسبات اهرم کرده است.

خط لوله

خطوط لوله Kubeflow یک ماژول اصلی در پروژه Kubeflow است که بر ساخت، استقرار و مدیریت گردش‌های کاری پیچیده یادگیری ماشین تمرکز دارد. مجموعه ای جامع از ابزارها را برای طراحی و خودکارسازی خطوط لوله ML ارائه می دهد که به دانشمندان و مهندسان داده اجازه می دهد تا به طور کارآمد فرآیندهای آموزش و استقرار مدل های ML را مدیریت و نظارت کنند. با Kubeflow Pipelines، کاربران به راحتی می‌توانند گردش‌های کاری پیچیده را تعریف، به اشتراک بگذارند، دوباره استفاده کنند و خودکار کنند.

در رابط خط لوله، می توانید از پیش ساخته شده آپلود کنید .gz یا .yaml فایل ها هنگامی که خط لوله ایجاد می شود، به صورت بصری در رابط گرافیکی مانند شکل زیر نمایش داده می شود. برای دستورالعمل های دقیق در مورد ایجاد خطوط لوله، به اسناد رسمی مراجعه کنید.

import kfp

from kfp import dsl

from kfp.dsl import component, Input, Output, Dataset, Model

_# Step 1:_ _数据下载和预处理_

@component(

    base_image=”python:3.8-slim”,

    packages_to_install=[

        ‘pandas’,

        ‘scikit-learn’,

        ‘joblib’,

        ‘numpy’,

        ‘requests’

    ]

)

def preprocess_data_op(output_data: Output[Dataset]):

    print(“开始执行 preprocess_data_op…”)

    try:

        import pandas as pd

        print(“成功导入 pandas 模块。”)

    except ImportError as e:

        print(f”导入 pandas 失败: {e}”)

        raise e

    from sklearn.model_selection import train_test_split

    from sklearn.preprocessing import StandardScaler

    import os

    print(“正在下载数据集…”)

    url = “https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv”

    columns = [‘Pregnancies’, ‘Glucose’, ‘BloodPressure’, ‘SkinThickness’, ‘Insulin’, ‘BMI’, ‘DiabetesPedigreeFunction’, ‘Age’, ‘Outcome’]

    data = pd.read_csv(url, names=columns)

    print(“数据集下载完成。”)

    _#_ _数据清洗和特征工程_

    print(“正在进行数据清洗和特征工程…”)

    X = data.drop(‘Outcome’, axis=1)

    y = data[‘Outcome’]

    _#_ _标准化特征_

    print(“正在标准化特征…”)

    scaler = StandardScaler()

    X_scaled = scaler.fit_transform(X)

    _#_ _划分训练集和测试集_

    print(“正在划分训练集和测试集…”)

    X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)

    _#_ _保存预处理后的数据_

    print(“正在保存预处理后的数据…”)

    os.makedirs(output_data.path, exist_ok=True)

    pd.DataFrame(X_train).to_csv(os.path.join(output_data.path, ‘X_train.csv’), index=False)

    pd.DataFrame(X_test).to_csv(os.path.join(output_data.path, ‘X_test.csv’), index=False)

    pd.DataFrame(y_train).to_csv(os.path.join(output_data.path, ‘y_train.csv’), index=False)

    pd.DataFrame(y_test).to_csv(os.path.join(output_data.path, ‘y_test.csv’), index=False)

    print(f”数据预处理完成并已保存到 {output_data.path}。”)

_# Step 2:_ _模型训练_

@component(

    base_image=”python:3.8-slim”,

    packages_to_install=[

        ‘pandas’,

        ‘scikit-learn’,

        ‘joblib’,

        ‘numpy’

    ]

)

def train_model_op(input_data: Input[Dataset], output_model: Output[Model]):

    print(“开始执行 train_model_op…”)

    try:

        import pandas as pd

        print(“成功导入 pandas 模块。”)

    except ImportError as e:

        print(f”导入 pandas 失败: {e}”)

        raise e

    from sklearn.linear_model import LogisticRegression

    import joblib

    import os

    print(“正在加载训练数据…”)

    X_train = pd.read_csv(os.path.join(input_data.path, ‘X_train.csv’))

    y_train = pd.read_csv(os.path.join(input_data.path, ‘y_train.csv’))

    _#_ _训练模型_

    print(“正在训练模型…”)

    model = LogisticRegression()

    model.fit(X_train, y_train.values.ravel())

    _#_ _创建输出目录并保存模型_

    os.makedirs(output_model.path, exist_ok=True)  _#_ _确保输出目录存在_

    model_path = os.path.join(output_model.path, ‘trained_model.joblib’)

    joblib.dump(model, model_path)

    print(f”模型训练完成并已保存到 {model_path}。”)

_# Step 3:_ _模型评估_

@component(

    base_image=”python:3.8-slim”,

    packages_to_install=[

        ‘pandas’,

        ‘scikit-learn’,

        ‘joblib’,

        ‘numpy’

    ]

)

def evaluate_model_op(input_data: Input[Dataset], input_model: Input[Model]):

    print(“开始执行 evaluate_model_op…”)

    try:

        import pandas as pd

        print(“成功导入 pandas 模块。”)

    except ImportError as e:

        print(f”导入 pandas 失败: {e}”)

        raise e

    from sklearn.metrics import accuracy_score

    import joblib

    import os  # 添加os模块的导入

    print(“正在加载测试数据和模型…”)

    X_test = pd.read_csv(os.path.join(input_data.path, ‘X_test.csv’))

    y_test = pd.read_csv(os.path.join(input_data.path, ‘y_test.csv’))

    model = joblib.load(os.path.join(input_model.path, ‘trained_model.joblib’))

    _#_ _预测和评估_

    print(“正在进行模型预测和评估…”)

    y_pred = model.predict(X_test)

    accuracy = accuracy_score(y_test, y_pred)

    print(f”模型准确率: {accuracy}”)

# Step 4: Pipeline 定义

@dsl.pipeline(

    name=”Diabetes Classifier Pipeline”,

    description=’A pipeline to train and evaluate a diabetes classifier model’

)

def diabetes_pipeline():

    preprocess = preprocess_data_op()

    train = train_model_op(input_data=preprocess.outputs[‘output_data’])

    evaluate = evaluate_model_op(input_data=preprocess.outputs[‘output_data’], input_model=train.outputs[‘output_model’])

# Compile the pipeline

if __name__ == “__main__”:

    kfp.compiler.Compiler().compile(diabetes_pipeline, ‘diabetes_pipeline.yaml’)

فایل فوق یک فایل خط لوله قابل استفاده است که می تواند در ماژول Pipelines باز شود. گردش کار اصلی به صورت زیر نشان داده شده است:

پس از اجرای خط لوله، نتایج به شرح زیر است:

این فایل پایتون در درجه اول خط لوله Kubeflow Pipelines (KFP) را برای پردازش داده ها، آموزش مدل یادگیری ماشین و ارزیابی برای طبقه بندی دیابت تعریف می کند.

فایل ابتدا تعریف می کند preprocess_data_op جزء، که مجموعه داده دیابت را دانلود می کند و پیش پردازش داده ها را انجام می دهد. این شامل تمیز کردن داده ها، استانداردسازی ویژگی ها، و تقسیم به مجموعه های آموزشی و آزمایشی است. داده های از پیش پردازش شده برای استفاده بعدی در آموزش و ارزیابی مدل در یک مسیر خروجی مشخص ذخیره می شوند.
بعد، train_model_op جزء تعریف شده است که از داده های آموزشی از پیش پردازش شده برای آموزش یک مدل رگرسیون لجستیک استفاده می کند. مدل آموزش دیده در یک مسیر خروجی مشخص ذخیره می شود. با استفاده از scikit-learn کتابخانه، این مؤلفه به سرعت مدل را آموزش می دهد و یک فایل مدل آموزش دیده برای مرحله ارزیابی بعدی فراهم می کند.
را evaluate_model_op جزء نیز در فایل تعریف شده است که داده های تست و مدل آموزش دیده را بارگذاری می کند، سپس از داده های تست برای پیش بینی و ارزیابی مدل استفاده می کند. این مؤلفه دقت مدل را به عنوان معیار عملکرد محاسبه و خروجی می‌گیرد و به ارزیابی اثربخشی مدل کمک می‌کند.
در نهایت، فایل یک خط لوله به نام تعریف می کند diabetes_pipeline، که سه جزء بالا را به هم پیوند می دهد. با استفاده از dsl.pipeline دکوراتور، مراحل پیش پردازش داده ها، آموزش مدل و مراحل ارزیابی مدل در یک گردش کار کامل ترکیب می شوند. این خط لوله در نهایت در یک فایل YAML (diabetes_pipeline.yaml) که می تواند در محیط Kubeflow مستقر و اجرا شود.

به طور کلی، این مثال استفاده اساسی از Argo Workflow را نشان می‌دهد که با تعریف وظایف و وابستگی‌های ساده، به مدیریت گردش کار خودکار در محیط Kubernetes دست می‌یابد.

برای کارهایی که باید چندین بار اجرا شوند یا دارای مراحل پیش پردازش مشترک هستند، حافظه های پنهان پردازش شده قبلی را می توان بر اساس نام آنها مجددا استفاده کرد تا کارایی آموزش را بهبود بخشد.

منشی

AutoML یک منطقه محبوب در یادگیری ماشین است که عمدتا برای بهینه سازی مدل و تنظیم هایپرپارامتر استفاده می شود. در اینجا، Katib، یک پروژه AutoML مبتنی بر Kubernetes، استفاده می شود. برای جزئیات بیشتر، از Katib در GitHub دیدن کنید.

Katib عمدتاً تنظیم هایپرپارامتر، توقف اولیه و جستجوی معماری عصبی را ارائه می دهد. از الگوریتم های مختلف بهینه سازی هایپرپارامتر، از جمله جستجوی تصادفی، بهینه سازی بیزی و HyperBand پشتیبانی می کند. این الگوریتم‌ها به توسعه‌دهندگان کمک می‌کنند تا بهترین پیکربندی‌های فراپارامتر را در یک فضای پارامتر مشخص به‌طور مؤثر جستجو کنند. با تعریف آزمایش‌ها، کاربران می‌توانند فراپارامترهایی را که باید تنظیم شوند، محدوده آنها، هدف بهینه‌سازی (به عنوان مثال، دقت یا از دست دادن)، و الگوریتم جستجوی مورد استفاده را مشخص کنند. Katib همچنین از استراتژی‌های توقف زودهنگام پشتیبانی می‌کند و اجازه می‌دهد آزمایش‌هایی با عملکرد ضعیف به صورت پویا در طول آموزش خاتمه داده شوند و در نتیجه منابع محاسباتی را ذخیره کنند. علاوه بر این، Katib قابلیت‌های جستجوی معماری عصبی (NAS) را ارائه می‌کند که به کاربران اجازه می‌دهد تا معماری‌های مختلف شبکه را برای بهبود عملکرد مدل بررسی کنند.

همانطور که در بخش 6.1 نشان داده شده است، یک نوت بوک جدید ایجاد کنید. پس از ایجاد یک فایل پایتون، دستور زیر را در ترمینال اجرا کنید تا کتابخانه های لازم دانلود شود.

pip install kubeflow-katib

import kubeflow.katib as katib

_# Step 1. Create an objective function._

def objective(parameters):

    _# Import required packages._

    import time

    time.sleep(5)

    _# Calculate objective function._

    result = 4 * int(parameters[“a”]) – float(parameters[“b”]) ** 2

    _# Katib parses metrics in this format: <metric-name>=<metric-value>._

    print(f”result={result}”)

_# Step 2. Create HyperParameter search space._

parameters = {

    “a”: katib.search.int(min=10, max=20),

    “b”: katib.search.double(min=0.1, max=0.2)

}

_# Step 3. Create Katib Experiment._

katib_client = katib.KatibClient()

name = “tune-experiment”

katib_client.tune(

    name=name,

    objective=objective,

    parameters=parameters,

    objective_metric_name=”result”,

    max_trial_count=12

)

_# Step 4. Get the best HyperParameters._

print(katib_client.get_optimal_hyperparameters(name))

پس از اجرا، می توانید فایل های بهینه سازی پارامتر و گردش کار کلی را در AutoML مشاهده کنید.

این کد به طور خودکار بهینه سازی هایپرپارامتر را با تعریف یک تابع هدف، با استفاده از یک الگوریتم جستجوی تصادفی انجام می دهد. تابع هدف به شکل است result = 4a – b^2، پارامتر کجا a یک عدد صحیح از 10 تا 20 و پارامتر است b یک عدد ممیز شناور از 0.1 تا 0.2 است. کد ابتدا تابع هدف را تعریف می کند و سپس فضای جستجو را برای فراپارامترها ایجاد می کند. بعد، Kubeflow Katib's KatibClient برای شروع آزمایش استفاده می شود و تابع هدف، محدوده پارامترها و حداکثر تعداد آزمایش را مشخص می کند (12). در نهایت، katib_client.get_optimal_hyperparameters(name) روش ترکیب بهینه ابرپارامترها را بازیابی و خروجی می‌دهد و به تنظیم خودکار فراپارامتر برای بهینه‌سازی تابع هدف مشخص شده دست می‌یابد.

محدوده مقدار برای a 10-20 است و برای b0.1-0.2 است. تحت این شرایط، از الگوریتم جستجوی تصادفی برای یافتن حداکثر مقدار استفاده می شود F.

در زیر نمونه ای از یک تابع پیچیده تر و استفاده از الگوریتم های دیگر برای محاسبه آورده شده است:

import kubeflow.katib as katib

_# Step 1. Create an objective function._

def objective(parameters):

    _# Import required packages._

    import time

    import math

    time.sleep(5)

    _# Calculate a more complex objective function._

    a = int(parameters[“a”])

    b = float(parameters[“b”])

    _#_ _复杂的目标函数示例:结合多项式、对数和三角函数的组合_

    result = (3 * a ** 2 + 2 * b – math.sin(a * b)) / (1 + math.log(b + 0.1)) + math.sqrt(abs(a – b))

    _# Katib parses metrics in this format: <metric-name>=<metric-value>._

    print(f”result={result}”)

_# Step 2. Create HyperParameter search space._

parameters = {

    “a”: katib.search.int(min=10, max=20),

    “b”: katib.search.double(min=0.1, max=0.2)

}

_# Step 3. Create Katib Experiment._

katib_client = katib.KatibClient()

name = “tune-experiment-for-kalibbase”

katib_client.tune(

    name=name,

    objective=objective,

    parameters=parameters,

    algorithm_name=”bayesianoptimization”,

objective_metric_name=”result”,

#objective_type=”minimize”,  # 指定最小化目标函数

    max_trial_count=12

)

_# Step 4. Get the best HyperParameters._

print(katib_client.get_optimal_hyperparameters(name))

با استفاده از یک تابع پیچیده تر برای بهینه سازی پارامترها، الگوریتم جستجوی بیزی استفاده می شود:

این مقاله به طور مختصر به معرفی kubeflow و روش های استقرار و استفاده از آن می پردازد. اخیراً در حال تحقیق بر روی پلت فرم kubeflow بودم و متوجه شدم که اطلاعات کمتری به صورت آنلاین وجود دارد. علاوه بر این، تکرار نسخه آن سریعتر است و برخی از روش های فراخوانی و استفاده تغییر کرده است. با توجه به محتوای کار، برخی از عملکردهای اصلی آن مانند تنظیم پارامتر katib، ساخت خط لوله kubeflow و ایجاد چند کاربر انجام شده است. منتظر موارد خاص باشید

kubeflow

Kubeflow یک پلتفرم منبع باز است که برای استقرار، مدیریت و مقیاس‌بندی جریان‌های کاری یادگیری ماشین (ML) در Kubernetes طراحی شده است، با هدف ساده‌سازی استقرار و عملیات پروژه‌های یادگیری ماشین در محیط‌های تولید. توابع ارکستراسیون کانتینر و مدیریت منابع بر اساس Kubernetes. Kubeflow با تقسیم گردش کار یادگیری ماشین به مجموعه‌ای از وظایف محفظه‌ای، می‌تواند از قابلیت‌های مقیاس‌بندی خودکار، تحمل خطا و زمان‌بندی Kubernetes برای اطمینان از اجرای کارآمد وظایف یادگیری ماشین استفاده کند. Kubeflow مجموعه کاملی از ابزارها و خدمات را برای پشتیبانی از همه چیز از کل چرخه زندگی یادگیری ماشین از آماده سازی داده ها، آموزش مدل، تنظیم تا استقرار ارائه می دهد. این راه حل انتها به انتها به دانشمندان و مهندسان داده کمک می کند تا به سرعت از توسعه به تولید منتقل شوند.

https%3A%2F%2Fdev to uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmuzi509fur9ep8vmww1q

به طور کلی، kubeflow از اجزای زیر تشکیل شده است

  1. داشبورد مرکزی Kubeflow یک رابط وب برای دسترسی به Kubeflow و اجزای آن فراهم می کند. این به عنوان یک مرکز متمرکز عمل می کند و ابزارها و خدمات مختلف را در داخل خوشه برای مدیریت آسان تر پلت فرم یادگیری ماشین یکپارچه می کند.
  2. Kubeflow با نوت بوک های Jupyter برای ارائه یک محیط تعاملی برای اکتشاف داده، آزمایش و توسعه مدل. نوت‌بوک‌ها از چندین زبان مانند Python، R و Scala پشتیبانی می‌کنند و گردش‌های کاری ML مشترک و قابل تکرار را امکان‌پذیر می‌سازند.
  3. خطوط لوله Kubeflow به کاربران اجازه می‌دهد تا گردش‌های کاری پیچیده ML را به‌عنوان نمودارهای غیر چرخه مستقیم (DAG) تعریف و اجرا کنند. این خطوط لوله به خودکارسازی و مدیریت فرآیندهای سرتاسری مانند پیش پردازش داده ها، آموزش مدل، ارزیابی و استقرار، افزایش تکرارپذیری و همکاری کمک می کند. Kubeflow Pipelines SDK مجموعه ای از بسته های پایتون برای تعریف و اجرای کارآمد گردش کار ML است.
  4. اپراتور آموزش Kubeflow ابزارهایی را برای آموزش مدل‌های ML در مقیاس بزرگ فراهم می‌کند و از آموزش توزیع‌شده با چارچوب‌هایی مانند TensorFlow، PyTorch و XGBoost پشتیبانی می‌کند. از مقیاس پذیری و مدیریت منابع Kubernetes برای آموزش مدل کارآمد در سراسر خوشه ها استفاده می کند.
  5. سرویس Kubeflow استقرار مدل‌های آموزش‌دیده ML را به‌عنوان سرویس‌های مقیاس‌پذیر، آماده تولید، چارچوب‌های پشتیبانی مانند TensorFlow Serving، Seldon Core یا سرورهای سفارشی امکان‌پذیر می‌کند. مدل ها را می توان برای پیش بینی های زمان واقعی یا دسته ای از طریق نقاط پایانی HTTP مستقر کرد.
  6. فراداده Kubeflow یک مخزن متمرکز برای مدیریت ابرداده‌های مربوط به آزمایش‌ها، اجراها و مصنوعات ML است که از تکرارپذیری، همکاری و حاکمیت در سراسر گردش کار اطمینان می‌دهد.

راه اندازی محیط

شرط لازم برای استقرار Kubeflow داشتن یک کلاستر است. من از Kubernetes نسخه 1.26 استفاده می کنم که با kubeadm نصب و اجرا شده است. نسخه Kubeflow مربوطه 1.8.1 است.

نصب NFS

از آنجایی که استقرار Kubeflow به یک کلاس ذخیره سازی پیش فرض نیاز دارد، در اینجا نحوه نصب و استقرار فایل سیستم NFS با nfs-subdir-external-provisioner آورده شده است.

https%3A%2F%2Fdev to

طبق اسناد رسمی، نصب Kubeflow با استفاده از مانیفست Kubeflow نیاز به یک پیش فرض دارد کلاس ذخیره سازی، سفارشی کردن، و کوبکتل ابزار. برای استفاده از کلاس ذخیره سازی پیش فرض، nfs-subdir-external-provisioner مستقر شده است. این می تواند به طور خودکار روابط PV و PVC را ایجاد و مدیریت کند. در زیر مراحل نصب و استقرار NFS و افزونه NFS آورده شده است.

با استفاده از دستور سرویس NFS را نصب کنید apt install -y nfs-kernel-server.

ایجاد دایرکتوری ذخیره سازی داده با mkdir -p /data/redis.

با افزودن دایرکتوری پیکربندی جدید، محتویات فایل /etc/exports را تغییر دهید: /data/redis 192.168.0.0/24(rw,sync,no_all_squash,no_subtree_check,no_root_squash).

https%3A%2F%2Fdev to

پس از انجام مراحل بالا، سرویس NFS را مجددا راه اندازی کنید.

استقرار NFS-Subdir-External-Provisioner

NFS-Subdir-External-Provisioner یک ارائه دهنده حجم پویا است که از یک سرور NFS موجود و پیکربندی شده برای پشتیبانی از ارائه پویا حجم های پایدار Kubernetes از طریق ادعاهای حجم دائمی استفاده می کند.

قبل از استقرار سرویس NFS-subdir، مطمئن شوید که یک گره با سرویس NFS دارید و دایرکتوری ذخیره سازی مربوطه را می شناسید. در مثال بالا، گره و دایرکتوری هستند 192.168.0.208 و /data/redisبه ترتیب

  • یک حساب کاربری ایجاد کنید
apiVersion: v1

kind: ServiceAccount

metadata:

  name: nfs-client-provisioner

  namespace: default _#_ _替换成你要部署的_ _Namespace_

---

kind: ClusterRole

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: nfs-client-provisioner-runner

rules:

  - apiGroups: [""]

    resources: ["persistentvolumes"]

    verbs: ["get", "list", "watch", "create", "delete"]

  - apiGroups: [""]

    resources: ["persistentvolumeclaims"]

    verbs: ["get", "list", "watch", "update"]

  - apiGroups: ["storage.k8s.io"]

    resources: ["storageclasses"]

    verbs: ["get", "list", "watch"]

  - apiGroups: [""]

    resources: ["events"]

    verbs: ["create", "update", "patch"]

---

kind: ClusterRoleBinding

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: run-nfs-client-provisioner

subjects:

  - kind: ServiceAccount

    name: nfs-client-provisioner

    namespace: default

roleRef:

  kind: ClusterRole

  name: nfs-client-provisioner-runner

  apiGroup: rbac.authorization.k8s.io

---

kind: Role

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: leader-locking-nfs-client-provisioner

  namespace: default

rules:

  - apiGroups: [""]

    resources: ["endpoints"]

    verbs: ["get", "list", "watch", "create", "update", "patch"]

---

kind: RoleBinding

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: leader-locking-nfs-client-provisioner

  namespace: default

subjects:

  - kind: ServiceAccount

    name: nfs-client-provisioner

    namespace: default

roleRef:

  kind: Role

  name: leader-locking-nfs-client-provisioner

  apiGroup: rbac.authorization.k8s.io
  • NFS-Subdir-External-Provisioner را مستقر کنید و پارامترهای پیکربندی را در صورت نیاز تغییر دهید:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate  # Set upgrade strategy to Recreate (default is RollingUpdate)
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          # image: gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner:v4.0.0
          image: registry.cn-beijing.aliyuncs.com/xngczl/nfs-subdir-external-provisione:v4.0.0
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME  # Name of the provisioner, must match the name set in the storage class
              value: nfs-client
            - name: NFS_SERVER  # NFS server address, must match the value in the volumes parameter
              value: 192.168.0.208
            - name: NFS_PATH  # NFS server data storage directory, must match the value in the volumes parameter
              value: /data/redis
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.0.208  # NFS server address
            path: /data/redis  # NFS server data storage directory
  • ایجاد NFS StorageClass:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-storage
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"  # Set as the default storage class
provisioner: nfs-client  # Must match the provisioner name set in the deployment
parameters:
  archiveOnDelete: "true"  # Set to "false" to delete PVC without retaining data; "true" retains data

سپس فایل های بالا را با استفاده از kubectl application -f اعمال کنید. همچنین، با chmod 777 /data/redis، به دایرکتوری ذخیره سازی NFS مجوز بدهید.

نصب Kubeflow

بسته باینری مربوطه skustomize_v5.0.3_linux_amd64.tar.gz را از مخزن رسمی GitHub پروژه مانیفست Kubeflow دانلود کرده و آن را در /usr/local/bin دایرکتوری بسته رسمی Kubeflow manifest mainfests-1.8.1.tar.gz را دانلود کنید.

https%3A%2F%2Fdev to

StorageClass پیش فرض را تغییر دهید

فایل های YAML را با افزودن ویرایش کنید storageClassName: nfs-storage در فایل های زیر واقع در mainfests-1.8.1 دایرکتوری:

  • apps/katib/upstream/components/mysql/pvc.yaml
  • common/oidc-client/oidc-authservice/base/pvc.yaml
  • apps/pipeline/upstream/third-party/minio/base/minio-pvc.yaml
  • apps/pipeline/upstream/third-party/mysql/base/mysql-pv-claim.yaml

APP_SECURE_COOKIES را اصلاح کنید

فایل پیکربندی را برای تنظیم ویرایش کنید APP_SECURE_COOKIES=false، که استفاده از کوکی های امن را غیرفعال می کند.

باز کردن فایل با:
vim ./apps/jupyter/jupyter-web-app/upstream/base/params.env
params.env

تنظیم کنید APP_SECURE_COOKIES به false برای اطمینان از دسترسی داشبورد به Kubeflow پس از استقرار. همچنین می توانید نمونه های دیگری را که ممکن است به این تغییر نیاز داشته باشند با استفاده از دستور زیر بررسی کنید:

find ./ -type f -exec grep -l “APP_SECURE_COOKIES” {} ;
در بیشتر موارد، فقط پیکربندی Jupyter Web App (JWP) به این به‌روزرسانی نیاز دارد.

JWP

Kubeflow را مستقر کنید

پس از انجام تغییرات لازم در پیکربندی، به دایرکتوری مانیفست رفته و دستور زیر را برای استقرار خودکار Kubeflow اجرا کنید. به دلیل تعداد زیاد وابستگی ها، ممکن است مشکلاتی در حین نصب ایجاد شود. تنظیمات قبلی باید اکثر مشکلات را حل کنند، اما اگر نصب با مشکل مواجه شود یا پادها به درستی اجرا نشوند، ممکن است نیاز به عیب یابی بیشتری باشد.

while ! kustomize build example | kubectl apply -f -; do echo "Retrying to apply resources"; sleep 10; done

SVC را به NodePort Mode تغییر دهید

از آنجایی که سرویس های مستقر همه از نوع ClusterIP هستند، نمی توان به آنها دسترسی خارجی داشت. بنابراین، شما باید به صورت دستی تغییر دهید istio-ingressgateway سرویس به نوع NodePort.
k edit svc -n istio-system istio-ingressgateway
https%3A%2F%2Fdev to uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz35uclc30dputybzqqc9

اعتبار پیش فرض ورود به سیستم عبارتند از:

  • نام کاربری: user@example.com
  • رمز عبور: 12341234

وارد شوید

با استفاده از Kubeflow

بررسی اجمالی Kubeflow

در زیر مقدمه ای بر اجزای کلیدی Kubeflow آورده شده است:

  • سرورهای نوت بوک: این ابزارها به عنوان ابزاری برای مدیریت آزمایش‌های تعاملی عمل می‌کنند و به محققان کمک می‌کنند تا آزمایش‌های الگوریتمی را سریع انجام دهند. آنها همچنین قابلیت های یکپارچه مدیریت اسناد را ارائه می دهند.
  • AutoML: این کار فرآیندهایی مانند مهندسی ویژگی، انتخاب مدل، تنظیم فراپارامتر و ارزیابی مدل را خودکار می‌کند و تعداد آزمایش‌های دستی مورد نیاز را کاهش می‌دهد.
  • خط لوله: یک ابزار مهندسی که مراحل مختلف یک گردش کار الگوریتمی را در نمودار توپولوژی سازماندهی می کند. می توان آن را با Argo برای پیاده سازی MLO ها ترکیب کرد.
  • بدون سرور: این اجازه می دهد تا مدل ها به طور مستقیم به عنوان خدمات مستقر شوند و مسیر از آزمایش تا تولید را کوتاه کنند.

اجزای Kubeflow

توسعه مدل – نوت بوک

نوت‌بوک‌های Kubeflow یک جزء حیاتی از پلتفرم Kubeflow است که به دانشمندان داده و مهندسان ML امکان می‌دهد تا نوت‌بوک‌های Jupyter را روی Kubernetes اجرا کنند. این امر به طور قابل توجهی مدیریت و استفاده از نوت بوک های Jupyter را در محیط های ابری ساده می کند. با Kubeflow Notebooks، کاربران به راحتی می توانند چندین نمونه Jupyter Notebook را در یک خوشه Kubernetes ایجاد و مدیریت کنند. این نمونه ها را می توان با منابع خاصی مانند CPU، حافظه و GPU پیکربندی کرد و از جداسازی و استفاده کارآمد از منابع در یک محیط چند کاربره اطمینان حاصل کرد.

راه اندازی نوت بوک

یک کار جدید از طریق رابط نوت بوک ایجاد کنید:
وظیفه جدید

در صفحه پیکربندی، می توانید نام را تنظیم کنید و منابعی مانند CPU و GPU را اختصاص دهید. پس از ایجاد، غلاف مربوطه ظاهر می شود. برای استفاده از GPU، به اسناد رسمی مراجعه کنید.
پیکربندی Pod
پیکربندی GPU

برای پیوند به پاد مربوطه، روی “اتصال” کلیک کنید. در این مرحله، ممکن است در کشیدن تصاویر با مشکلاتی مواجه شوید که قبل از اجرا شدن پاد، نیاز به کشیدن دستی تصویر به گره مشخص شده است.

آموزش مدل

آموزش مدل

هنگام ایجاد یک نوت بوک، می توانید یک تصویر را با TensorFlow انتخاب کنید و به شما امکان می دهد مستقیماً از چارچوب استفاده کنید. تصاویر دیگری مانند PyTorch-CUDA نیز در دسترس هستند. پس از راه اندازی، می توانید یک کد آموزشی ساده مانند شکل زیر اجرا کنید:

import numpy as np

import tensorflow as tf

from tensorflow.keras.datasets import mnist

from tensorflow.keras.utils import to_categorical

from tensorflow.keras.models import Sequential

from tensorflow.keras.layers import Dense, Flatten, Dropout, Conv2D, MaxPooling2D

_#_ _加载__MNIST__数据集_

(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

_#_ _预处理数据:调整形状并归一化_

train_images = train_images.reshape(-1, 28, 28, 1).astype('float32') / 255.0

test_images = test_images.reshape(-1, 28, 28, 1).astype('float32') / 255.0

_#_ _将标签转换为_ _one-hot_ _编码_

train_labels = to_categorical(train_labels, 10)

test_labels = to_categorical(test_labels, 10)

_#_ _构建模型_

model = Sequential([

    Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)),

    MaxPooling2D(pool_size=(2, 2)),

    Conv2D(64, kernel_size=(3, 3), activation='relu'),

    MaxPooling2D(pool_size=(2, 2)),

    Flatten(),

    Dense(128, activation='relu'),

    Dropout(0.5),

    Dense(10, activation='softmax')

])

_#_ _编译模型_

model.compile(optimizer="adam",

              loss="categorical_crossentropy",

              metrics=['accuracy'])

_#_ _训练模型_

model.fit(train_images, train_labels, epochs=10, batch_size=64, validation_data=(test_images, test_labels))

_#_ _评估模型_

test_loss, test_accuracy = model.evaluate(test_images, test_labels, verbose=0)

print(f"Test accuracy: {test_accuracy:.4f}")

# 保存模型

model.save('mnist_cnn_model.keras')

print("模型保存成功")

و ما داریم
https%3A%2F%2Fdev to uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22d5hi6ly7m79ut62v49

همچنین می‌توانیم کتاب‌های جدید ژوپیتر را ویرایش کنیم

import numpy as np

import tensorflow as tf

from PIL import Image, ImageOps, ImageFilter

import matplotlib.pyplot as plt

_#_ _加载保存的模型_

loaded_model = tf.keras.models.load_model('mnist_cnn_model.keras')

定义你自己的图片文件名列表

image_files = [

    'mnist_test_0_label_9.png',

    'mnist_test_2_label_8.png',

    'mnist_test_4_label_2.png',

    'mnist_test_1_label_0.png',

    'mnist_test_3_label_7.png'

]

_#image_files = ['__图片__.jpg', '123.jpg', 'third.jpg', '9.jpg']_

def preprocess_image(img):

    _#_ _转换为灰度图像_

    img = img.convert('L')

    _#_ _自动对比度增强_

    img = ImageOps.autocontrast(img)

    _#_ _裁剪数字的边缘并居中_

    img = img.crop(img.getbbox())  _#_ _裁剪非空白区域_

    img = img.resize((20, 20), Image.Resampling.LANCZOS)  _#_ _调整图像大小,保持最大信息_

    background = Image.new('L', (28, 28), 0)  _#_ _创建黑色背景_

    offset = ((28 - img.size[0]) // 2, (28 - img.size[1]) // 2)

    background.paste(img, offset)  _#_ _将图像粘贴到背景上使其居中_

    return background

_#_ _创建一个图形,包含__5__行__2__列的子图_

fig, axs = plt.subplots(5, 2, figsize=(10, 25))

_#fig, axs = plt.subplots(4, 2, figsize=(10, 25))_

for i, file in enumerate(image_files):

    _#_ _加载图像_

    img = Image.open(file)

    _#_ _对图像进行预处理_

    processed_img = preprocess_image(img)

    _#_ _将图像转换为数组并进行标准化,确保形状为_ _(28, 28, 1)_

    img_array = np.array(processed_img).reshape(1, 28, 28, 1).astype('float32') / 255.0

    _#_ _进行预测_

    predictions = loaded_model.predict(img_array)

    _#_ _获取预测结果_

    predicted_digit = np.argmax(predictions[0])

    _#_ _显示原始图片_

    axs[i, 0].imshow(img, cmap='gray')

    axs[i, 0].set_title(f'原始图片: {file}')

    axs[i, 0].axis('off')

    _#_ _显示处理后的图片_

    axs[i, 1].imshow(processed_img, cmap='gray')

    axs[i, 1].set_title(f'预测结果: {predicted_digit}')

    axs[i, 1].axis('off')

    print(f"{file} 预测的数字是: {predicted_digit}")

plt.tight_layout()

plt.show()

https%3A%2F%2Fdev to
https%3A%2F%2Fdev to uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcupj2inukvscbnfmg6gb

آموزش GPU

استفاده از تصویر GPU به منابع GPU در خوشه ما نیاز دارد، همانطور که در زیر نشان داده شده است:
خوشه GPU

هنگام انتخاب یک تصویر GPU، اگر می‌خواهید یک GPU اضافه کنید اما پیامی دریافت می‌کنید که نشان می‌دهد هیچ GPU در خوشه موجود نیست، باید یک GPU را به صورت فیزیکی روی یک گره نصب کنید و سپس یک اپراتور به خوشه اضافه کنید تا از منابع GPU استفاده کند. .

در زیر روش نصب اپراتور NVIDIA GPU آورده شده است:
مرجع: راهنمای نصب اپراتور رسمی NVIDIA

Download and prepare Helm 3:

curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
&& chmod 700 get_helm.sh
&& ./get_helm.sh

Ensure NFD mode is disabled; if it's enabled, manually turn it off:

kubectl get nodes -o json | jq '.items[].metadata.labels | keys | any(startswith("feature.node.kubernetes.io"))'

Add the NVIDIA Helm repository:

helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
&& helm repo update

Deploy the GPU Operator:

helm install --wait --generate-name
-n gpu-operator --create-namespace
nvidia/gpu-operator
--set driver.version=535

توجه داشته باشید که نسخه درایور باید با مدل GPU خاص شما مطابقت داشته باشد. به عنوان مثال، من از نسخه 535 استفاده کردم زیرا پردازنده گرافیکی A800 دارم. اطمینان حاصل کنید که نسخه صحیح درایور را بر اساس مدل NVIDIA GPU خود انتخاب کنید.

پس از اجرای دستورات، باید موارد زیر را مشاهده کنید:
موفقیت در استقرار

گره اکنون منابع قابل زمانبندی را به عنوان نشان می دهد nvidia.com/gpu:
منابع GPU

Kubeflow را باز کنید تا از GPU برای کارهای آموزشی استفاده کنید. در این صفحه، تصویری را که شامل CUDA می‌شود، مشخص کنید و پردازنده گرافیکی NVIDIA موجود در خوشه در پیکربندی GPU را انتخاب کنید.
راه اندازی GPU Kubeflow

پس از راه اندازی، وارد Jupyter شوید و یک محیط Python 3 ایجاد کنید. سپس می توانید کد یادگیری ماشین را توسعه دهید و از آن استفاده کنید nvidia-smi دستور در پاد برای بررسی و استفاده از GPU.
دستور NVIDIA-SMI

در زیر کد آموزش با استفاده از GPU آورده شده است:

import os

import tensorflow as tf

import time

import numpy as np

from tensorflow.keras import layers, models

import matplotlib.pyplot as plt

print("====检查 GPU 可用性====")

os.environ['TF_FORCE_GPU_ALLOW_GROWTH'] = 'true'

_#_ _检查_ _GPU_ _是否可用_

if tf.test.is_gpu_available():

    print("\033[1;32m[GPU 可用] 将进行 GPU 和 CPU 训练对比\033[0m")

    gpu_device = tf.config.list_physical_devices('GPU')[0]

    print(f"可用的 GPU: {gpu_device}")

else:

    print("\033[1;31m[GPU 不可用] 只能使用 CPU 进行训练\033[0m")

    exit()

print("\n====加载和预处理数据====")

(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()

train_images = train_images.reshape((60000, 28, 28, 1)).astype('float32') / 255

test_images = test_images.reshape((10000, 28, 28, 1)).astype('float32') / 255

def create_model():

    model = models.Sequential([

        layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),

        layers.MaxPooling2D((2, 2)),

        layers.Conv2D(64, (3, 3), activation='relu'),

        layers.MaxPooling2D((2, 2)),

        layers.Conv2D(64, (3, 3), activation='relu'),

        layers.Flatten(),

        layers.Dense(64, activation='relu'),

        layers.Dense(10, activation='softmax')

    ])

    model.compile(optimizer="adam",

                  loss="sparse_categorical_crossentropy",

                  metrics=['accuracy'])

    return model

_# GPU_ _训练_

print("\n====开始 GPU 训练====")

with tf.device('/GPU:0'):

    gpu_model = create_model()

    start_time = time.time()

    gpu_history = gpu_model.fit(train_images, train_labels, epochs=10,

                                validation_split=0.2, batch_size=64, verbose=1)

    gpu_time = time.time() - start_time

_# CPU_ _训练_

print("\n====开始 CPU 训练====")

os.environ['CUDA_VISIBLE_DEVICES'] = '-1'  _#_ _禁用_ _GPU_

with tf.device('/CPU:0'):

    cpu_model = create_model()

    start_time = time.time()

    cpu_history = cpu_model.fit(train_images, train_labels, epochs=10,

                                validation_split=0.2, batch_size=64, verbose=1)

    cpu_time = time.time() - start_time

_#_ _结果对比_

print("\n====训练时间对比====")

print(f"\033[1;34mGPU 训练时间: {gpu_time:.2f} 秒\033[0m")

print(f"\033[1;34mCPU 训练时间: {cpu_time:.2f} 秒\033[0m")

print(f"\033[1;32mGPU 加速比: {cpu_time / gpu_time:.2f}x\033[0m")

_#_ _绘制训练过程的损失和准确率曲线_

def plot_history(history, title):

    acc = history.history['accuracy']

    val_acc = history.history['val_accuracy']

    loss = history.history['loss']

    val_loss = history.history['val_loss']

    epochs = range(1, len(acc) + 1)

    plt.figure(figsize=(12, 5))

    plt.subplot(1, 2, 1)

    plt.plot(epochs, loss, 'bo-', label="Training loss")

    plt.plot(epochs, val_loss, 'ro-', label="Validation loss")

    plt.title(f'{title} - Training and validation loss')

    plt.xlabel('Epochs')

    plt.ylabel('Loss')

    plt.legend()

    plt.subplot(1, 2, 2)

    plt.plot(epochs, acc, 'bo-', label="Training accuracy")

    plt.plot(epochs, val_acc, 'ro-', label="Validation accuracy")

    plt.title(f'{title} - Training and validation accuracy')

    plt.xlabel('Epochs')

    plt.ylabel('Accuracy')

    plt.legend()

    plt.show()

print("\n====可视化 GPU 训练过程====")

plot_history(gpu_history, "GPU Training")

print("\n====可视化 CPU 训练过程====")

plot_history(cpu_history, "CPU Training")

_#_ _评估_ _GPU_ _模型_

print("\n====评估 GPU 训练的模型====")

test_loss, test_acc = gpu_model.evaluate(test_images, test_labels, verbose=0)

print(f'\n\033[1;32mTest accuracy: {test_acc:.4f}\033[0m')

_#_ _保存_ _GPU_ _训练的模型_

print("\n====保存 GPU 训练的模型====")

gpu_model.save('mnist_model_gpu.keras')

print("模型已保存为 mnist_model_gpu.keras")

این کد قدرت محاسباتی قابل توجه GPU ها را در مقایسه با CPU ها به ویژه در وظایف یادگیری عمیق نشان می دهد. کد ابتدا GPU های موجود در محیط را بررسی می کند و سپس یک شبکه عصبی کانولوشنال ساده (CNN) را در هر دو GPU و CPU با استفاده از مجموعه داده ارقام دست نویس MNIST برای طبقه بندی آموزش می دهد.

GPU در مقابل آموزش CPU
خروجی آموزش

در طول آموزش، می توانید استفاده از GPU را با استفاده از nvidia-smi دستور، که بینش‌های بی‌درنگ در مورد استفاده از GPU ارائه می‌کند.

خروجی nvidia-smi

همانطور که در تصویر نشان داده شده است، استفاده از GPU در طول آموزش حدود 9٪ است که نشان می دهد این کار با موفقیت GPU را برای محاسبات اهرم کرده است.

خط لوله

خطوط لوله Kubeflow یک ماژول اصلی در پروژه Kubeflow است که بر ساخت، استقرار و مدیریت گردش‌های کاری پیچیده یادگیری ماشین تمرکز دارد. مجموعه ای جامع از ابزارها را برای طراحی و خودکارسازی خطوط لوله ML ارائه می دهد که به دانشمندان و مهندسان داده اجازه می دهد تا به طور کارآمد فرآیندهای آموزش و استقرار مدل های ML را مدیریت و نظارت کنند. با Kubeflow Pipelines، کاربران به راحتی می‌توانند گردش‌های کاری پیچیده را تعریف، به اشتراک بگذارند، دوباره استفاده کنند و خودکار کنند.

در رابط خط لوله، می توانید از پیش ساخته شده آپلود کنید .gz یا .yaml فایل ها هنگامی که خط لوله ایجاد می شود، به صورت بصری در رابط گرافیکی مانند شکل زیر نمایش داده می شود. برای دستورالعمل های دقیق در مورد ایجاد خطوط لوله، به اسناد رسمی مراجعه کنید.

رابط خط لوله

import kfp

from kfp import dsl

from kfp.dsl import component, Input, Output, Dataset, Model

_# Step 1:_ _数据下载和预处理_

@component(

    base_image="python:3.8-slim",

    packages_to_install=[

        'pandas',

        'scikit-learn',

        'joblib',

        'numpy',

        'requests'

    ]

)

def preprocess_data_op(output_data: Output[Dataset]):

    print("开始执行 preprocess_data_op...")

    try:

        import pandas as pd

        print("成功导入 pandas 模块。")

    except ImportError as e:

        print(f"导入 pandas 失败: {e}")

        raise e

    from sklearn.model_selection import train_test_split

    from sklearn.preprocessing import StandardScaler

    import os

    print("正在下载数据集...")

    url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv"

    columns = ['Pregnancies', 'Glucose', 'BloodPressure', 'SkinThickness', 'Insulin', 'BMI', 'DiabetesPedigreeFunction', 'Age', 'Outcome']

    data = pd.read_csv(url, names=columns)

    print("数据集下载完成。")

    _#_ _数据清洗和特征工程_

    print("正在进行数据清洗和特征工程...")

    X = data.drop('Outcome', axis=1)

    y = data['Outcome']

    _#_ _标准化特征_

    print("正在标准化特征...")

    scaler = StandardScaler()

    X_scaled = scaler.fit_transform(X)

    _#_ _划分训练集和测试集_

    print("正在划分训练集和测试集...")

    X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)

    _#_ _保存预处理后的数据_

    print("正在保存预处理后的数据...")

    os.makedirs(output_data.path, exist_ok=True)

    pd.DataFrame(X_train).to_csv(os.path.join(output_data.path, 'X_train.csv'), index=False)

    pd.DataFrame(X_test).to_csv(os.path.join(output_data.path, 'X_test.csv'), index=False)

    pd.DataFrame(y_train).to_csv(os.path.join(output_data.path, 'y_train.csv'), index=False)

    pd.DataFrame(y_test).to_csv(os.path.join(output_data.path, 'y_test.csv'), index=False)

    print(f"数据预处理完成并已保存到 {output_data.path}。")

_# Step 2:_ _模型训练_

@component(

    base_image="python:3.8-slim",

    packages_to_install=[

        'pandas',

        'scikit-learn',

        'joblib',

        'numpy'

    ]

)

def train_model_op(input_data: Input[Dataset], output_model: Output[Model]):

    print("开始执行 train_model_op...")

    try:

        import pandas as pd

        print("成功导入 pandas 模块。")

    except ImportError as e:

        print(f"导入 pandas 失败: {e}")

        raise e

    from sklearn.linear_model import LogisticRegression

    import joblib

    import os

    print("正在加载训练数据...")

    X_train = pd.read_csv(os.path.join(input_data.path, 'X_train.csv'))

    y_train = pd.read_csv(os.path.join(input_data.path, 'y_train.csv'))

    _#_ _训练模型_

    print("正在训练模型...")

    model = LogisticRegression()

    model.fit(X_train, y_train.values.ravel())

    _#_ _创建输出目录并保存模型_

    os.makedirs(output_model.path, exist_ok=True)  _#_ _确保输出目录存在_

    model_path = os.path.join(output_model.path, 'trained_model.joblib')

    joblib.dump(model, model_path)

    print(f"模型训练完成并已保存到 {model_path}。")

_# Step 3:_ _模型评估_

@component(

    base_image="python:3.8-slim",

    packages_to_install=[

        'pandas',

        'scikit-learn',

        'joblib',

        'numpy'

    ]

)

def evaluate_model_op(input_data: Input[Dataset], input_model: Input[Model]):

    print("开始执行 evaluate_model_op...")

    try:

        import pandas as pd

        print("成功导入 pandas 模块。")

    except ImportError as e:

        print(f"导入 pandas 失败: {e}")

        raise e

    from sklearn.metrics import accuracy_score

    import joblib

    import os  # 添加os模块的导入

    print("正在加载测试数据和模型...")

    X_test = pd.read_csv(os.path.join(input_data.path, 'X_test.csv'))

    y_test = pd.read_csv(os.path.join(input_data.path, 'y_test.csv'))

    model = joblib.load(os.path.join(input_model.path, 'trained_model.joblib'))

    _#_ _预测和评估_

    print("正在进行模型预测和评估...")

    y_pred = model.predict(X_test)

    accuracy = accuracy_score(y_test, y_pred)

    print(f"模型准确率: {accuracy}")

# Step 4: Pipeline 定义

@dsl.pipeline(

    name="Diabetes Classifier Pipeline",

    description='A pipeline to train and evaluate a diabetes classifier model'

)

def diabetes_pipeline():

    preprocess = preprocess_data_op()

    train = train_model_op(input_data=preprocess.outputs['output_data'])

    evaluate = evaluate_model_op(input_data=preprocess.outputs['output_data'], input_model=train.outputs['output_model'])

# Compile the pipeline

if __name__ == "__main__":

    kfp.compiler.Compiler().compile(diabetes_pipeline, 'diabetes_pipeline.yaml')

فایل فوق یک فایل خط لوله قابل استفاده است که می تواند در ماژول Pipelines باز شود. گردش کار اصلی به صورت زیر نشان داده شده است:

گردش کار خط لوله

پس از اجرای خط لوله، نتایج به شرح زیر است:

نتایج خط لوله

این فایل پایتون در درجه اول خط لوله Kubeflow Pipelines (KFP) را برای پردازش داده ها، آموزش مدل یادگیری ماشین و ارزیابی برای طبقه بندی دیابت تعریف می کند.

  • فایل ابتدا تعریف می کند preprocess_data_op جزء، که مجموعه داده دیابت را دانلود می کند و پیش پردازش داده ها را انجام می دهد. این شامل تمیز کردن داده ها، استانداردسازی ویژگی ها، و تقسیم به مجموعه های آموزشی و آزمایشی است. داده های از پیش پردازش شده برای استفاده بعدی در آموزش و ارزیابی مدل در یک مسیر خروجی مشخص ذخیره می شوند.

  • بعد، train_model_op جزء تعریف شده است که از داده های آموزشی از پیش پردازش شده برای آموزش یک مدل رگرسیون لجستیک استفاده می کند. مدل آموزش دیده در یک مسیر خروجی مشخص ذخیره می شود. با استفاده از scikit-learn کتابخانه، این مؤلفه به سرعت مدل را آموزش می دهد و یک فایل مدل آموزش دیده برای مرحله ارزیابی بعدی فراهم می کند.

  • را evaluate_model_op جزء نیز در فایل تعریف شده است که داده های تست و مدل آموزش دیده را بارگذاری می کند، سپس از داده های تست برای پیش بینی و ارزیابی مدل استفاده می کند. این مؤلفه دقت مدل را به عنوان معیار عملکرد محاسبه و خروجی می‌گیرد و به ارزیابی اثربخشی مدل کمک می‌کند.

  • در نهایت، فایل یک خط لوله به نام تعریف می کند diabetes_pipeline، که سه جزء بالا را به هم پیوند می دهد. با استفاده از dsl.pipeline دکوراتور، مراحل پیش پردازش داده ها، آموزش مدل و مراحل ارزیابی مدل در یک گردش کار کامل ترکیب می شوند. این خط لوله در نهایت در یک فایل YAML (diabetes_pipeline.yaml) که می تواند در محیط Kubeflow مستقر و اجرا شود.

به طور کلی، این مثال استفاده اساسی از Argo Workflow را نشان می‌دهد که با تعریف وظایف و وابستگی‌های ساده، به مدیریت گردش کار خودکار در محیط Kubernetes دست می‌یابد.

برای کارهایی که باید چندین بار اجرا شوند یا دارای مراحل پیش پردازش مشترک هستند، حافظه های پنهان پردازش شده قبلی را می توان بر اساس نام آنها مجددا استفاده کرد تا کارایی آموزش را بهبود بخشد.

ذخیره سازی خط لوله

منشی

AutoML یک منطقه محبوب در یادگیری ماشین است که عمدتا برای بهینه سازی مدل و تنظیم هایپرپارامتر استفاده می شود. در اینجا، Katib، یک پروژه AutoML مبتنی بر Kubernetes، استفاده می شود. برای جزئیات بیشتر، از Katib در GitHub دیدن کنید.

Katib عمدتاً تنظیم هایپرپارامتر، توقف اولیه و جستجوی معماری عصبی را ارائه می دهد. از الگوریتم های مختلف بهینه سازی هایپرپارامتر، از جمله جستجوی تصادفی، بهینه سازی بیزی و HyperBand پشتیبانی می کند. این الگوریتم‌ها به توسعه‌دهندگان کمک می‌کنند تا بهترین پیکربندی‌های فراپارامتر را در یک فضای پارامتر مشخص به‌طور مؤثر جستجو کنند. با تعریف آزمایش‌ها، کاربران می‌توانند فراپارامترهایی را که باید تنظیم شوند، محدوده آنها، هدف بهینه‌سازی (به عنوان مثال، دقت یا از دست دادن)، و الگوریتم جستجوی مورد استفاده را مشخص کنند. Katib همچنین از استراتژی‌های توقف زودهنگام پشتیبانی می‌کند و اجازه می‌دهد آزمایش‌هایی با عملکرد ضعیف به صورت پویا در طول آموزش خاتمه داده شوند و در نتیجه منابع محاسباتی را ذخیره کنند. علاوه بر این، Katib قابلیت‌های جستجوی معماری عصبی (NAS) را ارائه می‌کند که به کاربران اجازه می‌دهد تا معماری‌های مختلف شبکه را برای بهبود عملکرد مدل بررسی کنند.

همانطور که در بخش 6.1 نشان داده شده است، یک نوت بوک جدید ایجاد کنید. پس از ایجاد یک فایل پایتون، دستور زیر را در ترمینال اجرا کنید تا کتابخانه های لازم دانلود شود.

pip install kubeflow-katib

import kubeflow.katib as katib

_# Step 1. Create an objective function._

def objective(parameters):

    _# Import required packages._

    import time

    time.sleep(5)

    _# Calculate objective function._

    result = 4 * int(parameters["a"]) - float(parameters["b"]) ** 2

    _# Katib parses metrics in this format: <metric-name>=<metric-value>._

    print(f"result={result}")

_# Step 2. Create HyperParameter search space._

parameters = {

    "a": katib.search.int(min=10, max=20),

    "b": katib.search.double(min=0.1, max=0.2)

}

_# Step 3. Create Katib Experiment._

katib_client = katib.KatibClient()

name = "tune-experiment"

katib_client.tune(

    name=name,

    objective=objective,

    parameters=parameters,

    objective_metric_name="result",

    max_trial_count=12

)

_# Step 4. Get the best HyperParameters._

print(katib_client.get_optimal_hyperparameters(name))

پس از اجرا، می توانید فایل های بهینه سازی پارامتر و گردش کار کلی را در AutoML مشاهده کنید.

گردش کار AutoML
بهینه سازی پارامتر

این کد به طور خودکار بهینه سازی هایپرپارامتر را با تعریف یک تابع هدف، با استفاده از یک الگوریتم جستجوی تصادفی انجام می دهد. تابع هدف به شکل است result = 4a - b^2، پارامتر کجا a یک عدد صحیح از 10 تا 20 و پارامتر است b یک عدد ممیز شناور از 0.1 تا 0.2 است. کد ابتدا تابع هدف را تعریف می کند و سپس فضای جستجو را برای فراپارامترها ایجاد می کند. بعد، Kubeflow Katib's KatibClient برای شروع آزمایش استفاده می شود و تابع هدف، محدوده پارامترها و حداکثر تعداد آزمایش را مشخص می کند (12). در نهایت، katib_client.get_optimal_hyperparameters(name) روش ترکیب بهینه ابرپارامترها را بازیابی و خروجی می‌دهد و به تنظیم خودکار فراپارامتر برای بهینه‌سازی تابع هدف مشخص شده دست می‌یابد.

پارامترهای بهینه
تنظیم فراپارامتر

محدوده مقدار برای a 10-20 است و برای b0.1-0.2 است. تحت این شرایط، از الگوریتم جستجوی تصادفی برای یافتن حداکثر مقدار استفاده می شود F.

در زیر نمونه ای از یک تابع پیچیده تر و استفاده از الگوریتم های دیگر برای محاسبه آورده شده است:

تابع پیچیده

import kubeflow.katib as katib

_# Step 1. Create an objective function._

def objective(parameters):

    _# Import required packages._

    import time

    import math

    time.sleep(5)

    _# Calculate a more complex objective function._

    a = int(parameters["a"])

    b = float(parameters["b"])

    _#_ _复杂的目标函数示例:结合多项式、对数和三角函数的组合_

    result = (3 * a ** 2 + 2 * b - math.sin(a * b)) / (1 + math.log(b + 0.1)) + math.sqrt(abs(a - b))

    _# Katib parses metrics in this format: <metric-name>=<metric-value>._

    print(f"result={result}")

_# Step 2. Create HyperParameter search space._

parameters = {

    "a": katib.search.int(min=10, max=20),

    "b": katib.search.double(min=0.1, max=0.2)

}

_# Step 3. Create Katib Experiment._

katib_client = katib.KatibClient()

name = "tune-experiment-for-kalibbase"

katib_client.tune(

    name=name,

    objective=objective,

    parameters=parameters,

    algorithm_name="bayesianoptimization",

objective_metric_name="result",

#objective_type="minimize",  # 指定最小化目标函数

    max_trial_count=12

)

_# Step 4. Get the best HyperParameters._

print(katib_client.get_optimal_hyperparameters(name))

با استفاده از یک تابع پیچیده تر برای بهینه سازی پارامترها، الگوریتم جستجوی بیزی استفاده می شود:

الگوریتم جستجوی بیزی

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا