Danbooruタグで遊んでる

plat
·
公開:2023/12/17

なんも考えないで描いてるので多分文章読みずらいと思う。

tl;dr

  • プロンプトを自動でマシマシしてほしい

    • ランダムはちょっと微妙かも

    • LLMでプロンプト生成したい!

  • データセットのフィルタリング、大事

  • danbooru タグ to 自然言語をやりたい!

画像生成するときのプロンプト考えるもそれはそれで楽しいし、最初はそれだけで無限に時間溶かすことができたけど、最近は自分のイメージしてないものが出てきて欲しい感もあったりする。

なのでDanbooruタグを自動生成できるようなLLMを作ったりしていたりする。(↓は前に公開したやつ。あとでもう少し詳しく話す)

プロンプト生成の他の事例

プロンプトの自動化、というと既に色々な例がある。↓は、かなり最初期に出た midjourney のプロンプトを自動化するもの。ベースは GPT-2 (GPT-2 はとっても小さいものもあるのでファインチューンしやすい)

最初期だからといっても侮れない。

割と筋が通ったプロンプトが出てくる。midjourney 仕様なので --ar 16:9 付きである。

この「筋が通っている」ということはプロンプトを補完する上で重要な点だと思う。

和風の雰囲気が欲しいのに、突然サイバーパンク要素を突っ込まれたら混乱してしまう。(そういうカオスを求めているならもちろん良いが、欲しくない時にはそうなって欲しくない)

プロンプトを補完するというアイディアも含めて、かなり面白い先行事例だなと思っている。

danbooru タグで学習されたプロンプト生成モデル

これは最近知ったのだが、元WDチームの salt さんが作っていた GPT-neo 125M ベースのモデル。このモデルではタグをシャッフルして学習していたらしい。(そんなに性能は良くなかったらしい)

NAIのランダムプロンプト

イラストを学習、生成するときのスタンダードになりつつある Danbooru タグ。個人的にはかなり表記揺れを抑えられて非常に素晴らしい仕様だなと思っている。(特に、「正座」のような英語訳が長ったらしくなったり言いにくいものを「seiza」と統一して表現できることは本当に良い)

1girl, chibi, seiza, =_=, kimono,

画像は NAIDv3 による 「1girl, chibi, seiza, =_=, kimono」。このプロンプトの過半数のタグは日本語由来だが、もはや慣れきって違和感を感じないレベルに自然。

NAIDv3 は本当にタグへの理解が強くてすごいのだがそっちは一旦置いておいて、NAIDv3のついでに追加されたランダムプロンプト機能について

なんも考えたくない時に便利である。適当にぽちぽちしているとそれっぽいプロンプトが出てくる。詳しくは見ていないが、これは通信を介していないのでブラウザ上の JavaScript で完結していると思う。

このランダムなプロンプトは筋が通っているのだろうか?という問題がある。上の画像を含めていくつかランダムなタグを翻訳してみてみる。(ニッチなタグも出てくるので)

画像のやつ

画像のやつ

少女、風景、森、ベランダ、上半身、蛇のモンスターガール、固形で楕円の瞳(chibiに多い目の描き方)、超長い髪、おでこ、ルーズソックス、ブラウス

カオスであるが、それ以上にプロンプト同士に矛盾が発生しているのが気になる。上半身指定の場合はルーズソックスは映らない (脱いだものかもしれないが、この少女は蛇なので足はない)し、超長い髪の条件を満たすことが難しい(髪の長さが身長くらい必要) なのでちょっと混乱する。生成画像は↓

上半身指定とルーズソックスが無視された。というように、ちょっと矛盾があるといい感じになってくれない。

他にも試してみる。

no humans, concept art, nature, shade, hallway, brick wall, bath, skeleton, mushroom, maple leaf

人間なし、コンセプトアート、自然、影、廊下、レンガの壁、風呂、骸骨、きのこ、紅葉

風景だけならまだ理解の及ぶ範囲だ。秋に、元屋敷の廃墟の壁が崩れてキノコが生えたり周囲が草に覆われ自然に溢れた感じなっており、さらに風呂場にいる骸骨が見えている状態を表したコンセプトアート、と想像ができる。かなり脳内補完したが、生成するとどうなるだろうか?

私の想像していたものとはちょっと異なる感じなったが、雰囲気は良い。風呂と紅葉要素が薄い感じがある。

という感じで、想定外が出てくるもの楽しいものではあるが、矛盾が発生しやすい点がある。

上半身を指定したら足に関する情報は欲しくないし、風呂 (bath, 浴槽) を指定したら浴室 (bathroom) も入れて欲しい(森の中に浴槽単体は謎...)とか、ちょっと物足りない部分がある。

それでも `no humans` の時には `1girl` は出なかったりするので、カテゴリでいくつか分類してバッティングしないようにして、あとはランダムでいくつか選ぶ、みたいな感じなのかもしれない。

ランダムに選ぶときの難しさは、要素の特性の食い違いやそういう事前の分類とか選び方を考えることにありそう。

上半身を指定していても、下駄箱だったら画面に写って靴のタグはつくかもしれないから、一概に足に関するタグだからと言って上半身タグがついた時に入らない可能性がないわけじゃない感じ。

LLM で補完したい

LLM はこの問題にはオーバースペックすぎるかもしれないけど、ロマンがあるじゃないですか。なんだかいい感じにしてくれそう。

少し真面目な理由を考えると、LLM ならタグごとの関係性を考慮して、「こういうタグがあるときはこういうタグを出してもいい」みたいなのを覚えてくれないかな〜という期待がある。

RetNet を触ってみたいのもあって、最初にあげたモデルを作った。

これは midjourney のプロンプトと danbooru タグ (このデータセットはあまり綺麗じゃなかった...) を使って学習した。

danbooru タグの学習時には、一切のフィルタリング、クリーニングを行っていなかったので、普通にアーティスト名、版権、キャラクター名、bad id, absurdres, signature, artist name, watermark が発生してしまう...

また、タグの順序もいじっていないので完全にアルファベット順に生成されるようになっているが、これは悪いことではないと考えている。danbooru タグはタグ同士の関係性が読み取れないので、無闇にランダムにすると変になりそうなイメージ(実験はしてない...) があるので、それならむしろアルファベット順という秩序があった方がなんか良さそうな気がする。けど、やっぱりこれでもいくつか問題が出たりする。

データセットを準備するのが面倒だったので既存のものを適当にそのまま使ったせいで色んなノイズが入ってしまっていた。なので、このモデルを作った後に綺麗な Danbooru タグを求めて自前でデータセットを作成した。

アーティスト名、版権、キャラクター名、メタタグが分類されており、`_` の処理も(多分)ちゃんと行っているので、`@_@` とか `+_+` も出せる。 以降のモデルではこのデータセットを使っている。2016年〜なのは特に深い理由はない。なんか数も集まったしこれ以上いらんかな〜という気分で2016になった。

このデータセットを使って作った実験的なモデルがこれ。(右側のデモは謎挙動で一文字ずつしか生成されないので、ローカルで使うかボタン連打して)

Meta の OPT-125m を使って学習した。OPT はかなり頭いい気がするけど商用不可なのだ... 商売する予定があるわけじゃないけど、なんだかちょっとアレ

このモデルは名前にもあるように SFT (Supervised Fine-Tuning) を行ったモデル。文章の補完しかしない事前学習済みモデルに対して、質問に答えたりできるように学習するやつ。(SFTTrainer を使ったんだから SFT だろう!)

次のようなプロンプトで生成するように学習している。

Create a tag prompt under the following conditions.

Tags: 1girl, cat ears, blue hair, school uniform, upper body, light smile

NSFW: No

Tag Prompt:

ヒントとして必ず含めるべきタグを与えて、長いプロンプトを作らせるという感じである。ヒントのタグは生成されるタグと異なり、順序を完全にランダムにしている。なので、入力順にかかわらずアルファベット順で綺麗に出てくるようになっている。結果として割とうまくいったと思う。

また、ヒントに含めるタグも工夫しており、版権 (original以外) の場合は絶対にヒントに版権名やキャラクター名を含めるようにすることで、何も指定していない時に勝手に版権要素をぶっ込まれることを回避している。

SDPrompt-RetNet-300M は事前学習を 5 エポックやったガチガチ過学習した補完限定のモデル(先頭しか指定できない)だが、このOPTのモデルは与えた条件の範囲内で自由に作ってくれる。

少し問題があるとすれば、プロンプトの後半が zipper pull tag まみれになること... (これは一定確率で逆順のプロンプトを学習させたら解決しないか?と考えているけどまだ試せていない)←(10%の割合で逆転させたものを学習したら逆に劣化した)

OPT の時は danbooru タグの他に midjourney の自然言語プロンプトも学習していて、

Create a natural prompt under the following conditions.

Summary: Rainy Day in Cyberpunk City Tokyo

NSFW: No

Natural Prompt:

で自然言語のプロンプトが生成されるように学習している。

ここの学習には、ストーリーからタイトルを生成する軽量な T5 モデルを使ってプロンプトを要約させたものをデータセットとして使っている。

また、単語を適当にカンマで区切って danbooru タグ風に列挙して自然言語にさせることも学習したが、こっちはそんなに指示守ってくれなかった。(おそらくdanbooruタグの語彙になかったから覚えづらかったのと、データセットの数でかなり負けてたことも原因かも)

詳しく知らないのでわかんないのだが、プロンプトを LLM 使ってアップサンプル?詳細な説明をつけて画像生成モデル学習するといいみたいな話を聞いて、danbooru タグから自然言語に変換できたらこういうことができそうでいいな〜と思っている。

そういうことも考えて、danbooru のタグ一覧データセットを作った。

これはタグ単体の情報とかのデータセット。これを使って、文章中に完全一致する単語をタグとして取得したり、nltk で表現を統一してマッチしたらタグにする、みたいなことをやりたいなと思った。そう思って実装したんだけど、正規表現の処理が重すぎるのか、処理がバカみたいに遅くてデータセット作れなかった。悲しい。

終わり

今も RetNet の新しいモデルを作っている (事前学習終わってこの後SFTしたいな〜感) ので、いつか公開すると思う。

画像は danbooru タグに特化した頭の悪いトークナイザー。danbooru タグのためにしか存在しない。danbooruタグはかなりの効率でトークナイズできるが、自然言語をトークナイズしようとするとかなりポンコツ。

@plat
記憶が秒で消えるのでメモ。基本的に語彙力がないです。