見出し画像

Pony系LoRAのタグ出しと編集について

この記事の対象について

・AUTOMATIC1111 web-uiなどで画像のタグ付けをしたことがある人
・Pony系モデル向けのLoRA作りをしている人・したい人
・LoRA作りにおいてタグの編集を少しでも楽したい人
・多少怪しいかもしれないソフトでも使ってみる覚悟がある人

注意点:
・今回の記事については所謂「貴方自身のリスクでどうぞ」という話なので、出所不明のスクリプトやモデルを使うのが怖いという人は手を出さない事をオススメします。
・この記事は2024-07-14時点でのものなので、ソフトのバージョンアップや外部環境の変化等によって内容が古くなる可能性があります。

現状のPony系モデルのTagger

昨今Pony系モデルが非常に大きな勢力になってきた一方で、そこで使われているタグは従来のbooruタグからe621タグという別系統のものになりました。

Pony系モデルはbooru語で学習できないわけではないのですが、やはり大元のPony v6がe621語で学習されている以上、ポテンシャルを活かすためにもあるいは単なる興味でe621語でLoRA学習をしてみたいという人もいるかとは思いますが、一方でそもそも「タグ出し用のモデルが見つからない」という入口で一部の人(?)は少なからず躓いているように見えます。

そこで「この記事を書いている時点での&自分の観測範囲では」という但し書きが付きますが、現在のe621系のタグ出しモデルとその使い方についてざっと解説したいと思います。
まずは今ある主要なモデルについて(あくまで自分の知ってる範囲なので、他にもっと優秀なモデルを知っていたら是非教えて下さい)

Z3D-E621-Convnext → webuiのwd14-taggerに少し手を加えると使用できるモデル。ただし挙動は暴れ馬で、誤タグ特に種族タグ多し。
eva02-vit-large-448-8046 → 安定したタグ出しな一方で、大人しめというかタグの幅そのものが狭い?
tagger-siglip-so400m-384-9940 → たぶん最新。出せるタグは増えている?多少使ってみたところでは448-8046と比べて飛躍的な変化は感じられなかった。

さて、このうちtagger-siglip-so400m-384-9940についてはまだ直接スクリプトを書いて動かす以外方法はないようですが、Z3D-E621-Convnextとeva02-vit-large-448-8046についてはcivitaiで公開されているスクリプトで動かすことができます。(ちなみにbooru語系の新しいモデルにも対応済み)

というわけで今回はそのスクリプト「Image/Video Booru Tagger (WD14 + DeepDanbooru + E621)」を使用する方法を案内していきます。

Image/Video Booru Tagger (WD14 + DeepDanbooru + E621) v4.2のインストール方法

1.Python v3.9.x ~ v3.11.x が必要条件ですが、これについてはStable Diffusionを動かしている人なら既に入ってると思うので割愛。
2.FFmpeg(最新バージョン)をダウンロードする

3.解凍したFFmpegを任意のフォルダに置く
PATHを通すのであまり深いところに置かないほうがいいかも?
4.システム環境変数を設定
Winキー→[システム環境変数の編集]→[環境変数(N)]→Path[編集]→FFmpegを置いたパスをコピペ。
環境変数の設定ができていればコマンドプロンプトで ffmpeg -version と打つと以下のように返ってくる。

5.CivitaiよりダウンロードしたimageVideoBooruTaggerWD14_v42内のrequirements.txtの5行目の内容を以下のように書き換え
numpy → numpy<2

(※2024-07-14現在、そのままインストールを行うとパッケージのバージョン違いによって起動しない問題が発生しており、その一時的な回避策。今後のバージョンアップによって問題が発生しなくなればこの手順は不要です)

6.install.batをクリック
7.インストールが終わったらrun.batをクリック

動画のタグ出し機能(といっても今回は使わない)のためにFFmpegと環境変数を弄らなければいけないのですが、それ以外は特に面倒なところはないと思います。

Image/Video Booru Tagger v4.2の使い方

起動に成功したらこのような画面が表示されます。
それぞれの項目を設定していきましょう。

1.画像フォルダのパスとタグの.txtファイルの出力先
基本的に同じにする。
2.使用するモデルにチェックを入れる
今回は[E621:Z3D-E621-Convnext][E621:Thouph-eva02-vit-large-448-8046]にチェックを入れます。Thresholdは高すぎると殆どタグを吐かない一方で、特にZ3Dは低くすると無関係なタグを大量に吐くので0.3~0.4あたりから調節してみるといいでしょう。
3.謎項目。e621モデルでタグを出す場合はチェックを外さないと動作しないのでチェックを外す。
4.詳細設定。それぞれの項目についてはデフォルトの状態から変更しないほうがいいですが、一応日本語訳を載せておきます

Skip files that already have an output tags file. >> If False then it will overwrite them <<
出力タグファイルがすでにあるファイルはスキップします。False の場合は上書きされます

Save tags file as 'fileName.fileExtension.txt' >> If False then it will save as 'fileName.txt' <<
タグファイルを 'fileName.fileExtension.txt' として保存します。False の場合は 'fileName.txt' として保存されます。

Split tags by newlines. >> if False then it will split them by commas <<
タグを改行で分割します。False の場合は、カンマで分割します

Also tag videos
動画にもタグを付ける

Only save tags predicted with all used models. > Avoid this when using E621 <
使用されたすべてのモデルで予測されたタグのみを保存します。  E621 を使用する場合はこれを避けてください

Include tag probability in output file. (You probably do not want this)
出力ファイルにタグ確率を含めます。(おそらくこれは望ましくないでしょう)

Exclude rating tags (ex: rating:safe)
評価タグを除外する(例:評価:安全)

Exclude character and copyright tags (ex: hatsune_miko, attack_on_titan). Warning: decreases speed on slow CPUs
キャラクターと著作権タグを除外します (例: hatsune_miko、attack_on_titan)。警告: 低速 CPU では速度が低下します。

Exclude 'realistic' tags (ex: 3d, realistic, photorealistic, ...)
「リアル」タグを除外します (例: 3D、リアル、フォトリアリスティックなど)

Replace underscores with spaces (ex: blue_eyes -> blue eyes)
アンダースコアをスペースに置き換えます(例:blue_eyes -> blue eyes)

Append 'auto_tag' namespace (ex: blue_eyes -> auto_tag:blue_eyes)
'auto_tag' 名前空間を追加します (例: blue_eyes -> auto_tag:blue_eyes)

Append 'auto_tag' namespace to additional tags as well
追加のタグにも「auto_tag」名前空間を追加します

5.Additional tagsは強制的に追加するタグ。これは既存のtaggerと同様に主にトリガータグなどを設定します。
Exclude tagsは除外したいタグ。これも既存のtaggerと同じ機能になります。

1~5の全ての項目のチェックが問題なければ[Start]を押してタグ出し開始。無事に完了してタグ出しの結果に満足した方はここで終了です。
お疲れ様でした。このページは閉じて次はsd-scriptsの設定を詰めて学習を回してしまいましょう。

e621系taggerの重複概念タグ多すぎ問題

ここからは「いや、これだけだとちょっとなー…タグがなー…」という方へ、まぁそうですよね。
さて改めてタグ出しの結果を確認してみましょう。
Thresholdの設定次第にはなりますが、大体以下のようになるはずです。

タグの整理にはBooruDatasetTagManagerを使ってます

通常タグは出力したそのままでは色々と問題があったりします。
問題になるタグは大別して

1.誤タグ
2.なんかよくわからんタグ(digital mediaとかart workみたいなやつ)
3.足りないタグ
4.重複概念タグ


になると思うのですが、まず1と2については単純に消すだけです。(特に2については、そもそもe621のmedia types:の種別なら digital_media_(artwork) になるのでこのタグ出しそのものが不正確)
種族タグなどもそうですが、こういったモデルが手癖のように吐き出してくるものがあるので、それらはExclude tagsで強制的に弾いてしまうのがいいでしょう。
例えばキャラクターLoRAを作る際に、そのキャラがhumanであることが確定している場合はhumanoidやらその他大量の種族タグは不要です。

3については画像を個別にチェックしつつe621のタグ辞典とにらめっこして足していく以外の方法は現時点ではありません。
ただ現時点でのPony系モデルは全てのe621タグの内容を学習しているわけでも再現できるわけでもない以上、あまりにもマイナーなタグ付けに拘っても結果には大きな影響はないでしょう。

さて問題は4です。
上で挙げた画像の例でもいくつもの重複概念タグがあり、
uniformとmaid uniform
みたいな「片方あればもう片方いらんやろ」ってやつが発生してます。

uniformとmaid uniformで被り、hairも単体だと「うーん?」ってなる
こういうのが地味にチェック作業の負担に

また skirtとblue skirt みたいな基本的な被りから、underwearとlingerie といった応用問題的なやつや、逆に garterとgarter strap みたいな一見被っているようでそれぞれ別のものを表す引っ掛け問題みたいなタグもあります。
(※解説すると、e621語ではgarterは「腿に巻く飾りなどがついた帯状の布」で、garter strapは「ストッキング等を吊るためにgarter beltから伸びてる紐」です。つまり「片方あればもう片方いらんやろ」の関係ではない)

これらは必ずしも消さなければいけないわけじゃないんですが、なにしろLoRA作りにおいて画像に適切なタグがついているかをチェックするためには、まずこの大量のタグを整理しないと「画像数 x タグ数」で掛け算式に膨大な作業時間が発生します。
これをなんとかしたいわけです。

一例を挙げるとこの画像ですが……

以前某匿名掲示板向けにネタで作った薩摩義士伝パロディLoRAから流用

この画像に付いてるタグが以下の通り

この例だと特に苦手なタイプの画像をタグ出しさせて出た結果なわけですが、まず大量の重複概念タグを消せれば、肝心の誤タグ消しやら正しいタグを付け加える作業も随分と楽になると思います。(この場合はexplosion, radial speed lines(集中線),yelling(叫ぶ),rubble, sequence…などなど)

さて、何かいいアプローチはないもんでしょうか?

答:舟を編みましょう(辞書を作りましょう)

このエロとケモナーまみれの言葉の海を渡る舟を編む、辞書を作りましょう。ところでその海ってなんか白く濁ってネバネバしてませんか?
…といっても、言葉の定義付けや用法やカテゴライズやその他の本来の意味での「辞書作り」という気が遠くなる作業はe621の馬締(まじめ)さんならぬ、変態海外兄貴のポニー締さん達がしてくれており、例えば先程のgarterとgarter strapの例についても「Not to be confused with」と丁寧に注意書きされていたりします。

あとは「"maid uniform"があれば"uniform"を消す」「tearsやsweatがあればbodily fluids(体液全般)を消す」といった「アレがあればコレを消す」という仕組みを持った何かがあればいいわけです。
そしてそれも既にあったりします。

このAUTOMATIC1111用(一応forgeでも使える)エクステンションには、そのものずばりの「重複概念タグを消す」という機能があり、これを使うことによってワンクリックで画像フォルダ内の各.txtファイルにある重複概念タグを消すことができます。

しかし悲しいかな。
このエクステンションが作られた頃はまだbooruタグが全盛の時代であり、このエクステンション内にある辞書型データのファイルにはbooru語の記述しかありません。
けどスクリプトの仕組みそのものはbooruタグだけに固定されているわけではないので、ファイルの差し替えさえ行ってしまえばe621語に対応する事が可能なわけです。
というわけで辞書(型データのファイル)を作りましょう。

……というのも酷な話なので、既にできたものをこちらで用意しました。
3分クッキング?

Captioning Helperの導入方法と使い方

ここからはCaptioning Helperの使い方と上記ファイルの導入方法をざっと説明していきます。

といってもインストールそのものはA1111ユーザーにはいつもの方法です。
[Extensions(拡張機能)] →[Install from URL(URLからインストール)]のURL欄に"https://github.com/gnnsnzh/captioning_helper"と入れましょう。

Captioning Helperのメイン画面

これがCaptioning Helperメイン画面となるわけですが、基本的には
データセットのディレクトリ: 画像とタグが入ったフォルダを指定
あとは[Remove Unnecessary Tags] [Remove Duplicate Tags]にチェックを入れて[実行]を押すだけです。

hair colorやeye color系の統一やMerge Tagsといった面白い機能(例えばlong hair, black hairをlong black hairという風に統合する)という機能もあるのですが、e621語にはおそらく対応してないと思われるのと今回の趣旨ではないので詳しくは解説しません。機能に興味があればReadmeを読んでみてください。

辞書データの差し替え方法

Captioning HelperのRead meには以下のような記述があります。

Remove Unnecessary Tags
重複する概念のタグを削除し、より詳細なタグを残します。
重複するワードを検出してるわけではなく、手動でリスト化したタグを参照しています。
削除対象のタグはtag_config_data.pyを参照してください。

https://github.com/gnnsnzh/captioning_helper

というわけで、この"tag_config_data.py"をデフォルトのbooru語のものからe621語のものに差し替えます。
[AUTOMATIC1111のインストールフォルダ] → [webui]→ [extensions] → [captioning_helper] → [scripts] とフォルダを開いていってみてください。

scriptsフォルダ内部

1.tag_config_data.pyを"tag_config_data.bak"にリネーム
2.上のリンクからダウンロードしたtag_config_data.pyを同フォルダに移動
3.A1111 web-uiを再起動

これで使えるようになっている筈です。
試しに学習データがあるフォルダを指定して[Remove Unnecessary Tags] [Remove Duplicate Tags]にチェックを入れて[実行]をしてみましょう。

このように「どのタグによってどのタグを消したか」がログに出力されます。

あとこのtag_config_data.pyの中身ですが
"(消したいタグ)" : ["(これがあると消えるタグ1)", "(これがあると消えるタグ2)", "(これがあると消えるタグ3, 4, 5….)"],
という構造なので、ここの記述を変えれば「soloがあるときにduoが消えるってのはちょっとやめにしたい」みたいな細かいカスタマイズもできます。

また例えばe621語の構造では重複概念ではないけど、実運用上では弾きたいというタグを消すができます。一例として
「hair between eyesがあるときはbangs(前髪)は消したい」
といった場合は
"bangs": ["hair between eyes"],
という記述になります。

e621語では重複概念ではないものの
目の間を通る髪(hair between eyes)は普通前髪(bangs)以外あり得ない

ただtag_config_data.pyの記述に構文ミスがあるとエクステンションそのものが立ち上がらなくなるのでその点は要注意ですが、その際は修正するなり
tag_config_data.bakをtag_config_data.pyにリネーム
で元に戻しましょう。
もっとも最悪のケースでもエクステンションのフォルダを消してまたインストールしなおせば機能そのものは復活できます。

ちなみに私はタグの対応表をスプレッドシートで管理してcsvで出力→辞書ファイルに変換という方法でやってます。

(余談)そもそも重複タグは消すべきなのか

と、ここまで長々とやっておいてなんですが、そもそも重複概念タグは消すべきなんでしょうか?

元々のPonyが種族や 網・目・亜目・下目・上科・科…etc ある程度の細かい分類のタグを付けて例えばdomestic cat(家猫)を学習しているのなら、その構造を守るべきなのか。それともベースのモデルで何科の何目の~云々は学習しているなら屋上屋を架すべきではないのか。
単純に楽をしたいので出来る限りタグは削りたいのですが、要はそれがLoRAの出来にどう関わってくるか?って話です。

ここはChatGPT君に質問してみましょう。

User:
sd-scripts(Stable Diffusion)での画像の学習についての質問です。 たとえば青いスカートをはいた女性の画像を学習させるときに、タグにskirt, blue skirtという2つの概念が重複したタグが存在する場合、skirtのほうは消して学習させるべきなのでしょうか?また重複した概念のタグを残した状態と消した状態でどう学習の結果は変わるのでしょうか?

ChatGPT:
SD-Scripts(Stable Diffusion)で画像の学習を行う際に、「skirt」と「blue skirt」というタグが重複して存在する場合の扱いについてですが、以下のように考えることができます。

タグを消すか残すかの選択

  1. 「skirt」を消す場合:

    • 利点: モデルは「blue skirt」という具体的なタグに集中し、青いスカートの特徴をより詳細に学習できます。

    • 欠点: スカート全般の概念の理解がやや弱くなる可能性があります。

  2. 両方のタグを残す場合:

    • 利点: モデルは「skirt」と「blue skirt」の両方の概念を学習するため、スカート全般の特徴も捉えつつ、青いスカートの特徴も理解できます。

    • 欠点: 学習の際にモデルが混乱し、特定の色(青)のスカートを生成する精度がやや低下する可能性があります。

学習結果の違い

  • 「skirt」を消した場合: 青いスカートに特化した学習が行われるため、青いスカートの再現性が高まります。

  • 両方のタグを残した場合: スカート全般の理解が深まり、より多様なスカートの生成が可能になりますが、青いスカートの特定の特徴がやや薄まる可能性があります。

最適な選択

  • 具体的な結果が必要な場合: 「skirt」を消し、「blue skirt」に集中する方が良いでしょう。

  • 汎用的な結果が必要な場合: 両方のタグを残すことで、スカート全般に対する理解が深まります。

このように、学習の目的に応じてタグの選択を行うことで、より効果的なモデルの訓練が可能になります。

User:
「汎用的な結果が必要な場合」という話ですが、つまり「青いスカート」をskirt, blue skirtというタグで学習させたとき、skirtという単語はblue skirtという要素を飲み込んだより大きな概念になるのでしょうか?
これは例えば大規模なファインチューンやLoRAをマージしてより規模の大きいモデルを作成する場合は、重複したタグを使ってより全般的な理解を深めるほうがいいのでしょうか?

ChatGPT:

タグの概念とその影響

「skirt」と「blue skirt」の関係

  • skirt: 一般的なスカートの概念を表します。

  • blue skirt: 特定の属性(青色)を持つスカートを指します。

重複したタグの効果

  • タグの重複: 「skirt」と「blue skirt」を両方使うことで、モデルは「skirt」という広範な概念の中に「blue skirt」という具体的なサブカテゴリが存在することを学習します。

  • 汎用的な理解: 重複したタグを使うことで、モデルは一般的なスカートの概念と特定の属性を持つスカートの両方を学習し、より全般的で柔軟な理解が可能になります。

大規模なファインチューンやLoRAのマージ

  • 重複タグの利点: ファインチューンやLoRAをマージする際に、重複したタグを使用すると、モデルがより多様なデータセットから幅広い特徴を学習しやすくなります。

  • 全般的な理解: 重複タグを使うことで、モデルが特定の特徴とその関連する一般的な概念を同時に学習でき、より強力で汎用的なモデルを構築できます。

このように、重複したタグを使用することで、特定の属性を含む広範な概念を学習する効果が得られ、より強力で柔軟なモデルの構築が可能になります。

User:
逆にモデルの学習が特定のキャラクターなどを表現したいときに臨時的に使われるLoRAの場合は、具体的な結果に近いblue skirtという単語のみで青いスカートを学習させたほうがいいのでしょうか?

ChatGPT:
特定のキャラクターや具体的な特徴を学習させたい場合、LoRA(Low-Rank Adaptation)を使用する際には、より具体的なタグ(例:「blue skirt」)を使用する方が効果的です。これにより、モデルは特定の特徴を詳細に学習し、目的の表現を正確に再現することができます。

具体的なタグの利点

  • 精度の向上: 具体的な特徴を強調し、モデルがその特徴を正確に捉えるようにします。

  • 過剰な一般化を防止: 一般的なタグを避けることで、モデルが不要な情報を学習するのを防ぎます。

結論

特定のキャラクターや具体的な属性を学習させる場合には、「blue skirt」のような具体的なタグのみを使用するのが最適です。これにより、必要な特徴を強調して効果的に学習させることができます。

……という事らしいです。

なんか回答を誘導してしまった感があって鵜呑みにしづらいのですが、ChatGPTを信じるなら通常のLoRAという用途で学習させる際には、「これは青いスカートです」という絞り込んだ表現のほうがいいし、大規模な学習やマージしてより大きなモデルに組み込む目的のLoRAなら「blue skirtはskirtの一種です」という広範な概念が必要だと。

学習の仕組みで考えても、あるキャラクターの特徴を大量に出現した単語(トークン)に分けて覚えさせたとして、プロンプトでその大量の単語をいちいち網羅しなければ特徴を再現しきれない…というのは使い勝手が悪いものになりますし。出来れば短いプロンプトでキャラクターの特徴をバッチリ出せるようにしたいものです。(…と考えるとトリガーワードにキャラの特徴を収束させるやり方って賢い)

というわけで、おそらく重複概念のタグを削るのはLoRAにおいては問題ないみたいです。でも将来的にLoRAをマージして別のモデルを作る用途なら削らないほうがいい、つまりモデルの用途によってタグの付け方は変わる…と。
いやはやなんとも面倒くさいですね。

特に意味はない

その他の作業やら

さてここからはそれぞれの方法で誤タグを弾いて、正しいタグを記述していく作業になります。
ただこれについてはそれぞれの環境・使ってるツールごとにやり方が根本的に変わってくるので説明が難しいところがあります。

BooruDatasetTagManagerの画面
ちゃんとe621タグにも対応している

ただ私の場合はBooruDatasetTagManagerを使用してAll Tagsの欄から
・明らかに不要なタグ("2021"とか"artwork"みたいなやつ)」を消す
・その他のタグは適用されている画像を絞り込みを行って、適用が間違っていたら個別に消す
というタグごとにクロールする方法(緑枠)で消していき、誤タグがなくなったら今度は画像ごとにクロール(紫枠)して不足しているタグを記述していくという方法でやってます。

もっともこの辺のやり方も、20~30枚程度の画像で作るキャラクターLoRAと多くの画像を要するスタイルやシチュエーションLoRAなどで変わってきます。
何かもっと良い方法があれば是非アドバイスや紹介をお願いします。

以上となります。
現状タグ打ちは人間が地道にちまちまやるか、誤タグや不足タグは然程気にせず教師データの量で押し切るかのいずれかしかないみたいですが、もっといい方法……例えばタグ出しモデルとLLMを組み合わせた賢いとかで革命が起きるといいですね。


いいなと思ったら応援しよう!