Diffusers 文件
文字反轉 (Textual Inversion)
並獲得增強的文件體驗
開始使用
Textual Inversion
Textual Inversion 是一種訓練技術,只需幾張你想要學習的示例圖片,即可個性化影像生成模型。該技術透過學習和更新文字嵌入(新的嵌入與你必須在提示詞中使用的特殊詞語相關聯)來匹配你提供的示例圖片。
如果你在 vRAM 有限的 GPU 上進行訓練,應嘗試在訓練命令中啟用 `gradient_checkpointing` 和 `mixed_precision` 引數。你還可以透過使用 xFormers 的記憶體高效注意力機制來減少記憶體佔用。JAX/Flax 訓練也支援在 TPU 和 GPU 上進行高效訓練,但它不支援梯度檢查點或 xFormers。在與 PyTorch 相同的配置和設定下,Flax 訓練指令碼的速度應該至少快約 70%!
本指南將探討 textual_inversion.py 指令碼,幫助你更熟悉它,以及如何根據你自己的用例進行調整。
在執行指令碼之前,請確保從原始碼安裝庫
git clone https://github.com/huggingface/diffusers
cd diffusers
pip install .
導航到包含訓練指令碼的示例資料夾並安裝您正在使用的指令碼所需的依賴項
cd examples/textual_inversion
pip install -r requirements.txt
🤗 Accelerate 是一個幫助你在多個 GPU/TPU 上或使用混合精度進行訓練的庫。它會根據你的硬體和環境自動配置你的訓練設定。請檢視 🤗 Accelerate 快速入門以瞭解更多資訊。
初始化 🤗 Accelerate 環境
accelerate config
要設定預設的 🤗 Accelerate 環境而不選擇任何配置
accelerate config default
或者如果您的環境不支援互動式 shell(例如筆記本),您可以使用
from accelerate.utils import write_basic_config
write_basic_config()
最後,如果您想在自己的資料集上訓練模型,請檢視 建立訓練資料集 指南,瞭解如何建立與訓練指令碼相容的資料集。
以下各節重點介紹了訓練指令碼中對於理解如何修改至關重要的部分,但並未詳細涵蓋指令碼的每個方面。如果你有興趣瞭解更多,可以隨意閱讀指令碼,如果你有任何問題或疑慮,請告訴我們。
指令碼引數
訓練指令碼有許多引數可以幫助你根據需求定製訓練過程。所有引數及其描述都列在 parse_args()
函式中。在適用的情況下,Diffusers 為每個引數提供了預設值,例如訓練批次大小和學習率,但如果你願意,可以在訓練命令中更改這些值。
例如,要將梯度累積步數增加到預設值 1 以上:
accelerate launch textual_inversion.py \ --gradient_accumulation_steps=4
其他一些需要指定的基本且重要的引數包括:
--pretrained_model_name_or_path
:Hub 上的模型名稱或預訓練模型的本地路徑--train_data_dir
:包含訓練資料集(示例圖片)的資料夾路徑--output_dir
:訓練好的模型的儲存位置--push_to_hub
:是否將訓練好的模型推送到 Hub--checkpointing_steps
:在模型訓練時儲存檢查點的頻率;這很有用,如果由於某種原因訓練中斷,你可以透過在訓練命令中新增--resume_from_checkpoint
來從該檢查點繼續訓練--num_vectors
:用於學習嵌入的向量數量;增加此引數有助於模型學得更好,但會增加訓練成本--placeholder_token
:用於關聯所學嵌入的特殊詞語(你必須在推理的提示詞中使用該詞)--initializer_token
:一個大致描述你試圖訓練的物件或風格的單個詞--learnable_property
:你是要訓練模型學習一種新的“風格”(例如,梵高的繪畫風格)還是“物件”(例如,你的狗)
訓練指令碼
與其他一些訓練指令碼不同,textual_inversion.py 有一個自定義的資料集類,TextualInversionDataset
,用於建立資料集。你可以自定義影像大小、佔位符標記、插值方法、是否裁剪影像等。如果需要更改資料集的建立方式,可以修改 TextualInversionDataset
。
接下來,你將在 main()
函式中找到資料集預處理程式碼和訓練迴圈。
# Load tokenizer
if args.tokenizer_name:
tokenizer = CLIPTokenizer.from_pretrained(args.tokenizer_name)
elif args.pretrained_model_name_or_path:
tokenizer = CLIPTokenizer.from_pretrained(args.pretrained_model_name_or_path, subfolder="tokenizer")
# Load scheduler and models
noise_scheduler = DDPMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler")
text_encoder = CLIPTextModel.from_pretrained(
args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision
)
vae = AutoencoderKL.from_pretrained(args.pretrained_model_name_or_path, subfolder="vae", revision=args.revision)
unet = UNet2DConditionModel.from_pretrained(
args.pretrained_model_name_or_path, subfolder="unet", revision=args.revision
)
接著,將特殊的 佔位符標記 新增到分詞器中,並重新調整嵌入以適應新的標記。
然後,指令碼從 TextualInversionDataset
中 建立一個數據集
train_dataset = TextualInversionDataset(
data_root=args.train_data_dir,
tokenizer=tokenizer,
size=args.resolution,
placeholder_token=(" ".join(tokenizer.convert_ids_to_tokens(placeholder_token_ids))),
repeats=args.repeats,
learnable_property=args.learnable_property,
center_crop=args.center_crop,
set="train",
)
train_dataloader = torch.utils.data.DataLoader(
train_dataset, batch_size=args.train_batch_size, shuffle=True, num_workers=args.dataloader_num_workers
)
最後,訓練迴圈 處理從預測噪聲殘差到更新特殊佔位符標記的嵌入權重等所有其他事情。
如果您想了解更多關於訓練迴圈如何工作的資訊,請檢視 理解管道、模型和排程器 教程,它分解了去噪過程的基本模式。
啟動指令碼
完成所有更改或對預設配置滿意後,您就可以啟動訓練指令碼了!🚀
在本指南中,你將下載一些貓玩具的圖片,並將它們儲存在一個目錄中。但請記住,如果你願意,可以建立並使用自己的資料集(請參閱建立用於訓練的資料集指南)。
from huggingface_hub import snapshot_download
local_dir = "./cat"
snapshot_download(
"diffusers/cat_toy_example", local_dir=local_dir, repo_type="dataset", ignore_patterns=".gitattributes"
)
將環境變數 `MODEL_NAME` 設定為 Hub 上的模型 ID 或本地模型的路徑,並將 `DATA_DIR` 設定為你剛剛下載貓圖片所儲存的路徑。該指令碼會在你的倉庫中建立並儲存以下檔案:
learned_embeds.bin
:與你的示例圖片相對應的學習到的嵌入向量token_identifier.txt
:特殊的佔位符標記type_of_concept.txt
:你正在訓練的概念型別(“物件”或“風格”)
在單個 V100 GPU 上,完整的訓練過程大約需要 1 小時。
在啟動指令碼之前,還有一件事。如果你有興趣跟蹤訓練過程,可以在訓練進行時定期儲存生成的圖片。在訓練命令中新增以下引數:
--validation_prompt="A <cat-toy> train"
--num_validation_images=4
--validation_steps=100
export MODEL_NAME="stable-diffusion-v1-5/stable-diffusion-v1-5"
export DATA_DIR="./cat"
accelerate launch textual_inversion.py \
--pretrained_model_name_or_path=$MODEL_NAME \
--train_data_dir=$DATA_DIR \
--learnable_property="object" \
--placeholder_token="<cat-toy>" \
--initializer_token="toy" \
--resolution=512 \
--train_batch_size=1 \
--gradient_accumulation_steps=4 \
--max_train_steps=3000 \
--learning_rate=5.0e-04 \
--scale_lr \
--lr_scheduler="constant" \
--lr_warmup_steps=0 \
--output_dir="textual_inversion_cat" \
--push_to_hub
訓練完成後,你可以像下面這樣使用新訓練的模型進行推理:
from diffusers import StableDiffusionPipeline
import torch
pipeline = StableDiffusionPipeline.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", torch_dtype=torch.float16).to("cuda")
pipeline.load_textual_inversion("sd-concepts-library/cat-toy")
image = pipeline("A <cat-toy> train", num_inference_steps=50).images[0]
image.save("cat-train.png")
後續步驟
恭喜你訓練了自己的 Textual Inversion 模型!🎉 要了解更多關於如何使用新模型的資訊,以下指南可能會有所幫助:
- 瞭解如何載入 Textual Inversion 嵌入並將其用作負向嵌入。
- 瞭解如何使用 Textual Inversion 進行 Stable Diffusion 1/2 和 Stable Diffusion XL 的推理。