多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

sd-scripts 中 OFTv2 与 BOFT 正交微调适配器训练完全指南

sd-scripts 中 OFTv2 与 BOFT 正交微调适配器训练完全指南 深度学习计算机视觉媒体生成模型训练微调【免费下载链接】sd-scripts项目地址https://gitcode.com/gh_mirrors/sd/sd-scripts点击查看免费下载本文基于 sd-scripts 仓库中的 train_network_oft_boft.md系统讲解如何在train_network.pySD1.x / SD2.x与sdxl_train_network.pySDXL中训练 OFTv2 与 BOFT 两类正交微调适配器。与 LoRA 通过低秩矩阵叠加增量不同正交适配器通过在目标层输入侧乘以学习到的正交旋转矩阵来微调模型具有保留预训练权重范数与夹角结构的独特特性。读完本文你将掌握两种模块的数学原理、全部命令行参数、完整训练命令、权重格式与 PEFT/OMI 兼容加载方式以及合并与性能优化要点。1. 概述正交微调与传统 LoRA 的本质区别OFTv2Orthogonal Fine-Tuning v2与 BOFTButterfly Orthogonal Fine-Tuning都属于正交变换类适配器。它们与 LoRA 的核心差异在于LoRA在权重矩阵上叠加低秩增量W W BA改变权重本身OFTv2 / BOFT不修改权重矩阵本身而是在目标层输入侧乘以一个学习到的正交旋转矩阵x R·x预训练权重被整体旋转。由于旋转保持范数与向量间夹角预训练权重向量的范数norm与两两夹角pairwise angles均被保留这被认为能更好地维持预训练模型的特征几何结构。模块方法每层可训练参数networks.oft_v2OFTv2块对角正交变换Cayley 参数化oft_R.weightnetworks.boftBOFT蝴蝶分解正交变换 每输出通道缩放boft_R、boft_s适用模型范围SD1.x、SD2.x、SDXLU-Net 与 Text Encoder。不支持FLUX.1、SD3、Lumina、HunyuanImage 与 Anima。目标层范围与networks.lora一致U-Net 中Transformer2DModel块内的全部 Linear 层与 1x1 Conv2d 层以及 Text Encoder 的 attention / MLP 层通过enable_convtrue可额外纳入 3x3 Conv2d 层。说明这两个模块由 umisetokikaze 在 PR #2357 中贡献实现遵循 PEFT 的 OFT / BOFT 层规范因此可以加载 PEFT 格式的权重。传统networks.oft模块输出侧旋转、不同权重格式保持原样不变仍可继续使用。1.1 源码实现路径两个模块分别位于 networks/oft_v2.py 与 networks/boft.py二者共享 networks/orthogonal_common.py 中的公共工具。从源码可以确认的模块结构目标替换模块常量orthogonal_common.pyTEXT_ENCODER_TARGET_REPLACE_MODULE [CLIPAttention, CLIPSdpaAttention, CLIPMLP]UNET_TARGET_REPLACE_MODULE [Transformer2DModel]UNET_TARGET_REPLACE_MODULE_CONV2D_3X3 [ResnetBlock2D, Downsample2D, Upsample2D]层筛选遍历named_modules()只接受类名恰好为Linear或Conv2d的子模块Conv2d 默认仅限 1x1is_conv2d_1x13x3 需enable_convtrueorthogonal_common.py限制条件orthogonal_common.py正交适配器不支持分组卷积groups ! 1与 dilation 1 的 Conv2d 层遇到会直接抛出ValueError。2. 命令行参数模块选择、block size 语义与 dropout2.1 模块选择与全局参数--network_module指定训练的网络模块OFTv2 用networks.oft_v2BOFT 用networks.boft--network_alpha被两个模块完全忽略源码create_network中直接del network_alpha--network_dim语义与 LoRA 及旧版networks.oft均不同。关键语义提醒对networks.oft_v2与networks.boft--network_dim被解释为块大小block size即单个正交块的尺寸而不是块数量旧版networks.oft中它表示块数。省略--network_dim时OFTv2 的默认块大小为32BOFT 的默认块大小为4。--network_dropout会被映射为旋转块的乘性 dropoutmultiplicative dropout训练过程中按概率将随机选中的旋转块替换为单位矩阵。从源码实现看这一映射发生在两个层面train_network.py训练脚本通过neuron_dropoutargs.network_dropout与net_kwargs[dropout]传入而_create_network_args中 dropout 的取值优先级为「显式--network_dropout--network_args中的dropout/dropout_probabilityOFTv2或boft_dropout/dropoutBOFT」。2.2 OFTv2 专属参数--network_args参数默认值说明block_size或oft_block_size--network_dim32每个正交块的大小优先于--network_dimcoft或oft_coftfalse启用约束 OFTCOFT每步把旋转投影到 ε 球内coft_eps6e-5COFT 的约束半径block_share或oft_block_sharefalse层内所有块共享同一个旋转块参数更少dropout或dropout_probability0.0块 dropout 概率若显式给出--network_dropout则以其为准enable_convfalse同时作用于 3x3 Conv2d 层ResNet 块、上/下采样器auto_adjusttrue当in_features不能被块大小整除时自动挑选最近的约数false则直接报错include_patterns/exclude_patterns无Python 正则列表对模块名做完整匹配例如exclude_patterns[.*attn2.*]2.3 BOFT 专属参数--network_args参数默认值说明block_size或boft_block_size--network_dim4每个正交块的大小与block_num二选一block_num或boft_block_num无每层块数量块大小由in_features推导boft_n_butterfly_factor1蝴蝶因子数量。1为带缩放因子的普通块对角 OFT大于 1 时引入蝴蝶置换。大于 1 要求块大小与块数量均为偶数且in_features能被block_size * 2^(factor-1)整除dropout或boft_dropout0.0块 dropout 概率--network_dropout优先enable_convfalse同时作用于 3x3 Conv2d 层auto_adjusttrue请求形状不合法时自动选择有效块形状include_patterns/exclude_patterns无与 OFTv2 相同2.4 参数解析与形状校验的源码佐证OFTv2 参数解析oft_v2.py_create_network_args依次解析block_size取oft_block_size或block_size缺省回落network_dim再缺省 32、coft、coft_eps、block_share、dropout、enable_conv、auto_adjust、include_patterns/exclude_patternsBOFT 参数解析boft.py支持boft_block_size/boft_block_num互斥指定block_size缺省为network_dim再缺省为 4形状校验boft.py_valid_boft_shape检查block_size * block_num in_features当因子数 1 时还要求block_num % 2^(factor-1) 0、block_size与block_num均为偶数、in_features % (block_size * 2^(factor-1)) 0。若同时给定block_size与block_num会直接抛出ValueErrorauto_adjust 实现orthogonal_common.pyadjust_block_size在给定块大小不能整除in_features时向上/向下寻找最近的约数OFTv2 侧若auto_adjustfalse且不整除则抛错oft_v2.py。3. 完整训练命令示例3.1 SDXL OFTv2仅 U-Netaccelerate launch --num_cpu_threads_per_process 1 sdxl_train_network.py \ --pretrained_model_name_or_path/path/to/sdxl_model.safetensors \ --dataset_config/path/to/config.toml \ --output_dir./output --output_namesdxl_oftv2 --save_model_assafetensors \ --network_modulenetworks.oft_v2 --network_dim32 \ --network_args coftfalse block_sharefalse \ --network_train_unet_only \ --learning_rate1e-4 --max_train_steps1000 --train_batch_size1 \ --mixed_precisionfp16 --sdpa --gradient_checkpointing --cache_latents要点说明--network_dim32作为 OFTv2 的块大小--network_train_unet_only仅训练 U-Net 部分对应脚本中的--network_train_unet_only参数SD1.x/SD2.x 使用train_network.py时还可结合--network_train_text_encoder_only等--cache_latents缓存潜在表示以节省显存--gradient_checkpointing会同时在反向传播阶段重算旋转矩阵见第 6 节注意事项。3.2 BOFT 双蝴蝶因子--network_modulenetworks.boft --network_dim8 \ --network_args boft_n_butterfly_factor2即块大小 8、蝴蝶因子为 22^(2-1) 2要求in_features能被 16 整除且块数量为偶数auto_adjust默认开启可自动适配。3.3 其余通用选项--unet_lr、--text_encoder_lr、--network_weights加载已有权重继续训练、采样生成等选项与 LoRA 训练完全一致详见 train_network.md 与 sdxl_train_network.md。4. 工作原理Cayley 参数化、COFT 与蝴蝶置换4.1 OFTv2块对角旋转与 Cayley 参数化OFTv2 将每层的输入特征in_features划分为rank in_features // block_size个块每个块使用一个block_size × block_size的正交矩阵。可训练参数oft_R.weight的形状为(rank, n_elements)其中n_elements block_size * (block_size - 1) / 2即反对称矩阵的上三角独立元素数——正交矩阵的 Cayley 参数化只需要这么多自由度。核心实现oft_v2.py_pytorch_skew_symmetric把参数向量组装成反对称矩阵matrix - matrix.transpose(-2, -1)_cayley_batch通过Cayley 变换R (I Q)^{-1}(I - Q)从反对称矩阵Q生成正交矩阵。默认启用 Neumann 级数近似use_cayley_neumanntrue默认展开 5 项可在精度与速度间取舍关闭时使用精确的torch.linalg.solveforward将输入xreshape 为(..., rank, block_size)用torch.einsum(...rk,rkc-...rc, ...)逐块旋转后还原形状block_sharetrue时仅保留 1 个旋转块按rank次数repeat复用oft_v2.py参数量从rank × n_elements降为1 × n_elements。4.2 COFTε 球约束投影cofttrue时每步前向先将旋转参数投影到以单位矩阵为中心的ε 球内oft_v2.py计算参数矩阵到原点的 Frobenius 范数若超出coft_eps则缩放回边界。这一约束能限制旋转偏离单位阵的程度防止微调破坏原始权重结构。测试用例 test_orthogonal_networks.py 验证了 COFT 投影后梯度依然正常传播、基础权重保持不变。4.3 BOFT蝴蝶分解与输出缩放BOFT 的可训练参数为boft_R形状(n_factors, block_num, block_size, block_size)与boft_s形状(out_features, 1)每输出通道缩放。其特点boft.py蝴蝶置换boft_n_butterfly_factor 1时通过block_butterfly_perm生成置换矩阵boft_P非持久 buffer对块做奇偶交错重排使不同块之间产生信息交互突破纯块对角的表达限制Cayley 变换cayley_batch对每个block_size × block_size块独立做 Cayley 变换生成正交块旋转-缩放前向时逐因子做P blockdiag(R) P^T并连乘再右乘输入权重最后按输出通道乘以boft_s缩放dropout 差异BOFT 的乘性 dropout 在随机选中的单个因子内随机替换p × block_num个块为单位矩阵boft.py与 OFTv2 按块整体掩码的实现略有不同。5. 权重格式与兼容性5.1 保存格式权重使用与 LoRA 相同的前缀保存lora_unet_...、lora_te_...、lora_te1_...、lora_te2_...后接参数名例如lora_unet_down_blocks_1_attentions_0_transformer_blocks_0_attn1_to_q.oft_R.weight前缀规则定义在 orthogonal_common.pynative 键名由native_prefixorthogonal_common.py把模块名中的.替换为_生成。BOFT 对应...boft_R、...boft_s。5.2 加载时的多格式识别使用--network_weights、gen_img.py或合并流程加载时除 native 格式外还识别以下键格式orthogonal_common.pyOMI 风格前缀unet./clip_l./clip_g.加原始点分模块名omi_prefixPEFT 适配器格式base_model.model.模块名.oft_R.weight/.boft_R/.boft_s。可以直接传入包含adapter_model.safetensors的 PEFT 适配器目录——load_weights_sd会自动识别目录并从中读取适配器文件orthogonal_common.py。匹配不到的键会发出警告并忽略。测试用例 test_orthogonal_networks.py 验证了 PEFT 风格权重可直接构建网络与训练加载SDXL 场景下 PEFT 键不区分两个 Text Encoder加载时需自行注意映射关系native 格式的lora_te1_/lora_te2_前缀则能精确区分。兼容性细节BOFT 在加载时会对boft_s的形状做自适应转置_adapt_state_for_local_shapeboft.py兼容 PEFT 中(out_features, 1)与本地布局的差异auto_adjust选出的实际块形状在加载时通过_infer_from_state从权重张量形状反推OFTv2 用三角元素数反推块大小BOFT 读取boft_R形状因此不影响自己训练产出的 checkpoint 兼容性。6. 注意事项与性能优化速度旋转矩阵每步前向都要从参数出发通过大量小矩阵运算重建Cayley 变换 einsum因此每步开销高于 LoRA小 batch 下 GPU 利用率可能偏低。加大 batch size可摊薄该固定开销--gradient_checkpointing会在反向阶段同样重算旋转进一步增加计算量合并两个模块均支持merge_to网络接口is_mergeable()返回True可在gen_img.py等场景把适配器合并进基础权重合并结果是原权重被精确旋转后的版本。训练脚本中也可通过--base_weights预合并加载train_network.pyauto_adjusttrue默认当请求的块大小不整除in_features时某些层可能被静默选择不同的块大小。由于加载时从保存权重推断实际形状这不会影响与你自己 checkpoint 的兼容性若希望严格报错而非静默调整请设auto_adjustfalse前向一致性测试仓库测试 test_orthogonal_networks.py 对 Linear、1x1 Conv2d、3x3 Conv2d 三种层验证了「hook 前向输出」与「merge 后权重」数值一致atol/rtol1e-5可作为自行验证合并正确性的参考方法。7. 快速决策OFTv2 还是 BOFT维度OFTv2BOFT参数语义纯块对角旋转Cayley块对角旋转 蝴蝶置换 输出缩放默认块大小324每层参数oft_R.weightboft_Rboft_s约束变体COFTε 球投影无依赖缩放因子表达力扩展block_share减参boft_n_butterfly_factor增参增表达适用对象SD1.x / SD2.x / SDXL同左两者共享同一套目标层筛选、权重前缀与多格式加载逻辑切换只需更换--network_module并按上表调整--network_dim块大小与--network_args。开始训练前建议先在小步数、小 batch 上验证训练曲线再根据显存与速度表现决定 batch size 与是否启用--gradient_checkpointing。赞分享深度学习计算机视觉媒体生成模型训练微调【免费下载链接】sd-scripts项目地址https://gitcode.com/gh_mirrors/sd/sd-scripts点击查看免费下载相关推荐SDXL 训练完全指南sd-scripts 中 sdxl_train.py 微调、LoRA 与 Textual Inversion 实战SDXL 训练完全指南sd scripts 中 sdxl_train.py 微调、LoRA 与 Textual Inversion 实战 导读 本文面向希望在深度学习计算机视觉媒体生成模型训练微调sd-scripts 之 DreamBooth 训练完整指南从数据准备、正则化图像到 Text EncoderU-Net 微调实战sd scripts 之 DreamBooth 训练完整指南从数据准备、正则化图像到 Text EncoderU Net 微调实战 本文是基于 sd scr深度学习计算机视觉媒体生成模型训练微调如何用 kohya-ss/sd-scripts 轻松掌握AI图像生成与训练超详细新手教程如何用 kohya ss/sd scripts 轻松掌握AI图像生成与训练超详细新手教程 kohya ss/sd scripts 是一套功能强大的AI图像生成深度学习计算机视觉媒体生成模型训练微调上一篇AWS CLI 实战使用 aws apigateway get-model-template 获取 API Gateway 模型映射模板下一篇终极指南如何用pdf-lib在浏览器中实现IndexedDB缓存优化PDF性能创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表