はじめに

インストール

推奨する Python 環境は、使用しているプラットフォームによって異なります:

ステップ 1: Python 環境 (Windows x86-64、macOS、Linux)

Python のバージョンと環境を管理するために Miniconda の使用を推奨します。マシンに miniconda をインストールしてください。

Windows: インストールが完了したら、スタートメニューからAnaconda Promptを開きます。
macOS/Linux: インストールが完了したら、新しいシェルウィンドウを開きます

Qualcomm® AI Hub Workbench の環境を設定します:

conda create python=3.10 -n qai_hub
conda activate qai_hub
ステップ 1: Python 環境 (Windows on ARM)

Miniconda は Windows on ARM(例: Snapdragon X Elite)をネイティブにサポートしていません。代わりに、Python download page 用の Windows ARM64 Python を直接ダウンロードすることを推奨します。この場合、Python 3.11 以上が必要です。

Qualcomm® AI Hub 用の環境をセットアップ:

python -m venv qai_hub
.\qai_hub\Scripts\activate

警告

これらの手順のいずれかで SSL: CERTIFICATE_VERIFY_FAILED または self-signed certificate エラーが発生した場合、SSL インターセプションやトラフィック検査ツールがインストールされている可能性があります。IT 部門に PEM 形式(通常は .pem または .crt ファイル)の内部信頼証明書バンドルを依頼してください。その後、Python の pip および Python Requests ライブラリを環境作成前にこの証明書で設定します:

  • Miniconda: conda config --set ssl_verify <path to certificate>

  • Python を直接使用する場合: 環境変数 REQUESTS_CA_BUNDLE を証明書のパスに設定してください。

Step 2: Install Python client
pip3 install qai-hub
ステップ3: サインイン

Qualcomm® AI Hub Workbench にアクセスし、Qualcomm IDでサインインして作成したジョブに関する情報を表示します。

サインインしたら、Account -> Settings -> API Token に移動します。これにより、クライアントを設定するために使用できるAPIトークンが提供されます。

ステップ 4、オプション A(推奨): Persistent APIトークンの構成

API トークンをワークステーションに永続化してクライアントを構成します。この操作は一度だけ行えば十分です。これは Qualcomm® AI Hub Workbench を使用する推奨方法です。

ターミナルで次のコマンドを実行してください:

qai-hub configure --api_token INSERT_API_TOKEN

API トークンが正しくインストールされているかどうかは、利用可能なデバイスの一覧を取得することで確認できます。そのためには、Python ターミナルで次のように入力してください:

import qai_hub as hub
client = hub.Client()
client.get_devices()

この方法を選択した場合、以下のオプション B を実行する必要はありません。

ステップ 4、オプション B(一時的な環境向け): セッション API トークンの構成

Amazon SageMaker のような一時的な顧客環境では、API トークンをディスクに永続的に保存できないため、AI Hub Workbench クライアントを使用するたびに構成する必要があります。

Qualcomm® AI Hub Workbench クライアントをインポートした後に、API トークンを提供してください。例:

import qai_hub as hub
client_config = hub.ClientConfig(api_token="INSERT_API_TOKEN")
client = hub.Client(client_config)

API トークンが正しく機能しているかどうかは、利用可能なデバイスの一覧を取得することで確認できます。クライアントを初期化した後、次のコードを Python スクリプトに追加してください:

client.get_devices()

このトークン構成方法を使用してセッションを初期化するたびに、API トークンを提供する必要があります。

これで Qualcomm® AI Hub Workbench でジョブを送信する準備が整いました。問題が発生した場合は、 お問い合わせ ください。以下の例を試して、希望するデバイスでプロファイルジョブを実行してみてください。

簡単な例(PyTorch)

Qualcomm® AI Hub Workbench 環境を設定したら、次のステップはプロファイリングジョブを送信することです。まず、この例の依存関係をインストールします:

pip3 install "qai-hub[torch]"

警告

スニペットがAPI認証エラーで失敗する場合、有効なAPIトークンがインストールされていないことを意味します。設定方法については、インストール を参照してください。

選択したデバイスタイプでMobileNet v2ネットワークの分析を送信します。上記のリストから任意のデバイスを使用して、以下のオプションとは異なるデバイスを指定できます。

モバイル

import numpy as np
import requests
import torch
from PIL import Image
from torchvision.models import mobilenet_v2

import qai_hub as hub

client = hub.Client()

# Using pre-trained MobileNet
torch_model = mobilenet_v2(pretrained=True)
torch_model.eval()

# Step 1: Trace model
input_shape = (1, 3, 224, 224)
example_input = torch.rand(input_shape)
traced_torch_model = torch.jit.trace(torch_model, example_input)

# Step 2: Compile model
compile_job = client.submit_compile_job(
    model=traced_torch_model,
    device=hub.Device("Samsung Galaxy S24 (Family)"),
    input_specs=dict(image=input_shape),
    options="--target_runtime tflite",
)
assert isinstance(compile_job, hub.CompileJob)

# Step 3: Profile on cloud-hosted device
target_model = compile_job.get_target_model()
assert isinstance(target_model, hub.Model)
profile_job = client.submit_profile_job(
    model=target_model,
    device=hub.Device("Samsung Galaxy S24 (Family)"),
)
assert isinstance(profile_job, hub.ProfileJob)


# Step 4: Run inference on cloud-hosted device
sample_image_url = (
    "https://qaihub-public-assets.s3.us-west-2.amazonaws.com/apidoc/input_image1.jpg"
)
response = requests.get(sample_image_url, stream=True)
response.raw.decode_content = True
image = Image.open(response.raw).resize((224, 224))
input_array = np.expand_dims(
    np.transpose(np.array(image, dtype=np.float32) / 255.0, (2, 0, 1)), axis=0
)

# Run inference using the on-device model on the input image
inference_job = client.submit_inference_job(
    model=target_model,
    device=hub.Device("Samsung Galaxy S24 (Family)"),
    inputs=dict(image=[input_array]),
)
assert isinstance(inference_job, hub.InferenceJob)

on_device_output = inference_job.download_output_data()
assert isinstance(on_device_output, dict)

# Step 5: Post-processing the on-device output
output_name = list(on_device_output.keys())[0]
out = on_device_output[output_name][0]
on_device_probabilities = np.exp(out) / np.sum(np.exp(out), axis=1)

# Read the class labels for imagenet
sample_classes = "https://qaihub-public-assets.s3.us-west-2.amazonaws.com/apidoc/imagenet_classes.txt"
response = requests.get(sample_classes, stream=True)
response.raw.decode_content = True
categories = [str(s.strip()) for s in response.raw]

# Print top five predictions for the on-device model
print("Top-5 On-Device predictions:")
top5_classes = np.argsort(on_device_probabilities[0], axis=0)[-5:]
for c in reversed(top5_classes):
    print(f"{c} {categories[c]:20s} {on_device_probabilities[0][c]:>6.1%}")

# Step 6: Download model
target_model = compile_job.get_target_model()
assert isinstance(target_model, hub.Model)
target_model.download("mobilenet_v2.tflite")

IOT

import numpy as np
import requests
import torch
from PIL import Image
from torchvision.models import mobilenet_v2

import qai_hub as hub

client = hub.Client()

# Using pre-trained MobileNet
torch_model = mobilenet_v2(pretrained=True)
torch_model.eval()

# Step 1: Trace model
input_shape = (1, 3, 224, 224)
example_input = torch.rand(input_shape)
traced_torch_model = torch.jit.trace(torch_model, example_input)

# Step 2: Compile model
compile_job = client.submit_compile_job(
    model=traced_torch_model,
    device=hub.Device("RB3 Gen 2 (Proxy)"),
    input_specs=dict(image=input_shape),
    options="--target_runtime tflite",
)
assert isinstance(compile_job, hub.CompileJob)


# Step 3: Profile on cloud-hosted device
target_model = compile_job.get_target_model()
assert isinstance(target_model, hub.Model)
profile_job = client.submit_profile_job(
    model=target_model,
    device=hub.Device("RB3 Gen 2 (Proxy)"),
)
assert isinstance(profile_job, hub.ProfileJob)


# Step 4: Run inference on cloud-hosted device
sample_image_url = (
    "https://qaihub-public-assets.s3.us-west-2.amazonaws.com/apidoc/input_image1.jpg"
)
response = requests.get(sample_image_url, stream=True)
response.raw.decode_content = True
image = Image.open(response.raw).resize((224, 224))
input_array = np.expand_dims(
    np.transpose(np.array(image, dtype=np.float32) / 255.0, (2, 0, 1)), axis=0
)

# Run inference using the on-device model on the input image
inference_job = client.submit_inference_job(
    model=target_model,
    device=hub.Device("RB3 Gen 2 (Proxy)"),
    inputs=dict(image=[input_array]),
)
assert isinstance(inference_job, hub.InferenceJob)

on_device_output = inference_job.download_output_data()
assert isinstance(on_device_output, dict)

# Step 5: Post-processing the on-device output
output_name = list(on_device_output.keys())[0]
out = on_device_output[output_name][0]
on_device_probabilities = np.exp(out) / np.sum(np.exp(out), axis=1)

# Read the class labels for imagenet
sample_classes = "https://qaihub-public-assets.s3.us-west-2.amazonaws.com/apidoc/imagenet_classes.txt"
response = requests.get(sample_classes, stream=True)
response.raw.decode_content = True
categories = [str(s.strip()) for s in response.raw]

# Print top five predictions for the on-device model
print("Top-5 On-Device predictions:")
top5_classes = np.argsort(on_device_probabilities[0], axis=0)[-5:]
for c in reversed(top5_classes):
    print(f"{c} {categories[c]:20s} {on_device_probabilities[0][c]:>6.1%}")

# Step 6: Download model
target_model = compile_job.get_target_model()
assert isinstance(target_model, hub.Model)
target_model.download("mobilenet_v2.tflite")

コンピュート

import numpy as np
import requests
import torch
from PIL import Image
from torchvision.models import mobilenet_v2

import qai_hub as hub

client = hub.Client()

# Using pre-trained MobileNet
torch_model = mobilenet_v2(pretrained=True)
torch_model.eval()

# Step 1: Trace model
input_shape = (1, 3, 224, 224)
example_input = torch.rand(input_shape)
traced_torch_model = torch.jit.trace(torch_model, example_input)

# Step 2: Compile model
compile_job = client.submit_compile_job(
    model=traced_torch_model,
    device=hub.Device("Snapdragon X Elite CRD"),
    input_specs=dict(image=input_shape),
    options="--target_runtime onnx",
)
assert isinstance(compile_job, hub.CompileJob)

# Step 3: Profile on cloud-hosted device
target_model = compile_job.get_target_model()
assert isinstance(target_model, hub.Model)
profile_job = client.submit_profile_job(
    model=target_model,
    device=hub.Device("Snapdragon X Elite CRD"),
)
assert isinstance(profile_job, hub.ProfileJob)


# Step 4: Run inference on cloud-hosted device
sample_image_url = (
    "https://qaihub-public-assets.s3.us-west-2.amazonaws.com/apidoc/input_image1.jpg"
)
response = requests.get(sample_image_url, stream=True)
response.raw.decode_content = True
image = Image.open(response.raw).resize((224, 224))
input_array = np.expand_dims(
    np.transpose(np.array(image, dtype=np.float32) / 255.0, (2, 0, 1)), axis=0
)

# Run inference using the on-device model on the input image
inference_job = client.submit_inference_job(
    model=target_model,
    device=hub.Device("Snapdragon X Elite CRD"),
    inputs=dict(image=[input_array]),
)
assert isinstance(inference_job, hub.InferenceJob)

on_device_output = inference_job.download_output_data()
assert isinstance(on_device_output, dict)

# Step 5: Post-processing the on-device output
output_name = list(on_device_output.keys())[0]
out = on_device_output[output_name][0]
on_device_probabilities = np.exp(out) / np.sum(np.exp(out), axis=1)

# Read the class labels for imagenet
sample_classes = "https://qaihub-public-assets.s3.us-west-2.amazonaws.com/apidoc/imagenet_classes.txt"
response = requests.get(sample_classes, stream=True)
response.raw.decode_content = True
categories = [str(s.strip()) for s in response.raw]

# Print top five predictions for the on-device model
print("Top-5 On-Device predictions:")
top5_classes = np.argsort(on_device_probabilities[0], axis=0)[-5:]
for c in reversed(top5_classes):
    print(f"{c} {categories[c]:20s} {on_device_probabilities[0][c]:>6.1%}")

# Step 6: Download model
target_model = compile_job.get_target_model()
assert isinstance(target_model, hub.Model)
target_model.download("mobilenet_v2.onnx")

自動車

import numpy as np
import requests
import torch
from PIL import Image
from torchvision.models import mobilenet_v2

import qai_hub as hub

client = hub.Client()

# Using pre-trained MobileNet
torch_model = mobilenet_v2(pretrained=True)
torch_model.eval()

# Step 1: Trace model
input_shape = (1, 3, 224, 224)
example_input = torch.rand(input_shape)
traced_torch_model = torch.jit.trace(torch_model, example_input)

# Step 2: Compile model
compile_job = client.submit_compile_job(
    model=traced_torch_model,
    device=hub.Device("SA8650 (Proxy)"),
    input_specs=dict(image=input_shape),
    options="--target_runtime qnn_dlc",
)
assert isinstance(compile_job, hub.CompileJob)

# Step 3: Profile on cloud-hosted device
target_model = compile_job.get_target_model()
assert isinstance(target_model, hub.Model)
profile_job = client.submit_profile_job(
    model=target_model,
    device=hub.Device("SA8650 (Proxy)"),
)
assert isinstance(profile_job, hub.ProfileJob)

# Step 4: Run inference on cloud-hosted device
sample_image_url = (
    "https://qaihub-public-assets.s3.us-west-2.amazonaws.com/apidoc/input_image1.jpg"
)
response = requests.get(sample_image_url, stream=True)
response.raw.decode_content = True
image = Image.open(response.raw).resize((224, 224))
input_array = np.expand_dims(
    np.transpose(np.array(image, dtype=np.float32) / 255.0, (2, 0, 1)), axis=0
)

# Run inference using the on-device model on the input image
inference_job = client.submit_inference_job(
    model=target_model,
    device=hub.Device("SA8650 (Proxy)"),
    inputs=dict(image=[input_array]),
)
assert isinstance(inference_job, hub.InferenceJob)

on_device_output = inference_job.download_output_data()
assert isinstance(on_device_output, dict)

# Step 5: Post-processing the on-device output
output_name = list(on_device_output.keys())[0]
out = on_device_output[output_name][0]
on_device_probabilities = np.exp(out) / np.sum(np.exp(out), axis=1)

# Read the class labels for imagenet
sample_classes = "https://qaihub-public-assets.s3.us-west-2.amazonaws.com/apidoc/imagenet_classes.txt"
response = requests.get(sample_classes, stream=True)
response.raw.decode_content = True
categories = [str(s.strip()) for s in response.raw]

# Print top five predictions for the on-device model
print("Top-5 On-Device predictions:")
top5_classes = np.argsort(on_device_probabilities[0], axis=0)[-5:]
for c in reversed(top5_classes):
    print(f"{c} {categories[c]:20s} {on_device_probabilities[0][c]:>6.1%}")

# Step 6: Download model
target_model = compile_job.get_target_model()
assert isinstance(target_model, hub.Model)
target_model.download("mobilenet_v2.so")

これにより、コンパイルジョブとプロファイルジョブが送信され、両方のジョブのURLが表示されます。最後に、コードはサンプルデータで推論ジョブを実行します。すべてのジョブは /jobs/ で表示できます。

ジョブのステータスはプログラムで照会できます:

status = profile_job.get_status()
print(status)

以下のスニペットを使用してジョブの結果にアクセスできます。主に3つの部分があります

  • プロファイル: JSON形式のプロファイリング結果。

  • ターゲットモデル: デプロイメントの準備が整った最適化済みモデル。

  • 結果: ジョブのすべてのアーティファクト(ログを含む)を含むフォルダー。

これらはジョブが終了するまで待機するブロッキングAPI呼び出しであることに注意してください:

  • プロファイル結果を JSON 形式でダウンロード(ブロッキング呼び出し)

profile = profile_job.download_profile()
print(profile)
  • 最適化されたモデルをダウンロード(ブロッキング呼び出し)

compile_job.model.download("model_filename")
  • 結果を現在のディレクトリにダウンロード(ブロッキング呼び出し)

profile_job.download_results(".")

詳細については、モデルのプロファイリング または API documentation を参照してください。