モデルのプロファイリング

デバイス上でニューラルネットワークモデルをデプロイする際には、多くの重要な質問が生じます:

  • ターゲットハードウェア全体での推論レイテンシはどれくらいですか?

  • モデルは特定のメモリ予算内に収まりますか?

  • モデルはニューラルプロセッシングユニットを活用できますか?

プロファイルジョブは、クラウド上の物理デバイスでモデルを実行し、パフォーマンスを分析することで、これらの質問に答えます。

プロファイルジョブでも、--qairt_version オプションを使用して特定の Qualcomm® AI Runtime バージョンを指定できます。指定しない場合は、バージョン選択 に従ってバージョンが選択されます。

事前コンパイルされたモデルのプロファイリング

Qualcomm® AI Hub Workbench supports profiling a previously compiled model. In this example, we optimize and profile a model that is previously compiled using a submit_compile_job(). Note how we were able to use the compiled model from compile_job using get_target_model().

import qai_hub as hub

client = hub.Client()

# Profile the previously compiled model
profile_job = client.submit_profile_job(
    model=compile_job.get_target_model(),
    device=hub.Device("Samsung Galaxy S24 (Family)"),
)
assert isinstance(profile_job, hub.ProfileJob)

戻り値は ProfileJob のインスタンスです。すべてのジョブのリストを表示するには、/jobs/ にアクセスしてください。

PyTorch モデルのプロファイリング

この例では、PyTorch が必要です。以下のようにインストールできます。

pip3 install "qai-hub[torch]"

この例では、Qualcomm® AI Hub Workbench を使用して PyTorch モデルを最適化し、プロファイルします。

import torch

import qai_hub as hub

client = hub.Client()


class SimpleNet(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = torch.nn.Linear(5, 2)

    def forward(self, x):
        return self.linear(x)


input_shapes: list[tuple[int, ...]] = [(3, 5)]
torch_model = SimpleNet()

# Trace the model using random inputs
torch_inputs = tuple(torch.randn(shape) for shape in input_shapes)
pt_model = torch.jit.trace(torch_model, torch_inputs)

# Submit compile job
compile_job = client.submit_compile_job(
    model=pt_model,
    device=hub.Device("Samsung Galaxy S23 (Family)"),
    input_specs=dict(x=input_shapes[0]),
)
assert isinstance(compile_job, hub.CompileJob)

# Submit profile job using results form compile job
profile_job = client.submit_profile_job(
    model=compile_job.get_target_model(),
    device=hub.Device("Samsung Galaxy S23 (Family)"),
)
assert isinstance(profile_job, hub.ProfileJob)

For more information on options when uploading, compiling, and submitting a job, see upload_model(), submit_compile_job(), and submit_profile_job().

TorchScript モデルのプロファイリング

既に保存されたトレースまたはスクリプト化されたtorchモデル(torch.jit.save で保存されたもの)がある場合は、それを直接送信できます。例として mobilenet_v2.pt を使用します。前回の例と同様に、TorchScript モデルは適切なターゲットにコンパイルされた後にのみプロファイリングできます。

import qai_hub as hub

client = hub.Client()

# Compile previously saved torchscript model
compile_job = client.submit_compile_job(
    model="mobilenet_v2.pt",
    device=hub.Device("Samsung Galaxy S23 (Family)"),
    input_specs=dict(image=(1, 3, 224, 224)),
)
assert isinstance(compile_job, hub.CompileJob)

profile_job = client.submit_profile_job(
    model=compile_job.get_target_model(),
    device=hub.Device("Samsung Galaxy S23 (Family)"),
)
assert isinstance(profile_job, hub.ProfileJob)

ONNX モデルのプロファイリング

Qualcomm® AI Hub Workbench は ONNX モデルもサポートしています。ONNX モデルは、 TensorFlow Lite などのターゲットにコンパイルするか、 ONNX Runtime を使用して直接プロファイリングできます。両方の方法の例として mobilenet_v2.onnx を使用します。この例では、 TensorFlow Lite ターゲットモデルにコンパイルします。

import qai_hub as hub

client = hub.Client()

compile_job = client.submit_compile_job(
    model="mobilenet_v2.onnx",
    device=hub.Device("Samsung Galaxy S23 (Family)"),
)
assert isinstance(compile_job, hub.CompileJob)

profile_job = client.submit_profile_job(
    model=compile_job.get_target_model(),
    device=hub.Device("Samsung Galaxy S23 (Family)"),
)
assert isinstance(profile_job, hub.ProfileJob)

この例では、ONNX Runtime を使用して ONNX モデルを直接プロファイリングします。

import qai_hub as hub

client = hub.Client()

profile_job = client.submit_profile_job(
    model="mobilenet_v2.onnx",
    device=hub.Device("Samsung Galaxy S23 (Family)"),
)
assert isinstance(profile_job, hub.ProfileJob)

QNNコンテキストバイナリを使用した事前コンパイルされたQNN ONNX モデルも直接プロファイリングできます。この例では、事前コンパイルされたQNN ONNX のコンパイル のコンパイル例を継続して、モデルをプロファイリングします:

import qai_hub as hub

# Profile the previously compiled model
profile_job = hub.submit_profile_job(
    model=compile_job.get_target_model(),
    device=hub.Device("Snapdragon 8 Elite QRD"),
)
assert isinstance(profile_job, hub.ProfileJob)

浮動小数点をサポートしないデバイス上で ONNX モデルをプロファイリングする

一部のデバイスには、浮動小数点(FP32 または FP16)モデルをサポートしない HTP が搭載されています。これらのデバイスで ONNX Runtime を使用して実行する場合、 Qualcomm® AI Hub Workbench は QNN Execution Provider を自動的に有効化しません。この動作により、すべてのモデルは CPU 上で実行されることで成功します。完全に量子化されたモデルを使用している場合、オプション --onnx_execution_providers=qnn を使用して QNN Execution Provider を有効化することで、NPU 上でより良いパフォーマンスを得られる可能性があります。この例では、まずデフォルトオプションを使用して CPU 上で完全に量子化されたモデルを実行し、その後 QNN Execution Provider を有効化して NPU 上でモデルを実行します。両方の方法の例として、 resnet50_w8a8.onnx を使用します。

import qai_hub as hub

client = hub.Client()

# Profile a quantized model with default options - the model will run on the CPU
profile_job = client.submit_profile_job(
    "resnet50_w8a8.onnx",
    device=hub.Device("Dragonwing RB3 Gen 2 Vision Kit"),
)

assert isinstance(profile_job, hub.ProfileJob)

# Profile a quantized model with the QNN Execution Provider
profile_job = client.submit_profile_job(
    "resnet50_w8a8.onnx",
    device=hub.Device("Dragonwing RB3 Gen 2 Vision Kit"),
    options="--onnx_execution_providers=qnn",
)

assert isinstance(profile_job, hub.ProfileJob)

QNN DLCのプロファイリング

Qualcomm® AI Hub Workbench はプロファイリングのためにQNN DLC形式をサポートしています。この例では、 PyTorch モデルをQNN DLCにコンパイル の例を継続してモデルをプロファイルします。

import qai_hub as hub

client = hub.Client()

# Profile the previously compiled model
profile_job = client.submit_profile_job(
    model=compile_job.get_target_model(),
    device=hub.Device("Samsung Galaxy S24 (Family)"),
)
assert isinstance(profile_job, hub.ProfileJob)

QNNコンテキストバイナリのプロファイリング

Qualcomm® AI Hub Workbench はプロファイリングのためにQNNコンテキストバイナリ形式をサポートしています。この例では、 PyTorch モデルをQNNコンテキストバイナリにコンパイル の例を継続してモデルをプロファイリングします:

import qai_hub as hub

client = hub.Client()

# Profile the previously compiled model
profile_job = client.submit_profile_job(
    model=compile_job.get_target_model(),
    device=hub.Device("Samsung Galaxy S24 (Family)"),
)
assert isinstance(profile_job, hub.ProfileJob)

TensorFlow Lite モデルのプロファイリング

Qualcomm® AI Hub Workbench は .tflite 形式のモデルのプロファイリングもサポートしています。 SqueezeNet10 model を使用します。

import qai_hub as hub

client = hub.Client()

# Profile TensorFlow Lite model (from file)
profile_job = client.submit_profile_job(
    model="SqueezeNet10.tflite",
    device=hub.Device("Samsung Galaxy S23 (Family)"),
)

複数のデバイスでモデルのプロファイリング

多くの場合、複数のデバイスでのパフォーマンスをモデル化することが重要です。この例では、最近の Snapdragon® 8 Gen 1 および Snapdragon® 8 Gen 2 デバイスでプロファイリングを行い、十分なテストカバレッジを確保します。TensorFlow Lite の例から SqueezeNet model を再利用しますが、今回は2つのデバイスでプロファイリングします。

import qai_hub as hub

client = hub.Client()

devices = [
    hub.Device("Samsung Galaxy S23 (Family)"),  # Snapdragon 8 Gen 2
    hub.Device("Samsung Galaxy S24 (Family)"),  # Snapdragon 8 Gen 3
]

jobs = client.submit_profile_job(model="SqueezeNet10.tflite", device=devices)

各デバイスごとに別々のプロファイルジョブが作成されます。

プロファイリングのためのモデルのアップロード

プロファイルジョブを送信せずにモデル(例:SqueezeNet10.tflite)をアップロードすることが可能です

import qai_hub as hub

client = hub.Client()
hub_model = client.upload_model("SqueezeNet10.tflite")
print(hub_model)

アップロードされたモデルの model_id を使用してプロファイリングジョブを実行できます。:

import qai_hub as hub

client = hub.Client()

# Retrieve model using ID
hub_model = client.get_model("mabc123")

# Submit job
profile_job = client.submit_profile_job(
            model=hub_model,
            device=hub.Device("Samsung Galaxy S23 (Family)"),
)

事前にアップロードされたモデルのプロファイリング

前回のジョブからモデルを再利用して新しいプロファイルジョブを開始できます(例:異なるデバイスで)。これにより、同じモデルを複数回アップロードする必要がなくなります。:

import qai_hub as hub

client = hub.Client()

# Get the model from the profile job
profile_job = client.get_job("jabc123")
hub_model = profile_job.model

# Run the model from the job
new_profile_job = client.submit_profile_job(
    model=hub_model,
    device=hub.Device("Samsung Galaxy S22 Ultra 5G"),
)