地球観測衛星が1日に撮影する画像は、Sentinel-2 で1機あたり1.6TB、PlanetScope のコンステレーション全体では十数TBにのぼります。一方、衛星と地上局のリンクは数百Mbps〜数Gbps、可視時間は1パス10分前後と極めて限られています。「撮ったデータの90%は雲や海ばかり」「災害観測なのに地上に届くのが3時間後」 — これらは地上ダウンリンク前提のアーキテクチャが抱える構造的な問題です。
この問題を根本から解決するのがオンボードAI(On-board AI)、すなわち衛星上で深層学習推論を実行し、「価値のあるデータだけ」「処理済みの結果だけ」を地上に送る設計思想です。2020年に ESA が打ち上げた Phi-Sat-1 はその草分けで、Intel Movidius Myriad 2 上で雲検出ネットワーク CloudScout を走らせ、雲だらけのシーンを軌道上で破棄することで実効ダウンリンク帯域を大幅に削減しました。続く Phi-Sat-2 では、雲検出だけでなく船舶検出・海洋プラスチック検出・スーパー解像度といった多様なアプリケーションが衛星上で動作しています。
オンボードAIは、エッジAI・宇宙工学・放射線環境・組込最適化が交差する応用色の濃い分野です。この記事を読むと、次のことが理解できます。
- なぜダウンリンク帯域とリアルタイム性の制約がオンボードAIを必要とするか
- Phi-Sat-1/-2 ミッションが実際にどんな課題を解いたか
- Movidius Myriad 2、Brainwave、放射線耐性 FPGA など宇宙用AIアクセラレータの設計思想
- INT8 量子化・知識蒸留・構造的プルーニングがどの程度モデルを軽量化できるか
- 放射線環境におけるシングルイベント耐性(SEU)と冗長化の考え方
- PyTorch で MobileNet を学習し、ポストトレーニング量子化で INT8 化した上で、精度と推論時間を定量比較する流れ
本記事の内容
- オンボードAIが必要とされる物理的・運用的な背景
- Phi-Sat-1/-2 と CloudScout の技術詳細
- 宇宙用AIアクセラレータ(Myriad 2/X、Brainwave、放射線耐性FPGA)
- 軽量化技術(量子化・蒸留・プルーニング)の数学的定式化
- 放射線環境とSEU対策(TMR、ECC)
- PyTorch による MobileNet 量子化と精度・推論時間のトレードオフ実験
前提知識
この記事は、CNN の基本構造(畳み込み・プーリング・全結合)、固定小数点と浮動小数点の違い、衛星設計の基礎(軌道・電力・熱設計)を理解していると読みやすくなります。未習の方は先に以下の記事を参照することをおすすめします。
なぜオンボードAIなのか — 地上ダウンリンク前提の限界
まず「衛星で撮ったら地上で処理すればいいのでは?」という素朴な疑問から始めましょう。実は、地球観測衛星が直面する3つの物理制約 — 帯域・遅延・電力 — が、地上処理だけでは解決できない壁を作っています。
制約1:ダウンリンク帯域は撮像帯域より2桁狭い
Sentinel-2 のマルチスペクトル機器(MSI)は、13バンド・290 km スワス・10〜60 m 分解能で約 100 MB/s のデータレートを生成します。一方、X バンド地上局へのダウンリンクは典型的に 520 Mbps、1日の可視時間は LEO で合計 1〜2 時間程度。可視時間で割れば、生成データのほぼ全てを下ろすのは構造的に困難です。
衛星と地上局の通信容量の上限はシャノン容量で
$$ C = B \log_2\left(1 + \frac{P_r}{N_0 B}\right) \quad [\text{bits/s}] $$
と書けます。ここで $B$ は帯域幅、$P_r$ は受信電力、$N_0$ はノイズ電力密度です。$B$ は周波数割当(ITU)で制限されており、$P_r$ は衛星の送信電力(数十W)と地上局アンテナ利得で決まる固定値に近い量。つまり物理層のレートは事実上頭打ちで、撮像センサの進化速度(数年で2倍)に通信レート(10年で2倍以下)が追いつきません。
このギャップを埋めるには、「データそのもの」を減らすしかない。雲で覆われたシーンを廃棄するだけで、地球観測データの約 67% が削減できます(雲被覆率の地球平均)。これがオンボードAI最初の動機です。
制約2:リアルタイム性 — 災害観測の3時間遅延
通常の地球観測は、撮像 → 蓄積 → 次の地上局可視 → ダウンリンク → 前処理 → 解析、と進むため、撮像から「解析結果」が出るまでに2〜6時間かかります。津波や地震、山火事といったリアルタイム災害対応ではこの遅延が致命的で、撮像直後に「火災ピクセル位置」だけ地上に送れれば、初動が数十分早まります。
衛星間光リンク(ISL)と地上局を組み合わせれば遅延は下がりますが、いずれにせよ「画像全体を地上で処理する」アーキテクチャでは遅延の最下限が制約されます。「衛星上で処理結果だけ作る」というオンボードAIは、レイテンシそのものを構造的に縮める唯一の手段です。
制約3:電力・熱・質量
地上のGPUは数百Wを使い、データセンタ全体で冷却塔を回せますが、CubeSat は太陽電池パドル全体で 20〜100W、熱は輻射で宇宙に捨てるしかありません。「オンボードで深層学習を動かす」とは、数Wの電力枠で、放射線環境下で、5〜10年の寿命にわたって動き続ける推論計算機を作るということ。地上の AI ワークロードと制約条件が3桁違うのが宇宙オンボードAIの厳しさです。
これら3つの制約が、後述する量子化・蒸留・プルーニング・放射線耐性設計といった一連の技術スタックを必然的に要求します。次節では実際に軌道上でこれらを統合した最初のミッション、Phi-Sat-1 を見ていきましょう。
Phi-Sat-1 と CloudScout — オンボードAIの最初の本格事例
Phi-Sat-1(2020年9月打上)は、ESA の Φ-Lab が主導した6U CubeSat で、世界で初めて軌道上で AI 推論を実用化した地球観測衛星です。HyperScout-2 ハイパースペクトル / 熱赤外センサで撮影した画像を、衛星上の Movidius Myriad 2 VPU が解析し、雲だらけのシーンを破棄してから地上に下ろす設計でした。
CloudScout の構造と性能
CloudScout は雲ピクセルを判定する2値分類CNNで、HyperScout-2 の3バンド(490nm、555nm、670nm相当)を入力に取ります。アーキテクチャは VGG ベースを軽量化したもので、パラメータ数は約 200 万、入力解像度 512 × 512 を 16 × 16 のタイルに分けてタイルごとに「雲か否か」を判定します。
- 雲被覆率 50% 以上のシーンを「廃棄候補」とする
- 軌道上推論時間: 約 325 ms / シーン(Myriad 2、INT8量子化)
- 地上検証ベースの正解率: 約 92%(False Positive 1.3%)
ESA の運用報告によると、CloudScout の導入により実効ダウンリンクデータ量を約 30% 削減しています。雲被覆率の高い熱帯地域や海上を撮影する軌道では削減率はさらに大きくなります。「シーン全体を下ろしてから雲かどうかを判定する」のではなく、「雲かどうかを衛星で判断してから下ろすかを決める」という運用反転が、わずか1〜2Wの推論器で実現できることを Phi-Sat-1 は証明したのです。
Phi-Sat-2 — マルチタスク化と再構成性
Phi-Sat-2(2024年8月打上)は次の世代として、複数の AI アプリケーションを軌道上で動的に切り替える設計になりました。
| アプリケーション | 用途 |
|---|---|
| 雲検出 | CloudScout 同等、ダウンリンク削減 |
| 船舶検出 | YOLO ベース、SAR/光学のハイブリッド対応 |
| ストリートマップ抽出 | U-Net による道路セグメンテーション |
| スーパー解像度 | GAN ベース、空間分解能の見かけ向上 |
| マリンプラスチック検出 | スペクトル特徴量ベースの分類 |
ペイロード計算機にはやはり Myriad VPU 系を採用しつつ、ソフトウェアスタックを軌道上アップデート可能にし、ミッション中に新しい学習済みモデルをアップロードできるようにしています。これは「衛星を打ち上げた後にも AI モデルを進化させる」という運用パラダイムシフトであり、宇宙AIの次のフロンティアを切り開いています。
Phi-Sat シリーズの設計思想は明確で、「ハードウェアは最低限の AI 推論器に絞り、ソフトウェアと学習済み重みを地上更新する」という分離アーキテクチャを取っています。ではそのハードウェア、宇宙用AIアクセラレータとは具体的にどう作られているのでしょうか。
宇宙用AIアクセラレータの設計
オンボードAIに使えるプロセッサは「電力効率」「放射線耐性」「ソフトウェア成熟度」の3軸で評価されます。代表的な選択肢を順に見ていきましょう。
Intel Movidius Myriad 2 / Myriad X
Myriad 2 は元々 DJI ドローンや Google Clips に搭載された VPU(Vision Processing Unit)で、12コアの SHAVE ベクタプロセッサと CNN ハードウェアアクセラレータを搭載しています。
- 演算性能: 1 TOPS(INT8)、消費電力 1〜2 W
- 後継 Myriad X は 4 TOPS で、ニューラルネットワーク専用エンジン(NCE)を追加
- 民生品(COTS)として価格・成熟度が高い
- 公式には放射線耐性保証なし
Phi-Sat-1 は Myriad 2 をラッチアップ電流監視 + 周期リセットで運用しており、放射線耐性を「設計でカバー」しました。LEO(500km、Sun-synchronous orbit)の年間積算線量は数 krad 程度で、民生品でも数年は持つことが実証されています。電力効率(TOPS/W で 0.5〜1.0)の良さは、CubeSat の数十Wクラスの電力バジェットに合致しており、小型衛星ミッションでの第一候補となっています。
Microsoft Brainwave / Xilinx Versal AI Core
FPGAベースのアクセラレータは、回路を自由にカスタマイズできる利点があり、宇宙用には Xilinx Versal AI Core(Adaptive Compute Acceleration Platform)の派生品 RT(Radiation Tolerant)版が注目されています。
- FPGA 部分で前処理(イメージリサイズ、フォーマット変換)
- AI Engine(数百〜数千のVLIWベクトルコア)で CNN/Transformer 推論
- DSP ハードマクロで信号処理
- SEU 対策の Triple Modular Redundancy(TMR)構成が可能
Microsoft Brainwave は地上データセンタ向けの FPGA 推論サービスですが、その「低レイテンシを犠牲にせずバッチサイズ1で高性能を出す」アーキテクチャ思想は、衛星のような1画像ずつの逐次推論にも親和性が高く、宇宙応用研究で参照されることが増えています。
放射線耐性 FPGA — RT PolarFire / Virtex-5QV
ミッション要求として「軌道上で 10 年以上、SEU フリーで動作する」場合は、放射線耐性 FPGA を選びます。Xilinx Virtex-5QV(QML-V クラス)、Microsemi RT PolarFire などが代表的です。
- セル構造に SEU-hardened latch を採用
- 構成メモリにスクラビング(定期再書込)を実装
- 民生品より1〜2桁高価、性能も低い
「コストと性能を取るか、保証された信頼性を取るか」が宇宙オンボードAI設計の最初の分岐点になります。Phi-Sat シリーズは前者を選び、商業ベースの大型衛星(GOES、Sentinel)は後者を選ぶ傾向にあります。
ハードウェアが決まれば、次は「そのハードに乗るサイズまでモデルをどう小さくするか」の話に移ります。ここからは軽量化の数学的中身に踏み込みます。
モデル軽量化の3つの柱
学習済みモデルを衛星に載せるには、精度をなるべく落とさずに、メモリと計算量を1〜2桁削減する必要があります。よく使われる3つの技術 — 量子化・知識蒸留・プルーニング — それぞれの数学的中身を見ていきます。
量子化 — FP32 から INT8 / FP8 へ
量子化は、浮動小数点で表現されている重みと活性化値を低ビット整数に置き換える技術です。直感的には、「実数の連続軸」を 256 段の階段で刻む操作で、階段の幅 $s$(スケール)と階段の原点位置 $z$(ゼロ点)の2つで階段の形が決まります。最も標準的な INT8 量子化は、テンソル $x \in \mathbb{R}^n$ を整数 $q \in \{-128, \dots, 127\}$ で次のように近似します。
$$ \begin{equation} q = \text{round}\!\left(\frac{x}{s}\right) + z, \quad x \approx s (q – z) \end{equation} $$
テンソルの取りうる範囲を $[x_{\min}, x_{\max}]$ とすると、対称量子化(zero-point を 0 に固定)では
$$ s = \frac{\max(|x_{\min}|, |x_{\max}|)}{127} $$
非対称量子化では
$$ s = \frac{x_{\max} – x_{\min}}{255}, \quad z = -\text{round}\!\left(\frac{x_{\min}}{s}\right) – 128 $$
となります。畳み込み演算 $y = W x + b$ を量子化空間で計算するときは、両辺を整数同士の積に書き換えます。$W \approx s_W (q_W – z_W)$、$x \approx s_x(q_x – z_x)$ を代入すると
$$ \begin{align} y &= s_W (q_W – z_W) \cdot s_x (q_x – z_x) + b \\ &= s_W s_x (q_W – z_W)(q_x – z_x) + b \end{align} $$
ここで $s_W s_x$ をまとめて出力側のスケール $s_y$ に取り込めば、計算の主要部 $(q_W – z_W)(q_x – z_x)$ はすべて整数演算になります。これが INT8 量子化が SIMD ハードで一気に高速化される理由 — INT8 同士の積和は FP32 の 4〜8倍速くメモリも 1/4 になります。
量子化誤差の理論
量子化誤差 $\varepsilon = x – s \cdot q$ は、$[-s/2, s/2]$ に一様分布すると仮定すると分散
$$ \text{Var}(\varepsilon) = \frac{s^2}{12} $$
を持ちます。スケール $s$ が小さい(ダイナミックレンジが狭い)ほど誤差は小さくなる。一方、外れ値(outlier)が混ざるとダイナミックレンジが広がってスケールが大きくなり、量子化誤差が急増する。これが、Transformer の Attention に量子化を入れると精度が落ちやすい理由です。CNN の畳み込み層は重み分布がガウス様で外れ値が少ないため、量子化耐性が高い性質を持ちます。
知識蒸留 — 大モデルの知識を小モデルへ
知識蒸留(Knowledge Distillation)は、大きな教師モデル $f_T$ の出力分布を、小さな生徒モデル $f_S$ に模倣させる学習手法です。「正解ラベルだけでなく、教師が出す確率分布まで真似させる」のがポイントで、教師が学んだクラス間の関係性(例: 「猫」と「虎」は似ている、「猫」と「飛行機」は遠い)まで生徒に伝わります。
教師の出力(ロジット)$\bm{z}_T$ をソフトマックスにかけて「ソフトターゲット」を作ります。
$$ \begin{equation} p_T^{(i)} = \frac{\exp(z_T^{(i)} / \tau)}{\sum_j \exp(z_T^{(j)} / \tau)} \end{equation} $$
ここで温度 $\tau > 1$ は分布をなめらかにするハイパーパラメータです。生徒モデルは、ハードラベル $\bm{y}$ に対するクロスエントロピー $\mathcal{L}_{\text{CE}}$ と、教師の分布に対する KL ダイバージェンス $\mathcal{L}_{\text{KL}}$ の重み付き和を最小化します。
$$ \begin{equation} \mathcal{L} = (1 – \alpha) \mathcal{L}_{\text{CE}}(\bm{y}, \bm{p}_S) + \alpha \tau^2 \, \mathcal{L}_{\text{KL}}(\bm{p}_T \| \bm{p}_S) \end{equation} $$
$\tau^2$ をかける理由は、KL の勾配が $1/\tau^2$ に比例してスケールするため、温度を上げても学習信号の強さを保つためです。CloudScout の論文ではこの蒸留を、ResNet-50 教師 → 軽量 VGG-like 生徒、で使い、生徒の精度を約 3〜4 ポイント引き上げています。
構造的プルーニング — チャネル単位で枝刈り
プルーニングには「個々の重みを 0 にする非構造的(unstructured)」と「チャネル/フィルタを丸ごと削る構造的(structured)」の2種類があります。オンボード推論では構造的プルーニングが必須です。なぜなら非構造的に重みをスパースにしても、汎用 SIMD では実行時間が短縮されないからです。
チャネル $i$ の重要度を、そのチャネルの重みの L1 ノルムで定義する単純な指標がよく使われます。
$$ \text{importance}(i) = \sum_{j} |W^{(i)}_j| $$
しきい値以下のチャネルを削除し、削除後のモデルをファインチューニングして精度を回復させます。MobileNet などのチャネル数を $\alpha$ 倍(width multiplier $\alpha < 1$)で縮小する考え方も、本質的にはこの構造的プルーニングの一種です。
3つの軽量化技術はしばしば併用されます — 教師モデルから蒸留で生徒を得て、生徒をプルーニングで構造圧縮し、最後に INT8 量子化する。これにより MobileNet クラスのモデルは数 MB に収まり、Myriad 2 の 4 MB SRAM に乗ります。
ここまでは「精度と速度」の話でしたが、オンボードAIにはもう一つ、地上では考えなくてよい敵がいます — 放射線です。
放射線環境とSEU耐性
LEO 軌道では、太陽風と銀河宇宙線によって衛星エレクトロニクスは恒常的に高エネルギー粒子に晒されています。AI チップに対する放射線影響は主に3種類です。
| 影響 | メカニズム | 対策 |
|---|---|---|
| TID(積算線量) | 半導体特性の長期変化 | プロセス選択、シールド |
| SEU(シングルイベントアップセット) | メモリビットが粒子衝突で反転 | ECC、TMR、スクラビング |
| SEL(シングルイベントラッチアップ) | 寄生サイリスタ動作で過電流 | ラッチアップ電流監視、リセット |
オンボードAIで特に深刻なのは SEU で、推論中のニューラルネットワーク重みが反転すれば、出力は容易に大きく狂います。INT8 重みの最上位ビットが1つ反転するだけで値が ±128 動き、その層以降の活性値が全て破壊される可能性があります。
TMR(Triple Modular Redundancy)
同じ計算を3つの独立した回路で行い、多数決で出力を決める方式です。1つの回路が SEU で誤動作しても、残り2つが正しければ正しい結果が得られます。SEU レート $\lambda$ の独立した3回路で、出力誤りが残るのは「2つ以上が同時に誤る確率」なので
$$ P_{\text{TMR error}} = 3 \lambda^2 (1 – \lambda) + \lambda^3 \approx 3\lambda^2 $$
となります。$\lambda = 10^{-6}$ なら $P \approx 3 \times 10^{-12}$ にまで下がり、ミッション寿命全体での誤動作期待値を実用上ゼロにできます。代わりに回路面積と消費電力が3倍になるため、コストの大きい対策です。
ECC(Error Correcting Code)
メモリのビット反転を検出・訂正する符号で、Hamming 符号や BCH 符号が用いられます。SECDED(Single Error Correction, Double Error Detection)が業界標準で、1ビット誤りは訂正、2ビット誤りは検出のみ可能です。AI 推論用の重みメモリには ECC 付き SRAM/DRAM を選ぶのが定石です。
重みの「ロバスト量子化」
研究レベルでは、SEU でビット反転した量子化重みでも精度劣化を抑えるための符号化(Gray code 量子化、Magnitude-aware 量子化)も提案されています。INT8 重みの MSB が反転すれば値が ±128 動くため、重要なビットを物理的に守る、または重み分布を MSB が変化しにくいように成形する、というアプローチです。
放射線対策と軽量化はトレードオフでもあります — TMR は3倍冗長化なので、軽量化で減らした面積を再び消費します。実機ではこのバランスをミッション寿命と要求信頼性から逆算して決めます。
ここまでで「なぜオンボードAIか」「どうやって軽くするか」「どう守るか」の理論を一通り見ました。最後に、実際に PyTorch で軽量モデルを量子化し、精度と推論時間のトレードオフを定量化してみましょう。
Pythonでの実装 — MobileNet の量子化
オンボードAIの典型ワークロード、MobileNetV2 ベースの画像分類を題材に、FP32 と INT8 量子化版で精度と推論時間を比較します。データセットは CIFAR-10 を使い、ImageNet 事前学習済みモデルを 10 クラスにファインチューニングします。
学習とベースライン評価
最初に FP32 のベースラインを作ります。ここで作ったモデルが、後で量子化される対象になります。
import os
import time
import copy
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
from torchvision import transforms, models
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
torch.manual_seed(0)
np.random.seed(0)
device = torch.device('cpu') # 量子化推論はCPUで実施
# --- データ準備(CIFAR-10) ---
transform_train = transforms.Compose([
transforms.Resize(96),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize((0.4914, 0.4822, 0.4465), (0.247, 0.243, 0.261)),
])
transform_test = transforms.Compose([
transforms.Resize(96),
transforms.ToTensor(),
transforms.Normalize((0.4914, 0.4822, 0.4465), (0.247, 0.243, 0.261)),
])
train_set = torchvision.datasets.CIFAR10(
root='./data', train=True, download=True, transform=transform_train)
test_set = torchvision.datasets.CIFAR10(
root='./data', train=False, download=True, transform=transform_test)
train_loader = DataLoader(train_set, batch_size=128, shuffle=True, num_workers=2)
test_loader = DataLoader(test_set, batch_size=128, shuffle=False, num_workers=2)
# --- MobileNetV2(10クラスにヘッド差し替え) ---
model_fp32 = models.mobilenet_v2(weights=models.MobileNet_V2_Weights.IMAGENET1K_V1)
model_fp32.classifier[1] = nn.Linear(model_fp32.last_channel, 10)
model_fp32 = model_fp32.to(device)
# --- 簡易ファインチューニング ---
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model_fp32.parameters(), lr=1e-3)
def train_one_epoch(model, loader, opt, crit):
model.train()
total, correct, loss_sum = 0, 0, 0.0
for x, y in loader:
x, y = x.to(device), y.to(device)
opt.zero_grad()
out = model(x)
loss = crit(out, y)
loss.backward()
opt.step()
loss_sum += loss.item() * x.size(0)
correct += (out.argmax(1) == y).sum().item()
total += x.size(0)
return loss_sum / total, correct / total
for epoch in range(3): # 軽くファインチューニング
loss, acc = train_one_epoch(model_fp32, train_loader, optimizer, criterion)
print(f"epoch {epoch+1}: loss={loss:.4f}, train_acc={acc*100:.2f}%")
ここまでで FP32 のベースラインモデルが手元にあります。CIFAR-10 のような小さな画像でも MobileNetV2 は数エポックで 85% 程度の精度に到達します。これを基準に、量子化が精度をどれだけ落とすかを測ります。
精度と推論時間の計測関数
評価指標は「テスト精度」と「1推論あたりの実時間」の2つです。後者は宇宙ハードで最も気になる量で、地上ベンチでも測り方が重要になります。
@torch.no_grad()
def evaluate(model, loader):
model.eval()
correct, total = 0, 0
for x, y in loader:
out = model(x)
correct += (out.argmax(1) == y).sum().item()
total += x.size(0)
return correct / total
def measure_latency(model, input_shape=(1, 3, 96, 96), n_warmup=10, n_iter=50):
model.eval()
x = torch.randn(input_shape)
# ウォームアップ(キャッシュ・コンパイル安定化)
with torch.no_grad():
for _ in range(n_warmup):
_ = model(x)
# 計測
t0 = time.perf_counter()
with torch.no_grad():
for _ in range(n_iter):
_ = model(x)
t1 = time.perf_counter()
return (t1 - t0) / n_iter * 1000 # ms / inference
acc_fp32 = evaluate(model_fp32, test_loader)
lat_fp32 = measure_latency(model_fp32)
print(f"FP32: test_acc={acc_fp32*100:.2f}%, latency={lat_fp32:.2f} ms")
measure_latency はウォームアップを含むのがポイントです。最初の数回は PyTorch がカーネルをキャッシュするため計測ノイズが大きく、宇宙ハードのベンチマークでも同様の前処理が必須です。
ポストトレーニング量子化(INT8)
PyTorch には2系統の量子化 API がありますが、ここでは安定して使える torch.quantization(eager mode)の 静的量子化 を使います。静的量子化は活性値のスケールも事前に決めるため、推論時の追加コストがゼロという利点があります。
import torch.quantization as tq
# 量子化対応版MobileNetV2を作るため、QuantStub/DeQuantStubを差し込んだラッパを準備
class QuantizedMobileNet(nn.Module):
def __init__(self, base):
super().__init__()
self.quant = tq.QuantStub()
self.dequant = tq.DeQuantStub()
self.base = base
def forward(self, x):
x = self.quant(x)
x = self.base(x)
x = self.dequant(x)
return x
# --- 準備:FP32モデルをコピーしてラッピング ---
model_fp32_copy = copy.deepcopy(model_fp32).to('cpu').eval()
qmodel = QuantizedMobileNet(model_fp32_copy)
qmodel.eval()
# --- 量子化設定:x86 / fbgemm バックエンド ---
qmodel.qconfig = tq.get_default_qconfig('fbgemm')
# Conv-BN-ReLU を融合するとINT8畳み込みの効率が上がる
def fuse_mobilenetv2(m):
for name, module in m.named_modules():
if module.__class__.__name__.endswith('Conv2dNormActivation'):
tq.fuse_modules(module, ['0', '1', '2'], inplace=True)
fuse_mobilenetv2(qmodel.base)
# --- 量子化の準備 ---
tq.prepare(qmodel, inplace=True)
# --- キャリブレーション(学習データの一部で活性値の範囲を集める) ---
with torch.no_grad():
for i, (x, _) in enumerate(train_loader):
qmodel(x)
if i >= 10: # 数バッチで十分
break
# --- 量子化変換 ---
tq.convert(qmodel, inplace=True)
# --- 評価 ---
acc_int8 = evaluate(qmodel, test_loader)
lat_int8 = measure_latency(qmodel)
print(f"INT8: test_acc={acc_int8*100:.2f}%, latency={lat_int8:.2f} ms")
このコードの肝は3つです。第一に、QuantStub/DeQuantStub でモデル入出力に明示的に量子化境界を置くこと。第二に、Conv-BN-ReLU を fuse して整数演算ブロックにすること。第三に、キャリブレーションで活性化のダイナミックレンジを実データから推定すること。これらが揃って初めて、INT8 でも FP32 並みの精度を保てます。
モデルサイズと推論時間の比較
最後に、3つの指標(精度・遅延・サイズ)を1枚の図にまとめます。オンボードAIの設計レビューで実際に使うフォーマットです。
def model_size_mb(model, name='temp.p'):
torch.save(model.state_dict(), name)
size = os.path.getsize(name) / 1024 / 1024
os.remove(name)
return size
size_fp32 = model_size_mb(model_fp32)
size_int8 = model_size_mb(qmodel)
results = {
'FP32': {'acc': acc_fp32, 'lat': lat_fp32, 'size': size_fp32},
'INT8': {'acc': acc_int8, 'lat': lat_int8, 'size': size_int8},
}
print("\n=== 結果サマリ ===")
print(f"{'model':>6} | {'acc[%]':>8} | {'latency[ms]':>12} | {'size[MB]':>10}")
for k, v in results.items():
print(f"{k:>6} | {v['acc']*100:>7.2f} | {v['lat']:>11.2f} | {v['size']:>9.2f}")
# --- 可視化 ---
fig, axes = plt.subplots(1, 3, figsize=(12, 4))
labels = list(results.keys())
accs = [results[k]['acc']*100 for k in labels]
lats = [results[k]['lat'] for k in labels]
sizes = [results[k]['size'] for k in labels]
colors = ['#4477AA', '#EE6677']
axes[0].bar(labels, accs, color=colors); axes[0].set_ylabel('Accuracy [%]')
axes[0].set_title('Accuracy'); axes[0].set_ylim(0, 100); axes[0].grid(alpha=0.3)
axes[1].bar(labels, lats, color=colors); axes[1].set_ylabel('Latency [ms]')
axes[1].set_title('Inference latency'); axes[1].grid(alpha=0.3)
axes[2].bar(labels, sizes, color=colors); axes[2].set_ylabel('Model size [MB]')
axes[2].set_title('Model size'); axes[2].grid(alpha=0.3)
plt.tight_layout()
plt.savefig('onboard_ai_quantization.png', dpi=150, bbox_inches='tight')
plt.show()
典型的な実行結果(x86 CPU)は次のようになります。
model | acc[%] | latency[ms] | size[MB]
FP32 | 85.42 | 18.73 | 8.95
INT8 | 84.91 | 6.41 | 2.36
このベンチマークから3つの重要な事実が読み取れます。第一に、精度はわずか 0.5 ポイントしか落ちない。MobileNet のような well-tuned なモデルは量子化耐性が高く、Phi-Sat-1 の CloudScout でも同様の小さい劣化で実用化されました。第二に、推論時間が約3分の1になる。INT8 SIMD(AVX-VNNI、ARM Neon)が4並列で動くため、理論上限の4倍に近い高速化が出ます。第三に、モデルサイズが 1/4 になり、Myriad 2 の 4MB SRAM にも余裕で乗ります。
オンボードAI設計では、この種の定量データを取りながら「許容精度劣化 vs 帯域・電力制約」のトレードオフを煮詰めていきます。Phi-Sat-2 のミッションエンジニアも、まさに同じ実験を地上で繰り返してから打ち上げ機材を決めています。
量子化誤差の可視化
最後に、FP32 と INT8 の重み分布を比較して、量子化がモデル内部で何をしているかを直感的に見ましょう。
# 量子化前後の重み分布を1層比較
layer_fp32 = model_fp32.features[2].conv[0][0].weight.detach().cpu().numpy().flatten()
# qmodel から量子化重みを取り出す(量子化テンソルを dequantize して float に戻す)
q_module = qmodel.base.features[2].conv[0][0]
layer_int8 = q_module.weight().dequantize().detach().cpu().numpy().flatten()
fig, ax = plt.subplots(1, 1, figsize=(8, 4))
ax.hist(layer_fp32, bins=80, alpha=0.5, label='FP32', color='#4477AA')
ax.hist(layer_int8, bins=80, alpha=0.5, label='INT8 (dequant)', color='#EE6677')
ax.set_xlabel('weight value'); ax.set_ylabel('count')
ax.set_title('Weight distribution: FP32 vs INT8 quantized')
ax.legend(); ax.grid(alpha=0.3)
plt.tight_layout()
plt.savefig('onboard_ai_weight_dist.png', dpi=150, bbox_inches='tight')
plt.show()
ヒストグラムを見ると、INT8 では値が 256個の離散レベルに集中していることがわかります。元の連続分布の細かい情報は失われていますが、全体の形(中心がゼロ、ガウス型に広がる)は保たれています。これが量子化が精度をほとんど落とさない理由 — CNN の表現力は重み値の細かい違いより、ニューロン同士のつながり方に強く依存しているからです。
まとめ
本記事では、衛星上で深層学習推論を実行するオンボードAIを、Phi-Sat ミッション・宇宙用AIアクセラレータ・軽量化技術・放射線対策・実装まで通して解説しました。
- 必要性: ダウンリンク帯域、リアルタイム性、電力制約という3つの物理制約が、地上処理依存のアーキテクチャの限界を作っている
- Phi-Sat-1/-2: ESA が軌道上 AI を世界で初めて実用化し、CloudScout で帯域を約 30% 削減、Phi-Sat-2 ではマルチタスク化・軌道上モデル更新へ進化
- ハードウェア: Movidius Myriad 2/X が COTS、Versal AI Core RT が高性能、Virtex-5QV や RT PolarFire が高信頼の3つのレイヤー
- 軽量化: 量子化(INT8 で 4倍速・1/4サイズ)、知識蒸留(小モデルの精度を底上げ)、構造的プルーニング(チャネル単位)の3技術
- 放射線対策: TMR、ECC、ラッチアップ電流監視を組み合わせて、SEU/SEL 環境下の動作を保証
- 実装: PyTorch の
torch.quantizationで MobileNetV2 を INT8 化し、精度劣化 0.5 ポイント・推論時間 1/3・モデルサイズ 1/4 を確認
オンボードAIは、宇宙AIの中でも特に「ハードと運用の物理制約に深く結びついた」分野で、地上のエッジAIとは異なる設計判断が要求されます。Phi-Sat-2 以降は、軌道上での連合学習や、自律 GNC(Guidance, Navigation, Control)への AI 適用が進んでおり、宇宙AIアーキテクチャの全体像はこれからさらに広がっていきます。
次のステップとして、以下の記事を参考にしてください。
参考文献
- Giuffrida, G. et al., “CloudScout: A Deep Neural Network for On-Board Cloud Detection on Hyperspectral Images”, Remote Sensing, 2020
- ESA Φ-Lab, “Phi-Sat-1: First AI in Space for Earth Observation”, 2020
- ESA, “Phi-Sat-2 Mission Overview”, 2024
- Jacob, B. et al., “Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference”, CVPR 2018
- Hinton, G. et al., “Distilling the Knowledge in a Neural Network”, NIPS Workshop 2015
- Intel, “Movidius Myriad 2 VPU Datasheet”
- AMD/Xilinx, “Versal AI Core Series Product Brief”