「同じ子」のはずなのに、顔だけ毎回ちょっと違う
画像生成AIで、お気に入りのキャラを何枚か作ってみたことはないですか? 服装や髪の色、全体の雰囲気はちゃんと揃っているのに、顔つきだけ毎回ほんの少し変わる。「あれ、さっきの子とちょっと別人っぽい?」と感じる、あのモヤモヤです。
別ポーズや別の構図がほしくて条件を少しいじると、とたんに顔が揺れる。服はそのままなのに、顔だけが言うことを聞かない感じがします。
「種(seed)を固定すれば同じになる」、でも
このあたりを触っている人なら、「seedを固定して同じプロンプトを入れれば、ほぼ同じ絵が出る」のは知っているわけですが、本当に面白いのはその先です。
同じキャラで別のポーズや表情がほしいとき、自分たちは結局、seedを振ったりプロンプトを少し書き換えたりします。つまり「まったく同じ絵」ではなく「同じキャラの別カット」がほしい。ところがそこで条件を少し動かしたとたん、服や髪は揃っているのに顔だけがズレる。ここで一つ不思議が出てきます。なぜ、揃うところと揺れるところが分かれるのでしょう。同じ一つのプロンプトで指定したはずなのに。
言葉は「一点」ではなく「広さ」を指している
ここを、数学の言葉で解釈できるかやってみましょう。
カギになるのは、プロンプトという言葉が画像の何を指しているか、という見方です。直感的には「このプロンプト = この一枚の絵」と一対一で結びついていそうな気がします。でも、そうではなさそうなのです。
AIの内部には、ありとあらゆる画像が住んでいる「広大な地図」のような空間があります。ここで言っている「地図」は、実際にはモデル内部の高次元の潜在ベクトル空間(潜在空間)だと思ってください。この地図そのものの話は、以前の記事で書きました。

プロンプトはこの地図の上で、条件に合う絵が集まっているエリアを指している、と読めます。

「銀髪・赤い上着・笑顔」と指定すると、その条件を満たす絵はこの地図の上にひとかたまりの領域として存在します。AIはそのエリアの中から一枚を選んで描く。だから、エリアの中で「どこを選ぶか」がそのつど変われば、出てくる絵も少しずつ変わる。同じキャラの別カットを作るために条件をいじると、エリアの中の選ぶ場所が動いて、顔の座標も一緒に動いてしまう、というわけです。
「揃う属性」と「揺れる属性」が分かれる理由
面白いのは、このエリアの「広さ」が、属性ごとに違うことです。
「赤い上着」のように言葉でしっかり指定した特徴は、それを満たさない絵がエリアから外れるので、エリアはその方向に狭くなります。狭いところからどこを選んでもだいたい同じ。だから服は揃う。
一方、顔の細かいつくり、たとえば目の間隔、輪郭のわずかな丸み、鼻筋の角度は、プロンプトでいちいち全部を指定できません。指定が薄い特徴については、エリアがその方向にぐっと広いままになります。広いエリアの中から毎回ちがう場所を選べば、顔つきはそのぶん大きく揺れる。
ただし、どの属性が揃いやすく、どの属性が揺れやすいかはモデルや学習データによって変わります。多くのモデルでは服や髪色のように言葉で指定しやすい特徴は比較的揃えやすい一方、顔IDや微妙な造形は揺れやすいことが多い、くらいに見ておくのが安全です。

同じ「近いけど違う」という現象は、おすすめ欄でも顔を出します。条件に近いエリアの中から拾ってくるからこそ、近いのにピタリ同じではない。その話は、こちらの記事で扱っています。

指定の強い方向は狭く、弱い方向は広い。この非対称が、揃うところと揺れるところを分けています。
式にして見てみる
この「言葉はエリアを指す」という話を、短い式に書き直してみると、こう読めます。
$$ x \sim p(x \mid c) $$
記号をそのままほどきます。$x$ は出てくる一枚の絵。$c$ は自分たちが与えた条件(プロンプト)です。真ん中の縦棒「$\mid$」は「〜のもとで」。そして左の「$\sim$」は 「イコール」ではなく「この範囲からくじを引く」 という意味です。
この $p(x \mid c)$ を、条件 $c$ のもとでの $x$ の条件付き確率分布と言います。
つまりこの式は「条件 $c$ のもとで、ありうる絵 $x$ を一枚くじ引きする」と言っているだけです。$c = x$ という一対一ではなく、$c$ が決めるのはくじの箱の中身(どんな絵がどれくらいの濃さで入っているか)のほう。箱の中には条件に合う絵がたくさん入っていて、引くたびに違う一枚が出る。
ここで極端な場合を入れてみると、見通しがよくなります。もし条件 $c$ が顔のすみずみまで完全に指定しきっていれば、箱の中身は実質一枚だけになり、引いても引いても同じ顔が出ます。逆に、顔について $c$ がほとんど何も言っていなければ、箱の中の顔はバラバラで、引くたびに別の顔が出る。現実はこの中間で、服のように強く指定した方向は箱が薄く(揺れない)、顔の細部のように指定が薄い方向は箱が分厚い(揺れる)。同じ一つの箱の中で、方向によって分厚さが違う、ということです。
持ち帰り
そう考えると、顔が揺れるのは「AIが雑だから」ではなく、自分の出した言葉が、地図の上で思ったより広いエリアを指していたからだと読めてきます。つまり顔を固定したければ、顔のくじ箱を薄くしてやればいい。顔の特徴を言葉でもっと細かく縛る、参照画像で範囲を絞る、といった方向です。さらに踏み込むなら、LoRAのように特定キャラの特徴をモデル側へ寄せる方法も、この直感の延長にあります。
言い換えると、「同じキャラを保つ」とは、地図の上のエリアを自分の手でどこまで狭く描けるか、という勝負なのかもしれません。次に顔が揺れたとき、その揺れ幅は、自分が言葉でどれだけ狭くエリアを指定できたかの通知表だと思って眺めてみると、ちょっと面白くないですか?
