2024年5月31日金曜日

kakakikikeke を AI で大量生成してみました

kakakikikeke を AI で大量生成してみました

StableDiffusion の LoRA を作成して大量の kakakikikeke を作成してみました
これで永遠に自分が生成できます

環境

  • M2 Pro mac mini (macOS 14.5
  • Stable Diffusion WebUI 1.9.4
  • sd-scripts 0.8.7

学習させる画像

自分の昔の写真(15年くらい前の写真)を使いました
画像サイズはすべて 512x512 です

できれば 20-50 枚くらい準備したほうが精度が良いのですがとりあえずお試しなので 1 枚の画像から 4 枚の異なる背景の画像を用意しました
また少しだけ傾けけたりしています
こうすることで背景を変更させたりすることができます

画像のタグ情報を生成する

画像以外に画像のメタ情報を設定することでよりプロンプトで LoRA を強調することができます
タグ設定には https://github.com/toriato/stable-diffusion-webui-wd14-tagger を使っています

一応抽出できたタグ以外に個別のタグとして「kakakikikeke」を追加しました

LoRa の作成

LoRA の生成には有名な https://github.com/kohya-ss/sd-scripts を使いました
Apple Sillicon 上で動作させるには少し特殊な設定が必要になります

以下に学習時のパラメータを乗せておくので Apple Sillicon 上で動作させたい場合には参考にしてください

xformers を使わなかったり各種 precision の値、最適化関数を AdamW にするあたりが Apple Sillicon 上で動作させるポイントかなと思います
ちなみに画像の学習回数は15回です (ディレクトリに含める値なので以下では設定できない値)

ステップ数が 400 で画像が 4 枚で学習回数が 15 回でだいたい 1 時間くらいで完了します
もっと画像を増やしたりステップを増やしてもいいかもしれません


  "LoRA_type": "Standard",
  "LyCORIS_preset": "full",
  "adaptive_noise_scale": 0,
  "additional_parameters": "",
  "async_upload": false,
  "block_alphas": "",
  "block_dims": "",
  "block_lr_zero_threshold": "",
  "bucket_no_upscale": true,
  "bucket_reso_steps": 64,
  "bypass_mode": false,
  "cache_latents": true,
  "cache_latents_to_disk": false,
  "caption_dropout_every_n_epochs": 0,
  "caption_dropout_rate": 0,
  "caption_extension": ".txt",
  "clip_skip": 1,
  "color_aug": false,
  "constrain": 0,
  "conv_alpha": 1,
  "conv_block_alphas": "",
  "conv_block_dims": "",
  "conv_dim": 1,
  "dataset_config": "",
  "debiased_estimation_loss": false,
  "decompose_both": false,
  "dim_from_weights": false,
  "dora_wd": false,
  "down_lr_weight": "",
  "dynamo_backend": "no",
  "dynamo_mode": "default",
  "dynamo_use_dynamic": false,
  "dynamo_use_fullgraph": false,
  "enable_bucket": true,
  "epoch": 1,
  "extra_accelerate_launch_args": "",
  "factor": -1,
  "flip_aug": false,
  "fp8_base": false,
  "full_bf16": false,
  "full_fp16": false,
  "gpu_ids": "",
  "gradient_accumulation_steps": 1,
  "gradient_checkpointing": false,
  "huber_c": 0.1,
  "huber_schedule": "snr",
  "huggingface_path_in_repo": "",
  "huggingface_repo_id": "",
  "huggingface_repo_type": "",
  "huggingface_repo_visibility": "",
  "huggingface_token": "",
  "ip_noise_gamma": 0,
  "ip_noise_gamma_random_strength": false,
  "keep_tokens": 0,
  "learning_rate": 0.0001,
  "log_tracker_config": "",
  "log_tracker_name": "",
  "log_with": "",
  "logging_dir": "log",
  "loss_type": "l2",
  "lr_scheduler": "cosine",
  "lr_scheduler_args": "",
  "lr_scheduler_num_cycles": 1,
  "lr_scheduler_power": 1,
  "lr_warmup": 10,
  "main_process_port": 0,
  "masked_loss": false,
  "max_bucket_reso": 2048,
  "max_data_loader_n_workers": 0,
  "max_grad_norm": 1,
  "max_resolution": "512,512",
  "max_timestep": 1000,
  "max_token_length": 75,
  "max_train_epochs": 0,
  "max_train_steps": 400,
  "mem_eff_attn": false,
  "metadata_author": "",
  "metadata_description": "",
  "metadata_license": "",
  "metadata_tags": "",
  "metadata_title": "",
  "mid_lr_weight": "",
  "min_bucket_reso": 256,
  "min_snr_gamma": 0,
  "min_timestep": 0,
  "mixed_precision": "no",
  "model_list": "custom",
  "module_dropout": 0,
  "multi_gpu": false,
  "multires_noise_discount": 0.3,
  "multires_noise_iterations": 0,
  "network_alpha": 1,
  "network_dim": 8,
  "network_dropout": 0,
  "network_weights": "",
  "noise_offset": 0,
  "noise_offset_random_strength": false,
  "noise_offset_type": "Original",
  "num_cpu_threads_per_process": 2,
  "num_machines": 1,
  "num_processes": 1,
  "optimizer": "AdamW",
  "optimizer_args": "",
  "output_dir": "model",
  "output_name": "kakakikikeke",
  "persistent_data_loader_workers": false,
  "pretrained_model_name_or_path": "runwayml/stable-diffusion-v1-5",
  "prior_loss_weight": 1,
  "random_crop": false,
  "rank_dropout": 0,
  "rank_dropout_scale": false,
  "reg_data_dir": "",
  "rescaled": false,
  "resume": "",
  "resume_from_huggingface": "",
  "sample_every_n_epochs": 0,
  "sample_every_n_steps": 0,
  "sample_prompts": "",
  "sample_sampler": "euler_a",
  "save_as_bool": false,
  "save_every_n_epochs": 1,
  "save_every_n_steps": 0,
  "save_last_n_steps": 0,
  "save_last_n_steps_state": 0,
  "save_model_as": "safetensors",
  "save_precision": "float",
  "save_state": false,
  "save_state_on_train_end": false,
  "save_state_to_huggingface": false,
  "scale_v_pred_loss_like_noise_pred": false,
  "scale_weight_norms": 0,
  "sdxl": false,
  "sdxl_cache_text_encoder_outputs": false,
  "sdxl_no_half_vae": false,
  "seed": 0,
  "shuffle_caption": false,
  "stop_text_encoder_training": 0,
  "text_encoder_lr": 0.0001,
  "train_batch_size": 1,
  "train_data_dir": "/Users/kakakikikeke/Downloads/data",
  "train_norm": false,
  "train_on_input": true,
  "training_comment": "",
  "unet_lr": 0.0001,
  "unit": 1,
  "up_lr_weight": "",
  "use_cp": false,
  "use_scalar": false,
  "use_tucker": false,
  "v2": false,
  "v_parameterization": false,
  "v_pred_like_loss": 0,
  "vae": "",
  "vae_batch_size": 0,
  "wandb_api_key": "",
  "wandb_run_name": "",
  "weighted_captions": false,
  "xformers": "none"
}

Stable Diffusion WebUI で生成

あとは sd-webui で生成するだけです
sd-scripts で生成した LoRA を指定しプロンプトで生成します
プロンプトは以下です

realistic, 1boy, solo, male focus, day, teeth, blue eyes, black hair, polka dot shirt, upper body, shirt, smile, portrait, kakakikikeke, simple background	<lora:kakakikikeke:1>

また生成時のパラメータは以下だけいじっています

Sampling method -> Euler a
Sampling steps -> 30
Batch count -> 12

で、できあがった画像が以下

手が3本あったりします

考察

おそらくもっと学習データを増やせばもっと精度が良くなると思います
学習させたデータが同じ向きしかないのともともと画像がかなり荒いので生成される画像も少しかけ離れた感じになってしまいます
学習させたデータが上半身しかないのでそれも微妙だった気がします、できれば全身のいろいろな角度の写真が望ましかったかもしれません

また LoRA 学習時のタグ生成ももう少し工夫すればプロンプトにうまく反映できるようになるのかなと思います

あとはプロンプトでリアルな人間を生成する感じのプロンプトを付与すればもっとリアルな感じになるのかなと思います

(masterpiece,best quality:1.4),(8k,raw photo,photo realistic:1.2)

ベースのモデルをデフォルトのやつではなく日本人の顔に特化したモデルに変更してももっと良い結果になるかもしれません

最後に

たった一枚の写真でもここまで生成に反映できるとは思いませんでした
現在の年齢の写真や幼少期の写真も学習させれば生まれてから現在はたまた未来の自分までの画像が作成できるかもしれません

今回環境が M2 mac mini だったので学習させる画像の量に限界があるのがネックです
もし大量の画像を学習させていろんなバリデーションの自分を出力できるようにするのであればそれなりのスペックのマシンか Google Colab あたりで動作させる必要があるかもです

2024年5月10日金曜日

AI kakakikikeke に Tomorrow never knows を歌わせてみた

AI kakakikikeke に Tomorrow never knows を歌わせてみた

今流行りの AI による歌を自分で作成してみました

できたもの

うぉっおーの高音部分が出てないところがまたリアル

環境

  • macOS 14.4.1 (M2Pro Mac mini)
  • Python 3.9.18
  • RVC WebUI (updated1006v2)

作り方

流れは以下の感じです

  1. 自分の音声モデルの作成
  2. 音源のBGMと声の分割
  3. 分割した声のファイルと音声モデルを使って推論
  4. BGMと推論により作成された音源ファイルを合成

です
なお使用したツールは RVC と Audacity になります

自分の音声モデルの作成

自分の声はこれまで Podcast でしこたま録音しているのでそれを使いました
たくさんあったほうがいいのですが 20 分くらいあれば十分っぽいのでこれを使いました

これを使って RVC の Train 機能を使って音声モデルを作成するだけです
モデルを生成する際はいろいろとチューニング可能なのでそれによっても歌い方がだいぶ変わってきます

harvest は品質が良くなりますがかなり学習に時間がかかります

音源のBGMと声の分割

今回は Mr.Children さんの Tomorrow never knows を音源として使わせていただきます
特に理由はないですがただただ好きなだけです
あとは男性の音声モデルの場合は男性の音源を使うほうが精度が良いかなと思ったので男性ボーカルの歌を選択しました

分割した声のファイルと音声モデルを使って推論

音声モデルファイルは pytorch 形式で出力されます
このモデルを使って分割したボーカルのみのファイルに自分の声とボイスチェンジを行うのが推論になります

推論が完成するとボーカルが自分の声になったバージョンの Tommorrow never knows が完成します

ここでも harvest は品質が良くなりますがかなり推論に時間がかかります
今回は crape を使っています (一番良さそうだったので

また途中 BGM を歌っている部分があったのでそこもカットしています

合成する

あとは分割した BGM 部分と自分の声になったボーカルファイルを合成するだけです
これは RVC ではなく普通の DTM ソフトを使います
自分は Audacity を使いました

最後に

高音部分を学習させてあげれば更によくなるかもです

これで僕が死んでからも音声モデルさえ残しておけば僕の声を聞くことができるようになりました
M2 Mac mini を購入してから AI 関連の高負荷処理も簡単にさばけるようになったので AI 関連の作業が楽ちんです

参考サイト