MCP HubMCP Hub
스킬 목록으로 돌아가기

deploy-edge-ai-model

pjt222
업데이트됨 Yesterday
1 조회
17
2
17
GitHub에서 보기
개발aiapi

정보

이 스킬은 Google AI Edge Gallery, TensorFlow Lite, ONNX Runtime과 같은 도구를 사용하여 모바일 폰 및 IoT 시스템과 같은 엣지 디바이스에 머신러닝 모델을 배포하는 데 도움을 줍니다. 모델 양자화, 하드웨어 델리게이트 선택, Gemma 모델을 활용한 온디바이스 추론과 같은 핵심 기술을 다룹니다. 지연 시간, 비용 또는 연결성 제약으로 인해 AI 모델을 로컬에서 실행해야 할 때 사용하세요.

빠른 설치

Claude Code

추천
기본
npx skills add pjt222/agent-almanac -a claude-code
플러그인 명령대체
/plugin add https://github.com/pjt222/agent-almanac
Git 클론대체
git clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/deploy-edge-ai-model

Claude Code에서 이 명령을 복사하여 붙여넣어 스킬을 설치하세요

문서

Deploy Edge AI Model

完全な設定ファイル、量子化スクリプト、ベンチマークテンプレートは Extended Examples を参照。

最適化された推論、ハードウェアアクセラレーション、デバイス上モデル管理を伴う ML モデルをエッジデバイスへデプロイする。

使用タイミング

  • Google AI Edge Gallery 経由で LLM(Gemma 4、Phi、Llama)をモバイルデバイスへデプロイするとき
  • デバイス上推論のためにモデルを TensorFlow Lite または ONNX へ変換するとき
  • メモリ削減と高速推論のためにモデルを INT8/INT4 へ量子化するとき
  • ローカル AI 機能を持つ Android/iOS アプリを構築するとき
  • ハードウェアデリゲート(GPU、NPU、DSP、Hexagon、CoreML)を選ぶとき
  • ターゲットデバイスで推論レイテンシとメモリをベンチマークするとき
  • MediaPipe タスク(vision、text、audio)をモバイルまたは組込プラットフォームへデプロイするとき

入力

  • 必須: 訓練済モデル(SavedModel、PyTorch、ONNX、Hugging Face チェックポイント)
  • 必須: ターゲットプラットフォーム(Android、iOS、Linux 組込、ブラウザ)
  • 必須: ターゲットデバイスの制約(RAM、ストレージ、計算能力)
  • 任意: 訓練後量子化のためのキャリブレーションデータセット
  • 任意: LLM デプロイ用の Google AI Edge Gallery 設定
  • 任意: ハードウェアデリゲートの優先順位(GPU、NPU、CPU のみ)

手順

ステップ1: エッジデプロイ用にモデルを評価する

モデルサイズ、レイテンシ要件、ターゲットデバイス能力を評価する。

# assess_model.py
import os
import tensorflow as tf

def assess_model_for_edge(saved_model_path, target_ram_mb=4096):
    """Evaluate whether a model is suitable for edge deployment."""
    model = tf.saved_model.load(saved_model_path)

    # Check model size on disk
    model_size_mb = sum(
        os.path.getsize(os.path.join(dp, f))
        for dp, _, filenames in os.walk(saved_model_path)
        for f in filenames
    ) / (1024 * 1024)

    print(f"Model size: {model_size_mb:.1f} MB")
    print(f"Target RAM: {target_ram_mb} MB")
    print(f"Size/RAM ratio: {model_size_mb / target_ram_mb:.2%}")

    if model_size_mb > target_ram_mb * 0.25:
        print("WARNING: Model exceeds 25% of device RAM - quantization recommended")
        return False
    return True

エッジデプロイ意思決定マトリクス:

Model SizeDevice RAMRecommended Action
< 50 MB2+ GBDirect TFLite conversion
50-500 MB4+ GBINT8 quantization + TFLite
500 MB-2 GB6+ GBINT4 quantization + AI Edge Gallery
2-4 GB8+ GBGemma 4 via AI Edge Gallery with INT4
> 4 GB12+ GBWeight streaming or cloud-edge hybrid

期待結果: モデル評価が完了し、サイズと RAM 比が計算され、デバイス制約に基づく量子化推奨が生成される。

失敗時: SavedModel パスが有効か検証(ls saved_model/)、TensorFlow インストール確認(python -c "import tensorflow")、モデルロードに十分なディスク容量を確保、モデル形式がサポートされているか検証。

ステップ2: Google AI Edge Gallery 経由で LLM をデプロイする

Google AI Edge Gallery を使って Gemma 4 や他の LLM を Android デバイスへデプロイする。

# Clone AI Edge Gallery
git clone https://github.com/nickoala/ai-edge-gallery.git
cd ai-edge-gallery

# Build the Android app
./gradlew assembleDebug

# Install on connected device
adb install -r app/build/outputs/apk/debug/app-debug.apk

AI Edge Gallery 用の Gemma 4 モデルを設定:

{
  "models": [
    {
      "name": "Gemma 4 2B IT",
      "url": "https://huggingface.co/google/gemma-4-2b-it-gpu-int4",
      "format": "tflite",
      "backend": "gpu",
      "config": {
        "max_tokens": 1024,
        "temperature": 0.7,
        "top_k": 40,
        "top_p": 0.95
      }
    },
    {
      "name": "Gemma 4 4B IT",
      "url": "https://huggingface.co/google/gemma-4-4b-it-gpu-int4",
      "format": "tflite",
      "backend": "gpu",
      "config": {
        "max_tokens": 2048,
        "temperature": 0.7
      }
    }
  ]
}

LLM Inference API を使ったプログラム的デバイス上推論:

# gemma_edge_inference.py
from mediapipe.tasks.genai import llm_inference

# Configure the LLM
options = llm_inference.LlmInferenceOptions(
    model_path="/data/local/tmp/gemma-4-2b-it-int4.tflite",
    max_tokens=512,
    temperature=0.7,
    top_k=40,
    supported_lora_ranks=[4, 8, 16]  # Optional LoRA support
)

# Create inference engine
engine = llm_inference.LlmInference(options=options)

# Run inference
response = engine.generate_response("Explain edge computing in one sentence.")
print(response)

# Streaming inference
for chunk in engine.generate_response_async("List three benefits of on-device AI."):
    print(chunk, end="", flush=True)

期待結果: AI Edge Gallery アプリがビルド・インストールに成功し、Gemma 4 モデルがデバイスへダウンロードされ、デバイス上推論が一貫した応答を生成し、GPU デリゲートがアクセラレーションのためアクティブになる。

失敗時: Android SDK バージョン >= 26 を確認(adb shell getprop ro.build.version.sdk)、デバイスにモデルダウンロード用の十分なストレージがあるか検証、GPU デリゲートがサポートされているか確認(adb logcat | grep -i delegate)、Hugging Face モデルアクセス権限を確認、ADB 接続を検証(adb devices)。

ステップ3: TFLite でモデルを変換し量子化する

訓練後量子化を伴う TFLite 形式に標準モデルを変換する。

# convert_tflite.py
import os
import tensorflow as tf
import numpy as np

def convert_to_tflite(saved_model_path, output_path, quantization="dynamic"):
    """Convert SavedModel to TFLite with quantization."""
    converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_path)

    if quantization == "dynamic":
        converter.optimizations = [tf.lite.Optimize.DEFAULT]

    elif quantization == "int8":
        converter.optimizations = [tf.lite.Optimize.DEFAULT]
        converter.target_spec.supported_ops = [
            tf.lite.OpsSet.TFLITE_BUILTINS_INT8
        ]
        converter.inference_input_type = tf.int8
        converter.inference_output_type = tf.int8

        # Representative dataset for calibration
        def representative_dataset():
            for _ in range(100):
                yield [np.random.randn(1, 224, 224, 3).astype(np.float32)]
        converter.representative_dataset = representative_dataset

    elif quantization == "float16":
        converter.optimizations = [tf.lite.Optimize.DEFAULT]
        converter.target_spec.supported_types = [tf.float16]

    tflite_model = converter.convert()

    with open(output_path, "wb") as f:
        f.write(tflite_model)

    original_size = sum(
        os.path.getsize(os.path.join(dp, f))
        for dp, _, filenames in os.walk(saved_model_path)
        for f in filenames
    ) / (1024 * 1024)
    quantized_size = len(tflite_model) / (1024 * 1024)
    print(f"Original: {original_size:.1f} MB -> Quantized: {quantized_size:.1f} MB")
    print(f"Compression ratio: {original_size / quantized_size:.1f}x")

# Usage
convert_to_tflite("saved_model/", "model_int8.tflite", quantization="int8")

ONNX Runtime 量子化の代替:

# quantize_onnx.py
from onnxruntime.quantization import quantize_dynamic, quantize_static, QuantType

# Dynamic quantization (no calibration data needed)
quantize_dynamic(
    model_input="model.onnx",
    model_output="model_int8.onnx",
    weight_type=QuantType.QInt8
)

# Static quantization (better accuracy, needs calibration)
# ... (see EXAMPLES.md for complete calibration workflow)

期待結果: TFLite モデルが指定パスに生成、INT8 でモデルサイズが 2-4 倍縮小、推論精度が原モデルから 1-2% 以内、ONNX 量子化が有効モデルを生成する。

失敗時: 最新の量子化サポートに TensorFlow バージョン >= 2.15 を確認、代表データセットがモデル入力形状と一致するか検証、TFLite ですべての op がサポートされているか確認(フォールバックとして converter.allow_custom_ops = True)、ONNX opset バージョン互換性を確認。

ステップ4: ハードウェアデリゲートを設定する

ターゲットデバイス用のハードウェアアクセラレーションデリゲートを選択・設定する。

# configure_delegates.py
import tensorflow as tf

def create_interpreter_with_delegate(model_path, delegate="gpu"):
    """Create TFLite interpreter with hardware delegate."""

    if delegate == "gpu":
        delegate_obj = tf.lite.experimental.load_delegate(
            "libtensorflowlite_gpu_delegate.so",
            options={"precision": "fp16", "allow_quantized_models": "true"}
        )
    elif delegate == "nnapi":
        # Android Neural Networks API - routes to NPU/DSP
        delegate_obj = tf.lite.experimental.load_delegate(
            "libtensorflowlite_nnapi_delegate.so"
        )
    elif delegate == "xnnpack":
        # Optimized CPU inference
        delegate_obj = None  # XNNPACK is default in TFLite

    interpreter = tf.lite.Interpreter(
        model_path=model_path,
        experimental_delegates=[delegate_obj] if delegate_obj else None,
        num_threads=4
    )
    interpreter.allocate_tensors()
    return interpreter

デリゲート選択ガイド:

DeviceBest DelegateFallbackNotes
Android (Qualcomm)NNAPI -> Hexagon DSPGPU -> XNNPACKCheck nnapi_accelerator_name
Android (MediaTek)NNAPI -> APUGPU -> XNNPACKDimensity chips have dedicated APU
Android (Samsung)NNAPI -> NPUGPU -> XNNPACKExynos NPU via NNAPI
iOSCoreML delegateMetal GPUUse coreml_delegate for ANE
Linux embeddedGPU (if available)XNNPACKRPi uses XNNPACK CPU
BrowserWebGL / WebGPUWASM SIMDVia TensorFlow.js

期待結果: デリゲートがエラーなくロード、推論がターゲットアクセラレータ上で実行、モデルとデバイスに依存し CPU のみより 2-10 倍レイテンシ改善。

失敗時: デバイスにデリゲートライブラリが存在するか検証、デバイスが要求デリゲートをサポートするか確認(CPU 機能は adb shell cat /proc/cpuinfo)、GPU/NPU 不可なら XNNPACK へフォールバック、GPU デリゲートには OpenCL サポートを確認、NNAPI バージョンを検証(adb shell getprop ro.android.ndk.version)。

ステップ5: デバイス上の性能をベンチマークする

ターゲットデバイス上で推論レイテンシ、メモリ使用量、消費電力を計測する。

# Use TFLite benchmark tool
adb push model_int8.tflite /data/local/tmp/

# CPU benchmark
adb shell /data/local/tmp/benchmark_model \
  --graph=/data/local/tmp/model_int8.tflite \
  --num_threads=4 \
  --num_runs=50 \
  --warmup_runs=5

# GPU benchmark
adb shell /data/local/tmp/benchmark_model \
  --graph=/data/local/tmp/model_int8.tflite \
  --use_gpu=true \
  --num_runs=50

# NNAPI benchmark
adb shell /data/local/tmp/benchmark_model \
  --graph=/data/local/tmp/model_int8.tflite \
  --use_nnapi=true \
  --nnapi_accelerator_name=google-edgetpu \
  --num_runs=50

Python ベンチマーキング:

# benchmark_edge.py
import time
import numpy as np
import psutil

def benchmark_inference(interpreter, input_data, num_runs=100):
    """Benchmark TFLite model inference."""
    input_details = interpreter.get_input_details()
    output_details = interpreter.get_output_details()

    # Warmup
    for _ in range(10):
        interpreter.set_tensor(input_details[0]["index"], input_data)
        interpreter.invoke()

    # Benchmark
    latencies = []
    mem_before = psutil.Process().memory_info().rss / (1024 * 1024)
    for _ in range(num_runs):
        start = time.perf_counter()
        interpreter.set_tensor(input_details[0]["index"], input_data)
        interpreter.invoke()
        latencies.append((time.perf_counter() - start) * 1000)
    mem_after = psutil.Process().memory_info().rss / (1024 * 1024)

    print(f"Latency (p50): {np.percentile(latencies, 50):.1f} ms")
    print(f"Latency (p95): {np.percentile(latencies, 95):.1f} ms")
    print(f"Latency (p99): {np.percentile(latencies, 99):.1f} ms")
    print(f"Memory delta: {mem_after - mem_before:.1f} MB")
    print(f"Throughput: {1000 / np.mean(latencies):.1f} inferences/sec")

期待結果: ベンチマークがレイテンシパーセンタイル、メモリ使用量、スループット指標を出力する; vision モデルで GPU デリゲートが CPU より 2-5 倍速度向上を示す; Gemma 4 2B が旗艦スマホで 10-30 トークン/秒を達成する。

失敗時: ベンチマークバイナリがデバイスアーキテクチャ(arm64-v8a)と一致するか確認、モデルがデバイスへ push されたか検証(adb shell ls /data/local/tmp/)、十分なデバイスストレージを確認、メモリ圧を減らすためバックグラウンドアプリを終了、サーマルスロットリングが起きていないか検証(adb shell cat /sys/class/thermal/thermal_zone*/temp)。

ステップ6: 本番デプロイ用にパッケージする

埋め込みまたはダウンロード可能モデルを伴う最終モバイルアプリケーションを構築する。

// Android: EdgeAIManager.kt
import com.google.mediapipe.tasks.genai.llminference.LlmInference

class EdgeAIManager(private val context: Context) {
    private var llmInference: LlmInference? = null

    fun initialize(modelPath: String) {
        val options = LlmInference.LlmInferenceOptions.builder()
            .setModelPath(modelPath)
            .setMaxTokens(512)
            .setTemperature(0.7f)
            .setTopK(40)
            .setResultListener { result, done ->
                // Handle streaming tokens
                onTokenReceived(result, done)
            }
            .build()

        llmInference = LlmInference.createFromOptions(context, options)
    }

    fun generateResponse(prompt: String): String {
        return llmInference?.generateResponse(prompt)
            ?: throw IllegalStateException("Model not initialized")
    }

    fun release() {
        llmInference?.close()
        llmInference = null
    }
}

モデルダウンロードとキャッシング戦略:

// ModelDownloader.kt
class ModelDownloader(private val context: Context) {
    private val modelDir = File(context.filesDir, "models")

    suspend fun ensureModel(modelName: String, url: String): File {
        val modelFile = File(modelDir, modelName)
        if (modelFile.exists()) return modelFile

        modelDir.mkdirs()
        // Download with progress tracking
        // ... (see EXAMPLES.md for complete implementation)
        return modelFile
    }
}

期待結果: Android アプリが MediaPipe 依存と共にビルド、初回起動時にモデルがロード、推論がレイテンシ予算内で実行、初回ダウンロード後にモデルがキャッシュされる、未対応デバイスで優雅にフォールバック。

失敗時: build.gradle で minSdk >= 26 を確認、MediaPipe 依存バージョンを検証、モデルファイルが破損していないか確認(SHA256 をチェック)、モデル用の十分なデバイスストレージを検証、ProGuard ルールが MediaPipe クラスを保持するか確認、複数デバイスティアでテスト。

バリデーション

  • モデルが op 互換性エラーなく TFLite/ONNX へ変換される
  • 量子化モデル精度が許容公差内(< 2% 劣化)
  • ハードウェアデリゲートがロードし推論を加速する
  • ベンチマークレイテンシがターゲットを満たす(例: vision で < 100ms、LLM で < 50ms/トークン)
  • メモリ使用量がデバイス予算内に収まる
  • AI Edge Gallery が Gemma 4 モデルを正しくロード・実行する
  • デバイス上 LLM が一貫した応答を生成する
  • アプリケーションがモデルダウンロード、キャッシュ、更新を扱う
  • 未対応デバイスで優雅な劣化
  • ターゲット用途に許容される範囲のバッテリー影響

よくある落とし穴

  • TFLite で未対応の op: カスタム op が変換失敗 - converter.allow_custom_ops = True を使うかサポート対替に置換、op 互換性リストを確認
  • 量子化精度損失: INT4 が敏感タスクで品質を劣化 - 混合精度を使う、代表データでキャリブレーション、エッジ固有テストセットで評価
  • デリゲート初期化失敗: 旧型デバイスで GPU デリゲートがクラッシュ - 常に CPU フォールバックを実装、ロード前にデリゲート互換性を確認
  • デバイスのメモリ圧: モデル + アプリが利用可能 RAM を超える - メモリマップトモデルを使う、モデルアンロードを実装、バッチサイズを 1 へ縮小
  • サーマルスロットリング: 持続推論がデバイス過熱を引き起こす - デューティサイクリングを実装、推論頻度を減らす、サーマルゾーンを監視
  • モデルダウンロードサイズ: セルラーデータでの大きいモデル - Wi-Fi のみダウンロードを提供、再開可能ダウンロードを実装、漸進的モデルロードを使う
  • バージョン断片化: 一部デバイスでは動くが他では動かない - 代表的デバイスマトリクスでテスト、NNAPI バージョンチェックを使う、デバイス互換性データベースを維持

関連スキル

  • deploy-ml-model-serving - クラウドベースモデルサービング(エッジへの補完)
  • monitor-model-drift - 時間とともにモデル品質を監視
  • register-ml-model - エッジデプロイ前にモデルを登録
  • create-dockerfile - エッジモデル変換パイプラインをコンテナ化
  • create-multistage-dockerfile - モデル変換パイプライン用のマルチステージビルド

GitHub 저장소

pjt222/agent-almanac
경로: i18n/ja/skills/deploy-edge-ai-model
0
agentsagentskillsai-assisted-developmentclaude-codeskillsteams

연관 스킬

qmd

개발

qmd는 BM25, 벡터 임베딩, 재순위화를 결합한 하이브리드 검색을 통해 로컬 파일을 색인화하고 검색할 수 있는 로컬 검색 및 색인화 CLI 도구입니다. 명령줄 사용과 Claude 통합을 위한 MCP(Model Context Protocol) 모드를 모두 지원합니다. 이 도구는 임베딩에 Ollama를 사용하고 색인을 로컬에 저장하여 터미널에서 직접 문서나 코드베이스를 검색하는 데 이상적입니다.

스킬 보기

subagent-driven-development

개발

이 스킬은 각 독립적인 작업마다 새로운 하위 에이전트를 배치하고 작업 사이에 코드 리뷰를 진행하여 구현 계획을 실행합니다. 이 리뷰 프로세스를 통해 품질 게이트를 유지하면서 빠른 반복 작업을 가능하게 합니다. 동일한 세션 내에서 대부분 독립적인 작업을 진행할 때 내장된 품질 검증과 함께 지속적인 진행을 보장하기 위해 사용하세요.

스킬 보기

mcporter

개발

mcporter 스킬은 개발자가 Claude에서 직접 Model Context Protocol(MCP) 서버를 관리하고 호출할 수 있도록 합니다. 이 스킬은 사용 가능한 서버를 나열하고, 인수를 사용해 해당 서버의 도구를 호출하며, 인증 및 데몬 생명주기를 처리하는 명령어를 제공합니다. 개발 워크플로우에서 MCP 서버 기능을 통합하고 테스트할 때 이 스킬을 사용하세요.

스킬 보기

adk-deployment-specialist

개발

이 스킬은 A2A 프로토콜을 사용하여 Vertex AI ADK 에이전트를 배포하고 오케스트레이션하며, AgentCard 검색, 작업 제출, 코드 실행 샌드박스 및 메모리 뱅크와 같은 지원 도구를 관리합니다. Python, Java 또는 Go 언어로 순차, 병렬 또는 루프 오케스트레이션 패턴을 갖춘 다중 에이전트 시스템 구축을 가능하게 합니다. Google Cloud에서 ADK 에이전트 배포 또는 에이전트 워크플로우 오케스트레이션을 요청받았을 때 사용하세요.

스킬 보기