すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:クラウドネイティブ AI スイート

最終更新日:Apr 04, 2026

このガイドでは、オープンソースの Fashion-MNIST データセットを使用して、クラウドネイティブ AI スイートを用いてディープラーニングタスクを実行し、分散トレーニングのパフォーマンスを最適化し、モデルのパフォーマンスをデバッグし、モデルを ACK クラスターにデプロイする方法を説明します。

背景情報

クラウドネイティブ AI スイートは、AI エンジニアリングを加速させるために、個別にデプロイ可能なコンポーネント (K8s Helm Charts) を提供します。

クラウドネイティブ AI スイートには、管理者と開発者の 2 つのユーザーロールがあります。

  • 管理者:ユーザーと権限の管理、クラスターリソースの割り当て、外部ストレージの設定、データセットの管理、およびクラスターダッシュボードでのクラスター使用率の監視を行います。

  • 開発者:クラスターリソースを使用してタスクを送信します。開発者は、管理者によって作成され、権限を割り当てられる必要があります。その後、開発者は Arena CLI や Jupyter Notebook などのツールを使用して日常の開発を行います。

前提条件

開始する前に、以下の前提条件が満たされていることを確認してください。

  • Kubernetes クラスターが作成されていること。詳細については、「ACK マネージドクラスターの作成」をご参照ください。

    • クラスター内の各ノードには、少なくとも 300 GB のディスク領域が必要です。

    • 最適なデータアクセラレーションの比較のために、それぞれが 8 つの V100 GPU を搭載した 4 つのインスタンスを使用してください。

    • 最適なトポロジー対応のため、2 つの V100 インスタンスを使用してください。

  • クラウドネイティブ AI スイートがインストールされていること。詳細については、「クラウドネイティブ AI スイートのインストール」をご参照ください。

  • AI ダッシュボードにアクセスできること。アクセスの設定方法については、「AI ダッシュボードへのアクセス」をご参照ください。

  • AI 開発者コンソールにアクセスできること。アクセスの設定方法については、「AI 開発者コンソールへのアクセス」をご参照ください。

    説明

    Alibaba Cloud が提供する AI コンソール (AI 開発者コンソールおよび AI ダッシュボードを含む) は、2025 年 1 月 22 日からホワイトリストに登録されたユーザーに提供されます。この日より前に AI 開発者コンソールまたは AI ダッシュボードをデプロイした場合、コンソールの使用には影響ありません。ホワイトリストに登録されていないユーザーは、オープンソースコミュニティから AI コンソールをインストールして設定できます。詳細な手順については、「オープンソース AI コンソール」をご参照ください。

  • Fashion MNIST データセットをダウンロードし、Object Storage Service (OSS) にアップロードしていること。OSS へのファイルのアップロード方法については、「ファイルのアップロード」をご参照ください。

  • テストコードを含む Git リポジトリの URL、ユーザー名、パスワードを持っていること。

  • kubectl を使用して Kubernetes クラスターに接続していること。詳細については、「クラスターの kubeconfig を取得し、kubectl を使用してクラスターに接続」をご参照ください。

  • Arena コマンドライン送信ツールがインストールされていること。詳細については、「Arena クライアントの設定」をご参照ください。

実験環境

このガイドでは、AI 開発者がクラウドネイティブ AI スイートを使用して Fashion-MNIST タスクを開発、トレーニング、高速化、管理、評価、デプロイする手順を説明します。

この実験のクラスター構成は以下の通りです。

ホスト名

IP

ロール

GPU

vCPU

メモリ

cn-beijing.192.168.0.13

192.168.0.13

ジャンプサーバー

1

8

30580004 KiB

cn-beijing.192.168.0.16

192.168.0.16

ワーカー

1

8

30580004 KiB

cn-beijing.192.168.0.17

192.168.0.17

ワーカー

1

8

30580004 KiB

cn-beijing.192.168.0.240

192.168.0.240

ワーカー

1

8

30580004 KiB

cn-beijing.192.168.0.239

192.168.0.239

ワーカー

1

8

30580004 KiB

目標

このチュートリアルでは、以下の方法を説明します。

  • データセットの管理

  • Jupyter Notebook 開発環境の設定

  • 単一ノードのトレーニングジョブの送信

  • 分散トレーニングジョブの送信

  • Fluid を使用したトレーニングジョブの高速化

  • ACK AI ジョブスケジューラを使用したトレーニングジョブの高速化

  • モデルの管理

  • モデルの評価

  • 推論サービスのデプロイ

ステップ 1:開発者アカウントの作成とリソースの割り当て

管理者に連絡して、以下のリソースを取得してください。

  • ユーザーアカウント。

  • リソースクォータ。

  • コンソールを使用してジョブを送信する場合の AI Developer Console のエンドポイントです。

    説明

    Alibaba Cloud が提供する AI コンソール (開発者コンソールおよび O&M コンソールを含む) は、2025 年 1 月 22 日からホワイトリストに登録されたユーザーに提供されます。ホワイトリストの展開前に開発者コンソールまたは O&M コンソールをデプロイした場合、使用には影響ありません。ホワイトリストに登録されていないユーザーは、オープンソースコミュニティからオープンソースの AI コンソールをインストールして設定できます。オープンソースの設定の詳細については、「オープンソース AI コンソール」をご参照ください。

  • Arena CLI を使用してジョブを送信する場合、クラスターにアクセスするための kubeconfig ファイルを取得します。詳細については、「kubeconfig を取得し、クラスターに接続する」をご参照ください。

ステップ 2:データセットの作成

データセットは管理者によって管理される必要があります。この例では、Fashion-MNIST データセットを使用します。

Fashion-MNIST データセットの作成

  1. 以下の YAML マニフェストを含む fashion-mnist.yaml という名前のファイルを作成します。

    この例では、OSS をバックエンドとする永続ボリューム (PV) と永続ボリューム要求 (PVC) を作成します。

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: fashion-demo-pv
    spec:
      accessModes:
      - ReadWriteMany
      capacity:
        storage: 10Gi
      csi:
        driver: ossplugin.csi.alibabacloud.com
        volumeAttributes:
          bucket: fashion-mnist
          otherOpts: ""
          url: oss-cn-beijing.aliyuncs.com
          akId: "AKID"
          akSecret: "AKSECRET"
        volumeHandle: fashion-demo-pv
      persistentVolumeReclaimPolicy: Retain
      storageClassName: oss
      volumeMode: Filesystem
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: fashion-demo-pvc
      namespace: demo-ns
    spec:
      accessModes:
      - ReadWriteMany
      resources:
        requests:
          storage: 10Gi
      selector:
        matchLabels:
          alicloud-pvname: fashion-demo-pv
      storageClassName: oss
      volumeMode: Filesystem
      volumeName: fashion-demo-pv
  2. 次のコマンドを実行して、Fashion-MNIST データセットを作成します。

    kubectl create -f fashion-mnist.yaml
  3. PV と PVC が Bound 状態であることを確認します。

    • 次のコマンドを実行して、PV のステータスを確認します。

      kubectl get pv fashion-demo-pv

      期待される出力:

      NAME              CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                        STORAGECLASS   REASON   AGE
      fashion-demo-pv   10Gi       RWX            Retain           Bound    demo-ns/fashion-demo-pvc     oss                     8h
    • 次のコマンドを実行して、PVC のステータスを確認します。

      kubectl get pvc fashion-demo-pvc -n demo-ns

      期待される出力:

      NAME               STATUS   VOLUME            CAPACITY   ACCESS MODES   STORAGECLASS   AGE
      fashion-demo-pvc   Bound    fashion-demo-pv   10Gi       RWX            oss            8h

    出力は、PV と PVC の両方のステータスが Bound であることを示しています。

データセットの高速化

管理者は AI ダッシュボードからデータセットを高速化できます。

  1. AI ダッシュボードへのアクセス」を行います。
  2. AI ダッシュボードの左側のナビゲーションウィンドウで、[Dataset] > [Dataset List] を選択します。
  3. [Dataset list] ページで、対象のデータセットの [Actions] 列にある [Accelerate] をクリックします。

    下図は高速化されたデータセットを示します。加速数据集

ステップ 3:モデル開発

このセクションでは、Jupyter Notebook を使用して開発環境をセットアップする方法について説明します。プロセスは以下の通りです。

  1. オプション:カスタムイメージを使用して Jupyter Notebook を作成します。

  2. Jupyter Notebook でモデルを開発し、テストします。

  3. Jupyter Notebook から Git リポジトリにコードをプッシュします。

  4. Arena SDK を使用してトレーニングジョブを送信します。

(オプション) ステップ 1:カスタムイメージからノートブックを作成する

AI 開発者コンソールは、Jupyter Notebook 用のデフォルトの TensorFlow および PyTorch イメージを提供します。これらのイメージが要件を満たさない場合は、カスタムイメージをビルドできます。

  1. 以下のテンプレートを使用して Dockerfile という名前のファイルを作成します。

    カスタムイメージの仕様の詳細については、「ノートブックの作成と使用」をご参照ください。

    cat<<EOF >dockerfile
    FROM tensorflow/tensorflow:1.15.5-gpu
    USER root
    RUN pip install jupyter && \
        pip install ipywidgets && \
        jupyter nbextension enable --py widgetsnbextension && \
        pip install jupyterlab && jupyter serverextension enable --py jupyterlab
    EXPOSE 8888
    #USER jovyan
    CMD ["sh", "-c", "jupyter-lab --notebook-dir=/home/jovyan --ip=0.0.0.0 --no-browser --allow-root --port=8888 --NotebookApp.token='' --NotebookApp.password='' --NotebookApp.allow_origin='*' --NotebookApp.base_url=${NB_PREFIX} --ServerApp.authenticate_prometheus=False"]
    EOF
  2. 次のコマンドを実行して、Dockerfile からイメージをビルドします。

    docker build -f dockerfile .

    期待される出力:

    Sending build context to Docker daemon  9.216kB
    Step 1/5 : FROM tensorflow/tensorflow:1.15.5-gpu
     ---> 73be11373498
    Step 2/5 : USER root
     ---> Using cache
     ---> 7ee21dc7e42e
    Step 3/5 : RUN pip install jupyter &&     pip install ipywidgets &&     jupyter nbextension enable --py widgetsnbextension &&     pip install jupyterlab && jupyter serverextension enable --py jupyterlab
     ---> Using cache
     ---> 23bc51c5e16d
    Step 4/5 : EXPOSE 8888
     ---> Using cache
     ---> 76a55822ddae
    Step 5/5 : CMD ["sh", "-c", "jupyter-lab --notebook-dir=/home/jovyan --ip=0.0.0.0 --no-browser --allow-root --port=8888 --NotebookApp.token='' --NotebookApp.password='' --NotebookApp.allow_origin='*' --NotebookApp.base_url=${NB_PREFIX} --ServerApp.authenticate_prometheus=False"]
     ---> Using cache
     ---> 3692f04626d5
    Successfully built 3692f04626d5
  3. 次のコマンドを実行して、イメージにタグを付け、コンテナレジストリにプッシュします。

    docker tag ${IMAGE_ID} registry-vpc.cn-beijing.aliyuncs.com/${DOCKER_REPO}/jupyter:fashion-mnist-20210802a
    docker push registry-vpc.cn-beijing.aliyuncs.com/${DOCKER_REPO}/jupyter:fashion-mnist-20210802a
  4. コンテナレジストリからイメージをプルするためのシークレットを作成します。

    詳細については、「プライベートレジストリからイメージをプルするためのシークレットの作成」をご参照ください。

    kubectl create secret docker-registry regcred \
      --docker-server=<your-registry-server> \
      --docker-username=<your-username> \
      --docker-password=<your-password> \
      --docker-email=<your-email>
  5. AI 開発者コンソールで Jupyter Notebook を作成します。

    Jupyter Notebook の作成方法の詳細については、「ノートブックの作成と使用」をご参照ください。

    Jupyter Notebook を作成するために必要なパラメーターについては、次の図をご参照ください。创建Notebook

ステップ 2:ノートブックでの開発とテスト

  1. AI 開発者コンソールにアクセスします
  2. AI 開発者コンソールの左側のナビゲーションウィンドウで、[Notebook] をクリックします。
  3. [ノートブック] ページで、ステータス[実行中] の Jupyter Notebook をクリックします。

  4. 新しいターミナルランチャーを作成し、データがマウントされていることを確認します。

    pwd
    /root/data
    ls -alh

    期待される出力:

    total 30M
    drwx------ 1 root root    0 Jan  1  1970 .
    drwx------ 1 root root 4.0K Aug  2 04:15 ..
    drwxr-xr-x 1 root root    0 Aug  1 14:16 saved_model
    -rw-r----- 1 root root 4.3M Aug  1 01:53 t10k-images-idx3-ubyte.gz
    -rw-r----- 1 root root 5.1K Aug  1 01:53 t10k-labels-idx1-ubyte.gz
    -rw-r----- 1 root root  26M Aug  1 01:54 train-images-idx3-ubyte.gz
    -rw-r----- 1 root root  29K Aug  1 01:53 train-labels-idx1-ubyte.gz
  5. 新しいノートブックを作成し、次のコードを追加します。

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
    
    import os
    import gzip
    import numpy as np
    import tensorflow as tf
    from tensorflow import keras
    print('TensorFlow version: {}'.format(tf.__version__))
    dataset_path = "/root/data/"
    model_path = "./model/"
    model_version =  "v1"
    
    def load_data():
        files = [
            'train-labels-idx1-ubyte.gz',
            'train-images-idx3-ubyte.gz',
            't10k-labels-idx1-ubyte.gz',
            't10k-images-idx3-ubyte.gz'
        ]
        paths = []
        for fname in files:
            paths.append(os.path.join(dataset_path, fname))
        with gzip.open(paths[0], 'rb') as labelpath:
            y_train = np.frombuffer(labelpath.read(), np.uint8, offset=8)
        with gzip.open(paths[1], 'rb') as imgpath:
            x_train = np.frombuffer(imgpath.read(), np.uint8, offset=16).reshape(len(y_train), 28, 28)
        with gzip.open(paths[2], 'rb') as labelpath:
            y_test = np.frombuffer(labelpath.read(), np.uint8, offset=8)
        with gzip.open(paths[3], 'rb') as imgpath:
            x_test = np.frombuffer(imgpath.read(), np.uint8, offset=16).reshape(len(y_test), 28, 28)
        return (x_train, y_train),(x_test, y_test)
    
    def train():
        (train_images, train_labels), (test_images, test_labels) = load_data()
    
        # scale the values to 0.0 to 1.0
        train_images = train_images / 255.0
        test_images = test_images / 255.0
    
        # reshape for feeding into the model
        train_images = train_images.reshape(train_images.shape[0], 28, 28, 1)
        test_images = test_images.reshape(test_images.shape[0], 28, 28, 1)
    
        class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
                    'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
    
        print('\ntrain_images.shape: {}, of {}'.format(train_images.shape, train_images.dtype))
        print('test_images.shape: {}, of {}'.format(test_images.shape, test_images.dtype))
    
        model = keras.Sequential([
        keras.layers.Conv2D(input_shape=(28,28,1), filters=8, kernel_size=3,
                            strides=2, activation='relu', name='Conv1'),
        keras.layers.Flatten(),
        keras.layers.Dense(10, activation=tf.nn.softmax, name='Softmax')
        ])
        model.summary()
        testing = False
        epochs = 5
        model.compile(optimizer='adam',
                    loss='sparse_categorical_crossentropy',
                    metrics=['accuracy'])
        logdir = "/training_logs"
        tensorboard_callback = keras.callbacks.TensorBoard(log_dir=logdir)
        model.fit(train_images,
            train_labels,
            epochs=epochs,
            callbacks=[tensorboard_callback],
        )
        test_loss, test_acc = model.evaluate(test_images, test_labels)
        print('\nTest accuracy: {}'.format(test_acc))
        export_path = os.path.join(model_path, model_version)
        print('export_path = {}\n'.format(export_path))
        tf.keras.models.save_model(
            model,
            export_path,
            overwrite=True,
            include_optimizer=True,
            save_format=None,
            signatures=None,
            options=None
        )
        print('\nSaved model success')
    if __name__ == '__main__':
        train()
    重要

    コード内で、`dataset_path` と `model_path` はデータソースのマウントパスを指す必要があります。これにより、ノートブックはデータセットがローカルに保存されているかのようにアクセスできます。

  6. ノートブックで、执行图标 アイコンをクリックしてコードを実行します。

    期待される出力:

    TensorFlow version: 1.15.5
    
    train_images.shape: (60000, 28, 28, 1), of float64
    test_images.shape: (10000, 28, 28, 1), of float64
    Model: "sequential_2"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #
    =================================================================
    Conv1 (Conv2D)               (None, 13, 13, 8)         80
    _________________________________________________________________
    flatten_2 (Flatten)          (None, 1352)              0
    _________________________________________________________________
    Softmax (Dense)              (None, 10)                13530
    =================================================================
    Total params: 13,610
    Trainable params: 13,610
    Non-trainable params: 0
    _________________________________________________________________
    Train on 60000 samples
    Epoch 1/5
    60000/60000 [==============================] - 3s 57us/sample - loss: 0.5452 - acc: 0.8102
    Epoch 2/5
    60000/60000 [==============================] - 3s 52us/sample - loss: 0.4103 - acc: 0.8555
    Epoch 3/5
    60000/60000 [==============================] - 3s 55us/sample - loss: 0.3750 - acc: 0.8681
    Epoch 4/5
    60000/60000 [==============================] - 3s 55us/sample - loss: 0.3524 - acc: 0.8757
    Epoch 5/5
    60000/60000 [==============================] - 3s 53us/sample - loss: 0.3368 - acc: 0.8798
    10000/10000 [==============================] - 0s 37us/sample - loss: 0.3770 - acc: 0.8673
    
    Test accuracy: 0.8672999739646912
    export_path = ./model/v1
    Saved model success

ステップ 3:Git リポジトリにコードをプッシュする

  1. 次のコマンドを実行して Git をインストールします。

    apt-get update
    apt-get install git
  2. 次のコマンドを実行して Git を設定し、認証情報をキャッシュします。

    git config --global credential.helper store
    git pull ${YOUR_GIT_REPO}
  3. 次のコマンドを実行して、コードを Git リポジトリにプッシュします。

    git push origin fashion-test

    期待される出力:

    Total 0 (delta 0), reused 0 (delta 0)
    To codeup.aliyun.com:60b4cf5c66bba1c04b442e49/tensorflow-fashion-mnist-sample.git
     * [new branch]      fashion-test -> fashion-test

ステップ 4:トレーニングジョブの送信

  1. Arena SDK の依存関係をインストールします。

    !pip install coloredlogs
  2. Python ファイルを作成し、次のコードを追加します。

    import os
    import sys
    import time
    from arenasdk.client.client import ArenaClient
    from arenasdk.enums.types import *
    from arenasdk.exceptions.arena_exception import *
    from arenasdk.training.tensorflow_job_builder import *
    from arenasdk.logger.logger import LoggerBuilder
    
    def main():
        print("Starting to test the Arena Python SDK")
        client = ArenaClient("","demo-ns","info","arena-system") # ジョブが送信される名前空間
        print("ArenaClient created successfully.")
        print("Creating tfjob...")
        job_name = "arena-sdk-distributed-test"
        job_type = TrainingJobType.TFTrainingJob
        try:
            # トレーニングジョブをビルド
            job =  TensorflowJobBuilder().with_name(job_name)\
                .with_workers(1)\
                .with_gpus(1)\
                .with_worker_image("tensorflow/tensorflow:1.5.0-devel-gpu")\
                .with_ps_image("tensorflow/tensorflow:1.5.0-devel")\
                .with_ps_count(1)\
                .with_datas({"fashion-demo-pvc":"/data"})\
                .enable_tensorboard()\
                .with_sync_mode("git")\
                .with_sync_source("https://codeup.aliyun.com/60b4cf5c66bba1c04b442e49/tensorflow-fashion-mnist-sample.git")\  # Git リポジトリの URL
                .with_envs({\
                    "GIT_SYNC_USERNAME":"USERNAME", \   # Git リポジトリのユーザー名
                    "GIT_SYNC_PASSWORD":"PASSWORD",\    # Git リポジトリのパスワード
                    "TEST_TMPDIR":"/",\
                })\
                .with_command("python code/tensorflow-fashion-mnist-sample/tf-distributed-mnist.py").build()
            # トレーニングジョブが存在しない場合は作成
            if client.training().get(job_name, job_type):
                print("The job {} already exists. Deleting it.".format(job_name))
                client.training().delete(job_name, job_type)
                time.sleep(3)
    
            output = client.training().submit(job)
            print(output)
    
            count = 0
            # トレーニングジョブが実行を開始するのを待機
            while True:
                if count > 160:
                    raise Exception("Timed out waiting for the job to start running")
                jobInfo = client.training().get(job_name,job_type)
                if jobInfo.get_status() == TrainingJobStatus.TrainingJobPending:
                    print("Job status is PENDING. Waiting...")
                    count = count + 1
                    time.sleep(5)
                    continue
                print("Current status of job {} is {}".format(job_name, jobInfo.get_status().value))
                break
            # トレーニングジョブのログを取得
            logger = LoggerBuilder().with_accepter(sys.stdout).with_follow().with_since("5m")
            #jobInfo.get_instances()[0].get_logs(logger)
            # トレーニングジョブの情報を表示
            print(str(jobInfo))
            # トレーニングジョブを削除
            #client.training().delete(job_name, job_type)
        except ArenaException as e:
            print(e)
    
    main()
    • namespace:この例では、トレーニングジョブは demo-ns 名前空間に送信されます。

    • with_sync_source:Git リポジトリのアドレス。

    • with_envs:Git リポジトリのユーザー名とパスワード。

  3. ノートブックで、执行图标 アイコンをクリックしてコードを実行します。

    期待される出力:

    2021-11-02/08:57:28 DEBUG util.py[line:19] - execute command: [arena get --namespace=demo-ns --arena-namespace=arena-system --loglevel=info arena-sdk-distributed-test --type=tfjob -o json]
    2021-11-02/08:57:28 DEBUG util.py[line:19] - execute command: [arena submit --namespace=demo-ns --arena-namespace=arena-system --loglevel=info tfjob --name=arena-sdk-distributed-test --workers=1 --gpus=1 --worker-image=tensorflow/tensorflow:1.5.0-devel-gpu --ps-image=tensorflow/tensorflow:1.5.0-devel --ps=1 --data=fashion-demo-pvc:/data --tensorboard --sync-mode=git --sync-source=https://codeup.aliyun.com/60b4cf5c66bba1c04b442e49/tensorflow-fashion-mnist-sample.git --env=GIT_SYNC_USERNAME=kubeai --env=GIT_SYNC_PASSWORD=kubeai@ACK123 --env=TEST_TMPDIR=/ python code/tensorflow-fashion-mnist-sample/tf-distributed-mnist.py]
    start to test arena-python-sdk
    create ArenaClient succeed.
    start to create tfjob
    2021-11-02/08:57:29 DEBUG util.py[line:19] - execute command: [arena get --namespace=demo-ns --arena-namespace=arena-system --loglevel=info arena-sdk-distributed-test --type=tfjob -o json]
    service/arena-sdk-distributed-test-tensorboard created
    deployment.apps/arena-sdk-distributed-test-tensorboard created
    tfjob.kubeflow.org/arena-sdk-distributed-test created
    
    job status is PENDING,waiting...
    2021-11-02/09:00:34 DEBUG util.py[line:19] - execute command: [arena get --namespace=demo-ns --arena-namespace=arena-system --loglevel=info arena-sdk-distributed-test --type=tfjob -o json]
    current status is RUNNING of job arena-sdk-distributed-test
    {
        "allocated_gpus": 1,
        "chief_name": "arena-sdk-distributed-test-worker-0",
        "duration": "185s",
        "instances": [
            {
                "age": "13s",
                "gpu_metrics": [],
                "is_chief": false,
                "name": "arena-sdk-distributed-test-ps-0",
                "node_ip": "192.168.5.8",
                "node_name": "cn-beijing.192.168.5.8",
                "owner": "arena-sdk-distributed-test",
                "owner_type": "tfjob",
                "request_gpus": 0,
                "status": "Running"
            },
            {
                "age": "13s",
                "gpu_metrics": [],
                "is_chief": true,
                "name": "arena-sdk-distributed-test-worker-0",
                "node_ip": "192.168.5.8",
                "node_name": "cn-beijing.192.168.5.8",
                "owner": "arena-sdk-distributed-test",
                "owner_type": "tfjob",
                "request_gpus": 1,
                "status": "Running"
            }
        ],
        "name": "arena-sdk-distributed-test",
        "namespace": "demo-ns",
        "priority": "N/A",
        "request_gpus": 1,
        "tensorboard": "http://192.168.5.6:31068",
        "type": "tfjob"
    }

ステップ 4:モデルのトレーニング

これらの例では、スタンドアロンのトレーニングジョブ、分散トレーニングジョブ、Fluid で高速化されたトレーニングジョブ、および ACK AI ジョブスケジューラで高速化された分散トレーニングジョブを送信する方法を示します。

例 1:スタンドアロンの TensorFlow トレーニングジョブの送信

ノートブックでコードを開発して保存した後、Arena CLI または AI 開発者コンソールを使用してトレーニングジョブを送信できます。

方法 1:Arena CLI を使用する

arena \
  submit \
  tfjob \
  -n ns1 \
  --name=fashion-mnist-arena \
  --data=fashion-mnist-jackwg-pvc:/root/data/ \
  --env=DATASET_PATH=/root/data/ \
  --env=MODEL_PATH=/root/saved_model \
  --env=MODEL_VERSION=1 \
  --env=GIT_SYNC_USERNAME=<GIT_USERNAME> \
  --env=GIT_SYNC_PASSWORD=<GIT_PASSWORD> \
  --sync-mode=git \
  --sync-source=https://codeup.aliyun.com/60b4cf5c66bba1c04b442e49/tensorflow-fashion-mnist-sample.git \
  --image="tensorflow/tensorflow:2.2.2-gpu" \
  "python /root/code/tensorflow-fashion-mnist-sample/train.py --log_dir=/training_logs"

方法 2:AI 開発者コンソールを使用する

  1. データソースを設定します。詳細については、「データセットの設定」をご参照ください。

    配置训练数据

    主要なパラメーターを次の表に示します。

    パラメーター

    必須

    名前

    fashion-demo

    はい

    名前空間

    demo-ns

    はい

    PersistentVolumeClaim

    fashion-demo-pvc

    はい

    ローカルディレクトリ

    /root/data

    いいえ

  2. ソースコードリポジトリを設定します。詳細については、「ソースコードリポジトリの設定」をご参照ください。

    新增代码配置

    パラメーター

    必須

    名前

    fashion-git

    はい

    Git URL

    https://codeup.aliyun.com/60b4cf5c66bba1c04b442e49/tensorflow-fashion-mnist-sample.git

    はい

    デフォルトブランチ

    master

    いいえ

    ローカルディレクトリ

    /root/

    いいえ

    プライベート Git ユーザー名

    プライベート Git リポジトリのユーザー名。

    いいえ

    プライベート Git パスワード/認証情報

    プライベート Git リポジトリのパスワード。

    いいえ

  3. スタンドアロンのトレーニングジョブを送信します。詳細については、「TensorFlow トレーニングジョブの送信」をご参照ください。

    トレーニングパラメーターを設定し、送信 をクリックします。その後、[ジョブリスト] でトレーニングジョブを表示できます。次の表に、ジョブを送信するためのパラメーターを示します。提交单机训练任务

    パラメーター

    説明

    タスク名

    この例では、ジョブ名は fashion-tf-ui です。

    ジョブタイプ

    この例では、[TF Stand-alone] を選択します。

    名前空間

    この例では、名前空間は demo-ns です。これはデータセットの名前空間と一致する必要があります。

    データソース

    この例では、このメソッドの最初のステップで設定した fashion-demo を選択します。

    ソースコード

    この例では、このメソッドの 2 番目のステップで設定した fashion-git を選択します。

    コードブランチ

    この例では、コードブランチは master です。

    コマンド

    この例では、コマンドは "export DATASET_PATH=/root/data/ &&export MODEL_PATH=/root/saved_model &&export MODEL_VERSION=1 &&python /root/code/tensorflow-fashion-mnist-sample/train.py" です。

    プライベート Git リポジトリ

    プライベートソースコードリポジトリを使用する場合は、そのユーザー名とパスワードを設定する必要があります。

    インスタンス数

    デフォルト値は 1 です。

    イメージ

    この例では、イメージは tensorflow/tensorflow:2.2.2-gpu です。

    イメージプルシークレット

    プライベートイメージレジストリを使用する場合は、事前にイメージプルシークレットを作成する必要があります。

    CPU (コア)

    デフォルト値は 4 です。

    メモリ (GB)

    デフォルト値は 8 です。

    Arena CLI のリファレンスについては、「Arena を使用して TensorFlow トレーニングジョブを送信する」をご参照ください。

  4. ジョブログを表示します。

    1. AI Developer コンソールの左側のナビゲーションウィンドウで、タスク をクリックします。

    2. タスク ページで、対象のジョブの名前をクリックします。

    3. 「ジョブ詳細」ページで、インスタンス タブをクリックし、ターゲットインスタンスのアクション 列のログ をクリックします。

      以下はサンプルログ情報です。

      train_images.shape: (60000, 28, 28, 1), of float64
      test_images.shape: (10000, 28, 28, 1), of float64
      Model: "sequential"
      _________________________________________________________________
      Layer (type)                 Output Shape              Param #
      =================================================================
      Conv1 (Conv2D)               (None, 13, 13, 8)         80
      _________________________________________________________________
      flatten (Flatten)            (None, 1352)              0
      _________________________________________________________________
      Softmax (Dense)              (None, 10)                13530
      =================================================================
      Total params: 13,610
      Trainable params: 13,610
      Non-trainable params: 0
      _________________________________________________________________
      Epoch 1/5
      2021-08-01 14:21:17.532237: E tensorflow/core/profiler/internal/gpu/cupti_tracer.cc:1430] function cupti_interface_->EnableCallback( 0 , subscriber_, CUPTI_CB_DOMAIN_DRIVER_API, cbid)failed with error CUPTI_ERROR_INVALID_PARAMETER
      2021-08-01 14:21:17.532390: I tensorflow/core/profiler/internal/gpu/device_tracer.cc:216]  GpuTracer has collected 0 callback api events and 0 activity events.
      2021-08-01 14:21:17.533535: I tensorflow/core/profiler/rpc/client/save_profile.cc:168] Creating directory: /training_logs/train/plugins/profile/2021_08_01_14_21_17
      2021-08-01 14:21:17.533928: I tensorflow/core/profiler/rpc/client/save_profile.cc:174] Dumped gzipped tool data for trace.json.gz to /training_logs/train/plugins/profile/2021_08_01_14_21_17/fashion-mnist-arena-chief-0.trace.json.gz
      2021-08-01 14:21:17.534251: I tensorflow/core/profiler/utils/event_span.cc:288] Generation of step-events took 0 ms
      
      2021-08-01 14:21:17.534961: I tensorflow/python/profiler/internal/profiler_wrapper.cc:87] Creating directory: /training_logs/train/plugins/profile/2021_08_01_14_21_17Dumped tool data for overview_page.pb to /training_logs/train/plugins/profile/2021_08_01_14_21_17/fashion-mnist-arena-chief-0.overview_page.pb
      Dumped tool data for input_pipeline.pb to /training_logs/train/plugins/profile/2021_08_01_14_21_17/fashion-mnist-arena-chief-0.input_pipeline.pb
      Dumped tool data for tensorflow_stats.pb to /training_logs/train/plugins/profile/2021_08_01_14_21_17/fashion-mnist-arena-chief-0.tensorflow_stats.pb
      Dumped tool data for kernel_stats.pb to /training_logs/train/plugins/profile/2021_08_01_14_21_17/fashion-mnist-arena-chief-0.kernel_stats.pb
      
      1875/1875 [==============================] - 3s 2ms/step - loss: 0.5399 - accuracy: 0.8116
      Epoch 2/5
      1875/1875 [==============================] - 3s 2ms/step - loss: 0.4076 - accuracy: 0.8573
      Epoch 3/5
      1875/1875 [==============================] - 3s 2ms/step - loss: 0.3727 - accuracy: 0.8694
      Epoch 4/5
      1875/1875 [==============================] - 3s 2ms/step - loss: 0.3512 - accuracy: 0.8769
      Epoch 5/5
      1875/1875 [==============================] - 3s 2ms/step - loss: 0.3351 - accuracy: 0.8816
      313/313 [==============================] - 0s 1ms/step - loss: 0.3595 - accuracy: 0.8733
      2021-08-01 14:21:34.820089: W tensorflow/python/util/util.cc:329] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
      WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/resource_variable_ops.py:1817: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
      Instructions for updating:
      If using Keras pass *_constraint arguments to layers.
      
      Test accuracy: 0.8733000159263611
      export_path = /root/saved_model/1
      
      
      Saved model success
  5. TensorBoard を表示します。

    kubectl port-forward コマンドを使用して TensorBoard サービスにアクセスします。次の手順に従ってください。

    1. 次のコマンドを実行して、TensorBoard サービスのエンドポイントを取得します。

      kubectl get svc -n demo-ns

      期待される出力:

      NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)               AGE
      tf-dist-arena-tensorboard   NodePort    172.16.XX.XX     <none>        6006:32226/TCP        80m
    2. 次のコマンドを実行して、TensorBoard ポートを転送します。

      kubectl port-forward svc/tf-dist-arena-tensorboard -n demo-ns 6006:6006

      期待される出力:

      Forwarding from 127.0.0.1:6006 -> 6006
      Forwarding from [::1]:6006 -> 6006
      Handling connection for 6006
      Handling connection for 6006
    3. ブラウザで http://localhost:6006/ を開き、TensorBoard を表示します。

      Tensorboard

例 2:分散トレーニングジョブの送信

方法 1:Arena CLI を使用する

  1. 次のコマンドを実行して、トレーニングジョブを送信します。

    arena submit tf \
        -n demo-ns \
        --name=tf-dist-arena \
        --working-dir=/root/ \
        --data fashion-mnist-pvc:/data \
        --env=TEST_TMPDIR=/ \
        --env=GIT_SYNC_USERNAME=kubeai \
        --env=GIT_SYNC_PASSWORD=kubeai@ACK123 \
        --env=GIT_SYNC_BRANCH=master \
        --gpus=1 \
        --workers=2 \
        --worker-image=tensorflow/tensorflow:1.5.0-devel-gpu \
        --sync-mode=git \
        --sync-source=https://codeup.aliyun.com/60b4cf5c66bba1c04b442e49/tensorflow-fashion-mnist-sample.git \
        --ps=1 \
        --ps-image=tensorflow/tensorflow:1.5.0-devel \
        --tensorboard \
        "python code/tensorflow-fashion-mnist-sample/tf-distributed-mnist.py --log_dir=/training_logs"
  2. 次のコマンドを実行して、TensorBoard サービスのエンドポイントを取得します。

    kubectl get svc -n demo-ns

    期待される出力:

    NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                 AGE
    tf-dist-arena-tensorboard   NodePort    172.16.204.248   <none>        6006:32226/TCP          80m
  3. 次のコマンドを実行して、TensorBoard ポートを転送します。

    このコマンドは、TensorBoard サービスへのローカルプロキシを作成します。

    kubectl port-forward svc/tf-dist-arena-tensorboard -n demo-ns 6006:6006

    期待される出力:

    Forwarding from 127.0.0.1:6006 -> 6006
    Forwarding from [::1]:6006 -> 6006
    Handling connection for 6006
    Handling connection for 6006
  4. ブラウザで http://localhost:6006/ を開き、TensorBoard を表示します。

    查看Tensorboard

方法 2:AI 開発者コンソールを使用する

  1. データソースを設定します。詳細については、「データセットの設定」をご参照ください。

    この例では、1 のデータを再利用します。設定は繰り返しません。

  2. ソースコードリポジトリを設定します。詳細については、「ソースコードリポジトリの設定」をご参照ください。

    この例では、2 のコードを再利用するため、設定は再度説明しません。

  3. 分散トレーニングジョブを送信します。詳細については、「TensorFlow トレーニングジョブの送信」をご参照ください。

    パラメーターを設定した後、送信 をクリックします。その後、[ジョブリスト] でトレーニングジョブを表示できます。次の表では、ジョブを送信するためのパラメーターについて説明します。提交TF分布式训练任务

    パラメーター

    説明

    タスク名

    この例では、ジョブ名は fashion-ps-ui です。

    ジョブタイプ

    この例では、[TF Distributed] を選択します。

    名前空間

    この例では、名前空間は demo-ns です。これはデータセットの名前空間と一致する必要があります。

    データソース

    この例では、例 1 で設定した fashion-demo を選択します。

    ソースコード

    この例では、例 1 で設定した fashion-git を選択します。

    コマンド

    この例では、コマンドは "export TEST_TMPDIR=/root/ && python code/tensorflow-fashion-mnist-sample/tf-distributed-mnist.py --log_dir=/training_logs" です。

    イメージ

    • ジョブリソース構成 > ワーカータブ > Image:この例では、tensorflow/tensorflow:1.5.0-devel-gpu に設定します。

    • ジョブリソース構成 > PS タブ > Image:この例では、tensorflow/tensorflow:1.5.0-devel に設定します。

    Arena CLI のリファレンスについては、「Arena を使用して TensorFlow トレーニングジョブを送信する」をご参照ください。

  4. TensorBoard を表示します。詳細については、[方法 1:Arena CLI を使用する] のステップ 2 から 4 をご参照ください。

例 3:Fluid で高速化されたトレーニングジョブの送信

この例では、AI ダッシュボードを使用してデータセットを高速化し、高速化されたデータセットを使用するジョブのトレーニング時間をベースラインと比較する方法を示します。ワークフローは以下の通りです。

  1. 管理者が AI ダッシュボードから既存のデータセットを高速化します。

  2. 開発者が Arena CLI を使用して、高速化されたデータセットを使用するトレーニングジョブを送信します。

  3. arena list コマンドを使用してジョブの実行時間を比較します。

  1. ワンクリックで既存のデータセットを高速化します。

    ステップ 2:データセットの作成」で fashion-demo-pvc データセットをすでに高速化している場合は、このステップをスキップできます。高速化されたデータセットの作成方法については、「データセットの管理」をご参照ください。

  2. 高速化されたデータセットを使用するジョブを送信します。

    開発者は、demo-ns 名前空間で高速化されたデータセットを使用するトレーニングジョブを送信します。高速化されていないジョブとの主な違いは以下の通りです。

    • --data:高速化された PVC の名前。この例では fashion-demo-pvc-acc です。

    • --env=DATASET_PATH:コードがデータを読み取るパス。このパスは、マウントパス (この例では --data からの /root/data/) + PVC 名 (この例では fashion-demo-pvc-acc) です。

    arena \
      submit \
      tfjob \
      -n demo-ns \
      --name=fashion-mnist-fluid \
      --data=fashion-demo-pvc-acc:/root/data/ \
      --env=DATASET_PATH=/root/data/fashion-demo-pvc-acc \
      --env=MODEL_PATH=/root/saved_model \
      --env=MODEL_VERSION=1 \
      --env=GIT_SYNC_USERNAME=${GIT_USERNAME} \
      --env=GIT_SYNC_PASSWORD=${GIT_PASSWORD} \
      --sync-mode=git \
      --sync-source=https://codeup.aliyun.com/60b4cf5c66bba1c04b442e49/tensorflow-fashion-mnist-sample.git \
      --image="tensorflow/tensorflow:2.2.2-gpu" \
      "python /root/code/tensorflow-fashion-mnist-sample/train.py --log_dir=/training_logs"
  3. 次のコマンドを実行して、2 つのトレーニングジョブの実行速度を比較します。

    arena list -n demo-ns

    期待される出力:

    NAME                 STATUS     TRAINER  DURATION  GPU(Requested)  GPU(Allocated)  NODE
    fashion-mnist-fluid  SUCCEEDED  TFJOB    33s       0               N/A             192.168.5.7
    fashion-mnist-arena  SUCCEEDED  TFJOB    3m        0               N/A             192.168.5.8

    arena list の出力が示すように、Fluid で高速化されたジョブは 33 秒で完了しましたが、ベースラインジョブは同じコードとノードリソースを使用して 3 分かかりました。

例 4:ACK AI ジョブスケジューラを使用して分散トレーニングジョブを高速化する

ACK AI ジョブスケジューラは、ACK がクラウドネイティブ AI とビッグデータ向けに提供する最適化されたスケジューラプラグインです。ギャングスケジューリング、キャパシティスケジューリング、トポロジー対応スケジューリングなどの機能をサポートしています。この例では、GPU トポロジー対応スケジューリングを使用して、その高速化効果を示します。

ACK AI ジョブスケジューラは、NVLink や PCIe スイッチなどの GPU 間の通信方法や、CPU の NUMA トポロジーなど、ノード上の異種リソースのトポロジー情報を利用します。これにより、スケジューラはクラスターレベルで最適なスケジューリング決定を下し、AI ジョブのパフォーマンスを向上させることができます。GPU トポロジー対応スケジューリングの詳細については、「GPU トポロジー対応スケジューリング」をご参照ください。CPU トポロジー対応スケジューリングの詳細については、「トポロジー対応 CPU スケジューリングの有効化」をご参照ください。

次の例では、GPU トポロジー対応スケジューリングを有効にし、パフォーマンスを比較する方法を示します。

  1. まず、次のコマンドを実行して、トポロジー対応スケジューリングなしのベースライントレーニングジョブを作成します。

    arena submit mpi \
      --name=tensorflow-4-vgg16 \
      --gpus=1 \
      --workers=4 \
      --image=registry.cn-hangzhou.aliyuncs.com/kubernetes-image-hub/tensorflow-benchmark:tf2.3.0-py3.7-cuda10.1 \
      "mpirun --allow-run-as-root -np "4" -bind-to none -map-by slot -x NCCL_DEBUG=INFO -x NCCL_SOCKET_IFNAME=eth0 -x LD_LIBRARY_PATH -x PATH --mca pml ob1 --mca btl_tcp_if_include eth0 --mca oob_tcp_if_include eth0 --mca orte_keep_fqdn_hostnames t --mca btl ^openib python /tensorflow/benchmarks/scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py --model=vgg16 --batch_size=64 --variable_update=horovod"
  2. トポロジー対応スケジューリングを有効にしたトレーニングジョブを作成します。

    ノードにラベルを追加します。次の例では、cn-beijing.192.168.XX.XX という名前のノードを使用します。実際のノード名に置き換えてください。

    kubectl label node cn-beijing.192.168.XX.XX ack.node.gpu.schedule=topology --overwrite

    --gputopology=true フラグを追加して、トポロジー対応スケジューリングを有効にしたトレーニングジョブを作成するために次のコマンドを実行します。

    arena submit mpi \
      --name=tensorflow-topo-4-vgg16 \
      --gpus=1 \
      --workers=4 \
      --gputopology=true \
      --image=registry.cn-hangzhou.aliyuncs.com/kubernetes-image-hub/tensorflow-benchmark:tf2.3.0-py3.7-cuda10.1 \
      "mpirun --allow-run-as-root -np "4" -bind-to none -map-by slot -x NCCL_DEBUG=INFO -x NCCL_SOCKET_IFNAME=eth0 -x LD_LIBRARY_PATH -x PATH --mca pml ob1 --mca btl_tcp_if_include eth0 --mca oob_tcp_if_include eth0 --mca orte_keep_fqdn_hostnames t --mca btl ^openib python /tensorflow/benchmarks/scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py --model=vgg16 --batch_size=64 --variable_update=horovod"
  3. 2 つのトレーニングジョブのパフォーマンスを比較します。

    1. 次のコマンドを実行して、2 つのトレーニングジョブの実行時間を比較します。

      arena list -n demo-ns

      期待される出力:

      NAME                             STATUS     TRAINER  DURATION  GPU(Requested)  GPU(Allocated)  NODE
      tensorflow-topo-4-vgg16          SUCCEEDED  MPIJOB   44s       4               N/A             192.168.4.XX1
      tensorflow-4-vgg16-image-warned  SUCCEEDED  MPIJOB   2m        4               N/A             192.168.4.XX0
    2. 次のコマンドを実行して、トポロジー対応スケジューリングを有効にしたトレーニングジョブの合計処理速度を表示します。

      arena logs tensorflow-topo-4-vgg16 -n demo-ns

      期待される出力:

      100 images/sec: 251.7 +/- 0.1 (jitter = 1.2)  7.262
      ----------------------------------------------------------------
      total images/sec: 1006.44
    3. 次のコマンドを実行して、トポロジー対応スケジューリングなしのトレーニングジョブの合計処理速度を表示します。

      arena logs tensorflow-4-vgg16-image-warned -n demo-ns

      期待される出力:

      100 images/sec: 56.4 +/- 0.2 (jitter = 1.5)  7.261
      ----------------------------------------------------------------
      total images/sec: 225.50

上記出力は、以下のパフォーマンス比較を示しています。

トレーニングジョブ

GPU スループット (イメージ/秒)

合計スループット (イメージ/秒)

持続時間 (秒)

トポロジー対応スケジューリングあり

251.7

1006.44

44

トポロジー対応スケジューリングなし

56.4

225.50

120

ノードで GPU トポロジー対応スケジューリングを有効にすると、そのノードでは通常の GPU リソーススケジューリングはサポートされなくなります。通常の GPU スケジューリングを復元するには、次のコマンドを実行してノードラベルを変更します。

kubectl label node cn-beijing.192.168.XX.XX0 ack.node.gpu.schedule=default --overwrite

ステップ 5:モデル管理

  1. AI 開発者コンソールにアクセスします
  2. AI 開発者コンソールの左側のナビゲーションウィンドウで、[Model Manage] をクリックします。
  3. [Model Management] ページで、[Create Model] をクリックします。

  4. 作成する ダイアログボックスで、Model Name[モデルバージョン]、および関連付けられた [トレーニングジョブ] を設定します。

    この例では、モデル名は fashion-mnist-demo、モデルバージョンは v1、選択されたトレーニングジョブは tf-single です。

  5. OKをクリックします。新しいモデルが表示されます。

    创建模型

    新しいモデルを評価するには、対応するモデルの [New Model Evaluation] をクリックします。

ステップ 6:モデル評価

クラウドネイティブ AI スイートは、Arena と AI 開発者コンソールを介したモデル評価ジョブの送信をサポートしています。この例では、Fashion-MNIST トレーニングジョブ中に保存されたチェックポイントを評価するプロセスを示します。

  1. Arena を使用してチェックポイント作成を有効にしたトレーニングジョブを送信します。

  2. Arena を使用して評価ジョブを送信します。

  3. AI 開発者コンソールで異なる評価の結果を比較します。

  1. チェックポイント作成を有効にしたトレーニングジョブを送信します。

    次のコマンドを実行して、fashion-demo-pvc PVC にチェックポイントを保存するトレーニングジョブを送信します。

    arena \
      submit \
      tfjob \
      -n demo-ns \ # 必要に応じて名前空間を設定できます。
      --name=fashion-mnist-arena-ckpt \
      --data=fashion-demo-pvc:/root/data/ \
      --env=DATASET_PATH=/root/data/ \
      --env=MODEL_PATH=/root/data/saved_model \
      --env=MODEL_VERSION=1 \
      --env=GIT_SYNC_USERNAME=${GIT_USERNAME} \ # Git のユーザー名を入力します。
      --env=GIT_SYNC_PASSWORD=${GIT_PASSWORD} \ # Git のパスワードを入力します。
      --env=OUTPUT_CHECKPOINT=1 \
      --sync-mode=git \
      --sync-source=https://codeup.aliyun.com/60b4cf5c66bba1c04b442e49/tensorflow-fashion-mnist-sample.git \
      --image="tensorflow/tensorflow:2.2.2-gpu" \
      "python /root/code/tensorflow-fashion-mnist-sample/train.py --log_dir=/training_logs"
  2. 評価ジョブを送信します。

    1. 評価イメージをビルドします。

      モデル評価コードを取得します。kubeai-sdk ディレクトリで、次のコマンドを実行してイメージをビルドし、プッシュします。

      docker build . -t ${DOCKER_REGISTRY}:fashion-mnist
      docker push ${DOCKER_REGISTRY}:fashion-mnist
    2. 次のコマンドを実行して、クラウドネイティブ AI スイートによってデプロイされた MySQL サービスに関する情報を取得します。

      kubectl get svc -n kube-ai ack-mysql

      期待される出力:

      NAME        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
      ack-mysql   ClusterIP   172.16.XX.XX    <none>        3306/TCP   28h
    3. 次のコマンドを実行して、評価ジョブを送信します。

      arena evaluate model \
       --namespace=demo-ns \
       --loglevel=debug \
       --name=evaluate-job \
       --image=registry.cn-beijing.aliyuncs.com/kube-ai/kubeai-sdk-demo:fashion-minist \
       --env=ENABLE_MYSQL=True \
       --env=MYSQL_HOST=172.16.77.227 \
       --env=MYSQL_PORT=3306 \
       --env=MYSQL_USERNAME=kubeai \
       --env=MYSQL_PASSWORD=kubeai@ACK \
       --data=fashion-demo-pvc:/data \
       --model-name=1 \
       --model-path=/data/saved_model/ \
       --dataset-path=/data/ \
       --metrics-path=/data/output \
       "python /kubeai/evaluate.py"
      説明

      前のステップの出力から MySQL の IP アドレスとポートを取得します。

  3. 評価結果を比較します。

    1. AI 開発者コンソールの左側のナビゲーションウィンドウで、[Model Management] をクリックします。

      模型评测列表

    2. タスク で、評価ジョブの名前をクリックして、そのメトリックを表示します。

      评测任务指标

      複数のジョブを選択して、それらのメトリックを並べて比較することもできます。多任务对比指标

ステップ 7:モデルのデプロイ

モデルを開発・評価した後、アプリケーション用のサービスとしてデプロイできます。このセクションでは、以前にトレーニングしたモデルを TensorFlow Serving サービスとしてデプロイする方法を説明します。Arena は、Triton や Seldon などの他のサービングフレームワークもサポートしています。詳細については、「Arena serve ドキュメント」をご参照ください。

この例では、「ステップ 4:モデルのトレーニング」でトレーニングしたモデルを使用します。モデルは、「ステップ 2:データセットの作成」で作成した PVC (fashion-demo-pvc) に保存されています。モデルが異なるタイプのストレージに保存されている場合は、まずクラスターに対応する PVC を作成する必要があります。

  1. 次のコマンドを実行して、Arena を使用して TensorFlow モデルを TensorFlow Serving にデプロイします。

    arena serve tensorflow \
      --loglevel=debug \
      --namespace=demo-ns \
      --name=fashion-mnist \
      --model-name=1  \
      --gpus=1  \
      --image=tensorflow/serving:1.15.0-gpu \
      --data=fashion-demo-pvc:/data \
      --model-path=/data/saved_model/ \
      --version-policy=latest
  2. 次のコマンドを実行して、デプロイされた推論サービスの名前を取得します。

    arena serve list -n demo-ns

    期待される出力:

    NAME           TYPE        VERSION       DESIRED  AVAILABLE  ADDRESS         PORTS                   GPU
    fashion-mnist  Tensorflow  202111031203  1        1          172.16.XX.XX    GRPC:8500,RESTFUL:8501  1

    クラスター内から呼び出しを行うには、出力の ADDRESS と PORTS を使用します。

  3. Jupyter で、TensorFlow Serving HTTP サービスにリクエストを送信するためのノートブックを作成します。

    この例では、「ステップ 3:モデル開発」で作成した Jupyter Notebook を使用してリクエストを送信します。

    • 初期化コードで、server_ip を前のステップの ADDRESS (172.16.XX.XX) に設定します。

    • 初期化コードで、server_http_port を前のステップの RESTFUL ポート (8501) に設定します。

    ノートブックの初期化コードは以下の通りです。

    import os
    import gzip
    import numpy as np
    # import matplotlib.pyplot as plt
    import random
    import requests
    import json
    
    server_ip = "172.16.XX.XX"
    server_http_port = 8501
    
    dataset_dir = "/root/data/"
    
    def load_data():
            files = [
                'train-labels-idx1-ubyte.gz',
                'train-images-idx3-ubyte.gz',
                't10k-labels-idx1-ubyte.gz',
                't10k-images-idx3-ubyte.gz'
            ]
    
            paths = []
            for fname in files:
                paths.append(os.path.join(dataset_dir, fname))
    
            with gzip.open(paths[0], 'rb') as labelpath:
                y_train = np.frombuffer(labelpath.read(), np.uint8, offset=8)
            with gzip.open(paths[1], 'rb') as imgpath:
                x_train = np.frombuffer(imgpath.read(), np.uint8, offset=16).reshape(len(y_train), 28, 28)
            with gzip.open(paths[2], 'rb') as labelpath:
                y_test = np.frombuffer(labelpath.read(), np.uint8, offset=8)
            with gzip.open(paths[3], 'rb') as imgpath:
                x_test = np.frombuffer(imgpath.read(), np.uint8, offset=16).reshape(len(y_test), 28, 28)
    
    
            return (x_train, y_train),(x_test, y_test)
    
    def show(idx, title):
      plt.figure()
      plt.imshow(test_images[idx].reshape(28,28))
      plt.axis('off')
      plt.title('\n\n{}'.format(title), fontdict={'size': 16})
    
    class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
                   'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
    
    (train_images, train_labels), (test_images, test_labels) = load_data()
    train_images = train_images / 255.0
    test_images = test_images / 255.0
    
    # reshape for feeding into the model
    train_images = train_images.reshape(train_images.shape[0], 28, 28, 1)
    test_images = test_images.reshape(test_images.shape[0], 28, 28, 1)
    
    print('\ntrain_images.shape: {}, of {}'.format(train_images.shape, train_images.dtype))
    print('test_images.shape: {}, of {}'.format(test_images.shape, test_images.dtype))
    
    rando = random.randint(0,len(test_images)-1)
    #show(rando, 'An Example Image: {}'.format(class_names[test_labels[rando]]))
    
    # !pip install -q requests
    
    # import requests
    # headers = {"content-type": "application/json"}
    # json_response = requests.post('http://localhost:8501/v1/models/fashion_model:predict', data=data, headers=headers)
    # predictions = json.loads(json_response.text)['predictions']
    
    # show(0, 'The model thought this was a {} (class {}), and it was actually a {} (class {})'.format(
    #   class_names[np.argmax(predictions[0])], np.argmax(predictions[0]), class_names[test_labels[0]], test_labels[0]))
    
    
    def request_model(data):
        headers = {"content-type": "application/json"}
        json_response = requests.post('http://{}:{}/v1/models/1:predict'.format(server_ip, server_http_port), data=data, headers=headers)
        print('=======response:', json_response, json_response.text)
        predictions = json.loads(json_response.text)['predictions']
    
        print('The model thought this was a {} (class {}), and it was actually a {} (class {})'.format(class_names[np.argmax(predictions[0])], np.argmax(predictions[0]), class_names[test_labels[0]], test_labels[0]))
        #show(0, 'The model thought this was a {} (class {}), and it was actually a {} (class {})'.format(
        #  class_names[np.argmax(predictions[0])], np.argmax(predictions[0]), class_names[test_labels[0]], test_labels[0]))
    
    # def request_model_version(data):
    #     headers = {"content-type": "application/json"}
    #     json_response = requests.post('http://{}:{}/v1/models/1/version/1:predict'.format(server_ip, server_http_port), data=data, headers=headers)
    #     print('=======response:', json_response, json_response.text)
    
    #     predictions = json.loads(json_response.text)
    #     for i in range(0,3):
    #       show(i, 'The model thought this was a {} (class {}), and it was actually a {} (class {})'.format(
    #         class_names[np.argmax(predictions[i])], np.argmax(predictions[i]), class_names[test_labels[i]], test_labels[i]))
    
    data = json.dumps({"signature_name": "serving_default", "instances": test_images[0:3].tolist()})
    print('Data: {} ... {}'.format(data[:50], data[len(data)-52:]))
    #request_model_version(data)
    request_model(data)

    Jupyter Notebook で 执行图标 アイコンをクリックしてセルを実行します。次の出力が表示されます。

    train_images.shape: (60000, 28, 28, 1), of float64
    test_images.shape: (10000, 28, 28, 1), of float64
    Data: {"signature_name": "serving_default", "instances": ...  [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0]]]]}
    =======response: <Response [200]> {
        "predictions": [[7.42696e-07, 6.91237556e-09, 2.66364452e-07, 2.27735413e-07, 4.0373439e-07, 0.00490919966, 7.27086217e-06, 0.0316713452, 0.0010733594, 0.962337255], [0.00685342, 1.8516447e-08, 0.9266119, 2.42278338e-06, 0.0603800081, 4.01338771e-12, 0.00613868702, 4.26091073e-15, 1.35764185e-05, 3.38685469e-10], [1.09047969e-05, 0.999816835, 7.98738e-09, 0.000122893631, 4.85748023e-05, 1.50353979e-10, 3.57102294e-07, 1.89657579e-09, 4.4604468e-07, 9.23274524e-09]
        ]
    }
    The model thought this was a Ankle boot (class 9), and it was actually a Ankle boot (class 9)

よくある質問

  • Jupyter Notebook コンソールにソフトウェアをインストールするにはどうすればよいですか?

    Jupyter Notebook コンソールで次のコマンドを実行します。

    apt-get install <software-name>
  • Jupyter Notebook コンソールでの文字化けを解決するにはどうすればよいですか?

    /etc/locale ファイルを以下の内容で更新し、ターミナルを再起動します。

    LC_CTYPE="da_DK.UTF-8"
    LC_NUMERIC="da_DK.UTF-8"
    LC_TIME="da_DK.UTF-8"
    LC_COLLATE="da_DK.UTF-8"
    LC_MONETARY="da_DK.UTF-8"
    LC_MESSAGES="da_DK.UTF-8"
    LC_PAPER="da_DK.UTF-8"
    LC_NAME="da_DK.UTF-8"
    LC_ADDRESS="da_DK.UTF-8"
    LC_TELEPHONE="da_DK.UTF-8"
    LC_MEASUREMENT="da_DK.UTF-8"
    LC_IDENTIFICATION="da_DK.UTF-8"
    LC_ALL=