Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
110 commits
Select commit Hold shift + click to select a range
8b013b0
initial CEP
Koratahiu Dec 30, 2025
e4c2521
gamma 1
Koratahiu Dec 30, 2025
7cd25b8
adjust position
Koratahiu Dec 30, 2025
39af0d3
fix transformer (CEP)
Koratahiu Jan 29, 2026
df574e0
Merge branch 'master' of https://github.com/Nerogar/OneTrainer into cep
Koratahiu Jan 29, 2026
85a5d38
Merge branch 'upstream' into pr-1235
dxqb Feb 15, 2026
a860bb5
add flux2
dxqb Feb 15, 2026
67dfd2d
update
dxqb Mar 22, 2026
230cae8
update
dxqb Mar 24, 2026
e6fff00
Merge branch 'upstream' into W16A8
dxqb Mar 24, 2026
0c869b8
torch 2.11
dxqb Mar 24, 2026
fe50e8d
feat: split CTK UI into controller/base-view/ctk-view pattern
May 10, 2026
a88f369
refactor: abstract CTK views and migrate logic to controllers
May 10, 2026
f7e4159
copy: add PySide6 view copies mirroring CTK structure
May 10, 2026
a36aa74
feat: implement PySide6 views replacing CTK placeholder copies
May 10, 2026
ec2ee0a
refactor: replace manual entry+browse-button pairs with path_entry in…
May 11, 2026
c5b21f0
Merge branch 'ctk_abstraction' into pyside_copy
May 11, 2026
e19d149
refactor: mirror VideoToolUI path_entry refactor to PySide6VideoToolU…
May 11, 2026
624ce5d
refactor: remove _create_browse_dir/file_button from PySide6VideoTool…
May 11, 2026
65bdda2
copy: sync pyside6_components.py with ctk_components.py (allow_video_…
May 11, 2026
24b1a5e
refactor: add allow_video_files to pyside6_components path_entry
May 11, 2026
c3961ba
fix: declare undeclared self attrs in Base*View classes
May 15, 2026
d039871
refactor: move Windows DPI awareness block to CtkTrainUIView
May 15, 2026
307eef2
Merge branch 'ctk_abstraction' into pyside_copy
May 15, 2026
29a62a1
chore: sync PySide6 copies from ctk_abstraction merge
May 15, 2026
7b067a6
refactor: adapt PySide6 views to ctk_abstraction interface changes
May 15, 2026
1bb5a56
refactor: remove unused __init__ from BaseConceptTabView
May 15, 2026
06ca10c
Merge branch 'ctk_abstraction' into pyside_copy
May 15, 2026
98272c8
Merge branch 'pyside_copy' into pyside
May 15, 2026
a38020a
refactor: move QSizePolicy import to module level in PySide6TrainingT…
May 15, 2026
9c05ddd
fix: store str repr in options_kv var so UIState enum lookup works
May 15, 2026
9f42590
Merge branch 'upstream' into ctk_copy
May 16, 2026
8dd86c6
fix: apply upstream COFT removal to CtkLoraTabView
May 16, 2026
19b5724
Merge branch 'ctk_copy' into ctk_abstraction
May 16, 2026
126bc97
Merge branch 'ctk_abstraction' into pyside_copy
May 16, 2026
81cbe89
Merge branch 'pyside_copy' into pyside
May 16, 2026
2de990a
feat: add data prefetch and rename dataloader_threads to caching_threads
May 17, 2026
d5ac1e4
refactor: split latent_caching into image_caching and text_caching
May 17, 2026
895c75a
prefetch: use dedicated CUDA stream to avoid serialising with trainin…
May 17, 2026
271f51e
Upgrade transformers to 5.9 and huggingface-hub to 1.16
May 24, 2026
5a8745c
Merge branch 'master' into torch_2_11
dxqb May 25, 2026
6913fc6
Upgrade torch to 2.12.0 (CUDA 13.0 / ROCm 7.2)
May 25, 2026
6e4c2e5
Switch nccl pin to cu13 (matches torch 2.12+cu130 dependency)
May 25, 2026
b3c6462
Update triton-windows to 3.7.0.post26 (matches triton 3.7.0)
May 25, 2026
8c10d1c
Merge branch 'transformers5' into anima_base
May 25, 2026
532625e
Make gradient checkpointing and offloading per-component; centralize …
May 25, 2026
d89eab8
Merge branch 'master' of https://github.com/Nerogar/OneTrainer into cep
Koratahiu May 26, 2026
85e850e
Remove cep_enabled bool, and fix vali loss
Koratahiu May 26, 2026
065f922
add Ernie support
Koratahiu May 26, 2026
7609ab5
fix paper formula
Koratahiu May 26, 2026
88a0406
@staticmethod and no self
Koratahiu May 26, 2026
5a41835
Merge branch 'master' into split-offload
dxqb May 26, 2026
0fe37fc
Add a pull request template
TheForgotten69 May 27, 2026
7ad6b6c
Add CLAUDE.md
TheForgotten69 May 27, 2026
6d3356e
Add AGENTS.md
TheForgotten69 May 27, 2026
4d00a21
Make doc references visible in PR template
TheForgotten69 May 27, 2026
3a86c17
Fix missing end-of-file newlines
TheForgotten69 May 27, 2026
d624556
fix: gate autocast on train dtype instead of dtype-set uniformity
dxqb May 27, 2026
3b8214c
Address PR review feedback on AGENTS.md and PR template
TheForgotten69 May 28, 2026
bcc7d5d
raise instead of silently degrading float32 fallback on non-CUDA
dxqb May 28, 2026
96ccec0
Resolve delta docstring
Koratahiu May 29, 2026
ca91c00
row += 1 for cep gamma
Koratahiu May 29, 2026
2045afd
required=True for cep gamma
Koratahiu May 29, 2026
3984c3f
Merge branch 'upstream' into ctk_copy
dxqb May 29, 2026
c602458
Sync Ctk* copies with upstream changes merged into Base* files
dxqb May 29, 2026
23ad1a2
Merge ctk_copy: LoKr support, Scaled OFT, ETA fix, row counter fix; k…
dxqb May 29, 2026
9f27035
Merge branch 'ctk_abstraction' into pyside_copy
dxqb May 29, 2026
031c511
Merge pyside_copy: upstream LoKr, Scaled OFT, ETA fix, model/training…
dxqb May 29, 2026
02f1032
Make Qt UI the default; rename train_ui scripts to _ctk/_qt
dxqb May 29, 2026
a3a8d2d
Fix over-wide widgets: extend _pack_form to absorb extra horizontal s…
dxqb May 29, 2026
51636c5
Hint ctk fallback in unported Qt6 views
dxqb May 29, 2026
01cca79
Move Rolling Backup Count under the Rolling Backup toggle
dxqb May 29, 2026
647afc2
Move Rolling Backup Count under the Rolling Backup toggle
dxqb May 29, 2026
6658da5
Merge branch 'ctk_abstraction' into pyside_copy
dxqb May 29, 2026
8c5a7a3
Merge branch 'pyside_copy' into pyside
dxqb May 29, 2026
4c9c012
Remove AI assistance checkboxes to fix task counter pollution
TheForgotten69 May 29, 2026
477f940
Merge branch 'upstream' into anima_base
dxqb May 30, 2026
ea59c93
anima: Anima model support (LoRA + Fine-Tune)
dxqb May 30, 2026
25366c8
Remove PR template, moved to separate PR
TheForgotten69 May 31, 2026
e54623e
Remove Windows DPI-awareness hack from PySide6 view
dxqb Jun 3, 2026
7117833
fix: call init_compile() in training thread to apply dynamo config
dxqb Jun 4, 2026
67169e8
Merge branch 'fix/compiled-optimizer-thread-local' into anima
dxqb Jun 4, 2026
5a5411d
Use decorator form for factory.register()
dxqb Jun 4, 2026
c81e970
wire up Ernie text encoder layer offloading
dxqb Jun 4, 2026
440051c
Force light color scheme on PySide6 UI startup
dxqb Jun 4, 2026
408e7e2
Merge branch 'upstream' into ctk_copy
dxqb Jun 4, 2026
a0bd3e4
Sync CtkConceptWindowView and ConceptWindowController with Base copy
dxqb Jun 4, 2026
3d90a9e
Merge ctk_copy: transformers 5.9, torch 2.12, compile thread-safety
dxqb Jun 4, 2026
dc4fdea
Merge branch 'ctk_abstraction' into pyside_copy
dxqb Jun 4, 2026
d64d50b
Merge branch 'pyside_copy' into pyside
dxqb Jun 4, 2026
03b7156
Merge branch 'master' into anima
dxqb Jun 4, 2026
283cc60
Merge PR #1445 (Decouple CTK from UI logic; lay groundwork for Qt6) i…
dxqb Jun 4, 2026
e9ee294
Merge PR #1446 (implement Qt6 views) into preview
dxqb Jun 4, 2026
7e1028c
Merge PR #1108 (Full finetuning with activation quantization) into pr…
dxqb Jun 4, 2026
2ff97d1
Merge PR #1235 (Conditional Embedding Perturbation (CEP)) into preview
dxqb Jun 4, 2026
015a312
Merge PR #1462 (split "Latent Caching" into "Image Caching" and "Text…
dxqb Jun 4, 2026
79c68f5
Merge PR #1476 (Make gradient checkpointing and offloading per-compon…
dxqb Jun 4, 2026
878e236
Merge PR #1480 (Add AGENTS.md, CLAUDE.md) into preview
dxqb Jun 4, 2026
94c0083
Merge PR #1481 (always enable mixed-precision / autocasting) into pre…
dxqb Jun 4, 2026
41024fb
Merge PR #1487 (Anima) into preview
dxqb Jun 4, 2026
6667a35
Merge PR #1461 (Batch prefetching) into preview
dxqb Jun 4, 2026
0ffbe0a
Merge PR #1498 (Use decorator form for factory.register()) into preview
dxqb Jun 4, 2026
1dc2761
Merge PR #1500 (fix: wire up Ernie text encoder layer offloading) int…
dxqb Jun 4, 2026
fc363ff
Remove OffloadingWindow: superseded by per-component offloading from …
dxqb Jun 4, 2026
5de0bc2
Add Windows-only dark mode support with Qt6 tab rendering fixes
TheForgotten69 Jun 5, 2026
81dfba6
Trim theme comment
TheForgotten69 Jun 5, 2026
3a35ced
Keep original light-mode stylesheet, add dark mode separately
TheForgotten69 Jun 5, 2026
feba96b
Apply Windows dark mode fixes as overrides on top of base stylesheet
TheForgotten69 Jun 5, 2026
d876a93
Preserve forced light mode on non-Windows platforms
TheForgotten69 Jun 5, 2026
eb7be99
Simplify theme: drop QSS overrides, fix Windows dark by not forcing l…
TheForgotten69 Jun 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# development
PLAN.md # claude's planning file, kept local-only
.idea
*.bak
*.pyc
Expand Down Expand Up @@ -38,3 +39,5 @@ pixi.toml
train.bat
debug_report.log
config_diff.txt
CLAUDE.md
PLAN.md
162 changes: 162 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# AGENTS.md

OneTrainer trains diffusion models with full fine-tune / LoRA / embedding /
FINE_TUNE_VAE methods. Built on `diffusers` + PyTorch +
[`mgds`](https://github.com/Nerogar/MGDS). Supported families:
`modules/util/enum/ModelType.py`.

## Run

```
pre-commit install # install OUTSIDE the project venv
pre-commit run --all-files # mandatory before every PR
python scripts/train.py --config-path <preset.json> [--secrets-path secrets.json]
python scripts/train_ui.py # GUI (CustomTkinter)
```

Every `scripts/*.py` (except `generate_debug_report.py`) starts with `script_imports()`
from `scripts/util/import_util.py`: it fixes `sys.path`, filters xformers/Triton noise,
and bootstraps ZLUDA. Don't try to replicate it from a bare `python -c`.

There is **no automated test suite.** Verification is launching scripts and exercising
the change.

## Layout

```
modules/
model/ BaseModel subclasses — state (weights, optim, EMA, embeddings)
modelLoader/ BaseModelLoader — ckpt/safetensors/diffusers → model
modelSetup/ BaseModelSetup — optimizer, LR, grad checkpointing, device
dataLoader/ BaseDataLoader — wraps mgds dataset; bucketing, aug, captions
modelSampler/ BaseModelSampler — preview/inference sampling
modelSaver/ BaseModelSaver — model → disk
trainer/ BaseTrainer, GenericTrainer (main loop), CloudTrainer (RunPod), MultiTrainer
module/
EMA / LoRA / OFT / AdditionalEmbedding training wrappers
quantized/ Fp8 / Nf4 / W8A8 / GGUFA8 / SVD linear layers
Blip / ClipSeg / WD / Rembg / HPSv2 / AestheticScore backends for caption_ui / generate_*
ui/ CustomTkinter; one *UI/*Tab/*Window per screen.
TrainUI extends ctk.CTk; others extend ctk.CTkToplevel.
util/
create.py ★ factory — TrainConfig → pipeline
factory.py auto-discovery (import_dir + class registry)
config/ TrainConfig + sub-configs (Sample, Concept, Cloud, Secrets)
enum/ ModelType, Optimizer, LearningRateScheduler, NoiseScheduler,
TrainingMethod, DataType, ...
callbacks/ TrainCallbacks (training-loop event hooks)
commands/ TrainCommands (UI → trainer signals)
optimizer/ CAME / adam / adamw / adafactor / muon extensions
ui/ UIState, components.py, validation.py
LayerOffloadConductor.py ⚠ fragile VRAM offloading; incompatible with dataloader_threads > 1
zluda/ Windows AMD shim; disables cuDNN / flash_sdp / mem_efficient_sdp / cudnn_sdp

scripts/
util/import_util.py ★ script_imports() — sys.path + ZLUDA bootstrap; called first by every script
train.py / train_ui.py / train_remote.py / sample.py
caption_ui.py / convert_model_ui.py / video_tool_ui.py
generate_captions.py / generate_masks.py / convert_model.py / calculate_loss.py
create_train_files.py / install_zluda.py / generate_debug_report.py

training_presets/ ~50 partial-override JSONs of TrainConfig defaults, "#<model> <method>[ <vram>].json"
embedding_templates/ plain-text prompt files (`<embedding>` placeholder); .gitignore excludes user files
resources/ icons + sd_model_spec/*.json
docs/ ProjectStructure / Contributing / QuickStartGuide / CliTraining /
EmbeddingTraining / CaptioningAndMasking / RamOffloading / DockerImage
LAUNCH-SCRIPTS.md OT_* env vars, venv/conda selection
lib.include.sh runtime/venv/conda bootstrap; forces PYTORCH_ENABLE_MPS_FALLBACK=1 on macOS
```

## Architecture

### Factory + auto-discovery (`modules/util/create.py`)

`create_trainer(config, callbacks, commands)` is the top-level entry: returns
`CloudTrainer` if `config.cloud.enabled`, `MultiTrainer` if `config.multi_gpu`, else
`GenericTrainer` (the only branch that calls `ZLUDA.initialize_devices`).

`GenericTrainer.start()` then calls per-layer factories in order:
`create_model_loader → create_model_setup → create_data_loader → create_model_saver →
create_model_sampler`.

The selection mechanism for those five "per-model" layers is **auto-discovery**:

```python
factory.import_dir("modules/modelSampler", "modules.modelSampler")
factory.import_dir("modules/modelLoader", "modules.modelLoader")
factory.import_dir("modules/modelSaver", "modules.modelSaver")
factory.import_dir("modules/modelSetup", "modules.modelSetup")
factory.import_dir("modules/dataLoader", "modules.dataLoader")
```

Dropping a file with the right base class in any of those five directories registers
it — you do **not** edit `create.py` to register new per-model classes. You **do** edit
`create.py` for `create_optimizer`, `create_ema`, `create_lr_scheduler`,
`create_noise_scheduler`, `create_trainer` — those are explicit `match`/`case` branches
keyed off enums.

### UI

CustomTkinter. One file per screen in `modules/ui/`. `TrainUI` (the root window)
extends `ctk.CTk`; `CaptionUI`, `ConvertModelUI`, `VideoToolUI` extend `ctk.CTkToplevel`.
`TrainUI` composes tabs (`ModelTab`, `TrainingTab`, `SamplingTab`, `LoraTab`,
`ConceptTab`, `AdditionalEmbeddingsTab`, `CloudTab`); sub-windows are opened by whichever
component needs them.

Reactive state: `modules/util/ui/UIState.py` is `UIState(master, obj)` — it introspects
typed attributes on any config-shaped object and two-way-binds them to tkinter
vars. Shared widgets: `components.py`. Validation: `validation.py` +
`validation_helpers.py`.

### Config

`TrainConfig` (`modules/util/config/TrainConfig.py`) is **not** a `@dataclass`; it's a
`BaseConfig` subclass using class-level annotations. Serialization is via `to_dict()` /
`from_dict()` on `BaseConfig` — JSON conversion happens at the call site
(`scripts/train.py` does `json.load` → `from_dict`). `TrainConfig.py` also declares
several sub-configs inline (`TrainOptimizerConfig`, `TrainModelPartConfig`,
`TrainEmbeddingConfig`, `QuantizationConfig`); standalone sub-configs:
`SampleConfig.py`, `ConceptConfig.py`, `CloudConfig.py`, `SecretsConfig.py`.

Validation lives in `modules/util/ui/validation.py` — the **UI** layer. CLI scripts
bypass it. Validate at load time too if a field can be invalid from JSON.

Presets in `training_presets/` are partial overrides applied on top of
`TrainConfig.default_values()` (only fields that differ from defaults are present).

## Recipes

Detailed implementation guides live in [`docs/recipes/`](docs/recipes/):

- **New optimizer** — see [`docs/recipes/AddOptimizer.md`](docs/recipes/AddOptimizer.md).

### Add a `TrainConfig` field

1. Declare a class-level annotation (`my_field: int`) on the appropriate `BaseConfig` subclass; set its default in that class's `default_values()`.
2. UI: bind via `UIState`. Add validation in `modules/util/ui/validation.py` if it can be invalid.
3. Presets keep loading (partial overrides). Migrate only if a default they relied on changes.
4. CLI bypasses UI validation — if a malformed JSON value would crash deeper in, validate at load.

### Hook into the training loop

- **Callbacks** (training → caller): `modules/util/callbacks/TrainCallbacks.py`. Instantiated in `scripts/train.py` / `TrainUI`, passed to `create_trainer(...)`.
- **Commands** (caller → training): `modules/util/commands/TrainCommands.py`. Available: `stop`, `sample_default`, `sample_custom(SampleConfig)`, `backup`, `save` (each paired with `get_and_reset_*` polled by the trainer). Multi-GPU sync: `modules/util/multi_gpu_util.py::sync_commands` + `TrainCommands.merge`.

## Footguns

- `modules/util/LayerOffloadConductor.py` — **incompatible with `dataloader_threads > 1`** when `gradient_checkpointing.offload()` and `layer_offload_fraction > 0` (hard-raised in `create.py`).
- ZLUDA (`modules/zluda/ZLUDA.py`) — `ZLUDA.initialize_devices(config)` runs only in the `GenericTrainer` branch of `create_trainer`. On Win-AMD it disables `cuDNN`, `flash_sdp`, `mem_efficient_sdp`, `cudnn_sdp`. Silent CPU fallback if its self-test fails.
- macOS — `lib.include.sh` exports `PYTORCH_ENABLE_MPS_FALLBACK=1`. Slow workflow on Mac? Suspect this first.
- `OT_*` env vars (`LAUNCH-SCRIPTS.md`) change install / venv selection / low-mem mode / platform requirements.
- CustomTkinter trace-removal workaround in `modules/util/ui/components.py` (references upstream CTK PR #2077, unlikely to merge). Don't simplify without re-verifying.
- `requirements-global.txt` has `git+https` commit pins for `diffusers`, `mgds`, `muon`. Don't bump silently.
- Adding a `ModelType` without sweeping every `if/elif model_type == ...` causes silent feature absence (no crash).
- CLI scripts bypass UI validation — a field validated only in `modules/util/ui/validation.py` can arrive malformed from JSON.

## Before opening a PR

- `pre-commit run --all-files` clean
- Launched the affected UI / script and exercised the change
- Touched the training path? Ran a short training job with a real preset
- No silent new top-level dependencies
- Can defend every line in the diff
3 changes: 3 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# CLAUDE.md

This project's contributor rules for AI coding agents live in **[AGENTS.md](AGENTS.md)**.
8 changes: 8 additions & 0 deletions docs/recipes/AddOptimizer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Adding a New Optimizer

1. `modules/util/enum/Optimizer.py` — add enum entry; update `is_adaptive` / `is_schedule_free` / `supports_fused_back_pass` predicates if applicable.
2. `modules/util/create.py::create_optimizer` — add `case Optimizer.<NAME>:`.
3. `modules/util/optimizer_util.py::OPTIMIZER_DEFAULT_PARAMETERS` — register default hyperparams.
4. If torch internals need patching: add a module under `modules/util/optimizer/` modelled on the existing `*_extensions.py`.
5. UI exposure: `modules/ui/OptimizerParamsWindow.py`.
6. Pin any new package in `requirements-global.txt` (or appropriate platform file).
161 changes: 161 additions & 0 deletions modules/dataLoader/AnimaBaseDataLoader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import os

from modules.dataLoader.BaseDataLoader import BaseDataLoader
from modules.dataLoader.mixin.DataLoaderText2ImageMixin import DataLoaderText2ImageMixin
from modules.model.AnimaModel import PROMPT_MAX_LENGTH, AnimaModel
from modules.model.BaseModel import BaseModel
from modules.modelSetup.BaseAnimaSetup import BaseAnimaSetup
from modules.modelSetup.BaseModelSetup import BaseModelSetup
from modules.util import factory
from modules.util.config.TrainConfig import TrainConfig
from modules.util.enum.ModelType import ModelType
from modules.util.TrainProgress import TrainProgress

from mgds.pipelineModules.DecodeTokens import DecodeTokens
from mgds.pipelineModules.DecodeVAE import DecodeVAE
from mgds.pipelineModules.EncodeAnimaText import EncodeAnimaText
from mgds.pipelineModules.EncodeVAE import EncodeVAE
from mgds.pipelineModules.RescaleImageChannels import RescaleImageChannels
from mgds.pipelineModules.SampleVAEDistribution import SampleVAEDistribution
from mgds.pipelineModules.SaveImage import SaveImage
from mgds.pipelineModules.SaveText import SaveText
from mgds.pipelineModules.ScaleImage import ScaleImage
from mgds.pipelineModules.Tokenize import Tokenize


class AnimaBaseDataLoader(
BaseDataLoader,
DataLoaderText2ImageMixin,
):
def _preparation_modules(self, config: TrainConfig, model: AnimaModel):
rescale_image = RescaleImageChannels(image_in_name='image', image_out_name='image', in_range_min=0, in_range_max=1, out_range_min=-1, out_range_max=1)
encode_image = EncodeVAE(in_name='image', out_name='latent_image_distribution', vae=model.vae, autocast_contexts=[model.autocast_context], dtype=model.train_dtype.torch_dtype())
image_sample = SampleVAEDistribution(in_name='latent_image_distribution', out_name='latent_image', mode='mean')
downscale_mask = ScaleImage(in_name='mask', out_name='latent_mask', factor=0.125)
# Anima has no chat template — tokenize raw prompt with both tokenizers
tokenize_prompt = Tokenize(in_name='prompt', tokens_out_name='tokens', mask_out_name='tokens_mask', tokenizer=model.tokenizer, max_token_length=PROMPT_MAX_LENGTH)
tokenize_t5 = Tokenize(in_name='prompt', tokens_out_name='t5_tokens', mask_out_name='t5_tokens_mask', tokenizer=model.t5_tokenizer, max_token_length=PROMPT_MAX_LENGTH)
# EncodeAnimaText runs Qwen3 encoder + AnimaTextConditioner; output is fixed (512, 1024)
encode_prompt = EncodeAnimaText(
tokens_name='tokens', tokens_attention_mask_name='tokens_mask',
t5_tokens_name='t5_tokens', t5_tokens_attention_mask_name='t5_tokens_mask',
hidden_state_out_name='text_encoder_hidden_state',
text_encoder=model.text_encoder, text_conditioner=model.text_conditioner,
autocast_contexts=[model.autocast_context], dtype=model.train_dtype.torch_dtype(),
)

modules = [rescale_image, encode_image, image_sample]
if config.masked_training or config.model_type.has_mask_input():
modules.append(downscale_mask)

modules += [tokenize_prompt, tokenize_t5]

if not config.train_text_encoder_or_embedding():
modules.append(encode_prompt)

return modules

def _cache_modules(self, config: TrainConfig, model: AnimaModel, model_setup: BaseAnimaSetup):
image_split_names = ['latent_image', 'original_resolution', 'crop_offset']

if config.masked_training or config.model_type.has_mask_input():
image_split_names.append('latent_mask')

image_aggregate_names = ['crop_resolution', 'image_path']

text_split_names = []

sort_names = image_aggregate_names + image_split_names + [
'prompt', 'tokens', 'tokens_mask', 't5_tokens', 't5_tokens_mask', 'text_encoder_hidden_state',
'concept'
]

if not config.train_text_encoder_or_embedding():
text_split_names += ['tokens', 'tokens_mask', 't5_tokens', 't5_tokens_mask', 'text_encoder_hidden_state']

return self._cache_modules_from_names(
model, model_setup,
image_split_names=image_split_names,
image_aggregate_names=image_aggregate_names,
text_split_names=text_split_names,
sort_names=sort_names,
config=config,
text_caching=not config.train_text_encoder_or_embedding(),
)

def _output_modules(self, config: TrainConfig, model: AnimaModel, model_setup: BaseAnimaSetup):
output_names = [
'image_path', 'latent_image',
'prompt',
'tokens',
'tokens_mask',
't5_tokens',
't5_tokens_mask',
'original_resolution', 'crop_resolution', 'crop_offset',
]

if config.masked_training or config.model_type.has_mask_input():
output_names.append('latent_mask')

if not config.train_text_encoder_or_embedding():
output_names.append('text_encoder_hidden_state')

return self._output_modules_from_out_names(
model, model_setup,
output_names=output_names,
config=config,
use_conditioning_image=False,
vae=model.vae,
autocast_context=[model.autocast_context],
train_dtype=model.train_dtype,
)

def _debug_modules(self, config: TrainConfig, model: AnimaModel): #TODO clean up
debug_dir = os.path.join(config.debug_dir, "dataloader")

def before_save_fun():
model.vae_to(self.train_device)

decode_image = DecodeVAE(in_name='latent_image', out_name='decoded_image', vae=model.vae, autocast_contexts=[model.autocast_context], dtype=model.train_dtype.torch_dtype())
upscale_mask = ScaleImage(in_name='latent_mask', out_name='decoded_mask', factor=8)
decode_prompt = DecodeTokens(in_name='tokens', out_name='decoded_prompt', tokenizer=model.tokenizer)

#FIXME https://github.com/Nerogar/OneTrainer/issues/1015
#save_image = SaveImage(image_in_name='decoded_image', original_path_in_name='image_path', path=debug_dir, in_range_min=-1, in_range_max=1, before_save_fun=before_save_fun)

# SaveImage(image_in_name='latent_mask', original_path_in_name='image_path', path=debug_dir, in_range_min=0, in_range_max=1, before_save_fun=before_save_fun)
save_mask = SaveImage(image_in_name='decoded_mask', original_path_in_name='image_path', path=debug_dir, in_range_min=0, in_range_max=1, before_save_fun=before_save_fun)
save_prompt = SaveText(text_in_name='decoded_prompt', original_path_in_name='image_path', path=debug_dir, before_save_fun=before_save_fun)

# These modules don't really work, since they are inserted after a sorting operation that does not include this data
# SaveImage(image_in_name='mask', original_path_in_name='image_path', path=debug_dir, in_range_min=0, in_range_max=1),
# SaveImage(image_in_name='image', original_path_in_name='image_path', path=debug_dir, in_range_min=-1, in_range_max=1),

modules = [decode_image]

#FIXME https://github.com/Nerogar/OneTrainer/issues/1015
#modules.append(save_image)

if config.masked_training or config.model_type.has_mask_input():
modules += [upscale_mask, save_mask]

modules += [decode_prompt, save_prompt]

return modules

def _create_dataset(
self,
config: TrainConfig,
model: BaseModel,
model_setup: BaseModelSetup,
train_progress: TrainProgress,
is_validation: bool = False,
):
return DataLoaderText2ImageMixin._create_dataset(self,
config, model, model_setup, train_progress, is_validation,
aspect_bucketing_quantization=64,
allow_video_files=False, #don't allow video files, but...
vae_frame_dim=True, #...Anima has a video-capable VAE. convert images to video dimensions
)

factory.register(BaseDataLoader, AnimaBaseDataLoader, ModelType.ANIMA)
9 changes: 4 additions & 5 deletions modules/dataLoader/ChromaBaseDataLoader.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from mgds.pipelineModules.Tokenize import Tokenize


@factory.register(BaseDataLoader, ModelType.CHROMA_1)
class ChromaBaseDataLoader(
BaseDataLoader,
DataLoaderText2ImageMixin,
Expand All @@ -50,7 +51,7 @@ def _preparation_modules(self, config: TrainConfig, model: ChromaModel):
if not config.train_text_encoder_or_embedding():
modules.append(encode_prompt)

if config.latent_caching and not config.train_text_encoder_or_embedding():
if config.text_caching and not config.train_text_encoder_or_embedding():
modules.append(prune_masked_tokens)

return modules
Expand Down Expand Up @@ -80,7 +81,7 @@ def _cache_modules(self, config: TrainConfig, model: ChromaModel, model_setup: B
text_split_names=text_split_names,
sort_names=sort_names,
config=config,
text_caching = not config.train_text_encoder_or_embedding(),
text_caching=config.text_caching and not config.train_text_encoder_or_embedding(),
)

def _output_modules(self, config: TrainConfig, model: ChromaModel, model_setup: BaseChromaSetup):
Expand Down Expand Up @@ -110,7 +111,7 @@ def _output_modules(self, config: TrainConfig, model: ChromaModel, model_setup:
train_dtype=model.train_dtype,
)

if config.latent_caching and not config.train_text_encoder_or_embedding():
if config.text_caching and not config.train_text_encoder_or_embedding():
output_module_list = [pad_masked_tokens] + output_module_list

return output_module_list
Expand Down Expand Up @@ -154,5 +155,3 @@ def _create_dataset(
config, model, model_setup, train_progress, is_validation,
aspect_bucketing_quantization=64,
)

factory.register(BaseDataLoader, ChromaBaseDataLoader, ModelType.CHROMA_1)
Loading