Text-to-Image
Diffusers
Safetensors
sd3
sd3-diffusers
simpletuner
Not-For-All-Audiences
lora
template:sd-lora
lycoris
license: other | |
base_model: "stabilityai/stable-diffusion-3.5-medium" | |
tags: | |
- sd3 | |
- sd3-diffusers | |
- text-to-image | |
- diffusers | |
- simpletuner | |
- not-for-all-audiences | |
- lora | |
- template:sd-lora | |
- lycoris | |
inference: true | |
widget: | |
- text: 'unconditional (blank prompt)' | |
parameters: | |
negative_prompt: 'blurry, cropped, ugly' | |
output: | |
url: ./assets/image_0_0.png | |
- text: 'a portrait of a nude emver1rev1 in a room sitting on a sofa with her legs spread wide.' | |
parameters: | |
negative_prompt: 'blurry, cropped, ugly' | |
output: | |
url: ./assets/image_1_0.png | |
# ematest | |
This is a LyCORIS adapter derived from [stabilityai/stable-diffusion-3.5-medium](https://huggingface.co/stabilityai/stable-diffusion-3.5-medium). | |
The main validation prompt used during training was: | |
``` | |
a portrait of a nude emver1rev1 in a room sitting on a sofa with her legs spread wide. | |
``` | |
## Validation settings | |
- CFG: `4.0` | |
- CFG Rescale: `0.0` | |
- Steps: `30` | |
- Sampler: `FlowMatchEulerDiscreteScheduler` | |
- Seed: `42` | |
- Resolution: `1024x1024` | |
- Skip-layer guidance: | |
skip_guidance_layers=[7, 8, 9], | |
Note: The validation settings are not necessarily the same as the [training settings](#training-settings). | |
You can find some example images in the following gallery: | |
<Gallery /> | |
The text encoder **was not** trained. | |
You may reuse the base model text encoder for inference. | |
## Training settings | |
- Training epochs: 17 | |
- Training steps: 300 | |
- Learning rate: 1e-06 | |
- Learning rate schedule: polynomial | |
- Warmup steps: 1084 | |
- Max grad norm: 0.01 | |
- Effective batch size: 6 | |
- Micro-batch size: 6 | |
- Gradient accumulation steps: 1 | |
- Number of GPUs: 1 | |
- Gradient checkpointing: True | |
- Prediction type: flow-matching (extra parameters=['flux_schedule_auto_shift', 'shift=0.0', 'flux_use_uniform_schedule']) | |
- Optimizer: adamw_bf16 | |
- Trainable parameter precision: Pure BF16 | |
- Caption dropout probability: 10.0% | |
### LyCORIS Config: | |
```json | |
{ | |
"bypass_mode": true, | |
"algo": "lokr", | |
"multiplier": 1.0, | |
"full_matrix": true, | |
"linear_dim": 10000, | |
"linear_alpha": 1, | |
"factor": 4, | |
"apply_preset": { | |
"target_module": [ | |
"Attention", | |
"FeedForward" | |
], | |
"module_algo_map": { | |
"FeedForward": { | |
"factor": 4 | |
}, | |
"Attention": { | |
"factor": 2 | |
} | |
} | |
} | |
} | |
``` | |
## Datasets | |
### emver1rev1 | |
- Repeats: 0 | |
- Total number of images: 102 | |
- Total number of aspect buckets: 1 | |
- Resolution: 1.0 megapixels | |
- Cropped: true | |
- Crop style: center | |
- Crop aspect: square | |
- Used for regularisation data: No | |
## Inference | |
```python | |
import torch | |
from diffusers import DiffusionPipeline | |
from lycoris import create_lycoris_from_weights | |
def download_adapter(repo_id: str): | |
import os | |
from huggingface_hub import hf_hub_download | |
adapter_filename = "pytorch_lora_weights.safetensors" | |
cache_dir = os.environ.get('HF_PATH', os.path.expanduser('~/.cache/huggingface/hub/models')) | |
cleaned_adapter_path = repo_id.replace("/", "_").replace("\\", "_").replace(":", "_") | |
path_to_adapter = os.path.join(cache_dir, cleaned_adapter_path) | |
path_to_adapter_file = os.path.join(path_to_adapter, adapter_filename) | |
os.makedirs(path_to_adapter, exist_ok=True) | |
hf_hub_download( | |
repo_id=repo_id, filename=adapter_filename, local_dir=path_to_adapter | |
) | |
return path_to_adapter_file | |
model_id = 'stabilityai/stable-diffusion-3.5-medium' | |
adapter_repo_id = 'alexnvo/ematest' | |
adapter_filename = 'pytorch_lora_weights.safetensors' | |
adapter_file_path = download_adapter(repo_id=adapter_repo_id) | |
pipeline = DiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.bfloat16) # loading directly in bf16 | |
lora_scale = 1.0 | |
wrapper, _ = create_lycoris_from_weights(lora_scale, adapter_file_path, pipeline.transformer) | |
wrapper.merge_to() | |
prompt = "a portrait of a nude emver1rev1 in a room sitting on a sofa with her legs spread wide." | |
negative_prompt = 'blurry, cropped, ugly' | |
## Optional: quantise the model to save on vram. | |
## Note: The model was quantised during training, and so it is recommended to do the same during inference time. | |
from optimum.quanto import quantize, freeze, qint8 | |
quantize(pipeline.transformer, weights=qint8) | |
freeze(pipeline.transformer) | |
pipeline.to('cuda' if torch.cuda.is_available() else 'mps' if torch.backends.mps.is_available() else 'cpu') # the pipeline is already in its target precision level | |
image = pipeline( | |
prompt=prompt, | |
negative_prompt=negative_prompt, | |
num_inference_steps=30, | |
generator=torch.Generator(device='cuda' if torch.cuda.is_available() else 'mps' if torch.backends.mps.is_available() else 'cpu').manual_seed(42), | |
width=1024, | |
height=1024, | |
guidance_scale=4.0, | |
skip_guidance_layers=[7, 8, 9], | |
).images[0] | |
image.save("output.png", format="PNG") | |
``` | |
## Exponential Moving Average (EMA) | |
SimpleTuner generates a safetensors variant of the EMA weights and a pt file. | |
The safetensors file is intended to be used for inference, and the pt file is for continuing finetuning. | |
The EMA model may provide a more well-rounded result, but typically will feel undertrained compared to the full model as it is a running decayed average of the model weights. | |