推論の実行
特殊なハードウェアを備えたモバイルおよびエッジデバイスでモデルを実行することは、参照環境での実行とは異なる場合があります。たとえば、PyTorch 実装がfloat32精度で推論を実行する一方で、ターゲットハードウェアはfloat16またはint8を使用して計算を行う場合があります。これにより、数値の不一致やアンダーフローおよびオーバーフローの可能性が生じることがあります。これが結果に悪影響を与えるかどうかは、モデルとデータの分布に依存します。
Inference jobs provide you with a way to upload input data, run inference on
real hardware, and download the output results. By comparing these results
directly to your reference implementation, you can determine whether or not
the optimized model works as expected. Inference is only supported for optimized
models: models in source formats such as PyTorch and ONNX must be compiled
with submit_compile_job() or similar.
推論ジョブでは、--qairt_version オプションを使用して特定の Qualcomm® AI Runtime バージョンを指定できます。指定しない場合は、バージョン選択 に従ってバージョンが選択されます。
TensorFlow Lite モデルでの推論の実行
この例では、TensorFlow Lite モデル SqueezeNet10.tflite を使用して推論を実行します。
import numpy as np
import qai_hub as hub
client = hub.Client()
sample = np.random.random((1, 224, 224, 3)).astype(np.float32)
inference_job = client.submit_inference_job(
model="SqueezeNet10.tflite",
device=hub.Device("Samsung Galaxy S23 (Family)"),
inputs=dict(x=[sample]),
)
assert isinstance(inference_job, hub.InferenceJob)
inference_job.download_output_data()
推論の入力はディクショナリでなければならず、キーは特徴の名前、値はテンソルです。テンソルはnumpy配列のリスト、または単一のデータポイントの場合は単一のnumpy配列であることができます。
inference_jobはInferenceJobのインスタンスです。
Multiple inference jobs can be launched at the same time by providing a list of
Device objects to the
submit_inference_job() API.
Running Inference with QNN DLC and Context Binaries
This example compiles a TorchScript model (mobilenet_v2.pt) to QNN DLC or QNN context binary format. Then inference is run on device with the compiled target model.
import numpy as np
import qai_hub as hub
client = hub.Client()
sample = np.random.random((1, 3, 224, 224)).astype(np.float32)
compile_job = client.submit_compile_job(
model="mobilenet_v2.pt",
device=hub.Device("Samsung Galaxy S23 (Family)"),
options="--target_runtime qnn_dlc",
input_specs=dict(image=(1, 3, 224, 224)),
)
assert isinstance(compile_job, hub.CompileJob)
inference_job = client.submit_inference_job(
model=compile_job.get_target_model(),
device=hub.Device("Samsung Galaxy S23 (Family)"),
inputs=dict(image=[sample]),
)
assert isinstance(inference_job, hub.InferenceJob)
import numpy as np
import qai_hub as hub
client = hub.Client()
input_shape = (1, 3, 224, 224)
sample = np.random.random(input_shape).astype(np.float32)
compile_job = client.submit_compile_job(
model="mobilenet_v2.pt",
device=hub.Device("Samsung Galaxy S24 (Family)"),
options="--target_runtime qnn_context_binary",
input_specs=dict(image=input_shape),
)
assert isinstance(compile_job, hub.CompileJob)
inference_job = client.submit_inference_job(
model=compile_job.get_target_model(),
device=hub.Device("Samsung Galaxy S24 (Family)"),
inputs=dict(image=[sample]),
)
assert isinstance(inference_job, hub.InferenceJob)
推論ジョブを使用してオンデバイスでモデルの精度を検証する
This example demonstrates how to validate the numerics of a QNN DLC model on-device.
プロファイリングの例 the profiling example (mobilenet_v2.pt) からモデルを再利用します。
import torch
import qai_hub as hub
client = hub.Client()
device_s23 = hub.Device(name="Samsung Galaxy S23 (Family)")
compile_job = client.submit_compile_job(
model="mobilenet_v2.pt",
device=device_s23,
input_specs={"x": (1, 3, 224, 224)},
options="--target_runtime qnn_dlc",
)
assert isinstance(compile_job, hub.CompileJob)
on_device_model = compile_job.get_target_model()
この最適化された .so モデルを使用し、特定のデバイスで入力データを使用して推論を実行できます。この例で使用される入力画像は input_image1.jpg からダウンロードできます。
import numpy as np
from PIL import Image
# Convert the image to numpy array of shape [1, 3, 224, 224]
image = Image.open("input_image1.jpg").resize((224, 224))
img_array = np.array(image, dtype=np.float32)
# Ensure correct layout (NCHW) and re-scale
input_array = np.expand_dims(np.transpose(img_array / 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=on_device_model,
device=device_s23,
inputs=dict(x=[input_array]),
)
assert isinstance(inference_job, hub.InferenceJob)
このオンデバイスのraw出力を使用してクラス予測を生成し、参照実装と比較できます。これにはimagenetクラスが必要です - imagenet_classes.txt。
# Get the on-device output
on_device_output: dict[str, list[np.ndarray]] = inference_job.download_output_data() # type: ignore
# Load the torch model and perform inference
torch_model = torch.jit.load("mobilenet_v2.pt")
torch_model.eval()
# Calculate probabilities for torch model
torch_input = torch.from_numpy(input_array)
torch_output = torch_model(torch_input)
torch_probabilities = torch.nn.functional.softmax(torch_output[0], dim=0)
# Calculate probabilities for 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
with open("imagenet_classes.txt") as f:
categories = [s.strip() for s in f.readlines()]
# 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%}")
# Print top five prediction for torch model
print("Top-5 PyTorch predictions:")
top5_prob, top5_catid = torch.topk(torch_probabilities, 5)
for i in range(top5_prob.size(0)):
print(
f"{top5_catid[i]:4d} {categories[top5_catid[i]]:20s} {top5_prob[i].item():>6.1%}"
)
上記のコードは次のような結果を生成します:
Top-5 On-Device predictions:
968 cup 71.3%
504 coffee mug 16.4%
967 espresso 7.8%
809 soup bowl 1.3%
659 mixing bowl 1.2%
Top-5 PyTorch predictions:
968 cup 71.4%
504 coffee mug 16.1%
967 espresso 8.0%
809 soup bowl 1.4%
659 mixing bowl 1.2%
オンデバイスの結果はリファレンス実装とほぼ同等です。これは、モデルが正確性の低下を経験していないことを示しており、デプロイ後に期待通りに動作することを確認できます。
この信頼を強化するために、これを複数の画像に拡張し、KLダイバージェンスの測定や精度の比較(ラベルが既知の場合)などの定量的な要約を使用することを検討してください。これにより、ターゲットデバイス全体での検証が容易になります。
事前にアップロードされたデータセットとモデルを使用して推論を実行する
Analogous to models, Qualcomm® AI Hub Workbench exposes an API to enable users to upload data that can be reused.
import numpy as np
import qai_hub as hub
client = hub.Client()
data = dict(
x=[
np.random.random((1, 224, 224, 3)).astype(np.float32),
np.random.random((1, 224, 224, 3)).astype(np.float32),
]
)
hub_dataset = client.upload_dataset(data)
アップロードされたデータセットを使用して推論ジョブを実行できます。この例では SqueezeNet10.tflite を使用します。
# Submit job
job = client.submit_inference_job(
model="SqueezeNet10.tflite",
device=hub.Device("Samsung Galaxy S23 (Family)"),
inputs=hub_dataset,
)