Grinding
詳細
ファイルをダウンロード
このバージョンについて
モデル説明
pussyjob alphaの更新:テストの結果、精液の噴射は得られず、精液後のみのショットしか得られませんでした。いくつかのプロンプトキャプションが誤っていたことに気付きました。現在、再学習中です。
彼女があなたの上をこすりつけています…精液を出さないようにしましょう!
Wan T2V、14B
プロンプティング:
女性が男性の上にまたがり、性交を行っている。
男性はベッドに横たわっている。女性はその上をこすりつけて動いている。
シーンは男性の視点から撮影されている。
pussyjob v2 - alpha用プロンプティング:
女性が床の上で男性の上にまたがっている。両者とも裸である。
女性は自分の膣を男性の陰茎にこすりつけている。男性の陰茎は射精時に精液の噴流を放つ。
シーンは男性の視点からのミディアムショット。リアリスティック。
Cfg:約3.0が最も効果的
学習:
このLoRAは、4090でdiffusion-pipeを用いて作成されました。ほとんどデフォルト設定です。下記に含まれるtomlファイルを参照してください。
私は57本のクリップ(各256x256、24fps、48フレーム)を使用して学習しました。これらのクリップは、720p-1080p解像度の6本の公開動画から、DaVinci Resolve(無料)を用いて抽出しました。60エポック学習した後、テストしたところ結果は普通でしたが、特に優れていませんでした。一晩通して合計約10時間の学習を行い、最終的に160エポックで以下の結果を得ました。
各クリップのキャプションは、この記事のガイドラインに基づいて作成しました。また、著者(@ComfyTinker!)との議論を通じて、キャプション作成についての理解を深めました。
キャプション作成:
各ファイルは、以下のような例に基づいて手動でキャプション付けしました:
女性が男性の上にまたがり、性交を行っている。
男性はベッドに横たわっている。女性はその上をこすりつけて動いている。
顔は映っていない。女性と男性は裸である。女性は体型が良く、大きな胸をしている。長い流れている金髪である。背景には緑の壁が見える。女性は側面から明るい自然光で照らされている。
シーンは男性の視点から撮影されている。リアリスティック。
ここでは、勝手に作ったキーワードは使用していません。この経験から得た重要な教訓は、Wan/HunyuanではCLIPモデルを訓練していないため、作り出したキーワードを使うと「概念的」(つまり、プロンプトに関係なく常に適用される)LoRAになってしまい、プロンプトに応じたターゲットLoRAにならないことです。なぜなら、現在のトレーニング手法ではCLIPモデルに新しい単語を追加できないため、作り出したキーワードは無視されるか、何らかの未知の処理が行われるからです。
その他の学び:以前、約50本の128x128クリップを使用し、キーワード「gr1nd1ng」を用いて学習しました。女性の動きの結果は非常に良かったですが、男性の動きはバラバラになってしまいました。これはおそらく解像度が低かったためです。
フィードバックや質問はこちらへ歓迎します!
config.toml:
# データセット設定ファイル。
output_dir = '/mnt/d/Projects/video-training/grinding/output'
dataset = '/mnt/d/Projects/video-training/grinding/dataset_256px.toml'
# 学習設定
epochs = 200
micro_batch_size_per_gpu = 1
pipeline_stages = 1
gradient_accumulation_steps = 4
gradient_clipping = 1.0
warmup_steps = 100
# 評価設定
eval_every_n_epochs = 1
eval_before_first_step = true
eval_micro_batch_size_per_gpu = 1
eval_gradient_accumulation_steps = 1
# その他の設定
save_every_n_epochs = 10
checkpoint_every_n_epochs = 10
#checkpoint_every_n_minutes = 30
activation_checkpointing = true
partition_method = 'parameters'
save_dtype = 'bfloat16'
caching_batch_size = 1
steps_per_print = 1
video_clip_mode = 'single_middle'
blocks_to_swap = 15 # 10は低すぎ、スワップが多発し学習が遅くなる(180秒/ステップ vs 25秒/ステップ)
[model]
type = 'wan'
# 1.3B
#ckpt_path = '/mnt/d/software_tools/diffusion-pipe/models/wan/Wan2.1-T2V-1.3B'
# 14B
ckpt_path = '/mnt/d/software_tools/diffusion-pipe/models/wan/Wan2.1-T2V-14B'
transformer_path = '/mnt/d/software_tools/diffusion-pipe/models/wan/Wan2_1-T2V-14B_fp8_e5m2.safetensors' #kijai
vae_path = '/mnt/d/software_tools/diffusion-pipe/models/wan/Wan_2_1_VAE_bf16.safetensors' #kijai
llm_path = '/mnt/d/software_tools/diffusion-pipe/models/wan/umt5-xxl-enc-bf16.safetensors' #kijai
dtype = 'bfloat16'
timestep_sample_method = 'logit_normal'
[adapter]
type = 'lora'
rank = 32
dtype = 'bfloat16'
[optimizer]
type = 'adamw_optimi'
lr = 5e-5
betas = [0.9, 0.99]
weight_decay = 0.01
eps = 1e-8
dataset.toml(hearmemanのRunPodから拝借しましたが、ほとんどの値はtdrusselのデフォルト設定です):
# 学習に使用する解像度。正方形画像の一辺の長さで指定します。複数のサイズを指定できます。
# !!!警告!!!:これはあなたが思っているのとは異なる動作をする可能性があります。画像はまずアスペクト比バケットにグループ化され、その後、各画像はresolutionsリストで指定されたすべてのサイズにリサイズされます。これは、複数の総画素面積を一度に学習する「マルチ解像度学習」の方法です。データセットは、このリストの長さ分、複製されたように扱われます。
# あらかじめ定義された(幅、高さ、フレーム)サイズバケットを使用したい場合は、cosmos_dataset.toml例を参照してください。
resolutions = [256]
# 以下のように(幅、高さ)のペアでも解像度を指定できます。これは機能的に何の違いもありません。単に学習したい画素総数(面積)を指定する別の方法です。
# resolutions = [[1280, 720]]
# アスペクト比バケットを有効化します。異なるARバケットに対して、最終サイズは上記で設定したresolutionsの面積に一致するように調整されます。
enable_ar_bucket = true
# 最小および最大アスペクト比(幅/高さ比)を指定します。
min_ar = 0.5
max_ar = 2.0
# min_ar と max_ar の間で対数的に等間隔に配置されるアスペクト比バケットの総数。
num_ar_buckets = 7
# 上記の範囲指定の代わりに、ar_bucketsを手動で指定できます。
# 各エントリは幅/高さ比、または(幅、高さ)ペアで指定できますが、TOMLの制約により混在できません。
# ar_buckets = [[512, 512], [448, 576]]
# ar_buckets = [1.0, 1.5]
# 動画学習では、フレームバケットを設定する必要があります(アスペクト比バケットと同様)。画像の場合は必ずフレームバケット1が存在します。動画は、フレームバケット長以上である限り、可能な限り最長のフレームバケットに割り当てられます。
# ただし、動画は画像用フレームバケット(1)には割り当てられません。動画が非常に短い場合は、単に破棄されます。
frame_buckets = [1, 16, 32, 48]
# 24GB以上のVRAM、または複数GPUとパイプライン並列化を使用している場合、または空間解像度を下げる場合、より長いフレームバケットで学習できるかもしれません。
# frame_buckets = [1, 33, 65, 97]
[[directory]]
# 画像/動画のディレクトリパスと対応するキャプションファイル。キャプションファイルはメディアファイル名と一致し、拡張子は.txtです。
# キャプションファイルが存在しない場合、警告がログに出力されますが、空のキャプションで学習が続行されます。
path = '/mnt/d/Projects/video-training/grinding/8-256px/'
# マスク学習を有効化できます。マスクは損失関数内で画像の学習対象領域を示します。マスクディレクトリには、トレーニング画像と同じ名前(拡張子は無視)のマスク画像を配置します。例えば、トレーニング画像1.jpgには、1.jpg、1.pngなどのマスク画像が対応します。対応するマスクがなければ、警告が表示されますが、その画像にはマスクなしで学習が進みます。マスクでは、白色は学習対象、黒色はマスク無しを意味します。その間の値は0〜1の重みとして扱われます(例えば、グレー値を0.5の重みに使用可能)。実際には、Rチャネルのみが抽出されマスク重みに変換されます。
# mask_pathはマスク画像が含まれる任意のディレクトリを指すことができます。
#mask_path = '/home/anon/data/images/grayscale/masks'
# 1エポックあたりの繰り返し回数。データセットはこの回数だけ複製されたかのように動作します。
# これはsd-scriptsと同様の意味です:num_repeats=1は、エポック1回が全サンプルを一度だけ通ることを意味します(複製なし)。
num_repeats = 1
# 設定の上書き例:ar_bucketsを直接指定する場合。
# ar_buckets = [[448, 576]]
# resolutions = [[448, 576]]
# frame_buckets = [1]
# 複数のディレクトリをリストできます。
# 動画データセットがある場合は、以下の3行のコメントを外し、num_repeatsを設定してください。
# [[directory]]
# path = '/video_dataset_here'
# num_repeats = 5