lora-scripts icon indicating copy to clipboard operation
lora-scripts copied to clipboard

选择DAdapAdam优化器时默认学习率过高

Open alex9441 opened this issue 6 months ago • 2 comments

今天打算试用一下时髦的DadapAdam,发现 v1.12.0中默认的学习率为

learning_rate =1 unet_lr =1 text_encoder_lr =1 开练后直接 avr_loss=nan 了.

问过几个AI且查了些资料后,手动覆盖为

learning_rate = 0.1 unet_lr = 0.1 text_encoder_lr = 0.1

另外添加了 clip_grad_norm=1.0

建议UI界面修改这方面的设定,给出一定的提示,并添加在DAdapAdam优化器手动设置学习率的功能. 还有clip_grad_norm选项.

谨致码运昌隆!

alex9441 avatar Jun 01 '25 02:06 alex9441

非常非常感谢,解决了大问题。

ilikeulinux avatar Jun 01 '25 05:06 ilikeulinux

在Web UI界面中设置了unet_lr=0.1,但在训练开始后学习率仍然是1.0。这很可能是参数传递流程中的问题。我们需要检查参数从Web UI到训练脚本的传递过程。

问题分析

根据代码,学习率参数的处理流程如下:

  1. 用户界面层:用户在Web UI中设置unet_lr=0.1
  2. 参数解析层argparse解析参数
  3. 优化器创建层get_optimizer函数使用参数创建优化器

问题可能出现在参数解析层或优化器创建层。

解决方案

1. 检查参数解析流程

在参数解析部分,我们需要确保unet_lr参数被正确解析并传递:

# 在参数解析部分,确保有unet_lr参数的定义
parser.add_argument("--unet_lr", type=float, default=None, help="learning rate for U-Net / U-Netの学習率")

# 在训练脚本中,打印参数值确认
logger.info(f"Parsed unet_lr: {args.unet_lr}")

2. 在优化器创建层使用unet_lr

get_optimizer函数中,我们需要使用unet_lr而不是全局的learning_rate

def get_optimizer(args, trainable_params) -> tuple[str, str, object]:
    # 使用unet_lr作为学习率,如果设置了的话
    lr = args.unet_lr if args.unet_lr is not None else args.learning_rate
    logger.info(f"Using learning rate: {lr}")
    
    # ... [优化器创建逻辑不变]

3. 完整的参数传递流程

从Web UI到训练脚本的完整参数传递流程:

# Web UI部分 - 构建命令行参数
def start_training():
    args = [
        "--unet_lr", str(webui_settings.unet_lr_value),
        # 其他参数...
    ]
    subprocess.run(["python", "train.py"] + args)

# train.py - 参数解析
parser = argparse.ArgumentParser()
parser.add_argument("--unet_lr", type=float, default=None)
# 其他参数...

# train.py - 训练逻辑
def main():
    args = parser.parse_args()
    optimizer = get_optimizer(args, trainable_params)

关键检查点

  1. Web UI参数构建:确保unet_lr值被正确添加到命令行参数中
  2. argparse解析:确认args.unet_lr在训练脚本中被正确解析
  3. 优化器使用:在get_optimizer函数中使用args.unet_lr而不是args.learning_rate

建议的完整修改

train.py中:

# 在get_optimizer函数开头添加
if args.unet_lr is not None:
    logger.info(f"Using U-Net specific learning rate: {args.unet_lr}")
    lr = args.unet_lr
else:
    logger.info(f"Using global learning rate: {args.learning_rate}")
    lr = args.learning_rate

# 在D-Adaptation优化器部分
if optimizer_type.startswith("DAdapt".lower()) or optimizer_type == "Prodigy".lower():
    # 使用上面设置的lr,而不是固定值
    optimizer = optimizer_class(trainable_params, lr=lr, **optimizer_kwargs)

调试建议

  1. 在Web UI中添加日志,输出实际发送给训练脚本的命令行参数
  2. 在训练脚本开头添加参数打印:
    logger.info("Received arguments:")
    for arg in vars(args):
        logger.info(f"{arg}: {getattr(args, arg)}")
    
  3. get_optimizer函数开头添加学习率值打印

这个修改应该能解决参数传递的问题,确保用户在Web UI中设置的unet_lr值能正确应用到优化器中。

Omg-ciTy avatar Sep 15 '25 14:09 Omg-ciTy