Diffusers documentation
LoRA
LoRA
LoRA (Low-Rank Adaptation) điều chỉnh một mô hình được huấn luyện trước cho một tác vụ mới bằng cách đóng băng các trọng số gốc và huấn luyện một tập hợp nhỏ các tham số mới. Quá trình điều chỉnh nhanh hơn và rẻ hơn so với fine-tuning toàn bộ, giúp phương pháp này trở nên thực tế cho các tác vụ như tạo ảnh theo phong cách mới.
Checkpoint LoRA thường chỉ nặng vài trăm MB. Hãy tải chúng bằng pipeline.load_lora_weights và đặt weight_name thành tên tệp checkpoint. Xem load_lora_weights() để biết các tham số chung.
import torch
from diffusers import AutoPipelineForText2Image
pipeline = AutoPipelineForText2Image.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
dtype=torch.float16
).to("cuda") # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
"ostris/super-cereal-sdxl-lora",
weight_name="cereal_box_sdxl_v1.safetensors",
adapter_name="cereal"
)
pipeline("bears, pizza bites").images[0]import torch
from diffusers import LTXConditionPipeline
from diffusers.utils import export_to_video, load_image
pipeline = LTXConditionPipeline.from_pretrained(
"Lightricks/LTX-Video-0.9.5", dtype=torch.bfloat16
).to("cuda") # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
"Lightricks/LTX-Video-Cakeify-LoRA",
weight_name="ltxv_095_cakeify_lora.safetensors",
adapter_name="cakeify"
)
pipeline.set_adapters("cakeify")
# use "CAKEIFY" to trigger the LoRA
prompt = "CAKEIFY a person using a knife to cut a cake shaped like a Pikachu plushie"
image = load_image("https://huggingface.co/Lightricks/LTX-Video-Cakeify-LoRA/resolve/main/assets/images/pikachu.png")
video = pipeline(
prompt=prompt,
image=image,
width=576,
height=576,
num_frames=161,
decode_timestep=0.03,
decode_noise_scale=0.025,
num_inference_steps=50,
).frames[0]
export_to_video(video, "output.mp4", fps=26)Các API pipeline LoRA trên trang này hoạt động giống nhau giữa các họ model. Module denoising là pipeline.unet trên Stable Diffusion và SDXL, và là pipeline.transformer trên các model kiểu DiT như Flux, Stable Diffusion 3, AuraFlow và LTX. Mẫu hình tương tự cũng áp dụng cho các model video như CogVideoX, HunyuanVideo và Wan. Các phương pháp PEFT ở cấp model sử dụng thuộc tính đó cùng với prefix tương ứng ("unet" hoặc "transformer").
pipeline.load_lora_weights là cách được khuyến nghị để nạp trọng số LoRA vào denoiser (UNet hoặc transformer) và các text encoder. Xem load_lora_weights() để biết các tham số chung. Nó có thể xử lý các trường hợp sau:
- checkpoint chia sẻ các khóa giữa denoiser và các text encoder
- checkpoint sử dụng các khóa denoiser và text-encoder riêng biệt
Phương thức load_lora_adapter() nạp một bộ thích ứng LoRA ở cấp mô hình trên bất kỳ mô hình Diffusers nào kế thừa từ PeftAdapterMixin, chẳng hạn như UNet hoặc transformer. Nó xây dựng và chuẩn bị cấu hình bộ thích ứng, sau đó nạp trọng số vào module đó.
Sử dụng prefix để lọc các khóa state dict cho module đích ("unet" hoặc "transformer"). Mặc định là "transformer", do đó Stable Diffusion và SDXL phải truyền prefix="unet".
import torch
from diffusers import AutoPipelineForText2Image
pipeline = AutoPipelineForText2Image.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
dtype=torch.float16
).to("cuda") # or "mps", "xpu", "cpu"
pipeline.unet.load_lora_adapter(
"jbilcke-hf/sdxl-cinematic-1",
weight_name="pytorch_lora_weights.safetensors",
adapter_name="cinematic",
prefix="unet"
)
# use cnmt in the prompt to trigger the LoRA
pipeline("A cute cnmt eating a slice of pizza, stunning color scheme, masterpiece, illustration").images[0]import torch
from diffusers import FluxPipeline
pipeline = FluxPipeline.from_pretrained(
"black-forest-labs/FLUX.1-dev", dtype=torch.bfloat16
).to("cuda") # or "mps", "xpu", "cpu"
pipeline.transformer.load_lora_adapter(
"alvarobartt/ghibli-characters-flux-lora",
adapter_name="lora",
prefix="transformer",
)torch.compile
torch.compile tăng tốc độ suy luận bằng cách biên dịch mô hình PyTorch để sử dụng các kernel được tối ưu hóa. Trước khi biên dịch, cần phải hợp nhất trọng số LoRA vào mô hình cơ sở và gỡ bỏ chúng trước.
import torch
from diffusers import DiffusionPipeline
# load base model and LoRA
pipeline = DiffusionPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
dtype=torch.float16
).to("cuda") # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
"ostris/ikea-instructions-lora-sdxl",
weight_name="ikea_instructions_xl_v1_5.safetensors",
adapter_name="ikea"
)
# activate LoRA and set adapter weight
pipeline.set_adapters("ikea", adapter_weights=0.7)
# fuse LoRAs and unload weights
pipeline.fuse_lora(adapter_names=["ikea"], lora_scale=1.0)
pipeline.unload_lora_weights()Thông thường, hãy biên dịch denoiser vì đây là thành phần tiêu tốn nhiều tài nguyên tính toán nhất trong pipeline.
pipeline.unet.to(memory_format=torch.channels_last)
pipeline.unet = torch.compile(pipeline.unet, mode="reduce-overhead", fullgraph=True)
pipeline("A bowl of ramen shaped like a cute kawaii bear").images[0]Đối với Flux và các pipeline DiT khác, hãy biên dịch pipeline.transformer thay vào đó.
pipeline.transformer = torch.compile(pipeline.transformer, mode="reduce-overhead", fullgraph=True)Tham khảo phần hotswapping để tìm hiểu cách tránh biên dịch lại khi làm việc với các mô hình đã biên dịch và nhiều LoRA.
Thang đo trọng số
Sử dụng tham số adapter_weights trong set_adapters() để kiểm soát mức độ áp dụng của LoRA. Trọng số 0 tương đương với việc chỉ sử dụng trọng số của mô hình cơ sở, còn trọng số 1 tương đương với việc sử dụng hoàn toàn LoRA.
Truyền một giá trị vô hướng vào adapter_weights trong set_adapters() để kiểm soát mức độ mạnh của việc áp dụng LoRA.
import torch
from diffusers import AutoPipelineForText2Image
pipeline = AutoPipelineForText2Image.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
dtype=torch.float16
).to("cuda") # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
"ostris/super-cereal-sdxl-lora",
weight_name="cereal_box_sdxl_v1.safetensors",
adapter_name="cereal"
)
pipeline.set_adapters("cereal", adapter_weights=1.0)
pipeline("bears, pizza bites").images[0]set_adapters là mẫu chính, nhưng một số pipeline cũng chấp nhận cross_attention_kwargs={"scale": 1.0} trong lời gọi như một cách phụ để điều chỉnh attention. Các pipeline không sử dụng cross-attention thường phơi bày attention_kwargs thay thế (hoặc joint_attention_kwargs trên Flux và Stable Diffusion 3).
Phương thức set_adapters() chỉ điều chỉnh trọng số chú ý. Nếu một LoRA có ResNets hoặc bộ giảm mẫu và tăng mẫu, các thành phần này giữ giá trị tỷ lệ là
1.0.
Truyền một từ điển để mở rộng từng khối text encoder hoặc denoiser. Các khóa trong từ điển tuân theo các module của pipeline. Ví dụ bên dưới là SDXL (unet cùng các text encoder). Flux sử dụng transformer và text_encoder. SD3 sử dụng transformer và nhiều text encoder.
Trong ví dụ SDXL này, khối "down" trong UNet được nhân với 0.9 và bạn có thể chỉ định thêm tỷ lệ cho các khối attention trong "block_0" và "block_1" dưới "up". Nếu một khối như "mid" không được chỉ định, giá trị mặc định 1.0 sẽ được sử dụng.
import torch
from diffusers import AutoPipelineForText2Image
pipeline = AutoPipelineForText2Image.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
dtype=torch.float16
).to("cuda") # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
"ostris/super-cereal-sdxl-lora",
weight_name="cereal_box_sdxl_v1.safetensors",
adapter_name="cereal"
)
scales = {
"text_encoder": 0.5,
"text_encoder_2": 0.5,
"unet": {
"down": 0.9,
"up": {
"block_0": 0.6,
"block_1": [0.4, 0.8, 1.0],
}
}
}
pipeline.set_adapters("cereal", scales)
pipeline("bears, pizza bites").images[0]Lịch trình mở rộng
Việc điều chỉnh động thang đo LoRA trong quá trình lấy mẫu giúp bạn kiểm soát tốt hơn bố cục và tổng thể của hình ảnh, vì một số bước có thể được hưởng lợi nhiều hơn từ việc tăng hoặc giảm thang đo.
character LoRA trong ví dụ dưới đây bắt đầu với một scale cao hơn, sau đó giảm dần trong 20 bước đầu tiên để thiết lập việc tạo nhân vật. Ở các bước sau, chỉ áp dụng scale 0.2 để tránh thêm quá nhiều đặc trưng của LoRA vào các phần khác của hình ảnh mà LoRA không được huấn luyện.
import torch
from diffusers import FluxPipeline
pipeline = FluxPipeline.from_pretrained(
"black-forest-labs/FLUX.1-dev", dtype=torch.bfloat16
).to("cuda") # or "mps", "xpu", "cpu"
pipeline.load_lora_weights("alvarobartt/ghibli-characters-flux-lora", adapter_name="lora")
num_inference_steps = 30
lora_steps = 20
lora_scales = torch.linspace(1.5, 0.7, lora_steps).tolist()
lora_scales += [0.2] * (num_inference_steps - lora_steps + 1)
pipeline.set_adapters("lora", lora_scales[0])
def callback(pipeline: FluxPipeline, step: int, timestep: torch.LongTensor, callback_kwargs: dict):
pipeline.set_adapters("lora", lora_scales[step + 1])
return callback_kwargs
prompt = """
Ghibli style The Grinch, a mischievous green creature with a sly grin, peeking out from behind a snow-covered tree while plotting his antics,
in a quaint snowy village decorated for the holidays, warm light glowing from cozy homes, with playful snowflakes dancing in the air
"""
pipeline(
prompt=prompt,
guidance_scale=3.0,
num_inference_steps=num_inference_steps,
generator=torch.Generator().manual_seed(42),
callback_on_step_end=callback,
).images[0]Hotswapping
Hotswapping LoRAs là một cách hiệu quả để làm việc với nhiều LoRA trong khi tránh việc tích lũy bộ nhớ từ nhiều lần gọi load_lora_weights và trong một số trường hợp, tránh việc biên dịch lại, nếu mô hình đã được biên dịch. Quy trình làm việc này yêu cầu một LoRA đã được nạp vì trọng số LoRA mới sẽ được thay thế tại chỗ cho LoRA hiện có đã được nạp.
import torch
from diffusers import DiffusionPipeline
# load base model and LoRAs
pipeline = DiffusionPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
dtype=torch.float16
).to("cuda") # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
"ostris/ikea-instructions-lora-sdxl",
weight_name="ikea_instructions_xl_v1_5.safetensors",
adapter_name="ikea"
)Chức năng Hotswapping không được hỗ trợ cho các LoRA nhắm vào text encoder.
Đặt hotswap=True trên load_lora_weights để thay thế LoRA thứ hai. Sử dụng tham số adapter_name để chỉ định LoRA cần thay thế. Nếu bạn bỏ qua adapter_name khi tải, Diffusers sẽ đặt tên cho các adapter là default_0, default_1, và tiếp tục như vậy. Các adapter có tên sẽ dễ nhắm đến một cách rõ ràng hơn.
pipeline.load_lora_weights(
"lordjia/by-feng-zikai",
hotswap=True,
adapter_name="ikea"
)Các mô hình đã biên dịch
Đối với các mô hình đã biên dịch, hãy sử dụng enable_lora_hotswap() để tránh việc biên dịch lại khi hotswap các LoRA. Phương thức này nên được gọi trước khi nạp LoRA đầu tiên và torch.compile nên được gọi sau khi nạp LoRA đầu tiên.
Phương thức enable_lora_hotswap() không phải lúc nào cũng cần thiết nếu LoRA thứ hai nhắm đến các rank và scales LoRA giống hệt với LoRA đầu tiên.
Trong enable_lora_hotswap(), đặt target_rank bằng rank cao nhất trong số các adapter bạn dự định tải (mặc định là 128).
import torch
from diffusers import DiffusionPipeline
# load base model and LoRAs
pipeline = DiffusionPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
dtype=torch.float16
).to("cuda") # or "mps", "xpu", "cpu"
# 1. enable_lora_hotswap
pipeline.enable_lora_hotswap(target_rank=128)
pipeline.load_lora_weights(
"ostris/ikea-instructions-lora-sdxl",
weight_name="ikea_instructions_xl_v1_5.safetensors",
adapter_name="ikea"
)
# 2. torch.compile
pipeline.unet = torch.compile(pipeline.unet, mode="reduce-overhead", fullgraph=True)
# 3. hotswap
pipeline.load_lora_weights(
"lordjia/by-feng-zikai",
hotswap=True,
adapter_name="ikea"
)Di chuyển mã của bạn vào trong trình quản lý ngữ cảnh
with torch._dynamo.config.patch(error_on_recompile=True)để phát hiện xem mô hình có bị biên dịch lại hay không. Nếu mô hình vẫn bị biên dịch lại dù bạn đã thực hiện tất cả các bước ở trên, vui lòng mở một issue kèm theo một ví dụ có thể tái hiện được.
Nếu bạn dự kiến độ phân giải thay đổi trong quá trình suy luận với tính năng này, hãy đảm bảo đặt dynamic=True khi biên dịch. Tham khảo biên dịch hình dạng động để biết thêm chi tiết.
Vẫn còn một số kịch bản mà việc biên dịch lại là không thể tránh khỏi, chẳng hạn như khi LoRA được hotswap nhắm đến nhiều lớp hơn so với adapter ban đầu. Hãy cố gắng tải LoRA nhắm đến nhiều lớp nhất trước tiên. Để biết thêm chi tiết về hạn chế này, hãy tham khảo tài liệu hotswapping của PEFT.
Why `target_rank` and load order matter
Phương thức enable_lora_hotswap() chuyển hệ số tỷ lệ LoRA từ float sang torch.tensors và đệm (pad) hình dạng của trọng số lên hình dạng lớn nhất cần thiết để tránh việc gán lại toàn bộ thuộc tính khi dữ liệu trong trọng số được thay thế.
Đây là lý do tại sao đối số target_rank lại quan trọng. Kết quả không thay đổi ngay cả khi các giá trị được đệm bằng số không. Tuy nhiên, quá trình tính toán có thể chậm hơn tùy thuộc vào kích thước đệm.
Vì không có thuộc tính LoRA mới nào được thêm vào, mỗi LoRA tiếp theo chỉ được phép nhắm đến cùng các lớp, hoặc một tập con của các lớp, mà LoRA đầu tiên nhắm đến. Việc chọn thứ tự nạp LoRA là quan trọng vì nếu các LoRA nhắm đến các lớp không giao nhau, bạn có thể kết thúc với việc tạo ra một LoRA giả nhắm đến tập hợp của tất cả các lớp đích.
Xem bài đăng trên blog LoRA fast để biết thêm về việc hotswap LoRA với các mô hình đã được biên dịch, và để xem chi tiết triển khai, hãy xem tệp hotswap.py.
Merge
Trọng số từ mỗi LoRA có thể được gộp lại để tạo ra sự pha trộn của nhiều phong cách hiện có. Có một số phương pháp để gộp LoRA, mỗi phương pháp khác nhau ở cách các trọng số được gộp (có thể ảnh hưởng đến chất lượng tạo ra).
set_adapters
Phương thức set_adapters() kết hợp các LoRA bằng cách nối các ma trận có trọng số của chúng. Truyền tên các LoRA vào set_adapters() và sử dụng tham số adapter_weights để kiểm soát việc mở rộng của từng LoRA. Ví dụ, nếu adapter_weights=[0.5, 0.5], kết quả đầu ra sẽ là trung bình của cả hai LoRA.
Ưu tiên sử dụng
adapter_weightstrong set_adapters() để kiểm soát mức độ áp dụng của từng LoRA đã hợp nhất. Xem phần Weight scale để biết thêm chi tiết.
import torch
from diffusers import DiffusionPipeline
pipeline = DiffusionPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
dtype=torch.float16
).to("cuda") # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
"ostris/ikea-instructions-lora-sdxl",
weight_name="ikea_instructions_xl_v1_5.safetensors",
adapter_name="ikea"
)
pipeline.load_lora_weights(
"lordjia/by-feng-zikai",
weight_name="fengzikai_v1.0_XL.safetensors",
adapter_name="feng"
)
pipeline.set_adapters(["ikea", "feng"], adapter_weights=[0.7, 0.8])
# use by Feng Zikai to activate the lordjia/by-feng-zikai LoRA
pipeline("A bowl of ramen shaped like a cute kawaii bear, by Feng Zikai").images[0]add_weighted_adapter
Đây là một phương pháp thử nghiệm và bạn có thể tham khảo Model merging của PEFT để biết thêm chi tiết. Xem issue này nếu bạn quan tâm đến động lực và thiết kế đằng sau tích hợp này.
Phương thức add_weighted_adapter cho phép sử dụng các phương pháp gộp hiệu quả hơn như TIES hoặc DARE. Các phương pháp gộp này loại bỏ các tham số dư thừa và có thể gây xung đột khỏi các mô hình đã gộp. Lưu ý rằng các rank của LoRA cần có cùng rank để có thể gộp. Bài hướng dẫn bên dưới sử dụng UNet của SDXL.
Hãy đảm bảo rằng phiên bản ổn định mới nhất của Diffusers và PEFT đã được cài đặt.
pip install -U -q diffusers peft
Tải một UNet tương ứng với UNet LoRA.
import copy
import torch
from diffusers import AutoModel, DiffusionPipeline
from peft import get_peft_model, LoraConfig, PeftModel
unet = AutoModel.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
dtype=torch.float16,
use_safetensors=True,
variant="fp16",
subfolder="unet",
).to("cuda") # or "mps", "xpu", "cpu"Tải một pipeline, truyền UNet vào nó và tải một LoRA.
pipeline = DiffusionPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
variant="fp16",
dtype=torch.float16,
unet=unet
).to("cuda") # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
"ostris/ikea-instructions-lora-sdxl",
weight_name="ikea_instructions_xl_v1_5.safetensors",
adapter_name="ikea"
)Tạo một PeftModel từ checkpoint LoRA bằng cách kết hợp UNet đầu tiên bạn đã tải và LoRA UNet từ pipeline.
sdxl_unet = copy.deepcopy(unet)
ikea_peft_model = get_peft_model(
sdxl_unet,
pipeline.unet.peft_config["ikea"],
adapter_name="ikea"
)
original_state_dict = {f"base_model.model.{k}": v for k, v in pipeline.unet.state_dict().items()}
ikea_peft_model.load_state_dict(original_state_dict, strict=True)Bạn có thể lưu và tái sử dụng
ikea_peft_modelbằng cách đẩy nó lên Hub như minh họa bên dưới.ikea_peft_model.push_to_hub("ikea_peft_model", token=TOKEN)
Lặp lại quy trình này và tạo một PeftModel cho LoRA thứ hai.
pipeline.delete_adapters("ikea")
sdxl_unet.delete_adapters("ikea")
pipeline.load_lora_weights(
"lordjia/by-feng-zikai",
weight_name="fengzikai_v1.0_XL.safetensors",
adapter_name="feng"
)
pipeline.set_adapters(adapter_names="feng")
feng_peft_model = get_peft_model(
sdxl_unet,
pipeline.unet.peft_config["feng"],
adapter_name="feng"
)
original_state_dict = {f"base_model.model.{k}": v for k, v in pipeline.unet.state_dict().items()}
feng_peft_model.load_state_dict(original_state_dict, strict=True)Tải một mô hình UNet cơ sở và tải các adapter.
base_unet = AutoModel.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
dtype=torch.float16,
use_safetensors=True,
variant="fp16",
subfolder="unet",
).to("cuda") # or "mps", "xpu", "cpu"
model = PeftModel.from_pretrained(
base_unet,
"stevhliu/ikea_peft_model",
use_safetensors=True,
subfolder="ikea",
adapter_name="ikea"
)
model.load_adapter(
"stevhliu/feng_peft_model",
use_safetensors=True,
subfolder="feng",
adapter_name="feng"
)Gộp các LoRA bằng add_weighted_adapter và chỉ định cách bạn muốn gộp chúng bằng combination_type. Ví dụ bên dưới sử dụng phương pháp "dare_linear" (xem bài đăng trên blog này để tìm hiểu thêm về các phương pháp gộp này), trong đó phương pháp này sẽ cắt bỏ ngẫu nhiên một số trọng số và sau đó thực hiện tổng có trọng số của các tensor dựa trên trọng số được đặt cho từng LoRA trong weights.
Kích hoạt các LoRA đã hợp nhất bằng set_adapters().
model.add_weighted_adapter(
adapters=["ikea", "feng"],
combination_type="dare_linear",
weights=[1.0, 1.0],
adapter_name="ikea-feng"
)
model.set_adapters("ikea-feng")
pipeline = DiffusionPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
unet=model,
variant="fp16",
dtype=torch.float16,
).to("cuda") # or "mps", "xpu", "cpu"
pipeline("A bowl of ramen shaped like a cute kawaii bear, by Feng Zikai").images[0]fuse_lora
Phương thức fuse_lora() hợp nhất trọng số LoRA trực tiếp với trọng số của bộ khử nhiễu gốc (UNet hoặc transformer) và bộ mã hóa văn bản của mô hình nền. Điều này làm giảm chi phí tải mô hình nền cho mỗi LoRA vì mô hình chỉ được tải một lần, từ đó giảm mức sử dụng bộ nhớ và tăng tốc độ suy luận.
import torch
from diffusers import DiffusionPipeline
pipeline = DiffusionPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
dtype=torch.float16
).to("cuda") # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
"ostris/ikea-instructions-lora-sdxl",
weight_name="ikea_instructions_xl_v1_5.safetensors",
adapter_name="ikea"
)
pipeline.load_lora_weights(
"lordjia/by-feng-zikai",
weight_name="fengzikai_v1.0_XL.safetensors",
adapter_name="feng"
)
pipeline.set_adapters(["ikea", "feng"], adapter_weights=[0.7, 0.8])Gọi fuse_lora() để hợp nhất chúng. Tham số lora_scale kiểm soát mức độ nhân kết quả với trọng số LoRA. Việc điều chỉnh này cần được thực hiện ngay bây giờ vì việc truyền scale vào cross_attention_kwargs sẽ không hoạt động trong pipeline.
pipeline.fuse_lora(adapter_names=["ikea", "feng"], lora_scale=1.0)Gỡ bỏ trọng số LoRA vì chúng đã được hợp nhất với mô hình nền. Lưu pipeline đã hợp nhất bằng cách sử dụng save_pretrained() để lưu cục bộ hoặc ~PushToHubMixin.push_to_hub để lưu lên Hub.
pipeline.unload_lora_weights()
pipeline.save_pretrained("path/to/fused-pipeline")pipeline.unload_lora_weights()
pipeline.push_to_hub("fused-ikea-feng")Pipeline đã được hợp nhất giờ có thể được tải nhanh chóng để suy luận mà không cần phải tải riêng từng LoRA.
pipeline = DiffusionPipeline.from_pretrained(
"username/fused-ikea-feng", dtype=torch.float16,
).to("cuda") # or "mps", "xpu", "cpu"
pipeline("A bowl of ramen shaped like a cute kawaii bear, by Feng Zikai").images[0]Sử dụng unfuse_lora() để khôi phục trọng số của mô hình gốc, chẳng hạn khi bạn muốn sử dụng một giá trị lora_scale khác. Bạn chỉ có thể thực hiện unfuse nếu có đúng một LoRA đã được fuse. Ví dụ, thao tác này sẽ không hoạt động với pipeline ở trên vì có nhiều LoRA đã được fuse. Trong những trường hợp như vậy, bạn sẽ cần tải lại toàn bộ mô hình.
pipeline.unfuse_lora()
Quản lý
Diffusers cung cấp một số phương pháp giúp bạn quản lý việc làm việc với LoRA. Các phương pháp này đặc biệt hữu ích nếu bạn đang làm việc với nhiều LoRA.
set_adapters
set_adapters() cũng kích hoạt LoRA hiện tại để sử dụng nếu có nhiều LoRA đang hoạt động. Điều này cho phép bạn chuyển đổi giữa các LoRA khác nhau bằng cách chỉ định tên của chúng.
import torch
from diffusers import DiffusionPipeline
pipeline = DiffusionPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
dtype=torch.float16
).to("cuda") # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
"ostris/ikea-instructions-lora-sdxl",
weight_name="ikea_instructions_xl_v1_5.safetensors",
adapter_name="ikea"
)
pipeline.load_lora_weights(
"lordjia/by-feng-zikai",
weight_name="fengzikai_v1.0_XL.safetensors",
adapter_name="feng"
)
# activates the feng LoRA instead of the ikea LoRA
pipeline.set_adapters("feng")save_lora_adapter
Lưu một adapter bằng save_lora_adapter() trên cùng module mà bạn đã nạp vào (pipeline.unet hoặc pipeline.transformer).
import torch
from diffusers import AutoPipelineForText2Image
pipeline = AutoPipelineForText2Image.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
dtype=torch.float16
).to("cuda") # or "mps", "xpu", "cpu"
pipeline.unet.load_lora_adapter(
"jbilcke-hf/sdxl-cinematic-1",
weight_name="pytorch_lora_weights.safetensors",
adapter_name="cinematic",
prefix="unet"
)
pipeline.unet.save_lora_adapter("path/to/save", adapter_name="cinematic")unload_lora_weights
Phương thức unload_lora_weights() sẽ gỡ bỏ các trọng số LoRA trong pipeline để khôi phục các trọng số của mô hình gốc.
pipeline.unload_lora_weights()
disable_lora
Phương thức disable_lora() tắt tất cả các LoRA (nhưng chúng vẫn được giữ trong pipeline) và khôi phục pipeline về trọng số mô hình cơ bản.
pipeline.disable_lora()
get_active_adapters
Phương thức get_active_adapters() trả về danh sách các LoRA đang hoạt động được gắn vào một pipeline.
pipeline.get_active_adapters()
# ["cereal", "ikea"]get_list_adapters
Phương thức get_list_adapters() trả về tất cả các LoRA đã được nạp cho từng thành phần trong pipeline. Các khóa trong từ điển khớp với các module đã được nạp, chẳng hạn như unet hoặc transformer và bất kỳ text encoder nào.
pipeline.get_list_adapters()
# {"unet": ["cereal", "ikea"], "text_encoder_2": ["cereal"]}delete_adapters
Phương thức delete_adapters() xóa hoàn toàn một LoRA cùng các lớp của nó khỏi mô hình.
pipeline.delete_adapters("ikea")Các bước tiếp theo
- Duyệt LoRA Studio để xem các LoRA khác nhau có thể sử dụng, hoặc bạn có thể tải lên Hub các LoRA yêu thích từ Civitai bằng Space bên dưới.
Bạn có thể tìm thêm các LoRA khác trong các Space FLUX LoRA the Explorer và LoRA the Explorer.
Xem bài viết trên blog Fast LoRA inference for Flux with Diffusers and PEFT để tìm hiểu cách tối ưu hóa suy luận LoRA bằng các phương pháp như FlashAttention-3 và lượng tử hóa fp8.