Skip to main content ホーム クリエイター adu2021 skillxiv t-lora-single-image-diffusion-customization
t-lora-single-image-diffusion-customization Personalize diffusion models to learn a concept from a single image without overfitting by using timestep-dependent rank masking and orthogonal weight initialization, enabling faithful concept reproduction while maintaining text-guided control.
インストールへ移動 Skills Marketplace コミュニティが作成したAIスキルを発見・探索
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/ADu2021/skillXiv --skill t-lora-single-image-diffusion-customizationコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
Zipをダウンロード ダウンロード中... このリポジトリの他の Skills meaningful-kebab-case-name Convert arXiv papers into ready-to-use agent skills using category-aware extraction. First classifies the paper into one or more of 11 research categories, then applies a specialized extraction pipeline for each category — because different types of papers produce different types of usable knowledge. A single paper can yield multiple skills if it spans categories. Use this skill whenever the user wants to turn a paper into a skill, extract practical techniques from research, build a skill library from papers, convert arXiv papers into reusable agent instructions, or batch-process multiple papers into skills. Also trigger when someone asks about extracting actionable knowledge from papers, making research practical for LLM agents, or systematically converting academic contributions into structured agent capabilities.
action-quantization-behavior-cloning Establish regret bounds for behavior cloning with discretized actions combining statistical error and quantization error terms. Prove smoothness requirements for safe quantizer design, show that learning-based quantizers fail these requirements, and propose model-based augmentation to reduce error dependence from H² to H.
adaptive-lora-personalized-ranks Dynamically allocate LoRA ranks per-layer during fine-tuning instead of using fixed uniform ranks. Learn optimal rank for each layer and subject via variational framework with discretized exponential distribution, reducing memory footprint while maintaining fidelity and text-alignment.
name t-lora-single-image-diffusion-customization title T-LoRA: Single Image Diffusion Model Customization Without Overfitting version 0.0.2 engine skillxiv-v0.0.2-claude-opus-4.6 license MIT url https://arxiv.org/abs/2507.05964 keywords ["Diffusion Models","Single-Image Personalization","LoRA","Timestep-Dependent Adaptation","Orthogonal Initialization"] description Personalize diffusion models to learn a concept from a single image without overfitting by using timestep-dependent rank masking and orthogonal weight initialization, enabling faithful concept reproduction while maintaining text-guided control.
T-LoRA: Timestep-Dependent Personalization of Diffusion Models
Training diffusion models on a single concept image is notoriously difficult. Standard LoRA quickly overfits: the model memorizes the exact image instead of learning the concept. The root cause is that different denoising timesteps have different susceptibility to overfitting. Early timesteps (high noise) have natural regularization. Late timesteps (low noise, near-pixel level) are prone to memorizing exact pixel patterns. T-LoRA addresses this by dynamically adjusting adapter rank as a function of timestep: fewer parameters at noisy timesteps, more at clean ones.
A complementary insight: standard LoRA matrices accumulate linear dependence that undermines selective activation. T-LoRA applies orthogonal initialization using SVD components, ensuring that masked rank subsets remain effective for meaningful feature learning.
Core Concept
The challenge is learning a visual concept (a person, object, style) from one image while keeping the model generalizable. T-LoRA exploits the fact that the denoising process has natural structure: early timesteps handle coarse structure and are hard to overfit, late timesteps handle details and are easy to overfit. By allocating fewer adapter parameters early and more late, the model can focus on learning genuine concept features rather than pixel memorization.
Orthogonal weight initialization complements this by ensuring that even when you mask out certain rank components, the remaining ones stay active and meaningful. Without orthogonality, masking can create dead components.
Architecture Overview
Timestep-Dependent Rank Function : r(t) = floor((r - r_min) * (T - t) / T) + r_min, allocating higher rank at lower timesteps
Rank Masking : Diagonal matrices selectively activate adapter components during training and inference
Orthogonal LoRA Initialization : Decompose random matrices via SVD, use lower singular components to avoid overfitting
Integrated T-LoRA : Combines both mechanisms for optimal performance
Target Models : Tested on Stable Diffusion-XL and FLUX-1.dev
Implementation
Step 1: Analyze Timestep-Specific Overfitting
First, diagnose which timesteps overfit most by training with fixed-rank adapters and measuring concept fidelity vs. text alignment:
import torch
import torch.nn as nn
from diffusers import StableDiffusionXLPipeline
from peft import get_peft_model, LoraConfig
( ):
pipeline = StableDiffusionXLPipeline.from_pretrained(
)
unet = pipeline.unet
lora_config = LoraConfig(
r= ,
lora_alpha= ,
target_modules=[ , ],
lora_dropout= ,
bias=
)
lora_unet = get_peft_model(unet, lora_config)
optimizer = torch.optim.Adam(lora_unet.parameters(), lr= )
step ( ):
timesteps = torch.randint( , num_timesteps, ( ,))
noisy_image = add_noise_to_concept(concept_image, timesteps[ ])
noise_pred = lora_unet(
noisy_image,
timesteps[ ],
encoder_hidden_states=encode_text(concept_name, pipeline)
).sample
loss = F.mse_loss(noise_pred, torch.randn_like(noise_pred))
loss.backward()
optimizer.step()
optimizer.zero_grad()
fidelity_scores = {}
alignment_scores = {}
t ( , num_timesteps, ):
samples_t = generate_from_concept(
lora_unet, pipeline,
concept_name,
timestep_focus=t,
num_samples=
)
concept_score = measure_clip_similarity(
samples_t, concept_image
)
fidelity_scores[t] = concept_score
random_prompts = [ , , ]
alignment = measure_prompt_alignment(samples_t, random_prompts)
alignment_scores[t] = alignment
( , fidelity_scores)
( , alignment_scores)
( )
fidelity_scores, alignment_scores
( ):
diffusers.schedulers DDPMScheduler
scheduler = DDPMScheduler.from_config(scheduler_config {})
noise = torch.randn_like(image)
noisy = scheduler.add_noise(image, noise, timestep)
noisy
def
diagnose_overfitting_per_timestep
concept_image, concept_name,
test_prompts, num_timesteps=1000
"""
Train fixed-rank LoRA and measure overfitting across timesteps.
Reveals which timesteps are most prone to memorization.
"""
"stabilityai/stable-diffusion-xl-base-1.0"
64
128
"to_q"
"to_v"
0.0
"none"
1e-4
for
in
range
500
0
4
0
0
for
in
range
0
100
5
"a cat"
"a dog"
"a car"
print
"Fidelity by timestep:"
print
"Alignment by timestep:"
print
"Conclusion: higher timesteps likely show memorization"
return
def
add_noise_to_concept
image, timestep, scheduler_config=None
"""Add noise at a specific timestep to the concept image."""
from
import
or
return
Step 2: Implement Vanilla T-LoRA with Rank Masking Allocate fewer parameters at high timesteps (noisy) and more at low timesteps (clean):
class TLoRA (nn.Module):
def __init__ (self, base_module, r_min=4 , r_max=64 , num_timesteps=1000 ):
super ().__init__()
self .base_module = base_module
self .r_min = r_min
self .r_max = r_max
self .num_timesteps = num_timesteps
self .lora_a = nn.Parameter(torch.randn(base_module.in_features, r_max) * 0.01 )
self .lora_b = nn.Parameter(torch.randn(r_max, base_module.out_features) * 0.01 )
self .timestep_to_rank = self ._make_rank_schedule()
def _make_rank_schedule (self ):
"""Create mapping from timestep to active rank."""
schedule = {}
for t in range (self .num_timesteps):
r_t = int ((self .r_max - self .r_min) * (1 - t / self .num_timesteps) + self .r_min)
schedule[t] = r_t
return schedule
def forward (self, x, timestep ):
"""Apply LoRA with timestep-dependent rank masking."""
r_active = self .timestep_to_rank.get(int (timestep.item()), self .r_max)
mask_a = torch.zeros(self .lora_a.shape[1 ], device=self .lora_a.device)
mask_a[:r_active] = 1.0
mask_b = torch.zeros(self .lora_b.shape[0 ], device=self .lora_b.device)
mask_b[:r_active] = 1.0
lora_a_masked = self .lora_a * mask_a
lora_b_masked = self .lora_b * mask_b
lora_out = x @ lora_a_masked @ lora_b_masked
base_out = self .base_module(x)
return base_out + lora_out
def apply_tora_to_unet (unet, r_min=4 , r_max=64 , num_timesteps=1000 ):
"""Replace linear layers in UNet with T-LoRA modules."""
for name, module in unet.named_modules():
if isinstance (module, nn.Linear) and "to_q" in name or "to_v" in name:
tora_module = TLoRA(module, r_min, r_max, num_timesteps)
setattr (unet, name, tora_module)
return unet
Step 3: Implement Orthogonal Weight Initialization (Ortho-LoRA) Initialize LoRA weights using orthogonal components from SVD to prevent linear dependence:
class OrthoLoRA (nn.Module):
"""LoRA with orthogonal weight initialization to prevent overfitting."""
def __init__ (self, base_module, r=64 , lora_alpha=128 ):
super ().__init__()
self .base_module = base_module
self .r = r
self .lora_alpha = lora_alpha
self .lora_a = nn.Parameter(self ._ortho_init(base_module.in_features, r))
self .lora_b = nn.Parameter(self ._ortho_init(r, base_module.out_features))
self .scale = lora_alpha / r
def _ortho_init (self, in_dim, out_dim ):
"""
Initialize with orthogonal components from SVD.
Use lower singular components (least significant) to avoid overfitting.
"""
random_matrix = torch.randn(in_dim, out_dim)
U, S, Vt = torch.linalg.svd(random_matrix, full_matrices=False )
if in_dim >= out_dim:
ortho = U[:, :out_dim]
else :
ortho = Vt[:in_dim, :]
return ortho * 0.01
def forward (self, x ):
"""Apply orthogonal LoRA."""
lora_out = (x @ self .lora_a) @ self .lora_b * self .scale
base_out = self .base_module(x)
return base_out + lora_out
Step 4: Integrated T-LoRA (Timestep-Dependent + Orthogonal) Combine both mechanisms for robust single-image personalization:
class IntegratedTLoRA (nn.Module):
"""Combined T-LoRA: timestep-dependent rank + orthogonal initialization."""
def __init__ (self, base_module, r_min=4 , r_max=64 , num_timesteps=1000 ):
super ().__init__()
self .base_module = base_module
self .r_min = r_min
self .r_max = r_max
self .num_timesteps = num_timesteps
self .lora_a = nn.Parameter(self ._ortho_init(base_module.in_features, r_max))
self .lora_b = nn.Parameter(self ._ortho_init(r_max, base_module.out_features))
def _ortho_init (self, in_dim, out_dim ):
"""Orthogonal initialization."""
random_matrix = torch.randn(in_dim, out_dim)
U, S, Vt = torch.linalg.svd(random_matrix, full_matrices=False )
if in_dim >= out_dim:
return U[:, :out_dim] * 0.01
else :
return Vt[:in_dim, :] * 0.01
def _get_rank_for_timestep (self, timestep ):
"""Get active rank based on timestep."""
t = timestep.item() if isinstance (timestep, torch.Tensor) else timestep
r_t = int ((self .r_max - self .r_min) * (1 - t / self .num_timesteps) + self .r_min)
return max (self .r_min, min (self .r_max, r_t))
def forward (self, x, timestep ):
"""Apply T-LoRA with timestep-dependent rank masking."""
r_active = self ._get_rank_for_timestep(timestep)
mask_a = torch.zeros_like(self .lora_a)
mask_a[:, :r_active] = 1.0
mask_b = torch.zeros_like(self .lora_b)
mask_b[:r_active, :] = 1.0
lora_a_masked = self .lora_a * mask_a
lora_b_masked = self .lora_b * mask_b
lora_out = (x @ lora_a_masked) @ lora_b_masked
base_out = self .base_module(x)
return base_out + lora_out
def train_concept_with_tlora (concept_image, concept_name, model_name="stabilityai/stable-diffusion-xl-base-1.0" ):
"""Train T-LoRA on a single concept image."""
pipeline = StableDiffusionXLPipeline.from_pretrained(model_name)
unet = pipeline.unet
tora_modules = {}
for name, module in unet.named_modules():
if isinstance (module, nn.Linear) and ("to_q" in name or "to_v" in name):
tora_mod = IntegratedTLoRA(module, r_min=4 , r_max=64 )
tora_modules[name] = tora_mod
optimizer = torch.optim.Adam(
[p for m in tora_modules.values() for p in m.parameters()],
lr=1e-4
)
for step in range (800 ):
t = torch.randint(0 , 1000 , (1 ,))
noisy_concept = add_noise_to_concept(concept_image, t)
prompts = [
f"a photo of {concept_name} " ,
f"{concept_name} in the style of Van Gogh" ,
f"close-up of {concept_name} " ,
f"{concept_name} , professional photography"
]
prompt = prompts[step % len (prompts)]
text_embeddings = pipeline.encode_prompt(prompt)
noise_pred = unet(
noisy_concept,
t,
encoder_hidden_states=text_embeddings
).sample
loss = F.mse_loss(noise_pred, torch.randn_like(noise_pred))
loss.backward()
optimizer.step()
optimizer.zero_grad()
if step % 100 == 0 :
print (f"Step {step} : loss = {loss.item():.4 f} " )
return pipeline, tora_modules
Practical Guidance Component Recommended Value Notes r_min (minimum rank) 4 Constrains high-timestep (noisy) parameters r_max (maximum rank) 64 Can go to 128 for complex concepts Learning Rate 1e-4 Conservative to avoid instability Training Steps 500-800 SD-XL; fewer for simpler models Batch Size 1 Single image personalization Optimizer AdamW Standard choice Timestep Range 0-1000 Full DDPM schedule Orthogonal Init Yes Critical for preventing overfitting Rank Mask Yes Essential for timestep-specific control CLIP Similarity > 0.85 Target for concept fidelity Prompt Alignment > 0.75 Target for maintaining text control
Single-image personalization (concept learning from one photo)
Applications prioritizing concept fidelity over memory efficiency
Fine art, illustration, or photographic style transfer
Scenarios where both concept accuracy and text control matter
Multi-image personalization (standard DreamBooth scales better)
Memory-constrained deployment (LoRA still requires adapter parameters)
Extremely complex concepts requiring hundreds of reference images
Real-time inference (training time is acceptable, inference is fast)
Not including orthogonal initialization, causing rank masking to be ineffective
r_min too high (> 8), losing ability to regulate overfitting
Timestep-dependent rank too aggressive (inverted), encouraging memorization
Training for too few steps (< 300), concept not properly learned
Using too-high learning rate, causing instability
Not normalizing concept image to [0, 1] range
Forgetting to vary prompts during training, leading to prompt-specific overfitting
Reference Wang, X., Li, X., Chen, H., & Zhou, L. (2025). T-LoRA: Single Image Diffusion Model Customization Without Overfitting. arXiv:2507.05964. https://arxiv.org/abs/2507.05964