線画のOYAJIくんが自分の声で喋った──原画131枚と「存在しない声」で作る音声つき動画LoRA、うまくいったことと半分しか効かなかったこと

テクノロジー

このブログのマスコット、OYAJIくんをご存じでしょうか。ハゲ・丸メガネ・無精ひげ・黒Tシャツの線画のおじさんで、前作の記事で画像生成のLoRAを作り、これから当ブログの挿絵に使っていこうと思っています。ただ、静止画です。喋りません。動きません。

一方、この1週間は顔も声も存在しない人物を動画AIに覚えさせる話と、その改善編を書きました。LTX-2.3という映像と音声を同時に生成するモデルに、写真のような人物と設計した声を覚えさせる話です。実写風の人物で手順を固めたのは、本命のOYAJIくん作成の練習だったからです。線画のOYAJIくんを、自分の声で喋らせたい。

線画は写真と勝手が違います。顔検出が効かない、口が数本の線でしかない、白背景に黒い線だけなので「実写要素が混入すれば失敗」。どちらかと言えば実写向きの動画生成モデルで線画を動かす方が難しいはず。また、実写で作った検品の道具が半分使えません。この記事は、それでも1日でOYAJIくんが喋りだすまでと、欲張ってカメラを動かそうとして半分しか効かなかったところまでの記録です。

まず結果をどうぞ

「どうも、ギークオヤジです。」線画のまま手を振って、自分の声で名乗ります。台詞は音声認識で全文一致。線画アニメの口パクとしては、これぐらいで十分ではないでしょうか
「この動画も、家のパソコンで作りました。」学習に使っていない台詞です。声の類似度は設計した声のお手本に対して0.80

比較として、LoRAを外して同じプロンプト・同じseedで生成したもの。トリガー語の「oyajikun」を知らないので別人が出てきますし、声も別人です。

LoRAなし。線画のおじさんは出ますが、OYAJIくんではありません。声の類似度は0.20。LTX-2.3は「日本人の中年男性」までは知っていますが、彼のことは知らない
「失敗した動画は、消さずに残しておきます。」これも未学習の台詞。マグカップを持って、ちゃんとOYAJIくんの顔で喋ります

映像と音声は1回の生成で同時に出ています。声を後から合成して口を合わせたのではなく、モデルが「OYAJIくんの絵」と「OYAJIくんの声」を一緒に覚えた結果です。

線画は動画に乗るのか(Step 0)

実写での経験があるとはいえ、線画のキャラを音声つき動画モデルに学習させた例は、探した範囲では見つかりませんでした。だから最初にやったのは、いきなり本番のデータを作ることではなく、そもそも成立するのかを最小の手数で確かめることでした。

原画を見直す

素材は前作で作ったOYAJIくんの原画138枚です。着手前に本人(私)から一言ありました。「画像生成のときは、線が途中で切れていたり形が崩れている絵も成功扱いにしていた気がする。動画に入れるなら除いた方がいい」。Claudeに138枚を全部見直させたところ、7枚を除外しました。頭が異常に大きいチビキャラ比率、空中にもう1つ浮いているグラス、画面端から出てくる胴体のない手、モニターの中にもう1人映っている本人。画像生成では「面白い失敗」で済んでいたものが、動画の学習データでは「そういうキャラ」として覚えられます。

残った131枚の一部。黒Tシャツの胸に「OYAJI」と書いてありますが、これはキャプションに書きません。「書かれていない共通要素はトリガー語に焼き付く」を、今回はわざと使います
残った131枚の一部。黒Tシャツの胸に「OYAJI」と書いてありますが、これはキャプションに書きません。「書かれていない共通要素はトリガー語に焼き付く」を、今回はわざと使います

キャプションの方針は実写のときと逆にしました。実写では「眼鏡・髪・年齢を書くな」でしたが、今回はハゲ・丸メガネ・無精ひげ・黒Tシャツ・黒短パン・胸のロゴを書かない。全部トリガー語「oyajikun」に焼き付けたいからです。代わりに画材は必ず書く。「a black-and-white line drawing with bold ink lines and no color」。これを書かないと、LTX-2.3は勝手に陰影を付けたり色を足したりします。向き・ポーズ・表情・小道具・場面・漫画記号(動線、強調線、汗、zzz、吹き出し)は、あれば必ず書く。前作で「書かれていない動線が全部の絵に出てくる」をやらかした反省です。

素のLTX-2.3と、静止画だけのLoRA

まず、LoRAなしのLTX-2.3が線画を5秒間保てるかを見ました。保てました。黒Tシャツの線画の男性が白背景で手を振り、口を動かします。ただし画風は写実寄りで、OYAJIくんの丸い漫画調ではない。画風の維持は本体が持っている。同一性と漫画調はLoRAの仕事、と切り分けられました。

そこで、まず原画131枚だけで静止画のLoRAを作りました。音声なし、2600ステップ、1時間35分です。動画モデルに静止画だけを学習させるのは変な感じがしますが、「OYAJIくんという絵柄」を覚えさせるには十分で、動きは本体が補います。

同じプロンプト・同じseedで、左2枚がLoRAなし、右2枚が静止画LoRA。上着を着ていない別人、腕組みの怖い人、実写の商店街が、全部OYAJIくんになります。歩きも怒りも本体の動きのまま
同じプロンプト・同じseedで、左2枚がLoRAなし、右2枚が静止画LoRA。上着を着ていない別人、腕組みの怖い人、実写の商店街が、全部OYAJIくんになります。歩きも怒りも本体の動きのまま

問題は「OYAJIくんかどうか」をどう測るかでした。実写では顔認識モデル(FaceNet)で顔の一致を数値にしていましたが、顔認識は線画の顔を顔と認識しません。口パク検査に使っていたMediaPipeも全滅。代わりに、画像の埋め込み(CLIP)で「原画131枚の中で一番近い5枚との類似度」を測る指標を作りました。10通りの計算方法を「原画同士(正解)」と「素のLTXが描いた線画のハゲ眼鏡の男(意地悪な不正解)」で較正して、一番よく分離したものです。それでも差は薄く、正解の下位10%が0.839、不正解の上位10%が0.800。しきい値0.82は粗いふるいとして使い、最後は目で見る前提です。

チェックポイント同一性(12プロンプト平均)0.82以上
LoRAなし0.7361/12
epoch 40.8268/12
epoch 120.8389/12
epoch 200.8167/12

epoch 4では半分が「髪のある少年」でしたが、epoch 8以降は12本全部でハゲ・丸メガネ・無精ひげ・黒Tシャツが出ます。カメラの寄りも、商店街を歩いて寄ってくる後退追従も出ました。弱点は「夕日の海」と書くと空が橙色になること。キャプションの「色なし」より、本体の常識が勝ちます。

ここまでで、線画は動画に乗る、口も動く、カメラ語もある程度効く。Step 0は合格。ここで初めて、本番のデータ作りに進みました。

声を設計する

OYAJIくんの声は存在しないので、実写のときと同じくQwen3-TTSのVoiceDesignで文章から作ります。6種類の指示文を書き、それぞれ2テイクずつ生成して聞き比べました。

指示文の要約
A五十代の日本人男性、温かくややガラガラした中低音、急がず、自虐ユーモア、ビール片手に技術を語る親戚のおじさん
B深く落ち着いたバリトン、ドキュメンタリーのナレーション風
C明るくおどけた声、コメディのタイミング、テンション高めのブロガー
Dハスキーで少し疲れているが優しい、深夜ラジオのDJ
E鼻にかかったコミカルな声、趣味ブログのマスコット
Fテレビのアナウンサー風の明瞭なバリトン

1回目の生成では、台本にあった「五十路」を12本中10本が「ごじゅうろ」と読み、1本は笑い声のループで崩壊しました。台本を「いそじ」とかな書きにして作り直し。選んだのはAです。ビール片手に語る親戚のおじさん。本人に一番近いからではありません。マスコットに合うからです(震え声

選んだ声をお手本にして、ブログの話題で書いた台本50行をクローンしました。「今日は、新しいグラフィックボードの話をします」「五十肩が痛いので、今日は早めに休みます」「失敗した動画は、消さずに残しておきます」。読み間違えやすい語はかな書きにしてあります。この「かな書き」が後で効いてきます。

喋るクリップを作る

学習データの作り方は実写と同じです。原画1枚と台詞の音声をLTX-2.3に渡し、口パク動画を作る。ただし線画ならではの違いが2つありました。

1つ目は種画像の形です。原画は正方形、動画は16:9。実写では顔を中心に切り抜きましたが、線画は白背景なので白で左右を足すだけでいい。最初は中央で切り抜いて全身の絵の頭が画面外に出て崩壊しましたが、パディングにしたら解決。線画は切り抜き要らずです。

2つ目は顔ゲートです。実写では「生成された顔がマスターと一致するか」を顔認識で検査し、外れたら種画像を差し替える仕組みでした。これが線画では顔を検出して全部不一致と判定し、42本全部の種画像を先頭の1枚に差し替えてしまった。気づいたら、40本が同じ「腰に手・吹き出し・草」の構図でした。口は動いているし同一性も0.9と良好なのに、構図が1種類。これで学習したら「OYAJIくんは常に腰に手」が焼き付きます。顔ゲートを外して作り直しました。

作り直した会話クリップ。座って、伸びをして、リクライニングして、それぞれの構図で口が動きます。上の1本目が実際の学習データです
作り直した会話クリップ。座って、伸びをして、リクライニングして、それぞれの構図で口が動きます。上の1本目が実際の学習データです
学習データの1本。原画(木の床に立つ)+クローンした声「新しいグラフィックボードが届きました」→LTX-2.3の口パク生成。これが36本

口が動いているかの検査は、MediaPipeが使えないので目視です。42本の「口の周りだけ」を並べたシートをClaudeが作り、翌朝に私が見ました。ここで面白いことが起きました。私が「顔がフレームから外れている」と判定した3本は、全フレームで確かめると顔は画面内で口も動いていた。口の周りを自動で切り出す窓が、口以外の場所に付いていたのです。判定は必ず全体のフレームで、が教訓。

もう1本、私が見つけた本物の問題がこれです。

振り返ると別人。種画像が後ろ斜めからの絵で顔がほぼ見えないのに、「カメラに向かって話す」と指示したので、LTXが顔をでっち上げました。角眼鏡、細い目、別の髪型
振り返ると別人。種画像が後ろ斜めからの絵で顔がほぼ見えないのに、「カメラに向かって話す」と指示したので、LTXが顔をでっち上げました。角眼鏡、細い目、別の髪型

原因は前作にありました。この原画のタグに「from behind(後ろから)」が付いていなかったため、キャプションに視点の記述がなく、会話クリップの種画像として除外されなかった。前作の記事で「キャプションに書かれていない要素は焼き付く」と書きましたが、書かれていない要素は、検品もすり抜けます。この1枚はキャプションを直し、クリップは除外。最終的に35本を採用しました。

学習と結果

データは会話クリップ36本(このときはまだ35本になる前)を3回ずつ繰り返し、原画131枚を音声なしの静止画として足して、1エポック239サンプル。レシピは実写のv4と同じ(rank 32、片方向ブロックスワップ)で、まず2600ステップ。2時間22分です。

声の類似度(青)と線画の同一性(赤)の推移。未学習の台詞4本を含む6本の平均。声は2400ステップ前後で頭打ち、同一性は3300〜4300で最も高く、その後は両方下がる
声の類似度(青)と線画の同一性(赤)の推移。未学習の台詞4本を含む6本の平均。声は2400ステップ前後で頭打ち、同一性は3300〜4300で最も高く、その後は両方下がる

2600ステップ時点で声はまだ上がっていたので、学習状態から5200ステップまで継続しました(2時間43分)。結果、声は2400前後で頭打ち、同一性は3300〜4300が山で、その先は両方下がる。両方が一番良い4302ステップを採用しました。

観点採用 step 4302参考
声の類似度(平均 / 最低)0.75 / 0.62声のクローン自身がお手本と0.60、LoRAなしのLTXは0.20
読みの正確さ(文字誤り率)0.02実写v4は0.13〜0.30
線画の同一性(平均 / 最低)0.88 / 0.86LoRAなし0.74
彩度(色が付いていないか)0.001実写フレームは0.3前後

声の0.75は実写v4の0.83より低い数字ですが、この男声はクローン同士でも0.60しか一致しない、ばらつきの大きい声です。0.75は「OYAJIくんの声の帯」の中にいます。

意外だったのは読みの正確さです。実写では未学習の台詞を1〜3割読み間違えましたが、今回は0.02。台本をかな書き寄りにした効果と見ています。「五十路」を「ごじゅうろ」と読んだTTSの失敗が、結果的に台本全体を読みやすくしてくれました。

線画のOYAJIくんが、自分の声で喋る。実写のときに揃えた手順と道具のおかげです。

欲張ってカメラを動かした(v2)

会話クリップは全部固定カメラなので、このLoRAを使うとカメラが動きにくくなります。実写のv2〜v4で経験した「固定カメラの焼き付き」です。実写のときは、台詞なしのテキストからの生成でカメラが動くクリップを24本作り、音声を抜いて2割混ぜたら、カメラ語の効きが6倍になりました。同じ手を線画でも打ちました。

採用したカメラ移動クリップの一部。寄り、引き、廊下の後退追従、本屋の横追従、足元から顔へのティルト、俯瞰へのクレーン。全部、台詞なし・音声なしの映像だけのサンプルです
採用したカメラ移動クリップの一部。寄り、引き、廊下の後退追従、本屋の横追従、足元から顔へのティルト、俯瞰へのクレーン。全部、台詞なし・音声なしの映像だけのサンプルです
「slow dolly-in: the camera pushes forward from a full-body shot to a close-up of his face」。全身から顔まで寄ります。線画でも寄り・引きはほぼ確実に出ました(11本中11本)
「lateral tracking shot: the camera glides sideways with him, bookshelves passing behind him」。横顔で本棚の前を歩き、本棚が流れます。顔認識ならぬ「線画認識」の指標では落第でしたが、目で見て救済

ここで線画ならではの改良が1つ。実写のとき、寄り・引きのズームは「フレーム差分」にも「全体のシフト」にも映らず、動いているのに「静止」と誤判定されて3本を手で救済しました。今回は特徴点から拡大率を推定する指標を足し、寄り・引き11本を全部自動で拾えました。線画は特徴点が取りやすいので、こういう指標が素直に効きます。

24本生成して20本を採用。会話35本×3、カメラ20本×3、原画131枚で1エポック296サンプル、5400ステップ、7時間14分。実写v4のときの「2割の対照データ」と同じ比率です。

結果:半分しか効かなかった

カメラ語の効き。同じ場面・同じseedで「static camera」と「push-in / tracking / hand-held」を書き分けたときの差。LoRAなしは+11.65、v1は+3.41、v2は最良のepoch 16でも+4.82
カメラ語の効き。同じ場面・同じseedで「static camera」と「push-in / tracking / hand-held」を書き分けたときの差。LoRAなしは+11.65、v1は+3.41、v2は最良のepoch 16でも+4.82
観点v1 (4302)v2 epoch 16v2 epoch 18
カメラ語の効き(動き / シフト)+3.41 / +60px+4.82 / +88px+3.25 / +25px
声の類似度(平均 / 最低)0.75 / 0.620.70 / 0.560.76 / 0.69
線画の同一性0.880.860.86
色漏れ(彩度の最大)0.0040.0210.028

改善はしました。しかし実写のときの「6倍」とは程遠い。ペア別に見ると、寄り・引き・ティルトはv1でもv2でも動き、後退追従・横追従・手持ちはどちらでも効かない。そして5000ステップ台では、線画のはずのビールジョッキが黄色く塗られたクリップが出始めました。彩度の数字は小さいですが、v1では皆無だった現象です。

原因は、たぶんデータの比率です。実写v4で音声なしの静止画は13枚(1割強)でしたが、今回は原画131枚が1エポックの44%を占めています。131枚の静止画が「動かない構図」をトリガー語に強く結び付けていて、カメラ20本(2割)では剥がし切れなかった。同じ手を打っても、データの地形が違えば効き方が違う。

判断は、既定はv1の4302のまま。v2は「線画では静止画の比重を下げないとカメラは剥がれない」ことを教えてくれた実験として、候補を保管しました。次に直すなら、原画を非正面の40枚程度に絞って静止画を15%まで落とし、追従・横追従・手持ちに寄せたカメラクリップ(すでに第2バッチ24本を作って17本を採用済み)を足して、色漏れが出る前の4300ステップ前後で止める。ただし学習に7時間かかるので、しばらくはv2で色々生成して課題を貯めてから、まとめて直すことにしました。

人間がやったこと、AIに任せたこと

工程人間(私)Claude Code
進め方「T2I LoRAを直してから? データ準備から?」と相談し、Step 0から始める案に同意実現性確認 → 声 → 会話 → カメラ → 学習、の段取り提案
原画「崩れた絵は除いた方がいい」138枚の全数目視、7枚除外、キャプション131本の全文レビュー
6案を聞いてAを選ぶ。ローマ字台本の読みチェック指示文6案の設計、読み違えの修正、50行のクローン生成
会話クリップ翌朝、口シートを見て採否。0028の「振り返ると別人」を発見42本の生成、顔ゲート事故の復旧、全フレームでの再確認
学習・評価「4302を採用」2600→5200の継続、全チェックポイントの自動評価
カメラ「進めてください」線画用ゲート(拡大率つき)、48本の生成と37本の選別、v2の学習と評価、v1維持の提案
次の判断「いったんv2で色々生成して、課題が見つかったらまとめて改善」──

今回の人間の手柄は2つ。「崩れた絵を除け」と、「振り返ると別人」を目で見つけたことです。どちらも数値には出ていませんでした。同一性の指標は0028を0.87で通していました。指標は指標が測るものしか測らない。目で見る工程を、私はまだ手放せません。

正直、気になっていること

  • カメラは半分しか効いていない。寄り・引きは効くが、追従・横追従・手持ちは効かない。静止画の比重を下げる再学習が要る
  • 5000ステップ台で色が漏れる。白黒の縛りが緩む前に止める必要がある。線画LoRAの過学習は「顔が崩れる」より先に「色が付く」で現れるのかもしれない
  • v2は構図が広くなった。カメラ指示のないプロンプトでも全身寄りの絵が出る。全身から始まる寄り・引きのクリップの影響。顔が小さい分、口パクが見えにくい
  • 声の最低値が0.6台。「どうも、ギークオヤジです」のような短い一文で毎回下がる。短い発話は指標が不安定なのか、声が乗り切らないのか、まだ切り分けていない
  • 線画の口は数本の線なので、口パクの自動検査がない。目視の負担がそのまま残っている

まとめ

  • 線画のキャラは音声つき動画モデルに乗る。原画131枚の静止画LoRAで絵柄を覚え、口パククリップ36本で声を覚える。実写と同じ手順で、丸1日
  • キャプションは実写の逆。キャラの特徴は書かずに焼き付け、画材(白黒・太い線・色なし)は必ず書く。書かないと本体が色を足す
  • 線画には顔認識も口検出も効かない。画像埋め込みの近傍5で同一性を測り、較正してから使う。それでも最後は目
  • 種画像は白パディングで16:9に。切り抜くと頭が飛ぶ
  • 顔が見えない原画を会話の種にしない。振り返った先が別人になる。キャプションに視点がないと検品もすり抜ける
  • 台本はかな書き寄りに。読みの正確さが実写の数倍良くなった
  • 実写で効いた手が、線画では半分しか効かなかった。静止画が44%を占めるデータでは、2割のカメラクリップでは固定カメラが剥がれない。同じ手でも、データの地形を見て打つ
  • 線画LoRAの過学習は色漏れで現れる。白黒の縛りが緩む前に止める

前作の記事の最後に「OYAJIくんに喋らせたい」と書き、実写の記事でも「次こそ線画のOYAJIくん」と書きました。ようやく、喋りました。まだ寄ったり引いたりしかできませんが、ビール片手に技術を語る親戚のおじさんの声で、「失敗した動画は、消さずに残しておきます」と言ってくれます。

この記事の挿絵も、そのうち動きだすかもしれません。五十路の実験は、まだ続く。

コメント

タイトルとURLをコピーしました