AI執筆について
この記事は、筆者の実験ログ、実機スクリーンショット、検証結果をもとに、AI(ChatGPT)による構成整理と文章化の支援を受けて作成しています。実験の実施、結果の確認、最終的な内容判断は筆者が行っています。
この記事で伝えたいこと
Apple Watch上で、ネットワーク接続なしに画像を生成する小型モデルを作っています。
ただし、これはStable Diffusionのような巨大な拡散モデルをApple Watchへ無理やり載せる試みではありません。クラウドやMacで作った教師画像を使って、Apple Watch上ではもっと小さな生成器だけを動かす、という方針です。
2026年6月14日時点では、実機上で次のところまで来ています。
| 項目 | 現状 |
|---|---|
| 出力サイズ | 128×128 |
| 実行環境 | Apple Watch 11実機 |
| ネットワーク | 生成時はオフライン |
| メモリ使用量 | おおむね30MB程度 |
| 生成時間 | 数十秒程度 |
| 得意なもの | 動物、一部の物体、car / cat / dog / sun / face / mountain / 宇宙飛行士 など |
| まだ弱いもの | 長い自然文、複数物体、細かい構図、シャープさ |
検証・開発環境は以下です。
| 区分 | 内容 |
|---|---|
| 実機 | Apple Watch 11 |
| 開発機 | M2 Mac mini(メモリ8GB) |
| OS | macOS 26.5 |
| IDE | Xcode 26.5 |
この記事では、何を作っているのか、拡散モデルと何が違うのか、ここまでに何を試してきたのかを整理します。
まず、拡散モデルとは何が違うのか
一番誤解されやすいところはここです。
今回のモデルは、Stable Diffusionを小さくしたものではありません。
一般的な拡散モデルは、ざっくり言うと「ノイズだらけの画像から、何十ステップもかけて少しずつノイズを取り除き、画像らしくしていく」方式です。高品質な画像や長い自然文プロンプトに強い一方で、text encoder、U-NetやTransformer、VAEなどが関わるため、モデルも計算もかなり重くなります。
一方、今回Apple Watch上で動かしているのは、座標ベースの小さなMLPです。
各ピクセルについて、x, y 座標、半径方向の特徴、Fourier特徴、そしてプロンプトとseedから作った小さなlatentを入力し、そのピクセルのRGBを直接出します。
図1: 拡散モデルは反復的にノイズを除去する。今回のApple Watch側モデルは、座標とlatentから各ピクセルのRGBを直接計算する。
違いを表にすると、次のようになります。
| 観点 | 一般的な拡散モデル | 今回のApple Watch側モデル |
|---|---|---|
| 生成方法 | ノイズから反復的にdenoise | 座標ごとにRGBを直接出力 |
| 主な強み | 高品質、長い自然文、複雑な構図 | 小さい、オフライン、端末上で動かしやすい |
| 主な弱み | モデルサイズと計算量が大きい | 画質、自由入力、複数物体表現に限界がある |
| 端末上の実行 | Apple Watchではかなり厳しい | Apple Watch 11実機で実行可能 |
| 画像の作り方 | 画像全体を少しずつ復元 | ピクセルごとの関数として画像を表す |
このプロジェクトの狙いは、「最高画質の画像生成」ではありません。
Apple Watchというかなり制約の強い環境で、短いプロンプトから、それっぽく読める小さな画像をオフラインで生成することです。
ゴールと制約
最初に決めたゴールはかなり厳しめでした。
- Apple Watch上で動かす
- できれば完全オフライン
- メモリ使用量を小さく保つ
- 生成時間は多少かかってもよい
- プリセットだけでなく、短い自由入力プロンプトにも少しずつ対応したい
- 画像は小さくてもよいが、対象物が何となく読める品質にはしたい
この条件だと、一般的な画像生成モデルをそのまま載せるのは現実的ではありません。
そこで方針を分けました。
学習用の教師画像はMacやクラウドGPUで作る。Apple Watch上では、できるだけ小さな生成器だけを動かす。
この分担にしたことで、端末側の処理をかなり単純にできます。
実機上で動いている処理
Apple Watch側でやっていることは、かなりシンプルです。
- 入力プロンプトを正規化する
- 既知の名詞・色・動作・形容詞・構図語彙に分解する
- プロンプトとseedからlatentを作る
- 128×128の各ピクセルをMLPで生成する
- 軽い後処理で色ノイズを抑える
図2: 実機側では、重い自然言語モデルや拡散モデルを動かさず、語彙分解と座標MLPだけで生成する。
現在採用している主な設定は次の通りです。
| 項目 | 値 |
|---|---|
| 出力サイズ | 128×128 |
| latent次元 | 64 |
| hidden幅 | 1536 |
| hidden層数 | 2 |
| prompt encoder | compositional_v2 |
| 学習step | 30000 |
| 学習batch size | 8192 |
| target downsample | 96 |
| target blur radius | 0.15 |
watchOS側では、重みを読み込み、Accelerate の cblas_sgemm を使ってバッチ単位でMLPを評価しています。
処理のイメージは次のようなものです。
prompt + seed
-> compositional latent
x, y, r, Fourier features, latent
-> tiny MLP
-> RGB
ポイントは、画像を「1枚の大きなデータ」として一気に作るのではなく、「座標を入れるとRGBが返ってくる関数」として表現していることです。
なぜ普通のtext encoderを載せていないのか
自由入力に対応したいなら、CLIPのようなtext encoderを載せたくなります。
ただ、Apple Watch上ではそれ自体がかなり重いです。
- モデルサイズが増える
- メモリ使用量が増える
- 推論時間が増える
- 画像生成器側の容量に対して、入力できる自然文の幅が広すぎる
そのため現時点では、自然文をそのまま理解するのではなく、制限付きの語彙へ分解する方式にしています。
想定しているのは、たとえば次のような短いプロンプトです。
cat
blue bird
small fox sitting
floating cloud
front view clock
green alien walking
striped umbrella
ice cream
この方式は万能ではありません。
しかし、Apple Watchで動かす小型モデルとしては現実的です。完全な自然文理解を目指すより、既知語彙をうまく組み合わせる方が、実機体験として安定します。
教師データはSDXLで作る
Apple Watch上の小型モデルを直接うまく学習させるには、良い教師画像が必要です。
そこで、教師画像は主にSDXLで作っています。Mac上での生成も試しましたが、まとまった枚数を作るには時間がかかるため、最終的にはRunPod上のRTX 4090を使いました。
ここで大事なのは、SDXLをApple Watch上で動かしているわけではない、という点です。
SDXLはあくまで先生です。先生が作った画像を使って、小さなMLPに「このプロンプトなら、だいたいこういう形になる」という知識を移しています。
図3: SDXLは教師画像を作るために使う。Apple Watch上では、学習済みの小さなMLPだけを動かす。
教師画像生成では、次の方針を強く意識しています。
- 1枚に1対象だけ
- 中央配置
- 背景はシンプル
- 小さくしてもシルエットが読める
- 文字、ロゴ、透かしを入れない
- 複数物体、パターン、タイル状配置を避ける
SDXLには、たとえば次のようなプロンプトを投げます。
exactly one cute fox, isolated single subject, centered,
full subject visible, clean simple illustration,
matte plain light gray background, empty background,
readable silhouette, no text, no logo, no watermark
ネガティブプロンプトでは、次のようなものを避けます。
text, logo, watermark, caption, low quality, blurry,
noisy, distorted, deformed, cropped subject,
multiple subjects, repeated subject, tiled layout,
pattern, busy background, cluttered background
教師データをそのまま全部使わない理由
生成した教師画像は、そのまま全部は使いません。
理由は、小型モデルがとても素直だからです。
教師画像に余計な背景模様や繰り返しパターンが入っていると、それも学習してしまいます。大きなモデルなら多少吸収できるノイズでも、今回のような小型MLPでは品質に直撃します。
そこで、次のような画像を弾いています。
- 背景のエッジ密度が高すぎるもの
- 前景成分が分裂しすぎているもの
- 最大前景成分が小さすぎるもの
- 複数物体に見えるもの
- パターン化しているもの
図4: 小型モデルでは、背景ノイズや複数物体の混入がそのまま品質低下につながりやすい。
さらに、単純にスコア上位だけを採用するのではなく、quality_diverse という選び方を使っています。
これは、カテゴリごとに高品質な画像を選びつつ、同じ種類のプロンプトだけに偏らないようにするものです。
たとえば cat であれば、次のようなバリエーションが残るようにします。
cat
small cat
fluffy cat
cat sitting
cat jumping
front view cat
cartoon cat
watercolor cat
小型モデルで短い自由入力に少しでも対応するには、「品質」と「多様性」の両方が必要でした。
ここまでの反復
ここまで、かなり多くの反復をしています。
最初は、学習済みジャンルについては何となくそれっぽい画像を出せる状態でした。ただ、次の問題がありました。
- 学習していないジャンルに弱い
- 自由入力プロンプトに弱い
- 動詞や形容詞がほぼ効かない
- 画像がかなりぼやける
- 背景にノイズや模様が混じる
この段階では、プリセット画像生成に近い状態でした。
その後、SDXL教師データ生成、フィルタリング、語彙拡張、curatedデータ補強、軽量後処理を順に試しました。
v4 / v5での改善
v4からv5では、主に次の改善を入れました。
- 46カテゴリ程度まで拡張
- 色、動作、形容詞、構図、スタイルのスロットを追加
-
compositional_v2prompt encoderを使用 -
quality_diverseによる多様性維持 -
orange/pizza/breadのような問題カテゴリにcurated補強データを追加
v5では、次の規模のデータを作りました。
| 項目 | 件数 |
|---|---|
| 生成metadata | 5346 |
| 採用 | 4248 |
| reject | 1098 |
| フィルタ後 | 2203 |
| problem3除外後 | 2059 |
この段階で、動物系や一部の物体はかなり改善しました。
ただし、まだ背景ノイズとぼやけは残っていました。
軽量後処理
生成モデルそのものではなく、表示直前の後処理も試しました。
超解像モデルは重く、今回の問題である「背景のざらつき」を直接解くものでもありません。
そこで、RGBを輝度と色差に分けて処理しています。
- RGBを輝度 + 色差に変換
- 色差成分をやや強めに平滑化
- 輝度成分はエッジを見ながら弱く平滑化
- 輪郭をなるべく残しつつ、背景の細かい色ノイズを抑える
これは根本的な品質改善ではありません。
ただ、実機表示ではノイズ感を少し抑える効果がありました。
v6での語彙拡張
v6では、既存46カテゴリを残したまま、新規29カテゴリを追加しました。
追加したカテゴリの例です。
astronaut
alien
dragon
penguin
turtle
elephant
lion
monkey
frog
duck
deer
whale
umbrella
key
bottle
pencil
lamp
phone
computer
crown
diamond
sword
shield
cactus
volcano
fire
ice cream
donut
sushi
また、動作・形容詞・状態語彙も増やしました。
dancing
climbing
spinning
sliding
open
striped
spotted
closed
broken
wooden
metallic
transparent
sharp
spiky
v6のデータ規模は次の通りです。
| 項目 | 件数 |
|---|---|
| 生成metadata | 5956 |
| 採用 | 5428 |
| reject | 528 |
| フィルタ後 | 3000 |
| problem3除外後 | 2880 |
学習候補として、hidden=1536 と hidden=2048 を比較しました。
hidden=2048 は一部でシャープになる一方、色破綻やパターン混入が出ました。特にhybrid版では赤く偏る破綻が出たため不採用にしました。
最終的に、v6では hidden=1536 のhybrid版を採用しています。
現在できること
2026年6月14日時点では、次のことができるようになっています。
Apple Watch 11実機上でオフライン生成できる
クラウドに投げず、watchOSアプリ内で画像を生成できます。
Stable Diffusionのような巨大モデルは載せていません。実機確認では、メモリ使用量は30MB程度まで増えましたが、Apple Watch上では十分許容できる範囲でした。
128×128画像を生成できる
現在は128×128を実用候補にしています。
Apple Watch上の小さな表示領域では、128×128でも対象物が読めれば十分使えます。
学習済みカテゴリはかなり読める
特に、次のようなカテゴリは比較的安定しています。
cat
dog
fox
owl
fish
tree
star
face
cloud
train
heart
orange
bread
ice cream
fire
まだ荒さはありますが、「何を描こうとしているか」はかなり伝わるようになりました。
新カテゴリにも一部対応できる
v6では新カテゴリの反応がかなり増えました。
特に次のあたりは形が出やすいです。
alien
penguin
duck
key
bottle
crown
sword
shield
fire
ice cream
donut
短い自由入力に少し対応できる
完全な自然文ではありませんが、次のような短い組み合わせには反応できます。
blue bird
small fox sitting
floating cloud
front view clock
green alien walking
cute dragon flying
penguin sliding
striped umbrella
metallic sword tilted
transparent bottle
日本語エイリアスにも一部対応している
プロンプト正規化側には、日本語エイリアスも入れています。
猫
犬
赤い
青い
小さい
走っている
浮いている
宇宙飛行士
ペンギン
アイスクリーム
日本語の自然文を理解しているわけではありません。
ただ、既知語彙にマッチすればlatentに反映できます。
最新バージョンの実機生成結果
基本的には最新バージョンをApple Watch 11実機で動かした結果です。ただし、Face の例だけは重みのバージョンが少し違う実機結果です。
下の図は、実機スクリーンショットから生成画像部分を切り出して並べたものです。全体としてはまだぼやけや粒状感がありますが、短いプロンプトに対して、おおまかなシルエットや色の方向性は出るようになってきました。
図5: Car / Cat / Dog / Sun / Mountain / 宇宙飛行士 / Face の実機生成結果。高精細な画像ではないものの、Apple Watch上でオフライン生成した小さな画像としては、対象物の方向性が読み取れる段階まで来ている。
※Face のスクリーンショットは重みのバージョンが少し違うため、厳密な同一条件比較ではなく、Face プロンプトの挙動例として載せています。
今回のサンプルを見ると、得意なものと弱いものがかなり分かりやすく出ています。
| prompt | 見え方 | コメント |
|---|---|---|
Car |
横向きの車体として読める | 低解像度でも「車っぽい」横長シルエットが出ている |
Cat |
顔と胴体のまとまりが出る | 動物カテゴリは比較的安定している |
Dog |
四足動物の姿勢が出る | 細部は曖昧だが、犬らしい体の向きは見える |
Sun |
黄色い円と周辺の光が出る | 色と中心構造が強く出やすい例 |
Mountain |
山の三角形のシルエットが出る | 単純な形状は小型モデルでも比較的出しやすい |
宇宙飛行士 |
人型の中央シルエットが出る | 日本語エイリアスが既知語彙にマッチした例。 |
Face |
顔らしい明暗のまとまりが出る | 別重み版の例だが、顔カテゴリへの反応としては分かりやすい |
図6: 実機スクリーンショット全体。宇宙飛行士 の例は、UI表示だけ Face が残っていたものとして扱っている。
まだできないこと
一方で、まだできないことも多いです。
完全な自由入力プロンプトは理解できない
現在のprompt encoderは、CLIPのような自然言語理解モデルではありません。
そのため、次のような入力は苦手です。
a small red fox sleeping under a tree at night
a robot holding an umbrella in the rain
a cat wearing a crown next to a cake
単語単位では一部拾えますが、関係性や構文は理解していません。
複数物体の関係は描けない
現在の教師データは、基本的に「1枚に1対象」です。
これはApple Watch向けの小型モデルでは有効ですが、その代わり次のような表現は苦手です。
- 猫と犬
- 木の下の狐
- 傘を持つロボット
- 机の上の本
- 背景のあるシーン
複数物体を入れると、モデル容量に対して難易度が一気に上がります。
動詞や形容詞はまだ弱い
sitting、flying、floating などは一部効きます。
しかし、名詞ほど安定していません。
特に次のような語彙はまだ弱いです。
climbingspinningopentransparenttop viewfront viewstripedspotted
教師画像側では表現できていても、小型MLPへ蒸留するとかなり平均化されます。
画像はまだぼやける
現状でも、画像はかなりぼやけています。
主な理由は次の通りです。
- モデル容量が小さい
- 128×128を直接MLPで出している
- 教師画像に含まれる細かい背景ノイズ
- 小型モデルが高周波成分をきれいに表現しきれない
- ノイズを避けるために学習ターゲットを少し滑らかにしている
後処理でノイズ感は少し抑えられます。
ただし、構造そのもののシャープさは、学習とモデル設計で改善する必要があります。
新カテゴリを増やすと既存品質が落ちるリスクがある
v6ではカテゴリ数を46から75に増やしました。
新カテゴリへの反応は増えましたが、カテゴリ数が増えるほどモデル容量の奪い合いが起きます。
そのため、今後さらにカテゴリを増やす場合は、単純に追加するだけではなく、次のような工夫が必要です。
- 既存カテゴリを忘れないように混ぜる
- カテゴリごとの枚数を調整する
- 問題カテゴリだけcurated補強する
- 採用するカテゴリを絞る
- モデル容量を少し増やすか検討する
大きくすれば必ず良くなるわけではない
hidden=2048 も試しましたが、必ずしも良くなりませんでした。
一部はシャープになったものの、色が大きく偏ったり、pizza や orange のようなカテゴリでパターン混入が戻ったりしました。
今回の範囲では、hidden=1536 の方が安定していました。
これは、Apple Watch向けの小型生成では重要な教訓です。
モデルを大きくすればすべて解決するわけではありません。データ品質、カテゴリ数、語彙、後処理、実機メモリのバランスを取る必要があります。
図7: 拡散モデルは画質と自由度に強い。今回のtiny MLPは端末上の軽さに寄せている。
実装上のポイント
1. 端末上では小さく保つ
端末上で動くのは、座標MLPと軽いプロンプト正規化だけです。
重いSDXLやtext encoderは端末に載せていません。
2. 教師データはクラウドGPUで作る
教師画像の生成はRunPod上のRTX 4090で行っています。
v6では、SDXLで教師画像を作り、フィルタリングして、最終的に3000件程度の学習データへ絞りました。
3. 品質だけでなく多様性も残す
小型モデルでは、同じような教師画像ばかりを入れると、自由入力に弱くなります。
そのため、カテゴリごとに高品質画像を選びつつ、色・動作・形容詞・構図・スタイルのバリエーションも残しています。
4. 問題カテゴリは個別補強する
orange、pizza、bread は、教師画像がパターン化しやすいカテゴリでした。
そこで、これらはcuratedデータを別で作り、hybrid学習時に混ぜています。
このようなカテゴリ別補強は、今後も必要になりそうです。
5. 後処理は軽く入れる
生成後に、色差ノイズを中心に抑える軽い後処理を入れています。
これは超解像ではありません。
画像を高精細にするものではなく、背景のざらつきを少し抑えるためのものです。
Apple Watch上でも軽く動く範囲に収めています。
現在の成果物
現在採用しているモデルは、v6の hidden=1536 hybrid版です。
| 項目 | 値 |
|---|---|
| カテゴリ数 | 75 |
| フィルタ後データ | 3000 |
| problem3除外後 | 2880 |
| hidden | 1536 |
| latent | 64 |
| 出力 | 128×128 |
| 実機メモリ | 約30MB |
| 実機 | Apple Watch 11 |
実機では、以前より動物系と新規カテゴリの反応が良くなりました。
たとえば、次のような入力は比較的良い結果が出ています。
car
cat
dog
sun
face
mountain
astronaut / 宇宙飛行士
heart
fire
ice cream
train
alien
penguin
今後の方針
ここから先は、いくつか方向性があります。
方針A: データ品質をさらに詰める
最も堅実なのは、データセットの品質を上げる方向です。
具体的には次の作業です。
- カテゴリ別に教師画像を確認する
- パターン化しやすいカテゴリを特定する
- そのカテゴリだけプロンプトを調整する
- curated補強データを作る
- reject条件をカテゴリ別に変える
これは地味ですが、小型モデルではかなり効きます。
次にやるなら、まずこの方向が良さそうです。
方針B: 語彙をさらに増やす
新カテゴリや形容詞・動作語彙をさらに増やす方向です。
ただし、カテゴリ数を増やすほど既存品質が落ちるリスクがあります。
そのため、今後は一気に増やすより、テーマごとに小さく追加するのが良さそうです。
- 動物パック
- 食べ物パック
- 道具パック
- ファンタジーパック
- 乗り物パック
- 構図語彙パック
方針C: prompt UIを制限付きにする
完全自由入力を目指すより、UI側で少し制限するのも有効です。
たとえば、次のようなスロット式です。
subject: cat
color: white
action: sitting
style: cartoon
view: front
ユーザーには自然に見せつつ、内部的には既知語彙の組み合わせに落とします。
Apple Watchの画面サイズを考えると、完全な自由入力よりこの方が体験として安定する可能性があります。
方針D: モデル構造を少し変える
現在は座標MLPで直接RGBを出しています。
次の候補としては、次のような構造も考えられます。
- 低解像度をMLPで出して軽いアップサンプルを組み合わせる
- 小さなCNN decoderを追加する
- RGBではなく低周波成分と輪郭成分を分ける
- 後処理込みで学習する
- ノイズを抑える損失を追加する
ただし、構造変更は実機速度やメモリに影響します。
現状では、まずデータ品質を詰める方が優先度は高そうです。
まとめ
Apple Watch上で動く小型画像生成モデルとして、かなり制約の強い条件で進めてきました。
この取り組みのポイントは、Stable DiffusionをApple Watchに載せることではありません。
SDXLのような大きなモデルは教師画像作成に使い、実機上では座標ベースの小さなMLPだけを動かす、という分担にしています。
現時点でできることは次の通りです。
- Apple Watch 11実機で128×128画像を生成できる
- メモリ30MB程度で動く
- 学習済みカテゴリはそれなりに読める
- 新カテゴリにも少し対応できる
- 色・動作・形容詞・構図語彙も一部反映できる
- 軽い後処理でノイズ感を少し抑えられる
一方で、まだ次の課題があります。
- 完全な自由入力は難しい
- 複数物体や関係性は描けない
- 動詞・形容詞・構図語彙はまだ弱い
- 画像はまだぼやける
- カテゴリを増やすと既存品質が落ちるリスクがある
ここまでの結果を見る限り、次の一手は「さらに大きいモデルにする」よりも、「データ品質をカテゴリ別に詰める」方向がよさそうです。
特に、パターン化しやすい食べ物系、構図語彙、動作語彙を個別に改善していくと、実機での体験はまだ伸ばせそうです。






