استقرار 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 مجموعه کاملی از ابزارها و خدمات را برای پشتیبانی از همه چیز از کل چرخه زندگی یادگیری ماشین از آماده سازی داده ها، آموزش مدل، تنظیم تا استقرار ارائه می دهد. این راه حل انتها به انتها به دانشمندان و مهندسان داده کمک می کند تا به سرعت از توسعه به تولید منتقل شوند.
به طور کلی، 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 است و برای b
0.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))
با استفاده از یک تابع پیچیده تر برای بهینه سازی پارامترها، الگوریتم جستجوی بیزی استفاده می شود: