* feat: Add LoHa/LoKr network support for SDXL and Anima - networks/network_base.py: shared AdditionalNetwork base class with architecture auto-detection (SDXL/Anima) and generic module injection - networks/loha.py: LoHa (Low-rank Hadamard Product) module with HadaWeight custom autograd, training/inference classes, and factory functions - networks/lokr.py: LoKr (Low-rank Kronecker Product) module with factorization, training/inference classes, and factory functions - library/lora_utils.py: extend weight merge hook to detect and merge LoHa/LoKr weights alongside standard LoRA Linear and Conv2d 1x1 layers only; Conv2d 3x3 (Tucker decomposition) support will be added separately. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: Enhance LoHa and LoKr modules with Tucker decomposition support - Added Tucker decomposition functionality to LoHa and LoKr modules. - Implemented new methods for weight rebuilding using Tucker decomposition. - Updated initialization and weight handling for Conv2d 3x3+ layers. - Modified get_diff_weight methods to accommodate Tucker and non-Tucker modes. - Enhanced network base to include unet_conv_target_modules for architecture detection. * fix: rank dropout handling in LoRAModule for Conv2d and Linear layers, see #2272 for details * doc: add dtype comment for load_safetensors_with_lora_and_fp8 function * fix: enhance architecture detection to support InferSdxlUNet2DConditionModel for gen_img.py * doc: update model support structure to include Lumina Image 2.0, HunyuanImage-2.1, and Anima-Preview * doc: add documentation for LoHa and LoKr fine-tuning methods * Update networks/network_base.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/loha_lokr.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: refactor LoHa and LoKr imports for weight merging in load_safetensors_with_lora_and_fp8 function --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
17 KiB
📝 Click on the language section to expand / 言語をクリックして展開
LoHa / LoKr (LyCORIS)
Overview / 概要
In addition to standard LoRA, sd-scripts supports LoHa (Low-rank Hadamard Product) and LoKr (Low-rank Kronecker Product) as alternative parameter-efficient fine-tuning methods. These are based on techniques from the LyCORIS project.
- LoHa: Represents weight updates as a Hadamard (element-wise) product of two low-rank matrices. Reference: FedPara (arXiv:2108.06098)
- LoKr: Represents weight updates as a Kronecker product with optional low-rank decomposition. Reference: LoKr (arXiv:2309.14859)
The algorithms and recommended settings are described in the LyCORIS documentation and guidelines.
Both methods target Linear and Conv2d layers. Conv2d 1x1 layers are treated similarly to Linear layers. For Conv2d 3x3+ layers, optional Tucker decomposition or flat (kernel-flattened) mode is available.
This feature is experimental.
日本語
sd-scriptsでは、標準的なLoRAに加え、代替のパラメータ効率の良いファインチューニング手法として LoHa(Low-rank Hadamard Product)と LoKr(Low-rank Kronecker Product)をサポートしています。これらは LyCORIS プロジェクトの手法に基づいています。
- LoHa: 重みの更新を2つの低ランク行列のHadamard積(要素ごとの積)で表現します。参考文献: FedPara (arXiv:2108.06098)
- LoKr: 重みの更新をKronecker積と、オプションの低ランク分解で表現します。参考文献: LoKr (arXiv:2309.14859)
アルゴリズムと推奨設定はLyCORISのアルゴリズム解説とガイドラインを参照してください。
LinearおよびConv2d層の両方を対象としています。Conv2d 1x1層はLinear層と同様に扱われます。Conv2d 3x3+層については、オプションのTucker分解またはflat(カーネル平坦化)モードが利用可能です。
この機能は実験的なものです。
Acknowledgments / 謝辞
The LoHa and LoKr implementations in sd-scripts are based on the LyCORIS project by KohakuBlueleaf. We would like to express our sincere gratitude for the excellent research and open-source contributions that made this implementation possible.
日本語
sd-scriptsのLoHaおよびLoKrの実装は、KohakuBlueleaf氏によるLyCORISプロジェクトに基づいています。この実装を可能にしてくださった素晴らしい研究とオープンソースへの貢献に心から感謝いたします。
Supported architectures / 対応アーキテクチャ
LoHa and LoKr automatically detect the model architecture and apply appropriate default settings. The following architectures are currently supported:
- SDXL: Targets
Transformer2DModelfor UNet andCLIPAttention/CLIPMLPfor text encoders. Conv2d layers inResnetBlock2D,Downsample2D, andUpsample2Dare also supported whenconv_dimis specified. No defaultexclude_patterns. - Anima: Targets
Block,PatchEmbed,TimestepEmbedding, andFinalLayerfor DiT, andQwen3Attention/Qwen3MLPfor the text encoder. Defaultexclude_patternsautomatically skips modulation, normalization, embedder, and final_layer modules.
日本語
LoHaとLoKrは、モデルのアーキテクチャを自動で検出し、適切なデフォルト設定を適用します。現在、以下のアーキテクチャに対応しています:
- SDXL: UNetの
Transformer2DModel、テキストエンコーダのCLIPAttention/CLIPMLPを対象とします。conv_dimを指定した場合、ResnetBlock2D、Downsample2D、Upsample2DのConv2d層も対象になります。デフォルトのexclude_patternsはありません。 - Anima: DiTの
Block、PatchEmbed、TimestepEmbedding、FinalLayer、テキストエンコーダのQwen3Attention/Qwen3MLPを対象とします。デフォルトのexclude_patternsにより、modulation、normalization、embedder、final_layerモジュールは自動的にスキップされます。
Training / 学習
To use LoHa or LoKr, change the --network_module argument in your training command. All other training options (dataset config, optimizer, etc.) remain the same as LoRA.
日本語
LoHaまたはLoKrを使用するには、学習コマンドの --network_module 引数を変更します。その他の学習オプション(データセット設定、オプティマイザなど)はLoRAと同じです。
LoHa (SDXL)
accelerate launch --num_cpu_threads_per_process 1 --mixed_precision bf16 sdxl_train_network.py \
--pretrained_model_name_or_path path/to/sdxl.safetensors \
--dataset_config path/to/toml \
--mixed_precision bf16 --fp8_base \
--optimizer_type adamw8bit --learning_rate 2e-4 --gradient_checkpointing \
--network_module networks.loha --network_dim 32 --network_alpha 16 \
--max_train_epochs 16 --save_every_n_epochs 1 \
--output_dir path/to/output --output_name my-loha
LoKr (SDXL)
accelerate launch --num_cpu_threads_per_process 1 --mixed_precision bf16 sdxl_train_network.py \
--pretrained_model_name_or_path path/to/sdxl.safetensors \
--dataset_config path/to/toml \
--mixed_precision bf16 --fp8_base \
--optimizer_type adamw8bit --learning_rate 2e-4 --gradient_checkpointing \
--network_module networks.lokr --network_dim 32 --network_alpha 16 \
--max_train_epochs 16 --save_every_n_epochs 1 \
--output_dir path/to/output --output_name my-lokr
For Anima, replace sdxl_train_network.py with anima_train_network.py and use the appropriate model path and options.
日本語
Animaの場合は、sdxl_train_network.py を anima_train_network.py に置き換え、適切なモデルパスとオプションを使用してください。
Common training options / 共通の学習オプション
The following --network_args options are available for both LoHa and LoKr, same as LoRA:
| Option | Description |
|---|---|
verbose=True |
Display detailed information about the network modules |
rank_dropout=0.1 |
Apply dropout to the rank dimension during training |
module_dropout=0.1 |
Randomly skip entire modules during training |
exclude_patterns=[r'...'] |
Exclude modules matching the regex patterns (in addition to architecture defaults) |
include_patterns=[r'...'] |
Override excludes: modules matching these regex patterns will be included even if they match exclude_patterns |
network_reg_lrs=regex1=lr1,regex2=lr2 |
Set per-module learning rates using regex patterns |
network_reg_dims=regex1=dim1,regex2=dim2 |
Set per-module dimensions (rank) using regex patterns |
日本語
以下の --network_args オプションは、LoRAと同様にLoHaとLoKrの両方で使用できます:
| オプション | 説明 |
|---|---|
verbose=True |
ネットワークモジュールの詳細情報を表示 |
rank_dropout=0.1 |
学習時にランク次元にドロップアウトを適用 |
module_dropout=0.1 |
学習時にモジュール全体をランダムにスキップ |
exclude_patterns=[r'...'] |
正規表現パターンに一致するモジュールを除外(アーキテクチャのデフォルトに追加) |
include_patterns=[r'...'] |
正規表現パターンに一致するモジュールのみを対象とする |
network_reg_lrs=regex1=lr1,regex2=lr2 |
正規表現パターンでモジュールごとの学習率を設定 |
network_reg_dims=regex1=dim1,regex2=dim2 |
正規表現パターンでモジュールごとの次元(ランク)を設定 |
Conv2d support / Conv2dサポート
By default, LoHa and LoKr target Linear and Conv2d 1x1 layers. To also train Conv2d 3x3+ layers (e.g., in SDXL's ResNet blocks), use the conv_dim and conv_alpha options:
--network_args "conv_dim=16" "conv_alpha=8"
For Conv2d 3x3+ layers, you can enable Tucker decomposition for more efficient parameter representation:
--network_args "conv_dim=16" "conv_alpha=8" "use_tucker=True"
- Without
use_tucker: The kernel dimensions are flattened into the input dimension (flat mode). - With
use_tucker=True: A separate Tucker tensor is used to handle the kernel dimensions, which can be more parameter-efficient.
日本語
デフォルトでは、LoHaとLoKrはLinearおよびConv2d 1x1層を対象とします。Conv2d 3x3+層(SDXLのResNetブロックなど)も学習するには、conv_dimとconv_alphaオプションを使用します:
--network_args "conv_dim=16" "conv_alpha=8"
Conv2d 3x3+層に対して、Tucker分解を有効にすることで、より効率的なパラメータ表現が可能です:
--network_args "conv_dim=16" "conv_alpha=8" "use_tucker=True"
use_tuckerなし: カーネル次元が入力次元に平坦化されます(flatモード)。use_tucker=True: カーネル次元を扱う別のTuckerテンソルが使用され、よりパラメータ効率が良くなる場合があります。
LoKr-specific option: factor / LoKr固有のオプション: factor
LoKr decomposes weight dimensions using factorization. The factor option controls how dimensions are split:
factor=-1(default): Automatically find balanced factors. For example, dimension 512 is split into (16, 32).factor=N(positive integer): Force factorization using the specified value. For example,factor=4splits dimension 512 into (4, 128).
--network_args "factor=4"
When network_dim (rank) is large enough relative to the factorized dimensions, LoKr uses a full matrix instead of a low-rank decomposition for the second factor. A warning will be logged in this case.
日本語
LoKrは重みの次元を因数分解して分割します。factor オプションでその分割方法を制御します:
factor=-1(デフォルト): バランスの良い因数を自動的に見つけます。例えば、次元512は(16, 32)に分割されます。factor=N(正の整数): 指定した値で因数分解します。例えば、factor=4は次元512を(4, 128)に分割します。
--network_args "factor=4"
network_dim(ランク)が因数分解された次元に対して十分に大きい場合、LoKrは第2因子に低ランク分解ではなくフル行列を使用します。その場合、警告がログに出力されます。
Anima-specific option: train_llm_adapter / Anima固有のオプション: train_llm_adapter
For Anima, you can additionally train the LLM adapter modules by specifying:
--network_args "train_llm_adapter=True"
This includes LLMAdapterTransformerBlock modules as training targets.
日本語
Animaでは、以下を指定することでLLMアダプターモジュールも追加で学習できます:
--network_args "train_llm_adapter=True"
これにより、LLMAdapterTransformerBlock モジュールが学習対象に含まれます。
LoRA+ / LoRA+
LoRA+ (loraplus_lr_ratio etc. in --network_args) is supported with LoHa/LoKr. For LoHa, the second pair of matrices (hada_w2_a) is treated as the "plus" (higher learning rate) parameter group. For LoKr, the scale factor (lokr_w1) is treated as the "plus" parameter group.
--network_args "loraplus_lr_ratio=4"
This feature has been confirmed to work in basic testing, but feedback is welcome. If you encounter any issues, please report them.
日本語
LoRA+(--network_args の loraplus_lr_ratio 等)はLoHa/LoKrでもサポートされています。LoHaでは第2ペアの行列(hada_w2_a)が「plus」(より高い学習率)パラメータグループとして扱われます。LoKrではスケール係数(lokr_w1)が「plus」パラメータグループとして扱われます。
--network_args "loraplus_lr_ratio=4"
この機能は基本的なテストでは動作確認されていますが、フィードバックをお待ちしています。問題が発生した場合はご報告ください。
How LoHa and LoKr work / LoHaとLoKrの仕組み
LoHa
LoHa represents the weight update as a Hadamard (element-wise) product of two low-rank matrices:
ΔW = (W1a × W1b) ⊙ (W2a × W2b)
where W1a, W1b, W2a, W2b are low-rank matrices with rank network_dim. This means LoHa has roughly twice the number of trainable parameters compared to LoRA at the same rank, but can capture more complex weight structures due to the element-wise product.
For Conv2d 3x3+ layers with Tucker decomposition, each pair additionally has a Tucker tensor T and the reconstruction becomes: einsum("i j ..., j r, i p -> p r ...", T, Wb, Wa).
LoKr
LoKr represents the weight update using a Kronecker product:
ΔW = W1 ⊗ W2 (where W2 = W2a × W2b in low-rank mode)
The original weight dimensions are factorized (e.g., a 512×512 weight might be split so that W1 is 16×16 and W2 is 32×32). W1 is always a full matrix (small), while W2 can be either low-rank decomposed or a full matrix depending on the rank setting. LoKr tends to produce smaller models compared to LoRA at the same rank.
日本語
LoHa
LoHaは重みの更新を2つの低ランク行列のHadamard積(要素ごとの積)で表現します:
ΔW = (W1a × W1b) ⊙ (W2a × W2b)
ここで W1a, W1b, W2a, W2b はランク network_dim の低ランク行列です。LoHaは同じランクのLoRAと比較して学習可能なパラメータ数が 約2倍 になりますが、要素ごとの積により、より複雑な重み構造を捉えることができます。
Conv2d 3x3+層でTucker分解を使用する場合、各ペアにはさらにTuckerテンソル T があり、再構成は einsum("i j ..., j r, i p -> p r ...", T, Wb, Wa) となります。
LoKr
LoKrはKronecker積を使って重みの更新を表現します:
ΔW = W1 ⊗ W2 (低ランクモードでは W2 = W2a × W2b)
元の重みの次元が因数分解されます(例: 512×512の重みが、W1が16×16、W2が32×32に分割されます)。W1は常にフル行列(小さい)で、W2はランク設定に応じて低ランク分解またはフル行列になります。LoKrは同じランクのLoRAと比較して より小さいモデル を生成する傾向があります。
Inference / 推論
Trained LoHa/LoKr weights are saved in safetensors format, just like LoRA.
日本語
学習済みのLoHa/LoKrの重みは、LoRAと同様にsafetensors形式で保存されます。
SDXL
For SDXL, use gen_img.py with --network_module and --network_weights, the same way as LoRA:
python gen_img.py --ckpt path/to/sdxl.safetensors \
--network_module networks.loha --network_weights path/to/loha.safetensors \
--prompt "your prompt" ...
Replace networks.loha with networks.lokr for LoKr weights.
日本語
SDXLでは、LoRAと同様に gen_img.py で --network_module と --network_weights を指定します:
python gen_img.py --ckpt path/to/sdxl.safetensors \
--network_module networks.loha --network_weights path/to/loha.safetensors \
--prompt "your prompt" ...
LoKrの重みを使用する場合は networks.loha を networks.lokr に置き換えてください。
Anima
For Anima, use anima_minimal_inference.py with the --lora_weight argument. LoRA, LoHa, and LoKr weights are automatically detected and merged:
python anima_minimal_inference.py --dit path/to/dit --prompt "your prompt" \
--lora_weight path/to/loha_or_lokr.safetensors ...
日本語
Animaでは、anima_minimal_inference.py に --lora_weight 引数を指定します。LoRA、LoHa、LoKrの重みは自動的に判定されてマージされます:
python anima_minimal_inference.py --dit path/to/dit --prompt "your prompt" \
--lora_weight path/to/loha_or_lokr.safetensors ...