こんにちは、パレイド技術部の夏目です。前回、この連載は「応用編」として一区切りつけたつもりでした。ただその後、GNM Head の中に、地形フィットを経由しない別の入口があることに気づきました。今回はその入口を使って、「誰の顔か」と「どんな口の形か」を直接操作する検証記録です。
第 1〜3 回で使ったのは、地形メッシュを 253 次元の identity 空間に最小二乗で投影する経路でした。GNM Head にはもう一つ、性別・民族・表情のラベルを直接指定して顔を生成する CVAE(条件付き変分オートエンコーダ)のデコーダが同梱されています。地形を経由しない分、こちらは「誰か」と「どんな表情か」を単独で振れます。
本記事はローカル LLM による自動執筆パイプラインで生成されました。現段階ではクラウド AI(Claude 等)の補助や人間の編集が介在していますが、pareido.jp では最終的に AI が自律的にコンテンツを制作できる仕組みの構築を目指しています。
「誰か」を選ぶ ── gender × ethnicity の 8 パターン
identity 側のデコーダは、性別 2 クラス(Female / Male)と民族 4 クラス(Middle Eastern / Asian / White / Black)をラベルとして受け取り、それに条件づけた顔を潜在空間からサンプリングします。組み合わせは 8 通り、同じ乱数シードを固定すれば毎回同じ顔が再現できます。

第 1〜3 回の「地形に最も近い顔を最小二乗で解く」経路とは、使っているモデルの部分が違います。あちらは地形という入力ありきの投影で、こちらはラベルだけを与えて生成する経路です。同じ GNM Head パッケージの中に、目的が違う 2 つの顔の作り方が同居している、という整理になります。この 8 パターンは幾何のレンダリングだけで、img2img には回していません。次の表情側と違って、ここでは特につまずきはありませんでした。
母音の口を作る ── expression で 8 状態のビゼームを作る
同じデコーダの仕組みは、表情側にも使えます。GNM の expression には 20 種の意味ラベル(SMILE_WIDE、PUCKER、STRETCH_FACE など)があり、単独または複数を混ぜて 1 つの表情ベクトルを作れます。これを使って、日本語の母音(あ/い/う/え/お)+まばたき+無表情の 8 状態を作るのが今回の題材です。
以前の検証では、2 つのラベルを混ぜるとブレンドが打ち消し合って変化が小さくなりすぎることが分かっていました。そこで単一ラベル+スケールの形に絞り、さらに前日の検証で「口の開きが急すぎて崩れた」という反省を踏まえ、スケールを全体的に控えめにしました。
| 状態 | ラベル | スケール |
|---|---|---|
| 無表情 | なし | – |
| まばたき | WINK_LEFT+WINK_RIGHT(1:1) |
1.0 |
| 開口 | SURPRISE |
0.6 |
| あ | STRETCH_FACE |
0.7 |
| い | SMILE_WIDE |
0.6 |
| う | PUCKER |
0.8 |
| え | SMILE_WIDE+STRETCH_FACE(0.6:0.4) |
0.9 |
| お | FUNNELER |
0.7 |

幾何のレンダリングだけを見れば、8 状態はちゃんと見分けがつきます。ここまでは狙いどおりでした。
小さくしたはずが、また崩れた ── パッケージ消失と、denoise と髪のトレードオフ
作業を始めてまず引っかかったのは、検証コード自体でした。前回の表情実験はその場限りのコードで動かしていたためスクリプトとして残っておらず、しかも GNM 本体のパッケージが /tmp 配下に置かれていたせいで、Mac の再起動か何かで消えていました。今回はリポジトリの vendor/(.gitignore 済み)に固定し直し、検証コード自体もスクリプトとして書き起こしました。同じ轍を踏まないための後始末です。
スケールを控えめにした後も、SMILE_WIDE のスケールを 1.0 のまま使うと、口を開けた部分の歯茎境界がギザギザに露出するレンダリング崩れが残っていました。歯・舌の三角形を除外するだけでは防げず、開口量そのものを絞る必要があるということです。0.4〜0.7 で比較すると、0.7 から崩れが出始めます。

ここで新しい問題に気づきました。GNM Head には髪の頂点グループが存在しないため、レンダリングは常に坊主頭です。以前の検証では img2img が髪を描き足していたので気にしていませんでしたが、denoise 0.6・ControlNet 強度 0.8(母音の区別を保てる設定)のままだと、プロンプトに髪型を書いても坊主のままでした。denoise を 0.75 まで上げると髪は生えるものの、まばたきは開いた目に戻り、母音の口の形もほぼ無表情に均されてしまいます。

つまり今回の「変化を小さくする」修正は、幾何のレンダリング段階では効きましたが、img2img に渡した時点で「表情を保つ設定」と「髪を生やせる設定」が両立しない、という前日とは別の壁に当たった形です。どちらも denoise と ControlNet 強度という同じ 2 つのつまみで綱引きしているので、値を振るだけでは片方を立てればもう片方が崩れます。
まとめ / 次回に続く
今回の切り分けをまとめます。identity 側の 8 パターンはラベル指定だけで安定して動き、幾何レンダリングの範囲では問題がありません。expression 側も、スケールを控えめにすれば 8 状態は幾何として見分けがつくところまでは持ち込めました。ただし img2img のスタイル付け(今回は髪)を同時に求めると、denoise と ControlNet 強度の同じ調整幅の中で表情と髪が奪い合いになるという、前日までの検証では見えていなかった制約が新たに見つかりました。
次回は、この綱引きを 1 回の生成で片づけようとせず、口の形を保つ低 denoise の生成と、髪だけを別途足す局所的な処理を分離できないかを試すつもりです。